diff --git a/.clang-tidy b/.clang-tidy index 81f2d62596..9293603c71 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -105,6 +105,89 @@ Checks: '*, -readability-redundant-declaration, -readability-static-accessed-through-instance, -readability-static-definition-in-anonymous-namespace, + -altera-struct-pack-align, + -bugprone-easily-swappable-parameters, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-non-private-member-variables-in-classes, + -hicpp-uppercase-literal-suffix, + -llvm-qualified-auto, + -misc-non-private-member-variables-in-classes, + -misc-use-anonymous-namespace, + -modernize-concat-nested-namespaces, + -readability-const-return-type, + -readability-identifier-length, + -readability-isolate-declaration, + -readability-qualified-auto, + -readability-redundant-access-specifiers, + -cppcoreguidelines-avoid-do-while, + -misc-include-cleaner, + -misc-const-correctness, + -llvm-else-after-return, + -readability-function-cognitive-complexity, + -cppcoreguidelines-init-variables, + -bugprone-reserved-identifier, + -cert-dcl37-c, + -cert-dcl51-cpp, + -modernize-use-nodiscard, + -misc-confusable-identifiers, + -cert-err33-c, + -readability-redundant-inline-specifier, + -readability-uppercase-literal-suffix, + -bugprone-narrowing-conversions, + -cppcoreguidelines-narrowing-conversions, + -bugprone-switch-missing-default-case, + -cppcoreguidelines-avoid-goto, + -hicpp-avoid-goto, + -bugprone-branch-clone, + -bugprone-unhandled-self-assignment, + -cert-oop54-cpp, + -performance-enum-size, + -readability-avoid-nested-conditional-operator, + -cppcoreguidelines-prefer-member-initializer, + -cppcoreguidelines-explicit-virtual-functions, + -cppcoreguidelines-virtual-class-destructor, + -readability-convert-member-functions-to-static, + -readability-make-member-function-const, + -bugprone-assignment-in-if-condition, + -bugprone-implicit-widening-of-multiplication-result, + -bugprone-incorrect-roundings, + -bugprone-macro-parentheses, + -bugprone-multi-level-implicit-pointer-conversion, + -bugprone-signed-char-misuse, + -bugprone-too-small-loop-variable, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-use-default-member-init, + -hicpp-multiway-paths-covered, + -hicpp-named-parameter, + -misc-header-include-cycle, + -misc-no-recursion, + -performance-no-int-to-ptr, + -readability-avoid-return-with-void-value, + -readability-avoid-unconditional-preprocessor-if, + -readability-delete-null-pointer, + -readability-duplicate-include, + -readability-redundant-casting, + -readability-redundant-member-init, + -readability-reference-to-constructed-temporary, + -readability-simplify-boolean-expr, + -bugprone-unsafe-functions, + -cert-msc24-c, + -cert-msc32-c, + -cert-msc33-c, + -cert-msc51-cpp, + -cert-str34-c, + -cppcoreguidelines-macro-to-enum, + -modernize-macro-to-enum, + -abseil-string-find-str-contains, + -bugprone-suspicious-include, + -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, + -clang-analyzer-optin.core.EnumCastOutOfRange, + -modernize-type-traits, + -misc-definitions-in-headers, + -bugprone-casting-through-void, + -readability-redundant-string-init, ' WarningsAsErrors: '*' CheckOptions: diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ffbb271a90..aeb0789fb3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -3,92 +3,45 @@ description: Create a report to help us improve title: "[Bug] " labels: ["bug-report"] body: + - type: markdown + attributes: + value: | + **Tips for a great bug report:** + - Describe what went wrong and what you expected + - Include a flight log link from [logs.px4.io](http://logs.px4.io/) if possible + - Mention your PX4 version, flight controller, and vehicle type if relevant + - type: textarea attributes: label: Describe the bug - description: A clear and concise description of the bug. + description: A clear description of the bug and what you expected to happen. + placeholder: | + What happened and what did you expect instead? + + Steps to reproduce (if applicable): + 1. + 2. + 3. validations: required: true - type: textarea attributes: - label: To Reproduce + label: Flight Log / Additional Information description: | - Steps to reproduce the behavior. - 1. Drone switched on '...' - 2. Uploaded mission '....' (attach QGC mission file) - 3. Took off '....' - 4. See error - validations: - required: false + **Flight log** (highly recommended for flight-related issues): + - Upload to [PX4 Flight Review](http://logs.px4.io/) and paste the link - - type: textarea - attributes: - label: Expected behavior - description: A clear and concise description of what you expected to happen. - validations: - required: false - - - type: textarea - attributes: - label: Screenshot / Media - description: Add screenshot / media if you have them - - - type: textarea - attributes: - label: Flight Log - description: | - *Always* provide a link to the flight log file: - - Download the flight log file from the vehicle ([tutorial](https://docs.px4.io/main/en/getting_started/flight_reporting.html)). - - Upload the log to the [PX4 Flight Review](http://logs.px4.io/) - - Share the link to the log (Copy and paste the URL of the log) + **Additional details** (if relevant): + - PX4 version (output of `ver all` in MAVLink Shell) + - Flight controller model + - Vehicle type (multicopter, fixed-wing, VTOL, etc.) + - Screenshots or media placeholder: | - # PASTE HERE THE LINK TO THE LOG + Flight log link: + + Version: + + Hardware: validations: required: false - - - type: markdown - attributes: - value: | - ## Setup - - - type: textarea - attributes: - label: Software Version - description: | - Which version of PX4 are you using? - placeholder: | - # If you don't know the version, paste the output of `ver all` in the MAVLink Shell of QGC - validations: - required: false - - - type: input - attributes: - label: Flight controller - description: Specify your flight controller model (what type is it, where was it bought from, ...). - validations: - required: false - - - type: dropdown - attributes: - label: Vehicle type - options: - - Multicopter - - Helicopter - - Fixed Wing - - Hybrid VTOL - - Airship/Balloon - - Rover - - Boat - - Submarine - - Other - - - type: textarea - attributes: - label: How are the different components wired up (including port information) - description: Details about how all is wired. - - - type: textarea - attributes: - label: Additional context - description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 6dd27384ad..9660e1b97f 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: false +blank_issues_enabled: true contact_links: - name: Support Question url: https://docs.px4.io/main/en/contribute/support.html#forums-and-chat diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 034f46e2b8..8065709d86 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,22 +1,9 @@ - ### Solved Problem -When ... I found that ... - Fixes #{Github issue ID} ### Solution -- Add ... for ... -- Refactor ... ### Changelog Entry For release notes: @@ -27,11 +14,10 @@ Documentation: Need to clarify page ... / done, read docs.px4.io/... ``` ### Alternatives -We could also ... ### Test coverage -- Unit/integration test: ... -- Simulation/hardware testing logs: https://review.px4.io/ ### Context Related links, screenshot before/after, video + +--> diff --git a/.github/instructions/docs.en.instructions.md b/.github/instructions/docs.en.instructions.md new file mode 100644 index 0000000000..97801a724f --- /dev/null +++ b/.github/instructions/docs.en.instructions.md @@ -0,0 +1,48 @@ +--- +applyTo: "docs/en/**" +--- + +# Review Guidelines docs/en Tree + +## File System & Structure + +- **Naming:** Use `lowercase_with_underscores` for all filenames. No spaces. +- **Hierarchy:** Markdown files must reside exactly in a first-level category folder. + - Valid: `docs/en/category/file.md` + - Invalid: `docs/en/category/subcategory/file.md` +- **Text Files:** Any `.txt` or `.text` files must start with an underscore (e.g., `_notes.txt`). +- **Assets:** All images/non-docs must be in `/docs/assets/`. Deep nesting is permitted here. +- **Formats:** Prefer **SVG** for diagrams and **PNG** for screenshots. Flag JPG files. + +## Markdown & Style + +- **Headings:** Use Title Case ("First Letter Capitalisation"). + - The Page Title must be the only H1 (`#`). All others must be `##` or lower. + - Do not apply bold or italic styling inside a heading. +- **Formatting:** + - **Bold:** Only for UI elements (buttons, menu items). + - **Italics (Emphasis):** For tool names (e.g., *QGroundControl*). + - **Inline Code:** Use backticks for file paths, parameters, and CLI commands (e.g., `prettier`). +- **Structure:** End every line at the end of a sentence (Semantic Line Breaks). + +## Linking & Navigation + +- **Standard Links:** Use standard inline syntax: `[link text](../category/filename.md)`. + Note relative link. +- **Table Links:** To keep tables readable, use reference-style links. + - Definition: `[Link Name]: https://example.com` (placed below the table). + - Usage: `[Link Name]` within the table cell. +- **Images:** All image links must include a descriptive, accessible alt-text in the brackets: `![Detailed description of the image content](../../assets/path/to/image.png)`. + Note that all images should be relative references to images stored in the assets folder, which should be two folders below the any markdown file (as they are stored in a "category" subfolder) + +- **Standard Links:** Use standard inline syntax: `[link text](../category/filename.md)`. Note the use of relative links. +- **Table Links:** To keep tables easier to edit, prefer reference-style links. + - Definition: `[Link Name]: https://example.com` (placed below the table). + - Usage: `[Link Name]` within the table cell. +- **Images:** All image links must include a descriptive, accessible alt-text: `![Detailed description of the image content](../../assets/path/to/image.png)`. + - **Note:** All images must be relative references to the `/docs/assets/` folder. Since documents are nested in a category folder, this is usually two levels up (`../../assets/`). + +## Quality Control + +- **Prettier Check:** Ensure Prettier rules have been applied. If there is evidence of inconsistent indentation or spacing, request the author run `npx prettier --write .` before merging. +- **Language:** Enforce **UK English** spelling and grammar. diff --git a/.github/runs-on.yml b/.github/runs-on.yml new file mode 100644 index 0000000000..f68d406c8a --- /dev/null +++ b/.github/runs-on.yml @@ -0,0 +1,24 @@ +runners: + x86-small-runner: + cpu: [1, 2] + ram: [1, 4] + disk: default + spot: price-capacity-optimized + image: ubuntu24-full-x64 + extras: s3-cache + x86-firmware-builder: + cpu: [4, 8] + ram: [8, 16] + disk: default + family: ["c7i", "m7i", "r7i"] + spot: price-capacity-optimized + image: ubuntu24-full-x64 + extras: s3-cache + arm64-firmware-builder: + cpu: [4, 8] + ram: [8, 16] + disk: default + family: ["c7g", "m7g", "r7g"] + spot: price-capacity-optimized + image: ubuntu24-full-arm64 + extras: s3-cache diff --git a/.github/workflows/build_all_targets.yml b/.github/workflows/build_all_targets.yml index ef3b4d1470..4c0bc0fcb9 100644 --- a/.github/workflows/build_all_targets.yml +++ b/.github/workflows/build_all_targets.yml @@ -2,6 +2,37 @@ # - If you want to keep the tests running in GitHub Actions you need to uncomment the "runs-on: ubuntu-latest" lines # and comment the "runs-on: [runs-on,runner=..." lines. # - If you would like to duplicate this setup try setting up "RunsOn" on your own AWS account try https://runs-on.com +# +# =================================================================================== +# RELEASE UPLOAD LOGIC +# =================================================================================== +# This workflow handles building firmware and uploading to S3 + GitHub Releases. +# +# S3 Bucket Structure (s3://px4-travis/Firmware/): +# - master/ <- Latest main branch build (for QGC compatibility) +# - stable/ <- Latest stable release, controlled by 'stable' branch +# - beta/ <- Latest pre-release, controlled by 'beta' branch +# - vX.Y.Z/ <- Archived stable release +# - vX.Y.Z-beta1/ <- Archived pre-release +# +# Trigger Behavior: +# - Tag v1.16.1 -> Upload to: v1.16.1/ only (versioned archive) +# - Tag v1.17.0-beta1 -> Upload to: v1.17.0-beta1/ only (versioned archive) +# - Branch main -> Upload to: master/ (for QGC compatibility) +# - Branch stable -> Upload to: stable/ (QGC stable firmware) +# - Branch beta -> Upload to: beta/ (QGC beta firmware) +# - Branch release/** -> Build only, no S3 upload (CI validation) +# - Pull requests -> Build only, no S3 upload (CI validation) +# +# GitHub Releases: +# - All version tags create a draft GitHub Release +# - Pre-releases (alpha/beta/rc suffixes) are automatically marked as such +# +# IMPORTANT: Version tags do NOT upload to stable/ or beta/. Only the +# corresponding branch pushes control those directories. This prevents +# pre-release tags from accidentally overwriting stable firmware (#26340) +# and avoids race conditions between tag and branch builds. +# =================================================================================== name: Build all targets @@ -26,11 +57,16 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: write + actions: read + packages: read + jobs: group_targets: name: Scan for Board Targets # runs-on: ubuntu-latest - runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} timestamp: ${{ steps.set-timestamp.outputs.timestamp }} @@ -38,6 +74,14 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Cache Python pip + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**./Tools/setup/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + - name: Update python packaging to avoid canonicalize_version() error run: | pip3 install -U packaging @@ -48,12 +92,15 @@ jobs: path: "./Tools/setup/requirements.txt" - id: set-matrix - run: echo "::set-output name=matrix::$(./Tools/ci/generate_board_targets_json.py --group)" + name: Generate Build Matrix + run: echo "matrix=$(./Tools/ci/generate_board_targets_json.py --group)" >> $GITHUB_OUTPUT - id: set-timestamp - run: echo "::set-output name=timestamp::$(date +"%Y%m%d%H%M%S")" + name: Save Current Timestamp + run: echo "timestamp=$(date +"%Y%m%d%H%M%S")" >> $GITHUB_OUTPUT - id: set-branch + name: Save Current Branch Name run: | echo "branchname=${{ github.event_name == 'pull_request' && @@ -70,7 +117,7 @@ jobs: echo "$(./Tools/ci/generate_board_targets_json.py --group --verbose)" setup: - name: Build Group [${{ matrix.group }}][${{ matrix.arch == 'nuttx' && 'x86' || 'arm64' }}] + name: Build [${{ matrix.runner }}][${{ matrix.group }}] # runs-on: ubuntu-latest runs-on: [runs-on,"runner=8cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",spot=false] needs: group_targets @@ -79,7 +126,11 @@ 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 with: fetch-depth: 0 @@ -87,14 +138,24 @@ jobs: - name: Git ownership workaround run: git config --system --add safe.directory '*' - - name: Setup ccache - uses: actions/cache@v4 + # ccache key breakdown: + # ccache---- + # ccache---- + # ccache---- + - name: Cache Restore from Key + id: cc_restore + uses: actions/cache/restore@v4 with: path: ~/.ccache - key: ${{ matrix.group }}-ccache-${{ needs.group_targets.outputs.timestamp }} - restore-keys: ${{ matrix.group }}-ccache-${{ needs.group_targets.outputs.timestamp }} + key: ${{ format('ccache-{0}-{1}-{2}', runner.os, matrix.runner, matrix.group) }} + restore-keys: | + ccache-${{ runner.os }}-${{ matrix.runner }}-${{ matrix.group }}- + ccache-${{ runner.os }}-${{ matrix.runner }}- + ccache-${{ runner.os }}-${{ matrix.runner }}- + ccache-${{ runner.os }}- + ccache- - - name: Configure ccache + - name: Cache Config and Stats run: | mkdir -p ~/.ccache echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf @@ -102,10 +163,11 @@ jobs: echo "compression_level = 6" >> ~/.ccache/ccache.conf echo "max_size = 120M" >> ~/.ccache/ccache.conf echo "hash_dir = false" >> ~/.ccache/ccache.conf + echo "compiler_check = content" >> ~/.ccache/ccache.conf ccache -s ccache -z - - name: Building [${{ matrix.group }}] + - name: Building Artifacts for [${{ matrix.targets }}] run: | ./Tools/ci/build_all_runner.sh ${{matrix.targets}} ${{matrix.arch}} @@ -119,15 +181,34 @@ jobs: name: px4_${{matrix.group}}_build_artifacts path: artifacts/ - - name: Cache Save - run: ccache -s + - name: Cache Post Build Stats + if: always() + run: | + ccache -s + ccache -z + - name: Cache Save + if: always() + uses: actions/cache/save@v4 + with: + path: ~/.ccache + key: ${{ steps.cc_restore.outputs.cache-primary-key }} + + # =========================================================================== + # ARTIFACT UPLOAD JOB + # =========================================================================== + # Uploads build artifacts to S3 and creates GitHub Releases. + # Runs for version tags (v*), main, stable, and beta branch pushes. + # See header comments for full upload logic documentation. + # =========================================================================== artifacts: - name: Upload Artifacts to S3 + name: Upload Artifacts # runs-on: ubuntu-latest runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] needs: [setup, group_targets] - if: contains(fromJSON('["main", "stable", "beta"]'), needs.group_targets.outputs.branchname) + if: startsWith(github.ref, 'refs/tags/v') || contains(fromJSON('["main","stable","beta"]'), needs.group_targets.outputs.branchname) + outputs: + uploadlocation: ${{ steps.upload-location.outputs.uploadlocation }} steps: - name: Download Artifacts uses: actions/download-artifact@v4 @@ -135,11 +216,36 @@ jobs: path: artifacts/ merge-multiple: true - - name: Branch Name + - name: Choose Upload Location + id: upload-location run: | - echo "${{ needs.group_targets.outputs.branchname }}" + set -euo pipefail - - name: Uploading Artifacts to S3 [${{ needs.group_targets.outputs.branchname == 'main' && 'master' || needs.group_targets.outputs.branchname }}] + ref="${GITHUB_REF}" + branch=${{ needs.group_targets.outputs.branchname }} + location="$branch" + is_prerelease="false" + + # Main branch uploads to "master" for QGC backward compatibility + if [[ "$branch" == "main" ]]; then + location="master" + fi + + # Version tags: upload to versioned directory (e.g., v1.16.1/) + if [[ "$ref" == refs/tags/v[0-9]* ]]; then + tag="${ref#refs/tags/}" + location="$tag" + + # Pre-release tags contain -alpha, -beta, or -rc suffix + if [[ "$tag" =~ -(alpha|beta|rc) ]]; then + is_prerelease="true" + fi + fi + + echo "uploadlocation=$location" >> $GITHUB_OUTPUT + echo "is_prerelease=$is_prerelease" >> $GITHUB_OUTPUT + + - name: Uploading Artifacts to S3 [${{ steps.upload-location.outputs.uploadlocation }}] uses: jakejarvis/s3-sync-action@master with: args: --acl public-read @@ -149,25 +255,15 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: 'us-west-1' SOURCE_DIR: artifacts/ - DEST_DIR: Firmware/${{ needs.group_targets.outputs.branchname == 'main' && 'master' || needs.group_targets.outputs.branchname }}/ + DEST_DIR: Firmware/${{ steps.upload-location.outputs.uploadlocation }}/ - release: - name: Create Release and Upload Artifacts - permissions: - contents: write - # runs-on: ubuntu-latest - runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] - needs: [setup, group_targets] - if: startsWith(github.ref, 'refs/tags/') - steps: - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts/ - merge-multiple: true - - - name: Upload Binaries to Release + # Create a draft GitHub Release for all version tags + # Pre-releases are automatically marked as such + - name: Upload Artifacts to GitHub Release uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/v') with: draft: true + prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }} files: artifacts/*.px4 + name: ${{ steps.upload-location.outputs.uploadlocation }} diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 66821d5e17..e43feee8b3 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -19,6 +19,10 @@ concurrency: jobs: build: runs-on: ubuntu-latest + + container: + image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 + strategy: fail-fast: false matrix: @@ -35,20 +39,17 @@ jobs: "px4_sitl_allyes", "module_documentation", ] + steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Building [${{ matrix.check }}] - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 - options: -v ${{ github.workspace }}:/workspace - run: | - cd /workspace - git config --global --add safe.directory /workspace - make ${{ matrix.check }} + run: | + cd "$GITHUB_WORKSPACE" + git config --global --add safe.directory "$GITHUB_WORKSPACE" + make ${{ matrix.check }} - name: Uploading Coverage to Codecov.io if: contains(matrix.check, 'coverage') diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index b373c59765..fc3c5a46ea 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -1,4 +1,4 @@ -name: Clang Tidy +name: Static Analysis on: push: @@ -11,20 +11,59 @@ on: - '**' paths-ignore: - 'docs/**' + +permissions: + contents: read + jobs: - build: - runs-on: ubuntu-latest + clang_tidy: + name: Clang-Tidy + runs-on: [runs-on, runner=16cpu-linux-x64, "run-id=${{ github.run_id }}", "extras=s3-cache"] + container: + image: px4io/px4-dev:v1.17.0-beta1 steps: + - uses: runs-on/action@v2 - uses: actions/checkout@v4 with: fetch-depth: 0 + fetch-tags: true - - name: Testing (clang-tidy) - uses: addnab/docker-run-action@v3 + - name: Configure Git Safe Directory + run: git config --system --add safe.directory '*' + + - name: Restore Compiler Cache + id: cc_restore + uses: actions/cache/restore@v4 with: - image: px4io/px4-dev-clang:2021-09-08 - options: -v ${{ github.workspace }}:/workspace - run: | - cd /workspace - git config --global --add safe.directory /workspace - make clang-tidy + path: ~/.ccache + key: ccache-clang-tidy-${{ github.head_ref || github.ref_name }} + restore-keys: | + ccache-clang-tidy-${{ github.head_ref || github.ref_name }}- + ccache-clang-tidy-main- + ccache-clang-tidy- + + - name: Configure Compiler Cache + run: | + mkdir -p ~/.ccache + echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf + echo "compression = true" >> ~/.ccache/ccache.conf + echo "compression_level = 6" >> ~/.ccache/ccache.conf + echo "max_size = 120M" >> ~/.ccache/ccache.conf + echo "hash_dir = false" >> ~/.ccache/ccache.conf + echo "compiler_check = content" >> ~/.ccache/ccache.conf + ccache -s + ccache -z + + - name: Run Clang-Tidy Analysis + run: make -j16 clang-tidy + + - name: Compiler Cache Stats + if: always() + run: ccache -s + + - name: Save Compiler Cache + if: always() + uses: actions/cache/save@v4 + with: + path: ~/.ccache + key: ${{ steps.cc_restore.outputs.cache-primary-key }} diff --git a/.github/workflows/compile_macos.yml b/.github/workflows/compile_macos.yml index 6ea0e9687d..5e011a5bf6 100644 --- a/.github/workflows/compile_macos.yml +++ b/.github/workflows/compile_macos.yml @@ -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: diff --git a/.github/workflows/compile_ubuntu.yml b/.github/workflows/compile_ubuntu.yml index b213a5beaa..019081b9f6 100644 --- a/.github/workflows/compile_ubuntu.yml +++ b/.github/workflows/compile_ubuntu.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: version: ['ubuntu:22.04', 'ubuntu:24.04'] - runs-on: [runs-on,runner=8cpu-linux-x64,"image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,"image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false] container: image: ${{ matrix.version }} volumes: diff --git a/.github/workflows/dev_container.yml b/.github/workflows/dev_container.yml index a8dd32388e..8922d636cd 100644 --- a/.github/workflows/dev_container.yml +++ b/.github/workflows/dev_container.yml @@ -39,7 +39,7 @@ jobs: name: Set Tags and Variables permissions: contents: read - runs-on: [runs-on,"runner=1cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false,extras=s3-cache] + runs-on: [runs-on,"runner=1cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] outputs: px4_version: ${{ steps.px4_version.outputs.px4_version }} meta_tags: ${{ steps.meta.outputs.tags }} @@ -87,7 +87,7 @@ jobs: - platform: linux/amd64 arch: amd64 runner: x64 - runs-on: [runs-on,"runner=8cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",spot=false,extras=s3-cache] + runs-on: [runs-on,"runner=4cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] steps: - uses: runs-on/action@v1 - uses: actions/checkout@v4 @@ -130,15 +130,15 @@ jobs: load: false push: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} provenance: false - cache-from: type=gha,version=1 - cache-to: type=gha,version=1,mode=max + cache-from: type=gha,version=1,scope=${{ matrix.arch }} + cache-to: type=gha,version=1,mode=max,scope=${{ matrix.arch }} deploy: name: Deploy To Registry permissions: contents: read packages: write - runs-on: [runs-on,"runner=8cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",spot=false,extras=s3-cache] + runs-on: [runs-on,"runner=4cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] needs: [build, setup] if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} steps: diff --git a/.github/workflows/docs-orchestrator.yml b/.github/workflows/docs-orchestrator.yml new file mode 100644 index 0000000000..ad4ef6c260 --- /dev/null +++ b/.github/workflows/docs-orchestrator.yml @@ -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" diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index 369efbe2db..bdf729b2b3 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -1,19 +1,6 @@ -name: Docs - Deploy PX4 User Guide +name: Docs - Deploy PX4 User Guide to Github pages (Manual) on: - push: - branches: - - 'main' - - 'release/**' - paths: - - 'docs/en/**' - pull_request: - branches: - - '**' - paths: - - 'docs/en/**' - - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages @@ -33,7 +20,7 @@ env: jobs: build: - runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",extras=s3-cache,spot=false] steps: - uses: runs-on/action@v1 - name: Checkout @@ -68,7 +55,7 @@ jobs: deploy: if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }} needs: build - runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] steps: - name: Download Artifact diff --git a/.github/workflows/docs_deploy2.yml b/.github/workflows/docs_deploy2.yml deleted file mode 100644 index 32b4d38dcf..0000000000 --- a/.github/workflows/docs_deploy2.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: Docs - Deploy PX4 User Guide to AWS - -on: - push: - branches: - - "main" - - "release/**" - paths: - - "docs/en/**" - pull_request: - branches: - - "**" - paths: - - "docs/en/**" - - workflow_dispatch: - -permissions: - contents: read - id-token: write # for AWS OIDC - -concurrency: - group: docs-deploy - cancel-in-progress: false - -env: - BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - -jobs: - build: - runs-on: - [ - runs-on, - runner=8cpu-linux-x64, - image=ubuntu24-full-x64, - "run-id=${{ github.run_id }}", - spot=false, - extras=s3-cache, - ] - steps: - - uses: runs-on/action@v1 - - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: npm - cache-dependency-path: ./docs/yarn.lock - - - name: Install dependencies - run: yarn install --frozen-lockfile --cwd ./docs - - - name: Build with VitePress - working-directory: ./docs - run: | - npm run docs:build_ubuntu - touch .vitepress/dist/.nojekyll - npm run docs:sitemap - - - name: Upload artifact - if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }} - uses: actions/upload-artifact@v4 - with: - name: px4_docs_build - path: docs/.vitepress/dist/ - retention-days: 1 - - deploy: - if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }} - needs: build - runs-on: 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/${{ env.BRANCH_NAME }}/ \ - --delete \ - --exclude "*" --include "*.html" \ - --cache-control "public, max-age=60" - - - name: Upload assets with long cache - run: | - aws s3 sync ~/_book/ s3://px4-docs/${{ env.BRANCH_NAME }}/ \ - --delete \ - --exclude "*.html" \ - --cache-control "public, max-age=86400, immutable" diff --git a/.github/workflows/docs_flaw_checker.yml b/.github/workflows/docs_flaw_checker.yml deleted file mode 100644 index c31ae9a760..0000000000 --- a/.github/workflows/docs_flaw_checker.yml +++ /dev/null @@ -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/ diff --git a/.github/workflows/docs_pr_comment.yml b/.github/workflows/docs_pr_comment.yml deleted file mode 100644 index 41e443a786..0000000000 --- a/.github/workflows/docs_pr_comment.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/ekf_functional_change_indicator.yml b/.github/workflows/ekf_functional_change_indicator.yml index d84572386e..11c1970680 100644 --- a/.github/workflows/ekf_functional_change_indicator.yml +++ b/.github/workflows/ekf_functional_change_indicator.yml @@ -15,21 +15,21 @@ concurrency: jobs: unit_tests: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: main test - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 - options: -v ${{ github.workspace }}:/workspace + container: + image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: main test run: | - cd /workspace - git config --global --add safe.directory /workspace + cd "$GITHUB_WORKSPACE" + git config --global --add safe.directory "$GITHUB_WORKSPACE" make tests TESTFILTER=EKF - - name: Check if there is a functional change - run: git diff --exit-code - working-directory: src/modules/ekf2/test/change_indication + - name: Check if there is a functional change + run: git diff --exit-code + working-directory: src/modules/ekf2/test/change_indication diff --git a/.github/workflows/ekf_update_change_indicator.yml b/.github/workflows/ekf_update_change_indicator.yml index 991dfd397b..6f6e1dde55 100644 --- a/.github/workflows/ekf_update_change_indicator.yml +++ b/.github/workflows/ekf_update_change_indicator.yml @@ -8,40 +8,47 @@ on: jobs: unit_tests: runs-on: ubuntu-latest + + container: + image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 + env: GIT_COMMITTER_EMAIL: bot@px4.io GIT_COMMITTER_NAME: PX4BuildBot - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: main test - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 - options: -v ${{ github.workspace }}:/workspace + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: main test run: | - cd /workspace - git config --global --add safe.directory /workspace + cd "$GITHUB_WORKSPACE" + git config --global --add safe.directory "$GITHUB_WORKSPACE" make tests TESTFILTER=EKF - - name: Check if there exists diff and save result in variable - id: diff-check - run: echo "CHANGE_INDICATED=$(git diff --exit-code --output=/dev/null || echo $?)" >> $GITHUB_OUTPUT - working-directory: src/modules/ekf2/test/change_indication + - name: Check if there exists diff and save result in variable + id: diff-check + working-directory: src/modules/ekf2/test/change_indication + run: | + if git diff --quiet; then + echo "CHANGE_INDICATED=false" >> $GITHUB_OUTPUT + else + echo "CHANGE_INDICATED=true" >> $GITHUB_OUTPUT + fi - - name: auto-commit any changes to change indication - uses: stefanzweifel/git-auto-commit-action@v4 - with: - file_pattern: 'src/modules/ekf2/test/change_indication/*.csv' - commit_user_name: ${GIT_COMMITTER_NAME} - commit_user_email: ${GIT_COMMITTER_EMAIL} - commit_message: | - '[AUTO COMMIT] update change indication' + - name: auto-commit any changes to change indication + if: steps.diff-check.outputs.CHANGE_INDICATED == 'true' + uses: stefanzweifel/git-auto-commit-action@v4 + with: + file_pattern: 'src/modules/ekf2/test/change_indication/*.csv' + commit_user_name: ${{ env.GIT_COMMITTER_NAME }} + commit_user_email: ${{ env.GIT_COMMITTER_EMAIL }} + commit_message: | + [AUTO COMMIT] update change indication - See .github/workflopws/ekf_update_change_indicator.yml for more details + See .github/workflows/ekf_update_change_indicator.yml for more details - - name: if there is a functional change, fail check - if: ${{ steps.diff-check.outputs.CHANGE_INDICATED }} - run: exit 1 + - name: if there is a functional change, fail check + if: steps.diff-check.outputs.CHANGE_INDICATED == 'true' + run: exit 1 diff --git a/.github/workflows/failsafe_sim.yml b/.github/workflows/failsafe_sim.yml index edf3d1cd67..24cdb49550 100644 --- a/.github/workflows/failsafe_sim.yml +++ b/.github/workflows/failsafe_sim.yml @@ -48,6 +48,7 @@ jobs: run: | git clone https://github.com/emscripten-core/emsdk.git _emscripten_sdk cd _emscripten_sdk + git checkout 4.0.15 ./emsdk install latest ./emsdk activate latest diff --git a/.github/workflows/flash_analysis.yml b/.github/workflows/flash_analysis.yml index e909e24822..7f126352ab 100644 --- a/.github/workflows/flash_analysis.yml +++ b/.github/workflows/flash_analysis.yml @@ -24,7 +24,7 @@ env: jobs: analyze_flash: name: Analyzing ${{ matrix.target }} - runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] container: image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 strategy: @@ -54,6 +54,7 @@ jobs: run: | make clean make distclean + make submodulesclean - name: If it's a PR checkout the base branch if: ${{ github.event.pull_request }} @@ -97,7 +98,7 @@ jobs: # Track this issue https://github.com/PX4/PX4-Autopilot/issues/24408 post_pr_comment: name: Publish Results - runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}"] needs: [analyze_flash] env: V5X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-absolute) }} diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index c2da779c62..5fc26f8063 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -5,6 +5,7 @@ on: permissions: contents: read + issues: write # for JasonEtco/create-an-issue env: RUNS_IN_DOCKER: true diff --git a/.github/workflows/itcm_check.yml b/.github/workflows/itcm_check.yml index f6d5c4fd8c..767f69aa7c 100644 --- a/.github/workflows/itcm_check.yml +++ b/.github/workflows/itcm_check.yml @@ -22,7 +22,7 @@ concurrency: jobs: check_itcm: name: Checking ${{ matrix.target }} - runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] container: image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 strategy: @@ -41,6 +41,10 @@ jobs: scripts: > boards/nxp/tropic-community/nuttx-config/scripts/itcm_functions_includes.ld boards/nxp/tropic-community/nuttx-config/scripts/itcm_static_functions.ld + - target: nxp_mr-tropic + scripts: > + boards/nxp/mr-tropic/nuttx-config/scripts/itcm_functions_includes.ld + boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/mavros_mission_tests.yml b/.github/workflows/mavros_mission_tests.yml index c5d50109b6..0b1a84f7b3 100644 --- a/.github/workflows/mavros_mission_tests.yml +++ b/.github/workflows/mavros_mission_tests.yml @@ -19,25 +19,27 @@ concurrency: jobs: build: runs-on: ubuntu-latest + strategy: fail-fast: false - matrix: - config: - - {vehicle: "iris", mission: "MC_mission_box"} steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Build SITL and Run Tests - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev-ros-melodic:2021-09-08 - options: -v ${{ github.workspace }}:/workspace + - name: Build SITL and Run Tests (inside old ROS container) run: | - cd /workspace - git config --global --add safe.directory /workspace - make px4_sitl_default - make px4_sitl_default sitl_gazebo-classic - ./test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=${{matrix.config.mission}} vehicle:=${{matrix.config.vehicle}} + docker run --rm \ + -v "${GITHUB_WORKSPACE}:/workspace" \ + -w /workspace \ + px4io/px4-dev-ros-melodic:2021-09-08 \ + bash -c ' + git config --global --add safe.directory /workspace + make px4_sitl_default + make px4_sitl_default sitl_gazebo-classic + ./test/rostest_px4_run.sh \ + mavros_posix_test_mission.test \ + mission:=MC_mission_box \ + vehicle:=iris + ' diff --git a/.github/workflows/mavros_offboard_tests.yml b/.github/workflows/mavros_offboard_tests.yml index 2aaf21e95b..dd6b750812 100644 --- a/.github/workflows/mavros_offboard_tests.yml +++ b/.github/workflows/mavros_offboard_tests.yml @@ -19,27 +19,26 @@ concurrency: jobs: build: runs-on: ubuntu-latest - env: - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + strategy: fail-fast: false - matrix: - config: - - {test_file: "mavros_posix_tests_offboard_posctl.test", vehicle: "iris"} steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Build PX4 and Run Tests - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev-ros-melodic:2021-09-08 - options: -v ${{ github.workspace }}:/workspace + - name: Build SITL and Run Tests (inside old ROS container) run: | - cd /workspace - git config --global --add safe.directory /workspace - make px4_sitl_default - make px4_sitl_default sitl_gazebo-classic - ./test/rostest_px4_run.sh ${{matrix.config.test_file}} vehicle:=${{matrix.config.vehicle}} + docker run --rm \ + -v "${GITHUB_WORKSPACE}:/workspace" \ + -w /workspace \ + px4io/px4-dev-ros-melodic:2021-09-08 \ + bash -c ' + git config --global --add safe.directory /workspace + make px4_sitl_default + make px4_sitl_default sitl_gazebo-classic + ./test/rostest_px4_run.sh \ + mavros_posix_tests_offboard_posctl.test \ + vehicle:=iris + ' diff --git a/.github/workflows/nuttx_env_config.yml b/.github/workflows/nuttx_env_config.yml index 791f2fbf4c..f05b456bb6 100644 --- a/.github/workflows/nuttx_env_config.yml +++ b/.github/workflows/nuttx_env_config.yml @@ -19,27 +19,28 @@ concurrency: jobs: build: runs-on: ubuntu-latest + + container: + image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 + strategy: matrix: - config: [ - px4_fmu-v5_default, - ] + config: + - px4_fmu-v5_default steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - - name: Build PX4 and Run Test [${{ matrix.config }}] - uses: addnab/docker-run-action@v3 - with: - image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556 - options: -v ${{ github.workspace }}:/workspace + - name: Build PX4 and Run Test [${{ matrix.config }}] run: | - cd /workspace - git config --global --add safe.directory /workspace - export PX4_EXTRA_NUTTX_CONFIG="CONFIG_NSH_LOGIN_PASSWORD=\"test\";CONFIG_NSH_CONSOLE_LOGIN=y" + cd "$GITHUB_WORKSPACE" + git config --global --add safe.directory "$GITHUB_WORKSPACE" + export PX4_EXTRA_NUTTX_CONFIG='CONFIG_NSH_LOGIN_PASSWORD="test";CONFIG_NSH_CONSOLE_LOGIN=y' echo "PX4_EXTRA_NUTTX_CONFIG: $PX4_EXTRA_NUTTX_CONFIG" + make ${{ matrix.config }} nuttx_context + echo "Check that the config option is set" grep CONFIG_NSH_LOGIN_PASSWORD build/${{ matrix.config }}/NuttX/nuttx/.config diff --git a/.github/workflows/ros_integration_tests.yml b/.github/workflows/ros_integration_tests.yml index e15aa081e7..bbcce560d8 100644 --- a/.github/workflows/ros_integration_tests.yml +++ b/.github/workflows/ros_integration_tests.yml @@ -23,7 +23,7 @@ concurrency: jobs: build: - runs-on: [runs-on,runner=16cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] container: image: px4io/px4-dev-ros2-galactic:2021-09-08 options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined @@ -90,6 +90,9 @@ jobs: mkdir -p /opt/px4_ws/src cd /opt/px4_ws/src git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib.git + # Ignore python packages due to compilation issue (can be enabled when updating ROS) + touch px4-ros2-interface-lib/px4_ros2_py/COLCON_IGNORE || true + touch px4-ros2-interface-lib/examples/python/COLCON_IGNORE || true cd .. # Copy messages to ROS workspace "${PX4_DIR}/Tools/copy_to_ros_ws.sh" "$(pwd)" diff --git a/.github/workflows/ros_translation_node.yml b/.github/workflows/ros_translation_node.yml index 9b161dae90..64bae13f83 100644 --- a/.github/workflows/ros_translation_node.yml +++ b/.github/workflows/ros_translation_node.yml @@ -21,7 +21,7 @@ concurrency: jobs: build_and_test: name: Build and test - runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false] strategy: fail-fast: false matrix: diff --git a/.github/workflows/sitl_tests.yml b/.github/workflows/sitl_tests.yml index 6dc6eccd2d..c114b05cb3 100644 --- a/.github/workflows/sitl_tests.yml +++ b/.github/workflows/sitl_tests.yml @@ -24,7 +24,7 @@ concurrency: jobs: build: name: Testing PX4 ${{ matrix.config.model }} - runs-on: [runs-on,runner=16cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] container: image: px4io/px4-dev-simulation-focal:2021-09-08 options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined @@ -33,8 +33,10 @@ jobs: matrix: config: - {model: "iris", latitude: "59.617693", longitude: "-151.145316", altitude: "48", build_type: "RelWithDebInfo" } # Alaska - - {model: "tailsitter" , latitude: "29.660316", longitude: "-82.316658", altitude: "30", build_type: "RelWithDebInfo" } # Florida - - {model: "standard_vtol", latitude: "47.397742", longitude: "8.545594", altitude: "488", build_type: "Coverage" } # Zurich + # VTOL/tailsitter disabled: persistent flaky CI failures (timeouts, erratic + # transitions). Re-enable once the test infrastructure is stabilized. + # - {model: "tailsitter" , latitude: "29.660316", longitude: "-82.316658", altitude: "30", build_type: "RelWithDebInfo" } # Florida + # - {model: "standard_vtol", latitude: "47.397742", longitude: "8.545594", altitude: "488", build_type: "Coverage" } # Zurich steps: - uses: actions/checkout@v4 @@ -118,7 +120,7 @@ jobs: PX4_HOME_LON: ${{matrix.config.longitude}} PX4_HOME_ALT: ${{matrix.config.altitude}} PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}} - run: test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 10 --abort-early --model ${{matrix.config.model}} --upload test/mavsdk_tests/configs/sitl.json --verbose --force-color + run: test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 10 --abort-early --model ${{matrix.config.model}} test/mavsdk_tests/configs/sitl.json --verbose --force-color timeout-minutes: 45 - name: Upload failed logs diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 9e97122d43..96cfbc5799 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,10 +7,15 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v10 with: - days-before-stale: 30 - days-before-close: -1 + operations-per-run: 250 + days-before-stale: 90 + days-before-close: 30 stale-issue-label: 'stale' stale-pr-label: 'stale' remove-stale-when-updated: true + stale-issue-message: '' + close-issue-message: 'This issue has been automatically closed due to 120 days of inactivity. If you believe this is still relevant, please feel free to reopen it or create a new issue.' + stale-pr-message: '' + close-pr-message: 'This pull request has been automatically closed due to 120 days of inactivity. If you would like to continue, please feel free to reopen it or submit a new PR.' diff --git a/.github/workflows/sync_to_px4_msgs.yml b/.github/workflows/sync_to_px4_msgs.yml new file mode 100644 index 0000000000..eae00f3b3f --- /dev/null +++ b/.github/workflows/sync_to_px4_msgs.yml @@ -0,0 +1,62 @@ +name: Sync ROS 2 messages to px4_msgs +on: + push: + branches: + - 'main' + - 'stable' + - 'beta' + - 'release/**' + paths: + - 'msg/**' + - 'srv/**' + workflow_dispatch: + +permissions: + contents: read + +jobs: + sync_to_px4_msgs: + if: github.repository == 'PX4/PX4-Autopilot' + runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false] + steps: + - name: Checkout PX4 repo + uses: actions/checkout@v4 + + - name: Setup git credentials + run: | + git config --global user.name "${{ secrets.PX4BUILDBOT_USER }}" + git config --global user.email "${{ secrets.PX4BUILDBOT_EMAIL }}" + + - name: Clone PX4_msgs repo + run: | + git clone https://${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}@github.com/PX4/px4_msgs.git + + - name: Check out the same branch as the PX4 repo + run: | + cd px4_msgs + if git checkout ${{ github.ref_name }}; then + echo "Checked out existing branch" + else + git checkout -b ${{ github.ref_name }} + fi + + - name: Copy ROS 2 messages + run: | + rm -f px4_msgs/msg/*.msg + rm -f px4_msgs/msg/versioned/*.msg + rm -f px4_msgs/srv/*.srv + rm -f px4_msgs/srv/versioned/*.srv + cp msg/*.msg px4_msgs/msg/ + cp msg/versioned/*.msg px4_msgs/msg/ || true + cp srv/*.srv px4_msgs/srv/ + cp srv/versioned/*.srv px4_msgs/srv/ || true + + - name: Commit and push changes + run: | + cd px4_msgs + git status + git add . + git commit -a -m "Update to PX4 ${{ github.sha }}" || true + git push origin ${{ github.ref_name }} || true + cd .. + rm -rf px4_msgs diff --git a/.gitignore b/.gitignore index f90db3cf6f..fcf982c8df 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,6 @@ src/systemcmds/topic_listener/listener_generated.cpp # colcon log/ keys/ + +# metadata +_emscripten_sdk/ diff --git a/.gitmodules b/.gitmodules index a4c12ecebd..86cb85c961 100644 --- a/.gitmodules +++ b/.gitmodules @@ -100,3 +100,12 @@ [submodule "src/drivers/ins/microstrain/mip_sdk"] path = src/drivers/ins/microstrain/mip_sdk url = https://github.com/PX4/LORD-MicroStrain_mip_sdk.git +[submodule "src/drivers/ins/sbgecom/sbgECom"] + path = src/drivers/ins/sbgecom/sbgECom + url = https://github.com/PX4/sbgECom.git +[submodule "src/modules/mc_raptor/blob"] + path = src/modules/mc_raptor/blob + url = https://github.com/rl-tools/px4-blob +[submodule "src/lib/rl_tools/rl_tools"] + path = src/lib/rl_tools/rl_tools + url = https://github.com/rl-tools/rl-tools.git diff --git a/.vscode/cmake-variants.yaml b/.vscode/cmake-variants.yaml index 30eddc8e56..461ce2d95b 100644 --- a/.vscode/cmake-variants.yaml +++ b/.vscode/cmake-variants.yaml @@ -6,6 +6,16 @@ CONFIG: buildType: RelWithDebInfo settings: CONFIG: px4_sitl_default + px4_sitl_raptor: + short: px4_sitl_raptor + buildType: RelWithDebInfo + settings: + CONFIG: px4_sitl_raptor + px4_sitl_raptor_debug: + short: px4_sitl_raptor_debug + buildType: Debug + settings: + CONFIG: px4_sitl_raptor px4_sitl_spacecraft: short: px4_sitl_spacecraft buildType: RelWithDebInfo @@ -141,6 +151,11 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: ark_can-flow_canbootloader + ark_can-flow-mr_default: + short: ark_can-flow-mr_default + buildType: MinSizeRel + settings: + CONFIG: ark_can-flow-mr_default ark_can-flow-mr_canbootloader: short: ark_can-flow-mr_canbootloader buildType: MinSizeRel @@ -206,6 +221,16 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: ark_dist_canbootloader + ark_f9p-gps_default: + short: ark_f9p-gps_default + buildType: MinSizeRel + settings: + CONFIG: ark_f9p-gps_default + ark_f9p-gps_canbootloader: + short: ark_f9p-gps_canbootloader + buildType: MinSizeRel + settings: + CONFIG: ark_f9p-gps_canbootloader ark_fmu-v6x_bootloader: short: ark_fmu-v6x_bootloader buildType: MinSizeRel @@ -226,6 +251,16 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: ark_fpv_default + ark_mag_canbootloader: + short: ark_mag_canbootloader + buildType: MiniSizeRel + settings: + CONFIG: ark_mag_canbootloader + ark_mag_default: + short: ark_mag_default + buildType: MiniSizeRel + settings: + CONFIG: ark_mag_default ark_pi6x_bootloader: short: ark_pi6x_bootloader buildType: MinSizeRel @@ -236,6 +271,16 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: ark_pi6x_default + ark_x20-gps_default: + short: ark_x20-gps_default + buildType: MinSizeRel + settings: + CONFIG: ark_x20-gps_default + ark_x20-gps_canbootloader: + short: ark_x20-gps_canbootloader + buildType: MinSizeRel + settings: + CONFIG: ark_x20-gps_canbootloader atl_mantis-edu_default: short: atl_mantis-edu buildType: MinSizeRel @@ -386,6 +431,16 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: micoair_h743-v2_default + micoair_h743-lite_bootloader: + short: micoair_h743-lite_bootloader + buildType: MinSizeRel + settings: + CONFIG: micoair_h743-lite_bootloader + micoair_h743-lite_default: + short: micoair_h743-lite + buildType: MinSizeRel + settings: + CONFIG: micoair_h743-lite_default modalai_fc-v1_default: short: modalai_fc-v1 buildType: MinSizeRel @@ -436,6 +491,16 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: nxp_mr-canhubk3_fmu + nxp_mr-tropic_default: + short: nxp_mr-tropic_default + buildType: MinSizeRel + settings: + CONFIG: nxp_mr-tropic_default + nxp_mr-tropic_bootloader: + short: nxp_mr-tropic_bootloader + buildType: MinSizeRel + settings: + CONFIG: nxp_mr-tropic_bootloader nxp_tropic-community_default: short: nxp_tropic-community_default buildType: MinSizeRel @@ -466,3 +531,23 @@ CONFIG: buildType: MinSizeRel settings: CONFIG: x-mav_ap-h743v2_default + svehicle_e2_bootloader: + short: svehicle_e2_bootloader + buildType: MinSizeRel + settings: + CONFIG: svehicle_e2_bootloader + svehicle_e2_default: + short: svehicle_e2 + buildType: MinSizeRel + settings: + CONFIG: svehicle_e2_default + x-mav_ap-h743r1_bootloader: + short: x-mav_ap-h743r1-boot + buildType: MinSizeRel + settings: + CONFIG: x-mav_ap-h743r1_bootloader + x-mav_ap-h743r1_default: + short: x-mav_ap-h743r1 + buildType: MinSizeRel + settings: + CONFIG: x-mav_ap-h743r1_default diff --git a/.vscode/settings.json b/.vscode/settings.json index 1e799721ce..135a643316 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,7 +43,7 @@ "files.watcherExclude": { "**/build/**": true }, - "git.detectSubmodulesLimit": 20, + "git.detectSubmodulesLimit": 25, "git.ignoreLimitWarning": true, "githubPullRequests.defaultMergeMethod": "squash", "githubPullRequests.telemetry.enabled": false, diff --git a/CMakeLists.txt b/CMakeLists.txt index d827f7a8c8..7f4ff17ac4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,7 +267,7 @@ endif() set(package-contact "px4users@googlegroups.com") -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/CTestConfig.cmake b/CTestConfig.cmake deleted file mode 100644 index 5762625f32..0000000000 --- a/CTestConfig.cmake +++ /dev/null @@ -1,15 +0,0 @@ -## This file should be placed in the root directory of your project. -## Then modify the CMakeLists.txt file in the root directory of your -## project to incorporate the testing dashboard. -## -## # The following are required to submit to the CDash dashboard: -## ENABLE_TESTING() -## INCLUDE(CTest) - -set(CTEST_PROJECT_NAME "PX4 Firmware") -set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") - -set(CTEST_DROP_METHOD "http") -set(CTEST_DROP_SITE "my.cdash.org") -set(CTEST_DROP_LOCATION "/submit.php?project=PX4+Firmware") -set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Jenkinsfile b/Jenkinsfile index fb092cd83d..b6f6d3c98a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -101,6 +101,7 @@ pipeline { echo $0; git clone https://github.com/emscripten-core/emsdk.git _emscripten_sdk; cd _emscripten_sdk; + git checkout 4.0.15; ./emsdk install latest; ./emsdk activate latest; cd ..; @@ -220,36 +221,6 @@ pipeline { } } - stage('PX4 ROS msgs') { - agent { - docker { image 'px4io/px4-dev-base-focal:2021-08-18' } - } - steps { - sh('export') - sh('make distclean; git clean -ff -x -d .') - withCredentials([usernamePassword(credentialsId: 'px4buildbot_github_personal_token', passwordVariable: 'GIT_PASS', usernameVariable: 'GIT_USER')]) { - sh("git clone https://${GIT_USER}:${GIT_PASS}@github.com/PX4/px4_msgs.git") - // 'main' branch - sh('rm -f px4_msgs/msg/*.msg') - sh('rm -f px4_msgs/msg/versioned/*.msg') - sh('rm -f px4_msgs/srv/*.srv') - sh('rm -f px4_msgs/srv/versioned/*.srv') - sh('cp msg/*.msg px4_msgs/msg/') - sh('cp msg/versioned/*.msg px4_msgs/msg/ || true') - sh('cp srv/*.srv px4_msgs/srv/') - sh('cp srv/versioned/*.srv px4_msgs/srv/ || true') - sh('cd px4_msgs; git status; git add .; git commit -a -m "Update message definitions `date`" || true') - sh('cd px4_msgs; git push origin main || true') - sh('rm -rf px4_msgs') - } - } - when { - anyOf { - branch 'main' - } - } - } - stage('S3') { agent { docker { image 'px4io/px4-dev-base-focal:2021-08-18' } diff --git a/LICENSE b/LICENSE index b6f204509f..57c2b07f68 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2012 - 2023, PX4 Development Team +Copyright (c) 2012 - 2025, PX4 Development Team All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 5359184ffd..e1fcc89b5f 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -19,7 +19,7 @@ See [the documentation on Maintainers](https://docs.px4.io/main/en/contribute/ma | Matthias Grob | Multirotor | [@MaEtUgR](https://github.com/MaEtUgR) | maetugr | | Silvan Fuhrer | Fixed-Wing / VTOL | [@sfuhrer](https://github.com/sfuhrer) | sfuhrer | | Christian Friedrich | Rover | [@chfriedrich98](https://github.com/chfriedrich98) | christian982564 | -| Pedro Roque | Spacecraft | [@Pedro-Roque](https://github.com/Pedro-Roque) | .pedroroque | +| Pedro Roque | Spacecraft | [@Pedro-Roque](https://github.com/Pedro-Roque) | .pedroroque | | Jacob Dahl | Simulation | [@dakejahl](https://github.com/dakejahl) | dakejahl | diff --git a/Makefile b/Makefile index 996ffd47e5..df7c54f412 100644 --- a/Makefile +++ b/Makefile @@ -325,6 +325,8 @@ bootloaders_update: \ ark_fmu-v6x_bootloader \ ark_fpv_bootloader \ ark_pi6x_bootloader \ + auterion_fmu-v6s_bootloader \ + auterion_fmu-v6x_bootloader \ cuav_nora_bootloader \ cuav_x7pro_bootloader \ cuav_7-nano_bootloader \ @@ -344,6 +346,7 @@ bootloaders_update: \ micoair_h743_bootloader \ micoair_h743-aio_bootloader \ micoair_h743-v2_bootloader \ + micoair_h743-lite_bootloader \ modalai_fc-v2_bootloader \ mro_ctrl-zero-classic_bootloader \ mro_ctrl-zero-h7_bootloader \ @@ -409,7 +412,7 @@ tests: $(call cmake-build,px4_sitl_test) # work around lcov bug #316; remove once lcov is fixed (see https://github.com/linux-test-project/lcov/issues/316) -LCOBUG = --ignore-errors mismatch +LCOBUG = --ignore-errors mismatch,negative tests_coverage: @$(MAKE) clean @$(MAKE) --no-print-directory tests PX4_CMAKE_BUILD_TYPE=Coverage @@ -489,13 +492,29 @@ px4_sitl_default-clang: @cd "$(SRC_DIR)"/build/px4_sitl_default-clang && cmake "$(SRC_DIR)" $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=px4_sitl_default -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ @$(PX4_MAKE) -C "$(SRC_DIR)"/build/px4_sitl_default-clang +# Paths to exclude from clang-tidy (auto-generated from .gitmodules + manual additions): +# - All submodules (external code we consume, not edit) +# - Test code (allowed looser style) +# - Example code (educational, not production) +# - Vendored third-party code (e.g., CMSIS_5) +# - NuttX-only drivers excluded at CMake level (mcp_common); I2C-dependent libs excluded here (smbus) +# - GPIO excluded here (NuttX platform headers) +# - Emscripten failsafe web build: source path + Unity build path (failsafe_test.dir) +# because CMake Unity Builds merge sources into a generated .cxx under build/ +# +# To add manual exclusions, append to CLANG_TIDY_EXCLUDE_EXTRA below. +# Submodules are automatically excluded - no action needed when adding new ones. +CLANG_TIDY_SUBMODULES := $(shell git config --file .gitmodules --get-regexp path | awk '{print $$2}' | tr '\n' '|' | sed 's/|$$//') +CLANG_TIDY_EXCLUDE_EXTRA := src/systemcmds/tests|src/examples|src/modules/gyro_fft/CMSIS_5|src/lib/drivers/smbus|src/drivers/gpio|src/modules/commander/failsafe/emscripten|failsafe_test\.dir +CLANG_TIDY_EXCLUDE := $(CLANG_TIDY_SUBMODULES)|$(CLANG_TIDY_EXCLUDE_EXTRA) + clang-tidy: px4_sitl_default-clang - @cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -p . + @cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -exclude="$(CLANG_TIDY_EXCLUDE)" -p . # to automatically fix a single check at a time, eg modernize-redundant-void-arg # % run-clang-tidy-4.0.py -fix -j4 -checks=-\*,modernize-redundant-void-arg -p . clang-tidy-fix: px4_sitl_default-clang - @cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -fix -p . + @cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -exclude="$(CLANG_TIDY_EXCLUDE)" -fix -p . # TODO: Fix cppcheck errors then try --enable=warning,performance,portability,style,unusedFunction or --enable=all cppcheck: px4_sitl_default @@ -595,3 +614,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 diff --git a/README.md b/README.md index 8353f3add6..bf4d74bb76 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,109 @@ -# PX4 Drone Autopilot +

+ + PX4 Autopilot + +

-[![Releases](https://img.shields.io/github/release/PX4/PX4-Autopilot.svg)](https://github.com/PX4/PX4-Autopilot/releases) [![DOI](https://zenodo.org/badge/22634/PX4/PX4-Autopilot.svg)](https://zenodo.org/badge/latestdoi/22634/PX4/PX4-Autopilot) +

+ The autopilot stack the industry builds on. +

-[![Build Targets](https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml/badge.svg?branch=main)](https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml) [![SITL Tests](https://github.com/PX4/PX4-Autopilot/workflows/SITL%20Tests/badge.svg?branch=master)](https://github.com/PX4/PX4-Autopilot/actions?query=workflow%3A%22SITL+Tests%22) +

+ Releases + DOI + Build Targets + Discord +

-[![Discord Shield](https://discordapp.com/api/guilds/1022170275984457759/widget.png?style=shield)](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 + + + + + + + +
+ + Multicopter
+ Multicopter +
+
+ + Fixed Wing
+ Fixed Wing +
+
+ + VTOL
+ VTOL +
+
+ + Rover
+ Rover +
+
-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. +…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 full airframe reference. -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. - -Dronecode Logo -
 
+

+ + Dronecode Logo + +

diff --git a/ROMFS/CMakeLists.txt b/ROMFS/CMakeLists.txt index e1b08d078b..9b282339fd 100644 --- a/ROMFS/CMakeLists.txt +++ b/ROMFS/CMakeLists.txt @@ -85,10 +85,32 @@ endif() if(PX4_ETHERNET) set(added_arguments ${added_arguments} --ethernet) endif() +# Check if board has an rc.board_airframes file to filter airframes +set(board_airframes_file "${PX4_BOARD_DIR}/init/rc.board_airframes") +set(airframes_whitelist "") +if(EXISTS "${board_airframes_file}") + message(STATUS "ROMFS: Using board-specific airframes list: ${board_airframes_file}") + file(STRINGS "${board_airframes_file}" airframes_whitelist) + # Remove comments and empty lines + list(FILTER airframes_whitelist EXCLUDE REGEX "^[ \t]*#") + list(FILTER airframes_whitelist EXCLUDE REGEX "^[ \t]*$") +endif() + # create list of relative romfs file names set(romfs_copy_files_relative) foreach(romfs_file IN LISTS romfs_copy_files) string(REPLACE "${romfs_src_dir}/" "" romfs_file_rel ${romfs_file}) + + # If we have an airframes whitelist, filter airframe files + if(airframes_whitelist AND romfs_file_rel MATCHES "^init.d/airframes/") + # Extract just the filename + get_filename_component(airframe_name "${romfs_file_rel}" NAME) + # Check if it's in the whitelist + if(NOT "${airframe_name}" IN_LIST airframes_whitelist) + continue() + endif() + endif() + list(APPEND romfs_copy_files_relative ${romfs_file_rel}) endforeach() # copy the ROMFS files by creating a tar and extracting it to the build diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/10041_sihsim_airplane b/ROMFS/px4fmu_common/init.d-posix/airframes/10041_sihsim_airplane index 1853699171..100af65943 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/10041_sihsim_airplane +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/10041_sihsim_airplane @@ -27,7 +27,6 @@ param set-default SIH_KDV 0.2 param set-default SIH_VEHICLE_TYPE 1 # sih as fixed wing param set-default RWTO_TKOFF 1 # enable takeoff from runway (as opposed to launched) -param set-default CA_AIRFRAME 1 param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane b/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane index dc45a34029..81df6295d2 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane @@ -44,8 +44,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1031_gazebo-classic_plane_cam b/ROMFS/px4fmu_common/init.d-posix/airframes/1031_gazebo-classic_plane_cam index 695f851ff0..64a0055323 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1031_gazebo-classic_plane_cam +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1031_gazebo-classic_plane_cam @@ -46,8 +46,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult b/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult index 12e828c08c..16e6648ad7 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult @@ -46,8 +46,6 @@ param set-default MIS_TAKEOFF_ALT 30 param set-default NAV_ACC_RAD 15 param set-default NAV_DLL_ACT 2 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1033_jsbsim_rascal b/ROMFS/px4fmu_common/init.d-posix/airframes/1033_jsbsim_rascal index ef9df5af98..75e1009f23 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1033_jsbsim_rascal +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1033_jsbsim_rascal @@ -31,8 +31,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 param set-default RWTO_PSP 8 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1034_flightgear_rascal-electric b/ROMFS/px4fmu_common/init.d-posix/airframes/1034_flightgear_rascal-electric index ef9df5af98..75e1009f23 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1034_flightgear_rascal-electric +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1034_flightgear_rascal-electric @@ -31,8 +31,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 param set-default RWTO_PSP 8 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1035_gazebo-classic_techpod b/ROMFS/px4fmu_common/init.d-posix/airframes/1035_gazebo-classic_techpod index 68bb142094..db036041e5 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1035_gazebo-classic_techpod +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1035_gazebo-classic_techpod @@ -30,8 +30,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1036_jsbsim_malolo b/ROMFS/px4fmu_common/init.d-posix/airframes/1036_jsbsim_malolo index ef9df5af98..75e1009f23 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1036_jsbsim_malolo +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1036_jsbsim_malolo @@ -31,8 +31,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 param set-default RWTO_PSP 8 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1037_gazebo-classic_believer b/ROMFS/px4fmu_common/init.d-posix/airframes/1037_gazebo-classic_believer index 0a8343a4c8..cb39c54ffd 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1037_gazebo-classic_believer +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1037_gazebo-classic_believer @@ -38,8 +38,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1038_gazebo-classic_glider b/ROMFS/px4fmu_common/init.d-posix/airframes/1038_gazebo-classic_glider index ef2cd02606..9aedcf683e 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1038_gazebo-classic_glider +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1038_gazebo-classic_glider @@ -44,8 +44,6 @@ param set-default MIS_TAKEOFF_ALT 30 param set-default NAV_ACC_RAD 15 param set-default NAV_DLL_ACT 2 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_flightgear_rascal b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_flightgear_rascal index 544fd746e1..ff99bf697b 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_flightgear_rascal +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_flightgear_rascal @@ -35,8 +35,6 @@ param set-default RWTO_MAX_PITCH 20 param set-default RWTO_PSP 8 param set-default RWTO_AIRSPD_SCL 1.8 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane index 1fafd1d488..396c17f3f5 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane @@ -35,8 +35,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1044_gazebo-classic_plane_lidar b/ROMFS/px4fmu_common/init.d-posix/airframes/1044_gazebo-classic_plane_lidar index 23b7757d4b..e2e67b078c 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/1044_gazebo-classic_plane_lidar +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1044_gazebo-classic_plane_lidar @@ -46,8 +46,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/17001_flightgear_tf-g1 b/ROMFS/px4fmu_common/init.d-posix/airframes/17001_flightgear_tf-g1 index dd3b5759ba..875385e449 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/17001_flightgear_tf-g1 +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/17001_flightgear_tf-g1 @@ -43,8 +43,6 @@ param set-default FW_THR_TRIM 0.8 param set-default FW_THR_IDLE 0 param set-default COM_DISARM_PRFLT 0 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/17002_flightgear_tf-g2 b/ROMFS/px4fmu_common/init.d-posix/airframes/17002_flightgear_tf-g2 index 254b291eb0..061ed67745 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/17002_flightgear_tf-g2 +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/17002_flightgear_tf-g2 @@ -48,8 +48,6 @@ param set-default FW_THR_TRIM 0.8 param set-default FW_THR_IDLE 0 param set-default COM_DISARM_PRFLT 0 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4003_gz_rc_cessna b/ROMFS/px4fmu_common/init.d-posix/airframes/4003_gz_rc_cessna index 96dd5fa151..58e09228eb 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4003_gz_rc_cessna +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/4003_gz_rc_cessna @@ -53,8 +53,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default COM_PREARM_MODE 2 param set-default CA_ROTOR_COUNT 1 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol b/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol index 5bd432abde..cc8bed693f 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/4004_gz_standard_vtol @@ -101,6 +101,7 @@ param set-default NAV_ACC_RAD 5 param set-default NAV_DLL_ACT 2 param set-default VT_FWD_THRUST_EN 4 -param set-default VT_F_TRANS_THR 0.3 +param set-default VT_PITCH_MIN -5 +param set-default VT_F_TRANS_THR 1 param set-default VT_TYPE 2 param set-default FD_ESCS_EN 0 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4008_gz_advanced_plane b/ROMFS/px4fmu_common/init.d-posix/airframes/4008_gz_advanced_plane index 8ac407bac4..184ed7ba0d 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4008_gz_advanced_plane +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/4008_gz_advanced_plane @@ -11,8 +11,6 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=advanced_plane} param set-default SIM_GZ_EN 1 -param set-default SENS_EN_ARSPDSIM 1 - param set-default FW_LND_ANG 8 param set-default FW_PR_FF 0.08 @@ -48,8 +46,6 @@ param set-default NAV_DLL_ACT 2 param set-default RWTO_TKOFF 1 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_SV_CS_COUNT 6 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4019_gz_x500_gimbal b/ROMFS/px4fmu_common/init.d-posix/airframes/4019_gz_x500_gimbal index 80719ae3d3..9dcd642c2c 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4019_gz_x500_gimbal +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/4019_gz_x500_gimbal @@ -19,5 +19,6 @@ param set-default MNT_MAN_PITCH 2 param set-default MNT_MAN_YAW 3 param set-default MNT_RANGE_ROLL 180 -param set-default MNT_RANGE_PITCH 180 +param set-default MNT_MAX_PITCH 45 +param set-default MNT_MIN_PITCH -135 param set-default MNT_RANGE_YAW 720 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/50000_gz_rover_differential b/ROMFS/px4fmu_common/init.d-posix/airframes/50000_gz_rover_differential index 270c01c55b..c9e47be70e 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/50000_gz_rover_differential +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/50000_gz_rover_differential @@ -17,6 +17,7 @@ param set-default NAV_ACC_RAD 0.5 param set-default RD_WHEEL_TRACK 0.6 param set-default RD_TRANS_DRV_TRN 0.785398 param set-default RD_TRANS_TRN_DRV 0.174533 +param set-default RD_YAW_STK_GAIN 0.6 # Rate Control Parameters param set-default RO_YAW_RATE_I 0.01 @@ -25,6 +26,8 @@ param set-default RO_YAW_RATE_LIM 250 param set-default RO_YAW_ACCEL_LIM 400 param set-default RO_YAW_DECEL_LIM 800 param set-default RO_YAW_RATE_CORR 1 +param set-default RO_YAW_EXPO 0.85 +param set-default RO_YAW_SUPEXPO 0.3 # Attitude Control Parameters param set-default RO_YAW_P 5 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4012_gz_rover_ackermann b/ROMFS/px4fmu_common/init.d-posix/airframes/51000_gz_rover_ackermann similarity index 63% rename from ROMFS/px4fmu_common/init.d-posix/airframes/4012_gz_rover_ackermann rename to ROMFS/px4fmu_common/init.d-posix/airframes/51000_gz_rover_ackermann index 28025d79ac..96bb10862b 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4012_gz_rover_ackermann +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/51000_gz_rover_ackermann @@ -1,5 +1,5 @@ #!/bin/sh -# @name Rover Ackermann +# @name Generic Ackermann Rover # @type Rover # @class Rover @@ -14,30 +14,32 @@ param set-default SIM_GZ_EN 1 # Gazebo bridge param set-default NAV_ACC_RAD 0.5 # Ackermann Parameters -param set-default RA_WHEEL_BASE 0.321 +param set-default RA_WHEEL_BASE 0.5 param set-default RA_ACC_RAD_GAIN 2 -param set-default RA_ACC_RAD_MAX 3 +param set-default RA_ACC_RAD_MAX 1.5 param set-default RA_MAX_STR_ANG 0.5236 param set-default RA_STR_RATE_LIM 360 -# Rover Control Parameters -param set-default RO_ACCEL_LIM 3 -param set-default RO_DECEL_LIM 6 -param set-default RO_JERK_LIM 15 -param set-default RO_MAX_THR_SPEED 3.1 - -# Rover Rate Control Parameters -param set-default RO_YAW_RATE_I 0.1 -param set-default RO_YAW_RATE_P 1 -param set-default RO_YAW_RATE_LIM 180 +# Rate Control Parameters +param set-default RO_YAW_RATE_I 0.01 +param set-default RO_YAW_RATE_P 0.25 +param set-default RO_YAW_RATE_LIM 130 +param set-default RO_YAW_ACCEL_LIM 800 +param set-default RO_YAW_DECEL_LIM 800 param set-default RO_YAW_RATE_CORR 1 +param set-default RO_YAW_EXPO 0.85 +param set-default RO_YAW_SUPEXPO 0.3 -# Rover Attitude Control Parameters +# Attitude Control Parameters param set-default RO_YAW_P 3 -# Rover Velocity Control Parameters -param set-default RO_SPEED_LIM 3 -param set-default RO_SPEED_I 0.1 +# Velocity Control Parameters +param set-default RO_ACCEL_LIM 4 +param set-default RO_DECEL_LIM 6 +param set-default RO_JERK_LIM 10 +param set-default RO_MAX_THR_SPEED 3.1 +param set-default RO_SPEED_LIM 2.5 +param set-default RO_SPEED_I 0.01 param set-default RO_SPEED_P 1 param set-default RO_SPEED_RED 1 @@ -48,8 +50,8 @@ param set-default PP_LOOKAHD_MIN 1 # Wheels param set-default SIM_GZ_WH_FUNC1 101 -param set-default SIM_GZ_WH_MIN1 0 -param set-default SIM_GZ_WH_MAX1 200 +param set-default SIM_GZ_WH_MIN1 70 +param set-default SIM_GZ_WH_MAX1 130 param set-default SIM_GZ_WH_DIS1 100 # Steering diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/4015_gz_r1_rover_mecanum b/ROMFS/px4fmu_common/init.d-posix/airframes/52000_gz_rover_mecanum similarity index 64% rename from ROMFS/px4fmu_common/init.d-posix/airframes/4015_gz_r1_rover_mecanum rename to ROMFS/px4fmu_common/init.d-posix/airframes/52000_gz_rover_mecanum index 5d96694e83..c882924bda 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/4015_gz_r1_rover_mecanum +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/52000_gz_rover_mecanum @@ -1,5 +1,5 @@ #!/bin/sh -# @name Aion Robotics R1 Rover +# @name Generic Mecanum Rover # @type Rover # @class Rover @@ -7,14 +7,15 @@ PX4_SIMULATOR=${PX4_SIMULATOR:=gz} PX4_GZ_WORLD=${PX4_GZ_WORLD:=rover} -PX4_SIM_MODEL=${PX4_SIM_MODEL:=r1_rover_mecanum} +PX4_SIM_MODEL=${PX4_SIM_MODEL:=rover_mecanum} param set-default SIM_GZ_EN 1 # Gazebo bridge param set-default NAV_ACC_RAD 0.5 # Mecanum Parameters -param set-default RM_WHEEL_TRACK 0.3 +param set-default RM_WHEEL_TRACK 0.6 +param set-default RM_YAW_STK_GAIN 0.6 # Rover Control Parameters param set-default RO_ACCEL_LIM 3 @@ -29,15 +30,21 @@ param set-default RO_YAW_RATE_LIM 120 param set-default RO_YAW_ACCEL_LIM 240 param set-default RO_YAW_DECEL_LIM 1000 param set-default RO_YAW_RATE_CORR 1.75 +param set-default RO_YAW_EXPO 0.85 +param set-default RO_YAW_SUPEXPO 0.3 # Rover Attitude Control Parameters param set-default RO_YAW_P 5 -# Rover Velocity Control Parameters -param set-default RO_SPEED_LIM 2 -param set-default RO_SPEED_I 0.5 -param set-default RO_SPEED_P 1 -param set-default RO_SPEED_RED 1 +# Velocity Control Parameters +param set-default RO_ACCEL_LIM 4 +param set-default RO_DECEL_LIM 6 +param set-default RO_JERK_LIM 10 +param set-default RO_MAX_THR_SPEED 3.1 +param set-default RO_SPEED_LIM 2.5 +param set-default RO_SPEED_I 0.01 +param set-default RO_SPEED_P 0.1 +param set-default RO_SPEED_RED 0.5 # Pure Pursuit parameters param set-default PP_LOOKAHD_GAIN 0.5 @@ -48,24 +55,24 @@ param set-default PP_LOOKAHD_MIN 1 param set-default SENS_EN_MAGSIM 1 # Actuator mapping -param set-default SIM_GZ_WH_FUNC1 102 # right wheel front +param set-default SIM_GZ_WH_FUNC1 104 # left wheel back param set-default SIM_GZ_WH_MIN1 70 param set-default SIM_GZ_WH_MAX1 130 param set-default SIM_GZ_WH_DIS1 100 -param set-default SIM_GZ_WH_FUNC2 101 # left wheel front +param set-default SIM_GZ_WH_FUNC2 103 # right wheel back param set-default SIM_GZ_WH_MIN2 70 param set-default SIM_GZ_WH_MAX2 130 param set-default SIM_GZ_WH_DIS2 100 -param set-default SIM_GZ_WH_FUNC3 104 # right wheel back +param set-default SIM_GZ_WH_FUNC3 102 # left wheel front param set-default SIM_GZ_WH_MIN3 70 param set-default SIM_GZ_WH_MAX3 130 param set-default SIM_GZ_WH_DIS3 100 -param set-default SIM_GZ_WH_FUNC4 103 # left wheel back +param set-default SIM_GZ_WH_FUNC4 101 # right wheel front param set-default SIM_GZ_WH_MIN4 70 param set-default SIM_GZ_WH_MAX4 130 param set-default SIM_GZ_WH_DIS4 100 -param set-default SIM_GZ_WH_REV 10 +param set-default SIM_GZ_WH_REV 0 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/60002_gz_uuv_bluerov2_heavy b/ROMFS/px4fmu_common/init.d-posix/airframes/60002_gz_uuv_bluerov2_heavy index 287589a052..b80bf079b7 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/60002_gz_uuv_bluerov2_heavy +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/60002_gz_uuv_bluerov2_heavy @@ -34,7 +34,6 @@ param set-default COM_LOW_BAT_ACT 0 param set-default NAV_DLL_ACT 0 param set-default GF_ACTION 1 param set-default NAV_RCL_ACT 1 -param set-default COM_POSCTL_NAVL 2 # disable attitude failure detection param set-default FD_FAIL_P 0 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/6011_gazebo-classic_typhoon_h480 b/ROMFS/px4fmu_common/init.d-posix/airframes/6011_gazebo-classic_typhoon_h480 index f75374b15c..1904832613 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/6011_gazebo-classic_typhoon_h480 +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/6011_gazebo-classic_typhoon_h480 @@ -26,7 +26,6 @@ param set-default TRIG_INTERFACE 3 param set-default TRIG_MODE 4 param set-default MNT_MODE_IN 4 param set-default MNT_MODE_OUT 2 -param set-default MAV_PROTO_VER 2 param set-default CA_AIRFRAME 0 param set-default CA_ROTOR_COUNT 6 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/70000_gz_atmos b/ROMFS/px4fmu_common/init.d-posix/airframes/70000_gz_atmos index c17a92a305..49ef971307 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/70000_gz_atmos +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/70000_gz_atmos @@ -1,10 +1,21 @@ #!/bin/sh # -# @name 3DoF Spacecraft Model +# @name KTH-ATMOS # -# @type 2D Freeflyer with 8 thrusters - Planar motion +# @type Free-Flyer +# @class Spacecraft # -# @maintainer Pedro Roque +# @output Motor1 back left thruster, +x thrust +# @output Motor2 front left thruster, -x thrust +# @output Motor3 back right thruster, +x thrust +# @output Motor4 front right thruster, -x thrust +# @output Motor5 front left thruster, +y thrust +# @output Motor6 front right thruster, -y thrust +# @output Motor7 back left thruster, +y thrust +# @output Motor8 back right thruster, -y thrust +# +# @maintainer discower-io +# @url https://atmos.discower.io # . ${R}etc/init.d/rc.sc_defaults @@ -34,7 +45,6 @@ param set-default COM_LOW_BAT_ACT 0 param set-default NAV_DLL_ACT 0 param set-default GF_ACTION 1 param set-default NAV_RCL_ACT 1 -param set-default COM_POSCTL_NAVL 2 # disable attitude failure detection param set-default FD_FAIL_P 0 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/70001_gz_atmos_dual b/ROMFS/px4fmu_common/init.d-posix/airframes/70001_gz_atmos_dual new file mode 100644 index 0000000000..9a63cd420e --- /dev/null +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/70001_gz_atmos_dual @@ -0,0 +1,167 @@ +#!/bin/sh +# +# @name KTH-ATMOS +# +# @type Free-Flyer +# @class Spacecraft +# +# @output Motor1 back left thruster, +x thrust +# @output Motor2 front left thruster, -x thrust +# @output Motor3 back right thruster, +x thrust +# @output Motor4 front right thruster, -x thrust +# @output Motor5 front left thruster, +y thrust +# @output Motor6 front right thruster, -y thrust +# @output Motor7 back left thruster, +y thrust +# @output Motor8 back right thruster, -y thrust +# +# @maintainer discower-io +# @url https://atmos.discower.io +# + +. ${R}etc/init.d/rc.sc_defaults + +PX4_SIMULATOR=${PX4_SIMULATOR:=gz} +PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} +PX4_SIM_MODEL=${PX4_SIM_MODEL:=atmos_dual} + +param set-default SIM_GZ_EN 1 + +param set-default SENS_EN_MAGSIM 1 +param set-default COM_ARM_CHK_ESCS 0 # We don't have ESCs +param set-default FD_ESCS_EN 0 + +param set-default CA_AIRFRAME 14 +param set-default MAV_TYPE 45 + +param set-default CA_ROTOR_COUNT 8 +param set-default CA_R_REV 0 + +# Auto to be provided by Custom Airframe +param set-default CA_METHOD 0 + +# Set proper failsafes +param set-default COM_ACT_FAIL_ACT 0 +param set-default COM_LOW_BAT_ACT 0 +param set-default NAV_DLL_ACT 0 +param set-default GF_ACTION 1 +param set-default NAV_RCL_ACT 1 + +# disable attitude failure detection +param set-default FD_FAIL_P 0 +param set-default FD_FAIL_R 0 + +param set-default CA_ROTOR0_PX -0.12 +param set-default CA_ROTOR0_PY -0.12 +param set-default CA_ROTOR0_PZ 0.0 +param set-default CA_ROTOR0_CT 1.4 +param set-default CA_ROTOR0_AX 1.0 +param set-default CA_ROTOR0_AY 0.0 +param set-default CA_ROTOR0_AZ 0.0 + +param set-default CA_ROTOR1_PX 0.12 +param set-default CA_ROTOR1_PY -0.12 +param set-default CA_ROTOR1_PZ 0.0 +param set-default CA_ROTOR1_CT 1.4 +param set-default CA_ROTOR1_AX -1.0 +param set-default CA_ROTOR1_AY 0.0 +param set-default CA_ROTOR1_AZ 0.0 + +param set-default CA_ROTOR2_PX -0.12 +param set-default CA_ROTOR2_PY 0.12 +param set-default CA_ROTOR2_PZ 0.0 +param set-default CA_ROTOR2_CT 1.4 +param set-default CA_ROTOR2_AX 1.0 +param set-default CA_ROTOR2_AY 0.0 +param set-default CA_ROTOR2_AZ 0.0 + +param set-default CA_ROTOR3_PX 0.12 +param set-default CA_ROTOR3_PY 0.12 +param set-default CA_ROTOR3_PZ 0.0 +param set-default CA_ROTOR3_CT 1.4 +param set-default CA_ROTOR3_AX -1.0 +param set-default CA_ROTOR3_AY 0.0 +param set-default CA_ROTOR3_AZ 0.0 + +param set-default CA_ROTOR4_PX 0.12 +param set-default CA_ROTOR4_PY -0.12 +param set-default CA_ROTOR4_PZ 0.0 +param set-default CA_ROTOR4_CT 1.4 +param set-default CA_ROTOR4_AX 0.0 +param set-default CA_ROTOR4_AY 1.0 +param set-default CA_ROTOR4_AZ 0.0 + +param set-default CA_ROTOR5_PX 0.12 +param set-default CA_ROTOR5_PY 0.12 +param set-default CA_ROTOR5_PZ 0.0 +param set-default CA_ROTOR5_CT 1.4 +param set-default CA_ROTOR5_AX 0.0 +param set-default CA_ROTOR5_AY -1.0 +param set-default CA_ROTOR5_AZ 0.0 + +param set-default CA_ROTOR6_PX -0.12 +param set-default CA_ROTOR6_PY -0.12 +param set-default CA_ROTOR6_PZ 0.0 +param set-default CA_ROTOR6_CT 1.4 +param set-default CA_ROTOR6_AX 0.0 +param set-default CA_ROTOR6_AY 1.0 +param set-default CA_ROTOR6_AZ 0.0 + +param set-default CA_ROTOR7_PX -0.12 +param set-default CA_ROTOR7_PY 0.12 +param set-default CA_ROTOR7_PZ 0.0 +param set-default CA_ROTOR7_CT 1.4 +param set-default CA_ROTOR7_AX 0.0 +param set-default CA_ROTOR7_AY -1.0 +param set-default CA_ROTOR7_AZ 0.0 + +param set-default SIM_GZ_EC_FUNC1 101 +param set-default SIM_GZ_EC_FUNC2 102 +param set-default SIM_GZ_EC_FUNC3 103 +param set-default SIM_GZ_EC_FUNC4 104 +param set-default SIM_GZ_EC_FUNC5 105 +param set-default SIM_GZ_EC_FUNC6 106 +param set-default SIM_GZ_EC_FUNC7 107 +param set-default SIM_GZ_EC_FUNC8 108 +param set-default SIM_GZ_EC_FUNC9 301 +param set-default SIM_GZ_EC_FUNC10 302 +param set-default SIM_GZ_EC_FUNC11 303 +param set-default SIM_GZ_EC_FUNC12 304 + +param set-default SIM_GZ_EC_MIN1 0 +param set-default SIM_GZ_EC_MIN2 0 +param set-default SIM_GZ_EC_MIN3 0 +param set-default SIM_GZ_EC_MIN4 0 +param set-default SIM_GZ_EC_MIN5 0 +param set-default SIM_GZ_EC_MIN6 0 +param set-default SIM_GZ_EC_MIN7 0 +param set-default SIM_GZ_EC_MIN8 0 +param set-default SIM_GZ_EC_MIN9 1100 +param set-default SIM_GZ_EC_MIN10 1100 +param set-default SIM_GZ_EC_MIN11 1100 +param set-default SIM_GZ_EC_MIN12 1100 + +param set-default SIM_GZ_EC_MAX1 10000 +param set-default SIM_GZ_EC_MAX2 10000 +param set-default SIM_GZ_EC_MAX3 10000 +param set-default SIM_GZ_EC_MAX4 10000 +param set-default SIM_GZ_EC_MAX5 10000 +param set-default SIM_GZ_EC_MAX6 10000 +param set-default SIM_GZ_EC_MAX7 10000 +param set-default SIM_GZ_EC_MAX8 10000 +param set-default SIM_GZ_EC_MAX9 1900 +param set-default SIM_GZ_EC_MAX10 1900 +param set-default SIM_GZ_EC_MAX11 1900 +param set-default SIM_GZ_EC_MAX12 1900 + +# Controller Tunings +param set SC_YAWRATE_P 3.335 +param set SC_YAWRATE_I 0.87 +param set SC_YAWRATE_D 0.15 +param set SC_YR_INT_LIM 0.2 +param set SC_YAW_P 3.0 + +param set SPC_POS_P 0.20 +param set SPC_VEL_P 6.55 +param set SPC_VEL_I 0.0 +param set SPC_VEL_D 0.0 +param set SPC_VEL_MAX 12.0 diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt b/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt index b068b14aa1..a2e2a4d290 100644 --- a/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt +++ b/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt @@ -80,10 +80,8 @@ px4_add_romfs_files( 4009_gz_r1_rover 4010_gz_x500_mono_cam 4011_gz_lawnmower - 4012_gz_rover_ackermann 4013_gz_x500_lidar_2d 4014_gz_x500_mono_cam_down - 4015_gz_r1_rover_mecanum 4016_gz_x500_lidar_down 4017_gz_x500_lidar_front 4018_gz_quadtailsitter @@ -114,10 +112,13 @@ px4_add_romfs_files( 17002_flightgear_tf-g2 50000_gz_rover_differential + 51000_gz_rover_ackermann + 52000_gz_rover_mecanum 60002_gz_uuv_bluerov2_heavy 70000_gz_atmos + 70001_gz_atmos_dual # [22000, 22999] Reserve for custom models ) diff --git a/ROMFS/px4fmu_common/init.d-posix/px4-rc.gzsim b/ROMFS/px4fmu_common/init.d-posix/px4-rc.gzsim index ee24d195a7..5b4676e60e 100644 --- a/ROMFS/px4fmu_common/init.d-posix/px4-rc.gzsim +++ b/ROMFS/px4fmu_common/init.d-posix/px4-rc.gzsim @@ -159,24 +159,19 @@ if [ -n "${PX4_SIM_MODEL#*gz_}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ]; then fi # Set up camera to follow the model if requested - if [ -n "${PX4_GZ_FOLLOW}" ]; then + if [ -z "${PX4_GZ_NO_FOLLOW}" ]; then echo "INFO [init] Setting camera to follow ${MODEL_NAME_INSTANCE}" - # Set camera to follow the model - ${gz_command} service -s "/gui/follow" --reqtype gz.msgs.StringMsg \ - --reptype gz.msgs.Boolean --timeout 5000 \ - --req "data: \"${MODEL_NAME_INSTANCE}\"" > /dev/null 2>&1 - # Set default camera offset if not specified follow_x=${PX4_GZ_FOLLOW_OFFSET_X:--2.0} follow_y=${PX4_GZ_FOLLOW_OFFSET_Y:--2.0} follow_z=${PX4_GZ_FOLLOW_OFFSET_Z:-2.0} # Set camera offset - ${gz_command} service -s "/gui/follow/offset" --reqtype gz.msgs.Vector3d \ - --reptype gz.msgs.Boolean --timeout 5000 \ - --req "x: ${follow_x}, y: ${follow_y}, z: ${follow_z}" > /dev/null 2>&1 + ${gz_command} topic -t /gui/track -m gz.msgs.CameraTrack \ + -p "track_mode: FOLLOW, follow_target: {name: '${MODEL_NAME_INSTANCE}'},\ + follow_offset: {x: ${follow_x}, y: ${follow_y}, z: ${follow_z}}, follow_pgain: 1.0, track_pgain: 1.0" echo "INFO [init] Camera follow offset set to ${follow_x}, ${follow_y}, ${follow_z}" fi diff --git a/ROMFS/px4fmu_common/init.d-posix/rcS b/ROMFS/px4fmu_common/init.d-posix/rcS index bbbc55930c..0e443d30c4 100644 --- a/ROMFS/px4fmu_common/init.d-posix/rcS +++ b/ROMFS/px4fmu_common/init.d-posix/rcS @@ -126,15 +126,6 @@ then set AUTOCNF yes fi -# Allow overriding parameters via env variables: export PX4_PARAM_{name}={value} -env | while IFS='=' read -r line; do - value=${line#*=} - name=${line%%=*} - case $name in - "PX4_PARAM_"*) param set "${name#PX4_PARAM_}" "$value" ;; - esac -done - # multi-instance setup # shellcheck disable=SC2154 param set MAV_SYS_ID $((px4_instance+1)) @@ -173,7 +164,6 @@ param set-default COM_RC_IN_MODE 1 param set-default EKF2_REQ_GPS_H 0.5 param set-default IMU_GYRO_FFT_EN 1 -param set-default MAV_PROTO_VER 2 # Ensures QGC does not drop the first few packets after a SITL restart due to MAVLINK 1 packets param set-default -s MC_AT_EN 1 @@ -239,6 +229,15 @@ then exit 1 fi +# Allow overriding parameters via env variables: export PX4_PARAM_{name}={value} +env | while IFS='=' read -r line; do + value=${line#*=} + name=${line%%=*} + case $name in + "PX4_PARAM_"*) param set "${name#PX4_PARAM_}" "$value" ;; + esac +done + dataman start # only start the simulator if not in replay mode, as both control the lockstep time diff --git a/ROMFS/px4fmu_common/init.d/CMakeLists.txt b/ROMFS/px4fmu_common/init.d/CMakeLists.txt index 88c6be83a9..3c6cfb13f9 100644 --- a/ROMFS/px4fmu_common/init.d/CMakeLists.txt +++ b/ROMFS/px4fmu_common/init.d/CMakeLists.txt @@ -123,3 +123,9 @@ if(CONFIG_MODULES_TEMPERATURE_COMPENSATION) rc.thermal_cal ) endif() + +if(CONFIG_DRIVERS_VTXTABLE) + px4_add_romfs_files( + rc.vtxtable + ) +endif() diff --git a/ROMFS/px4fmu_common/init.d/airframes/1101_rc_plane_sih.hil b/ROMFS/px4fmu_common/init.d/airframes/1101_rc_plane_sih.hil index 2b54650a07..40e8110e04 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/1101_rc_plane_sih.hil +++ b/ROMFS/px4fmu_common/init.d/airframes/1101_rc_plane_sih.hil @@ -14,7 +14,6 @@ param set UAVCAN_ENABLE 0 -param set-default CA_AIRFRAME 1 param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d/airframes/17002_TF-AutoG2 b/ROMFS/px4fmu_common/init.d/airframes/17002_TF-AutoG2 index 7f85a770e1..8b431217d2 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/17002_TF-AutoG2 +++ b/ROMFS/px4fmu_common/init.d/airframes/17002_TF-AutoG2 @@ -18,6 +18,8 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board px4_fmu-v6x exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.fw_defaults @@ -40,8 +42,6 @@ param set-default FW_P_LIM_MAX 25 param set-default FW_P_LIM_MIN -5 param set-default FW_P_RMAX_NEG 20 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d/airframes/17003_TF-G2 b/ROMFS/px4fmu_common/init.d/airframes/17003_TF-G2 index 1907b33a32..0e4fca474b 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/17003_TF-G2 +++ b/ROMFS/px4fmu_common/init.d/airframes/17003_TF-G2 @@ -16,6 +16,8 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board px4_fmu-v6x exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.fw_defaults @@ -37,8 +39,6 @@ param set-default FW_P_LIM_MAX 25 param set-default FW_P_LIM_MIN -5 param set-default FW_P_RMAX_NEG 20 -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 diff --git a/ROMFS/px4fmu_common/init.d/airframes/2100_standard_plane b/ROMFS/px4fmu_common/init.d/airframes/2100_standard_plane index d872654722..e819c0ad4b 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/2100_standard_plane +++ b/ROMFS/px4fmu_common/init.d/airframes/2100_standard_plane @@ -10,7 +10,6 @@ . ${R}etc/init.d/rc.fw_defaults -param set-default CA_AIRFRAME 1 param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.3 param set-default CA_SV_CS_COUNT 4 diff --git a/ROMFS/px4fmu_common/init.d/airframes/2106_albatross b/ROMFS/px4fmu_common/init.d/airframes/2106_albatross index e27d146e03..6640dd5ea4 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/2106_albatross +++ b/ROMFS/px4fmu_common/init.d/airframes/2106_albatross @@ -32,7 +32,6 @@ param set-default FW_WR_IMAX 0.8 param set-default FW_WR_P 1 param set-default FW_W_RMAX 0 -param set-default CA_AIRFRAME 1 param set-default CA_ROTOR_COUNT 1 param set-default CA_SV_CS_COUNT 7 param set-default CA_SV_CS0_TRQ_R -0.5 diff --git a/ROMFS/px4fmu_common/init.d/airframes/3000_generic_wing b/ROMFS/px4fmu_common/init.d/airframes/3000_generic_wing index 6daab9cdac..8be0ee8d96 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/3000_generic_wing +++ b/ROMFS/px4fmu_common/init.d/airframes/3000_generic_wing @@ -10,8 +10,6 @@ . ${R}etc/init.d/rc.fw_defaults -param set-default CA_AIRFRAME 1 - param set-default CA_ROTOR_COUNT 1 param set-default CA_ROTOR0_PX 0.15 param set-default CA_SV_CS_COUNT 2 diff --git a/ROMFS/px4fmu_common/init.d/airframes/4016_holybro_px4vision b/ROMFS/px4fmu_common/init.d/airframes/4016_holybro_px4vision index 9b86703c31..1e699b5180 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4016_holybro_px4vision +++ b/ROMFS/px4fmu_common/init.d/airframes/4016_holybro_px4vision @@ -7,6 +7,8 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board px4_fmu-v6x exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.mc_defaults @@ -75,9 +77,6 @@ param set-default NAV_ACC_RAD 2 param set-default RTL_DESCEND_ALT 5 param set-default RTL_RETURN_ALT 5 -# Logging Parameters -param set-default SDLOG_PROFILE 131 - # Sensors Parameters param set-default SENS_CM8JL65_CFG 104 param set-default SENS_FLOW_MAXHGT 25 diff --git a/ROMFS/px4fmu_common/init.d/airframes/4017_nxp_hovergames b/ROMFS/px4fmu_common/init.d/airframes/4017_nxp_hovergames index 2cc60c5217..7830e5487e 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4017_nxp_hovergames +++ b/ROMFS/px4fmu_common/init.d/airframes/4017_nxp_hovergames @@ -7,6 +7,10 @@ # # @board px4_fmu-v2 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6s exclude +# @board ark_fmu-v6x exclude +# @board auterion_fmu-v6x exclude +# @board px4_fmu-v6x exclude # @board bitcraze_crazyflie exclude # # @maintainer Iain Galloway diff --git a/ROMFS/px4fmu_common/init.d/airframes/4020_holybro_px4vision_v1_5 b/ROMFS/px4fmu_common/init.d/airframes/4020_holybro_px4vision_v1_5 index c1b3c9a9ba..b134cabd6c 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4020_holybro_px4vision_v1_5 +++ b/ROMFS/px4fmu_common/init.d/airframes/4020_holybro_px4vision_v1_5 @@ -7,6 +7,7 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # @@ -77,9 +78,6 @@ param set-default NAV_ACC_RAD 2 param set-default RTL_DESCEND_ALT 5 param set-default RTL_RETURN_ALT 5 -# Logging Parameters -param set-default SDLOG_PROFILE 131 - # Sensors Parameters param set-default SENS_CM8JL65_CFG 202 param set-default SENS_FLOW_MAXHGT 25 diff --git a/ROMFS/px4fmu_common/init.d/airframes/4041_beta75x b/ROMFS/px4fmu_common/init.d/airframes/4041_beta75x index 5549255ec4..5dbd5ea3ee 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4041_beta75x +++ b/ROMFS/px4fmu_common/init.d/airframes/4041_beta75x @@ -13,6 +13,11 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6s exclude +# @board ark_fmu-v6x exclude +# @board auterion_fmu-v6x exclude +# @board px4_fmu-v6x exclude +# @board px4_fmu-v6xrt exclude # @board bitcraze_crazyflie exclude # diff --git a/ROMFS/px4fmu_common/init.d/airframes/4050_generic_250 b/ROMFS/px4fmu_common/init.d/airframes/4050_generic_250 index 22195b8457..625a879c49 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4050_generic_250 +++ b/ROMFS/px4fmu_common/init.d/airframes/4050_generic_250 @@ -29,9 +29,6 @@ param set-default MPC_MAN_TILT_MAX 60 param set-default THR_MDL_FAC 0.3 -# enable high-rate logging profile (helps with tuning) -param set-default SDLOG_PROFILE 19 - param set-default IMU_DGYRO_CUTOFF 50 param set-default IMU_GYRO_CUTOFF 90 diff --git a/ROMFS/px4fmu_common/init.d/airframes/4052_holybro_qav250 b/ROMFS/px4fmu_common/init.d/airframes/4052_holybro_qav250 index 4dc7f90aea..7ef37051e6 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4052_holybro_qav250 +++ b/ROMFS/px4fmu_common/init.d/airframes/4052_holybro_qav250 @@ -11,6 +11,8 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board px4_fmu-v6x exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.mc_defaults diff --git a/ROMFS/px4fmu_common/init.d/airframes/4053_holybro_kopis2 b/ROMFS/px4fmu_common/init.d/airframes/4053_holybro_kopis2 index 81e4b26d48..0afe99bfbe 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4053_holybro_kopis2 +++ b/ROMFS/px4fmu_common/init.d/airframes/4053_holybro_kopis2 @@ -9,6 +9,8 @@ # # @board px4_fmu-v2 exclude # @board bitcraze_crazyflie exclude +# @board px4_fmu-v6x exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.mc_defaults diff --git a/ROMFS/px4fmu_common/init.d/airframes/4061_atl_mantis_edu b/ROMFS/px4fmu_common/init.d/airframes/4061_atl_mantis_edu index fe40b95aa0..0d8ddaf2d8 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4061_atl_mantis_edu +++ b/ROMFS/px4fmu_common/init.d/airframes/4061_atl_mantis_edu @@ -10,6 +10,7 @@ # @board cuav_x7pro exclude # @board px4_fmu-v4pro exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # diff --git a/ROMFS/px4fmu_common/init.d/airframes/4071_ifo b/ROMFS/px4fmu_common/init.d/airframes/4071_ifo index 141ca861c4..25353b2a4c 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4071_ifo +++ b/ROMFS/px4fmu_common/init.d/airframes/4071_ifo @@ -12,6 +12,7 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # @board bitcraze_crazyflie exclude # @board cuav_x7pro exclude diff --git a/ROMFS/px4fmu_common/init.d/airframes/4073_ifo-s b/ROMFS/px4fmu_common/init.d/airframes/4073_ifo-s index 276e1b45db..ecc7ed5078 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4073_ifo-s +++ b/ROMFS/px4fmu_common/init.d/airframes/4073_ifo-s @@ -10,6 +10,7 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # @board bitcraze_crazyflie exclude # @board cuav_x7pro exclude diff --git a/ROMFS/px4fmu_common/init.d/airframes/4601_droneblocks_dexi_5 b/ROMFS/px4fmu_common/init.d/airframes/4601_droneblocks_dexi_5 index 38ffa06896..1d5b47608d 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4601_droneblocks_dexi_5 +++ b/ROMFS/px4fmu_common/init.d/airframes/4601_droneblocks_dexi_5 @@ -14,6 +14,7 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # @board bitcraze_crazyflie exclude # @board diatone_mamba-f405-mk2 exclude diff --git a/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21 b/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21 index 85b045e84a..3a69a846af 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21 +++ b/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21 @@ -13,6 +13,7 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board auterion_fmu-v6x exclude # @board px4_fmu-v6x exclude # @board diatone_mamba-f405-mk2 exclude # diff --git a/ROMFS/px4fmu_common/init.d/airframes/51002_nxp_b3rb b/ROMFS/px4fmu_common/init.d/airframes/51002_nxp_b3rb new file mode 100644 index 0000000000..09cf32a72e --- /dev/null +++ b/ROMFS/px4fmu_common/init.d/airframes/51002_nxp_b3rb @@ -0,0 +1,31 @@ +#!/bin/sh +# +# @name NXP B3RB Rover Ackermann +# +# @type Rover +# @class Rover +# +# @board px4_fmu-v2 exclude +# @board bitcraze_crazyflie exclude +# + +. ${R}etc/init.d/rc.rover_ackermann_defaults + +param set-default BAT1_N_CELLS 3 + +# Set geometry & output configration +param set-default PWM_MAIN_FUNC1 201 +param set-default PWM_MAIN_FUNC2 101 +param set-default PWM_MAIN_FUNC3 101 +param set-default PWM_MAIN_DIS1 1500 +param set-default PWM_MAIN_DIS2 0 +param set-default PWM_MAIN_DIS3 1500 +param set-default PWM_MAIN_MIN1 1000 +param set-default PWM_MAIN_MIN2 2500 +param set-default PWM_MAIN_MIN3 0 +param set-default PWM_MAIN_MAX1 2000 +param set-default PWM_MAIN_MAX2 2500 +param set-default PWM_MAIN_MAX3 50 +param set-default PWM_MAIN_TIM0 400 +param set-default PWM_MAIN_TIM1 400 +param set-default PWM_MAIN_TIM2 20000 diff --git a/ROMFS/px4fmu_common/init.d/airframes/60002_uuv_bluerov2_heavy b/ROMFS/px4fmu_common/init.d/airframes/60002_uuv_bluerov2_heavy index d397e5deae..7ad928367d 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/60002_uuv_bluerov2_heavy +++ b/ROMFS/px4fmu_common/init.d/airframes/60002_uuv_bluerov2_heavy @@ -45,7 +45,6 @@ param set-default COM_LOW_BAT_ACT 0 param set-default NAV_DLL_ACT 0 param set-default GF_ACTION 1 param set-default NAV_RCL_ACT 1 -param set-default COM_POSCTL_NAVL 2 # disable attitude failure detection param set-default FD_FAIL_P 0 diff --git a/ROMFS/px4fmu_common/init.d/airframes/6002_draco_r b/ROMFS/px4fmu_common/init.d/airframes/6002_draco_r index 531f0bc002..99b2be3e69 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/6002_draco_r +++ b/ROMFS/px4fmu_common/init.d/airframes/6002_draco_r @@ -12,7 +12,9 @@ # @board px4_fmu-v4pro exclude # @board px4_fmu-v5 exclude # @board px4_fmu-v5x exclude +# @board px4_fmu-v6x exclude # @board bitcraze_crazyflie exclude +# @board ark_fmu-v6x exclude # . ${R}etc/init.d/rc.mc_defaults diff --git a/ROMFS/px4fmu_common/init.d/airframes/70000_atmos b/ROMFS/px4fmu_common/init.d/airframes/70000_atmos index 0a7e809ad1..7cd7a6e743 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/70000_atmos +++ b/ROMFS/px4fmu_common/init.d/airframes/70000_atmos @@ -5,11 +5,24 @@ # @type Free-Flyer # @class Spacecraft # +# @output Motor1 back left thruster, +x thrust +# @output Motor2 front left thruster, -x thrust +# @output Motor3 back right thruster, +x thrust +# @output Motor4 front right thruster, -x thrust +# @output Motor5 front left thruster, +y thrust +# @output Motor6 front right thruster, -y thrust +# @output Motor7 back left thruster, +y thrust +# @output Motor8 back right thruster, -y thrust +# # @maintainer DISCOWER +# @url https://atmos.discower.io # . ${R}etc/init.d/rc.sc_defaults +# Overwrite DDS AG IP to `192.168.0.1` +param set-default UXRCE_DDS_AG_IP -1062731775 + param set-default CA_AIRFRAME 14 param set-default MAV_TYPE 45 @@ -25,7 +38,6 @@ param set-default COM_LOW_BAT_ACT 0 param set-default NAV_DLL_ACT 0 param set-default GF_ACTION 1 param set-default NAV_RCL_ACT 1 -param set-default COM_POSCTL_NAVL 2 # Set Mocap Vision frame param set EKF2_EV_CTRL 15 diff --git a/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt b/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt index 6728f842ce..8f13aa55b1 100644 --- a/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt +++ b/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt @@ -153,6 +153,7 @@ if(CONFIG_MODULES_ROVER_ACKERMANN) # [51000, 51999] Ackermann rovers 51000_generic_rover_ackermann 51001_axial_scx10_2_trail_honcho + 51002_nxp_b3rb ) endif() diff --git a/ROMFS/px4fmu_common/init.d/rc.fw_defaults b/ROMFS/px4fmu_common/init.d/rc.fw_defaults index 9d0db56e7c..b1cc06f200 100644 --- a/ROMFS/px4fmu_common/init.d/rc.fw_defaults +++ b/ROMFS/px4fmu_common/init.d/rc.fw_defaults @@ -10,6 +10,8 @@ set VEHICLE_TYPE fw # MAV_TYPE_FIXED_WING 1 param set-default MAV_TYPE 1 +param set-default CA_AIRFRAME 1 + # # Default parameters for fixed wing UAVs. # @@ -26,6 +28,7 @@ param set-default EKF2_MAG_ACCLIM 0 param set-default EKF2_REQ_EPH 10 param set-default EKF2_REQ_EPV 10 param set-default EKF2_REQ_HDRIFT 0.5 +param set-default EKF2_REQ_PDOP 4 param set-default EKF2_REQ_SACC 1 param set-default EKF2_REQ_VDRIFT 1 param set-default EKF2_RNG_QLTY_T 3 diff --git a/ROMFS/px4fmu_common/init.d/rc.mc_apps b/ROMFS/px4fmu_common/init.d/rc.mc_apps index adff4e963f..24a3f81ed7 100644 --- a/ROMFS/px4fmu_common/init.d/rc.mc_apps +++ b/ROMFS/px4fmu_common/init.d/rc.mc_apps @@ -41,3 +41,9 @@ if param compare -s MC_NN_EN 1 then mc_nn_control start fi + + +if param compare -s MC_RAPTOR_ENABLE 1 +then + mc_raptor start +fi diff --git a/ROMFS/px4fmu_common/init.d/rc.sc_defaults b/ROMFS/px4fmu_common/init.d/rc.sc_defaults index 0caa831cef..87bd5981a3 100644 --- a/ROMFS/px4fmu_common/init.d/rc.sc_defaults +++ b/ROMFS/px4fmu_common/init.d/rc.sc_defaults @@ -8,9 +8,6 @@ set VEHICLE_TYPE spacecraft # MAV_TYPE_SPACECRAFT_ORBITTER param set-default MAV_TYPE 45 -# Set micro-dds-client to use ethernet and IP-address 192.168.0.1 -param set-default UXRCE_DDS_AG_IP -1062731775 - # Disable preflight disarm to not interfere with external launching param set-default COM_DISARM_PRFLT -1 param set-default CBRK_SUPPLY_CHK 894281 diff --git a/ROMFS/px4fmu_common/init.d/rc.sensors b/ROMFS/px4fmu_common/init.d/rc.sensors index b88a0d334e..ea6b8d4f1e 100644 --- a/ROMFS/px4fmu_common/init.d/rc.sensors +++ b/ROMFS/px4fmu_common/init.d/rc.sensors @@ -154,6 +154,12 @@ then fi fi +# Microchip MCP9808 temperature sensor external I2C +if param compare -s SENS_EN_MCP9808 1 +then + mcp9808 start -X +fi + # TE MS4515 differential pressure sensor external I2C if param compare -s SENS_EN_MS4515 1 then @@ -219,6 +225,24 @@ then pcf8583 start -X -a 0x51 fi +# ADC sensor ADS7953 external SPI +if param compare -s ADC_ADS7953_EN 1 +then + ads7953 start -S +fi + +# ADC sensor tla2528 external I2C +if param compare -s ADC_TLA2528_EN 1 +then + tla2528 start -X +fi + +# Start TMP102 temperature sensor +if param compare SENS_EN_TMP102 1 +then + tmp102 start -X +fi + # probe for optional external I2C devices if param compare SENS_EXT_I2C_PRB 1 then @@ -237,6 +261,7 @@ then qmc5883p -X -q start rm3100 -X -q start bmm350 -X -q start + iis2mdc -X -q start # start last (wait for possible icm20948 passthrough mode) ak09916 -X -q start diff --git a/ROMFS/px4fmu_common/init.d/rc.vtxtable b/ROMFS/px4fmu_common/init.d/rc.vtxtable new file mode 100644 index 0000000000..70792b4caf --- /dev/null +++ b/ROMFS/px4fmu_common/init.d/rc.vtxtable @@ -0,0 +1,8 @@ +#!/bin/sh +# +# VTX table loading script. +# +# NOTE: Script variables are declared/initialized/unset in the rcS script. +# + +vtxtable load diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS index f747966e03..80749fbe8c 100644 --- a/ROMFS/px4fmu_common/init.d/rcS +++ b/ROMFS/px4fmu_common/init.d/rcS @@ -228,30 +228,26 @@ else fi unset BOARD_RC_ADDITIONAL_INIT - # Load airframe configuration based on SYS_AUTOSTART parameter - if ! param compare SYS_AUTOSTART 0 + # Load airframe configuration based on SYS_AUTOSTART parameter if successful VEHICLE_TYPE gets set + # Run autogenerated ROMFS airframe script + . ${R}etc/init.d/rc.autostart + + if [ ${VEHICLE_TYPE} = none ] then - # rc.autostart directly run the right airframe script which sets the VEHICLE_TYPE - # Look for airframe in ROMFS - . ${R}etc/init.d/rc.autostart - - if [ ${VEHICLE_TYPE} = none ] + # Run external airframe script on SD card + if [ $STORAGE_AVAILABLE = yes ] then - # Use external startup file - if [ $STORAGE_AVAILABLE = yes ] - then - . ${R}etc/init.d/rc.autostart_ext - else - echo "ERROR [init] SD card not mounted - can't load external airframe" - fi + . ${R}etc/init.d/rc.autostart_ext + else + echo "ERROR [init] SD not mounted, skipping external airframe" fi + fi - if [ ${VEHICLE_TYPE} = none ] - then - echo "ERROR [init] No airframe file found for SYS_AUTOSTART value" - param set SYS_AUTOSTART 0 - tune_control play error - fi + if [ ${VEHICLE_TYPE} = none ] + then + echo "ERROR [init] No airframe file found for SYS_AUTOSTART value" + param set SYS_AUTOSTART 0 + tune_control play error fi # Check parameter version and reset upon airframe configuration version mismatch. @@ -483,6 +479,19 @@ else pwm_out start fi + # + # Optional UAVCAN/DroneCAN or Cyphal + # + if param greater -s UAVCAN_ENABLE 0 + then + uavcan start + else + if param greater -s CYPHAL_ENABLE 0 + then + cyphal start + fi + fi + # # Configure vehicle type specific parameters. # Note: rc.vehicle_setup is the entry point for all vehicle type specific setup. @@ -511,6 +520,11 @@ else # . ${R}etc/init.d/rc.serial + if param greater -s ZENOH_ENABLE 0 + then + zenoh start + fi + # Must be started after the serial config is read rc_input start $RC_INPUT_ARGS @@ -616,6 +630,16 @@ else fi unset RC_LOGGING + # + # Start the VTX services. + # + set RC_VTXTABLE ${R}etc/init.d/rc.vtxtable + if [ -f ${RC_VTXTABLE} ] + then + . ${RC_VTXTABLE} + fi + unset RC_VTXTABLE + # # Set additional parameters and env variables for selected AUTOSTART. # @@ -632,27 +656,6 @@ else fi unset BOARD_BOOTLOADER_UPGRADE - # - # Check if UAVCAN is enabled, default to it for ESCs. - # - if param greater -s UAVCAN_ENABLE 0 - then - # Start core UAVCAN module. - if ! uavcan start - then - tune_control play error - fi - else - if param greater -s CYPHAL_ENABLE 0 - then - cyphal start - fi - fi - if param greater -s ZENOH_ENABLE 0 - then - zenoh start - fi - # # End of autostart. # diff --git a/Tools/astyle/astylerc b/Tools/astyle/astylerc index efdc279ca9..3d1b437ef3 100644 --- a/Tools/astyle/astylerc +++ b/Tools/astyle/astylerc @@ -15,4 +15,4 @@ ignore-exclude-errors-x lineend=linux exclude=EASTL add-brackets -max-code-length=120 +max-code-length=140 diff --git a/Tools/astyle/files_to_check_code_style.sh b/Tools/astyle/files_to_check_code_style.sh index 4ab53874a2..b70766efa2 100755 --- a/Tools/astyle/files_to_check_code_style.sh +++ b/Tools/astyle/files_to_check_code_style.sh @@ -21,11 +21,13 @@ exec find boards msg src platforms test \ -path src/lib/crypto/monocypher -prune -o \ -path src/lib/events/libevents -prune -o \ -path src/lib/parameters/uthash -prune -o \ + -path src/lib/rl_tools/rl_tools -prune -o \ -path src/lib/wind_estimator/python/generated -prune -o \ -path src/modules/ekf2/EKF/python/ekf_derivation/generated -prune -o \ -path src/modules/ekf2/EKF/yaw_estimator/derivation/generated -prune -o \ -path src/modules/gyro_fft/CMSIS_5 -prune -o \ -path src/modules/mavlink/mavlink -prune -o \ + -path src/modules/mc_raptor/blob -prune -o \ -path test/fuzztest -prune -o \ -path test/mavsdk_tests/catch2 -prune -o \ -path src/lib/crypto/monocypher -prune -o \ @@ -39,4 +41,5 @@ exec find boards msg src platforms test \ -path boards/modalai/voxl2/libfc-sensor-api -prune -o \ -path src/drivers/actuators/vertiq_io/iq-module-communication-cpp -prune -o \ -path src/lib/tensorflow_lite_micro/tflite_micro -prune -o \ + -path src/drivers/ins/sbgecom/sbgECom -prune -o \ \( -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print \) | grep $PATTERN diff --git a/Tools/auterion/remote_update_fmu.sh b/Tools/auterion/remote_update_fmu.sh index 2eeb66b999..d3777aebaf 100755 --- a/Tools/auterion/remote_update_fmu.sh +++ b/Tools/auterion/remote_update_fmu.sh @@ -7,6 +7,7 @@ fi ssh_port=22 ssh_user=root +ssh_opts="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" while getopts ":f:c:d:p:u:r" opt; do case ${opt} in @@ -67,7 +68,7 @@ target_file_name="update-dev.tar" if [ "$revert" == true ]; then # revert to the release version which was originally deployed cmd="cp $target_dir/update.tar $target_dir/$target_file_name" - ssh -t -p $ssh_port $ssh_user@$device "$cmd" + ssh $ssh_opts -t -p $ssh_port $ssh_user@$device "$cmd" else # create custom update-dev.tar tmp_dir="$(mktemp -d)" @@ -105,11 +106,11 @@ else $tar_name -C "$tmp_dir" --sort=name --owner=root:0 --group=root:0 --mtime='2019-01-01 00:00:00' -cvf $target_file_name $firmware_path $config_path # send it to the target to start flashing - scp -P $ssh_port "$target_file_name" $ssh_user@"$device":$target_dir + scp $ssh_opts -P $ssh_port "$target_file_name" $ssh_user@"$device":$target_dir popd &>/dev/null rm -rf "$tmp_dir" fi # grab status output for flashing progress cmd="tail --follow=name $target_dir/update_status 2>/dev/null || true" -ssh -t -p $ssh_port $ssh_user@$device "$cmd" +ssh $ssh_opts -t -p $ssh_port $ssh_user@$device "$cmd" diff --git a/Tools/check_submodules.sh b/Tools/check_submodules.sh index 1931deb9a3..bd92940ab7 100755 --- a/Tools/check_submodules.sh +++ b/Tools/check_submodules.sh @@ -17,37 +17,12 @@ if [[ -f $1"/.git" || -d $1"/.git" ]]; then SUBMODULE_STATUS=$(git submodule summary "$1") STATUSRETVAL=$(echo $SUBMODULE_STATUS | grep -A20 -i "$1") if ! [[ -z "$STATUSRETVAL" ]]; then - echo -e "\033[31mChecked $1 submodule, ACTION REQUIRED:\033[0m" - echo "" - echo -e "Different commits:" + echo -e "\033[33mWarning: $1 submodule has uncommitted changes:\033[0m" echo -e "$SUBMODULE_STATUS" echo "" + echo -e "To update submodules to the expected version, run:" + echo -e " \033[94mgit submodule sync --recursive && git submodule update --init --recursive\033[0m" echo "" - echo -e " *******************************************************************************" - echo -e " * \033[31mIF YOU DID NOT CHANGE THIS FILE (OR YOU DON'T KNOW WHAT A SUBMODULE IS):\033[0m *" - echo -e " * \033[31mHit 'u' and to update ALL submodules and resolve this.\033[0m *" - echo -e " * (performs \033[94mgit submodule sync --recursive\033[0m *" - echo -e " * and \033[94mgit submodule update --init --recursive\033[0m ) *" - echo -e " *******************************************************************************" - echo "" - echo "" - echo -e " Only for EXPERTS:" - echo -e " $1 submodule is not in the recommended version." - echo -e " Hit 'y' and to continue the build with this version. Hit to resolve manually." - echo -e " Use \033[94mgit add $1 && git commit -m 'Updated $1'\033[0m to choose this version (careful!)" - echo "" - read user_cmd - if [ "$user_cmd" == "y" ]; then - echo "Continuing build with manually overridden submodule.." - elif [ "$user_cmd" == "u" ]; then - git submodule sync --recursive -- $1 - git submodule update --init --recursive -- $1 || true - git submodule update --init --recursive --force -- $1 - echo "Submodule fixed, continuing build.." - else - echo "Build aborted." - exit 1 - fi fi else git submodule --quiet sync --recursive --quiet -- $1 diff --git a/Tools/ci/generate_board_targets_json.py b/Tools/ci/generate_board_targets_json.py index ceb412e2ec..214edd8186 100755 --- a/Tools/ci/generate_board_targets_json.py +++ b/Tools/ci/generate_board_targets_json.py @@ -25,22 +25,31 @@ parser.add_argument('-p', '--pretty', dest='pretty', action='store_true', help='Pretty output instead of a single line') parser.add_argument('-g', '--groups', dest='group', action='store_true', help='Groups targets') -parser.add_argument('-f', '--filter', dest='filter', help='comma separated list of board names to use instead of all') +parser.add_argument('-f', '--filter', dest='filter', help='comma separated list of build target name prefixes to include instead of all e.g. "px4_fmu-v5_"') args = parser.parse_args() verbose = args.verbose -board_filter = [] +target_filter = [] if args.filter: - for board in args.filter.split(','): - board_filter.append(board) + for target in args.filter.split(','): + 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'): @@ -144,7 +166,7 @@ for manufacturer in os.scandir(os.path.join(source_dir, '../boards')): label = files.name[:-9] target_name = manufacturer.name + '_' + board.name + '_' + label - if board_filter and not board_name in board_filter: + if target_filter and not any(target_name.startswith(f) for f in target_filter): if verbose: print(f'excluding board {board_name} ({target_name})') continue @@ -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 = [] diff --git a/Tools/ci/metadata_sync.sh b/Tools/ci/metadata_sync.sh new file mode 100755 index 0000000000..17d5017554 --- /dev/null +++ b/Tools/ci/metadata_sync.sh @@ -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 "$@" diff --git a/Tools/ci/package_build_artifacts.sh b/Tools/ci/package_build_artifacts.sh index f5ebb73fa0..aaf978b19f 100755 --- a/Tools/ci/package_build_artifacts.sh +++ b/Tools/ci/package_build_artifacts.sh @@ -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#*/} diff --git a/Tools/ci/test_metadata_sync.sh b/Tools/ci/test_metadata_sync.sh new file mode 100755 index 0000000000..55dbc64a72 --- /dev/null +++ b/Tools/ci/test_metadata_sync.sh @@ -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 "$@" diff --git a/Tools/docker_run.sh b/Tools/docker_run.sh index 34d08d16f1..773c8992eb 100755 --- a/Tools/docker_run.sh +++ b/Tools/docker_run.sh @@ -1,47 +1,27 @@ #! /bin/bash if [ -z ${PX4_DOCKER_REPO+x} ]; then - echo "guessing PX4_DOCKER_REPO based on input"; - if [[ $@ =~ .*clang.* ]] || [[ $@ =~ .*scan-build.* ]]; then - # clang tools - PX4_DOCKER_REPO="px4io/px4-dev-clang:2021-02-04" - elif [[ $@ =~ .*tests* ]]; then - # run all tests with simulation - PX4_DOCKER_REPO="px4io/px4-dev-simulation-bionic:2021-12-11" - fi + PX4_DOCKER_REPO="px4io/px4-dev:v1.17.0-beta1" else echo "PX4_DOCKER_REPO is set to '$PX4_DOCKER_REPO'"; fi -# otherwise default to nuttx -if [ -z ${PX4_DOCKER_REPO+x} ]; then - PX4_DOCKER_REPO="px4io/px4-dev:v1.16.0-rc1-258-g0369abd556" -fi - echo "PX4_DOCKER_REPO: $PX4_DOCKER_REPO"; -PWD=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -SRC_DIR=$PWD/../ +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +SRC_DIR=${SCRIPT_DIR}/../ CCACHE_DIR=${HOME}/.ccache mkdir -p "${CCACHE_DIR}" docker run -it --rm -w "${SRC_DIR}" \ --user="$(id -u):$(id -g)" \ - --env=AWS_ACCESS_KEY_ID \ - --env=AWS_SECRET_ACCESS_KEY \ - --env=BRANCH_NAME \ --env=CCACHE_DIR="${CCACHE_DIR}" \ - --env=CI \ - --env=CODECOV_TOKEN \ - --env=COVERALLS_REPO_TOKEN \ --env=PX4_ASAN \ --env=PX4_MSAN \ --env=PX4_TSAN \ --env=PX4_UBSAN \ - --env=TRAVIS_BRANCH \ - --env=TRAVIS_BUILD_ID \ --publish 14556:14556/udp \ --volume=${CCACHE_DIR}:${CCACHE_DIR}:rw \ --volume=${SRC_DIR}:${SRC_DIR}:rw \ - ${PX4_DOCKER_REPO} /bin/bash -c "$1 $2 $3" + ${PX4_DOCKER_REPO} /bin/bash -c "$@" diff --git a/Tools/mavlink_shell.py b/Tools/mavlink_shell.py index 7dd3675bc1..80ecdfaa45 100755 --- a/Tools/mavlink_shell.py +++ b/Tools/mavlink_shell.py @@ -191,7 +191,7 @@ def main(): cur_history_index = len(command_history) mav_serialport.write(cur_line+'\n') cur_line = '' - elif ord(ch) == 127: # backslash + elif ord(ch) == 8: # backspace if len(cur_line) > 0: erase_last_n_chars(1) cur_line = cur_line[:-1] diff --git a/Tools/module_config/generate_actuators_metadata.py b/Tools/module_config/generate_actuators_metadata.py index 196119259b..5d38ecf499 100755 --- a/Tools/module_config/generate_actuators_metadata.py +++ b/Tools/module_config/generate_actuators_metadata.py @@ -238,6 +238,7 @@ def get_actuator_output(yaml_config, output_functions, timer_config_file, verbos ( 'disarmed', 'Disarmed', 'DIS', False ), ( 'min', 'Minimum', 'MIN', False ), ( 'max', 'Maximum', 'MAX', False ), + ( 'center', 'Center\n(for Servos)', 'CENT', False ), ( 'failsafe', 'Failsafe', 'FAIL', True ), ] for key, label, param_suffix, advanced in standard_params_array: diff --git a/Tools/module_config/generate_params.py b/Tools/module_config/generate_params.py index 92b2593656..ecc29a4519 100755 --- a/Tools/module_config/generate_params.py +++ b/Tools/module_config/generate_params.py @@ -284,6 +284,9 @@ Note that non-motor outputs might already be active in prearm state if COM_PREAR ''' minimum_description = \ '''Minimum output value (when not disarmed). +''' + center_description = \ +'''Servo Center output value (when not disarmed). ''' maximum_description = \ '''Maxmimum output value (when not disarmed). @@ -296,6 +299,7 @@ When set to -1 (default), the value depends on the function (see {:}). standard_params_array = [ ( 'disarmed', 'Disarmed', 'DIS', disarmed_description ), ( 'min', 'Minimum', 'MIN', minimum_description ), + ( 'center', 'Center', 'CENT', center_description ), ( 'max', 'Maximum', 'MAX', maximum_description ), ( 'failsafe', 'Failsafe', 'FAIL', failsafe_description ), ] @@ -312,6 +316,10 @@ When set to -1 (default), the value depends on the function (see {:}). standard_params[key]['default'] = -1 standard_params[key]['min'] = -1 + if key == 'center': + standard_params[key]['default'] = -1 + standard_params[key]['min'] = -1 + param = { 'description': { 'short': channel_label+' ${i} '+label+' Value', diff --git a/Tools/msg/generate_msg_docs.py b/Tools/msg/generate_msg_docs.py index 18308aed9c..35827f4a44 100755 --- a/Tools/msg/generate_msg_docs.py +++ b/Tools/msg/generate_msg_docs.py @@ -8,6 +8,803 @@ Also generates docs/en/middleware/dds_topics.md from dds_topics.yaml import os import argparse import sys +import re + +VALID_FIELDS = { #Note, also have to add the message types as those can be fields + 'uint64', + 'uint16', + 'uint8', + 'uint32' +} + +ALLOWED_UNITS = set(["m", "m/s", "m/s^2", "(m/s)^2", "deg", "deg/s", "rad", "rad/s", "rad^2", "rpm" ,"V", "A", "mA", "mAh", "W", "dBm", "h", "s", "ms", "us", "Ohm", "MB", "Kb/s", "degC","Pa","%","-"]) +invalid_units = set() +ALLOWED_FRAMES = set(["NED","Body"]) +ALLOWED_INVALID_VALUES = set(["NaN", "0"]) +ALLOWED_CONSTANTS_NOT_IN_ENUM = set(["ORB_QUEUE_LENGTH","MESSAGE_VERSION"]) + +class Error: + def __init__(self, type, message, linenumber=None, issueString = None, field = None): + self.type = type + self.message = message + self.linenumber = linenumber + self.issueString = issueString + self.field = field + + def display_error(self): + #print(f"Debug: Error: display_error") + + + if 'trailing_whitespace' == self.type: + if self.issueString.strip(): + print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber}): {self.issueString}") + else: + print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber})") + elif 'leading_whitespace_field_or_constant' == self.type: + print(f"NOTE: Whitespace before field or constant ({self.message}: {self.linenumber}): {self.issueString}") + elif 'field_or_constant_has_multiple_whitepsace' == self.type: + print(f"NOTE: Field/constant has more than one sequential whitespace character ({self.message}: {self.linenumber}): {self.issueString}") + elif 'empty_start_line' == self.type: + print(f"NOTE: Empty line at start of file ({self.message}: {self.linenumber})") + elif 'internal_comment' == self.type: + print(f"NOTE: Internal Comment ({self.message}: {self.linenumber})\n {self.issueString}") + elif 'internal_comment_empty' == self.type: + print(f"NOTE: Empty Internal Comment ({self.message}: {self.linenumber})") + elif 'summary_missing' == self.type: + print(f"WARNING: No message description ({self.message})") + elif 'topic_error' == self.type: + print(f"NOTE: TOPIC ISSUE: {self.issueString}") + elif 'unknown_unit' == self.type: + print(f"WARNING: Unknown Unit: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'constant_not_in_assigned_enum' == self.type: + print(f"WARNING: `{self.issueString}` constant: Prefix not in `@enum` field metadata ({self.message}: {self.linenumber})") + elif 'unknown_invalid_value' == self.type: + print(f"WARNING: Unknown @invalid value: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'unknown_frame' == self.type: + print(f"WARNING: Unknown @frame: [{self.issueString}] on `{self.field}` ({self.message}: {self.linenumber})") + elif 'command_no_params_pipes' == self.type: + print(f"WARNING: `{self.field}` command has no parameters (pipes): [{self.issueString}] ({self.message}: {self.linenumber})") + elif 'command_missing_params' == self.type: + print(f"WARNING: `{self.field}` command missing params - should be 7 params surrounded by 8 pipes: [{self.issueString}] ({self.message}: {self.linenumber})") + elif 'command_too_many_params' == self.type: + print(f"WARNING: `{self.field}` command too many params (should be 7). Extras: [{self.issueString}] ({self.message}: {self.linenumber})") + + + else: + self.display_info() + + def display_info(self): + """ + Display info about an error. + Used as a fallback if error does not have specific printout in display_error() + """ + #print(f"Debug: Error: display_info") + print(f" type: {self.type}, message: {self.message}, linenumber: {self.linenumber}, issueString: {self.issueString}, field: {self.field}") + +class Enum: + def __init__(self, name, parentMessage): + self.name = name + self.parent = parentMessage + self.enumValues = dict() + + def display_info(self): + """ + Display info about an enum + """ + print(f"Debug: Enum: display_info") + print(f" name: {self.name}") + for key, value in self.enumValues.items(): + value.display_info() + +class ConstantValue: + def __init__(self, name, type, value, comment, line_number): + self.name = name.strip() + self.type = type.strip() + self.value = value.strip() + self.comment = comment + self.line_number = line_number + + if not self.value: + print(f"Debug WARNING: NO VALUE in ConstantValue: {self.name}") ## TODO make into ERROR + exit() + + # TODO if value or name are empty, error + + def display_info(self): + print(f"Debug: ConstantValue: display_info") + print(f" name: {self.name}, type: {self.type}, value: {self.value}, comment: {self.comment}, line: {self.line_number}") + + +class CommandParam: + """ + Represents an individual param in a command constant + Encapsulates parsing of the param to extract units etc. + """ + + def __init__(self, num, paramText, line_number, parentCommand): + self.paramNum = num + self.paramText = paramText.strip() + self.enum = None + self.range = None + #self.type = type + self.units = [] + self.enums = [] + self.minValue = None + self.maxValue = None + self.invalidValue = None + self.frameValue = None + self.lineNumber = line_number + self.parent = parentCommand + self.parentMessage = self.parent.parent + + match = None + if self.paramText: + match = re.match(r'^((?:\[[^\]]*\]\s*)+)(.*)$', paramText) + self.description = paramText + bracketed_part = None + if match: + bracketed_part = match.group(1).strip() # .strip() removes trailing whitespace from the bracketed part + self.description = match.group(2).strip() + if bracketed_part: + # get units + bracket_content_matches = re.findall(r'\[(.*?)\]', bracketed_part) + #print(f"DEBUG: bracket_content_matches: {bracket_content_matches}") + for item in bracket_content_matches: + item = item.strip() + if item.startswith('@'): # Not a unit: + if item.startswith('@enum'): + item = item.split(" ") + enum = item[1].strip() + if enum and enum not in self.enums: + self.enums.append(enum) + + # Create parent enum objects for any enums created in this step + for enumName in self.enums: + if not enumName in self.parentMessage.enums: + self.parentMessage.enums[enumName]=Enum(enumName,self.parentMessage) + + elif item.startswith('@range'): + item = item[6:].strip().split(",") + self.range = item + self.minValue = item[0].strip() + self.maxValue = item[1].strip() + elif item.startswith('@invalid'): + self.invalidValue = item[8:].strip() + #TODO: Do we require a description? (not currently) + if self.invalidValue.split(" ")[0] not in ALLOWED_INVALID_VALUES: + print(f"TODO: Command param do not support @invalid: {self.invalidValue}") + """ + error = Error("unknown_invalid_value", self.parent.filename, self.lineNumber, self.invalidValue, self.name) + #error.display_error() + if not "unknown_invalid_value" in self.parent.errors: + self.parent.errors["unknown_invalid_value"] = [] + self.parent.errors["unknown_invalid_value"].append(error) + """ + + elif item.startswith('@frame'): + self.frameValue = item[6:].strip() + print(f"TODO: Command param do not support @frame: {self.frameValue}") + """ + if self.frameValue not in ALLOWED_FRAMES: + error = Error("unknown_frame", self.parent.filename, self.lineNumber, self.frameValue, self.name) + #error.display_error() + if not "unknown_frame" in self.parent.errors: + self.parent.errors["unknown_frame"] = [] + self.parent.errors["unknown_frame"].append(error) + """ + else: + print(f"WARNING: Unhandled metadata in message comment: {item}") + # TODO - report errors for different kinds of metadata + exit() + + else: # bracket is a unit + unit = item.strip() + + if item == "-": + unit = "" + + if unit and unit not in self.units: + self.units.append(unit) + + if unit not in ALLOWED_UNITS: + invalid_units.add(unit) + error = Error("unknown_unit", self.parentMessage.filename, self.lineNumber, unit, self.parent.name) + #error.display_error() + if not "unknown_unit" in self.parentMessage.errors: + self.parentMessage.errors["unknown_unit"] = [] + self.parentMessage.errors["unknown_unit"].append(error) + + + def display_info(self): + print(f"Debug: CommandParam: display_info") + print(f" id: {self.paramNum}") + print(f" paramText: {self.paramText}\n unit: {self.units}\n enums: {self.enums}\n lineNumber: {self.lineNumber}\n range: {self.range}\n minValue: {self.minValue}\n maxValue: {self.maxValue}\n invalidValue: {self.invalidValue}\n frameValue: {self.frameValue}\n parent: {self.parent}\n ") + + + +class CommandConstant: + """ + Represents a constant that is a command definition. + Encapsulates parsing of the command format. + The individual params are further parsed in CommandParam + """ + def __init__(self, name, type, value, comment, line_number, parentMessage): + self.name = name.strip() + self.type = type.strip() + self.value = value.strip() + self.comment = comment + self.line_number = line_number + self.parent = parentMessage + + self.description = self.comment + self.param1 = None + self.param2 = None + self.param3 = None + self.param4 = None + self.param5 = None + self.param6 = None + self.param7 = None + + if not self.value: + print(f"Debug WARNING: NO VALUE in CommandConstant: {self.name}") ## TODO make into ERROR + exit() + + if not self.comment: # This is an bug for a command + #print(f"Debug WARNING: NO COMMENT in CommandConstant: {self.name}") ## TODO make into ERROR + return + + # Parse command comment to get the description and parameters. + # print(f"Debug CommandConstant: {self.comment}") + if not "|" in self.comment: + # This is an error for a command constant + error = Error("command_no_params_pipes", self.parent.filename, self.line_number, self.comment, self.name) + #error.display_error() + if not "command_no_params_pipes" in self.parent.errors: + self.parent.errors["command_no_params_pipes"] = [] + self.parent.errors["command_no_params_pipes"].append(error) + return + + # Split on pipes + commandSplit = self.comment.split("|") + if len(commandSplit) < 9: + # Should 7 pipes, so each command is fully surrounded + error = Error("command_missing_params", self.parent.filename, self.line_number, self.comment, self.name) + #error.display_error() + if not "command_missing_params" in self.parent.errors: + self.parent.errors["command_missing_params"] = [] + self.parent.errors["command_missing_params"].append(error) + + self.description = commandSplit[0].strip() + self.description = self.description if self.description else None + + params_to_update = commandSplit[1:8] + + for i, value in enumerate(params_to_update, start=1): + if value.strip(): + # parse the param + param = CommandParam(i, value, self.line_number, self) + #param.display_info() # DEBUG CODE XXX + setattr(self, f"param{i}", param) + # parse the param + + if len(commandSplit) > 8: + extras = commandSplit[8:] + error = Error("command_too_many_params", self.parent.filename, self.line_number, extras, self.name) + if not "command_too_many_params" in self.parent.errors: + self.parent.errors["command_too_many_params"] = [] + self.parent.errors["command_too_many_params"].append(error) + + + # TODO if value or name are empty, error + + def markdown_out(self): + #print("DEBUG: CommandConstant.markdown_out") + output = f"""### {self.name} ({self.value}) + +{self.description} + +Param | Units | Range/Enum | Description +--- | --- | --- | --- +""" + for i in range(1, 8): + attr_name = f"param{i}" + # getattr returns None if the attribute doesn't exist + val = getattr(self, attr_name, None) + + if val is not None: + rangeVal = "" + if val.minValue or val.maxValue: + rangeVal = f"[{val.minValue if val.minValue else '-'} : {val.maxValue if val.maxValue else '-' }]" + + output+=f"{i} | {", ".join(val.units)}|{', '.join(f"[{e}](#{e})" for e in val.enums)}{rangeVal} | {val.description}\n" + else: + output+=f"{i} | | | ?\n" + + output+=f"\n" + return output + + + def display_info(self): + print(f"Debug: CommandConstant: display_info") + print(f" name: {self.name}, type: {self.type}, value: {self.value}, comment: {self.comment}, line: {self.line_number}") + print(f" description: {self.description}\n param1: {self.param1}\n param2: {self.param2}\n param3: {self.param3}\n param4: {self.param4}\n param5: {self.param5}\n param6: {self.param6}\n param7: {self.param7}") + +class MessageField: + """ + Represents a field. + Encapsulates parsing of the field information. + """ + def __init__(self, name, type, comment, line_number, parentMessage): + self.name = name + self.type = type + self.comment = comment + self.unit = None + self.enums = None + self.minValue = None + self.maxValue = None + self.invalidValue = None + self.frameValue = None + self.lineNumber = line_number + self.parent = parentMessage + + #print(f"MessageComment: {comment}") + match = None + if self.comment: + match = re.match(r'^((?:\[[^\]]*\]\s*)+)(.*)$', comment) + self.description = comment + bracketed_part = None + if match: + bracketed_part = match.group(1).strip() # .strip() removes trailing whitespace from the bracketed part + self.description = match.group(2).strip() + if bracketed_part: + # get units + bracket_content_matches = re.findall(r'\[(.*?)\]', bracketed_part) + #print(f"bracket_content_matches: {bracket_content_matches}") + for item in bracket_content_matches: + item = item.strip() + if item.startswith('@'): # Not a unit: + if item.startswith('@enum'): + item = item.split(" ") + self.enums = item[1:] + # Create parent enum objects + for enumName in self.enums: + if not enumName in parentMessage.enums: + parentMessage.enums[enumName]=Enum(enumName,parentMessage) + elif item.startswith('@range'): + item = item[6:].strip().split(",") + self.minValue = item[0].strip() + self.maxValue = item[1].strip() + elif item.startswith('@invalid'): + self.invalidValue = item[8:].strip() + #TODO: Do we require a description? (not currently) + if self.invalidValue.split(" ")[0] not in ALLOWED_INVALID_VALUES: + error = Error("unknown_invalid_value", self.parent.filename, self.lineNumber, self.invalidValue, self.name) + #error.display_error() + if not "unknown_invalid_value" in self.parent.errors: + self.parent.errors["unknown_invalid_value"] = [] + self.parent.errors["unknown_invalid_value"].append(error) + elif item.startswith('@frame'): + self.frameValue = item[6:].strip() + if self.frameValue not in ALLOWED_FRAMES: + error = Error("unknown_frame", self.parent.filename, self.lineNumber, self.frameValue, self.name) + #error.display_error() + if not "unknown_frame" in self.parent.errors: + self.parent.errors["unknown_frame"] = [] + self.parent.errors["unknown_frame"].append(error) + else: + print(f"WARNING: Unhandled metadata in message comment: {item}") + # TODO - report errors for different kinds of metadata + exit() + + else: # bracket is a unit + self.unit = item + + if self.unit not in ALLOWED_UNITS: + invalid_units.add(self.unit) + error = Error("unknown_unit", self.parent.filename, self.lineNumber, self.unit, self.name) + #error.display_error() + if not "unknown_unit" in self.parent.errors: + self.parent.errors["unknown_unit"] = [] + self.parent.errors["unknown_unit"].append(error) + + if item == "-": + self.unit = "" + + + def display_info(self): + print(f"Debug: MessageField: display_info") + print(f" name: {self.name}, type: {self.type}, description: {self.description}, enums: {self.enums}, minValue: {self.minValue}, maxValue: {self.maxValue}, invalidValue: {self.invalidValue}, frameValue: {self.frameValue}") + + +class UORBMessage: + """ + Represents a whole message, including fields, enums, commands, constants. + The parser function delegates the parsing of each part of the message to + more appropriate classes, once the specific type of line has been identified. + """ + + def __init__(self, filename): + + self.filename = filename + msg_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../msg") + self.msg_filename = os.path.join(msg_path, self.filename) + self.name = os.path.splitext(os.path.basename(msg_file))[0] + self.shortDescription = "" + self.longDescription = "" + self.fields = [] + self.constantFields = dict() + self.commandConstants = dict() + self.enums = dict() + self.output_file = os.path.join(output_dir, f"{self.name}.md") + self.topics = [] + self.errors = dict() + + self.parseFile() + + if args.errors: + #print(f"DEBUG: args.errors: {args.errors}") + if args.error_messages: + messages = args.error_messages.split(" ") + #print(f"DEBUG: args.errors: {messages},self.name: {self.name}") + if self.name in messages: + self.reportErrors() + #print(f"Debug: {self.name} in {messages}") + else: + self.reportErrors() + + def reportErrors(self): + #print(f"Debug: UORBMessage: reportErrors()") + for errorType, errors in self.errors.items(): + for error in errors: + error.display_error() + + def markdown_out(self): + #print(f"Debug: UORBMessage: markdown_out()") + + # Add page header (forces wide pages) + markdown = f"""--- +pageClass: is-wide-page +--- + +# {self.name} (UORB message) + +""" + ## Append description info if present + markdown += f"{self.shortDescription}\n\n" if self.shortDescription else "" + markdown += f"{self.longDescription}\n\n" if self.longDescription else "" + + topicList = " ".join(self.topics) + markdown += f"**TOPICS:** {topicList}\n\n" + + # Generate field docs + markdown += f"## Fields\n\n" + markdown += "Name | Type | Unit [Frame] | Range/Enum | Description\n" + markdown += "--- | --- | --- | --- | ---\n" + for field in self.fields: + unit = f"{field.unit}" if field.unit else "" + frame = f"[{field.frameValue}]" if field.frameValue else "" + unit = f"{unit} {frame}" + unit.strip() + unit = f" {unit}" + + value = " " + if field.enums: + value = "" + for enum in field.enums: + value += f"[{enum}](#{enum})" + value = value.strip() + value = f"{value}" + elif field.minValue or field.maxValue: + value = f"[{field.minValue if field.minValue else '-'} : {field.maxValue if field.maxValue else '-' }]" + + description = f" {field.description}" if field.description else "" + invalid = f" (Invalid: {field.invalidValue}) " if field.invalidValue else "" + markdown += f"{field.name} | `{field.type}` |{unit}|{value}|{description}{invalid}\n" + + # Generate table for command docs + if len(self.commandConstants) > 0: + #print("DEBUGCOMMAND") + markdown += f"\n## Commands\n\n" + + """ + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- |---\n" + for name, command in self.commandConstants.items(): + description = f" {command.comment} " if enum.comment else " " + markdown += f' {name} | `{command.type}` | {command.value} |{description}\n' + """ + for commandConstant in self.commandConstants.values(): + #print(commandConstant) + markdown += commandConstant.markdown_out() + + # Generate enum docs + if len(self.enums) > 0: + markdown += f"\n## Enums\n" + + for name, enum in self.enums.items(): + markdown += f"\n### {name} {{#{name}}}\n\n" + + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- | ---\n" + + for enumValueName, enumValue in enum.enumValues.items(): + description = f" {enumValue.comment} " if enumValue.comment else " " + markdown += f' {enumValueName} | `{enumValue.type}` | {enumValue.value} |{description}\n' + + # Generate table for constants docs + if len(self.constantFields) > 0: + markdown += f"\n## Constants\n\n" + markdown += "Name | Type | Value | Description\n" + markdown += "--- | --- | --- |---\n" + for name, enum in self.constantFields.items(): + description = f" {enum.comment} " if enum.comment else " " + markdown += f' {name} | `{enum.type}` | {enum.value} |{description}\n' + + + + # Append msg contents to the end + with open(self.msg_filename, 'r') as source_file: + msg_contents = source_file.read() + msg_contents = msg_contents.strip() + + #Format markdown using msg name, comment, url, contents. + markdown += f""" + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/{self.filename}) + +::: details Click here to see original file + +```c +{msg_contents} +``` + +::: +""" + + with open(self.output_file, 'w') as content_file: + content_file.write(markdown) + + #exit() + + + def display_info(self): + print(f"UORBMessage: display_info") + print(f" name: {self.name}") + print(f" filename: {self.filename}, ") + print(f" msg_filename: {self.msg_filename}, ") + print(f"self.shortDescription: {self.shortDescription}") + print(f"self.longDescription: {self.longDescription}") + print(f"self.enums: {self.enums}") + + for enum, enumObject in self.enums.items(): + enumObject.display_info() + + # Output our data so far + for field in self.fields: + field.display_info() + + for enumvalue in self.constantFields: + print(enumvalue) + self.constantFields[enumvalue].display_info() + + def handleField(self, line, line_number, parentMessage): + #print(f"debug: handleField: (line): \n {line}") + # Note, here we know we don't have a comment or a topic. + # We expect it to be a field. + + # Check field doesn't have leading whitespace (trailing spaces already checked) + if line[:1].isspace(): # Returns True for ' ', '\t', '\n', '\r', etc. + #print("First character is whitespace") + error = Error("leading_whitespace_field_or_constant", self.filename, line_number, line) + if not "leading_whitespace_field_or_constant" in self.errors: + self.errors["leading_whitespace_field_or_constant"] = [] + self.errors["leading_whitespace_field_or_constant"].append(error) + + # Now we can parse the stripped line + fieldOrConstant = line.strip() + + # Check that the field or constant has only single whitespace separators + stripped_fieldOrConstant = re.sub(r'\s+', ' ', fieldOrConstant) # Collapse all spaces to a single space (LHS already stripped). + if stripped_fieldOrConstant != fieldOrConstant: + #print("Field/Constant has multiple whitespace characters") # Since the collapsed version shows them. + error = Error("field_or_constant_has_multiple_whitepsace", self.filename, line_number, line) + if not "field_or_constant_has_multiple_whitepsace" in self.errors: + self.errors["field_or_constant_has_multiple_whitepsace"] = [] + self.errors["field_or_constant_has_multiple_whitepsace"].append(error) + + fieldOrConstant = stripped_fieldOrConstant + + + + comment = None + if "#" in line: + commentExtract = line.split("#", 1) # Split once on left-most '#' + fieldOrConstant = commentExtract[0].strip() + comment = commentExtract[-1].strip() + + if "=" not in fieldOrConstant: + # Is a field: + field = fieldOrConstant.split(" ") + type = field[0].strip() + name = field[1].strip() + field = MessageField(name, type, comment, line_number, parentMessage) + self.fields.append(field) + else: + temp = fieldOrConstant.split("=") + value = temp[-1] + typeAndName = temp[0].split(" ") + type = typeAndName[0] + name = typeAndName[1] + if name.startswith("VEHICLE_CMD_") and parentMessage.name == 'VehicleCommand': #it's a command. + #print(f"DEBUG: startswith VEHICLE_CMD_ {name}") + commandConstant = CommandConstant(name, type, value, comment, line_number, parentMessage) + #commandConstant.display_info() + self.commandConstants[name]=commandConstant + else: #it's a constant (or part of an enum) + constantField = ConstantValue(name, type, value, comment, line_number) + self.constantFields[name]=constantField + + + def parseFile(self): + initial_block_lines = [] + #stopping_token = None + found_first_relevant_content = False + gettingInitialComments = False + gettingFields = False + + with open(self.msg_filename, 'r', encoding='utf-8') as uorbfile: + lines = uorbfile.read().splitlines() + for line_number, line in enumerate(lines, 1): + + if line != line.rstrip(): + #print(f"[{self.filename}] Trailing whitespace on line {line_number}: XX{line}YY") + error = Error("trailing_whitespace", self.filename, line_number, line) + if not "trailing_whitespace" in self.errors: + self.errors["trailing_whitespace"] = [] + self.errors["trailing_whitespace"].append(error) + + #print(f"line: {line}") + stripped_line = re.sub(r'\s+', ' ', line).strip() # Collapse all spaces to a single space and strip stuff off end. + #print(f"stripped_line: {stripped_line}") + # TODO? Perhaps report whitespace if the size of those two is different and it is empty + # Or perhaps we just fix it on request + + isEmptyLine = False if line.strip() else True + if not found_first_relevant_content and isEmptyLine: #Empty line + #print(f"{self.filename}: Empty line at start of file: [{line_number}]\n {line}") + error = Error("empty_start_line", self.filename, line_number, line) + if not "empty_start_line" in self.errors: + self.errors["empty_start_line"] = [] + self.errors["empty_start_line"].append(error) + #error.display_error() + continue + if not found_first_relevant_content and not isEmptyLine: + found_first_relevant_content = True + + if stripped_line.startswith("#"): + gettingInitialComments = True + else: + gettingInitialComments = False + gettingFields = True + + if gettingInitialComments and stripped_line.startswith("#"): + stripped_line=stripped_line[1:].strip() + #print(f"DEBUG: gettingInitialComments: comment line: {stripped_line}") + initial_block_lines.append(stripped_line) + else: + gettingInitialComments = False + gettingFields = True #Getting fields and constants + if gettingFields: + if isEmptyLine: + continue # empty line + if stripped_line.startswith("# TOPICS "): + stripped_line = stripped_line[9:] + stripped_line = stripped_line.split(" ") + self.topics+= stripped_line + # Note, default topic and topic errors handled after all lines parsed + continue + if stripped_line.startswith("#"): + # Its an internal comment + stripped_line=stripped_line[1:].strip() + + if stripped_line: + #print(f"{self.filename}: Internal comment: [{line_number}]\n {line}") + error = Error("internal_comment", self.filename, line_number, line) + if not "internal_comment" in self.errors: + self.errors["internal_comment"] = [] + self.errors["internal_comment"].append(error) + else: + #print(f"{self.filename}: Empty internal comment: [{line_number}]\n {line}") + error = Error("internal_comment_empty", self.filename, line_number, line) + if not "internal_comment_empty" in self.errors: + self.errors["internal_comment_empty"] = [] + self.errors["internal_comment_empty"].append(error) + #pass # Empty comment + continue + + # Must be a field or a comment. + self.handleField(line, line_number, parentMessage=self) + + # Fix up topics if the topic is empty + def camel_to_snake(name): + # Match upper case not at start of string + s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) + # Handle cases with multiple capital first letter + return re.sub('([A-Z]+)([A-Z][a-z]*)', r'\1_\2', s1).lower() + + defaultTopic = camel_to_snake(self.name) + if len(self.topics) == 0: + # We have no topic declared, so set the default topic + self.topics.append(defaultTopic) + elif len(self.topics) == 1: + # We have 1 topic declared - either it is default or there is some issue. + if defaultTopic in self.topics: + # Declared topic is default topic + error = Error("topic_error", self.filename, "", f"WARNING: TOPIC {defaultTopic} unnecessarily declared for {self.name}") + else: + # Declared topic is not default topic + error = Error("topic_error", self.filename, "", f"NOTE: TOPIC {self.topics[1]}: Only Declared topic is not default topic {defaultTopic} for {self.name}") + if not "topic_error" in self.errors: + self.errors["topic_error"] = [] + self.errors["topic_error"].append(error) + elif len(self.topics) > 1: + if defaultTopic not in self.topics: + error = Error("topic_error", self.filename, "", f"NOTE: TOPIC - Default topic {defaultTopic} for {self.name} not in {self.topics}") + + # Parse our short and long description + #print(f"DEBUG: initial_block_lines: {initial_block_lines}") + doingLongDescription = False + for summaryline in initial_block_lines: + if not self.shortDescription and summaryline.strip() == '': + continue + if not doingLongDescription and not summaryline.strip() == '': + self.shortDescription += f" {summaryline}" + self.shortDescription = self.shortDescription.strip() + if not self.shortDescription[-1:] == ".": # Add terminating fullstop if not present. + self.shortDescription += "." + if not doingLongDescription and summaryline.strip() == '': + doingLongDescription = True + continue + if doingLongDescription: + self.longDescription += f"{summaryline}\n" + + if self.longDescription: + self.longDescription.strip() + + if not self.shortDescription: + # Summary has not been defined + error = Error("summary_missing", self.filename) + if not "summary_missing" in self.errors: + self.errors["summary_missing"] = [] + self.errors["summary_missing"].append(error) + + + # TODO Parse our constantValues into enums, leaving only constants + constantValuesToRemove = [] + #print(f"DEBUG: Self.enums: {self.enums}") + for enumName, enumObject in self.enums.items(): + for enumValueName, enumValueObject in self.constantFields.items(): + if enumValueName.startswith(enumName): + # Copy this value into the object (cant be duplicate because parent is dict) + enumObject.enumValues[enumValueName]=enumValueObject + constantValuesToRemove.append(enumValueName) + # Now delete the original enumvalues + for enumValName in constantValuesToRemove: + del self.constantFields[enumValName] + constantsNotAssignedToEnums = len(self.constantFields) + if constantsNotAssignedToEnums > 0: + #print(f"Debug: WARNING constantsNotAssignedToEnums: {constantsNotAssignedToEnums}") + for enumValueName, enumValue in self.constantFields.items(): + if enumValueName in ALLOWED_CONSTANTS_NOT_IN_ENUM: # Ignore constants + pass + else: + error = Error("constant_not_in_assigned_enum", self.filename, enumValue.line_number, enumValueName) + if not "constant_not_in_assigned_enum" in self.errors: + self.errors["constant_not_in_assigned_enum"] = [] + self.errors["constant_not_in_assigned_enum"].append(error) + # TODO Maybe present as list of possible enums. import yaml @@ -127,83 +924,50 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description='Generate docs from .msg files') parser.add_argument('-d', dest='dir', help='output directory', required=True) + parser.add_argument('-e', dest='errors', action='store_true', help='Report errors') + parser.add_argument('-m', dest='error_messages', help='Message to report errors against (by default all)') args = parser.parse_args() output_dir = args.dir if not os.path.isdir(output_dir): + print(f"making output_dir {output_dir}") os.mkdir(output_dir) msg_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../msg") msg_files = get_msgs_list(msg_path) + msg_files.sort() versioned_msgs_list = '' unversioned_msgs_list = '' + msgTypes = set() for msg_file in msg_files: + # Add messages to set of allowed types (compound types) + #msg_type = msg_file.rsplit('/')[-1] + #msg_type = msg_type.rsplit('\\')[-1] + #msg_type = msg_type.rsplit('.')[0] msg_name = os.path.splitext(os.path.basename(msg_file))[0] - output_file = os.path.join(output_dir, msg_name+'.md') - msg_filename = os.path.join(msg_path, msg_file) - print("{:} -> {:}".format(msg_filename, output_file)) + msgTypes.add(msg_name) - #Format msg url - msg_url="[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/%s)" % msg_file - - msg_description = "" - summary_description = "" - - #Get msg description (first non-empty comment line from top of msg) - with open(msg_filename, 'r') as lineparser: - line = lineparser.readline() - while line.startswith('#') or (line.strip() == ''): - print('DEBUG: line: %s' % line) - line=line[1:].strip()+'\n' - stripped_line=line.strip() - if msg_description and not summary_description and stripped_line=='': - summary_description = msg_description.strip() - - msg_description+=line - line = lineparser.readline() - msg_description=msg_description.strip() - if not summary_description and msg_description: - summary_description = msg_description - print('msg_description: Z%sZ' % msg_description) - print('summary_description: Z%sZ' % summary_description) - summary_description - msg_contents = "" - #Get msg contents (read the file) - with open(msg_filename, 'r') as source_file: - msg_contents = source_file.read() - - #Format markdown using msg name, comment, url, contents. - markdown_output="""# %s (UORB message) - -%s - -%s - -```c -%s -``` -""" % (msg_name, msg_description, msg_url, msg_contents) - - with open(output_file, 'w') as content_file: - content_file.write(markdown_output) + for msg_file in msg_files: + message = UORBMessage(msg_file) + # Any additional tests that can't be in UORBMessage parser go here. + message.markdown_out() # Categorize as versioned or unversioned if "versioned" in msg_file: - versioned_msgs_list += '- [%s](%s.md)' % (msg_name, msg_name) - if summary_description: - versioned_msgs_list += " — %s" % summary_description + versioned_msgs_list += f"- [{message.name}]({message.name}.md)" + if message.shortDescription: + versioned_msgs_list += f" — {message.shortDescription}" versioned_msgs_list += "\n" else: - unversioned_msgs_list += '- [%s](%s.md)' % (msg_name, msg_name) - if summary_description: - unversioned_msgs_list += " — %s" % summary_description + unversioned_msgs_list += f"- [{message.name}]({message.name}.md)" + if message.shortDescription: + unversioned_msgs_list += f" — {message.shortDescription}" unversioned_msgs_list += "\n" - # Write out the index.md file - index_text="""# uORB Message Reference + index_text=f"""# uORB Message Reference ::: info This list is [auto-generated](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/msg/generate_msg_docs.py) from the source code. @@ -218,14 +982,14 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m ## Versioned Messages -%s +{versioned_msgs_list} ## Unversioned Messages -%s - """ % (versioned_msgs_list, unversioned_msgs_list) +{unversioned_msgs_list} + """ index_file = os.path.join(output_dir, 'index.md') - with open(index_file, 'w') as content_file: + with open(index_file, 'w', encoding='utf-8') as content_file: content_file.write(index_text) generate_dds_yaml_doc(msg_files) diff --git a/Tools/process_sensor_caldata.py b/Tools/process_sensor_caldata.py index e70ffc8878..89d06f0ede 100755 --- a/Tools/process_sensor_caldata.py +++ b/Tools/process_sensor_caldata.py @@ -1138,6 +1138,8 @@ if num_mags >= 1: if not math.isnan(sensor_mag_0['temperature'][0]): + mag_0_params['TC_M0_ID'] = int(np.median(sensor_mag_0['device_id'])) + # find the min, max and reference temperature mag_0_params['TC_M0_TMIN'] = np.amin(sensor_mag_0['temperature']) mag_0_params['TC_M0_TMAX'] = np.amax(sensor_mag_0['temperature']) @@ -1656,9 +1658,9 @@ sensor_baro_0['pressure'] = median_filter(sensor_baro_0['pressure']) # fit data median_pressure = np.median(sensor_baro_0['pressure']) if noResample: - coef_baro_0_x = np.polyfit(temp_rel,100*(sensor_baro_0['pressure']-median_pressure),5) # convert from hPa to Pa + coef_baro_0_x = np.polyfit(temp_rel,(sensor_baro_0['pressure']-median_pressure),5) # pressure in Pascal else: - temperature, baro = resampleWithDeltaX(temp_rel,100*(sensor_baro_0['pressure']-median_pressure)) # convert from hPa to Pa + temperature, baro = resampleWithDeltaX(temp_rel,(sensor_baro_0['pressure']-median_pressure)) # pressure in Pascal coef_baro_0_x = np.polyfit(temperature,baro,5) baro_0_params['TC_B0_X5'] = coef_baro_0_x[0] @@ -1675,7 +1677,7 @@ baro_0_x_resample = fit_coef_baro_0_x(temp_rel_resample) plt.figure(13,figsize=(20,13)) # draw plots -plt.plot(sensor_baro_0['temperature'],100*sensor_baro_0['pressure']-100*median_pressure,'b') +plt.plot(sensor_baro_0['temperature'],sensor_baro_0['pressure']-median_pressure,'b') plt.plot(temp_resample,baro_0_x_resample,'r') plt.title('Baro 0 ({}) Bias vs Temperature'.format(baro_0_params['TC_B0_ID'])) plt.ylabel('Z bias (Pa)') @@ -1717,9 +1719,9 @@ if num_baros >= 2: # fit data median_pressure = np.median(sensor_baro_1['pressure']) if noResample: - coef_baro_1_x = np.polyfit(temp_rel,100*(sensor_baro_1['pressure']-median_pressure),5) # convert from hPa to Pa + coef_baro_1_x = np.polyfit(temp_rel,(sensor_baro_1['pressure']-median_pressure),5) # pressure in Pascal else: - temperature, baro = resampleWithDeltaX(temp_rel,100*(sensor_baro_1['pressure']-median_pressure)) # convert from hPa to Pa + temperature, baro = resampleWithDeltaX(temp_rel,(sensor_baro_1['pressure']-median_pressure)) # pressure in Pascal coef_baro_1_x = np.polyfit(temperature,baro,5) baro_1_params['TC_B1_X5'] = coef_baro_1_x[0] @@ -1736,7 +1738,7 @@ if num_baros >= 2: plt.figure(14,figsize=(20,13)) # draw plots - plt.plot(sensor_baro_1['temperature'],100*sensor_baro_1['pressure']-100*median_pressure,'b') + plt.plot(sensor_baro_1['temperature'],sensor_baro_1['pressure']-median_pressure,'b') plt.plot(temp_resample,baro_1_x_resample,'r') plt.title('Baro 1 ({}) Bias vs Temperature'.format(baro_1_params['TC_B1_ID'])) plt.ylabel('Z bias (Pa)') @@ -1778,9 +1780,9 @@ if num_baros >= 3: # fit data median_pressure = np.median(sensor_baro_2['pressure']) if noResample: - coef_baro_2_x = np.polyfit(temp_rel,100*(sensor_baro_2['pressure']-median_pressure),5) # convert from hPa to Pa + coef_baro_2_x = np.polyfit(temp_rel,(sensor_baro_2['pressure']-median_pressure),5) # pressure in Pascal else: - temperature, baro = resampleWithDeltaX(temp_rel,100*(sensor_baro_2['pressure']-median_pressure)) # convert from hPa to Pa + temperature, baro = resampleWithDeltaX(temp_rel,(sensor_baro_2['pressure']-median_pressure)) # pressure in Pascal coef_baro_2_x = np.polyfit(temperature,baro,5) baro_2_params['TC_B2_X5'] = coef_baro_2_x[0] @@ -1797,7 +1799,7 @@ if num_baros >= 3: plt.figure(15,figsize=(20,13)) # draw plots - plt.plot(sensor_baro_2['temperature'],100*sensor_baro_2['pressure']-100*median_pressure,'b') + plt.plot(sensor_baro_2['temperature'],sensor_baro_2['pressure']-median_pressure,'b') plt.plot(temp_resample,baro_2_x_resample,'r') plt.title('Baro 2 ({}) Bias vs Temperature'.format(baro_2_params['TC_B2_ID'])) plt.ylabel('Z bias (Pa)') @@ -1838,7 +1840,7 @@ if num_baros >= 4: # fit data median_pressure = np.median(sensor_baro_3['pressure']) - coef_baro_3_x = np.polyfit(temp_rel,100*(sensor_baro_3['pressure']-median_pressure),5) # convert from hPa to Pa + coef_baro_3_x = np.polyfit(temp_rel,(sensor_baro_3['pressure']-median_pressure),5) # pressure in Pascal baro_3_params['TC_B3_X5'] = coef_baro_3_x[0] baro_3_params['TC_B3_X4'] = coef_baro_3_x[1] baro_3_params['TC_B3_X3'] = coef_baro_3_x[2] @@ -1853,7 +1855,7 @@ if num_baros >= 4: plt.figure(16,figsize=(20,13)) # draw plots - plt.plot(sensor_baro_3['temperature'],100*sensor_baro_3['pressure']-100*median_pressure,'b') + plt.plot(sensor_baro_3['temperature'],sensor_baro_3['pressure']-median_pressure,'b') plt.plot(temp_resample,baro_3_x_resample,'r') plt.title('Baro 3 ({}) Bias vs Temperature'.format(baro_3_params['TC_B3_ID'])) plt.ylabel('Z bias (Pa)') diff --git a/Tools/px4_uploader.py b/Tools/px4_uploader.py new file mode 100755 index 0000000000..3b54950747 --- /dev/null +++ b/Tools/px4_uploader.py @@ -0,0 +1,2113 @@ +#!/usr/bin/env python3 +############################################################################ +# +# Copyright (c) 2012-2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +""" +PX4 Firmware Uploader v2 - Rewritten with improved error handling and debugging. + +This script uploads firmware to PX4-based flight controllers via their bootloader. + +The PX4 firmware file is a JSON-encoded Python object containing metadata fields +and a zlib-compressed base64-encoded firmware image. + +Key improvements over px_uploader.py: +- Proper exception hierarchy with full context +- Verbose/debug logging support +- Self-contained port detection +- Clean separation of concerns +- Configurable timeouts +- Better progress reporting +""" + +import argparse +import base64 +import glob +import json +import logging +import os +import socket +import struct +import sys +import time +import zlib +from dataclasses import dataclass, field +from enum import IntEnum +from pathlib import Path +from typing import Optional + +# Check Python version early +if sys.version_info < (3, 7): + print("Python 3.7 or later is required.", file=sys.stderr) + sys.exit(1) + +try: + import serial + import serial.tools.list_ports +except ImportError as e: + print(f"Failed to import pyserial: {e}", file=sys.stderr) + print("\nInstall it with: python -m pip install pyserial", file=sys.stderr) + sys.exit(1) + + +# ============================================================================= +# Logging Configuration +# ============================================================================= + +logger = logging.getLogger("px4_uploader") + + +def setup_logging(verbose: bool = False, debug: bool = False) -> None: + """Configure logging based on verbosity level. + + Args: + verbose: Enable INFO level logging for operational details + debug: Enable DEBUG level logging for protocol-level details + """ + if debug: + level = logging.DEBUG + fmt = "%(asctime)s.%(msecs)03d [%(levelname)s] %(name)s: %(message)s" + elif verbose: + level = logging.INFO + fmt = "[%(levelname)s] %(message)s" + else: + level = logging.WARNING + fmt = "%(message)s" + + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(fmt, datefmt="%H:%M:%S")) + logger.addHandler(handler) + logger.setLevel(level) + + # Also check environment variable + if os.environ.get("PX4_UPLOADER_DEBUG", "").lower() in ("1", "true", "yes"): + logger.setLevel(logging.DEBUG) + + +# ============================================================================= +# Exception Hierarchy +# ============================================================================= + + +class UploadError(Exception): + """Base exception for all upload-related errors.""" + + def __init__( + self, + message: str, + port: Optional[str] = None, + operation: Optional[str] = None, + details: Optional[str] = None, + ): + self.port = port + self.operation = operation + self.details = details + + parts = [message] + if port: + parts.append(f"port={port}") + if operation: + parts.append(f"during {operation}") + if details: + parts.append(f"({details})") + + super().__init__(" ".join(parts)) + + +class ProtocolError(UploadError): + """Error in bootloader protocol communication.""" + + pass + + +class ConnectionError(UploadError): + """Error establishing or maintaining serial connection.""" + + pass + + +class FirmwareError(UploadError): + """Error loading or validating firmware file.""" + + pass + + +class BoardMismatchError(UploadError): + """Firmware not suitable for the connected board.""" + + pass + + +class TimeoutError(UploadError): + """Operation timed out.""" + + pass + + +class SiliconErrataError(UploadError): + """Board has silicon errata that prevents safe operation.""" + + pass + + +# ============================================================================= +# Protocol Constants +# ============================================================================= + + +class BootloaderCommand(IntEnum): + """Bootloader protocol commands.""" + + NOP = 0x00 # Guaranteed to be discarded by the bootloader + GET_SYNC = 0x21 + GET_DEVICE = 0x22 + CHIP_ERASE = 0x23 + CHIP_VERIFY = 0x24 # rev2 only + PROG_MULTI = 0x27 + READ_MULTI = 0x28 # rev2 only + GET_CRC = 0x29 # rev3+ + GET_OTP = 0x2A # rev4+, get a word from OTP area + GET_SN = 0x2B # rev4+, get a word from SN area + GET_CHIP = 0x2C # rev5+, get chip version + SET_BOOT_DELAY = 0x2D # rev5+, set boot delay + GET_CHIP_DES = 0x2E # rev5+, get chip description in ASCII + GET_VERSION = 0x2F # rev5+, get bootloader version in ASCII + REBOOT = 0x30 + CHIP_FULL_ERASE = 0x40 # Full erase of flash, rev6+ + + +class BootloaderResponse(IntEnum): + """Bootloader response codes.""" + + INSYNC = 0x12 + EOC = 0x20 + OK = 0x10 + FAILED = 0x11 + INVALID = 0x13 # rev3+ + BAD_SILICON_REV = 0x14 # rev5+ + + +class DeviceInfo(IntEnum): + """Device information parameter codes.""" + + BL_REV = 0x01 # Bootloader protocol revision + BOARD_ID = 0x02 # Board type + BOARD_REV = 0x03 # Board revision + FLASH_SIZE = 0x04 # Max firmware size in bytes + + +@dataclass +class ProtocolConfig: + """Protocol configuration constants.""" + + BL_REV_MIN: int = 2 # Minimum supported bootloader protocol + BL_REV_MAX: int = 6 # Maximum supported bootloader protocol + PROG_MULTI_MAX: int = ( + 252 # Max bytes per PROG_MULTI (protocol max 255, must be multiple of 4) + ) + READ_MULTI_MAX: int = 252 # Max bytes per READ_MULTI + MAX_DES_LENGTH: int = 20 # Max chip description length + + +# ============================================================================= +# Known PX4 USB Vendor/Product IDs +# ============================================================================= + +# Known VID/PID combinations for PX4 bootloaders and devices +PX4_USB_IDS: list[tuple[int, int, str]] = [ + # (Vendor ID, Product ID, Description) + (0x26AC, 0x0010, "3D Robotics PX4 FMU"), + (0x26AC, 0x0011, "3D Robotics PX4 BL"), + (0x26AC, 0x0012, "3D Robotics PX4IO"), + (0x26AC, 0x0032, "3D Robotics PX4 FMU v5"), + (0x3185, 0x0035, "Holybro Durandal"), + (0x3185, 0x0036, "Holybro Kakute"), + (0x3162, 0x004B, "Holybro Pixhawk 4"), + (0x1FC9, 0x001C, "NXP FMUK66"), + (0x2DAE, 0x1058, "Cube Orange"), + (0x2DAE, 0x1016, "Cube Black"), + (0x2DAE, 0x1011, "Cube Yellow"), + (0x0483, 0x5740, "STMicroelectronics Virtual COM Port"), # Generic ST bootloader + (0x1209, 0x5740, "Generic STM32"), + (0x1209, 0x5741, "ArduPilot"), + (0x3185, 0x0039, "ARK FMU v6x"), + (0x3185, 0x003A, "ARK Pi6x"), + (0x3185, 0x003B, "ARK FPV"), + (0x2341, 0x8036, "Arduino Leonardo"), # Some PX4 boards use this +] + + +# ============================================================================= +# Firmware Class +# ============================================================================= + + +@dataclass +class Firmware: + """Loads and validates a PX4 firmware file. + + The firmware file is JSON containing metadata and a zlib-compressed, + base64-encoded firmware image. + + Attributes: + path: Path to the firmware file + board_id: Target board ID from firmware metadata + board_revision: Board revision from metadata + image: Decompressed firmware binary (padded to 4-byte alignment) + image_size: Original image size before padding + image_maxsize: Maximum image size the firmware was built for + description: Full firmware metadata dictionary + """ + + path: Path + board_id: int = field(init=False) + board_revision: int = field(init=False) + image: bytes = field(init=False) + image_size: int = field(init=False) + image_maxsize: int = field(init=False) + description: dict = field(init=False) + + def __post_init__(self): + """Load and validate the firmware file.""" + self.path = Path(self.path) + self._load() + + def _load(self) -> None: + """Load firmware from JSON file.""" + logger.info(f"Loading firmware from {self.path}") + + if not self.path.exists(): + raise FirmwareError(f"Firmware file not found: {self.path}") + + try: + with open(self.path, "r") as f: + self.description = json.load(f) + except json.JSONDecodeError as e: + raise FirmwareError(f"Invalid firmware JSON: {e}", details=str(self.path)) + except IOError as e: + raise FirmwareError( + f"Cannot read firmware file: {e}", details=str(self.path) + ) + + # Extract required fields + required_fields = ["image", "board_id", "image_size", "image_maxsize"] + for field_name in required_fields: + if field_name not in self.description: + raise FirmwareError( + f"Firmware missing required field: {field_name}", + details=str(self.path), + ) + + self.board_id = self.description["board_id"] + self.board_revision = self.description.get("board_revision", 0) + self.image_size = self.description["image_size"] + self.image_maxsize = self.description["image_maxsize"] + + # Decompress image + try: + compressed = base64.b64decode(self.description["image"]) + image_data = bytearray(zlib.decompress(compressed)) + except (base64.binascii.Error, zlib.error) as e: + raise FirmwareError( + f"Cannot decompress firmware image: {e}", details=str(self.path) + ) + + # Pad to 4-byte alignment + while len(image_data) % 4 != 0: + image_data.append(0xFF) + + self.image = bytes(image_data) + + logger.info( + f"Loaded firmware: board_id={self.board_id}, " + f"size={self.image_size} bytes ({self.usage_percent:.1f}%)" + ) + + @property + def usage_percent(self) -> float: + """Percentage of maximum flash used.""" + return (self.image_size / self.image_maxsize) * 100.0 + + def crc(self, padlen: int) -> int: + """Calculate CRC32 of firmware image with padding. + + Args: + padlen: Total length to pad image to (typically flash size) + + Returns: + CRC32 value matching bootloader's calculation + """ + state = 0xFFFFFFFF + state = zlib.crc32(self.image, state) + + padding_length = padlen - len(self.image) + if padding_length > 0: + padding = b"\xff" * padding_length + state = zlib.crc32(padding, state) + + return (state ^ 0xFFFFFFFF) & 0xFFFFFFFF + + +# ============================================================================= +# Serial Transport +# ============================================================================= + + +class SerialTransport: + """Handles serial port communication with proper resource management. + + Provides context manager support for automatic cleanup and configurable + timeouts. + """ + + def __init__( + self, + port: str, + baudrate: int = 115200, + timeout: float = 0.5, + write_timeout: float = 2.0, + ): + """Initialize serial transport. + + Args: + port: Serial port path (e.g., /dev/ttyUSB0, COM3) + baudrate: Baud rate for communication + timeout: Read timeout in seconds + write_timeout: Write timeout in seconds (0 = no timeout) + """ + self.port_name = port + self.baudrate = baudrate + self.timeout = timeout + self.write_timeout = write_timeout + self._port: Optional[serial.Serial] = None + self._chartime = 10.0 / baudrate # 8N1 = 10 bits per byte + + def __enter__(self) -> "SerialTransport": + self.open() + return self + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: + self.close() + + def open(self) -> None: + """Open the serial port.""" + if self._port is not None and self._port.is_open: + return + + logger.debug(f"Opening serial port {self.port_name} at {self.baudrate} baud") + + try: + self._port = serial.Serial( + self.port_name, + self.baudrate, + timeout=self.timeout, + write_timeout=self.write_timeout, + ) + except serial.SerialException as e: + raise ConnectionError( + f"Cannot open serial port: {e}", port=self.port_name, operation="open" + ) + + def close(self) -> None: + """Close the serial port.""" + if self._port is not None: + logger.debug(f"Closing serial port {self.port_name}") + try: + self._port.close() + except Exception as e: + logger.warning(f"Error closing port {self.port_name}: {e}") + self._port = None + + @property + def is_open(self) -> bool: + """Check if port is open.""" + return self._port is not None and self._port.is_open + + def send(self, data: bytes) -> None: + """Send data over serial port. + + Args: + data: Bytes to send + + Raises: + ConnectionError: If send fails + """ + if not self.is_open: + raise ConnectionError( + "Port not open", port=self.port_name, operation="send" + ) + + logger.debug(f"TX: {data.hex()}") + + try: + self._port.write(data) + except serial.SerialException as e: + raise ConnectionError( + f"Write failed: {e}", port=self.port_name, operation="send" + ) + + def recv(self, count: int = 1, timeout: Optional[float] = None) -> bytes: + """Receive data from serial port. + + Args: + count: Number of bytes to receive + timeout: Override default timeout + + Returns: + Received bytes + + Raises: + TimeoutError: If timeout expires before all bytes received + ConnectionError: If read fails + """ + if not self.is_open: + raise ConnectionError( + "Port not open", port=self.port_name, operation="recv" + ) + + old_timeout = self._port.timeout + if timeout is not None: + self._port.timeout = timeout + + try: + data = self._port.read(count) + except serial.SerialException as e: + raise ConnectionError( + f"Read failed: {e}", port=self.port_name, operation="recv" + ) + finally: + if timeout is not None: + self._port.timeout = old_timeout + + if len(data) < count: + raise TimeoutError( + f"Timeout waiting for {count} bytes, got {len(data)}", + port=self.port_name, + operation="recv", + ) + + logger.debug(f"RX: {data.hex()}") + return data + + def flush(self) -> None: + """Flush output buffer.""" + if self._port is not None: + self._port.flush() + + def reset_buffers(self) -> None: + """Reset input and output buffers.""" + if self._port is not None: + self._port.reset_input_buffer() + self._port.reset_output_buffer() + + def set_baudrate(self, baudrate: int) -> None: + """Change baud rate. + + Args: + baudrate: New baud rate + """ + logger.debug(f"Changing baudrate to {baudrate}") + self.baudrate = baudrate + self._chartime = 10.0 / baudrate + + if self._port is not None: + try: + self._port.baudrate = baudrate + except (serial.SerialException, NotImplementedError) as e: + logger.debug(f"Cannot change baudrate: {e}") + raise + + @property + def chartime(self) -> float: + """Time to transmit one character.""" + return self._chartime + + +# ============================================================================= +# Bootloader Protocol +# ============================================================================= + + +class BootloaderProtocol: + """Implements the PX4 bootloader protocol. + + Handles all communication with the bootloader including sync, + identification, programming, and verification. + """ + + # Reboot command sequences + NSH_INIT = b"\r\r\r" + NSH_REBOOT_BL = b"reboot -b\n" + NSH_REBOOT = b"reboot\n" + + # MAVLink reboot commands (MAVLink v1 COMMAND_LONG with MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN) + MAVLINK_REBOOT_ID1 = bytes.fromhex( + "fe2172ff004c00004040000000000000000000000000" + "000000000000000000000000f600010000536b" + ) + MAVLINK_REBOOT_ID0 = bytes.fromhex( + "fe2145ff004c00004040000000000000000000000000" + "000000000000000000000000f600000000cc37" + ) + + def __init__( + self, + transport: SerialTransport, + sync_timeout: float = 0.5, + erase_timeout: float = 30.0, + windowed: bool = False, + ): + """Initialize bootloader protocol handler. + + Args: + transport: Serial transport instance + sync_timeout: Timeout for sync operations + erase_timeout: Timeout for chip erase + windowed: Use windowed mode for faster uploads on real serial ports + """ + self.transport = transport + self.sync_timeout = sync_timeout + self.erase_timeout = erase_timeout + + # Board info (populated by identify()) + self.bl_rev: int = 0 + self.board_type: int = 0 + self.board_rev: int = 0 + self.fw_maxsize: int = 0 + self.version: str = "unknown" + self.otp: bytes = b"" + self.sn: bytes = b"" + self.chip_id: int = 0 + self.chip_family: str = "" + self.chip_revision: str = "" + + # Windowed mode for faster uploads on some interfaces + self._windowed_mode = windowed + self._window_size = 0 + self._window_max = 256 + self._window_per = 2 # SYNC + result per block + + def _send_command(self, cmd: int, *args: bytes) -> None: + """Send a command to the bootloader. + + Args: + cmd: Command byte + *args: Additional data bytes + """ + data = bytes([cmd]) + b"".join(args) + bytes([BootloaderResponse.EOC]) + self.transport.send(data) + + def _recv_int(self) -> int: + """Receive a 32-bit little-endian integer.""" + raw = self.transport.recv(4) + return struct.unpack(" None: + """Wait for and validate sync response. + + Args: + flush: Whether to flush output buffer first + + Raises: + ProtocolError: If response is not valid INSYNC + OK + """ + if flush: + self.transport.flush() + + insync = self.transport.recv(1) + if insync[0] != BootloaderResponse.INSYNC: + raise ProtocolError( + f"Expected INSYNC (0x{BootloaderResponse.INSYNC:02X}), " + f"got 0x{insync[0]:02X}", + port=self.transport.port_name, + operation="sync", + ) + + result = self.transport.recv(1) + if result[0] == BootloaderResponse.INVALID: + raise ProtocolError( + "Bootloader reports INVALID OPERATION", port=self.transport.port_name + ) + if result[0] == BootloaderResponse.FAILED: + raise ProtocolError( + "Bootloader reports OPERATION FAILED", port=self.transport.port_name + ) + if result[0] == BootloaderResponse.BAD_SILICON_REV: + raise SiliconErrataError( + "Chip has silicon errata, programming not supported.\n" + "See https://docs.px4.io/main/en/flight_controller/silicon_errata.html", + port=self.transport.port_name, + ) + if result[0] != BootloaderResponse.OK: + raise ProtocolError( + f"Expected OK (0x{BootloaderResponse.OK:02X}), got 0x{result[0]:02X}", + port=self.transport.port_name, + ) + + def _try_sync(self) -> bool: + """Attempt to get sync without raising exceptions. + + Returns: + True if sync successful, False otherwise + """ + try: + self.transport.flush() + insync = self.transport.recv(1, timeout=0.1) + if insync[0] != BootloaderResponse.INSYNC: + return False + result = self.transport.recv(1, timeout=0.1) + if result[0] == BootloaderResponse.BAD_SILICON_REV: + raise SiliconErrataError( + "Chip has silicon errata, programming not supported", + port=self.transport.port_name, + ) + return result[0] == BootloaderResponse.OK + except TimeoutError: + return False + except Exception as e: + logger.debug(f"Sync attempt failed: {e}") + return False + + def _validate_sync_window(self, count: int) -> None: + """Validate multiple sync responses for windowed mode. + + Args: + count: Number of sync responses to validate (each is 2 bytes) + """ + if count <= 0: + return + + data = self.transport.recv(count) + if len(data) != count: + raise ProtocolError( + f"Expected {count} bytes, got {len(data)}", + port=self.transport.port_name, + operation="ack_window", + ) + + for i in range(0, len(data), 2): + if data[i] != BootloaderResponse.INSYNC: + raise ProtocolError( + f"Expected INSYNC at byte {i}, got 0x{data[i]:02X}", + port=self.transport.port_name, + ) + if data[i + 1] == BootloaderResponse.INVALID: + raise ProtocolError( + "Bootloader reports INVALID OPERATION", + port=self.transport.port_name, + ) + if data[i + 1] == BootloaderResponse.FAILED: + raise ProtocolError( + "Bootloader reports OPERATION FAILED", port=self.transport.port_name + ) + if data[i + 1] != BootloaderResponse.OK: + raise ProtocolError( + f"Expected OK, got 0x{data[i + 1]:02X}", + port=self.transport.port_name, + ) + + def _detect_interface_type(self) -> None: + """Detect if connected via USB CDC or real serial port. + + Currently just resets buffers. Windowed mode can be enabled manually + with --windowed for real serial ports (FTDI, etc.). + """ + self.transport.reset_buffers() + + def sync(self) -> None: + """Synchronize with bootloader. + + Sends sync command and waits for valid response. + + Raises: + ProtocolError: If sync fails + """ + logger.debug("Syncing with bootloader") + self.transport.reset_buffers() + self._send_command(BootloaderCommand.GET_SYNC) + self._get_sync() + logger.debug("Sync successful") + + def _get_device_info(self, param: int) -> int: + """Get device information parameter. + + Args: + param: DeviceInfo parameter code + + Returns: + Parameter value + """ + self._send_command(BootloaderCommand.GET_DEVICE, bytes([param])) + value = self._recv_int() + self._get_sync() + return value + + def _get_otp(self, address: int) -> bytes: + """Read 4 bytes from OTP area. + + Args: + address: OTP address (byte offset) + + Returns: + 4 bytes of OTP data + """ + self._send_command(BootloaderCommand.GET_OTP, struct.pack(" bytes: + """Read 4 bytes from serial number area. + + Args: + address: SN address (byte offset) + + Returns: + 4 bytes of SN data + """ + self._send_command(BootloaderCommand.GET_SN, struct.pack(" int: + """Get chip ID. + + Returns: + Chip ID value + """ + self._send_command(BootloaderCommand.GET_CHIP) + value = self._recv_int() + self._get_sync() + return value + + def _get_chip_description(self) -> tuple[str, str]: + """Get chip family and revision. + + Returns: + Tuple of (family, revision) strings + """ + self._send_command(BootloaderCommand.GET_CHIP_DES) + length = self._recv_int() + value = self.transport.recv(length) + self._get_sync() + + pieces = value.split(b",") + if len(pieces) >= 2: + return pieces[0].decode("latin-1"), pieces[1].decode("latin-1") + return "unknown", "unknown" + + def _get_version(self) -> str: + """Get bootloader version string. + + Returns: + Version string or "unknown" if not supported + """ + self._send_command(BootloaderCommand.GET_VERSION) + try: + length = self._recv_int() + value = self.transport.recv(length) + self._get_sync() + return value.decode("utf-8", errors="replace") + except (TimeoutError, ProtocolError): + # Older bootloaders don't support this + return "unknown" + + def identify(self) -> None: + """Identify the connected board. + + Queries bootloader for board information and stores in instance + attributes. + + Raises: + ProtocolError: If identification fails or protocol version unsupported + """ + logger.info("Identifying board...") + + self._detect_interface_type() + self.sync() + + # Get bootloader protocol revision + self.bl_rev = self._get_device_info(DeviceInfo.BL_REV) + logger.info(f"Bootloader protocol: v{self.bl_rev}") + + if self.bl_rev < ProtocolConfig.BL_REV_MIN: + raise ProtocolError( + f"Bootloader protocol {self.bl_rev} too old " + f"(minimum {ProtocolConfig.BL_REV_MIN})", + port=self.transport.port_name, + ) + if self.bl_rev > ProtocolConfig.BL_REV_MAX: + logger.warning( + f"Bootloader protocol {self.bl_rev} newer than supported " + f"({ProtocolConfig.BL_REV_MAX}), proceeding with caution" + ) + + # Get board info + self.board_type = self._get_device_info(DeviceInfo.BOARD_ID) + self.board_rev = self._get_device_info(DeviceInfo.BOARD_REV) + self.fw_maxsize = self._get_device_info(DeviceInfo.FLASH_SIZE) + + logger.info(f"Board type: {self.board_type}, revision: {self.board_rev}") + logger.info(f"Flash size: {self.fw_maxsize} bytes") + + # Get version string (v5+) + if self.bl_rev >= 5: + self.version = self._get_version() + logger.info(f"Bootloader version: {self.version}") + + # Get OTP and serial number (v4+) + if self.bl_rev >= 4: + self._read_otp_and_sn() + + # Get chip info (v5+) + if self.bl_rev >= 5: + self._read_chip_info() + + def _read_otp_and_sn(self) -> None: + """Read OTP and serial number data.""" + # Read OTP (32*6 = 192 bytes) + otp_data = bytearray() + for addr in range(0, 32 * 6, 4): + otp_data.extend(self._get_otp(addr)) + self.otp = bytes(otp_data) + + # Read serial number (12 bytes) + sn_data = bytearray() + for addr in range(0, 12, 4): + sn_bytes = self._get_sn(addr) + sn_data.extend(sn_bytes[::-1]) # Reverse byte order + self.sn = bytes(sn_data) + + logger.debug(f"Serial number: {self.sn.hex()}") + + # Try to get chip ID + try: + self.chip_id = self._get_chip() + logger.debug(f"Chip ID: 0x{self.chip_id:08X}") + except (TimeoutError, ProtocolError) as e: + logger.debug(f"Could not read chip ID: {e}") + + def _read_chip_info(self) -> None: + """Read chip family and revision (v5+).""" + try: + self.chip_family, self.chip_revision = self._get_chip_description() + logger.info(f"Chip: {self.chip_family} rev {self.chip_revision}") + except (TimeoutError, ProtocolError) as e: + logger.debug(f"Could not read chip description: {e}") + + def erase( + self, force_full: bool = False, progress_callback: Optional[callable] = None + ) -> None: + """Erase the flash memory. + + Args: + force_full: Force full chip erase (v6+) + progress_callback: Optional callback(progress, total) for progress + + Raises: + TimeoutError: If erase times out + ProtocolError: If erase fails + """ + logger.debug("Erasing flash") + + if force_full and self.bl_rev >= 6: + logger.debug("Using full chip erase") + self._send_command(BootloaderCommand.CHIP_FULL_ERASE) + else: + self._send_command(BootloaderCommand.CHIP_ERASE) + + # Erase can take a long time, poll for completion + deadline = time.monotonic() + self.erase_timeout + usual_duration = 15.0 + + while time.monotonic() < deadline: + elapsed = time.monotonic() - (deadline - self.erase_timeout) + remaining = deadline - time.monotonic() + + if progress_callback: + if remaining >= usual_duration: + progress_callback(elapsed, usual_duration) + else: + progress_callback(usual_duration, usual_duration) + + if self._try_sync(): + logger.debug("Erase complete") + if progress_callback: + progress_callback(1.0, 1.0) + return + + raise TimeoutError( + f"Erase timed out after {self.erase_timeout}s", + port=self.transport.port_name, + operation="erase", + ) + + def program( + self, firmware: Firmware, progress_callback: Optional[callable] = None + ) -> None: + """Program firmware to flash. + + Args: + firmware: Firmware instance to program + progress_callback: Optional callback(bytes_written, total_bytes) + + Raises: + ProtocolError: If programming fails + """ + image = firmware.image + total = len(image) + written = 0 + + logger.debug(f"Programming {total} bytes") + + # Split image into chunks + chunk_size = ProtocolConfig.PROG_MULTI_MAX + chunks = [image[i : i + chunk_size] for i in range(0, total, chunk_size)] + + for i, chunk in enumerate(chunks): + self._program_multi(chunk) + + if self._windowed_mode: + self._window_size += self._window_per + + # Periodically validate window + if (i + 1) % 256 == 0: + self._validate_sync_window(self._window_size) + self._window_size = 0 + else: + self._get_sync(flush=False) + + written += len(chunk) + if progress_callback: + progress_callback(written, total) + + # Validate any remaining window + if self._windowed_mode and self._window_size > 0: + self._validate_sync_window(self._window_size) + self._window_size = 0 + + logger.debug("Programming complete") + + def _program_multi(self, data: bytes) -> None: + """Program a chunk of data. + + Args: + data: Bytes to program (max PROG_MULTI_MAX) + """ + length = len(data) + cmd = bytes([BootloaderCommand.PROG_MULTI, length]) + data + cmd += bytes([BootloaderResponse.EOC]) + self.transport.send(cmd) + + if self._windowed_mode: + # Delay based on transmission time plus flash programming time + time.sleep(length * self.transport.chartime + 0.001) + + def verify_crc( + self, firmware: Firmware, progress_callback: Optional[callable] = None + ) -> None: + """Verify programmed firmware using CRC (v3+). + + Args: + firmware: Firmware instance to verify against + progress_callback: Optional callback for progress + + Raises: + ProtocolError: If verification fails + """ + if self.bl_rev < 3: + raise ProtocolError( + "CRC verification requires bootloader v3+", + port=self.transport.port_name, + ) + + logger.debug("Verifying CRC") + + expected_crc = firmware.crc(self.fw_maxsize) + logger.debug(f"Expected CRC: 0x{expected_crc:08X}") + + self._send_command(BootloaderCommand.GET_CRC) + + # CRC calculation takes time, especially on larger flash + time.sleep(0.5) + + if progress_callback: + progress_callback(0.5, 1.0) + + reported_crc = self._recv_int() + self._get_sync() + + if progress_callback: + progress_callback(1.0, 1.0) + + logger.debug(f"Reported CRC: 0x{reported_crc:08X}") + + if reported_crc != expected_crc: + raise ProtocolError( + f"CRC mismatch: expected 0x{expected_crc:08X}, " + f"got 0x{reported_crc:08X}", + port=self.transport.port_name, + operation="verify", + ) + + logger.debug("CRC verification passed") + + def verify_read( + self, firmware: Firmware, progress_callback: Optional[callable] = None + ) -> None: + """Verify programmed firmware by reading back (v2). + + Args: + firmware: Firmware instance to verify against + progress_callback: Optional callback(bytes_verified, total_bytes) + + Raises: + ProtocolError: If verification fails + """ + logger.debug("Verifying by read-back") + + self._send_command(BootloaderCommand.CHIP_VERIFY) + self._get_sync() + + image = firmware.image + total = len(image) + verified = 0 + + chunk_size = ProtocolConfig.READ_MULTI_MAX + chunks = [image[i : i + chunk_size] for i in range(0, total, chunk_size)] + + for chunk in chunks: + length = len(chunk) + cmd = bytes([BootloaderCommand.READ_MULTI, length]) + cmd += bytes([BootloaderResponse.EOC]) + self.transport.send(cmd) + self.transport.flush() + + readback = self.transport.recv(length) + self._get_sync() + + if readback != chunk: + logger.error(f"Verify failed at offset {verified}") + logger.debug(f"Expected: {chunk.hex()}") + logger.debug(f"Got: {readback.hex()}") + raise ProtocolError( + "Verification failed", + port=self.transport.port_name, + operation="verify", + ) + + verified += length + if progress_callback: + progress_callback(verified, total) + + logger.debug("Read-back verification passed") + + def verify( + self, firmware: Firmware, progress_callback: Optional[callable] = None + ) -> None: + """Verify programmed firmware using appropriate method. + + Uses CRC for v3+ bootloaders, read-back for v2. + + Args: + firmware: Firmware to verify against + progress_callback: Optional progress callback + """ + if self.bl_rev >= 3: + self.verify_crc(firmware, progress_callback) + else: + self.verify_read(firmware, progress_callback) + + def set_boot_delay(self, delay_ms: int) -> None: + """Set boot delay in flash (v5+). + + Args: + delay_ms: Boot delay in milliseconds + """ + if self.bl_rev < 5: + logger.warning("Boot delay requires bootloader v5+") + return + + self._send_command(BootloaderCommand.SET_BOOT_DELAY, struct.pack("b", delay_ms)) + self._get_sync() + logger.info(f"Boot delay set to {delay_ms}ms") + + def reboot(self) -> None: + """Reboot into the application. + + Raises: + ProtocolError: If reboot fails (v3+ validates first flash word) + """ + logger.info("Rebooting to application") + self._send_command(BootloaderCommand.REBOOT) + self.transport.flush() + + # v3+ can report failure if first flash word is invalid + if self.bl_rev >= 3: + try: + self._get_sync() + except TimeoutError: + # Timeout is expected - board is rebooting + pass + + def send_reboot_commands( + self, baudrates: list[int], use_protocol_splitter: bool = False + ) -> bool: + """Send reboot commands to try to enter bootloader. + + Tries MAVLink and NSH reboot commands at various baud rates. + + Args: + baudrates: List of baud rates to try + use_protocol_splitter: Use protocol splitter framing + + Returns: + True if commands were sent, False if no more baud rates to try + """ + for baudrate in baudrates: + try: + self.transport.set_baudrate(baudrate) + except (serial.SerialException, NotImplementedError): + continue + + logger.info(f"Sending reboot command at {baudrate} baud") + + def send(data: bytes) -> None: + if use_protocol_splitter: + self._send_protocol_splitter_frame(data) + else: + self.transport.send(data) + + try: + self.transport.flush() + send(self.MAVLINK_REBOOT_ID0) + send(self.MAVLINK_REBOOT_ID1) + send(self.NSH_INIT) + send(self.NSH_REBOOT_BL) + send(self.NSH_INIT) + send(self.NSH_REBOOT) + self.transport.flush() + except Exception as e: + logger.debug(f"Error sending reboot: {e}") + continue + + return True + + return False + + def _send_protocol_splitter_frame(self, data: bytes) -> None: + """Send data with protocol splitter framing. + + Header format: + - Byte 0: Magic ('S' = 0x53) + - Byte 1: Type (0) | Length high bits (7 bits) + - Byte 2: Length low bits + - Byte 3: Checksum (XOR of bytes 0-2) + """ + magic = 0x53 + len_h = (len(data) >> 8) & 0x7F + len_l = len(data) & 0xFF + checksum = magic ^ len_h ^ len_l + + header = bytes([magic, len_h, len_l, checksum]) + self.transport.send(header + data) + + +# ============================================================================= +# Port Detection +# ============================================================================= + + +class PortDetector: + """Detects PX4-compatible serial ports.""" + + # Platform-specific port patterns + LINUX_PATTERNS = [ + "/dev/serial/by-id/*PX4*", + "/dev/serial/by-id/*px4*", + "/dev/serial/by-id/*3D_Robotics*", + "/dev/serial/by-id/*Autopilot*", + "/dev/serial/by-id/*Bitcraze*", + "/dev/serial/by-id/*Gumstix*", + "/dev/serial/by-id/*Hex*", + "/dev/serial/by-id/*Holybro*", + "/dev/serial/by-id/*Cube*", + "/dev/serial/by-id/*ArduPilot*", + "/dev/serial/by-id/*BL_FMU*", + "/dev/serial/by-id/*_BL*", + "/dev/ttyACM*", + "/dev/ttyUSB*", + ] + + MACOS_PATTERNS = [ + "/dev/tty.usbmodemPX*", + "/dev/tty.usbmodem*", + "/dev/cu.usbmodemPX*", + "/dev/cu.usbmodem*", + ] + + WINDOWS_PATTERNS = [ + "COM*", + ] + + def __init__(self): + self.platform = sys.platform + + def detect_ports(self) -> list[str]: + """Detect available PX4-compatible serial ports. + + Returns: + List of port paths, prioritized by likelihood of being PX4 + """ + ports = set() + + # First, try USB VID/PID detection + vid_pid_ports = self._detect_by_vid_pid() + ports.update(vid_pid_ports) + + # Then try platform-specific patterns + pattern_ports = self._detect_by_patterns() + ports.update(pattern_ports) + + # Sort by priority (VID/PID matches first) + result = [] + for port in vid_pid_ports: + if port in ports: + result.append(port) + ports.discard(port) + result.extend(sorted(ports)) + + logger.info(f"Detected {len(result)} potential ports: {result}") + return result + + def _detect_by_vid_pid(self) -> list[str]: + """Detect ports by USB Vendor/Product ID. + + Returns: + List of ports matching known PX4 VID/PIDs + """ + ports = [] + known_ids = {(vid, pid) for vid, pid, _ in PX4_USB_IDS} + + try: + for port_info in serial.tools.list_ports.comports(): + if (port_info.vid, port_info.pid) in known_ids: + logger.debug( + f"Found PX4 device: {port_info.device} " + f"(VID=0x{port_info.vid:04X}, PID=0x{port_info.pid:04X})" + ) + ports.append(port_info.device) + except Exception as e: + logger.debug(f"VID/PID detection failed: {e}") + + return ports + + def _detect_by_patterns(self) -> list[str]: + """Detect ports by platform-specific glob patterns. + + Returns: + List of ports matching patterns + """ + if self.platform.startswith("linux"): + patterns = self.LINUX_PATTERNS + elif self.platform == "darwin": + patterns = self.MACOS_PATTERNS + elif self.platform.startswith("win") or self.platform == "cygwin": + patterns = self.WINDOWS_PATTERNS + else: + patterns = [] + + ports = [] + for pattern in patterns: + matches = glob.glob(pattern) + ports.extend(matches) + + return list(set(ports)) + + def expand_patterns(self, patterns: list[str]) -> list[str]: + """Expand glob patterns to actual port paths. + + Args: + patterns: List of port paths or glob patterns + + Returns: + List of expanded port paths + """ + ports = [] + for pattern in patterns: + if "*" in pattern or "?" in pattern: + matches = glob.glob(pattern) + if matches: + ports.extend(matches) + else: + logger.debug(f"Pattern matched no ports: {pattern}") + else: + ports.append(pattern) + + return list(set(ports)) + + +# ============================================================================= +# Progress Display +# ============================================================================= + + +class UploadProgressBar: + """Unified progress bar for the entire upload process. + + Shows a single progress bar with phases: + - Erase: 0-49% + - Program: 50-99% + - Verify: 99-100% + """ + + ERASE_START = 0 + ERASE_END = 49 + PROGRAM_START = 50 + PROGRAM_END = 99 + VERIFY_START = 99 + VERIFY_END = 100 + + def __init__(self, noninteractive: bool = False, json_output: bool = False): + # Use noninteractive mode if flag is set OR if not a TTY + self._json = json_output + self._noninteractive = json_output or noninteractive or not sys.stdout.isatty() + self._start_time = time.monotonic() + self._last_percent = -1 + self._last_printed_percent = -1 + self._phase = "Erase" + + def _render(self, percent: int) -> None: + """Render the progress bar.""" + if not self._noninteractive and percent == self._last_percent and percent < 100: + return + + if self._noninteractive: + # Print at 5% increments (0, 5, 10, ...) plus 99% for verify + next_milestone = ((self._last_printed_percent // 5) + 1) * 5 + if self._last_printed_percent < 0: + next_milestone = 0 + # Special case: print 99% only when in Verify phase + is_verify_99 = ( + self._phase == "Verify" + and self._last_printed_percent < 99 + and percent >= 99 + ) + if is_verify_99: + next_milestone = 99 + should_print = percent >= next_milestone or ( + percent >= 100 and self._last_printed_percent < 100 + ) + # Don't print 99% unless we're in Verify phase + if ( + should_print + and percent >= 99 + and percent < 100 + and self._phase != "Verify" + ): + should_print = False + if should_print: + # Print at the milestone, not the actual percent + if percent >= 100: + print_percent = 100 + elif percent >= 99 and self._phase == "Verify": + print_percent = 99 + else: + print_percent = (percent // 5) * 5 + if print_percent > self._last_printed_percent: + if print_percent >= 100: + phase = "done" + elif self._phase == "Erase": + phase = "erasing" + elif self._phase == "Program": + phase = "programming" + elif self._phase == "Verify": + phase = "verifying" + else: + phase = self._phase.lower() + if self._json: + print( + json.dumps( + { + "type": "progress", + "phase": phase, + "percent": print_percent, + } + ) + ) + else: + print(f"{phase.capitalize()}, progress: {print_percent}%") + self._last_printed_percent = print_percent + self._last_percent = percent + return + + # Step through each percent for smooth animation + if self._last_percent >= 0 and percent > self._last_percent + 1: + for p in range(self._last_percent + 1, percent): + self._render_single(p) + time.sleep(0.02) + + self._render_single(percent) + self._last_percent = percent + + def _render_single(self, percent: int) -> None: + """Render a single frame of the progress bar.""" + bar_width = 30 + filled_exact = bar_width * percent / 100.0 + filled_full = int(filled_exact) + filled_partial = filled_exact - filled_full + + # Unicode block characters for smooth progress + blocks = " ▏▎▍▌▋▊▉█" + partial_idx = int(filled_partial * 8) + + bar = "█" * filled_full + if filled_full < bar_width: + bar += blocks[partial_idx] + bar += " " * (bar_width - filled_full - 1) + + line = f"{self._phase:8s} ▕{bar}▏ {percent:3d}%" + print(f"\r{line}", end="", flush=True) + + def update_erase(self, current: float, total: float) -> None: + """Update progress during erase phase (0-45%).""" + self._phase = "Erase" + if total <= 0: + return + phase_progress = min(current / total, 1.0) + percent = int( + self.ERASE_START + phase_progress * (self.ERASE_END - self.ERASE_START) + ) + self._render(percent) + + def update_program(self, current: float, total: float) -> None: + """Update progress during program phase (50-99%).""" + self._phase = "Program" + if total <= 0: + return + phase_progress = min(current / total, 1.0) + percent = int( + self.PROGRAM_START + + phase_progress * (self.PROGRAM_END - self.PROGRAM_START) + ) + self._render(percent) + + def update_verify(self, current: float, total: float) -> None: + """Update progress during verify phase (90-100%).""" + self._phase = "Verify" + if total <= 0: + return + phase_progress = min(current / total, 1.0) + percent = int( + self.VERIFY_START + phase_progress * (self.VERIFY_END - self.VERIFY_START) + ) + self._render(percent) + + def finish(self) -> None: + """Complete the progress bar and show summary.""" + # Show "Verify" at 100% briefly so user sees verification passed + self._phase = "Verify" + self._last_percent = -1 # Force render + self._render(100) + + elapsed = time.monotonic() - self._start_time + + if self._noninteractive: + if self._json: + print(json.dumps({"type": "complete", "elapsed_seconds": int(elapsed)})) + else: + print(f"\nUploaded in {int(elapsed)}s") + return + + # Interactive mode: show 100% briefly, then clear and print summary + time.sleep(0.5) + print("\r\033[K", end="") + print(f"Uploaded in {int(elapsed)}s") + + +# ============================================================================= +# Uploader +# ============================================================================= + + +@dataclass +class UploaderConfig: + """Configuration for uploader.""" + + port: Optional[str] = None + baud_bootloader: int = 115200 + baud_flightstack: list[int] = field(default_factory=lambda: [57600]) + force: bool = False + force_erase: bool = False + boot_delay: Optional[int] = None + use_protocol_splitter: bool = False + retry_count: int = 3 + windowed: bool = False + noninteractive: bool = False + json_output: bool = False + + +class Uploader: + """Orchestrates firmware upload to PX4 bootloader.""" + + def __init__(self, config: UploaderConfig): + self.config = config + self.port_detector = PortDetector() + + def _print_message(self, message_type: str, **kwargs) -> None: + """Print a message, either as JSON or plain text.""" + if self.config.json_output: + # Format chip_id as hex string for JSON + if "chip_id" in kwargs and kwargs["chip_id"] is not None: + kwargs["chip_id"] = f"0x{kwargs['chip_id']:08X}" + # Remove None values from JSON output + kwargs = {k: v for k, v in kwargs.items() if v is not None} + print(json.dumps({"type": message_type, **kwargs})) + else: + # Format as plain text based on message type + if message_type == "board": + print( + f"\nFound board {kwargs['board_type']},{kwargs['board_rev']} " + f"protocol v{kwargs['protocol_version']} on {kwargs['port']}" + ) + elif message_type == "firmware": + print( + f"\nFirmware: board_id={kwargs['board_id']}, " + f"revision={kwargs['board_revision']}" + ) + print( + f"Size: {kwargs['image_size']} bytes ({kwargs['usage_percent']:.1f}%)" + ) + print(f"Bootloader version: {kwargs['bootloader_version']}") + elif message_type == "board_info": + if kwargs.get("serial"): + print(f"Serial: {kwargs['serial']}") + if kwargs.get("chip_id"): + print(f"Chip: 0x{kwargs['chip_id']:08X}") + if kwargs.get("chip_family"): + print(f"Family: {kwargs['chip_family']}") + if kwargs.get("chip_revision"): + print(f"Revision: {kwargs['chip_revision']}") + print(f"Flash: {kwargs['flash_size']} bytes") + print(f"Windowed mode: {'yes' if kwargs.get('windowed') else 'no'}") + + def upload(self, firmware_paths: list[str]) -> bool: + """Upload firmware to connected board. + + Args: + firmware_paths: List of firmware file paths to try + + Returns: + True if upload successful + + Raises: + UploadError: If upload fails + """ + # Load all firmware files + firmwares = [] + for path in firmware_paths: + try: + fw = Firmware(path) + firmwares.append(fw) + except FirmwareError as e: + logger.error(f"Failed to load {path}: {e}") + if len(firmware_paths) == 1: + raise + + if not firmwares: + raise FirmwareError("No valid firmware files") + + # Determine ports to try + if self.config.port: + patterns = self.config.port.split(",") + ports = self.port_detector.expand_patterns(patterns) + else: + ports = self.port_detector.detect_ports() + + if not ports: + raise ConnectionError("No serial ports found") + + logger.info(f"Trying ports: {ports}") + + # Send MAVLink release command to GCS + self._send_gcs_release() + + # Try each port + last_error = None + for port in ports: + try: + return self._upload_to_port(port, firmwares) + except BoardMismatchError as e: + logger.warning(f"Board mismatch on {port}: {e}") + last_error = e + continue + except (ConnectionError, TimeoutError) as e: + logger.debug(f"Connection failed on {port}: {e}") + last_error = e + continue + except UploadError as e: + logger.error(f"Upload failed on {port}: {e}") + last_error = e + raise + + if last_error: + raise last_error + raise ConnectionError("No bootloader found on any port") + + def _upload_to_port(self, port: str, firmwares: list[Firmware]) -> bool: + """Attempt upload on a specific port. + + Args: + port: Serial port path + firmwares: List of firmware options + + Returns: + True if successful + + Raises: + Various UploadError subclasses on failure + """ + logger.info(f"Trying port {port}") + + transport = SerialTransport( + port, + baudrate=self.config.baud_bootloader, + ) + + try: + transport.open() + except ConnectionError: + return False + + protocol = BootloaderProtocol( + transport, + windowed=self.config.windowed, + ) + + try: + # Try to identify bootloader + if not self._try_identify(transport, protocol): + return False + + # Find matching firmware + firmware = self._select_firmware(firmwares, protocol) + + # Perform upload + self._do_upload(protocol, firmware) + return True + + finally: + transport.close() + + def _try_identify( + self, transport: SerialTransport, protocol: BootloaderProtocol + ) -> bool: + """Try to identify the bootloader, sending reboot if needed. + + Args: + transport: Serial transport + protocol: Bootloader protocol handler + + Returns: + True if bootloader identified + """ + # First try to identify without reboot + try: + protocol.identify() + self._print_message( + "board", + board_type=protocol.board_type, + board_rev=protocol.board_rev, + protocol_version=protocol.bl_rev, + port=transport.port_name, + ) + return True + except (ProtocolError, TimeoutError): + pass + + # Try rebooting at each baud rate + for baud in self.config.baud_flightstack: + if not self.config.json_output: + print( + f"Attempting reboot on {transport.port_name} at {baud} baud...", + file=sys.stderr, + ) + + try: + transport.set_baudrate(baud) + except Exception: + continue + + # Send reboot commands multiple times to increase reliability + # The board might be busy and miss the first command + for attempt in range(3): + try: + transport.reset_buffers() + + # Send MAVLink reboot-to-bootloader commands + # Send broadcast (0/0) first, then targeted (1/0) + transport.send(protocol.MAVLINK_REBOOT_ID0) + transport.send(protocol.MAVLINK_REBOOT_ID1) + transport.flush() + + # Give MAVLink stack time to process + time.sleep(0.1) + + # Send NSH reboot-to-bootloader command + transport.send(protocol.NSH_INIT) + time.sleep(0.05) + transport.send(protocol.NSH_REBOOT_BL) + transport.flush() + + time.sleep(0.2) + except Exception: + pass + + # Wait for reboot - give the board time to process and restart + time.sleep(0.5) + transport.close() + time.sleep(0.5) + + # Reopen at bootloader baud rate and try to identify + try: + transport.set_baudrate(self.config.baud_bootloader) + transport.open() + except Exception: + continue + + # Try to identify multiple times - board may take time to enter bootloader + for identify_attempt in range(5): + try: + protocol.identify() + self._print_message( + "board", + board_type=protocol.board_type, + board_rev=protocol.board_rev, + protocol_version=protocol.bl_rev, + port=transport.port_name, + ) + return True + except (ProtocolError, TimeoutError): + # Board may still be rebooting, wait a bit and retry + time.sleep(0.3) + + return False + + def _select_firmware( + self, firmwares: list[Firmware], protocol: BootloaderProtocol + ) -> Firmware: + """Select appropriate firmware for the board. + + Args: + firmwares: Available firmware options + protocol: Protocol with board info + + Returns: + Selected firmware + + Raises: + BoardMismatchError: If no suitable firmware + """ + for fw in firmwares: + if fw.board_id == protocol.board_type: + if len(firmwares) > 1: + print(f"Using firmware {fw.path}") + return fw + + if self.config.force and len(firmwares) == 1: + print( + f"WARNING: Firmware board_id={firmwares[0].board_id} " + f"does not match device board_id={protocol.board_type}" + ) + print("FORCED UPLOAD, FLASHING ANYWAY!") + return firmwares[0] + + raise BoardMismatchError( + f"No suitable firmware for board {protocol.board_type}", + details=f"available: {[fw.board_id for fw in firmwares]}", + ) + + def _do_upload(self, protocol: BootloaderProtocol, firmware: Firmware) -> None: + """Perform the actual upload sequence. + + Args: + protocol: Bootloader protocol handler + firmware: Firmware to upload + """ + # Print firmware info + self._print_message( + "firmware", + board_id=firmware.board_id, + board_revision=firmware.board_revision, + image_size=firmware.image_size, + usage_percent=firmware.usage_percent, + bootloader_version=protocol.version, + ) + + # Check for silicon errata (bootloader v4 on Pixhawk) + if protocol.bl_rev == 4 and firmware.board_id == 9: + if firmware.image_size > 1032192 and not self.config.force: + raise SiliconErrataError( + "Board uses bootloader v4 and cannot safely flash >1MB.\n" + "Use px4_fmu-v2_default or update the bootloader.\n" + "Use --force to override if you know the board is safe." + ) + + # Check flash size + if protocol.fw_maxsize < firmware.image_size: + raise FirmwareError( + f"Firmware too large ({firmware.image_size} bytes) " + f"for flash ({protocol.fw_maxsize} bytes)" + ) + + # Check for undersized config + if ( + protocol.bl_rev >= 5 + and protocol.fw_maxsize > firmware.image_maxsize + and not self.config.force + ): + print( + f"WARNING: Board flash ({protocol.fw_maxsize} bytes) " + f"larger than firmware config ({firmware.image_maxsize} bytes)" + ) + + # Print OTP/SN info + self._print_board_info(protocol) + + # Create unified progress bar + if not self.config.json_output: + print() + progress = UploadProgressBar( + noninteractive=self.config.noninteractive, + json_output=self.config.json_output, + ) + + # Erase + protocol.erase( + force_full=self.config.force_erase, + progress_callback=progress.update_erase, + ) + + # Program + protocol.program(firmware, progress_callback=progress.update_program) + + # Verify + protocol.verify(firmware, progress_callback=progress.update_verify) + + # Set boot delay if requested + if self.config.boot_delay is not None: + protocol.set_boot_delay(self.config.boot_delay) + + # Reboot and show summary + protocol.reboot() + progress.finish() + + def _print_board_info(self, protocol: BootloaderProtocol) -> None: + """Print board OTP and chip info.""" + self._print_message( + "board_info", + serial=protocol.sn.hex() if protocol.sn else None, + chip_id=protocol.chip_id if protocol.chip_id else None, + chip_family=protocol.chip_family if protocol.chip_family else None, + chip_revision=protocol.chip_revision if protocol.chip_revision else None, + flash_size=protocol.fw_maxsize, + windowed=protocol._windowed_mode, + ) + + def _send_gcs_release(self) -> None: + """Send UDP message to release serial port from GCS.""" + try: + heartbeat = bytes.fromhex("fe097001010000000100020c5103033c8a") + command = bytes.fromhex( + "fe210101014c0000000000000000000000000000000000" + "00000000000000803f00000000f6000000008459" + ) + + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.sendto(heartbeat, ("127.0.0.1", 14550)) + sock.sendto(command, ("127.0.0.1", 14550)) + sock.close() + except Exception: + pass # Non-critical + + +# ============================================================================= +# Main Entry Point +# ============================================================================= + + +def main() -> int: + """Main entry point.""" + parser = argparse.ArgumentParser( + description="PX4 Firmware Uploader v2", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s firmware.px4 + %(prog)s --port /dev/ttyACM0 firmware.px4 + %(prog)s --port /dev/serial/by-id/*PX4* firmware.px4 + %(prog)s -v --force firmware.px4 + """, + ) + + parser.add_argument("firmware", nargs="+", help="Firmware file(s) to upload") + parser.add_argument( + "--port", + "-p", + help="Serial port(s) to use (comma-separated, supports wildcards). " + "If not specified, auto-detects PX4 devices.", + ) + parser.add_argument( + "--baud-bootloader", + type=int, + default=115200, + help="Bootloader baud rate (default: 115200)", + ) + parser.add_argument( + "--baud-flightstack", + default="57600", + help="Flight stack baud rate(s) for reboot (comma-separated, default: 57600)", + ) + parser.add_argument( + "--force", + "-f", + action="store_true", + help="Force upload even if board ID doesn't match", + ) + parser.add_argument( + "--force-erase", + action="store_true", + help="Force full chip erase (v6+ bootloader)", + ) + parser.add_argument( + "--boot-delay", type=int, help="Boot delay in milliseconds to store in flash" + ) + parser.add_argument( + "--use-protocol-splitter-format", + action="store_true", + help="Use protocol splitter framing for reboot commands", + ) + parser.add_argument( + "--windowed", + action="store_true", + help="Use windowed mode for faster uploads on real serial ports (FTDI)", + ) + parser.add_argument( + "--verbose", "-v", action="store_true", help="Enable verbose output" + ) + parser.add_argument( + "--debug", + "-d", + action="store_true", + help="Enable debug output (includes protocol traces)", + ) + parser.add_argument( + "--noninteractive", + action="store_true", + help="Non-interactive mode: print progress every 5%% for tools to parse", + ) + parser.add_argument( + "--noninteractive-json", + action="store_true", + help="Non-interactive JSON mode: print progress as JSON lines", + ) + + args = parser.parse_args() + + # Setup logging + setup_logging(verbose=args.verbose, debug=args.debug) + + # Warn about ModemManager on Linux + if ( + not args.noninteractive_json + and sys.platform.startswith("linux") + and os.path.exists("/usr/sbin/ModemManager") + ): + print("=" * 80) + print("WARNING: ModemManager detected. It may interfere with PX4 devices.") + print("Consider: sudo systemctl disable ModemManager") + print("=" * 80) + + # Parse baud rates + baud_flightstack = [int(x) for x in args.baud_flightstack.split(",")] + + # Create config + config = UploaderConfig( + port=args.port, + baud_bootloader=args.baud_bootloader, + baud_flightstack=baud_flightstack, + force=args.force, + force_erase=args.force_erase, + boot_delay=args.boot_delay, + use_protocol_splitter=args.use_protocol_splitter_format, + windowed=args.windowed, + noninteractive=args.noninteractive or args.noninteractive_json, + json_output=args.noninteractive_json, + ) + + if not args.noninteractive_json: + if args.use_protocol_splitter_format: + print("Using protocol splitter format for reboot commands") + print("Waiting for bootloader...") + + uploader = Uploader(config) + + try: + # Keep trying until we find a board or user interrupts + while True: + try: + if uploader.upload(args.firmware): + return 0 + except BoardMismatchError: + # No suitable firmware for this board + return 2 + except (ConnectionError, TimeoutError): + # No device found yet, keep trying + time.sleep(0.05) + except UploadError as e: + if args.noninteractive_json: + print(json.dumps({"type": "error", "message": str(e)})) + else: + print(f"\nError: {e}", file=sys.stderr) + return 1 + + except KeyboardInterrupt: + if args.noninteractive_json: + print(json.dumps({"type": "error", "message": "Upload aborted by user"})) + else: + print("\nUpload aborted by user.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/Tools/px4airframes/srcparser.py b/Tools/px4airframes/srcparser.py index 56c3ce52be..dc60cfa7fe 100644 --- a/Tools/px4airframes/srcparser.py +++ b/Tools/px4airframes/srcparser.py @@ -14,7 +14,6 @@ class AirframeGroup(object): self.af_class = af_class self.airframes = [] - def AddAirframe(self, airframe): """ Add airframe to the airframe group @@ -107,6 +106,8 @@ class AirframeGroup(object): return "Balloon" elif (self.type == "Vectored 6 DOF UUV"): return "Vectored6DofUUV" + elif self.type == "Free-Flyer": + return "FreeFlyer" return "AirframeUnknown" def GetAirframes(self): diff --git a/Tools/px4moduledoc/srcparser.py b/Tools/px4moduledoc/srcparser.py index 8b56e7bb08..749acef762 100644 --- a/Tools/px4moduledoc/srcparser.py +++ b/Tools/px4moduledoc/srcparser.py @@ -15,7 +15,7 @@ class ModuleDocumentation(object): # TOC in https://github.com/PX4/PX4-Autopilot/blob/main/docs/en/SUMMARY.md valid_categories = ['driver', 'estimator', 'controller', 'system', 'communication', 'command', 'template', 'simulation', 'autotune'] - valid_subcategories = ['', 'camera', 'distance_sensor', 'imu', 'ins', 'airspeed_sensor', + valid_subcategories = ['', 'adc', 'camera', 'distance_sensor', 'imu', 'ins', 'airspeed_sensor', 'magnetometer', 'baro', 'optical_flow', 'radio_control','rpm_sensor', 'transponder'] max_line_length = 80 # wrap lines that are longer than this diff --git a/Tools/px_uploader.py b/Tools/px_uploader.py deleted file mode 100755 index b83359785b..0000000000 --- a/Tools/px_uploader.py +++ /dev/null @@ -1,983 +0,0 @@ -#!/usr/bin/env python3 -############################################################################ -# -# Copyright (c) 2012-2024 PX4 Development Team. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name PX4 nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -# -# Serial firmware uploader for the PX4FMU bootloader -# -# The PX4 firmware file is a JSON-encoded Python object, containing -# metadata fields and a zlib-compressed base64-encoded firmware image. -# -# The uploader uses the following fields from the firmware file: -# -# image -# The firmware that will be uploaded. -# image_size -# The size of the firmware in bytes. -# board_id -# The board for which the firmware is intended. -# board_revision -# Currently only used for informational purposes. -# - -import sys -import argparse -import binascii -import socket -import struct -import json -import zlib -import base64 -import time -import array -import os - -from sys import platform as _platform - -try: - import serial -except ImportError as e: - print(f"Failed to import serial: {e}") - print("") - print("You may need to install it using:") - print(" python -m pip install pyserial") - print("") - sys.exit(1) - - -# Detect python version -if sys.version_info[0] < 3: - raise RuntimeError("Python 2 is not supported. Please try again using Python 3.") - sys.exit(1) - - -# Use monotonic time where available -def _time(): - try: - return time.monotonic() - except Exception: - return time.time() - -class FirmwareNotSuitableException(Exception): - def __init__(self, message): - super(FirmwareNotSuitableException, self).__init__(message) - - -class firmware(object): - '''Loads a firmware file''' - - desc = {} - image = bytes() - crctab = array.array('I', [ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d]) - crcpad = bytearray(b'\xff\xff\xff\xff') - - def __init__(self, path): - - # read the file - f = open(path, "r") - self.desc = json.load(f) - f.close() - - self.image = bytearray(zlib.decompress(base64.b64decode(self.desc['image']))) - - # pad image to 4-byte length - while ((len(self.image) % 4) != 0): - self.image.extend(b'\xff') - - def property(self, propname): - return self.desc[propname] - - def __crc32(self, bytes, state): - for byte in bytes: - index = (state ^ byte) & 0xff - state = self.crctab[index] ^ (state >> 8) - return state - - def crc(self, padlen): - state = self.__crc32(self.image, int(0)) - for _ in range(len(self.image), (padlen - 1), 4): - state = self.__crc32(self.crcpad, state) - return state - - -class uploader: - '''Uploads a firmware file to the PX4 bootloader''' - - # protocol bytes - INSYNC = b'\x12' - EOC = b'\x20' - - # reply bytes - OK = b'\x10' - FAILED = b'\x11' - INVALID = b'\x13' # rev3+ - BAD_SILICON_REV = b'\x14' # rev5+ - - # command bytes - NOP = b'\x00' # guaranteed to be discarded by the bootloader - GET_SYNC = b'\x21' - GET_DEVICE = b'\x22' - CHIP_ERASE = b'\x23' - CHIP_VERIFY = b'\x24' # rev2 only - PROG_MULTI = b'\x27' - READ_MULTI = b'\x28' # rev2 only - GET_CRC = b'\x29' # rev3+ - GET_OTP = b'\x2a' # rev4+ , get a word from OTP area - GET_SN = b'\x2b' # rev4+ , get a word from SN area - GET_CHIP = b'\x2c' # rev5+ , get chip version - SET_BOOT_DELAY = b'\x2d' # rev5+ , set boot delay - GET_CHIP_DES = b'\x2e' # rev5+ , get chip description in ASCII - GET_VERSION = b'\x2f' # rev5+ , get bootloader version in ASCII - CHIP_FULL_ERASE = b'\x40' # full erase of flash, rev6+ - MAX_DES_LENGTH = 20 - - REBOOT = b'\x30' - - INFO_BL_REV = b'\x01' # bootloader protocol revision - BL_REV_MIN = 2 # minimum supported bootloader protocol - BL_REV_MAX = 5 # maximum supported bootloader protocol - INFO_BOARD_ID = b'\x02' # board type - INFO_BOARD_REV = b'\x03' # board revision - INFO_FLASH_SIZE = b'\x04' # max firmware size in bytes - - PROG_MULTI_MAX = 252 # protocol max is 255, must be multiple of 4 - READ_MULTI_MAX = 252 # protocol max is 255 - - NSH_INIT = bytearray(b'\x0d\x0d\x0d') - NSH_REBOOT_BL = b"reboot -b\n" - NSH_REBOOT = b"reboot\n" - MAVLINK_REBOOT_ID1 = bytearray(b'\xfe\x21\x72\xff\x00\x4c\x00\x00\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x01\x00\x00\x53\x6b') - MAVLINK_REBOOT_ID0 = bytearray(b'\xfe\x21\x45\xff\x00\x4c\x00\x00\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x00\x00\x00\xcc\x37') - - MAX_FLASH_PRGRAM_TIME = 0.001 # Time on an F7 to send SYNC, RESULT from last data in multi RXed - - def __init__(self, portname, baudrate_bootloader, baudrate_flightstack): - # Open the port, keep the default timeout short so we can poll quickly. - # On some systems writes can suddenly get stuck without having a - # write_timeout > 0 set. - # chartime 8n1 * bit rate is us - self.chartime = 10 * (1.0 / baudrate_bootloader) - - # we use a window approche to SYNC, gathring - self.window = 0 - self.window_max = 256 - self.window_per = 2 # Sync, - self.ackWindowedMode = False # Assume Non Widowed mode for all USB CDC - self.port = serial.Serial(portname, baudrate_bootloader, timeout=0.5, write_timeout=0) - self.otp = b'' - self.sn = b'' - self.baudrate_bootloader = baudrate_bootloader - self.baudrate_flightstack = baudrate_flightstack - self.baudrate_flightstack_idx = -1 - self.force_erase = False - - def close(self): - if self.port is not None: - self.port.close() - - def open(self): - # upload timeout - timeout = _time() + 0.2 - - # attempt to open the port while it exists and until timeout occurs - while self.port is not None: - portopen = True - try: - portopen = self.port.is_open - except AttributeError: - portopen = self.port.isOpen() - - if not portopen and _time() < timeout: - try: - self.port.open() - except OSError: - # wait for the port to be ready - time.sleep(0.04) - except serial.SerialException: - # if open fails, try again later - time.sleep(0.04) - else: - break - - # debugging code - def __probe(self, state): - # self.port.setRTS(state) - return - - def __send(self, c): - # print("send " + binascii.hexlify(c)) - self.port.write(c) - - def __recv(self, count=1): - c = self.port.read(count) - if len(c) < 1: - raise RuntimeError("timeout waiting for data (%u bytes)" % count) - # print("recv " + binascii.hexlify(c)) - return c - - def __recv_int(self): - raw = self.__recv(4) - val = struct.unpack(" for a window of programing - # in about 13.81 Ms for 256 blocks written - def __ackSyncWindow(self, count): - if (count > 0): - data = bytearray(bytes(self.__recv(count))) - if (len(data) != count): - raise RuntimeError("Ack Window %i not %i " % (len(data), count)) - for i in range(0, len(data), 2): - if bytes([data[i]]) != self.INSYNC: - raise RuntimeError("unexpected %s instead of INSYNC" % data[i]) - if bytes([data[i+1]]) == self.INVALID: - raise RuntimeError("bootloader reports INVALID OPERATION") - if bytes([data[i+1]]) == self.FAILED: - raise RuntimeError("bootloader reports OPERATION FAILED") - if bytes([data[i+1]]) != self.OK: - raise RuntimeError("unexpected response 0x%x instead of OK" % ord(data[i+1])) - - # attempt to get back into sync with the bootloader - def __sync(self): - # send a stream of ignored bytes longer than the longest possible conversation - # that we might still have in progress - # self.__send(uploader.NOP * (uploader.PROG_MULTI_MAX + 2)) - self.port.flushInput() - self.__send(uploader.GET_SYNC + - uploader.EOC) - self.__getSync() - - def __trySync(self): - try: - self.port.flush() - if (self.__recv() != self.INSYNC): - # print("unexpected 0x%x instead of INSYNC" % ord(c)) - return False - c = self.__recv() - if (c == self.BAD_SILICON_REV): - raise NotImplementedError() - if (c != self.OK): - # print("unexpected 0x%x instead of OK" % ord(c)) - return False - return True - - except NotImplementedError: - raise RuntimeError("Programing not supported for this version of silicon!\n" - "See https://docs.px4.io/main/en/flight_controller/silicon_errata.html") - except RuntimeError: - # timeout, no response yet - return False - - # attempt to determins if the device is CDCACM or A FTDI - def __determineInterface(self): - self.port.flushInput() - # Set a baudrate that can not work on a real serial port - # in that it is 233% off. - try: - self.port.baudrate = self.baudrate_bootloader * 2.33 - except NotImplementedError as e: - # This error can occur because pySerial on Windows does not support odd baudrates - print(f"{e} -> could not check for FTDI device, assuming USB connection") - return - - self.__send(uploader.GET_SYNC + - uploader.EOC) - try: - self.__getSync(False) - except RuntimeError: - # if it fails we are on a real serial port - only leave this enabled on Windows - if sys.platform.startswith('win'): - self.ackWindowedMode = True - finally: - try: - self.port.baudrate = self.baudrate_bootloader - except Exception: - pass - - # send the GET_DEVICE command and wait for an info parameter - def __getInfo(self, param): - self.__send(uploader.GET_DEVICE + param + uploader.EOC) - value = self.__recv_int() - self.__getSync() - return value - - # send the GET_OTP command and wait for an info parameter - def __getOTP(self, param): - t = struct.pack("I", param) # int param as 32bit ( 4 byte ) char array. - self.__send(uploader.GET_OTP + t + uploader.EOC) - value = self.__recv(4) - self.__getSync() - return value - - # send the GET_SN command and wait for an info parameter - def __getSN(self, param): - t = struct.pack("I", param) # int param as 32bit ( 4 byte ) char array. - self.__send(uploader.GET_SN + t + uploader.EOC) - value = self.__recv(4) - self.__getSync() - return value - - # send the GET_CHIP command - def __getCHIP(self): - self.__send(uploader.GET_CHIP + uploader.EOC) - value = self.__recv_int() - self.__getSync() - return value - - # send the GET_CHIP command - def __getCHIPDes(self): - self.__send(uploader.GET_CHIP_DES + uploader.EOC) - length = self.__recv_int() - value = self.__recv(length) - self.__getSync() - pieces = value.split(b",") - return pieces - - def __getVersion(self): - self.__send(uploader.GET_VERSION + uploader.EOC) - try: - length = self.__recv_int() - value = self.__recv(length) - self.__getSync() - except RuntimeError: - # Bootloader doesn't support version call - return "unknown" - return value.decode() - - def __drawProgressBar(self, label, progress, maxVal): - if maxVal < progress: - progress = maxVal - - percent = (float(progress) / float(maxVal)) * 100.0 - - redraw = "\r" if sys.stdout.isatty() else "\n" - sys.stdout.write("%s%s: [%-20s] %.1f%%" % (redraw, label, '='*int(percent/5.0), percent)) - sys.stdout.flush() - - # send the CHIP_ERASE command and wait for the bootloader to become ready - def __erase(self, label): - print(f"Windowed mode: {self.ackWindowedMode}") - print("\n", end='') - - if self.force_erase: - print("Trying force erase of full chip...\n") - self.__send(uploader.CHIP_FULL_ERASE + - uploader.EOC) - else: - self.__send(uploader.CHIP_ERASE + - uploader.EOC) - - # erase is very slow, give it 30s - deadline = _time() + 30.0 - while _time() < deadline: - - usualEraseDuration = 15.0 - estimatedTimeRemaining = deadline-_time() - if estimatedTimeRemaining >= usualEraseDuration: - self.__drawProgressBar(label, 30.0-estimatedTimeRemaining, usualEraseDuration) - else: - self.__drawProgressBar(label, 10.0, 10.0) - sys.stdout.write(" (timeout: %d seconds) " % int(deadline-_time())) - sys.stdout.flush() - - if self.__trySync(): - self.__drawProgressBar(label, 10.0, 10.0) - if self.force_erase: - print("\nForce erase done.\n") - return - - if self.force_erase: - raise RuntimeError("timed out waiting for erase, force erase is likely not supported by bootloader!") - else: - raise RuntimeError("timed out waiting for erase") - - # send a PROG_MULTI command to write a collection of bytes - def __program_multi(self, data, windowMode): - - length = len(data).to_bytes(1, byteorder='big') - - self.__send(uploader.PROG_MULTI) - self.__send(length) - self.__send(data) - self.__send(uploader.EOC) - if (not windowMode): - self.__getSync(False) - else: - # The following is done to have minimum delay on the transmission - # of the ne fw. The per block cost of __getSync was about 16 mS per. - # Passively wait on Sync and Result using board rates and - # N.B. attempts to activly wait on InWating still carried 8 mS of overhead - self.__probe(False) - self.__probe(True) - time.sleep((ord(length) * self.chartime) + uploader.MAX_FLASH_PRGRAM_TIME) - self.__probe(False) - - # verify multiple bytes in flash - def __verify_multi(self, data): - - length = len(data).to_bytes(1, byteorder='big') - - self.__send(uploader.READ_MULTI) - self.__send(length) - self.__send(uploader.EOC) - self.port.flush() - programmed = self.__recv(len(data)) - if programmed != data: - print("got " + binascii.hexlify(programmed)) - print("expect " + binascii.hexlify(data)) - return False - self.__getSync() - return True - - # send the reboot command - def __reboot(self): - self.__send(uploader.REBOOT + - uploader.EOC) - self.port.flush() - - # v3+ can report failure if the first word flash fails - if self.bl_rev >= 3: - self.__getSync() - - # split a sequence into a list of size-constrained pieces - def __split_len(self, seq, length): - return [seq[i:i+length] for i in range(0, len(seq), length)] - - # upload code - def __program(self, label, fw): - self.__probe(False) - print("\n", end='') - code = fw.image - groups = self.__split_len(code, uploader.PROG_MULTI_MAX) - # Give imedate feedback - self.__drawProgressBar(label, 0, len(groups)) - uploadProgress = 0 - for bytes in groups: - self.__program_multi(bytes, self.ackWindowedMode) - # If in Window mode, extend the window size for the __ackSyncWindow - if self.ackWindowedMode: - self.window += self.window_per - - # Print upload progress (throttled, so it does not delay upload progress) - uploadProgress += 1 - if uploadProgress % 256 == 0: - self.__probe(True) - self.__probe(False) - self.__probe(True) - self.__ackSyncWindow(self.window) - self.__probe(False) - self.window = 0 - self.__drawProgressBar(label, uploadProgress, len(groups)) - - # Do any remaining fragment - self.__ackSyncWindow(self.window) - self.window = 0 - self.__drawProgressBar(label, 100, 100) - - # verify code - def __verify_v2(self, label, fw): - print("\n", end='') - self.__send(uploader.CHIP_VERIFY + - uploader.EOC) - self.__getSync() - code = fw.image - groups = self.__split_len(code, uploader.READ_MULTI_MAX) - verifyProgress = 0 - for bytes in groups: - verifyProgress += 1 - if verifyProgress % 256 == 0: - self.__drawProgressBar(label, verifyProgress, len(groups)) - if (not self.__verify_multi(bytes)): - raise RuntimeError("Verification failed") - self.__drawProgressBar(label, 100, 100) - - def __verify_v3(self, label, fw): - print("\n", end='') - self.__drawProgressBar(label, 1, 100) - expect_crc = fw.crc(self.fw_maxsize) - self.__send(uploader.GET_CRC + uploader.EOC) - time.sleep(0.5) - report_crc = self.__recv_int() - self.__getSync() - if report_crc != expect_crc: - print("Expected 0x%x" % expect_crc) - print("Got 0x%x" % report_crc) - raise RuntimeError("Program CRC failed") - self.__drawProgressBar(label, 100, 100) - - def __set_boot_delay(self, boot_delay): - self.__send(uploader.SET_BOOT_DELAY + - struct.pack("b", boot_delay) + - uploader.EOC) - self.__getSync() - - # get basic data about the board - def identify(self): - self.__determineInterface() - # make sure we are in sync before starting - self.__sync() - - # get the bootloader protocol ID first - self.bl_rev = self.__getInfo(uploader.INFO_BL_REV) - if (self.bl_rev < uploader.BL_REV_MIN) or (self.bl_rev > uploader.BL_REV_MAX): - print("Unsupported bootloader protocol %d" % uploader.INFO_BL_REV) - raise RuntimeError("Bootloader protocol mismatch") - - self.board_type = self.__getInfo(uploader.INFO_BOARD_ID) - self.board_rev = self.__getInfo(uploader.INFO_BOARD_REV) - self.fw_maxsize = self.__getInfo(uploader.INFO_FLASH_SIZE) - - self.version = self.__getVersion() - - # upload the firmware - def upload(self, fw_list, force=False, boot_delay=None, boot_check=False, force_erase=False): - self.force_erase = force_erase - # select correct binary - found_suitable_firmware = False - for file in fw_list: - fw = firmware(file) - if self.board_type == fw.property('board_id'): - if len(fw_list) > 1: print("using firmware binary {}".format(file)) - found_suitable_firmware = True - break - - if not found_suitable_firmware: - msg = "Firmware not suitable for this board (Firmware board_type=%u board_id=%u)" % ( - self.board_type, fw.property('board_id')) - print("WARNING: %s" % msg) - if force: - if len(fw_list) > 1: - raise FirmwareNotSuitableException("force flashing failed, more than one file provided, none suitable") - print("FORCED WRITE, FLASHING ANYWAY!") - else: - raise FirmwareNotSuitableException(msg) - - percent = fw.property('image_size') / fw.property('image_maxsize') - binary_size = float(fw.property('image_size')) - binary_max_size = float(fw.property('image_maxsize')) - percent = (binary_size / binary_max_size) * 100 - - print("Loaded firmware for board id: %s,%s size: %d bytes (%.2f%%) " % (fw.property('board_id'), fw.property('board_revision'), fw.property('image_size'), percent)) - print() - - print(f"Bootloader version: {self.version}") - - # Make sure we are doing the right thing - start = _time() - if self.board_type != fw.property('board_id'): - msg = "Firmware not suitable for this board (Firmware board_type=%u board_id=%u)" % ( - self.board_type, fw.property('board_id')) - print("WARNING: %s" % msg) - if force: - print("FORCED WRITE, FLASHING ANYWAY!") - else: - raise FirmwareNotSuitableException(msg) - - # Prevent uploads where the image would overflow the flash - if self.fw_maxsize < fw.property('image_size'): - raise RuntimeError("Firmware image is too large for this board") - - # OTP added in v4: - if self.bl_rev >= 4: - for byte in range(0, 32*6, 4): - x = self.__getOTP(byte) - self.otp = self.otp + x - # print(binascii.hexlify(x).decode('Latin-1') + ' ', end='') - # see src/modules/systemlib/otp.h in px4 code: - self.otp_id = self.otp[0:4] - self.otp_idtype = self.otp[4:5] - self.otp_vid = self.otp[8:4:-1] - self.otp_pid = self.otp[12:8:-1] - self.otp_coa = self.otp[32:160] - # show user: - try: - print("Sn: ", end='') - for byte in range(0, 12, 4): - x = self.__getSN(byte) - x = x[::-1] # reverse the bytes - self.sn = self.sn + x - print(binascii.hexlify(x).decode('Latin-1'), end='') # show user - print('') - print("Chip: %08x" % self.__getCHIP()) - - otp_id = self.otp_id.decode('Latin-1') - if ("PX4" in otp_id): - print("OTP id: " + otp_id) - print("OTP idtype: " + binascii.b2a_qp(self.otp_idtype).decode('Latin-1')) - print("OTP vid: " + binascii.hexlify(self.otp_vid).decode('Latin-1')) - print("OTP pid: " + binascii.hexlify(self.otp_pid).decode('Latin-1')) - print("OTP coa: " + binascii.b2a_base64(self.otp_coa).decode('Latin-1')) - - except Exception as e: - # ignore bad character encodings - print(f"Exception ignored: {e}") - pass - - # Silicon errata check was added in v5 - if (self.bl_rev >= 5): - des = self.__getCHIPDes() - if (len(des) == 2): - family, revision = des - print(f"Family: {family.decode()}") - print(f"Revision: {revision.decode()}") - print(f"Flash: {self.fw_maxsize} bytes") - - # Prevent uploads where the maximum image size of the board config is smaller than the flash - # of the board. This is a hint the user chose the wrong config and will lack features - # for this particular board. - - # This check should also check if the revision is an unaffected revision - # and thus can support the full flash, see - # https://github.com/PX4/Firmware/blob/master/src/drivers/boards/common/stm32/board_mcu_version.c#L125-L144 - - if self.fw_maxsize > fw.property('image_maxsize') and not force: - print(f"WARNING: Board can accept larger flash images ({self.fw_maxsize} bytes) than board config ({fw.property('image_maxsize')} bytes)") - else: - # If we're still on bootloader v4 on a Pixhawk, we don't know if we - # have the silicon errata and therefore need to flash px4_fmu-v2 - # with 1MB flash or if it supports px4_fmu-v3 with 2MB flash. - if fw.property('board_id') == 9 \ - and fw.property('image_size') > 1032192 \ - and not force: - raise RuntimeError("\nThe Board uses bootloader revision 4 and can therefore not determine\n" - "if flashing more than 1 MB (px4_fmu-v3_default) is safe, chances are\n" - "high that it is not safe! If unsure, use px4_fmu-v2_default.\n" - "\n" - "If you know you that the board does not have the silicon errata, use\n" - "this script with --force, or update the bootloader. If you are invoking\n" - "upload using make, you can use force-upload target to force the upload.\n") - self.__erase("Erase ") - self.__program("Program", fw) - - if self.bl_rev == 2: - self.__verify_v2("Verify ", fw) - else: - self.__verify_v3("Verify ", fw) - - if boot_delay is not None: - self.__set_boot_delay(boot_delay) - - print("\nRebooting.", end='') - self.__reboot() - self.port.close() - print(" Elapsed Time %3.3f\n" % (_time() - start)) - - def __next_baud_flightstack(self): - if self.baudrate_flightstack_idx + 1 >= len(self.baudrate_flightstack): - return False - try: - self.port.baudrate = self.baudrate_flightstack[self.baudrate_flightstack_idx + 1] - self.baudrate_flightstack_idx = self.baudrate_flightstack_idx + 1 - except serial.SerialException: - # Sometimes _configure_port fails - time.sleep(0.04) - - return True - - def send_protocol_splitter_format(self, data): - # Header Structure: - # bits: 1 2 3 4 5 6 7 8 - # header[0] - | Magic | (='S') - # header[1] - |T| LenH | (T - 0: mavlink; 1: rtps) - # header[2] - | LenL | - # header[3] - | Checksum | - - MAGIC = 83 - - len_bytes = len(data).to_bytes(2, "big") - LEN_H = len_bytes[0] & 127 - LEN_L = len_bytes[1] & 255 - CHECKSUM = MAGIC ^ LEN_H ^ LEN_L - - header_ints = [MAGIC, LEN_H, LEN_L, CHECKSUM] - header_bytes = struct.pack("{}B".format(len(header_ints)), *header_ints) - - self.__send(header_bytes) - self.__send(data) - - def send_reboot(self, use_protocol_splitter_format=False): - if (not self.__next_baud_flightstack()): - return False - - print("Attempting reboot on %s with baudrate=%d..." % (self.port.port, self.port.baudrate), file=sys.stderr) - if "ttyS" in self.port.port: - print("If the board does not respond, check the connection to the Flight Controller") - else: - print("If the board does not respond, unplug and re-plug the USB connector.", file=sys.stderr) - - try: - send_fct = self.__send - if use_protocol_splitter_format: - send_fct = self.send_protocol_splitter_format - - # try MAVLINK command first - self.port.flush() - send_fct(uploader.MAVLINK_REBOOT_ID1) - send_fct(uploader.MAVLINK_REBOOT_ID0) - # then try reboot via NSH - send_fct(uploader.NSH_INIT) - send_fct(uploader.NSH_REBOOT_BL) - send_fct(uploader.NSH_INIT) - send_fct(uploader.NSH_REBOOT) - self.port.flush() - self.port.baudrate = self.baudrate_bootloader - except Exception: - try: - self.port.flush() - self.port.baudrate = self.baudrate_bootloader - except Exception: - pass - - return True - - -def main(): - # Parse commandline arguments - parser = argparse.ArgumentParser(description="Firmware uploader for the PX autopilot system.") - parser.add_argument('--port', action="store", required=True, help="Comma-separated list of serial port(s) to which the FMU may be attached") - parser.add_argument('--baud-bootloader', action="store", type=int, default=115200, help="Baud rate of the serial port (default is 115200) when communicating with bootloader, only required for true serial ports.") - parser.add_argument('--baud-flightstack', action="store", default="57600", help="Comma-separated list of baud rate of the serial port (default is 57600) when communicating with flight stack (Mavlink or NSH), only required for true serial ports.") - parser.add_argument('--force', action='store_true', default=False, help='Override board type check, or silicon errata checks and continue loading') - parser.add_argument('--force-erase', action="store_true", help="Do not perform the blank check, always erase every sector of the application space") - parser.add_argument('--boot-delay', type=int, default=None, help='minimum boot delay to store in flash') - parser.add_argument('--use-protocol-splitter-format', action='store_true', help='use protocol splitter format for reboot') - parser.add_argument('firmware', action="store", nargs='+', help="Firmware file(s)") - args = parser.parse_args() - - if args.use_protocol_splitter_format: - print("Using protocol splitter format to reboot pixhawk!") - - # warn people about ModemManager which interferes badly with Pixhawk - if os.path.exists("/usr/sbin/ModemManager"): - print("==========================================================================================================") - print("WARNING: You should uninstall ModemManager as it conflicts with any non-modem serial device (like Pixhawk)") - print("==========================================================================================================") - - print("Waiting for bootloader...") - # tell any GCS that might be connected to the autopilot to give up - # control of the serial port - - # send to localhost and default GCS port - ipaddr = '127.0.0.1' - portnum = 14550 - - # COMMAND_LONG in MAVLink 1 - heartbeatpacket = bytearray.fromhex('fe097001010000000100020c5103033c8a') - commandpacket = bytearray.fromhex('fe210101014c00000000000000000000000000000000000000000000803f00000000f6000000008459') - - # initialize an UDP socket - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - # send heartbeat to initialize connection and command to free the link - s.sendto(heartbeatpacket, (ipaddr, portnum)) - s.sendto(commandpacket, (ipaddr, portnum)) - - # close the socket - s.close() - - # Spin waiting for a device to show up - try: - while True: - portlist = [] - patterns = args.port.split(",") - # on unix-like platforms use glob to support wildcard ports. This allows - # the use of /dev/serial/by-id/usb-3D_Robotics on Linux, which prevents the upload from - # causing modem hangups etc - if "linux" in _platform or "darwin" in _platform or "cygwin" in _platform: - import glob - for pattern in patterns: - portlist += glob.glob(pattern) - else: - portlist = patterns - - baud_flightstack = [int(x) for x in args.baud_flightstack.split(',')] - - successful = False - unsuitable_board = False - for port in portlist: - - # print("Trying %s" % port) - - # create an uploader attached to the port - try: - if "linux" in _platform: - # Linux, don't open Mac OS and Win ports - if "COM" not in port and "tty.usb" not in port: - up = uploader(port, args.baud_bootloader, baud_flightstack) - elif "darwin" in _platform: - # OS X, don't open Windows and Linux ports - if "COM" not in port and "ACM" not in port: - up = uploader(port, args.baud_bootloader, baud_flightstack) - elif "cygwin" in _platform: - # Cygwin, don't open native Windows COM and Linux ports - if "COM" not in port and "ACM" not in port: - up = uploader(port, args.baud_bootloader, baud_flightstack) - elif "win" in _platform: - # Windows, don't open POSIX ports - if "/" not in port: - up = uploader(port, args.baud_bootloader, baud_flightstack) - except Exception as e: - # open failed, rate-limit our attempts - time.sleep(0.05) - print(f"Exception ignored: {e}") - - # and loop to the next port - continue - - found_bootloader = False - while True: - up.open() - - # port is open, try talking to it - try: - # identify the bootloader - up.identify() - found_bootloader = True - print() - print(f"Found board id: {up.board_type},{up.board_rev} bootloader protocol revision {up.bl_rev} on {port}") - break - - except (RuntimeError, serial.SerialException): - - if not up.send_reboot(args.use_protocol_splitter_format): - break - - # wait for the reboot, without we might run into Serial I/O Error 5 - time.sleep(0.25) - - # always close the port - up.close() - - # wait for the close, without we might run into Serial I/O Error 6 - time.sleep(0.3) - - if not found_bootloader: - # Go to the next port - continue - - try: - # ok, we have a bootloader, try flashing it - up.upload(args.firmware, force=args.force, boot_delay=args.boot_delay, force_erase=args.force_erase) - - # if we made this far without raising exceptions, the upload was successful - successful = True - - except RuntimeError as e: - # print the error - print(f"\n\nError: {e}") - - except FirmwareNotSuitableException: - unsuitable_board = True - up.close() - continue - - except IOError: - up.close() - continue - - finally: - # always close the port - up.close() - - # we could loop here if we wanted to wait for more boards... - if successful: - sys.exit(0) - else: - sys.exit(1) - - if unsuitable_board: - # If we land here, we went through all ports, did not flash any - # board and found at least one unsuitable board. - # Exit with 2, so a caller can distinguish from other errors - sys.exit(2) - - # Delay retries to < 20 Hz to prevent spin-lock from hogging the CPU - time.sleep(0.05) - - # CTRL+C aborts the upload/spin-lock by interrupt mechanics - except KeyboardInterrupt: - print("\n Upload aborted by user.") - sys.exit(0) - - -if __name__ == '__main__': - main() - -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/Tools/run-clang-tidy.py b/Tools/run-clang-tidy.py index 4f29868bee..764edd6581 100755 --- a/Tools/run-clang-tidy.py +++ b/Tools/run-clang-tidy.py @@ -144,6 +144,8 @@ def main(): help='number of tidy instances to be run in parallel.') parser.add_argument('files', nargs='*', default=['.*'], help='files to be processed (regex on path)') + parser.add_argument('-exclude', dest='exclude', default=None, + help='regular expression matching files to exclude') parser.add_argument('-fix', action='store_true', help='apply fix-its') parser.add_argument('-format', action='store_true', help='Reformat code ' 'after applying fixes') @@ -192,6 +194,7 @@ def main(): # Build up a big regexy filter from all command line arguments. file_name_re = re.compile('(' + ')|('.join(args.files) + ')') + exclude_re = re.compile(args.exclude) if args.exclude else None try: # Spin up a bunch of tidy-launching threads. @@ -205,6 +208,8 @@ def main(): # Fill the queue with files. for name in files: if file_name_re.search(name): + if exclude_re and exclude_re.search(name): + continue queue.put(name) # Wait for all threads to be done. diff --git a/Tools/setup/docker-entrypoint.sh b/Tools/setup/docker-entrypoint.sh index 6d998eda2d..69101c5833 100755 --- a/Tools/setup/docker-entrypoint.sh +++ b/Tools/setup/docker-entrypoint.sh @@ -4,7 +4,7 @@ GREEN='\033[0;32m' NO_COLOR='\033[0m' # No Color SCRIPTID="${GREEN}[docker-entrypoint.sh]${NO_COLOR}" -echo -e "$SCRIPTID Starting" +echo -e "$SCRIPTID $( uname -m ) | $(date -u +%FT%TZ)" # Start virtual X server in the background # - DISPLAY default is :99, set in dockerfile @@ -22,6 +22,4 @@ if [ -n "${ROS_DISTRO}" ]; then source "/opt/ros/$ROS_DISTRO/setup.bash" fi -echo -e "$SCRIPTID ($( uname -m ))" - exec "$@" diff --git a/Tools/setup/requirements.txt b/Tools/setup/requirements.txt index a15da9b9e9..b9d83da852 100644 --- a/Tools/setup/requirements.txt +++ b/Tools/setup/requirements.txt @@ -6,6 +6,7 @@ future jinja2>=2.8 jsonschema kconfiglib +lark lxml matplotlib>=3.0 numpy>=1.13 @@ -14,8 +15,8 @@ packaging pandas>=0.21 pkgconfig psutil +pycryptodome pygments -wheel>=0.31.1 pymavlink pyros-genmsg pyserial @@ -24,7 +25,6 @@ pyyaml requests setuptools>=39.2.0 six>=1.12.0 -toml>=0.9 sympy>=1.10.1 -pycryptodome -lark +toml>=0.9 +wheel>=0.31.1 diff --git a/Tools/setup/ubuntu.sh b/Tools/setup/ubuntu.sh index b043b133c2..f84db9a603 100755 --- a/Tools/setup/ubuntu.sh +++ b/Tools/setup/ubuntu.sh @@ -6,9 +6,9 @@ set -e ## Can also be used in docker. ## ## Installs: -## - Common dependencies and tools for nuttx, jMAVSim, Gazebo +## - Common dependencies and tools for nuttx, Gazebo ## - NuttX toolchain (omit with arg: --no-nuttx) -## - jMAVSim and Gazebo9 simulator (omit with arg: --no-sim-tools) +## - Gazebo Harmonic simulator (omit with arg: --no-sim-tools) ## INSTALL_NUTTX="true" @@ -54,6 +54,22 @@ if [[ ! -f "${DIR}/${REQUIREMENTS_FILE}" ]]; then return 1 fi +# Linux Mint compatibility: use upstream Ubuntu values +if [ -r /etc/upstream-release/lsb-release ]; then + . /etc/upstream-release/lsb-release + UBUNTU_CODENAME="${DISTRIB_CODENAME:-${UBUNTU_CODENAME:-}}" + UBUNTU_RELEASE="${DISTRIB_RELEASE:-${UBUNTU_RELEASE:-}}" + + lsb_release() { + if [ "$1" = "-cs" ]; then + printf '%s' "$UBUNTU_CODENAME" + elif [ "$1" = "-rs" ]; then + printf '%s' "$UBUNTU_RELEASE" + else + command lsb_release "$@" + fi + } +fi # check ubuntu version # otherwise warn and point to docker? @@ -160,8 +176,10 @@ if [[ $INSTALL_NUTTX == "true" ]]; then echo echo "Fetching Xtensa compilers" - wget -q -P $DIR https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz - sudo tar -xf $DIR/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz -C /opt + XTENSA_FILE_NAME=xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz + wget -q -P $DIR https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/$XTENSA_FILE_NAME + sudo tar -xf $DIR/$XTENSA_FILE_NAME -C /opt + rm $DIR/$XTENSA_FILE_NAME echo 'export PATH=$PATH:/opt/xtensa-esp-elf/bin/' >> /home/$USER/.bashrc fi @@ -189,37 +207,18 @@ if [[ $INSTALL_SIM == "true" ]]; then bc \ ; - # Gazebo / Gazebo classic installation - if [[ "${UBUNTU_RELEASE}" == "18.04" || "${UBUNTU_RELEASE}" == "20.04" ]]; then - sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' - wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - - # Update list, since new gazebo-stable.list has been added - sudo apt-get update -y --quiet + # Gazebo Harmonic installation (Ubuntu 22.04+) + echo "[ubuntu.sh] Gazebo (Harmonic) will be installed" + # Add Gazebo binary repository + sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null + sudo apt-get update -y --quiet - # Install Gazebo classic - if [[ "${UBUNTU_RELEASE}" == "18.04" ]]; then - gazebo_classic_version=9 - gazebo_packages="gazebo$gazebo_classic_version libgazebo$gazebo_classic_version-dev" - else - # default and Ubuntu 20.04 - gazebo_classic_version=11 - gazebo_packages="gazebo$gazebo_classic_version libgazebo$gazebo_classic_version-dev" - fi - else - # Expects Ubuntu 22.04 > by default - echo "[ubuntu.sh] Gazebo (Harmonic) will be installed" - echo "[ubuntu.sh] Earlier versions will be removed" - # Add Gazebo binary repository - sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null - sudo apt-get update -y --quiet + # Install Gazebo + gazebo_packages="gz-harmonic libunwind-dev" - # Install Gazebo - gazebo_packages="gz-harmonic libunwind-dev" - - if [[ "${UBUNTU_RELEASE}" == "24.04" ]]; then - gazebo_packages="$gazebo_packages cppzmq-dev" - fi + if [[ "${UBUNTU_RELEASE}" == "24.04" ]]; then + gazebo_packages="$gazebo_packages cppzmq-dev" fi sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \ diff --git a/Tools/simulation/gazebo-classic/sitl_gazebo-classic b/Tools/simulation/gazebo-classic/sitl_gazebo-classic index 6697ab169c..5b6966ed57 160000 --- a/Tools/simulation/gazebo-classic/sitl_gazebo-classic +++ b/Tools/simulation/gazebo-classic/sitl_gazebo-classic @@ -1 +1 @@ -Subproject commit 6697ab169ceab512dc706acea63df4c882662c60 +Subproject commit 5b6966ed572a02e8273f446acb504a45a841ca53 diff --git a/Tools/simulation/gz b/Tools/simulation/gz index 6cfb3e362e..fe3fe236e3 160000 --- a/Tools/simulation/gz +++ b/Tools/simulation/gz @@ -1 +1 @@ -Subproject commit 6cfb3e362e1424caccb7363dca7e63484e44d188 +Subproject commit fe3fe236e36a3ed5bce01a7501347d20a466c407 diff --git a/Tools/simulation/jmavsim/jMAVSim b/Tools/simulation/jmavsim/jMAVSim index 66b764ada5..665b26d62d 160000 --- a/Tools/simulation/jmavsim/jMAVSim +++ b/Tools/simulation/jmavsim/jMAVSim @@ -1 +1 @@ -Subproject commit 66b764ada522893c05224950aa6268c809f8e48a +Subproject commit 665b26d62d36a33b6bf01c5931c589beb812c6a2 diff --git a/Tools/upload_log.py b/Tools/upload_log.py index a13f1b14b0..453c1538ea 100755 --- a/Tools/upload_log.py +++ b/Tools/upload_log.py @@ -25,10 +25,6 @@ except ImportError as e: sys.exit(1) -SERVER = 'https://logs.px4.io' -#SERVER = 'http://localhost:5006' # for testing locally -UPLOAD_URL = SERVER+'/upload' - quiet = False def ask_value(text, default=None): @@ -60,6 +56,8 @@ def main(): parser = ArgumentParser(description=__doc__) parser.add_argument('--quiet', '-q', dest='quiet', action='store_true', default=False, help='Quiet mode: do not ask for values which were not provided as parameters') + parser.add_argument('--server', dest='server', type=str, default='https://logs.px4.io', + help='Server URL (default: https://logs.px4.io), use http://localhost:5006 for testing locally') parser.add_argument("--description", dest="description", type=str, help="Log description", default=None) parser.add_argument("--feedback", dest="feedback", type=str, @@ -99,6 +97,9 @@ def main(): else: email = args.email + server = args.server + upload_url = server + '/upload' + payload = {'type': args.type, 'description': description, 'feedback': feedback, 'email': email, 'source': args.source} @@ -113,13 +114,13 @@ def main(): print('Uploading '+file_name+'...') with open(file_name, 'rb') as f: - r = requests.post(UPLOAD_URL, data=payload, files={'filearg': f}, + r = requests.post(upload_url, data=payload, files={'filearg': f}, allow_redirects=False) if r.status_code == 302: # redirect if 'Location' in r.headers: plot_url = r.headers['Location'] if len(plot_url) > 0 and plot_url[0] == '/': - plot_url = SERVER + plot_url + plot_url = server + plot_url print('URL: '+plot_url) diff --git a/boards/3dr/ctrl-zero-h7-oem-revg/default.px4board b/boards/3dr/ctrl-zero-h7-oem-revg/default.px4board index 7b0f4b75d0..366968f1ee 100644 --- a/boards/3dr/ctrl-zero-h7-oem-revg/default.px4board +++ b/boards/3dr/ctrl-zero-h7-oem-revg/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/3dr/ctrl-zero-h7-oem-revg/nuttx-config/scripts/script.ld b/boards/3dr/ctrl-zero-h7-oem-revg/nuttx-config/scripts/script.ld index 45b12075e5..02e763a790 100755 --- a/boards/3dr/ctrl-zero-h7-oem-revg/nuttx-config/scripts/script.ld +++ b/boards/3dr/ctrl-zero-h7-oem-revg/nuttx-config/scripts/script.ld @@ -132,7 +132,6 @@ ENTRY(_stext) */ EXTERN(abort) EXTERN(_bootdelay_signature) -EXTERN(board_get_manifest) SECTIONS { diff --git a/boards/3dr/ctrl-zero-h7-oem-revg/src/CMakeLists.txt b/boards/3dr/ctrl-zero-h7-oem-revg/src/CMakeLists.txt index 1a47c940b7..6a7d2ce306 100755 --- a/boards/3dr/ctrl-zero-h7-oem-revg/src/CMakeLists.txt +++ b/boards/3dr/ctrl-zero-h7-oem-revg/src/CMakeLists.txt @@ -48,7 +48,6 @@ else() i2c.cpp init.c led.c - mtd.cpp spi.cpp timer_config.cpp usb.c diff --git a/boards/accton-godwit/ga1/default.px4board b/boards/accton-godwit/ga1/default.px4board index c154100bbe..9e291d01d7 100644 --- a/boards/accton-godwit/ga1/default.px4board +++ b/boards/accton-godwit/ga1/default.px4board @@ -34,7 +34,6 @@ CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_DRIVERS_RC_INPUT=y @@ -67,7 +66,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 diff --git a/boards/accton-godwit/ga1/init/rc.board_defaults b/boards/accton-godwit/ga1/init/rc.board_defaults index f23e6c1743..92da057ef2 100644 --- a/boards/accton-godwit/ga1/init/rc.board_defaults +++ b/boards/accton-godwit/ga1/init/rc.board_defaults @@ -3,19 +3,13 @@ # board specific defaults #------------------------------------------------------------------------------ -# By disabling all 3 INA modules, we use the -# i2c_launcher instead. -param set - default SENS_EN_INA238 0 -param set - default SENS_EN_INA228 0 -param set - default SENS_EN_INA226 0 - # Mavlink ethernet (CFG 1000) -param set - default MAV_2_CONFIG 1000 -param set - default MAV_2_BROADCAST 1 -param set - default MAV_2_MODE 0 -param set - default MAV_2_RADIO_CTL 0 -param set - default MAV_2_RATE 100000 -param set - default MAV_2_REMOTE_PRT 14550 -param set - default MAV_2_UDP_PRT 14550 +param set-default MAV_2_CONFIG 1000 +param set-default MAV_2_BROADCAST 1 +param set-default MAV_2_MODE 0 +param set-default MAV_2_RADIO_CTL 0 +param set-default MAV_2_RATE 100000 +param set-default MAV_2_REMOTE_PRT 14550 +param set-default MAV_2_UDP_PRT 14550 safety_button start diff --git a/boards/accton-godwit/ga1/src/CMakeLists.txt b/boards/accton-godwit/ga1/src/CMakeLists.txt index 39ec808e1e..605cf16ac9 100644 --- a/boards/accton-godwit/ga1/src/CMakeLists.txt +++ b/boards/accton-godwit/ga1/src/CMakeLists.txt @@ -71,6 +71,5 @@ else() nuttx_arch # sdio nuttx_drivers # sdio px4_layer - platform_gpio_mcp23009 ) endif() diff --git a/boards/accton-godwit/ga1/src/init.cpp b/boards/accton-godwit/ga1/src/init.cpp index 6aef4114a8..ca48a74479 100644 --- a/boards/accton-godwit/ga1/src/init.cpp +++ b/boards/accton-godwit/ga1/src/init.cpp @@ -74,7 +74,6 @@ #include #include #include -#include /**************************************************************************** * Pre-Processor Definitions @@ -286,13 +285,6 @@ __EXPORT int board_app_initialize(uintptr_t arg) # endif /* CONFIG_MMCSD */ - ret = mcp23009_register_gpios(3, 0x25); - - if (ret != OK) { - led_on(LED_RED); - return ret; - } - #endif /* !defined(BOOTLOADER) */ return OK; diff --git a/boards/airmind/mindpx-v2/default.px4board b/boards/airmind/mindpx-v2/default.px4board index 50c6679426..10e061af3e 100644 --- a/boards/airmind/mindpx-v2/default.px4board +++ b/boards/airmind/mindpx-v2/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_ST_LSM303D=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/ark/can-flow-mr/default.px4board b/boards/ark/can-flow-mr/default.px4board new file mode 100644 index 0000000000..6474b8cdb7 --- /dev/null +++ b/boards/ark/can-flow-mr/default.px4board @@ -0,0 +1,30 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="cannode" +CONFIG_BOARD_CONSTRAINED_FLASH=y +CONFIG_BOARD_NO_HELP=y +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BOOTLOADERS=y +CONFIG_DRIVERS_DISTANCE_SENSOR_BROADCOM_AFBRS50=y +CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y +CONFIG_DRIVERS_OPTICAL_FLOW_PAA3905=y +CONFIG_BOARD_UAVCAN_INTERFACES=1 +CONFIG_DRIVERS_UAVCANNODE=y +CONFIG_UAVCANNODE_FLOW_MEASUREMENT=y +CONFIG_UAVCANNODE_RANGE_SENSOR_MEASUREMENT=y +CONFIG_UAVCANNODE_RAW_IMU=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_SENSORS=y +# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set +# CONFIG_SENSORS_VEHICLE_AIR_DATA is not set +# CONFIG_SENSORS_VEHICLE_ACCELERATION is not set +# CONFIG_SENSORS_VEHICLE_GPS_POSITION is not set +# CONFIG_SENSORS_VEHICLE_MAGNETOMETER is not set +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/ark/can-flow-mr/init/rc.board_sensors b/boards/ark/can-flow-mr/init/rc.board_sensors index 2d476fcefb..131d5d58a8 100644 --- a/boards/ark/can-flow-mr/init/rc.board_sensors +++ b/boards/ark/can-flow-mr/init/rc.board_sensors @@ -8,9 +8,8 @@ param set-default SENS_FLOW_RATE 150 param set-default SENS_IMU_CLPNOTI 0 param set-default SENS_AFBR_S_RATE 25 -param set-default SENS_AFBR_L_RATE 10 -param set-default SENS_AFBR_THRESH 8 -param set-default SENS_AFBR_HYSTER 2 +param set-default SENS_AFBR_L_RATE 5 +param set-default SENS_AFBR_MODE 1 # Internal SPI paa3905 -s start -Y 180 diff --git a/boards/ark/can-gps/src/board_config.h b/boards/ark/can-gps/src/board_config.h index 723310472f..81f0394944 100644 --- a/boards/ark/can-gps/src/board_config.h +++ b/boards/ark/can-gps/src/board_config.h @@ -47,7 +47,7 @@ #define GPIO_BTN_SAFETY /* PB15 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTB|GPIO_PIN15) /* Safety LED */ -#define GPIO_LED_SAFETY /* PA1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LED_SAFETY /* PA1 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN1) /* Tone alarm output. */ #define TONE_ALARM_TIMER 2 /* timer 2 */ diff --git a/boards/ark/cannode/default.px4board b/boards/ark/cannode/default.px4board index 29b964b237..f886a22b2e 100644 --- a/boards/ark/cannode/default.px4board +++ b/boards/ark/cannode/default.px4board @@ -31,6 +31,7 @@ CONFIG_UAVCANNODE_ESC_RAW_COMMAND=y CONFIG_UAVCANNODE_ESC_STATUS=y CONFIG_UAVCANNODE_FLOW_MEASUREMENT=y CONFIG_UAVCANNODE_GNSS_FIX=y +CONFIG_UAVCANNODE_HARDPOINT_COMMAND=y CONFIG_UAVCANNODE_HYGROMETER_MEASUREMENT=y CONFIG_UAVCANNODE_LIGHTS_COMMAND=y CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y diff --git a/boards/ark/dist/init/rc.board_sensors b/boards/ark/dist/init/rc.board_sensors index 0b7d52a6f1..16a809054c 100644 --- a/boards/ark/dist/init/rc.board_sensors +++ b/boards/ark/dist/init/rc.board_sensors @@ -11,7 +11,6 @@ param set-default SENS_AFBR_HYSTER 1 param set-default MAV_SYS_ID 158 param set-default MAV_COMP_ID 158 -param set-default MAV_PROTO_VER 2 param set-default MAV_0_MODE 14 param set-default MAV_0_FORWARD 0 diff --git a/boards/ark/f9p-gps/canbootloader.px4board b/boards/ark/f9p-gps/canbootloader.px4board new file mode 100644 index 0000000000..46917280f6 --- /dev/null +++ b/boards/ark/f9p-gps/canbootloader.px4board @@ -0,0 +1,5 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BOOTLOADERS=y diff --git a/boards/ark/f9p-gps/default.px4board b/boards/ark/f9p-gps/default.px4board new file mode 100644 index 0000000000..6c79012be7 --- /dev/null +++ b/boards/ark/f9p-gps/default.px4board @@ -0,0 +1,37 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="cannode" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BAROMETER_BMP388=y +CONFIG_DRIVERS_BOOTLOADERS=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y +CONFIG_DRIVERS_SAFETY_BUTTON=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_BOARD_UAVCAN_INTERFACES=1 +CONFIG_DRIVERS_UAVCANNODE=y +CONFIG_UAVCANNODE_BEEP_COMMAND=y +CONFIG_UAVCANNODE_GNSS_FIX=y +CONFIG_UAVCANNODE_LIGHTS_COMMAND=y +CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y +CONFIG_UAVCANNODE_RTK_DATA=y +CONFIG_UAVCANNODE_RAW_IMU=y +CONFIG_UAVCANNODE_SAFETY_BUTTON=y +CONFIG_UAVCANNODE_STATIC_PRESSURE=y +CONFIG_UAVCANNODE_STATIC_TEMPERATURE=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_SENSORS=y +# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set +# CONFIG_SENSORS_VEHICLE_AIR_DATA is not set +# CONFIG_SENSORS_VEHICLE_GPS_POSITION is not set +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/ark/f9p-gps/firmware.prototype b/boards/ark/f9p-gps/firmware.prototype new file mode 100644 index 0000000000..b23ef47ca3 --- /dev/null +++ b/boards/ark/f9p-gps/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 90, + "magic": "PX4FWv1", + "description": "Firmware for the ARK F9P GPS", + "image": "", + "build_time": 0, + "summary": "ARKF9PGPS", + "version": "0.1", + "image_size": 0, + "image_maxsize": 2080768, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/ark/f9p-gps/init/rc.board_defaults b/boards/ark/f9p-gps/init/rc.board_defaults new file mode 100644 index 0000000000..ca7fc7b3ef --- /dev/null +++ b/boards/ark/f9p-gps/init/rc.board_defaults @@ -0,0 +1,13 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +param set-default CBRK_IO_SAFETY 0 +param set-default CANNODE_SUB_MBD 1 +param set-default CANNODE_SUB_RTCM 1 +param set-default GPS_1_GNSS 63 +param set-default SENS_IMU_CLPNOTI 0 + +safety_button start +tone_alarm start diff --git a/boards/ark/f9p-gps/init/rc.board_sensors b/boards/ark/f9p-gps/init/rc.board_sensors new file mode 100644 index 0000000000..25bb268272 --- /dev/null +++ b/boards/ark/f9p-gps/init/rc.board_sensors @@ -0,0 +1,11 @@ +#!/bin/sh +# +# board sensors init +#------------------------------------------------------------------------------ +gps start -d /dev/ttyS0 -p ubx + +icm42688p -R 0 -s start + +bmp388 -I -b 1 start + +iis2mdc -R 2 -I -b 1 start diff --git a/boards/ark/f9p-gps/nuttx-config/canbootloader/defconfig b/boards/ark/f9p-gps/nuttx-config/canbootloader/defconfig new file mode 100644 index 0000000000..eff9943964 --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/canbootloader/defconfig @@ -0,0 +1,57 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/f9p-gps/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARDCTL=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_STACKSIZE=4096 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=0 +CONFIG_NUNGET_CHARS=0 +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_NOEXT_VECTORS=y +CONFIG_STM32_TIM8=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/f9p-gps/nuttx-config/include/board.h b/boards/ark/f9p-gps/nuttx-config/include/board.h new file mode 100644 index 0000000000..526392b92b --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/include/board.h @@ -0,0 +1,152 @@ +/************************************************************************************ + * configs/px4fmu/include/board.h + * include/arch/board/board.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#include "board_dma_map.h" + +#ifndef __ARCH_BOARD_BOARD_H +#define __ARCH_BOARD_BOARD_H + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include + +/* HSI - 8 MHz RC factory-trimmed + * LSI - 32 KHz RC + * HSE - 8 MHz Crystal + * LSE - not installed + */ +#define STM32_BOARD_USEHSE 1 +#define STM32_BOARD_XTAL 8000000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 + +/* Main PLL Configuration */ +#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8) +#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(384) +#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_4 +#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(8) +#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(2) + +#define STM32_RCC_PLLI2SCFGR_PLLI2SM RCC_PLLI2SCFGR_PLLI2SM(16) +#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) +#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SR RCC_PLLI2SCFGR_PLLI2SR(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SSRC RCC_PLLI2SCFGR_PLLI2SSRC(0) /* HSE or HSI depending on PLLSRC of PLLCFGR*/ + +#define STM32_RCC_DCKCFGR2_CK48MSEL RCC_DCKCFGR2_CK48MSEL_PLL +#define STM32_RCC_DCKCFGR2_FMPI2C1SEL RCC_DCKCFGR2_FMPI2C1SEL_APB +#define STM32_RCC_DCKCFGR2_SDIOSEL RCC_DCKCFGR2_SDIOSEL_48MHZ + +#define STM32_SYSCLK_FREQUENCY 96000000ul + +/* AHB clock (HCLK) is SYSCLK (96MHz) */ +#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ +#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (48MHz) */ +#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timers driven from APB1 will be twice PCLK1 (see page 112 of reference manual) */ +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* APB2 clock (PCLK2) is HCLK (96MHz) */ +#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY) + +/* Timers driven from APB2 will be PCLK2 since no prescale division */ +#define STM32_APB2_TIM1_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM9_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM10_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM11_CLKIN (STM32_PCLK2_FREQUENCY) + +/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx otherwise frequency is 2xAPBx. */ +#define BOARD_TIM2_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM3_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM4_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM5_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM6_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM7_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM8_FREQUENCY (2 * STM32_PCLK2_FREQUENCY) + +/* Alternate function pin selections ************************************************/ + +/* UARTs */ +#define GPIO_USART1_RX GPIO_USART1_RX_2 +#define GPIO_USART1_TX GPIO_USART1_TX_3 + +#define GPIO_USART2_RX GPIO_USART2_RX_1 +#define GPIO_USART2_TX GPIO_USART2_TX_1 + +/* CAN */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_1 +#define GPIO_CAN1_TX GPIO_CAN1_TX_1 + +/* I2C */ + +#define GPIO_MCU_I2C1_SCL +#define GPIO_MCU_I2C1_SDA + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1 +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_4 + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN9) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN10) + +/* SPI */ +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 + +#endif /* __ARCH_BOARD_BOARD_H */ diff --git a/boards/ark/f9p-gps/nuttx-config/include/board_dma_map.h b/boards/ark/f9p-gps/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..efa3d824b2 --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/include/board_dma_map.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMA1 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- + + +// DMA2 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- +#define DMACHAN_SPI1_RX DMAMAP_SPI1_RX_1 // DMA2, Stream 0, Channel 3 +#define DMACHAN_SPI1_TX DMAMAP_SPI1_TX_1 // DMA2, Stream 3, Channel 3 +#define DMACHAN_USART1_RX DMAMAP_USART1_RX_1 // DMA2, Stream 2, Channel 4 +#define DMAMAP_USART1_RX DMAMAP_USART1_RX_1 +//#define DMACHAN_USART1_TX DMAMAP_USART1_TX // DMA2, Stream 7, Channel 4 diff --git a/boards/ark/f9p-gps/nuttx-config/nsh/defconfig b/boards/ark/f9p-gps/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..bde9d7318c --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/nsh/defconfig @@ -0,0 +1,153 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/f9p-gps/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_CROMFS=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=2624 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_VARS=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32_ADC1=y +CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y +CONFIG_STM32_DMA1=y +CONFIG_STM32_DMA2=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_FLASH_PREFETCH=y +CONFIG_STM32_FLOWCONTROL_BROKEN=y +CONFIG_STM32_I2C1=y +CONFIG_STM32_I2C2=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWR=y +CONFIG_STM32_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32_SPI1=y +CONFIG_STM32_SPI1_DMA=y +CONFIG_STM32_SPI1_DMA_BUFFER=1024 +CONFIG_STM32_TIM8=y +CONFIG_STM32_USART1=y +CONFIG_STM32_USART2=y +CONFIG_STM32_USART_BREAKS=y +CONFIG_STM32_WWDG=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=2000 +CONFIG_USART1_RXDMA=y +CONFIG_USART1_TXBUFSIZE=2000 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USART2_TXBUFSIZE=1100 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/f9p-gps/nuttx-config/scripts/canbootloader_script.ld b/boards/ark/f9p-gps/nuttx-config/scripts/canbootloader_script.ld new file mode 100644 index 0000000000..6be5cffcd8 --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/scripts/canbootloader_script.ld @@ -0,0 +1,134 @@ +/**************************************************************************** + * nuttx-config/scripts/canbootloader_script.ld + * + * Copyright (c) 2025 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/f9p-gps/nuttx-config/scripts/script.ld b/boards/ark/f9p-gps/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..2f4769b8f5 --- /dev/null +++ b/boards/ark/f9p-gps/nuttx-config/scripts/script.ld @@ -0,0 +1,146 @@ +/**************************************************************************** + * scripts/ld.script + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08010000, LENGTH = 928K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(8); + /* + * This section positions the app_descriptor_t used + * by the make_can_boot_descriptor.py tool to set + * the application image's descriptor so that the + * uavcan bootloader has the ability to validate the + * image crc, size etc + */ + KEEP(*(.app_descriptor)) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/f9p-gps/src/CMakeLists.txt b/boards/ark/f9p-gps/src/CMakeLists.txt new file mode 100644 index 0000000000..7f8a23a27e --- /dev/null +++ b/boards/ark/f9p-gps/src/CMakeLists.txt @@ -0,0 +1,66 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +if("${PX4_BOARD_LABEL}" STREQUAL "canbootloader") + + add_library(drivers_board + boot_config.h + boot.c + led.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + canbootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/canbootloader) + +else() + add_library(drivers_board + can.c + i2c.cpp + init.c + led.c + spi.cpp + ) + + target_link_libraries(drivers_board + PRIVATE + arch_spi + drivers__led # drv_led_start + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/ark/f9p-gps/src/board_config.h b/boards/ark/f9p-gps/src/board_config.h new file mode 100644 index 0000000000..2d5f582075 --- /dev/null +++ b/boards/ark/f9p-gps/src/board_config.h @@ -0,0 +1,125 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * board internal definitions + */ + +#pragma once + +#include +#include +#include + +/* BUTTON */ +#define GPIO_BTN_SAFETY /* PB15 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTB|GPIO_PIN15) + +/* Safety LED */ +#define GPIO_LED_SAFETY /* PA1 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN1) + +/* Tone alarm output. */ +#define TONE_ALARM_TIMER 2 /* timer 2 */ +#define TONE_ALARM_CHANNEL 1 /* channel 1 */ +#define GPIO_TONE_ALARM_IDLE /* PA0 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TONE_ALARM /* PA0 */ (GPIO_ALT|GPIO_AF1|GPIO_SPEED_2MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) + +/* CAN Silent mode control */ +#define GPIO_CAN1_SILENT_S0 /* PB12 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN12) + +/* CAN termination software control */ +#define GPIO_CAN1_TERMINATION /* PB13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN_TERM GPIO_CAN1_TERMINATION + +/* ICM42688p FSYNC */ +#define GPIO_42688P_FSYNC /* PB8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN8) + +/* Boot config */ +#define GPIO_BOOT_CONFIG /* PC15 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN15|GPIO_EXTI) + +/* LEDs are driven with open drain to support Anode to 5V or 3.3V */ +#define GPIO_TIM1_CH1 /* PA8 */ (GPIO_TIM1_CH1_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH2 /* PA9 */ (GPIO_TIM1_CH2_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH3 /* PA10 */ (GPIO_TIM1_CH3_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) + +#define GPIO_I2C1_SCL_RESET /* PB6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SDA_RESET /* PB7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN7) + +#define GPIO_I2C2_SCL_RESET /* PB10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA_RESET /* PB9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9) + +#define GPIO_I2C2_SCL_RESET /* PB10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA_RESET /* PB9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9) + +#define GPIO_USART1_RX_GPIO (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART1_TX_GPIO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_USART2_RX_GPIO (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_TX_GPIO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) + +#define FLASH_BASED_PARAMS + +/* High-resolution timer */ +#define HRT_TIMER 3 /* use timer 3 for the HRT */ +#define HRT_TIMER_CHANNEL 4 /* use capture/compare channel 4 */ + +#define PX4_GPIO_INIT_LIST { \ + GPIO_BTN_SAFETY, \ + GPIO_LED_SAFETY, \ + GPIO_I2C1_SCL_RESET, \ + GPIO_I2C1_SDA_RESET, \ + GPIO_I2C2_SCL_RESET, \ + GPIO_I2C2_SDA_RESET, \ + GPIO_42688P_FSYNC, \ + GPIO_BOOT_CONFIG, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN1_SILENT_S0, \ + GPIO_CAN1_TERMINATION, \ + } + +__BEGIN_DECLS + +#define BOARD_HAS_N_S_RGB_LED 1 +#define BOARD_MAX_LEDS BOARD_HAS_N_S_RGB_LED + +#ifndef __ASSEMBLY__ + +extern void stm32_spiinitialize(void); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/ark/f9p-gps/src/boot.c b/boards/ark/f9p-gps/src/boot.c new file mode 100644 index 0000000000..3efdba508c --- /dev/null +++ b/boards/ark/f9p-gps/src/boot.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * Author: Ben Dyer + * Pavel Kirienko + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "boot_config.h" +#include "board.h" + +#include +#include +#include + +#include +#include "led.h" + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1ENR) | RCC_APB1ENR_CAN1EN, STM32_RCC_APB1ENR); + stm32_configgpio(GPIO_CAN1_RX); + stm32_configgpio(GPIO_CAN1_TX); + stm32_configgpio(GPIO_CAN1_SILENT_S0); + stm32_configgpio(GPIO_CAN1_TERMINATION); + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + putreg32(getreg32(STM32_RCC_APB1RSTR) & ~RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + +#if defined(OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO) + stm32_configgpio(GPIO_GETNODEINFO_JUMPER); +#endif + +} + +/************************************************************************************ + * Name: board_deinitialize + * + * Description: + * This function is called by the bootloader code prior to booting + * the application. Is should place the HW into an benign initialized state. + * + ************************************************************************************/ + +void board_deinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); +} + +/**************************************************************************** + * Name: board_get_product_name + * + * Description: + * Called to retrieve the product name. The returned value is a assumed + * to be written to a pascal style string that will be length prefixed + * and not null terminated + * + * Input Parameters: + * product_name - A pointer to a buffer to write the name. + * maxlen - The maximum number of charter that can be written + * + * Returned Value: + * The length of characters written to the buffer. + * + ****************************************************************************/ + +uint8_t board_get_product_name(uint8_t *product_name, size_t maxlen) +{ + DEBUGASSERT(maxlen > UAVCAN_STRLEN(HW_UAVCAN_NAME)); + memcpy(product_name, HW_UAVCAN_NAME, UAVCAN_STRLEN(HW_UAVCAN_NAME)); + return UAVCAN_STRLEN(HW_UAVCAN_NAME); +} + +/**************************************************************************** + * Name: board_get_hardware_version + * + * Description: + * Called to retrieve the hardware version information. The function + * will first initialize the the callers struct to all zeros. + * + * Input Parameters: + * hw_version - A pointer to a uavcan_hardwareversion_t. + * + * Returned Value: + * Length of the unique_id + * + ****************************************************************************/ + +size_t board_get_hardware_version(uavcan_HardwareVersion_t *hw_version) +{ + memset(hw_version, 0, sizeof(uavcan_HardwareVersion_t)); + + hw_version->major = HW_VERSION_MAJOR; + hw_version->minor = HW_VERSION_MINOR; + + return board_get_mfguid(*(mfguid_t *) hw_version->unique_id); +} + +/**************************************************************************** + * Name: board_indicate + * + * Description: + * Provides User feedback to indicate the state of the bootloader + * on board specific hardware. + * + * Input Parameters: + * indication - A member of the uiindication_t + * + * Returned Value: + * None + * + ****************************************************************************/ +#define led(n, code, r , g , b, h) {.red = (r),.green = (g), .blue = (b),.hz = (h)} + +typedef begin_packed_struct struct led_t { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t hz; +} end_packed_struct led_t; + +static const led_t i2l[] = { + + led(0, off, 0, 0, 0, 0), + led(1, reset, 128, 128, 128, 30), + led(2, autobaud_start, 0, 128, 0, 1), + led(3, autobaud_end, 0, 128, 0, 2), + led(4, allocation_start, 0, 0, 64, 2), + led(5, allocation_end, 0, 128, 64, 3), + led(6, fw_update_start, 32, 128, 64, 3), + led(7, fw_update_erase_fail, 32, 128, 32, 3), + led(8, fw_update_invalid_response, 64, 0, 0, 1), + led(9, fw_update_timeout, 64, 0, 0, 2), + led(a, fw_update_invalid_crc, 64, 0, 0, 4), + led(b, jump_to_app, 0, 128, 0, 10), + +}; + +void board_indicate(uiindication_t indication) +{ + rgb_led(i2l[indication].red, + i2l[indication].green, + i2l[indication].blue, + i2l[indication].hz); +} diff --git a/boards/ark/f9p-gps/src/boot_config.h b/boards/ark/f9p-gps/src/boot_config.h new file mode 100644 index 0000000000..7da61bb2bb --- /dev/null +++ b/boards/ark/f9p-gps/src/boot_config.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* + * @file boot_config.h + * + * bootloader definitions that configures the behavior and options + * of the Boot loader + * This file is relies on the parent folder's boot_config.h file and defines + * different usages of the hardware for bootloading + */ + +#pragma once + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* Bring in the board_config.h definitions + * todo:make this be pulled in from a targed's build + * files in nuttx*/ + +#include "board_config.h" +#include "uavcan.h" +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OPT_PREFERRED_NODE_ID ANY_NODE_ID + +//todo:wrap OPT_x in in ifdefs for command line definitions +#define OPT_TBOOT_MS 3000 +#define OPT_NODE_STATUS_RATE_MS 800 +#define OPT_NODE_INFO_RATE_MS 50 +#define OPT_BL_NUMBER_TIMERS 7 + +/* + * This Option set is set to 1 ensure a provider of firmware has an + * opportunity update the node's firmware. + * This Option is the default policy and can be overridden by + * a jumper + * When this Policy is set, the node will ignore tboot and + * wait indefinitely for a GetNodeInfo request before booting. + * + * OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT is used to allow + * the polarity of the jumper to be True Active + * + * wait OPT_WAIT_FOR_GETNODEINFO OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO + * Jumper + * yes 1 0 x + * yes 1 1 Active + * no 1 1 Not Active + * no 0 0 X + * yes 0 1 Active + * no 0 1 Not Active + * + */ +#define OPT_WAIT_FOR_GETNODEINFO 0 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1 + +#define OPT_ENABLE_WD 1 + +#define OPT_RESTART_TIMEOUT_MS 20000 + +/* Reserved for the Booloader */ +#define OPT_BOOTLOADER_SIZE_IN_K (1024*64) + +/* Reserved for the application out of the total + * system flash minus the BOOTLOADER_SIZE_IN_K + */ +#define OPT_APPLICATION_RESERVER_IN_K 0 + +#define OPT_APPLICATION_IMAGE_OFFSET OPT_BOOTLOADER_SIZE_IN_K +#define OPT_APPLICATION_IMAGE_LENGTH (FLASH_SIZE-(OPT_BOOTLOADER_SIZE_IN_K+OPT_APPLICATION_RESERVER_IN_K)) + + +#define FLASH_BASE STM32_FLASH_BASE +#define FLASH_SIZE STM32_FLASH_SIZE + +#define APPLICATION_LOAD_ADDRESS (FLASH_BASE + OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_SIZE (FLASH_SIZE-OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_LAST_8BIT_ADDRRESS ((uint8_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint8_t))) +#define APPLICATION_LAST_32BIT_ADDRRESS ((uint32_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint32_t))) +#define APPLICATION_LAST_64BIT_ADDRRESS ((uint64_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint64_t))) + +/* If this board uses big flash that have large sectors */ + +#define OPT_USE_YIELD + +/* Bootloader Option***************************************************************** + * + */ +#define GPIO_GETNODEINFO_JUMPER (GPIO_BOOT_CONFIG & ~GPIO_EXTI) diff --git a/boards/ark/f9p-gps/src/can.c b/boards/ark/f9p-gps/src/can.c new file mode 100644 index 0000000000..bb1a7025e8 --- /dev/null +++ b/boards/ark/f9p-gps/src/can.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file can.c + * + * Board-specific CAN functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "stm32.h" +#include "stm32_can.h" +#include "board_config.h" + +#ifdef CONFIG_CAN + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} + +#endif diff --git a/boards/ark/f9p-gps/src/i2c.cpp b/boards/ark/f9p-gps/src/i2c.cpp new file mode 100644 index 0000000000..6700d8c8f2 --- /dev/null +++ b/boards/ark/f9p-gps/src/i2c.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), + initI2CBusExternal(2), +}; diff --git a/boards/ark/f9p-gps/src/init.c b/boards/ark/f9p-gps/src/init.c new file mode 100644 index 0000000000..c036e72f56 --- /dev/null +++ b/boards/ark/f9p-gps/src/init.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * board specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "board_config.h" +#include "led.h" +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +# if defined(FLASH_BASED_PARAMS) +# include +#endif + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + watchdog_init(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + // Configure SPI all interfaces GPIO & enable power. + stm32_spiinitialize(); + + // Check if button is held. If so go into gps passthrough mode + if (stm32_gpioread(GPIO_BTN_SAFETY)) { + rgb_led(128, 128, 128, 10); + stm32_configgpio(GPIO_USART1_TX_GPIO); + stm32_configgpio(GPIO_USART1_RX_GPIO); + stm32_configgpio(GPIO_USART2_TX_GPIO); + stm32_configgpio(GPIO_USART2_RX_GPIO); + + while (1) { + watchdog_pet(); + stm32_gpiowrite(GPIO_USART2_TX_GPIO, stm32_gpioread(GPIO_USART1_RX_GPIO)); + stm32_gpiowrite(GPIO_USART1_TX_GPIO, stm32_gpioread(GPIO_USART2_RX_GPIO)); + } + } +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + px4_platform_init(); + +#if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); +#endif + +#if defined(FLASH_BASED_PARAMS) + static sector_descriptor_t params_sector_map[] = { + {2, 16 * 1024, 0x08008000}, + {3, 16 * 1024, 0x0800C000}, + {0, 0, 0}, + }; + + /* Initialize the flashfs layer to use heap allocated memory */ + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + } + +#endif // FLASH_BASED_PARAMS + + /* Configure the HW based on the manifest */ + //px4_platform_configure(); + + return OK; +} diff --git a/boards/ark/f9p-gps/src/led.c b/boards/ark/f9p-gps/src/led.c new file mode 100644 index 0000000000..d2a2126d33 --- /dev/null +++ b/boards/ark/f9p-gps/src/led.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +#include "led.h" + +#define TMR_BASE STM32_TIM1_BASE +#define TMR_FREQUENCY STM32_APB2_TIM1_CLKIN +#define TMR_REG(o) (TMR_BASE+(o)) + +void rgb_led(int r, int g, int b, int freqs) +{ + + long fosc = TMR_FREQUENCY; + long prescale = 2048; + long p1s = fosc / prescale; + long p0p5s = p1s / 2; + uint16_t val; + static bool once = 0; + + if (!once) { + once = 1; + + /* Enabel Clock to Block */ + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + + /* Reload */ + + val = getreg16(TMR_REG(STM32_BTIM_EGR_OFFSET)); + val |= ATIM_EGR_UG; + putreg16(val, TMR_REG(STM32_BTIM_EGR_OFFSET)); + + /* Set Prescaler STM32_TIM_SETCLOCK */ + + putreg16(prescale, TMR_REG(STM32_BTIM_PSC_OFFSET)); + + /* Enable STM32_TIM_SETMODE*/ + + putreg16(ATIM_CR1_CEN | ATIM_CR1_ARPE, TMR_REG(STM32_BTIM_CR1_OFFSET)); + + + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) | ATIM_CCMR1_OC1PE | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) | ATIM_CCMR1_OC2PE, TMR_REG(STM32_GTIM_CCMR1_OFFSET)); + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) | ATIM_CCMR2_OC3PE, TMR_REG(STM32_GTIM_CCMR2_OFFSET)); + putreg16(ATIM_CCER_CC3E | ATIM_CCER_CC3P | + ATIM_CCER_CC2E | ATIM_CCER_CC2P | + ATIM_CCER_CC1E | ATIM_CCER_CC1P, TMR_REG(STM32_GTIM_CCER_OFFSET)); + + + stm32_configgpio(GPIO_TIM1_CH1); + stm32_configgpio(GPIO_TIM1_CH2); + stm32_configgpio(GPIO_TIM1_CH3); + + /* master output enable = on */ + putreg16(ATIM_BDTR_MOE, (TMR_REG(STM32_ATIM_BDTR_OFFSET))); + } + + long p = freqs == 0 ? p1s : p1s / freqs; + putreg32(p, TMR_REG(STM32_BTIM_ARR_OFFSET)); + + p = freqs == 0 ? p1s + 1 : p0p5s / freqs; + + putreg32((r * p) / 255, TMR_REG(STM32_GTIM_CCR1_OFFSET)); + putreg32((g * p) / 255, TMR_REG(STM32_GTIM_CCR2_OFFSET)); + putreg32((b * p) / 255, TMR_REG(STM32_GTIM_CCR3_OFFSET)); + + val = getreg16(TMR_REG(STM32_BTIM_CR1_OFFSET)); + + if (freqs == 0) { + val &= ~ATIM_CR1_CEN; + + } else { + val |= ATIM_CR1_CEN; + } + + putreg16(val, TMR_REG(STM32_BTIM_CR1_OFFSET)); + +} diff --git a/boards/ark/fmu-v6x/src/spix_sync.h b/boards/ark/f9p-gps/src/led.h similarity index 81% rename from boards/ark/fmu-v6x/src/spix_sync.h rename to boards/ark/f9p-gps/src/led.h index 2e37c89086..0d71157cc8 100644 --- a/boards/ark/fmu-v6x/src/spix_sync.h +++ b/boards/ark/f9p-gps/src/led.h @@ -1,6 +1,7 @@ /**************************************************************************** * - * Copyright (C) 2023 PX4 Development Team. All rights reserved. + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * Author: David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,11 +33,5 @@ ****************************************************************************/ __BEGIN_DECLS -void spix_sync_channel_init(unsigned channel); -int spix_sync_servo_set(unsigned channel, uint8_t value); -unsigned spix_sync_servo_get(unsigned channel); -int spix_sync_servo_init(unsigned rate); -void spix_sync_servo_deinit(void); -void spix_sync_servo_arm(bool armed); -unsigned spix_sync_timer_get_period(unsigned timer); +void rgb_led(int r, int g, int b, int freqs); __END_DECLS diff --git a/boards/ark/f9p-gps/src/spi.cpp b/boards/ark/f9p-gps/src/spi.cpp new file mode 100644 index 0000000000..baafb0354c --- /dev/null +++ b/boards/ark/f9p-gps/src/spi.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortB, GPIO::Pin0}, SPI::DRDY{GPIO::PortB, GPIO::Pin1}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/ark/f9p-gps/uavcan_board_identity b/boards/ark/f9p-gps/uavcan_board_identity new file mode 100644 index 0000000000..59ef104022 --- /dev/null +++ b/boards/ark/f9p-gps/uavcan_board_identity @@ -0,0 +1,17 @@ +# UAVCAN boot loadable Module ID +set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR}) +set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR}) +add_definitions( + -DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major} + -DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor} +) + +set(uavcanblid_hw_version_major 0) +set(uavcanblid_hw_version_minor 90) +set(uavcanblid_name "\"org.ark.f9p-gps\"") + +add_definitions( + -DHW_UAVCAN_NAME=${uavcanblid_name} + -DHW_VERSION_MAJOR=${uavcanblid_hw_version_major} + -DHW_VERSION_MINOR=${uavcanblid_hw_version_minor} +) diff --git a/boards/ark/fmu-v6x/default.px4board b/boards/ark/fmu-v6x/default.px4board index a4b5c42f18..cb8bae6ae0 100644 --- a/boards/ark/fmu-v6x/default.px4board +++ b/boards/ark/fmu-v6x/default.px4board @@ -19,6 +19,7 @@ CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_AUAV=y CONFIG_COMMON_DISTANCE_SENSOR=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_PPS_CAPTURE=y CONFIG_DRIVERS_HEATER=y CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16507=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y @@ -34,11 +35,11 @@ CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y CONFIG_DRIVERS_MAGNETOMETER_LSM303AGR=y CONFIG_DRIVERS_MAGNETOMETER_RM3100=y -CONFIG_DRIVERS_MAGNETOMETER_MEMSIC_MMC5983MA=y CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y CONFIG_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 CONFIG_DRIVERS_PX4IO=y CONFIG_COMMON_RC=y @@ -71,7 +72,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 diff --git a/boards/ark/fmu-v6x/init/rc.board_defaults b/boards/ark/fmu-v6x/init/rc.board_defaults index d0732e90ef..7b96f86974 100644 --- a/boards/ark/fmu-v6x/init/rc.board_defaults +++ b/boards/ark/fmu-v6x/init/rc.board_defaults @@ -14,10 +14,7 @@ param set-default MAV_2_RATE 100000 param set-default MAV_2_REMOTE_PRT 14550 param set-default MAV_2_UDP_PRT 14550 -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 param set-default SENS_EN_INA226 1 - param set-default SENS_EN_THERMAL 1 param set-default SENS_IMU_MODE 1 param set-default SENS_IMU_TEMP 10.0 @@ -25,6 +22,8 @@ param set-default SENS_IMU_TEMP 10.0 #param set-default SENS_IMU_TEMP_I 0.025 #param set-default SENS_IMU_TEMP_P 1.0 +param set-default UAVCAN_ESC_IFACE 2 + if ver hwtypecmp ARKV6X000 then param set-default SENS_TEMP_ID 2818058 diff --git a/boards/ark/fmu-v6x/init/rc.board_sensors b/boards/ark/fmu-v6x/init/rc.board_sensors index aacbc22db0..7b2259f8ad 100644 --- a/boards/ark/fmu-v6x/init/rc.board_sensors +++ b/boards/ark/fmu-v6x/init/rc.board_sensors @@ -1,6 +1,6 @@ #!/bin/sh # -# ARK FMUARKV6X specific board sensors init +# ARK FMU V6X specific board sensors init #------------------------------------------------------------------------------ set HAVE_PM2 yes set HAVE_PM3 yes @@ -69,28 +69,25 @@ fi if ver hwtypecmp ARKV6X000 then - # Internal SPI bus IIM42652 with SPIX measured frequency of 32.051kHz - iim42652 -R 3 -s -b 1 -C 32051 start + # Internal SPI bus IIM42652 + iim42652 -R 3 -s -b 1 start - # Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz - icm42688p -R 9 -s -b 2 -C 32051 start + # Internal SPI bus ICM42688p + icm42688p -R 9 -s -b 2 start - # Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz - icm42688p -R 6 -s -b 3 -C 32051 start + # Internal SPI bus ICM42688p + icm42688p -R 6 -s -b 3 start fi if ver hwtypecmp ARKV6X001 then - # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz - #iim42653 -R 3 -s -b 1 -C 32051 start + # Internal SPI bus IIM42653 iim42653 -R 3 -s -b 1 start - # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz - #iim42653 -R 9 -s -b 2 -C 32051 start + # Internal SPI bus IIM42653 iim42653 -R 9 -s -b 2 start - # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz - #iim42653 -R 6 -s -b 3 -C 32051 start + # Internal SPI bus IIM42653 iim42653 -R 6 -s -b 3 start fi @@ -100,5 +97,11 @@ bmm150 -I start # Internal Baro on I2C bmp388 -I start +# Start an external PWM generator +if param greater PCA9685_EN_BUS 0 +then + pca9685_pwm_out start +fi + unset HAVE_PM2 unset HAVE_PM3 diff --git a/boards/ark/fmu-v6x/src/CMakeLists.txt b/boards/ark/fmu-v6x/src/CMakeLists.txt index 78b8222f19..a120ebe336 100644 --- a/boards/ark/fmu-v6x/src/CMakeLists.txt +++ b/boards/ark/fmu-v6x/src/CMakeLists.txt @@ -57,8 +57,6 @@ else() mtd.cpp sdio.c spi.cpp - spix_sync.c - spix_sync.h timer_config.cpp usb.c ) diff --git a/boards/ark/fmu-v6x/src/board_config.h b/boards/ark/fmu-v6x/src/board_config.h index 302fbc22d9..16d0aa9300 100644 --- a/boards/ark/fmu-v6x/src/board_config.h +++ b/boards/ark/fmu-v6x/src/board_config.h @@ -241,7 +241,7 @@ /* PWM */ -#define DIRECT_PWM_OUTPUT_CHANNELS 8 +#define DIRECT_PWM_OUTPUT_CHANNELS 9 #define GPIO_FMU_CH1 /* PI0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN0) #define GPIO_FMU_CH2 /* PH12 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN12) @@ -482,7 +482,7 @@ #define PX4_I2C_BUS_MTD 4,5 -#define BOARD_NUM_IO_TIMERS 3 +#define BOARD_NUM_IO_TIMERS 4 #define BOARD_SPIX_SYNC_FREQ 32000 __BEGIN_DECLS diff --git a/boards/ark/fmu-v6x/src/init.c b/boards/ark/fmu-v6x/src/init.c index 6c1c2257ed..c60f700af1 100644 --- a/boards/ark/fmu-v6x/src/init.c +++ b/boards/ark/fmu-v6x/src/init.c @@ -46,7 +46,6 @@ ****************************************************************************/ #include "board_config.h" -#include "spix_sync.h" #include #include @@ -290,9 +289,5 @@ __EXPORT int board_app_initialize(uintptr_t arg) #endif /* CONFIG_MMCSD */ - /* Configure the SPIX_SYNC output */ - spix_sync_servo_init(BOARD_SPIX_SYNC_FREQ); - spix_sync_servo_set(0, 150); - return OK; } diff --git a/boards/ark/fmu-v6x/src/spix_sync.c b/boards/ark/fmu-v6x/src/spix_sync.c deleted file mode 100644 index 056e38e75f..0000000000 --- a/boards/ark/fmu-v6x/src/spix_sync.c +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2023 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name Airmind nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** -* @file spix_sync.c -* -* -*/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include - -#include - -#include "spix_sync.h" - -#define REG(_tmr, _reg) (*(volatile uint32_t *)(spix_sync_timers[_tmr].base + _reg)) - -#define rCR1(_tmr) REG(_tmr, STM32_GTIM_CR1_OFFSET) -#define rCR2(_tmr) REG(_tmr, STM32_GTIM_CR2_OFFSET) -#define rSMCR(_tmr) REG(_tmr, STM32_GTIM_SMCR_OFFSET) -#define rDIER(_tmr) REG(_tmr, STM32_GTIM_DIER_OFFSET) -#define rSR(_tmr) REG(_tmr, STM32_GTIM_SR_OFFSET) -#define rEGR(_tmr) REG(_tmr, STM32_GTIM_EGR_OFFSET) -#define rCCMR1(_tmr) REG(_tmr, STM32_GTIM_CCMR1_OFFSET) -#define rCCMR2(_tmr) REG(_tmr, STM32_GTIM_CCMR2_OFFSET) -#define rCCER(_tmr) REG(_tmr, STM32_GTIM_CCER_OFFSET) -#define rCNT(_tmr) REG(_tmr, STM32_GTIM_CNT_OFFSET) -#define rPSC(_tmr) REG(_tmr, STM32_GTIM_PSC_OFFSET) -#define rARR(_tmr) REG(_tmr, STM32_GTIM_ARR_OFFSET) -#define rCCR1(_tmr) REG(_tmr, STM32_GTIM_CCR1_OFFSET) -#define rCCR2(_tmr) REG(_tmr, STM32_GTIM_CCR2_OFFSET) -#define rCCR3(_tmr) REG(_tmr, STM32_GTIM_CCR3_OFFSET) -#define rCCR4(_tmr) REG(_tmr, STM32_GTIM_CCR4_OFFSET) -#define rDCR(_tmr) REG(_tmr, STM32_GTIM_DCR_OFFSET) -#define rDMAR(_tmr) REG(_tmr, STM32_GTIM_DMAR_OFFSET) -#define rBDTR(_tmr) REG(_tmr, STM32_ATIM_BDTR_OFFSET) - -#define BOARD_SPIX_SYNC_PWM_FREQ 1024000 - -unsigned -spix_sync_timer_get_period(unsigned timer) -{ - return (rARR(timer)); -} - -static void spix_sync_timer_init_timer(unsigned timer, unsigned rate) -{ - if (spix_sync_timers[timer].base) { - - irqstate_t flags = px4_enter_critical_section(); - - /* enable the timer clock before we try to talk to it */ - - modifyreg32(spix_sync_timers[timer].clock_register, 0, spix_sync_timers[timer].clock_bit); - - /* disable and configure the timer */ - rCR1(timer) = 0; - rCR2(timer) = 0; - rSMCR(timer) = 0; - rDIER(timer) = 0; - rCCER(timer) = 0; - rCCMR1(timer) = 0; - rCCMR2(timer) = 0; - rCCR1(timer) = 0; - rCCR2(timer) = 0; - rCCR3(timer) = 0; - rCCR4(timer) = 0; - rCCER(timer) = 0; - rDCR(timer) = 0; - - if ((spix_sync_timers[timer].base == STM32_TIM1_BASE) || (spix_sync_timers[timer].base == STM32_TIM8_BASE)) { - - /* master output enable = on */ - - rBDTR(timer) = ATIM_BDTR_MOE; - } - - /* If the timer clock source provided as clock_freq is the STM32_APBx_TIMx_CLKIN - * then configure the timer to free-run at 1MHz. - * Otherwise, other frequencies are attainable by adjusting .clock_freq accordingly. - */ - - rPSC(timer) = (spix_sync_timers[timer].clock_freq / BOARD_SPIX_SYNC_PWM_FREQ) - 1; - - /* configure the timer to update at the desired rate */ - - rARR(timer) = (BOARD_SPIX_SYNC_PWM_FREQ / rate) - 1; - - /* generate an update event; reloads the counter and all registers */ - rEGR(timer) = GTIM_EGR_UG; - - px4_leave_critical_section(flags); - } - -} - -void spix_sync_channel_init(unsigned channel) -{ - /* Only initialize used channels */ - - if (spix_sync_channels[channel].timer_channel) { - - unsigned timer = spix_sync_channels[channel].timer_index; - - /* configure the GPIO first */ - px4_arch_configgpio(spix_sync_channels[channel].gpio_out); - - uint16_t polarity = spix_sync_channels[channel].masks; - - /* configure the channel */ - switch (spix_sync_channels[channel].timer_channel) { - case 1: - rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC1M_SHIFT) | GTIM_CCMR1_OC1PE; - rCCER(timer) |= polarity | GTIM_CCER_CC1E; - break; - - case 2: - rCCMR1(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR1_OC2M_SHIFT) | GTIM_CCMR1_OC2PE; - rCCER(timer) |= polarity | GTIM_CCER_CC2E; - break; - - case 3: - rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC3M_SHIFT) | GTIM_CCMR2_OC3PE; - rCCER(timer) |= polarity | GTIM_CCER_CC3E; - break; - - case 4: - rCCMR2(timer) |= (GTIM_CCMR_MODE_PWM1 << GTIM_CCMR2_OC4M_SHIFT) | GTIM_CCMR2_OC4PE; - rCCER(timer) |= polarity | GTIM_CCER_CC4E; - break; - } - } -} - -int -spix_sync_servo_set(unsigned channel, uint8_t cvalue) -{ - if (channel >= arraySize(spix_sync_channels)) { - return -1; - } - - unsigned timer = spix_sync_channels[channel].timer_index; - - /* test timer for validity */ - if ((spix_sync_timers[timer].base == 0) || - (spix_sync_channels[channel].gpio_out == 0)) { - return -1; - } - - unsigned period = spix_sync_timer_get_period(timer); - - unsigned value = (unsigned)cvalue * period / 255; - - /* configure the channel */ - if (value > 0) { - value--; - } - - - switch (spix_sync_channels[channel].timer_channel) { - case 1: - rCCR1(timer) = value; - break; - - case 2: - rCCR2(timer) = value; - break; - - case 3: - rCCR3(timer) = value; - break; - - case 4: - rCCR4(timer) = value; - break; - - default: - return -1; - } - - return 0; -} - -unsigned spix_sync_servo_get(unsigned channel) -{ - if (channel >= 3) { - return 0; - } - - unsigned timer = spix_sync_channels[channel].timer_index; - uint16_t value = 0; - - /* test timer for validity */ - if ((spix_sync_timers[timer].base == 0) || - (spix_sync_channels[channel].timer_channel == 0)) { - return 0; - } - - /* configure the channel */ - switch (spix_sync_channels[channel].timer_channel) { - case 1: - value = rCCR1(timer); - break; - - case 2: - value = rCCR2(timer); - break; - - case 3: - value = rCCR3(timer); - break; - - case 4: - value = rCCR4(timer); - break; - } - - unsigned period = spix_sync_timer_get_period(timer); - return ((value + 1) * 255 / period); -} - -int spix_sync_servo_init(unsigned rate) -{ - /* do basic timer initialisation first */ - for (unsigned i = 0; i < arraySize(spix_sync_timers); i++) { - spix_sync_timer_init_timer(i, rate); - } - - /* now init channels */ - for (unsigned i = 0; i < arraySize(spix_sync_channels); i++) { - spix_sync_channel_init(i); - } - - spix_sync_servo_arm(true); - return OK; -} - -void -spix_sync_servo_deinit(void) -{ - /* disable the timers */ - spix_sync_servo_arm(false); -} -void -spix_sync_servo_arm(bool armed) -{ - /* iterate timers and arm/disarm appropriately */ - for (unsigned i = 0; i < arraySize(spix_sync_timers); i++) { - if (spix_sync_timers[i].base != 0) { - if (armed) { - /* force an update to preload all registers */ - rEGR(i) = GTIM_EGR_UG; - - /* arm requires the timer be enabled */ - rCR1(i) |= GTIM_CR1_CEN | GTIM_CR1_ARPE; - - } else { - rCR1(i) = 0; - } - } - } -} diff --git a/boards/ark/fmu-v6x/src/timer_config.cpp b/boards/ark/fmu-v6x/src/timer_config.cpp index 3504c3569d..75d67bac99 100644 --- a/boards/ark/fmu-v6x/src/timer_config.cpp +++ b/boards/ark/fmu-v6x/src/timer_config.cpp @@ -60,8 +60,7 @@ constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { initIOTimer(Timer::Timer5, DMA{DMA::Index1}), initIOTimer(Timer::Timer4, DMA{DMA::Index1}), initIOTimer(Timer::Timer12), - //initIOTimer(Timer::Timer1), - //initIOTimer(Timer::Timer2), + initIOTimer(Timer::Timer1), }; constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { @@ -73,18 +72,8 @@ constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel3}, {GPIO::PortD, GPIO::Pin14}), initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel1}, {GPIO::PortH, GPIO::Pin6}), initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel2}, {GPIO::PortH, GPIO::Pin9}), - //initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), - //initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), + initIOTimerChannelCapture(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), }; constexpr io_timers_channel_mapping_t io_timers_channel_mapping = initIOTimerChannelMapping(io_timers, timer_io_channels); - - -constexpr io_timers_t spix_sync_timers[MAX_SPIX_SYNC_TIMERS] = { - initIOTimer(Timer::Timer1), -}; - -constexpr timer_io_channels_t spix_sync_channels[MAX_SPIX_SYNC_TIMERS] = { - initIOTimerChannel(spix_sync_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), -}; diff --git a/boards/ark/fpv/default.px4board b/boards/ark/fpv/default.px4board index e7437b0cc7..368c1af8e3 100644 --- a/boards/ark/fpv/default.px4board +++ b/boards/ark/fpv/default.px4board @@ -19,8 +19,17 @@ CONFIG_DRIVERS_HEATER=y CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y CONFIG_DRIVERS_IMU_MURATA_SCH16T=y CONFIG_COMMON_LIGHT=y -CONFIG_COMMON_MAGNETOMETER=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_OSD_MSP_OSD=y +CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y CONFIG_DRIVERS_UAVCAN=y @@ -50,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 diff --git a/boards/ark/fpv/init/rc.board_defaults b/boards/ark/fpv/init/rc.board_defaults index 5605f60d02..dc7a548573 100644 --- a/boards/ark/fpv/init/rc.board_defaults +++ b/boards/ark/fpv/init/rc.board_defaults @@ -30,6 +30,8 @@ param set-default BAT1_V_DIV 21.0 param set-default RC_CRSF_PRT_CFG 300 param set-default RC_SBUS_PRT_CFG 0 +param set-default UAVCAN_ESC_IFACE 1 + param set-default IMU_GYRO_DNF_EN 3 # Single IMU diff --git a/boards/ark/fpv/init/rc.board_sensors b/boards/ark/fpv/init/rc.board_sensors index 896b9ffd7d..e719938f86 100644 --- a/boards/ark/fpv/init/rc.board_sensors +++ b/boards/ark/fpv/init/rc.board_sensors @@ -16,3 +16,9 @@ iis2mdc -R 0 -I -b 4 start # Internal Baro on I2C bmp388 -I -b 2 start + +# Start an external PWM generator +if param greater PCA9685_EN_BUS 0 +then + pca9685_pwm_out start +fi diff --git a/boards/ark/mag/canbootloader.px4board b/boards/ark/mag/canbootloader.px4board new file mode 100644 index 0000000000..46917280f6 --- /dev/null +++ b/boards/ark/mag/canbootloader.px4board @@ -0,0 +1,5 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BOOTLOADERS=y diff --git a/boards/ark/mag/default.px4board b/boards/ark/mag/default.px4board new file mode 100644 index 0000000000..53f391b7e8 --- /dev/null +++ b/boards/ark/mag/default.px4board @@ -0,0 +1,22 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="cannode" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BOOTLOADERS=y +CONFIG_DRIVERS_MAGNETOMETER_RM3100=y +CONFIG_BOARD_UAVCAN_INTERFACES=1 +CONFIG_DRIVERS_UAVCANNODE=y +CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y +CONFIG_MODULES_SENSORS=y +# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set +# CONFIG_SENSORS_VEHICLE_AIR_DATA is not set +# CONFIG_SENSORS_VEHICLE_GPS_POSITION is not set +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/ark/mag/firmware.prototype b/boards/ark/mag/firmware.prototype new file mode 100644 index 0000000000..35ba6379fb --- /dev/null +++ b/boards/ark/mag/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 93, + "magic": "PX4FWv1", + "description": "Firmware for the ARK MAG board", + "image": "", + "build_time": 0, + "summary": "ARKMAG", + "version": "0.1", + "image_size": 0, + "image_maxsize": 2080768, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/ark/mag/init/rc.board_sensors b/boards/ark/mag/init/rc.board_sensors new file mode 100644 index 0000000000..29163fabc9 --- /dev/null +++ b/boards/ark/mag/init/rc.board_sensors @@ -0,0 +1,6 @@ +#!/bin/sh +# +# board sensors init +#------------------------------------------------------------------------------ + +rm3100 -s -b 2 start diff --git a/boards/ark/mag/nuttx-config/canbootloader/defconfig b/boards/ark/mag/nuttx-config/canbootloader/defconfig new file mode 100644 index 0000000000..11b948472f --- /dev/null +++ b/boards/ark/mag/nuttx-config/canbootloader/defconfig @@ -0,0 +1,57 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/mag/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARDCTL=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_STACKSIZE=4096 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=0 +CONFIG_NUNGET_CHARS=0 +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_NOEXT_VECTORS=y +CONFIG_STM32_TIM8=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/mag/nuttx-config/include/board.h b/boards/ark/mag/nuttx-config/include/board.h new file mode 100644 index 0000000000..18079b86e1 --- /dev/null +++ b/boards/ark/mag/nuttx-config/include/board.h @@ -0,0 +1,132 @@ +/************************************************************************************ + * configs/px4fmu/include/board.h + * include/arch/board/board.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#include "board_dma_map.h" + +#ifndef __ARCH_BOARD_BOARD_H +#define __ARCH_BOARD_BOARD_H + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include + +/* HSI - 8 MHz RC factory-trimmed + * LSI - 32 KHz RC + * HSE - 8 MHz Crystal + * LSE - not installed + */ +#define STM32_BOARD_USEHSE 1 +#define STM32_BOARD_XTAL 8000000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 + +/* Main PLL Configuration */ +#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8) +#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(384) +#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_4 +#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(8) +#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(2) + +#define STM32_RCC_PLLI2SCFGR_PLLI2SM RCC_PLLI2SCFGR_PLLI2SM(16) +#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) +#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SR RCC_PLLI2SCFGR_PLLI2SR(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SSRC RCC_PLLI2SCFGR_PLLI2SSRC(0) /* HSE or HSI depending on PLLSRC of PLLCFGR*/ + +#define STM32_RCC_DCKCFGR2_CK48MSEL RCC_DCKCFGR2_CK48MSEL_PLL +#define STM32_RCC_DCKCFGR2_FMPI2C1SEL RCC_DCKCFGR2_FMPI2C1SEL_APB +#define STM32_RCC_DCKCFGR2_SDIOSEL RCC_DCKCFGR2_SDIOSEL_48MHZ + +#define STM32_SYSCLK_FREQUENCY 96000000ul + +/* AHB clock (HCLK) is SYSCLK (96MHz) */ +#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ +#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (48MHz) */ +#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timers driven from APB1 will be twice PCLK1 (see page 112 of reference manual) */ +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* APB2 clock (PCLK2) is HCLK (96MHz) */ +#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY) + +/* Timers driven from APB2 will be PCLK2 since no prescale division */ +#define STM32_APB2_TIM1_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM9_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM10_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM11_CLKIN (STM32_PCLK2_FREQUENCY) + +/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx otherwise frequency is 2xAPBx. */ +#define BOARD_TIM2_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM3_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM4_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM5_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM6_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM7_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM8_FREQUENCY (2 * STM32_PCLK2_FREQUENCY) + +/* Alternate function pin selections ************************************************/ + +/* UARTs */ +#define GPIO_USART2_RX GPIO_USART2_RX_1 +#define GPIO_USART2_TX GPIO_USART2_TX_1 + +/* CAN */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_1 +#define GPIO_CAN1_TX GPIO_CAN1_TX_1 + +/* SPI */ +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1 /* PB15 */ +#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1 /* PB10 */ + +#endif /* __ARCH_BOARD_BOARD_H */ diff --git a/boards/ark/mag/nuttx-config/include/board_dma_map.h b/boards/ark/mag/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..773b49fc34 --- /dev/null +++ b/boards/ark/mag/nuttx-config/include/board_dma_map.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMA1 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- +#define DMACHAN_SPI2_RX DMAMAP_SPI2_RX // DMA1, Stream 3, Channel 0 +#define DMACHAN_SPI2_TX DMAMAP_SPI2_TX // DMA1, Stream 4, Channel 0 + +// DMA2 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- diff --git a/boards/ark/mag/nuttx-config/nsh/defconfig b/boards/ark/mag/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..665ad0c1c3 --- /dev/null +++ b/boards/ark/mag/nuttx-config/nsh/defconfig @@ -0,0 +1,149 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/mag/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_CROMFS=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=2624 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_VARS=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=254 +CONFIG_SCHED_HPWORKSTACKSIZE=3000 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32_ADC1=y +CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y +CONFIG_STM32_DMA1=y +CONFIG_STM32_DMA2=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_FLASH_PREFETCH=y +CONFIG_STM32_FLOWCONTROL_BROKEN=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWR=y +CONFIG_STM32_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32_SPI2=y +CONFIG_STM32_SPI2_DMA=y +CONFIG_STM32_SPI2_DMA_BUFFER=2048 +CONFIG_STM32_TIM8=y +CONFIG_STM32_USART2=y +CONFIG_STM32_USART_BREAKS=y +CONFIG_STM32_WWDG=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USART2_TXBUFSIZE=1100 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/mag/nuttx-config/scripts/canbootloader_script.ld b/boards/ark/mag/nuttx-config/scripts/canbootloader_script.ld new file mode 100644 index 0000000000..48a59fe92d --- /dev/null +++ b/boards/ark/mag/nuttx-config/scripts/canbootloader_script.ld @@ -0,0 +1,134 @@ +/**************************************************************************** + * nuttx-config/scripts/canbootloader_script.ld + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/mag/nuttx-config/scripts/script.ld b/boards/ark/mag/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..2f4769b8f5 --- /dev/null +++ b/boards/ark/mag/nuttx-config/scripts/script.ld @@ -0,0 +1,146 @@ +/**************************************************************************** + * scripts/ld.script + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08010000, LENGTH = 928K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(8); + /* + * This section positions the app_descriptor_t used + * by the make_can_boot_descriptor.py tool to set + * the application image's descriptor so that the + * uavcan bootloader has the ability to validate the + * image crc, size etc + */ + KEEP(*(.app_descriptor)) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/mag/src/CMakeLists.txt b/boards/ark/mag/src/CMakeLists.txt new file mode 100644 index 0000000000..4fae41fc0e --- /dev/null +++ b/boards/ark/mag/src/CMakeLists.txt @@ -0,0 +1,65 @@ +############################################################################ +# +# Copyright (c) 2020 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +if("${PX4_BOARD_LABEL}" STREQUAL "canbootloader") + + add_library(drivers_board + boot_config.h + boot.c + led.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + canbootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/canbootloader) + +else() + add_library(drivers_board + can.c + init.c + led.c + spi.cpp + ) + + target_link_libraries(drivers_board + PRIVATE + arch_spi + drivers__led # drv_led_start + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/ark/mag/src/board_config.h b/boards/ark/mag/src/board_config.h new file mode 100644 index 0000000000..ca6e5bb094 --- /dev/null +++ b/boards/ark/mag/src/board_config.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * board internal definitions + */ + +#pragma once + +#include +#include +#include + +/* CAN Silent mode control */ +#define GPIO_CAN1_SILENT_S0 /* PB11 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN11) + +/* CAN termination software control */ +#define GPIO_CAN1_TERMINATION /* PB13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN_TERM GPIO_CAN1_TERMINATION + +/* Boot config */ +#define GPIO_BOOT_CONFIG /* PC15 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN15|GPIO_EXTI) + +/* LEDs are driven with open drain to support Anode to 5V or 3.3V */ +#define GPIO_TIM1_CH1 /* PA8 */ (GPIO_TIM1_CH1_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH2 /* PA9 */ (GPIO_TIM1_CH2_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH3 /* PA10 */ (GPIO_TIM1_CH3_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) + +#define FLASH_BASED_PARAMS + +/* High-resolution timer */ +#define HRT_TIMER 3 /* use timer 3 for the HRT */ +#define HRT_TIMER_CHANNEL 4 /* use capture/compare channel 4 */ + +#define PX4_GPIO_INIT_LIST { \ + GPIO_BOOT_CONFIG, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN1_SILENT_S0, \ + GPIO_CAN1_TERMINATION, \ + } + +__BEGIN_DECLS + +#define BOARD_HAS_N_S_RGB_LED 1 +#define BOARD_MAX_LEDS BOARD_HAS_N_S_RGB_LED + +#ifndef __ASSEMBLY__ + +extern void stm32_spiinitialize(void); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/ark/mag/src/boot.c b/boards/ark/mag/src/boot.c new file mode 100644 index 0000000000..a26034e254 --- /dev/null +++ b/boards/ark/mag/src/boot.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Author: Ben Dyer + * Pavel Kirienko + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "boot_config.h" +#include "board.h" + +#include +#include +#include + +#include +#include "led.h" + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1ENR) | RCC_APB1ENR_CAN1EN, STM32_RCC_APB1ENR); + stm32_configgpio(GPIO_CAN1_RX); + stm32_configgpio(GPIO_CAN1_TX); + stm32_configgpio(GPIO_CAN1_SILENT_S0); + stm32_configgpio(GPIO_CAN1_TERMINATION); + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + putreg32(getreg32(STM32_RCC_APB1RSTR) & ~RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + +#if defined(OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO) + stm32_configgpio(GPIO_GETNODEINFO_JUMPER); +#endif + +} + +/************************************************************************************ + * Name: board_deinitialize + * + * Description: + * This function is called by the bootloader code prior to booting + * the application. Is should place the HW into an benign initialized state. + * + ************************************************************************************/ + +void board_deinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); +} + +/**************************************************************************** + * Name: board_get_product_name + * + * Description: + * Called to retrieve the product name. The returned value is a assumed + * to be written to a pascal style string that will be length prefixed + * and not null terminated + * + * Input Parameters: + * product_name - A pointer to a buffer to write the name. + * maxlen - The maximum number of charter that can be written + * + * Returned Value: + * The length of characters written to the buffer. + * + ****************************************************************************/ + +uint8_t board_get_product_name(uint8_t *product_name, size_t maxlen) +{ + DEBUGASSERT(maxlen > UAVCAN_STRLEN(HW_UAVCAN_NAME)); + memcpy(product_name, HW_UAVCAN_NAME, UAVCAN_STRLEN(HW_UAVCAN_NAME)); + return UAVCAN_STRLEN(HW_UAVCAN_NAME); +} + +/**************************************************************************** + * Name: board_get_hardware_version + * + * Description: + * Called to retrieve the hardware version information. The function + * will first initialize the the callers struct to all zeros. + * + * Input Parameters: + * hw_version - A pointer to a uavcan_hardwareversion_t. + * + * Returned Value: + * Length of the unique_id + * + ****************************************************************************/ + +size_t board_get_hardware_version(uavcan_HardwareVersion_t *hw_version) +{ + memset(hw_version, 0, sizeof(uavcan_HardwareVersion_t)); + + hw_version->major = HW_VERSION_MAJOR; + hw_version->minor = HW_VERSION_MINOR; + + return board_get_mfguid(*(mfguid_t *) hw_version->unique_id); +} + +/**************************************************************************** + * Name: board_indicate + * + * Description: + * Provides User feedback to indicate the state of the bootloader + * on board specific hardware. + * + * Input Parameters: + * indication - A member of the uiindication_t + * + * Returned Value: + * None + * + ****************************************************************************/ +#define led(n, code, r , g , b, h) {.red = (r),.green = (g), .blue = (b),.hz = (h)} + +typedef begin_packed_struct struct led_t { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t hz; +} end_packed_struct led_t; + +static const led_t i2l[] = { + + led(0, off, 0, 0, 0, 0), + led(1, reset, 128, 128, 128, 30), + led(2, autobaud_start, 0, 128, 0, 1), + led(3, autobaud_end, 0, 128, 0, 2), + led(4, allocation_start, 0, 0, 64, 2), + led(5, allocation_end, 0, 128, 64, 3), + led(6, fw_update_start, 32, 128, 64, 3), + led(7, fw_update_erase_fail, 32, 128, 32, 3), + led(8, fw_update_invalid_response, 64, 0, 0, 1), + led(9, fw_update_timeout, 64, 0, 0, 2), + led(a, fw_update_invalid_crc, 64, 0, 0, 4), + led(b, jump_to_app, 0, 128, 0, 10), + +}; + +void board_indicate(uiindication_t indication) +{ + rgb_led(i2l[indication].red, + i2l[indication].green, + i2l[indication].blue, + i2l[indication].hz); +} diff --git a/boards/ark/mag/src/boot_config.h b/boards/ark/mag/src/boot_config.h new file mode 100644 index 0000000000..76782f9a93 --- /dev/null +++ b/boards/ark/mag/src/boot_config.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* + * @file boot_config.h + * + * bootloader definitions that configures the behavior and options + * of the Boot loader + * This file is relies on the parent folder's boot_config.h file and defines + * different usages of the hardware for bootloading + */ + +#pragma once + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* Bring in the board_config.h definitions + * todo:make this be pulled in from a targed's build + * files in nuttx*/ + +#include "board_config.h" +#include "uavcan.h" +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OPT_PREFERRED_NODE_ID ANY_NODE_ID + +//todo:wrap OPT_x in in ifdefs for command line definitions +#define OPT_TBOOT_MS 3000 +#define OPT_NODE_STATUS_RATE_MS 800 +#define OPT_NODE_INFO_RATE_MS 50 +#define OPT_BL_NUMBER_TIMERS 7 + +/* + * This Option set is set to 1 ensure a provider of firmware has an + * opportunity update the node's firmware. + * This Option is the default policy and can be overridden by + * a jumper + * When this Policy is set, the node will ignore tboot and + * wait indefinitely for a GetNodeInfo request before booting. + * + * OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT is used to allow + * the polarity of the jumper to be True Active + * + * wait OPT_WAIT_FOR_GETNODEINFO OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO + * Jumper + * yes 1 0 x + * yes 1 1 Active + * no 1 1 Not Active + * no 0 0 X + * yes 0 1 Active + * no 0 1 Not Active + * + */ +#define OPT_WAIT_FOR_GETNODEINFO 0 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1 + +#define OPT_ENABLE_WD 1 + +#define OPT_RESTART_TIMEOUT_MS 20000 + +/* Reserved for the Booloader */ +#define OPT_BOOTLOADER_SIZE_IN_K (1024*64) + +/* Reserved for the application out of the total + * system flash minus the BOOTLOADER_SIZE_IN_K + */ +#define OPT_APPLICATION_RESERVER_IN_K 0 + +#define OPT_APPLICATION_IMAGE_OFFSET OPT_BOOTLOADER_SIZE_IN_K +#define OPT_APPLICATION_IMAGE_LENGTH (FLASH_SIZE-(OPT_BOOTLOADER_SIZE_IN_K+OPT_APPLICATION_RESERVER_IN_K)) + + +#define FLASH_BASE STM32_FLASH_BASE +#define FLASH_SIZE STM32_FLASH_SIZE + +#define APPLICATION_LOAD_ADDRESS (FLASH_BASE + OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_SIZE (FLASH_SIZE-OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_LAST_8BIT_ADDRRESS ((uint8_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint8_t))) +#define APPLICATION_LAST_32BIT_ADDRRESS ((uint32_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint32_t))) +#define APPLICATION_LAST_64BIT_ADDRRESS ((uint64_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint64_t))) + +/* If this board uses big flash that have large sectors */ + +#define OPT_USE_YIELD + +/* Bootloader Option***************************************************************** + * + */ +#define GPIO_GETNODEINFO_JUMPER (GPIO_BOOT_CONFIG & ~GPIO_EXTI) diff --git a/boards/ark/mag/src/can.c b/boards/ark/mag/src/can.c new file mode 100644 index 0000000000..7737965dc6 --- /dev/null +++ b/boards/ark/mag/src/can.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file can.c + * + * Board-specific CAN functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "stm32.h" +#include "stm32_can.h" +#include "board_config.h" + +#ifdef CONFIG_CAN + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} + +#endif diff --git a/boards/ark/mag/src/init.c b/boards/ark/mag/src/init.c new file mode 100644 index 0000000000..a6290bdc7a --- /dev/null +++ b/boards/ark/mag/src/init.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * board specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "board_config.h" +#include "led.h" +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +# if defined(FLASH_BASED_PARAMS) +# include +#endif + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + watchdog_init(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + // Configure SPI all interfaces GPIO & enable power. + stm32_spiinitialize(); +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + px4_platform_init(); + +#if defined(FLASH_BASED_PARAMS) + static sector_descriptor_t params_sector_map[] = { + {2, 16 * 1024, 0x08008000}, + {3, 16 * 1024, 0x0800C000}, + {0, 0, 0}, + }; + + /* Initialize the flashfs layer to use heap allocated memory */ + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + } + +#endif // FLASH_BASED_PARAMS + + /* Configure the HW based on the manifest */ + //px4_platform_configure(); + + return OK; +} diff --git a/boards/ark/mag/src/led.c b/boards/ark/mag/src/led.c new file mode 100644 index 0000000000..24c3c42bf4 --- /dev/null +++ b/boards/ark/mag/src/led.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +#include "led.h" + +#define TMR_BASE STM32_TIM1_BASE +#define TMR_FREQUENCY STM32_APB2_TIM1_CLKIN +#define TMR_REG(o) (TMR_BASE+(o)) + +void rgb_led(int r, int g, int b, int freqs) +{ + + long fosc = TMR_FREQUENCY; + long prescale = 2048; + long p1s = fosc / prescale; + long p0p5s = p1s / 2; + uint16_t val; + static bool once = 0; + + if (!once) { + once = 1; + + /* Enable Clock to Block */ + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + + /* Reload */ + + val = getreg16(TMR_REG(STM32_BTIM_EGR_OFFSET)); + val |= ATIM_EGR_UG; + putreg16(val, TMR_REG(STM32_BTIM_EGR_OFFSET)); + + /* Set Prescaler STM32_TIM_SETCLOCK */ + + putreg16(prescale, TMR_REG(STM32_BTIM_PSC_OFFSET)); + + /* Enable STM32_TIM_SETMODE*/ + + putreg16(ATIM_CR1_CEN | ATIM_CR1_ARPE, TMR_REG(STM32_BTIM_CR1_OFFSET)); + + + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) | ATIM_CCMR1_OC1PE | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) | ATIM_CCMR1_OC2PE, TMR_REG(STM32_GTIM_CCMR1_OFFSET)); + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) | ATIM_CCMR2_OC3PE, TMR_REG(STM32_GTIM_CCMR2_OFFSET)); + putreg16(ATIM_CCER_CC3E | ATIM_CCER_CC3P | + ATIM_CCER_CC2E | ATIM_CCER_CC2P | + ATIM_CCER_CC1E | ATIM_CCER_CC1P, TMR_REG(STM32_GTIM_CCER_OFFSET)); + + + stm32_configgpio(GPIO_TIM1_CH1); + stm32_configgpio(GPIO_TIM1_CH2); + stm32_configgpio(GPIO_TIM1_CH3); + + /* master output enable = on */ + putreg16(ATIM_BDTR_MOE, (TMR_REG(STM32_ATIM_BDTR_OFFSET))); + } + + long p = freqs == 0 ? p1s : p1s / freqs; + putreg32(p, TMR_REG(STM32_BTIM_ARR_OFFSET)); + + p = freqs == 0 ? p1s + 1 : p0p5s / freqs; + + putreg32((r * p) / 255, TMR_REG(STM32_GTIM_CCR1_OFFSET)); + putreg32((g * p) / 255, TMR_REG(STM32_GTIM_CCR2_OFFSET)); + putreg32((b * p) / 255, TMR_REG(STM32_GTIM_CCR3_OFFSET)); + + val = getreg16(TMR_REG(STM32_BTIM_CR1_OFFSET)); + + if (freqs == 0) { + val &= ~ATIM_CR1_CEN; + + } else { + val |= ATIM_CR1_CEN; + } + + putreg16(val, TMR_REG(STM32_BTIM_CR1_OFFSET)); + +} diff --git a/boards/ark/mag/src/led.h b/boards/ark/mag/src/led.h new file mode 100644 index 0000000000..b68e4aa70d --- /dev/null +++ b/boards/ark/mag/src/led.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * + * Copyright (C) 2015 PX4 Development Team. All rights reserved. + * Author: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +__BEGIN_DECLS +void rgb_led(int r, int g, int b, int freqs); +__END_DECLS diff --git a/boards/ark/mag/src/spi.cpp b/boards/ark/mag/src/spi.cpp new file mode 100644 index 0000000000..b32d42b514 --- /dev/null +++ b/boards/ark/mag/src/spi.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(DRV_MAG_DEVTYPE_RM3100, SPI::CS{GPIO::PortB, GPIO::Pin12}, SPI::DRDY{GPIO::PortB, GPIO::Pin4}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/ark/mag/uavcan_board_identity b/boards/ark/mag/uavcan_board_identity new file mode 100644 index 0000000000..1e30c3d822 --- /dev/null +++ b/boards/ark/mag/uavcan_board_identity @@ -0,0 +1,17 @@ +# UAVCAN boot loadable Module ID +set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR}) +set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR}) +add_definitions( + -DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major} + -DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor} +) + +set(uavcanblid_hw_version_major 0) +set(uavcanblid_hw_version_minor 93) +set(uavcanblid_name "\"org.ark.mag\"") + +add_definitions( + -DHW_UAVCAN_NAME=${uavcanblid_name} + -DHW_VERSION_MAJOR=${uavcanblid_hw_version_major} + -DHW_VERSION_MINOR=${uavcanblid_hw_version_minor} +) diff --git a/boards/ark/pi6x/default.px4board b/boards/ark/pi6x/default.px4board index 84c6fd79f2..6ad26366b3 100644 --- a/boards/ark/pi6x/default.px4board +++ b/boards/ark/pi6x/default.px4board @@ -19,6 +19,7 @@ CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_MAGNETOMETER_MEMSIC_MMC5983MA=y CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y CONFIG_DRIVERS_OPTICAL_FLOW_PAW3902=y +CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y @@ -41,7 +42,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 diff --git a/boards/ark/pi6x/init/rc.board_airframes b/boards/ark/pi6x/init/rc.board_airframes new file mode 100644 index 0000000000..4468c66ee4 --- /dev/null +++ b/boards/ark/pi6x/init/rc.board_airframes @@ -0,0 +1,2 @@ +4001_quad_x +4601_droneblocks_dexi_5 diff --git a/boards/ark/pi6x/init/rc.board_defaults b/boards/ark/pi6x/init/rc.board_defaults index 1b92949d1d..9ddf3f88c4 100644 --- a/boards/ark/pi6x/init/rc.board_defaults +++ b/boards/ark/pi6x/init/rc.board_defaults @@ -26,6 +26,8 @@ param set-default SENS_IMU_TEMP 10.0 #param set-default SENS_IMU_TEMP_I 0.025 #param set-default SENS_IMU_TEMP_P 1.0 +param set-default UAVCAN_ESC_IFACE 1 + if ver hwtypecmp ARKPI6X000 then # TODO: Add the correct sensor ID diff --git a/boards/ark/pi6x/init/rc.board_sensors b/boards/ark/pi6x/init/rc.board_sensors index cc97b1d601..c128fbca35 100644 --- a/boards/ark/pi6x/init/rc.board_sensors +++ b/boards/ark/pi6x/init/rc.board_sensors @@ -34,3 +34,9 @@ paw3902 -s -b 3 start -Y 90 # Internal distance sensor afbrs50 start + +# Start an external PWM generator +if param greater PCA9685_EN_BUS 0 +then + pca9685_pwm_out start +fi diff --git a/boards/ark/pi6x/rover.px4board b/boards/ark/pi6x/rover.px4board new file mode 100644 index 0000000000..cd49a241b5 --- /dev/null +++ b/boards/ark/pi6x/rover.px4board @@ -0,0 +1,17 @@ +CONFIG_MODULES_AIRSPEED_SELECTOR=n +CONFIG_MODULES_FLIGHT_MODE_MANAGER=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_MC_ATT_CONTROL=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n +CONFIG_MODULES_MC_POS_CONTROL=n +CONFIG_MODULES_MC_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_DRIVERS_ROBOCLAW=y +CONFIG_MODULES_ROVER_ACKERMANN=y +CONFIG_MODULES_ROVER_DIFFERENTIAL=y +CONFIG_MODULES_ROVER_MECANUM=y diff --git a/boards/ark/x20-gps/canbootloader.px4board b/boards/ark/x20-gps/canbootloader.px4board new file mode 100644 index 0000000000..46917280f6 --- /dev/null +++ b/boards/ark/x20-gps/canbootloader.px4board @@ -0,0 +1,5 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BOOTLOADERS=y diff --git a/boards/ark/x20-gps/default.px4board b/boards/ark/x20-gps/default.px4board new file mode 100644 index 0000000000..6c79012be7 --- /dev/null +++ b/boards/ark/x20-gps/default.px4board @@ -0,0 +1,37 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m4" +CONFIG_BOARD_ROMFSROOT="cannode" +CONFIG_BOARD_CONSTRAINED_MEMORY=y +CONFIG_DRIVERS_BAROMETER_BMP388=y +CONFIG_DRIVERS_BOOTLOADERS=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y +CONFIG_DRIVERS_SAFETY_BUTTON=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_BOARD_UAVCAN_INTERFACES=1 +CONFIG_DRIVERS_UAVCANNODE=y +CONFIG_UAVCANNODE_BEEP_COMMAND=y +CONFIG_UAVCANNODE_GNSS_FIX=y +CONFIG_UAVCANNODE_LIGHTS_COMMAND=y +CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y +CONFIG_UAVCANNODE_RTK_DATA=y +CONFIG_UAVCANNODE_RAW_IMU=y +CONFIG_UAVCANNODE_SAFETY_BUTTON=y +CONFIG_UAVCANNODE_STATIC_PRESSURE=y +CONFIG_UAVCANNODE_STATIC_TEMPERATURE=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_SENSORS=y +# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set +# CONFIG_SENSORS_VEHICLE_AIR_DATA is not set +# CONFIG_SENSORS_VEHICLE_GPS_POSITION is not set +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/ark/x20-gps/firmware.prototype b/boards/ark/x20-gps/firmware.prototype new file mode 100644 index 0000000000..d63aa2d618 --- /dev/null +++ b/boards/ark/x20-gps/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 89, + "magic": "PX4FWv1", + "description": "Firmware for the ARK X20 GPS", + "image": "", + "build_time": 0, + "summary": "ARKX20GPS", + "version": "0.1", + "image_size": 0, + "image_maxsize": 2080768, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/ark/x20-gps/init/rc.board_defaults b/boards/ark/x20-gps/init/rc.board_defaults new file mode 100644 index 0000000000..63f479fe53 --- /dev/null +++ b/boards/ark/x20-gps/init/rc.board_defaults @@ -0,0 +1,13 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +param set-default CBRK_IO_SAFETY 0 +param set-default CANNODE_SUB_MBD 1 +param set-default CANNODE_SUB_RTCM 1 +param set-default GPS_1_GNSS 47 +param set-default SENS_IMU_CLPNOTI 0 + +safety_button start +tone_alarm start diff --git a/boards/ark/x20-gps/init/rc.board_sensors b/boards/ark/x20-gps/init/rc.board_sensors new file mode 100644 index 0000000000..25bb268272 --- /dev/null +++ b/boards/ark/x20-gps/init/rc.board_sensors @@ -0,0 +1,11 @@ +#!/bin/sh +# +# board sensors init +#------------------------------------------------------------------------------ +gps start -d /dev/ttyS0 -p ubx + +icm42688p -R 0 -s start + +bmp388 -I -b 1 start + +iis2mdc -R 2 -I -b 1 start diff --git a/boards/ark/x20-gps/nuttx-config/canbootloader/defconfig b/boards/ark/x20-gps/nuttx-config/canbootloader/defconfig new file mode 100644 index 0000000000..d50bae4a9b --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/canbootloader/defconfig @@ -0,0 +1,57 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/x20-gps/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARDCTL=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_STACKSIZE=4096 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=0 +CONFIG_NUNGET_CHARS=0 +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_NOEXT_VECTORS=y +CONFIG_STM32_TIM8=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/x20-gps/nuttx-config/include/board.h b/boards/ark/x20-gps/nuttx-config/include/board.h new file mode 100644 index 0000000000..526392b92b --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/include/board.h @@ -0,0 +1,152 @@ +/************************************************************************************ + * configs/px4fmu/include/board.h + * include/arch/board/board.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#include "board_dma_map.h" + +#ifndef __ARCH_BOARD_BOARD_H +#define __ARCH_BOARD_BOARD_H + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include + +/* HSI - 8 MHz RC factory-trimmed + * LSI - 32 KHz RC + * HSE - 8 MHz Crystal + * LSE - not installed + */ +#define STM32_BOARD_USEHSE 1 +#define STM32_BOARD_XTAL 8000000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 + +/* Main PLL Configuration */ +#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(8) +#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(384) +#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_4 +#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(8) +#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(2) + +#define STM32_RCC_PLLI2SCFGR_PLLI2SM RCC_PLLI2SCFGR_PLLI2SM(16) +#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) +#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SR RCC_PLLI2SCFGR_PLLI2SR(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SSRC RCC_PLLI2SCFGR_PLLI2SSRC(0) /* HSE or HSI depending on PLLSRC of PLLCFGR*/ + +#define STM32_RCC_DCKCFGR2_CK48MSEL RCC_DCKCFGR2_CK48MSEL_PLL +#define STM32_RCC_DCKCFGR2_FMPI2C1SEL RCC_DCKCFGR2_FMPI2C1SEL_APB +#define STM32_RCC_DCKCFGR2_SDIOSEL RCC_DCKCFGR2_SDIOSEL_48MHZ + +#define STM32_SYSCLK_FREQUENCY 96000000ul + +/* AHB clock (HCLK) is SYSCLK (96MHz) */ +#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ +#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (48MHz) */ +#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timers driven from APB1 will be twice PCLK1 (see page 112 of reference manual) */ +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* APB2 clock (PCLK2) is HCLK (96MHz) */ +#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY) + +/* Timers driven from APB2 will be PCLK2 since no prescale division */ +#define STM32_APB2_TIM1_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM9_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM10_CLKIN (STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM11_CLKIN (STM32_PCLK2_FREQUENCY) + +/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx otherwise frequency is 2xAPBx. */ +#define BOARD_TIM2_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM3_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM4_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM5_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM6_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM7_FREQUENCY (2 * STM32_PCLK1_FREQUENCY) +#define BOARD_TIM8_FREQUENCY (2 * STM32_PCLK2_FREQUENCY) + +/* Alternate function pin selections ************************************************/ + +/* UARTs */ +#define GPIO_USART1_RX GPIO_USART1_RX_2 +#define GPIO_USART1_TX GPIO_USART1_TX_3 + +#define GPIO_USART2_RX GPIO_USART2_RX_1 +#define GPIO_USART2_TX GPIO_USART2_TX_1 + +/* CAN */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_1 +#define GPIO_CAN1_TX GPIO_CAN1_TX_1 + +/* I2C */ + +#define GPIO_MCU_I2C1_SCL +#define GPIO_MCU_I2C1_SDA + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1 +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_4 + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN9) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN10) + +/* SPI */ +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 + +#endif /* __ARCH_BOARD_BOARD_H */ diff --git a/boards/ark/x20-gps/nuttx-config/include/board_dma_map.h b/boards/ark/x20-gps/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..efa3d824b2 --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/include/board_dma_map.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMA1 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- + + +// DMA2 Channel/Stream Selections +//--------------------------------------------//---------------------------//---------------- +#define DMACHAN_SPI1_RX DMAMAP_SPI1_RX_1 // DMA2, Stream 0, Channel 3 +#define DMACHAN_SPI1_TX DMAMAP_SPI1_TX_1 // DMA2, Stream 3, Channel 3 +#define DMACHAN_USART1_RX DMAMAP_USART1_RX_1 // DMA2, Stream 2, Channel 4 +#define DMAMAP_USART1_RX DMAMAP_USART1_RX_1 +//#define DMACHAN_USART1_TX DMAMAP_USART1_TX // DMA2, Stream 7, Channel 4 diff --git a/boards/ark/x20-gps/nuttx-config/nsh/defconfig b/boards/ark/x20-gps/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..d7550e73bf --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/nsh/defconfig @@ -0,0 +1,153 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/ark/x20-gps/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F412CE=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_CROMFS=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=2624 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=2 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_VARS=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32_ADC1=y +CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y +CONFIG_STM32_DMA1=y +CONFIG_STM32_DMA2=y +CONFIG_STM32_FLASH_CONFIG_G=y +CONFIG_STM32_FLASH_PREFETCH=y +CONFIG_STM32_FLOWCONTROL_BROKEN=y +CONFIG_STM32_I2C1=y +CONFIG_STM32_I2C2=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWR=y +CONFIG_STM32_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32_SPI1=y +CONFIG_STM32_SPI1_DMA=y +CONFIG_STM32_SPI1_DMA_BUFFER=1024 +CONFIG_STM32_TIM8=y +CONFIG_STM32_USART1=y +CONFIG_STM32_USART2=y +CONFIG_STM32_USART_BREAKS=y +CONFIG_STM32_WWDG=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=2000 +CONFIG_USART1_RXDMA=y +CONFIG_USART1_TXBUFSIZE=2000 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USART2_TXBUFSIZE=1100 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/ark/x20-gps/nuttx-config/scripts/canbootloader_script.ld b/boards/ark/x20-gps/nuttx-config/scripts/canbootloader_script.ld new file mode 100644 index 0000000000..6be5cffcd8 --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/scripts/canbootloader_script.ld @@ -0,0 +1,134 @@ +/**************************************************************************** + * nuttx-config/scripts/canbootloader_script.ld + * + * Copyright (c) 2025 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/x20-gps/nuttx-config/scripts/script.ld b/boards/ark/x20-gps/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..2f4769b8f5 --- /dev/null +++ b/boards/ark/x20-gps/nuttx-config/scripts/script.ld @@ -0,0 +1,146 @@ +/**************************************************************************** + * scripts/ld.script + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F412 has 1M of FLASH beginning at address 0x0800:0000 and + * 256Kb of SRAM. SRAM is split up into three blocks: + * + * 1) 112Kb of SRAM beginning at address 0x2000:0000 + * 2) 16Kb of SRAM beginning at address 0x2001:c000 + * 3) 64Kb of SRAM beginning at address 0x2002:0000 + * 4) 64Kb of TCM SRAM beginning at address 0x1000:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The first 0x10000 of flash is reserved for the bootloader. + */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x08010000, LENGTH = 928K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +OUTPUT_ARCH(arm) + +ENTRY(__start) /* treat __start as the anchor for dead code stripping */ +EXTERN(_vectors) /* force the vectors to be included in the output */ + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(8); + /* + * This section positions the app_descriptor_t used + * by the make_can_boot_descriptor.py tool to set + * the application image's descriptor so that the + * uavcan bootloader has the ability to validate the + * image crc, size etc + */ + KEEP(*(.app_descriptor)) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/ark/x20-gps/src/CMakeLists.txt b/boards/ark/x20-gps/src/CMakeLists.txt new file mode 100644 index 0000000000..7f8a23a27e --- /dev/null +++ b/boards/ark/x20-gps/src/CMakeLists.txt @@ -0,0 +1,66 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +if("${PX4_BOARD_LABEL}" STREQUAL "canbootloader") + + add_library(drivers_board + boot_config.h + boot.c + led.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + canbootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/canbootloader) + +else() + add_library(drivers_board + can.c + i2c.cpp + init.c + led.c + spi.cpp + ) + + target_link_libraries(drivers_board + PRIVATE + arch_spi + drivers__led # drv_led_start + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/ark/x20-gps/src/board_config.h b/boards/ark/x20-gps/src/board_config.h new file mode 100644 index 0000000000..2d5f582075 --- /dev/null +++ b/boards/ark/x20-gps/src/board_config.h @@ -0,0 +1,125 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * board internal definitions + */ + +#pragma once + +#include +#include +#include + +/* BUTTON */ +#define GPIO_BTN_SAFETY /* PB15 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTB|GPIO_PIN15) + +/* Safety LED */ +#define GPIO_LED_SAFETY /* PA1 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN1) + +/* Tone alarm output. */ +#define TONE_ALARM_TIMER 2 /* timer 2 */ +#define TONE_ALARM_CHANNEL 1 /* channel 1 */ +#define GPIO_TONE_ALARM_IDLE /* PA0 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN0) +#define GPIO_TONE_ALARM /* PA0 */ (GPIO_ALT|GPIO_AF1|GPIO_SPEED_2MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0) + +/* CAN Silent mode control */ +#define GPIO_CAN1_SILENT_S0 /* PB12 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN12) + +/* CAN termination software control */ +#define GPIO_CAN1_TERMINATION /* PB13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN13) +#define GPIO_CAN_TERM GPIO_CAN1_TERMINATION + +/* ICM42688p FSYNC */ +#define GPIO_42688P_FSYNC /* PB8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN8) + +/* Boot config */ +#define GPIO_BOOT_CONFIG /* PC15 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN15|GPIO_EXTI) + +/* LEDs are driven with open drain to support Anode to 5V or 3.3V */ +#define GPIO_TIM1_CH1 /* PA8 */ (GPIO_TIM1_CH1_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH2 /* PA9 */ (GPIO_TIM1_CH2_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) +#define GPIO_TIM1_CH3 /* PA10 */ (GPIO_TIM1_CH3_1|GPIO_OPENDRAIN|GPIO_SPEED_2MHz) + +#define GPIO_I2C1_SCL_RESET /* PB6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SDA_RESET /* PB7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN7) + +#define GPIO_I2C2_SCL_RESET /* PB10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA_RESET /* PB9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9) + +#define GPIO_I2C2_SCL_RESET /* PB10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SDA_RESET /* PB9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9) + +#define GPIO_USART1_RX_GPIO (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3) +#define GPIO_USART1_TX_GPIO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) + +#define GPIO_USART2_RX_GPIO (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN3) +#define GPIO_USART2_TX_GPIO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN2) + +#define FLASH_BASED_PARAMS + +/* High-resolution timer */ +#define HRT_TIMER 3 /* use timer 3 for the HRT */ +#define HRT_TIMER_CHANNEL 4 /* use capture/compare channel 4 */ + +#define PX4_GPIO_INIT_LIST { \ + GPIO_BTN_SAFETY, \ + GPIO_LED_SAFETY, \ + GPIO_I2C1_SCL_RESET, \ + GPIO_I2C1_SDA_RESET, \ + GPIO_I2C2_SCL_RESET, \ + GPIO_I2C2_SDA_RESET, \ + GPIO_42688P_FSYNC, \ + GPIO_BOOT_CONFIG, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN1_SILENT_S0, \ + GPIO_CAN1_TERMINATION, \ + } + +__BEGIN_DECLS + +#define BOARD_HAS_N_S_RGB_LED 1 +#define BOARD_MAX_LEDS BOARD_HAS_N_S_RGB_LED + +#ifndef __ASSEMBLY__ + +extern void stm32_spiinitialize(void); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/ark/x20-gps/src/boot.c b/boards/ark/x20-gps/src/boot.c new file mode 100644 index 0000000000..3efdba508c --- /dev/null +++ b/boards/ark/x20-gps/src/boot.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * Author: Ben Dyer + * Pavel Kirienko + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "boot_config.h" +#include "board.h" + +#include +#include +#include + +#include +#include "led.h" + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1ENR) | RCC_APB1ENR_CAN1EN, STM32_RCC_APB1ENR); + stm32_configgpio(GPIO_CAN1_RX); + stm32_configgpio(GPIO_CAN1_TX); + stm32_configgpio(GPIO_CAN1_SILENT_S0); + stm32_configgpio(GPIO_CAN1_TERMINATION); + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + putreg32(getreg32(STM32_RCC_APB1RSTR) & ~RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); + +#if defined(OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO) + stm32_configgpio(GPIO_GETNODEINFO_JUMPER); +#endif + +} + +/************************************************************************************ + * Name: board_deinitialize + * + * Description: + * This function is called by the bootloader code prior to booting + * the application. Is should place the HW into an benign initialized state. + * + ************************************************************************************/ + +void board_deinitialize(void) +{ + putreg32(getreg32(STM32_RCC_APB1RSTR) | RCC_APB1RSTR_CAN1RST, STM32_RCC_APB1RSTR); +} + +/**************************************************************************** + * Name: board_get_product_name + * + * Description: + * Called to retrieve the product name. The returned value is a assumed + * to be written to a pascal style string that will be length prefixed + * and not null terminated + * + * Input Parameters: + * product_name - A pointer to a buffer to write the name. + * maxlen - The maximum number of charter that can be written + * + * Returned Value: + * The length of characters written to the buffer. + * + ****************************************************************************/ + +uint8_t board_get_product_name(uint8_t *product_name, size_t maxlen) +{ + DEBUGASSERT(maxlen > UAVCAN_STRLEN(HW_UAVCAN_NAME)); + memcpy(product_name, HW_UAVCAN_NAME, UAVCAN_STRLEN(HW_UAVCAN_NAME)); + return UAVCAN_STRLEN(HW_UAVCAN_NAME); +} + +/**************************************************************************** + * Name: board_get_hardware_version + * + * Description: + * Called to retrieve the hardware version information. The function + * will first initialize the the callers struct to all zeros. + * + * Input Parameters: + * hw_version - A pointer to a uavcan_hardwareversion_t. + * + * Returned Value: + * Length of the unique_id + * + ****************************************************************************/ + +size_t board_get_hardware_version(uavcan_HardwareVersion_t *hw_version) +{ + memset(hw_version, 0, sizeof(uavcan_HardwareVersion_t)); + + hw_version->major = HW_VERSION_MAJOR; + hw_version->minor = HW_VERSION_MINOR; + + return board_get_mfguid(*(mfguid_t *) hw_version->unique_id); +} + +/**************************************************************************** + * Name: board_indicate + * + * Description: + * Provides User feedback to indicate the state of the bootloader + * on board specific hardware. + * + * Input Parameters: + * indication - A member of the uiindication_t + * + * Returned Value: + * None + * + ****************************************************************************/ +#define led(n, code, r , g , b, h) {.red = (r),.green = (g), .blue = (b),.hz = (h)} + +typedef begin_packed_struct struct led_t { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t hz; +} end_packed_struct led_t; + +static const led_t i2l[] = { + + led(0, off, 0, 0, 0, 0), + led(1, reset, 128, 128, 128, 30), + led(2, autobaud_start, 0, 128, 0, 1), + led(3, autobaud_end, 0, 128, 0, 2), + led(4, allocation_start, 0, 0, 64, 2), + led(5, allocation_end, 0, 128, 64, 3), + led(6, fw_update_start, 32, 128, 64, 3), + led(7, fw_update_erase_fail, 32, 128, 32, 3), + led(8, fw_update_invalid_response, 64, 0, 0, 1), + led(9, fw_update_timeout, 64, 0, 0, 2), + led(a, fw_update_invalid_crc, 64, 0, 0, 4), + led(b, jump_to_app, 0, 128, 0, 10), + +}; + +void board_indicate(uiindication_t indication) +{ + rgb_led(i2l[indication].red, + i2l[indication].green, + i2l[indication].blue, + i2l[indication].hz); +} diff --git a/boards/ark/x20-gps/src/boot_config.h b/boards/ark/x20-gps/src/boot_config.h new file mode 100644 index 0000000000..7da61bb2bb --- /dev/null +++ b/boards/ark/x20-gps/src/boot_config.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* + * @file boot_config.h + * + * bootloader definitions that configures the behavior and options + * of the Boot loader + * This file is relies on the parent folder's boot_config.h file and defines + * different usages of the hardware for bootloading + */ + +#pragma once + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/* Bring in the board_config.h definitions + * todo:make this be pulled in from a targed's build + * files in nuttx*/ + +#include "board_config.h" +#include "uavcan.h" +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OPT_PREFERRED_NODE_ID ANY_NODE_ID + +//todo:wrap OPT_x in in ifdefs for command line definitions +#define OPT_TBOOT_MS 3000 +#define OPT_NODE_STATUS_RATE_MS 800 +#define OPT_NODE_INFO_RATE_MS 50 +#define OPT_BL_NUMBER_TIMERS 7 + +/* + * This Option set is set to 1 ensure a provider of firmware has an + * opportunity update the node's firmware. + * This Option is the default policy and can be overridden by + * a jumper + * When this Policy is set, the node will ignore tboot and + * wait indefinitely for a GetNodeInfo request before booting. + * + * OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT is used to allow + * the polarity of the jumper to be True Active + * + * wait OPT_WAIT_FOR_GETNODEINFO OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO + * Jumper + * yes 1 0 x + * yes 1 1 Active + * no 1 1 Not Active + * no 0 0 X + * yes 0 1 Active + * no 0 1 Not Active + * + */ +#define OPT_WAIT_FOR_GETNODEINFO 0 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1 +#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1 + +#define OPT_ENABLE_WD 1 + +#define OPT_RESTART_TIMEOUT_MS 20000 + +/* Reserved for the Booloader */ +#define OPT_BOOTLOADER_SIZE_IN_K (1024*64) + +/* Reserved for the application out of the total + * system flash minus the BOOTLOADER_SIZE_IN_K + */ +#define OPT_APPLICATION_RESERVER_IN_K 0 + +#define OPT_APPLICATION_IMAGE_OFFSET OPT_BOOTLOADER_SIZE_IN_K +#define OPT_APPLICATION_IMAGE_LENGTH (FLASH_SIZE-(OPT_BOOTLOADER_SIZE_IN_K+OPT_APPLICATION_RESERVER_IN_K)) + + +#define FLASH_BASE STM32_FLASH_BASE +#define FLASH_SIZE STM32_FLASH_SIZE + +#define APPLICATION_LOAD_ADDRESS (FLASH_BASE + OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_SIZE (FLASH_SIZE-OPT_APPLICATION_IMAGE_OFFSET) +#define APPLICATION_LAST_8BIT_ADDRRESS ((uint8_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint8_t))) +#define APPLICATION_LAST_32BIT_ADDRRESS ((uint32_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint32_t))) +#define APPLICATION_LAST_64BIT_ADDRRESS ((uint64_t *)((APPLICATION_LOAD_ADDRESS+APPLICATION_SIZE)-sizeof(uint64_t))) + +/* If this board uses big flash that have large sectors */ + +#define OPT_USE_YIELD + +/* Bootloader Option***************************************************************** + * + */ +#define GPIO_GETNODEINFO_JUMPER (GPIO_BOOT_CONFIG & ~GPIO_EXTI) diff --git a/boards/ark/x20-gps/src/can.c b/boards/ark/x20-gps/src/can.c new file mode 100644 index 0000000000..bb1a7025e8 --- /dev/null +++ b/boards/ark/x20-gps/src/can.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file can.c + * + * Board-specific CAN functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "stm32.h" +#include "stm32_can.h" +#include "board_config.h" + +#ifdef CONFIG_CAN + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} + +#endif diff --git a/boards/ark/x20-gps/src/i2c.cpp b/boards/ark/x20-gps/src/i2c.cpp new file mode 100644 index 0000000000..6700d8c8f2 --- /dev/null +++ b/boards/ark/x20-gps/src/i2c.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), + initI2CBusExternal(2), +}; diff --git a/boards/ark/x20-gps/src/init.c b/boards/ark/x20-gps/src/init.c new file mode 100644 index 0000000000..c036e72f56 --- /dev/null +++ b/boards/ark/x20-gps/src/init.c @@ -0,0 +1,168 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * board specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "board_config.h" +#include "led.h" +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +# if defined(FLASH_BASED_PARAMS) +# include +#endif + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void stm32_boardinitialize(void) +{ + watchdog_init(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + // Configure SPI all interfaces GPIO & enable power. + stm32_spiinitialize(); + + // Check if button is held. If so go into gps passthrough mode + if (stm32_gpioread(GPIO_BTN_SAFETY)) { + rgb_led(128, 128, 128, 10); + stm32_configgpio(GPIO_USART1_TX_GPIO); + stm32_configgpio(GPIO_USART1_RX_GPIO); + stm32_configgpio(GPIO_USART2_TX_GPIO); + stm32_configgpio(GPIO_USART2_RX_GPIO); + + while (1) { + watchdog_pet(); + stm32_gpiowrite(GPIO_USART2_TX_GPIO, stm32_gpioread(GPIO_USART1_RX_GPIO)); + stm32_gpiowrite(GPIO_USART1_TX_GPIO, stm32_gpioread(GPIO_USART2_RX_GPIO)); + } + } +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + px4_platform_init(); + +#if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); +#endif + +#if defined(FLASH_BASED_PARAMS) + static sector_descriptor_t params_sector_map[] = { + {2, 16 * 1024, 0x08008000}, + {3, 16 * 1024, 0x0800C000}, + {0, 0, 0}, + }; + + /* Initialize the flashfs layer to use heap allocated memory */ + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + } + +#endif // FLASH_BASED_PARAMS + + /* Configure the HW based on the manifest */ + //px4_platform_configure(); + + return OK; +} diff --git a/boards/ark/x20-gps/src/led.c b/boards/ark/x20-gps/src/led.c new file mode 100644 index 0000000000..d2a2126d33 --- /dev/null +++ b/boards/ark/x20-gps/src/led.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +#include "led.h" + +#define TMR_BASE STM32_TIM1_BASE +#define TMR_FREQUENCY STM32_APB2_TIM1_CLKIN +#define TMR_REG(o) (TMR_BASE+(o)) + +void rgb_led(int r, int g, int b, int freqs) +{ + + long fosc = TMR_FREQUENCY; + long prescale = 2048; + long p1s = fosc / prescale; + long p0p5s = p1s / 2; + uint16_t val; + static bool once = 0; + + if (!once) { + once = 1; + + /* Enabel Clock to Block */ + modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); + + /* Reload */ + + val = getreg16(TMR_REG(STM32_BTIM_EGR_OFFSET)); + val |= ATIM_EGR_UG; + putreg16(val, TMR_REG(STM32_BTIM_EGR_OFFSET)); + + /* Set Prescaler STM32_TIM_SETCLOCK */ + + putreg16(prescale, TMR_REG(STM32_BTIM_PSC_OFFSET)); + + /* Enable STM32_TIM_SETMODE*/ + + putreg16(ATIM_CR1_CEN | ATIM_CR1_ARPE, TMR_REG(STM32_BTIM_CR1_OFFSET)); + + + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) | ATIM_CCMR1_OC1PE | + (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) | ATIM_CCMR1_OC2PE, TMR_REG(STM32_GTIM_CCMR1_OFFSET)); + putreg16((ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) | ATIM_CCMR2_OC3PE, TMR_REG(STM32_GTIM_CCMR2_OFFSET)); + putreg16(ATIM_CCER_CC3E | ATIM_CCER_CC3P | + ATIM_CCER_CC2E | ATIM_CCER_CC2P | + ATIM_CCER_CC1E | ATIM_CCER_CC1P, TMR_REG(STM32_GTIM_CCER_OFFSET)); + + + stm32_configgpio(GPIO_TIM1_CH1); + stm32_configgpio(GPIO_TIM1_CH2); + stm32_configgpio(GPIO_TIM1_CH3); + + /* master output enable = on */ + putreg16(ATIM_BDTR_MOE, (TMR_REG(STM32_ATIM_BDTR_OFFSET))); + } + + long p = freqs == 0 ? p1s : p1s / freqs; + putreg32(p, TMR_REG(STM32_BTIM_ARR_OFFSET)); + + p = freqs == 0 ? p1s + 1 : p0p5s / freqs; + + putreg32((r * p) / 255, TMR_REG(STM32_GTIM_CCR1_OFFSET)); + putreg32((g * p) / 255, TMR_REG(STM32_GTIM_CCR2_OFFSET)); + putreg32((b * p) / 255, TMR_REG(STM32_GTIM_CCR3_OFFSET)); + + val = getreg16(TMR_REG(STM32_BTIM_CR1_OFFSET)); + + if (freqs == 0) { + val &= ~ATIM_CR1_CEN; + + } else { + val |= ATIM_CR1_CEN; + } + + putreg16(val, TMR_REG(STM32_BTIM_CR1_OFFSET)); + +} diff --git a/boards/ark/x20-gps/src/led.h b/boards/ark/x20-gps/src/led.h new file mode 100644 index 0000000000..0d71157cc8 --- /dev/null +++ b/boards/ark/x20-gps/src/led.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * Author: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +__BEGIN_DECLS +void rgb_led(int r, int g, int b, int freqs); +__END_DECLS diff --git a/boards/ark/x20-gps/src/spi.cpp b/boards/ark/x20-gps/src/spi.cpp new file mode 100644 index 0000000000..baafb0354c --- /dev/null +++ b/boards/ark/x20-gps/src/spi.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortB, GPIO::Pin0}, SPI::DRDY{GPIO::PortB, GPIO::Pin1}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/ark/x20-gps/uavcan_board_identity b/boards/ark/x20-gps/uavcan_board_identity new file mode 100644 index 0000000000..c84cc61d2b --- /dev/null +++ b/boards/ark/x20-gps/uavcan_board_identity @@ -0,0 +1,17 @@ +# UAVCAN boot loadable Module ID +set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR}) +set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR}) +add_definitions( + -DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major} + -DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor} +) + +set(uavcanblid_hw_version_major 0) +set(uavcanblid_hw_version_minor 89) +set(uavcanblid_name "\"org.ark.x20-gps\"") + +add_definitions( + -DHW_UAVCAN_NAME=${uavcanblid_name} + -DHW_VERSION_MAJOR=${uavcanblid_hw_version_major} + -DHW_VERSION_MINOR=${uavcanblid_hw_version_minor} +) diff --git a/boards/auterion/fmu-v6s/default.px4board b/boards/auterion/fmu-v6s/default.px4board index 296f2db880..2a4cbbe8a4 100644 --- a/boards/auterion/fmu-v6s/default.px4board +++ b/boards/auterion/fmu-v6s/default.px4board @@ -14,6 +14,9 @@ CONFIG_COMMON_DISTANCE_SENSOR=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_GNSS_SEPTENTRIO=y CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_PPS_CAPTURE=y +CONFIG_DRIVERS_VTX=y +CONFIG_VTX_CRSF_MSP_SUPPORT=y CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_BMI088_ACCELEROMETER_INT2=y CONFIG_COMMON_LIGHT=y @@ -21,11 +24,11 @@ CONFIG_COMMON_MAGNETOMETER=y CONFIG_DATAMAN_PERSISTENT_STORAGE=n CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y +CONFIG_DRIVERS_AUTERION_AUTOSTARTER=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_UAVCAN=y CONFIG_BOARD_UAVCAN_INTERFACES=1 CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2 @@ -57,7 +60,6 @@ CONFIG_LOGGER_STACK_SIZE=4100 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 @@ -66,9 +68,6 @@ CONFIG_MODULES_MC_RATE_CONTROL=y CONFIG_MODULES_NAVIGATOR=y CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y CONFIG_MODULES_RC_UPDATE=y -CONFIG_MODULES_ROVER_ACKERMANN=y -CONFIG_MODULES_ROVER_DIFFERENTIAL=y -CONFIG_MODULES_ROVER_MECANUM=y CONFIG_MODULES_SENSORS=y CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y CONFIG_MODULES_TIME_PERSISTOR=y @@ -77,9 +76,7 @@ CONFIG_MODULES_VTOL_ATT_CONTROL=y CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y CONFIG_SYSTEMCMDS_BSONDUMP=y CONFIG_SYSTEMCMDS_DMESG=y -CONFIG_SYSTEMCMDS_GPIO=y CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y -CONFIG_SYSTEMCMDS_I2C_LAUNCHER=y CONFIG_SYSTEMCMDS_I2CDETECT=y CONFIG_SYSTEMCMDS_LED_CONTROL=y CONFIG_SYSTEMCMDS_MFT=y @@ -91,11 +88,10 @@ CONFIG_SYSTEMCMDS_PARAM=y CONFIG_SYSTEMCMDS_PERF=y CONFIG_SYSTEMCMDS_REBOOT=y CONFIG_SYSTEMCMDS_SD_BENCH=y -CONFIG_SYSTEMCMDS_SD_STRESS=y -CONFIG_SYSTEMCMDS_SERIAL_TEST=y CONFIG_SYSTEMCMDS_SYSTEM_TIME=y CONFIG_SYSTEMCMDS_TOP=y CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y CONFIG_SYSTEMCMDS_UORB=y CONFIG_SYSTEMCMDS_VER=y CONFIG_SYSTEMCMDS_WORK_QUEUE=y +CONFIG_WQ_TTY_STACKSIZE=2500 diff --git a/boards/auterion/fmu-v6s/extras/auterion_fmu-v6s_bootloader.bin b/boards/auterion/fmu-v6s/extras/auterion_fmu-v6s_bootloader.bin index ab4a99d348..233552b397 100755 Binary files a/boards/auterion/fmu-v6s/extras/auterion_fmu-v6s_bootloader.bin and b/boards/auterion/fmu-v6s/extras/auterion_fmu-v6s_bootloader.bin differ diff --git a/boards/auterion/fmu-v6s/init/rc.board_defaults b/boards/auterion/fmu-v6s/init/rc.board_defaults index 012605bee3..1efbfc3811 100644 --- a/boards/auterion/fmu-v6s/init/rc.board_defaults +++ b/boards/auterion/fmu-v6s/init/rc.board_defaults @@ -3,12 +3,6 @@ # board specific defaults #------------------------------------------------------------------------------ -# By disabling INA modules, we use the -# i2c_launcher instead. -param set-default SENS_EN_INA226 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA238 0 - # Set the backend of the dataman to SRAM param set-default SYS_DM_BACKEND 1 # Set TELEM1 as default mavlink connection @@ -19,6 +13,13 @@ param set-default SDLOG_BACKEND 2 # 200kOhm/10kOhm voltage divider on V_BAT param set-default BAT1_V_DIV 21 +# Uncomment to use PWM9 as Analog input +# param set-default PWM_MAIN_TIM2 -2 + +# Uncomment to use PWM10 as PPS input +# param set-default PWM_MAIN_TIM3 -2 +# param set-default PWM_MAIN_FUNC10 2064 + # Skynode: use the "custom participant", IP=10.41.10.1 config for uxrce_dds_client param set-default UXRCE_DDS_PTCFG 2 param set-default UXRCE_DDS_AG_IP 170461697 diff --git a/boards/auterion/fmu-v6s/init/rc.board_sensors b/boards/auterion/fmu-v6s/init/rc.board_sensors index 4c4be283d7..b533c9931a 100644 --- a/boards/auterion/fmu-v6s/init/rc.board_sensors +++ b/boards/auterion/fmu-v6s/init/rc.board_sensors @@ -60,6 +60,9 @@ then set INA_CONFIGURED yes fi +# Auterion auto starter +auterion_autostarter start + if param compare BAT1_V_CHANNEL -2 then if [ "$INA_CONFIGURED" != "yes" ] @@ -74,5 +77,5 @@ ist8310 -X -b 1 -R 10 start # Start an external PWM generator if param greater PCA9685_EN_BUS 0 then - pca9685_pwm_out start -b 1 + pca9685_pwm_out start fi diff --git a/boards/auterion/fmu-v6s/nuttx-config/nsh/defconfig b/boards/auterion/fmu-v6s/nuttx-config/nsh/defconfig index 8dacaf564c..0ab86df4dd 100644 --- a/boards/auterion/fmu-v6s/nuttx-config/nsh/defconfig +++ b/boards/auterion/fmu-v6s/nuttx-config/nsh/defconfig @@ -160,7 +160,7 @@ CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_CMDPARMS=y CONFIG_NSH_CROMFSETC=y CONFIG_NSH_LINELEN=128 -CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_MAXARGUMENTS=24 CONFIG_NSH_NESTDEPTH=8 CONFIG_NSH_QUOTE=y CONFIG_NSH_ROMFSETC=y @@ -226,8 +226,8 @@ CONFIG_STM32H7_PHY_POLLING=y CONFIG_STM32H7_PROGMEM=y CONFIG_STM32H7_RTC=y CONFIG_STM32H7_RTC_HSECLOCK=y -CONFIG_STM32H7_RTC_MAGIC_REG=1 CONFIG_STM32H7_RTC_MAGIC=0xA5A5A5A5 +CONFIG_STM32H7_RTC_MAGIC_REG=1 CONFIG_STM32H7_RTC_MAGIC_TIME_SET=0xA6A6A6A6 CONFIG_STM32H7_SAVE_CRASHDUMP=y CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y @@ -238,9 +238,12 @@ CONFIG_STM32H7_SPI3_DMA_BUFFER=1024 CONFIG_STM32H7_SPI4=y CONFIG_STM32H7_SPI4_DMA=y CONFIG_STM32H7_SPI4_DMA_BUFFER=4096 -CONFIG_STM32H7_TIM12=y CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM2=y CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM4=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_TIM8=y CONFIG_STM32H7_UART4=y CONFIG_STM32H7_UART5=y CONFIG_STM32H7_UART7=y diff --git a/boards/auterion/fmu-v6s/src/board_config.h b/boards/auterion/fmu-v6s/src/board_config.h index afad06894e..4e40de72eb 100644 --- a/boards/auterion/fmu-v6s/src/board_config.h +++ b/boards/auterion/fmu-v6s/src/board_config.h @@ -135,15 +135,14 @@ /* PWM Timers */ -#define BOARD_NUM_IO_TIMERS 2 -#define DIRECT_PWM_OUTPUT_CHANNELS 8 +/* 3 for PWM outputs, 1 for input capture */ +#define BOARD_NUM_IO_TIMERS 4 +/* 9 for PWM outputs, 1 for input capture */ +#define DIRECT_PWM_OUTPUT_CHANNELS 10 /* High-resolution timer */ -#define HRT_TIMER 8 /* use timer8 for the HRT */ -#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ - -#define HRT_PPM_CHANNEL /* T8C2 */ 2 /* use capture/compare channel 1 */ -#define GPIO_PPM_IN /* PC7 */ GPIO_TIM8_CH2IN_1 +#define HRT_TIMER 4 /* use timer4 for the HRT */ +#define HRT_TIMER_CHANNEL 1 /* use capture/compare channel 1 */ /* This board provides a DMA pool and APIs */ #define BOARD_DMA_ALLOC_POOL_SIZE 5120 @@ -171,6 +170,10 @@ /* Enable the buffer for the dmesg command */ #define BOARD_ENABLE_CONSOLE_BUFFER +/* No CDCACM driver for this board, so this is manually defined for version.c + * so that the px4_board_version reports the correct board id to the companion */ +#define CONFIG_CDCACM_PRODUCTID 60 + __BEGIN_DECLS /**************************************************************************************************** diff --git a/boards/auterion/fmu-v6s/src/timer_config.cpp b/boards/auterion/fmu-v6s/src/timer_config.cpp index 66311d38e2..a409137ef8 100644 --- a/boards/auterion/fmu-v6s/src/timer_config.cpp +++ b/boards/auterion/fmu-v6s/src/timer_config.cpp @@ -44,11 +44,17 @@ * TIM3_CH2 T FMU_CH6 * TIM3_CH3 T FMU_CH7 * TIM3_CH4 T FMU_CH8 + * + * TIM5_CH1 T FMU_CH9 + * + * TIM8_CH2 T FMU_CAP1 < Input Capture */ constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { initIOTimer(Timer::Timer1, DMA{DMA::Index1}), initIOTimer(Timer::Timer3, DMA{DMA::Index1}), + initIOTimer(Timer::Timer5), + initIOTimer(Timer::Timer8), }; constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { @@ -60,6 +66,8 @@ constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel2}, {GPIO::PortB, GPIO::Pin5}), initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortC, GPIO::Pin9}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel1}, {GPIO::PortA, GPIO::Pin0}), + initIOTimerChannelCapture(io_timers, {Timer::Timer8, Timer::Channel2}, {GPIO::PortC, GPIO::Pin7}), }; constexpr io_timers_channel_mapping_t io_timers_channel_mapping = diff --git a/boards/auterion/fmu-v6x/bootloader.px4board b/boards/auterion/fmu-v6x/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/auterion/fmu-v6x/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/auterion/fmu-v6x/cmake/upload.cmake b/boards/auterion/fmu-v6x/cmake/upload.cmake new file mode 100644 index 0000000000..7319b46df3 --- /dev/null +++ b/boards/auterion/fmu-v6x/cmake/upload.cmake @@ -0,0 +1,49 @@ +############################################################################ +# +# Copyright (c) 2023 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + + +set(PX4_FW_NAME ${PX4_BINARY_DIR}/${PX4_BOARD_VENDOR}_${PX4_BOARD_MODEL}_${PX4_BOARD_LABEL}.px4) + +add_custom_target(upload_skynode_usb + COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME} + DEPENDS ${PX4_FW_NAME} + COMMENT "Uploading PX4" + USES_TERMINAL +) + +add_custom_target(upload_skynode_wifi + COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME} --wifi + DEPENDS ${PX4_FW_NAME} + COMMENT "Uploading PX4" + USES_TERMINAL +) diff --git a/boards/auterion/fmu-v6x/default.px4board b/boards/auterion/fmu-v6x/default.px4board new file mode 100644 index 0000000000..1cef7804ab --- /dev/null +++ b/boards/auterion/fmu-v6x/default.px4board @@ -0,0 +1,103 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ETHERNET=y +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS7" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" +CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_DRIVERS_ADC_ADS1115=y +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_BMP388=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_AUAV=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_DRIVERS_GPIO_MCP23009=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_PPS_CAPTURE=y +CONFIG_DRIVERS_IMU_BOSCH_BMI088=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_COMMON_LIGHT=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_DRIVERS_AUTERION_AUTOSTARTER=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_INPUT=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_DRIVERS_RPM_CAPTURE=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_SAFETY_BUTTON=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2 +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_FIGURE_OF_EIGHT=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_HARDFAULT_STREAM=y +CONFIG_MODULES_INTERNAL_COMBUSTION_ENGINE_CONTROL=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y +CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000 +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_ROVER_MECANUM=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NETMAN=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/auterion/fmu-v6x/extras/auterion_fmu-v6x_bootloader.bin b/boards/auterion/fmu-v6x/extras/auterion_fmu-v6x_bootloader.bin new file mode 100755 index 0000000000..c619569917 Binary files /dev/null and b/boards/auterion/fmu-v6x/extras/auterion_fmu-v6x_bootloader.bin differ diff --git a/boards/auterion/fmu-v6x/extras/px4_io-v2_default.bin b/boards/auterion/fmu-v6x/extras/px4_io-v2_default.bin new file mode 100755 index 0000000000..145089ae0d Binary files /dev/null and b/boards/auterion/fmu-v6x/extras/px4_io-v2_default.bin differ diff --git a/boards/auterion/fmu-v6x/firmware.prototype b/boards/auterion/fmu-v6x/firmware.prototype new file mode 100644 index 0000000000..644953a9e1 --- /dev/null +++ b/boards/auterion/fmu-v6x/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 53, + "magic": "AutFWv1", + "description": "Firmware for the AutFMUv6X board", + "image": "", + "build_time": 0, + "summary": "AutFMUv6X", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1966080, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/auterion/fmu-v6x/flash-analysis.px4board b/boards/auterion/fmu-v6x/flash-analysis.px4board new file mode 100644 index 0000000000..30717ad93c --- /dev/null +++ b/boards/auterion/fmu-v6x/flash-analysis.px4board @@ -0,0 +1 @@ +CONFIG_BOARD_LINKER_PREFIX="flash-analysis" diff --git a/boards/auterion/fmu-v6x/init/rc.board_defaults b/boards/auterion/fmu-v6x/init/rc.board_defaults new file mode 100644 index 0000000000..f004d1dfd4 --- /dev/null +++ b/boards/auterion/fmu-v6x/init/rc.board_defaults @@ -0,0 +1,28 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +# Skynode: use the "custom participant", IP=10.41.10.1 config for uxrce_dds_client +param set-default UXRCE_DDS_PTCFG 2 +param set-default UXRCE_DDS_AG_IP 170461697 +param set-default UXRCE_DDS_CFG 1000 + +# The buzzer draws too much power (0.2A) on the GPS power rail (limit 0.45A). +param set-default CBRK_BUZZER 782097 + +# Update default IP config if needed +netman update_default -i eth0 + +safety_button start + +# GPIO Expander driver on external I2C3 +if ver hwbasecmp 009 010 011 +then + # No USB + mcp23009 start -b 3 -X -D 0xf0 -O 0xf0 -P 0x0f -M 0 -U 10 +fi +if ver hwbasecmp 00a 008 +then + mcp23009 start -b 3 -X -D 0xf1 -O 0xf0 -P 0x0f -M 0 -U 10 +fi diff --git a/boards/auterion/fmu-v6x/init/rc.board_mavlink b/boards/auterion/fmu-v6x/init/rc.board_mavlink new file mode 100644 index 0000000000..88cdd87c66 --- /dev/null +++ b/boards/auterion/fmu-v6x/init/rc.board_mavlink @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Auterion FMUv6X specific board MAVLink startup script. +#------------------------------------------------------------------------------ + +if param compare MAV_S_FORWARD 1 +then + set S_FORWARD "-f" +else + set S_FORWARD "" +fi + +mavlink start -d /dev/ttyS4 -b 3000000 -r 290000 -m p:MAV_S_MODE -x -z $S_FORWARD + +unset S_FORWARD + +# Ensure nothing else starts on TEL2 (ttyS4) +set PRT_TEL2_ 1 diff --git a/boards/auterion/fmu-v6x/init/rc.board_sensors b/boards/auterion/fmu-v6x/init/rc.board_sensors new file mode 100644 index 0000000000..7f65a4a7b9 --- /dev/null +++ b/boards/auterion/fmu-v6x/init/rc.board_sensors @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Auterion FMUv6X specific board sensors init +#------------------------------------------------------------------------------ +set HAVE_PM2 yes +set INA_CONFIGURED no + +if mft query -q -k MFT -s MFT_PM2 -v 0 +then + set HAVE_PM2 no +fi +if param compare -s ADC_ADS1115_EN 1 +then + ads1115 start -X + board_adc start -n +else + board_adc start +fi + + +if param compare SENS_EN_INA226 1 +then + # Start Digital power monitors + ina226 -X -b 1 -t 1 -k start + + if [ $HAVE_PM2 = yes ] + then + ina226 -X -b 2 -t 2 -k start + fi + + set INA_CONFIGURED yes +fi + +if param compare SENS_EN_INA228 1 +then + # Start Digital power monitors + ina228 -X -b 1 -t 1 -k start + if [ $HAVE_PM2 = yes ] + then + ina228 -X -b 2 -t 2 -k start + fi + + set INA_CONFIGURED yes +fi + +if param compare SENS_EN_INA238 1 +then + # Start Digital power monitors + ina238 -X -b 1 -t 1 -k start + if [ $HAVE_PM2 = yes ] + then + ina238 -X -b 2 -t 2 -k start + fi + + set INA_CONFIGURED yes +fi + +# Auterion auto starter +auterion_autostarter start + +# Auterion's INA238 uses a shunt value of 0.0003 instead of 0.0005. +param set-default INA238_SHUNT 0.0003 + +# Internal SPI BMI088 +bmi088 -A -R 6 -s start +bmi088 -G -R 6 -s start + +# Internal SPI bus ICM42688p +icm42688p -R 12 -s start + +# Internal SPI bus ICM20602 +icm20602 -R 6 -s start + +# Internal magnetometer on I2C +bmm150 -I -R 0 start + +# External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer) +ist8310 -X -b 1 -R 10 start + +# Possible internal Baro +if param compare SENS_INT_BARO_EN 1 +then + bmp388 -I -a 0x77 start +fi + +#external baro +bmp388 -X start + +unset INA_CONFIGURED +unset HAVE_PM2 diff --git a/boards/auterion/fmu-v6x/multicopter.px4board b/boards/auterion/fmu-v6x/multicopter.px4board new file mode 100644 index 0000000000..4f1b9ef033 --- /dev/null +++ b/boards/auterion/fmu-v6x/multicopter.px4board @@ -0,0 +1,12 @@ +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=n +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=n +CONFIG_MODULES_AIRSPEED_SELECTOR=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_COMMON_RC=y +# CONFIG_EKF2_SIDESLIP is not set +# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set diff --git a/boards/auterion/fmu-v6x/nuttx-config/Kconfig b/boards/auterion/fmu-v6x/nuttx-config/Kconfig new file mode 100644 index 0000000000..bb33d3cfda --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# +config BOARD_HAS_PROBES + bool "Board provides GPIO or other Hardware for signaling to timing analyze." + default y + ---help--- + This board provides GPIO FMU-CH1-5, CAP1-6 as PROBE_1-11 to provide timing signals from selected drivers. + +config BOARD_USE_PROBES + bool "Enable the use the board provided FMU-CH1-5, CAP1-6 as PROBE_1-11" + default n + depends on BOARD_HAS_PROBES + + ---help--- + Select to use GPIO FMU-CH1-5, CAP1-6 to provide timing signals from selected drivers. diff --git a/boards/auterion/fmu-v6x/nuttx-config/bootloader/defconfig b/boards/auterion/fmu-v6x/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..fcbf56afd9 --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/bootloader/defconfig @@ -0,0 +1,83 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_SPI_EXCHANGE is not set +# CONFIG_STM32H7_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/auterion/fmu-v6x/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="auterion" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H753II=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_UART5=y +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_UART5_RXBUFSIZE=512 +CONFIG_UART5_RXDMA=y +CONFIG_UART5_TXBUFSIZE=512 +CONFIG_UART5_TXDMA=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/auterion/fmu-v6x/nuttx-config/include/board.h b/boards/auterion/fmu-v6x/nuttx-config/include/board.h new file mode 100644 index 0000000000..964976318a --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/include/board.h @@ -0,0 +1,570 @@ +/************************************************************************************ + * nuttx-configs/px4_fmu-v6x/include/board.h + * + * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved. + * Authors: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#ifndef __NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The px4_fmu-v6X board provides the following clock sources: + * + * X1: 16 MHz crystal for HSE + * + * So we have these clock source available within the STM32 + * + * HSI: 16 MHz RC factory-trimmed + * HSE: 16 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 16000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 16,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * Subject to: + * + * 1 <= PLLM <= 63 + * 4 <= PLLN <= 512 + * 150 MHz <= PLL_VCOL <= 420MHz + * 192 MHz <= PLL_VCOH <= 836MHz + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + * Subject to + * + * PLLP1 = {2, 4, 6, 8, ..., 128} + * PLLP2,3 = {2, 3, 4, ..., 128} + * CPUCLK <= 480 MHz + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (16,000,000 / 1) * 60 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(60) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 60) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(4) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(4) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/4 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration + * + * Note: look at Table 54 in ST Manual + */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 + +/* UART clock selection */ +/* reset to default to overwrite any changes done by any bootloader */ + +#define STM32_RCC_D2CCIP2R_USART234578_SEL RCC_D2CCIP2R_USART234578SEL_RCC +#define STM32_RCC_D2CCIP2R_USART16_SEL RCC_D2CCIP2R_USART16SEL_RCC + +/* FDCAN 1 2 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE /* FDCAN 1 2 clock source */ + +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states + * + * ------------ ---------- ----------- + * Vcore MAX ACLK WAIT STATES + * ------------ ---------- ----------- + * 1.15-1.26 V 70 MHz 0 + * (VOS1 level) 140 MHz 1 + * 210 MHz 2 + * 1.05-1.15 V 55 MHz 0 + * (VOS2 level) 110 MHz 1 + * 165 MHz 2 + * 220 MHz 3 + * 0.95-1.05 V 45 MHz 0 + * (VOS3 level) 90 MHz 1 + * 135 MHz 2 + * 180 MHz 3 + * 225 MHz 4 + * ------------ ---------- ----------- + */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* SDMMC definitions ********************************************************/ + +/* Init 400kHz, freq = PLL1Q/(2*div) div = PLL1Q/(2*freq) */ + +#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq) + * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s + */ + +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE + +/* LED definitions ******************************************************************/ +/* The PX4 FMUV6X board has three, LED_GREEN a Green LED, LED_BLUE a Blue LED and + * LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +/* LED definitions ******************************************************************/ +/* The px4_fmu-v6x board has three, LED_GREEN a Green LED, LED_BLUE a Blue LED and + * LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Alternate function pin selections ************************************************/ + +#define GPIO_USART1_RX GPIO_USART1_RX_3 /* PB7 */ +#define GPIO_USART1_TX GPIO_USART1_TX_3 /* PB6 */ + +#define GPIO_USART2_RX GPIO_USART2_RX_1 /* PA3 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ +#define GPIO_USART2_RTS GPIO_USART2_RTS_2 /* PD4 */ +#define GPIO_USART2_CTS GPIO_USART2_CTS_NSS_2 /* PD3 */ + +#ifdef PX4_RESTRICTED_BUILD +# define GPIO_USART3_RX 0 /* PD9 */ +#else +# define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#endif /* PX4_RESTRICTED_BUILD */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +#define GPIO_UART4_RX GPIO_UART4_RX_6 /* PH14 */ +#define GPIO_UART4_TX GPIO_UART4_TX_6 /* PH13 */ + +#define GPIO_UART5_RX GPIO_UART5_RX_3 /* PD2 */ +#define GPIO_UART5_TX GPIO_UART5_TX_3 /* PC12 */ +// GPIO_UART5_RTS no remap /* PC8 */ +#undef GPIO_UART5_CTS +#define GPIO_UART5_CTS ((GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN9) | GPIO_PULLDOWN) /* PC9 */ + + +#define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ +#define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ + +#define GPIO_UART7_RX GPIO_UART7_RX_4 /* PF6 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ +#define GPIO_UART7_RTS GPIO_UART7_RTS_2 /* PF8 */ +#define GPIO_UART7_CTS (GPIO_UART7_CTS_1 | GPIO_PULLDOWN) /* PE10 */ + +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* CAN + * + * CAN1 is routed to transceiver. + * CAN2 is routed to transceiver. + */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_3 /* PD0 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_3 /* PD1 */ +#define GPIO_CAN2_RX GPIO_CAN2_RX_1 /* PB12 */ +#define GPIO_CAN2_TX GPIO_CAN2_TX_1 /* PB13 */ + +/* SPI + * SPI1 is sensors1 + * SPI2 is sensors2 + * SPI3 is sensors3 + * SPI4 is Not Used + * SPI5 is FRAM + * SPI6 is EXTERNAL1 + * + */ + +#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_2MHz)) + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_3 /* PG9 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_2 /* PB5 */ +#define GPIO_SPI1_SCK ADJ_SLEW_RATE(GPIO_SPI1_SCK_1) /* PA5 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_3 /* PI2 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_4 /* PI3 */ +#define GPIO_SPI2_SCK ADJ_SLEW_RATE(GPIO_SPI2_SCK_6) /* PI1 */ + +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 /* PC11 */ +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_3 /* PB2 */ +#define GPIO_SPI3_SCK ADJ_SLEW_RATE(GPIO_SPI3_SCK_2) /* PC10 */ + +#define GPIO_SPI5_MISO GPIO_SPI5_MISO_2 /* PH7 */ +#define GPIO_SPI5_MOSI GPIO_SPI5_MOSI_1 /* PF11 */ +#define GPIO_SPI5_SCK ADJ_SLEW_RATE(GPIO_SPI5_SCK_1) /* PF7 */ + +#define GPIO_SPI6_MISO GPIO_SPI6_MISO_2 /* PA6 */ +#define GPIO_SPI6_MOSI GPIO_SPI6_MOSI_1 /* PG14 */ +#define GPIO_SPI6_SCK ADJ_SLEW_RATE(GPIO_SPI6_SCK_3) /* PB3 */ + +/* I2C + * + * The optional _GPIO configurations allow the I2C driver to manually + * reset the bus to clear stuck slaves. They match the pin configuration, + * but are normally-high GPIOs. + * + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* PB8 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* PB9 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN8) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN9) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_2 /* PF1 */ +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_2 /* PF0 */ + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN1) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN0) + +#define GPIO_I2C3_SCL GPIO_I2C3_SCL_1 /* PA8 */ +#define GPIO_I2C3_SDA GPIO_I2C3_SDA_2 /* PH8 */ + +#define GPIO_I2C3_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTA | GPIO_PIN8) +#define GPIO_I2C3_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTH | GPIO_PIN8) + +#define GPIO_I2C4_SCL GPIO_I2C4_SCL_2 /* PF14 */ +#define GPIO_I2C4_SDA GPIO_I2C4_SDA_2 /* PF15 */ + +#define GPIO_I2C4_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN14) +#define GPIO_I2C4_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN15) + +/* SDMMC2 + * + * VDD 3.3 + * GND + * SDMMC2_CK PD6 + * SDMMC2_CMD PD7 + * SDMMC2_D0 PB14 + * SDMMC2_D1 PB15 + * SDMMC2_D2 PG11 + * SDMMC2_D3 PB4 + */ + +#define GPIO_SDMMC2_CK GPIO_SDMMC2_CK_1 /* PD6 */ +#define GPIO_SDMMC2_CMD GPIO_SDMMC2_CMD_1 /* PD7 */ +// GPIO_SDMMC2_D0 No Remap /* PB14 */ +// GPIO_SDMMC2_D1 No Remap /* PB15 */ +#define GPIO_SDMMC2_D2 GPIO_SDMMC2_D2_1 /* PG11 */ +// GPIO_SDMMC2_D3 No Remap /* PB4 */ + +/* The STM32 H7 connects to a TI DP83848TSQ/NOPB + * using RMII + * + * STM32 H7 BOARD DP83848TSQ/NOPB + * GPIO SIGNAL PIN NAME + * -------- ------------ ------------- + * PA7 ETH_CRS_DV CRS_DV + * PC1 ETH_MDC MDC + * PA2 ETH_MDIO MDIO + * PA1 ETH_REF_CL X1 + * PC4 ETH_RXD0 RX_D0 + * PC5 ETH_RXD1 RX_D1 + * PB11 ETH_TX_EN TX_EN + * PG13 ETH_TXD0 TX_D0 + * PG12 ETH_TXD1 TX_D1 + * + * The PHY address is 1, since COL/PHYAD0 features a pull up. + */ + +#define GPIO_ETH_RMII_TX_EN GPIO_ETH_RMII_TX_EN_1 /* PB11 */ +#define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2 /* PG13 */ +#define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_2 /* PG12 */ + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PA9 + */ + + +/* Board provides GPIO or other Hardware for signaling to timing analyzer */ + +#if defined(CONFIG_BOARD_USE_PROBES) +# include "stm32_gpio.h" +# define PROBE_N(n) (1<<((n)-1)) +# define PROBE_1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTI|GPIO_PIN0) /* PI0 AUX1 */ +# define PROBE_2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN12) /* PH12 AUX2 */ +# define PROBE_3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN11) /* PH11 AUX3 */ +# define PROBE_4 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN10) /* PH10 AUX4 */ +# define PROBE_5 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN13) /* PD13 AUX5 */ +# define PROBE_6 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN14) /* PD14 AUX6 */ +# define PROBE_7 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN6) /* PH6 AUX7 */ +# define PROBE_8 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN9) /* PH9 AUX8 */ +# define PROBE_9 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN11) /* PE11 CAP1 */ + +# define PROBE_INIT(mask) \ + do { \ + if ((mask)& PROBE_N(1)) { stm32_configgpio(PROBE_1); } \ + if ((mask)& PROBE_N(2)) { stm32_configgpio(PROBE_2); } \ + if ((mask)& PROBE_N(3)) { stm32_configgpio(PROBE_3); } \ + if ((mask)& PROBE_N(4)) { stm32_configgpio(PROBE_4); } \ + if ((mask)& PROBE_N(5)) { stm32_configgpio(PROBE_5); } \ + if ((mask)& PROBE_N(6)) { stm32_configgpio(PROBE_6); } \ + if ((mask)& PROBE_N(7)) { stm32_configgpio(PROBE_7); } \ + if ((mask)& PROBE_N(8)) { stm32_configgpio(PROBE_8); } \ + if ((mask)& PROBE_N(9)) { stm32_configgpio(PROBE_9); } \ + } while(0) + +# define PROBE(n,s) do {stm32_gpiowrite(PROBE_##n,(s));}while(0) +# define PROBE_MARK(n) PROBE(n,false);PROBE(n,true) +#else +# define PROBE_INIT(mask) +# define PROBE(n,s) +# define PROBE_MARK(n) +#endif + +#endif /*__NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H */ diff --git a/boards/auterion/fmu-v6x/nuttx-config/include/board_dma_map.h b/boards/auterion/fmu-v6x/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..1f45efc569 --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/include/board_dma_map.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMAMUX1 Using at most 8 Channels on DMA1 -------- Assigned +// V + +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* 1 DMA1:37 ICM-20649 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* 2 DMA1:38 ICM-20649 */ + +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* 3 DMA1:39 ICM-42688-P */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* 4 DMA1:40 ICM-42688-P */ + +//#define DMAMAP_USART1_RX DMAMAP_DMA12_USART1RX_0 /* DMA1:41 GPS1 */ +//#define DMAMAP_USART1_TX DMAMAP_DMA12_USART1TX_0 /* DMA1:42 GPS1 */ + +//#define DMAMAP_USART2_RX DMAMAP_DMA12_USART2RX_0 /* DMA1:43 Telem3 */ +//#define DMAMAP_USART2_TX DMAMAP_DMA12_USART2TX_0 /* DMA1:44 Telem3 */ + +//#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_0 /* DMA1:45 DEBUG */ +//#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_0 /* DMA1:46 DEBUG */ + +//#define DMAMAP_UART4_RX DMAMAP_DMA12_UART4RX_0 /* DMA1:63 EXT2 */ +//#define DMAMAP_UART4_TX DMAMAP_DMA12_UART4TX_0 /* DMA1:64 EXT2 */ + +#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 /* 5 DMA1:71 PX4IO */ +#define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 /* 6 DMA1:72 PX4IO */ + +// Assigned in timer_config.cpp + +// Timer 4 /* 7 DMA1:32 TIM4UP */ +// Timer 5 /* 8 DMA1:50 TIM5UP */ + +// DMAMUX2 Using at most 8 Channels on DMA2 -------- Assigned +// V + +#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_1 /* 1 DMA2:61 BMI088 */ +#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_1 /* 2 DMA2:62 BMI088 */ + +#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_1 /* 3 DMA2:45 DEBUG */ +#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_1 /* 4 DMA2:46 DEBUG */ + +#define DMAMAP_UART5_RX DMAMAP_DMA12_UART5RX_1 /* 5 DMA2:65 TELEM2 */ +#define DMAMAP_UART5_TX DMAMAP_DMA12_UART5TX_1 /* 6 DMA2:66 TELEM2 */ + +#define DMAMAP_UART7_RX DMAMAP_DMA12_UART7RX_1 /* 7 DMA1:79 TELEM1 */ +#define DMAMAP_UART7_TX DMAMAP_DMA12_UART7TX_1 /* 8 DMA1:80 TELEM1 */ + +//#define DMAMAP_UART8_RX DMAMAP_DMA12_UART8RX_1 /* DMA1:81 GPS2 */ +//#define DMAMAP_UART8_TX DMAMAP_DMA12_UART8TX_1 /* DMA1:82 GPS2 */ + +// DMAMUX2 Using at most 8 Channels on BDMA -------- Assigned +// V + +#define DMAMAP_SPI6_RX DMAMAP_BDMA_SPI6_RX /* 1 BDMA:11 SPI J11 */ +#define DMAMAP_SPI6_TX DMAMAP_BDMA_SPI6_TX /* 2 BDMA:12 SPI J11 */ diff --git a/boards/auterion/fmu-v6x/nuttx-config/nsh/defconfig b/boards/auterion/fmu-v6x/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..6070e6696e --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/nsh/defconfig @@ -0,0 +1,313 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ARP is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_IFUPDOWN is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_NSLOOKUP is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TELNETD is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/auterion/fmu-v6x/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="auterion" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H753II=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95751 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_GPIO=y +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_DEV_URANDOM=y +CONFIG_ETH0_PHY_LAN8742A=y +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FSUTILS_IPCFG=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_THROTTLE=0 +CONFIG_IPCFG_BINARY=y +CONFIG_IPCFG_CHARDEV=y +CONFIG_IPCFG_PATH="/fs/mtd_net" +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_RAMTRON=y +CONFIG_NAME_MAX=40 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDB_DNSCLIENT_ENTRIES=8 +CONFIG_NETDB_DNSSERVER_NOADDR=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_DNSIPADDR=0xA290AFE +CONFIG_NETINIT_DRIPADDR=0xA290AFE +CONFIG_NETINIT_IPADDR=0xA290A02 +CONFIG_NETINIT_MONITOR=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETINIT_THREAD_PRIORITY=49 +CONFIG_NET_ARP_IPIN=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1518 +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_NACTIVESOCKETS=16 +CONFIG_NET_SOLINGER=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NET_UDP_WRITE_BUFFERS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 +CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 +CONFIG_RAMTRON_SETSPEED=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SDMMC2_SDIO_PULLUP=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FLASH_OVERRIDE_I=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C2=y +CONFIG_STM32H7_I2C3=y +CONFIG_STM32H7_I2C4=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100MBPS=0x8 +CONFIG_STM32H7_PHYSR_FULLDUPLEX=0x10 +CONFIG_STM32H7_PHYSR_MODE=0x10 +CONFIG_STM32H7_PHYSR_SPEED=0x8 +CONFIG_STM32H7_PHY_POLLING=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SDMMC2=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=1024 +CONFIG_STM32H7_SPI2=y +CONFIG_STM32H7_SPI2_DMA=y +CONFIG_STM32H7_SPI2_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI3=y +CONFIG_STM32H7_SPI3_DMA=y +CONFIG_STM32H7_SPI3_DMA_BUFFER=1024 +CONFIG_STM32H7_SPI5=y +CONFIG_STM32H7_SPI6=y +CONFIG_STM32H7_SPI6_DMA=y +CONFIG_STM32H7_SPI6_DMA_BUFFER=1024 +CONFIG_STM32H7_TIM12=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM4=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART6=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART5_IFLOWCONTROL=y +CONFIG_UART5_OFLOWCONTROL=y +CONFIG_UART5_RXDMA=y +CONFIG_UART5_TXBUFSIZE=10000 +CONFIG_UART5_TXDMA=y +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_IFLOWCONTROL=y +CONFIG_UART7_OFLOWCONTROL=y +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_RXDMA=y +CONFIG_UART7_TXBUFSIZE=3000 +CONFIG_UART7_TXDMA=y +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_IFLOWCONTROL=y +CONFIG_USART2_OFLOWCONTROL=y +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=3000 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=180 +CONFIG_USART3_RXDMA=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USART3_TXDMA=y +CONFIG_USART6_BAUD=57600 +CONFIG_USART6_RXBUFSIZE=600 +CONFIG_USART6_TXBUFSIZE=1500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/auterion/fmu-v6x/nuttx-config/scripts/bootloader_script.ld b/boards/auterion/fmu-v6x/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..037356efd3 --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,215 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Auterion FMUV6X uses an STM32H753II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Auterion FMUV6X has a test point on board, the BOOT0 pin is at ground so by + * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test + * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000 + * + * The STM32H743II also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The bootloader uses the first sector of the flash, which is 128K in length. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 128K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/auterion/fmu-v6x/nuttx-config/scripts/flash-analysis-script.ld b/boards/auterion/fmu-v6x/nuttx-config/scripts/flash-analysis-script.ld new file mode 100644 index 0000000000..5df2f5180a --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/scripts/flash-analysis-script.ld @@ -0,0 +1,6 @@ +INCLUDE "script.ld" + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 10080K +} diff --git a/boards/auterion/fmu-v6x/nuttx-config/scripts/script.ld b/boards/auterion/fmu-v6x/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..860eb2ddd9 --- /dev/null +++ b/boards/auterion/fmu-v6x/nuttx-config/scripts/script.ld @@ -0,0 +1,229 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Auterion FMUV6X uses an STM32H753II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Auterion FMUV6X has a test point on board, the BOOT0 pin is at ground so by + * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test + * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000 + * + * The STM32H743II also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1920K + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) +EXTERN(board_get_manifest) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/auterion/fmu-v6x/performance-test.px4board b/boards/auterion/fmu-v6x/performance-test.px4board new file mode 100644 index 0000000000..5e69dd7ae3 --- /dev/null +++ b/boards/auterion/fmu-v6x/performance-test.px4board @@ -0,0 +1,31 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ETHERNET=y +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS7" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" +CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3" +CONFIG_BOARD_ROMFSROOT="performance-test" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_MFT_CFG=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SD_STRESS=y +CONFIG_SYSTEMCMDS_SERIAL_TEST=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/auterion/fmu-v6x/rover.px4board b/boards/auterion/fmu-v6x/rover.px4board new file mode 100644 index 0000000000..cd49a241b5 --- /dev/null +++ b/boards/auterion/fmu-v6x/rover.px4board @@ -0,0 +1,17 @@ +CONFIG_MODULES_AIRSPEED_SELECTOR=n +CONFIG_MODULES_FLIGHT_MODE_MANAGER=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_MC_ATT_CONTROL=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n +CONFIG_MODULES_MC_POS_CONTROL=n +CONFIG_MODULES_MC_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_DRIVERS_ROBOCLAW=y +CONFIG_MODULES_ROVER_ACKERMANN=y +CONFIG_MODULES_ROVER_DIFFERENTIAL=y +CONFIG_MODULES_ROVER_MECANUM=y diff --git a/boards/auterion/fmu-v6x/spacecraft.px4board b/boards/auterion/fmu-v6x/spacecraft.px4board new file mode 100644 index 0000000000..997a9054a2 --- /dev/null +++ b/boards/auterion/fmu-v6x/spacecraft.px4board @@ -0,0 +1,21 @@ +CONFIG_BOARD_PWM_FREQ=100000 +CONFIG_MODULES_AIRSPEED_SELECTOR=n +CONFIG_MODULES_FLIGHT_MODE_MANAGER=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_LAND_DETECTOR=n +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=n +CONFIG_MODULES_MC_ATT_CONTROL=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n +CONFIG_MODULES_MC_POS_CONTROL=n +CONFIG_MODULES_MC_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_MODULES_ROVER_ACKERMANN=n +CONFIG_MODULES_ROVER_DIFFERENTIAL=n +CONFIG_MODULES_ROVER_MECANUM=n +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_SPACECRAFT=y diff --git a/boards/auterion/fmu-v6x/src/CMakeLists.txt b/boards/auterion/fmu-v6x/src/CMakeLists.txt new file mode 100644 index 0000000000..4e3d9bf3eb --- /dev/null +++ b/boards/auterion/fmu-v6x/src/CMakeLists.txt @@ -0,0 +1,74 @@ +############################################################################ +# +# Copyright (c) 2016 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_compile_definitions(BOOTLOADER) + add_library(drivers_board + bootloader_main.c + init.cpp + timer_config.cpp + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer #gpio + arch_io_pins # iotimer + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + can.c + i2c.cpp + init.cpp + led.c + mtd.cpp + sdio.c + spi.cpp + timer_config.cpp + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led # drv_led_start + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer + platform_gpio_mcp + ) +endif() diff --git a/boards/auterion/fmu-v6x/src/board_config.h b/boards/auterion/fmu-v6x/src/board_config.h new file mode 100644 index 0000000000..671a1c3e5f --- /dev/null +++ b/boards/auterion/fmu-v6x/src/board_config.h @@ -0,0 +1,524 @@ +/**************************************************************************** + * + * Copyright (c) 2016-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * AuterionFMU-v6x internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +#undef TRACE_PINS + +/* PX4IO connection configuration */ + +#define BOARD_USES_PX4IO_VERSION 2 +#define PX4IO_SERIAL_DEVICE "/dev/ttyS5" +#define PX4IO_SERIAL_TX_GPIO GPIO_USART6_TX +#define PX4IO_SERIAL_RX_GPIO GPIO_USART6_RX +#define PX4IO_SERIAL_BASE STM32_USART6_BASE +#define PX4IO_SERIAL_VECTOR STM32_IRQ_USART6 +#define PX4IO_SERIAL_TX_DMAMAP DMAMAP_USART6_TX +#define PX4IO_SERIAL_RX_DMAMAP DMAMAP_USART6_RX +#define PX4IO_SERIAL_RCC_REG STM32_RCC_APB2ENR +#define PX4IO_SERIAL_RCC_EN RCC_APB2ENR_USART6EN +#define PX4IO_SERIAL_CLOCK STM32_PCLK2_FREQUENCY +#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */ + +/* Configuration ************************************************************************************/ + +#define BOARD_HAS_LTC44XX_VALIDS 2 // N Bricks +#define BOARD_HAS_USB_VALID 1 // LTC Has USB valid +#define BOARD_HAS_NBAT_V 2d // 2 Digital Voltage +#define BOARD_HAS_NBAT_I 2d // 2 Digital Current + +/* PX4FMU GPIOs ***********************************************************************************/ + +/* Trace Clock and D0-D3 are available on the trace connector + * + * TRACECLK PE2 - Dedicated - Trace Connector Pin 1 + * TRACED0 PE3 - nLED_RED - Trace Connector Pin 3 + * TRACED1 PE4 - nLED_GREEN - Trace Connector Pin 5 + * TRACED2 PE5 - nLED_BLUE - Trace Connector Pin 7 + * TRACED3 PE6 - nARMED - Trace Connector Pin 8 + + */ + +/* LEDs are driven with push open drain to support Anode to 5V or 3.3V or used as TRACE0-2 */ + +#if !defined(TRACE_PINS) +# define GPIO_nLED_RED /* PE3 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3) +# define GPIO_nLED_GREEN /* PE4 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4) +# define GPIO_nLED_BLUE /* PE5 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN5) + +# define BOARD_HAS_CONTROL_STATUS_LEDS 1 +# define BOARD_OVERLOAD_LED LED_RED +# define BOARD_ARMED_STATE_LED LED_BLUE + +#else + +# define GPIO_TRACECLK1 (GPIO_TRACECLK |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +# define GPIO_TRACED0 (GPIO_TRACED0_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +# define GPIO_TRACED1 (GPIO_TRACED1_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +# define GPIO_TRACED2 (GPIO_TRACED2_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +# define GPIO_TRACED3 (GPIO_TRACED3_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +//#define GPIO_TRACESWO //(GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) + +# undef BOARD_HAS_CONTROL_STATUS_LEDS +# undef BOARD_OVERLOAD_LED +# undef BOARD_ARMED_STATE_LED + +# define GPIO_nLED_RED GPIO_TRACED0 +# define GPIO_nLED_GREEN GPIO_TRACED1 +# define GPIO_nLED_BLUE GPIO_TRACED2 +# define GPIO_nARMED GPIO_TRACED3 +# define GPIO_nARMED_INIT GPIO_TRACED3 +#endif + + +/* SPI */ + +#define SPI6_nRESET_EXTERNAL1 /* PF10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN10) +#define GPIO_SYNC /* PE9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_100MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN9) + +/* I2C busses */ + +/* Devices on the onboard buses. + * + * Note that these are unshifted addresses. + */ +#define BOARD_MTD_NUM_EEPROM 2 /* MTD: base_eeprom, imu_eeprom*/ + +#define PX4_I2C_OBDEV_SE050 0x48 + +#define GPIO_I2C2_DRDY1_BMP388 /* PG5 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN5) + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ + +#define ADC1_CH(n) (n) + +/* N.B. there is no offset mapping needed for ADC3 because */ +#define ADC3_CH(n) (n) + +/* We are only use ADC3 for REV/VER. + * ADC3_6V6 and ADC3_3V3 are mapped back to ADC1 + * To do this We are relying on PC2_C, PC3_C being connected to PC2, PC3 + * respectively by the SYSCFG_PMCR default of setting for PC3SO PC2SO PA1SO + * PA0SO of 0. + * + * 0 Analog switch closed (pads are connected through the analog switch) + * + * So ADC3_INP0 is GPIO_ADC123_INP12 + * ADC3_INP1 is GPIO_ADC12_INP13 + */ + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ + +#define PX4_ADC_GPIO \ + /* PA0 */ GPIO_ADC1_INP16, \ + /* PA4 */ GPIO_ADC12_INP18, \ + /* PB0 */ GPIO_ADC12_INP9, \ + /* PB1 */ GPIO_ADC12_INP5, \ + /* PC2 */ GPIO_ADC123_INP12, \ + /* PC3 */ GPIO_ADC12_INP13, \ + /* PF12 */ GPIO_ADC1_INP6, \ + /* PH3 */ GPIO_ADC3_INP14, \ + /* PH4 */ GPIO_ADC3_INP15 + +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_SCALED_VDD_3V3_SENSORS1_CHANNEL /* PA0 */ ADC1_CH(16) +#define ADC_SCALED_VDD_3V3_SENSORS2_CHANNEL /* PA4 */ ADC1_CH(18) +#define ADC_SCALED_VDD_3V3_SENSORS3_CHANNEL /* PB0 */ ADC1_CH(9) +#define ADC_SCALED_V5_CHANNEL /* PB1 */ ADC1_CH(5) +#define ADC_ADC3_6V6_CHANNEL /* PC2 */ ADC3_CH(12) +#define ADC_ADC3_3V3_CHANNEL /* PC3 */ ADC3_CH(13) +#define ADC_SCALED_VDD_3V3_SENSORS4_CHANNEL /* PF12 */ ADC1_CH(6) +#define ADC_HW_VER_SENSE_CHANNEL /* PH3 */ ADC3_CH(14) +#define ADC_HW_REV_SENSE_CHANNEL /* PH4 */ ADC3_CH(15) + +#define ADC_CHANNELS \ + ((1 << ADC_SCALED_VDD_3V3_SENSORS1_CHANNEL) | \ + (1 << ADC_SCALED_VDD_3V3_SENSORS2_CHANNEL) | \ + (1 << ADC_SCALED_VDD_3V3_SENSORS3_CHANNEL) | \ + (1 << ADC_SCALED_V5_CHANNEL) | \ + (1 << ADC_ADC3_6V6_CHANNEL) | \ + (1 << ADC_ADC3_3V3_CHANNEL)) | \ + (1 << ADC_SCALED_VDD_3V3_SENSORS4_CHANNEL) + +/* HW has to large of R termination on ADC todo:change when HW value is chosen */ + +#define HW_REV_VER_ADC_BASE STM32_ADC3_BASE + +#define SYSTEM_ADC_BASE STM32_ADC1_BASE + +/* HW has to large of R termination on ADC todo:change when HW value is chosen */ +#define BOARD_ADC_OPEN_CIRCUIT_V (5.6f) + +/* HW Version and Revision drive signals Default to 1 to detect */ +#define BOARD_HAS_HW_SPLIT_VERSIONING + +#define GPIO_HW_VER_REV_DRIVE /* PG0 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN0) +#define GPIO_HW_REV_SENSE /* PH4 */ GPIO_ADC3_INP15 +#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14 +#define HW_INFO_INIT_PREFIX "V6X" + +#define BOARD_NUM_SPI_CFG_HW_VERSIONS 1 +// Base/FMUM +#define V6X_16 HW_FMUM_ID(0x10) // FMUV6X, Auterion Sensor Set Rev 16 from EEPROM + +#define UAVCAN_NUM_IFACES_RUNTIME 1 + +/* HEATER + * PWM in future + */ +#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true)) + +/* PE6 is nARMED + * The GPIO will be set as input while not armed HW will have external HW Pull UP. + * While armed it shall be configured at a GPIO OUT set LOW + */ +#if !defined(TRACE_PINS) +#define GPIO_nARMED_INIT /* PE6 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN6) +#define GPIO_nARMED /* PE6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6) +#define BOARD_INDICATE_EXTERNAL_LOCKOUT_STATE(enabled) px4_arch_configgpio((enabled) ? GPIO_nARMED : GPIO_nARMED_INIT) +#define BOARD_GET_EXTERNAL_LOCKOUT_STATE() px4_arch_gpioread(GPIO_nARMED) +#endif + + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 9 + + +/* Power supply control and monitoring GPIOs */ + +#define GPIO_nPOWER_IN_A /* PG1 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN1) +#define GPIO_nPOWER_IN_B /* PG2 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN2) +#define GPIO_nPOWER_IN_C /* PG3 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN3) + +#define GPIO_nVDD_BRICK1_VALID GPIO_nPOWER_IN_A /* Brick 1 Is Chosen */ +#define GPIO_nVDD_BRICK2_VALID GPIO_nPOWER_IN_B /* Brick 2 Is Chosen */ +#define BOARD_NUMBER_BRICKS 2 +#define BOARD_NUMBER_DIGITAL_BRICKS 2 +#define GPIO_nVDD_USB_VALID GPIO_nPOWER_IN_C /* USB Is Chosen */ + +#define GPIO_VDD_5V_PERIPH_nEN /* PG4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN4) +#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15) +#define GPIO_VDD_5V_HIPOWER_nEN /* PG10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10) +#define GPIO_VDD_5V_HIPOWER_nOC /* PF13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13) +#define GPIO_VDD_3V3_SENSORS4_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8) +#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2) +#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13) + +/* MCP23009 GPIO expander */ +#define BOARD_GPIO_VDD_5V_COMP_VALID "/dev/gpio4" +#define BOARD_GPIO_VDD_5V_CAN1_GPS1_VALID "/dev/gpio5" + + +/* Spare GPIO */ + +#define GPIO_PG6 /* PG6 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN6) +#define GPIO_PD15 /* PD15 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN15) + +/* ETHERNET GPIO */ + +#define GPIO_ETH_POWER_EN /* PG15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN15) + +/* NFC GPIO */ + +#define GPIO_NFC_GPIO /* PC0 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTC|GPIO_PIN0) + + +/* Define True logic Power Control in arch agnostic form */ + +#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true)) +#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true)) +#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS4_EN, (on_true)) +#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true)) +#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN) +#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true)) +#define VDD_3V3_ETH_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_ETH_POWER_EN, (on_true)) + + +/* Tone alarm output */ + +#define TONE_ALARM_TIMER 14 /* Timer 14 */ +#define TONE_ALARM_CHANNEL 1 /* PF9 GPIO_TIM14_CH1OUT_2 */ + +#define GPIO_BUZZER_1 /* PF9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN9) + +#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1 +#define GPIO_TONE_ALARM GPIO_TIM14_CH1OUT_2 + +/* USB OTG FS + * + * PA9 OTG_FS_VBUS VBUS sensing + */ +#define GPIO_OTGFS_VBUS /* PA9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN9) + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + +#define HRT_PPM_CHANNEL /* T8C1 */ 1 /* use capture/compare channel 1 */ +#define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 + +/* Some RC protocols are bi-directional, therefore we need a half-duplex UART */ +#define RC_SERIAL_SINGLEWIRE +/* The STM32 UART by default wires half-duplex mode to the TX pin, but our + * signal in routed to the RX pin, so we need to swap the pins */ +#define RC_SERIAL_SWAP_RXTX + +/* Input Capture Channels. */ +#define INPUT_CAP1_TIMER 1 +#define INPUT_CAP1_CHANNEL /* T1C2 */ 2 +#define GPIO_INPUT_CAP1 /* PE11 */ GPIO_TIM1_CH2IN + +/* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2 */ +#define PWMIN_TIMER 4 +#define PWMIN_TIMER_CHANNEL /* T4C2 */ 2 +#define GPIO_PWM_IN /* PD13 */ GPIO_TIM4_CH2IN_2 + +/* Safety Switch is HW version dependent on having an PX4IO + * So we init to a benign state with the _INIT definition + * and provide the the non _INIT one for the driver to make a run time + * decision to use it. + */ +#define GPIO_nSAFETY_SWITCH_LED_OUT_INIT /* PD10 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN10) +#define GPIO_nSAFETY_SWITCH_LED_OUT /* PD10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN10) + +/* Enable the FMU to control it if there is no px4io fixme:This should be BOARD_SAFETY_LED(__ontrue) */ +#define GPIO_LED_SAFETY GPIO_nSAFETY_SWITCH_LED_OUT + +#define GPIO_SAFETY_SWITCH_IN /* PF5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN5) +/* Enable the FMU to use the switch it if there is no px4io fixme:This should be BOARD_SAFTY_BUTTON() */ +#define GPIO_BTN_SAFETY GPIO_SAFETY_SWITCH_IN /* Enable the FMU to control it if there is no px4io */ + +/* Power switch controls ******************************************************/ + +#define SPEKTRUM_POWER(_on_true) VDD_3V3_SPEKTRUM_POWER_EN(_on_true) + +/* + * FMUv6X has a separate RC_IN + * + * GPIO PPM_IN on PI5 T8CH1 + * SPEKTRUM_RX (it's TX or RX in Bind) on UART6 PC7 + * Inversion is possible in the UART and can drive GPIO PPM_IN as an output + */ + +#define GPIO_PPM_IN_AS_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTI|GPIO_PIN5) +#define SPEKTRUM_RX_AS_GPIO_OUTPUT() px4_arch_configgpio(GPIO_PPM_IN_AS_OUT) +#define SPEKTRUM_RX_AS_UART() /* Can be left as uart */ +#define SPEKTRUM_OUT(_one_true) px4_arch_gpiowrite(GPIO_PPM_IN_AS_OUT, (_one_true)) + +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 + +/* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ + +#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +#endif + +/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction) + * this board support the ADC system_power interface, and therefore + * provides the true logic GPIO BOARD_ADC_xxxx macros. + */ +#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_OTGFS_VBUS)) +#define BOARD_ADC_USB_VALID (!px4_arch_gpioread(GPIO_nVDD_USB_VALID)) + +/* FMUv6X never powers off the Servo rail */ + +#define BOARD_ADC_SERVO_VALID (1) + +#if !defined(BOARD_HAS_LTC44XX_VALIDS) || BOARD_HAS_LTC44XX_VALIDS == 0 +# define BOARD_ADC_BRICK1_VALID (1) +# define BOARD_ADC_BRICK2_VALID (0) +#elif BOARD_HAS_LTC44XX_VALIDS == 1 +# define BOARD_ADC_BRICK1_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK1_VALID)) +# define BOARD_ADC_BRICK2_VALID (0) +#elif BOARD_HAS_LTC44XX_VALIDS == 2 +# define BOARD_ADC_BRICK1_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK1_VALID)) +# define BOARD_ADC_BRICK2_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK2_VALID)) +#elif BOARD_HAS_LTC44XX_VALIDS == 3 +# define BOARD_ADC_BRICK1_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK1_VALID)) +# define BOARD_ADC_BRICK2_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK2_VALID)) +# define BOARD_ADC_BRICK3_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK3_VALID)) +#elif BOARD_HAS_LTC44XX_VALIDS == 4 +# define BOARD_ADC_BRICK1_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK1_VALID)) +# define BOARD_ADC_BRICK2_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK2_VALID)) +# define BOARD_ADC_BRICK3_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK3_VALID)) +# define BOARD_ADC_BRICK4_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK4_VALID)) +#else +# error Unsupported BOARD_HAS_LTC44XX_VALIDS value +#endif + +#define BOARD_ADC_PERIPH_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_PERIPH_nOC)) +#define BOARD_ADC_HIPOWER_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_HIPOWER_nOC)) + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ + +#define BOARD_HAS_ON_RESET 1 + +#if defined(TRACE_PINS) +#define GPIO_TRACE \ + GPIO_TRACECLK1, \ + GPIO_TRACED0, \ + GPIO_TRACED1, \ + GPIO_TRACED2, \ + GPIO_TRACED3 +#else +#define GPIO_TRACE (GPIO_OUTPUT|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN2) +#endif + +#define PX4_GPIO_INIT_LIST { \ + GPIO_TRACE, \ + PX4_ADC_GPIO, \ + GPIO_HW_VER_REV_DRIVE, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN2_TX, \ + GPIO_CAN2_RX, \ + GPIO_HEATER_OUTPUT, \ + GPIO_nPOWER_IN_A, \ + GPIO_nPOWER_IN_B, \ + GPIO_nPOWER_IN_C, \ + GPIO_VDD_5V_PERIPH_nEN, \ + GPIO_VDD_5V_PERIPH_nOC, \ + GPIO_VDD_5V_HIPOWER_nEN, \ + GPIO_VDD_5V_HIPOWER_nOC, \ + GPIO_VDD_3V3_SENSORS4_EN, \ + GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \ + GPIO_VDD_3V3_SD_CARD_EN, \ + GPIO_PD15, \ + GPIO_SYNC, \ + SPI6_nRESET_EXTERNAL1, \ + GPIO_ETH_POWER_EN, \ + GPIO_NFC_GPIO, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_nSAFETY_SWITCH_LED_OUT_INIT, \ + GPIO_SAFETY_SWITCH_IN, \ + GPIO_PG6, \ + GPIO_nARMED_INIT \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define PX4_I2C_BUS_MTD 4,5 + + +#define BOARD_NUM_IO_TIMERS 4 + +/* No CDCACM driver for this board, so this is manually defined for version.c + * so that the px4_board_version reports the correct board id to the companion */ +#define CONFIG_CDCACM_PRODUCTID 53 + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void); + +/**************************************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the PX4FMU board. + * + ****************************************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/auterion/fmu-v6x/src/bootloader_main.c b/boards/auterion/fmu-v6x/src/bootloader_main.c new file mode 100644 index 0000000000..ccb9a8326b --- /dev/null +++ b/boards/auterion/fmu-v6x/src/bootloader_main.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * + * Copyright (c) 2019-2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +void board_late_initialize(void) +{ +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/auterion/fmu-v6x/src/can.c b/boards/auterion/fmu-v6x/src/can.c new file mode 100644 index 0000000000..cdebe7a3ad --- /dev/null +++ b/boards/auterion/fmu-v6x/src/can.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file can.c + * + * Board-specific CAN functions. + */ + +#if !defined(CONFIG_CAN) + +#include + +#include "board_config.h" + + +__EXPORT +uint16_t board_get_can_interfaces(void) +{ + uint16_t enabled_interfaces = 0x3; + + if (!PX4_MFT_HW_SUPPORTED(PX4_MFT_CAN2)) { + enabled_interfaces &= ~(1 << 1); + } + + return enabled_interfaces; +} + +#else + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "chip.h" +#include "stm32_can.h" +#include "board_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} +#endif /* CONFIG_CAN */ diff --git a/boards/auterion/fmu-v6x/src/hw_config.h b/boards/auterion/fmu-v6x/src/hw_config.h new file mode 100644 index 0000000000..949a9284a5 --- /dev/null +++ b/boards/auterion/fmu-v6x/src/hw_config.h @@ -0,0 +1,127 @@ +/* + * hw_config.h + * + * Created on: May 17, 2015 + * Author: david_s5 + */ + +#ifndef HW_CONFIG_H_ +#define HW_CONFIG_H_ + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 0 +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,1500000" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 53 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (15) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 16 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +// Connected to VBUS on the Auterion FMU v6x +#define BOARD_FORCE_BL_PIN (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTA|GPIO_PIN9) +#define BOARD_FORCE_BL_STATE 1 + +/* + * Uncommenting this allows to force the bootloader through + * a PWM output pin. As this can accidentally initialize + * an ESC prematurely, it is not recommended. This feature + * has not been used and hence defaults now to off. + * + * # define BOARD_FORCE_BL_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN14) + * # define BOARD_FORCE_BL_PIN_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) + * + * # define BOARD_POWER_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4) + * # define BOARD_POWER_ON 1 + * # define BOARD_POWER_OFF 0 + * # undef BOARD_POWER_PIN_RELEASE // Leave pin enabling Power - un comment to release (disable power) + * +*/ + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB SERIAL0_DEV|SERIAL1_DEV +#endif + +#endif /* HW_CONFIG_H_ */ diff --git a/boards/auterion/fmu-v6x/src/i2c.cpp b/boards/auterion/fmu-v6x/src/i2c.cpp new file mode 100644 index 0000000000..8a557078e0 --- /dev/null +++ b/boards/auterion/fmu-v6x/src/i2c.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusExternal(1), + initI2CBusExternal(2), + initI2CBusExternal(3), + initI2CBusInternal(4), +}; diff --git a/boards/auterion/fmu-v6x/src/init.cpp b/boards/auterion/fmu-v6x/src/init.cpp new file mode 100644 index 0000000000..d11026f677 --- /dev/null +++ b/boards/auterion/fmu-v6x/src/init.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.cpp + * + * AuterionFMU-specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "board_config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + /* set the peripheral rails off */ + + VDD_5V_PERIPH_EN(false); + board_control_spi_sensors_power(false, 0xffff); + VDD_3V3_SENSORS4_EN(false); + + bool last = READ_VDD_3V3_SPEKTRUM_POWER_EN(); + /* Keep Spektum on to discharge rail*/ + VDD_3V3_SPEKTRUM_POWER_EN(false); + + /* wait for the peripheral rail to reach GND */ + usleep(ms * 1000); + syslog(LOG_DEBUG, "reset done, %d ms\n", ms); + + /* re-enable power */ + + /* switch the peripheral rail back on */ + VDD_3V3_SPEKTRUM_POWER_EN(last); + board_control_spi_sensors_power(true, 0xffff); + VDD_3V3_SENSORS4_EN(true); + VDD_5V_PERIPH_EN(true); + +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(io_timer_channel_get_gpio_output(i)); + } + + /* + * On resets invoked from system (not boot) ensure we establish a low + * output state on PWM pins to disarm the ESC and prevent the reset from potentially + * spinning up the motors. + */ + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +extern "C" __EXPORT void +stm32_boardinitialize(void) +{ + board_on_reset(-1); /* Reset PWM first thing */ + + /* configure LEDs */ + + board_autoled_initialize(); + + /* configure pins */ + + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + VDD_3V3_ETH_POWER_EN(true); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +__EXPORT int board_app_initialize(uintptr_t arg) +{ +#if !defined(BOOTLOADER) + + /* Power on Interfaces */ + VDD_3V3_SD_CARD_EN(true); + VDD_5V_PERIPH_EN(true); + VDD_5V_HIPOWER_EN(true); + VDD_3V3_SENSORS4_EN(true); + VDD_3V3_SPEKTRUM_POWER_EN(true); + + /* Need hrt running before using the ADC */ + + px4_platform_init(); + + // Use the default HW_VER_REV(0x0,0x0) for Ramtron + + stm32_spiinitialize(); + + /* Configure the HW based on the manifest */ + + px4_platform_configure(); + + if (OK == board_determine_hw_info()) { + syslog(LOG_INFO, "[boot] Rev 0x%1x : Ver 0x%1x %s\n", board_get_hw_revision(), board_get_hw_version(), + board_get_hw_type_name()); + + } else { + syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n"); + } + + /* Configure the Actual SPI interfaces (after we determined the HW version) */ + + stm32_spiinitialize(); + + board_spi_reset(10, 0xffff); + + /* Configure the DMA allocator */ + + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + +# if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); +# endif + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_on(LED_GREEN); // Indicate Power. + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + + // Ensure Power is off for > 10 mS + usleep(15 * 1000); + VDD_3V3_SD_CARD_EN(true); + usleep(500 * 1000); + +# ifdef CONFIG_MMCSD + int ret = stm32_sdio_initialize(); + + if (ret != OK) { + led_on(LED_RED); + return ret; + } + +# endif /* CONFIG_MMCSD */ + +#endif /* !defined(BOOTLOADER) */ + + return OK; +} diff --git a/boards/auterion/fmu-v6x/src/led.c b/boards/auterion/fmu-v6x/src/led.c new file mode 100644 index 0000000000..1e33dd1299 --- /dev/null +++ b/boards/auterion/fmu-v6x/src/led.c @@ -0,0 +1,235 @@ +/**************************************************************************** + * + * Copyright (c) 2013 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * PX4FMU LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +// B R S G +// 0 1 2 3 +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE + GPIO_nLED_RED, // Indexed by BOARD_LED_RED + GPIO_nSAFETY_SWITCH_LED_OUT, // Indexed by LED_SAFETY by xlatpx4 +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_BLUE, // Indexed by LED_BLUE + GPIO_nLED_RED, // Indexed by LED_RED, LED_AMBER + 0, // Indexed by LED_SAFETY (defaulted to an input) + GPIO_nLED_GREEN, // Indexed by LED_GREEN +}; + +#endif + +__EXPORT void led_init(void) +{ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on */ + + if (g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/auterion/fmu-v6x/src/mtd.cpp b/boards/auterion/fmu-v6x/src/mtd.cpp new file mode 100644 index 0000000000..8e57555eac --- /dev/null +++ b/boards/auterion/fmu-v6x/src/mtd.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include +// KiB BS nB +static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32) + .bus_type = px4_mft_device_t::SPI, + .devid = SPIDEV_FLASH(0) +}; +static const px4_mft_device_t i2c3 = { // 24LC64T on Base 8K 32 X 256 + .bus_type = px4_mft_device_t::I2C, + .devid = PX4_MK_I2C_DEVID(3, 0x51) +}; +static const px4_mft_device_t i2c4 = { // 24LC64T on IMU 8K 32 X 256 + .bus_type = px4_mft_device_t::I2C, + .devid = PX4_MK_I2C_DEVID(4, 0x50) +}; + + +static const px4_mtd_entry_t fmum_fram = { + .device = &spi5, + .npart = 1, + .partd = { + { + .type = MTD_PARAMETERS, + .path = "/fs/mtd_params", + .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT)) + } + }, +}; + +static const px4_mtd_entry_t base_eeprom = { + .device = &i2c3, + .npart = 2, + .partd = { + { + .type = MTD_MFT_VER, + .path = "/fs/mtd_mft_ver", + .nblocks = 248 + }, + { + .type = MTD_NET, + .path = "/fs/mtd_net", + .nblocks = 8 // 256 = 32 * 8 + + } + }, +}; + +static const px4_mtd_entry_t imu_eeprom = { + .device = &i2c4, + .npart = 3, + .partd = { + { + .type = MTD_CALDATA, + .path = "/fs/mtd_caldata", + .nblocks = 240 + }, + { + .type = MTD_MFT_REV, + .path = "/fs/mtd_mft_rev", + .nblocks = 8 + }, + { + .type = MTD_ID, + .path = "/fs/mtd_id", + .nblocks = 8 // 256 = 32 * 8 + } + }, +}; + +static const px4_mtd_manifest_t board_mtd_config = { + .nconfigs = 3, + .entries = { + &fmum_fram, + &base_eeprom, + &imu_eeprom + } +}; + +static const px4_mft_entry_s mtd_mft = { + .type = MTD, + .pmft = (void *) &board_mtd_config, +}; + +static const px4_mft_entry_s mft_mft = { + .type = MFT, + .pmft = (void *) system_query_manifest, +}; + +static const px4_mft_s mft = { + .nmft = 2, + .mfts = { + &mtd_mft, + &mft_mft, + } +}; + +const px4_mft_s *board_get_manifest(void) +{ + return &mft; +} diff --git a/boards/auterion/fmu-v6x/src/sdio.c b/boards/auterion/fmu-v6x/src/sdio.c new file mode 100644 index 0000000000..869d757756 --- /dev/null +++ b/boards/auterion/fmu-v6x/src/sdio.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "board_config.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(GPIO_SDMMC1_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + + if (sdio_dev && present != g_sd_inserted) { + sdio_mediachange(sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDMMC1_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + sdio_dev = sdio_initialize(SDIO_SLOTNO); + + if (!sdio_dev) { + syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev); + + if (ret != OK) { + syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(sdio_dev, true); +#endif + + return OK; +} + +#endif /* CONFIG_MMCSD */ diff --git a/boards/auterion/fmu-v6x/src/spi.cpp b/boards/auterion/fmu-v6x/src/spi.cpp new file mode 100644 index 0000000000..b1100edacf --- /dev/null +++ b/boards/auterion/fmu-v6x/src/spi.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** + * + * Copyright (C) 2020, 2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + 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}), + }, {GPIO::PortF, GPIO::Pin4}), + initSPIBus(SPI::Bus::SPI3, { + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}), + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}), + }, {GPIO::PortE, GPIO::Pin7}), + // initSPIBus(SPI::Bus::SPI4, { + // // no devices + // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h + // }, {GPIO::PortG, GPIO::Pin8}), + initSPIBus(SPI::Bus::SPI5, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7}) + }), + initSPIBusExternal(SPI::Bus::SPI6, { + initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}), + initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/auterion/fmu-v6x/src/timer_config.cpp b/boards/auterion/fmu-v6x/src/timer_config.cpp new file mode 100644 index 0000000000..a1c458d9eb --- /dev/null +++ b/boards/auterion/fmu-v6x/src/timer_config.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* Timer allocation + * + * TIM5_CH4 T FMU_CH1 + * TIM5_CH3 T FMU_CH2 + * TIM5_CH2 T FMU_CH3 + * TIM5_CH1 T FMU_CH4 + * + * TIM4_CH2 T FMU_CH5 + * TIM4_CH3 T FMU_CH6 + * + * TIM12_CH1 T FMU_CH7 + * TIM12_CH2 T FMU_CH8 + * + * TIM1_CH2 T FMU_CAP1 < Capture + * TIM1_CH3 T SPI2_DRDY2_ISM330_INT2 < Capture or GPIO INT + * TIM1_CH1 T SPIX_SYNC > Pulse or GPIO strobe + * + * TIM14_CH1 T BUZZER_1 - Driven by other driver + * TIM8_CH1_IN T FMU_PPM_INPUT - Sampled byt HRT by other driver + */ + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer5, DMA{DMA::Index1}), + initIOTimer(Timer::Timer4, DMA{DMA::Index1}), + initIOTimer(Timer::Timer12), + initIOTimer(Timer::Timer1), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel4}, {GPIO::PortI, GPIO::Pin0}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel3}, {GPIO::PortH, GPIO::Pin12}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel2}, {GPIO::PortH, GPIO::Pin11}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel1}, {GPIO::PortH, GPIO::Pin10}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel2}, {GPIO::PortD, GPIO::Pin13}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel3}, {GPIO::PortD, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel1}, {GPIO::PortH, GPIO::Pin6}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel2}, {GPIO::PortH, GPIO::Pin9}), + initIOTimerChannelCapture(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/auterion/fmu-v6x/uuv.px4board b/boards/auterion/fmu-v6x/uuv.px4board new file mode 100644 index 0000000000..3a7b00f13d --- /dev/null +++ b/boards/auterion/fmu-v6x/uuv.px4board @@ -0,0 +1,23 @@ +CONFIG_MODULES_AIRSPEED_SELECTOR=n +CONFIG_MODULES_FLIGHT_MODE_MANAGER=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_POS_CONTROL=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_LAND_DETECTOR=n +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=n +CONFIG_MODULES_MC_ATT_CONTROL=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n +CONFIG_MODULES_MC_POS_CONTROL=n +CONFIG_MODULES_MC_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_MODULES_ROVER_ACKERMANN=n +CONFIG_MODULES_ROVER_DIFFERENTIAL=n +CONFIG_MODULES_ROVER_MECANUM=n +CONFIG_MODULES_SPACECRAFT=n +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_UUV_ATT_CONTROL=y +CONFIG_MODULES_UUV_POS_CONTROL=y diff --git a/boards/auterion/fmu-v6x/zenoh.px4board b/boards/auterion/fmu-v6x/zenoh.px4board new file mode 100644 index 0000000000..6827430786 --- /dev/null +++ b/boards/auterion/fmu-v6x/zenoh.px4board @@ -0,0 +1,6 @@ +# CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE is not set +CONFIG_DRIVERS_UAVCAN=n +CONFIG_MODULES_UXRCE_DDS_CLIENT=n +CONFIG_SYSTEMCMDS_SD_BENCH=n +CONFIG_SYSTEMCMDS_I2CDETECT=n +CONFIG_MODULES_ZENOH=y diff --git a/boards/av/x-v1/default.px4board b/boards/av/x-v1/default.px4board index 5777261431..9692767d54 100644 --- a/boards/av/x-v1/default.px4board +++ b/boards/av/x-v1/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/beaglebone/blue/default.px4board b/boards/beaglebone/blue/default.px4board index 155e2fb7d1..42148e5013 100644 --- a/boards/beaglebone/blue/default.px4board +++ b/boards/beaglebone/blue/default.px4board @@ -14,6 +14,7 @@ CONFIG_DRIVERS_GPS=y CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y +CONFIG_DRIVERS_LINUX_PWM_OUT=y CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y @@ -30,8 +31,8 @@ CONFIG_MODULES_EVENTS=y CONFIG_MODULES_FLIGHT_MODE_MANAGER=y CONFIG_MODULES_FW_ATT_CONTROL=y CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y -CONFIG_MODULES_FW_MODE_MANAGER=y CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y CONFIG_MODULES_FW_RATE_CONTROL=y CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y diff --git a/boards/bluerobotics/navigator/init/rc.board_defaults b/boards/bluerobotics/navigator/init/rc.board_defaults index 18dc930ba7..ca136db1e3 100644 --- a/boards/bluerobotics/navigator/init/rc.board_defaults +++ b/boards/bluerobotics/navigator/init/rc.board_defaults @@ -11,3 +11,7 @@ param set BAT1_V_DIV 5.7 # Always keep current config param set SYS_AUTOCONFIG 0 + +# PCA9685 PWM Out defaults +param set-default PCA9685_EN_BUS 4 +param set-default PCA9685_I2C_ADDR 64 diff --git a/boards/bluerobotics/navigator/init/rc.board_sensors b/boards/bluerobotics/navigator/init/rc.board_sensors index 411995664b..790099d8af 100644 --- a/boards/bluerobotics/navigator/init/rc.board_sensors +++ b/boards/bluerobotics/navigator/init/rc.board_sensors @@ -28,7 +28,7 @@ then echo "ads1115 not found." fi -if ! pca9685_pwm_out start -a 0x40 -b 4 +if ! pca9685_pwm_out start then echo "pca9685_pwm_out not found." fi diff --git a/boards/corvon/743v1/extras/corvon_743v1_bootloader.bin b/boards/corvon/743v1/extras/corvon_743v1_bootloader.bin index a920927833..0875784c2c 100644 Binary files a/boards/corvon/743v1/extras/corvon_743v1_bootloader.bin and b/boards/corvon/743v1/extras/corvon_743v1_bootloader.bin differ diff --git a/boards/corvon/743v1/firmware.prototype b/boards/corvon/743v1/firmware.prototype index d4b0d6af34..4adb42ad91 100644 --- a/boards/corvon/743v1/firmware.prototype +++ b/boards/corvon/743v1/firmware.prototype @@ -1,5 +1,5 @@ { - "board_id": 1188, + "board_id": 1189, "magic": "PX4FWv1", "description": "Firmware for the CORVON743v1 board", "image": "", diff --git a/boards/corvon/743v1/src/hw_config.h b/boards/corvon/743v1/src/hw_config.h index 6e63d9b9a7..b773631093 100644 --- a/boards/corvon/743v1/src/hw_config.h +++ b/boards/corvon/743v1/src/hw_config.h @@ -96,7 +96,7 @@ #define INTERFACE_USART 1 #define INTERFACE_USART_CONFIG "/dev/ttyS0,115200" #define BOOT_DELAY_ADDRESS 0x000001a0 -#define BOARD_TYPE 1188 +#define BOARD_TYPE 1189 #define BOARD_FLASH_SECTORS (14) #define BOARD_FLASH_SIZE (16 * 128 * 1024) #define APP_RESERVATION_SIZE (1 * 128 * 1024) diff --git a/boards/cuav/fmu-v6x/default.px4board b/boards/cuav/fmu-v6x/default.px4board index 3458e2735d..924d74fb03 100644 --- a/boards/cuav/fmu-v6x/default.px4board +++ b/boards/cuav/fmu-v6x/default.px4board @@ -30,7 +30,6 @@ CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_DRIVERS_RC_INPUT=y @@ -61,7 +60,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 diff --git a/boards/cuav/fmu-v6x/init/rc.board_defaults b/boards/cuav/fmu-v6x/init/rc.board_defaults index 2274fe9c17..31fa79a42b 100644 --- a/boards/cuav/fmu-v6x/init/rc.board_defaults +++ b/boards/cuav/fmu-v6x/init/rc.board_defaults @@ -3,13 +3,6 @@ # board specific defaults #------------------------------------------------------------------------------ -# By disabling all 3 INA modules, we use the -# i2c_launcher instead. -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - - # Mavlink ethernet (CFG 1000) param set-default MAV_2_CONFIG 1000 param set-default MAV_2_BROADCAST 1 diff --git a/boards/cuav/fmu-v6x/init/rc.board_sensors b/boards/cuav/fmu-v6x/init/rc.board_sensors index e782fd6b54..5b6e2dd8f8 100644 --- a/boards/cuav/fmu-v6x/init/rc.board_sensors +++ b/boards/cuav/fmu-v6x/init/rc.board_sensors @@ -66,15 +66,15 @@ then fi fi +iim42652 -R 6 -s -C 32768 start bmi088 -A -R 4 -s start bmi088 -G -R 4 -s start -iim42652 -R 6 -s start icm45686 -R 2 -s start rm3100 -I -b 4 start -icp201xx -I -a 0x64 start bmp581 -b 2 -X -a 0x47 start +icp201xx -I -a 0x64 start # External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer) ist8310 -X -b 1 -R 10 start diff --git a/boards/cuav/fmu-v6x/src/CMakeLists.txt b/boards/cuav/fmu-v6x/src/CMakeLists.txt index a604f95974..36c8aec516 100644 --- a/boards/cuav/fmu-v6x/src/CMakeLists.txt +++ b/boards/cuav/fmu-v6x/src/CMakeLists.txt @@ -71,6 +71,5 @@ else() nuttx_arch # sdio nuttx_drivers # sdio px4_layer - platform_gpio_mcp23009 ) endif() diff --git a/boards/cuav/fmu-v6x/src/init.cpp b/boards/cuav/fmu-v6x/src/init.cpp index 8808576638..5ca52e8076 100644 --- a/boards/cuav/fmu-v6x/src/init.cpp +++ b/boards/cuav/fmu-v6x/src/init.cpp @@ -74,7 +74,6 @@ #include #include #include -#include /**************************************************************************** * Pre-Processor Definitions @@ -286,13 +285,6 @@ __EXPORT int board_app_initialize(uintptr_t arg) # endif /* CONFIG_MMCSD */ - ret = mcp23009_register_gpios(3, 0x25); - - if (ret != OK) { - led_on(LED_RED); - return ret; - } - #endif /* !defined(BOOTLOADER) */ return OK; diff --git a/boards/cuav/nora/default.px4board b/boards/cuav/nora/default.px4board index b0db9a1735..f2f52f8b1a 100644 --- a/boards/cuav/nora/default.px4board +++ b/boards/cuav/nora/default.px4board @@ -27,7 +27,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/cuav/nora/src/board_config.h b/boards/cuav/nora/src/board_config.h index 56dbf9cc8c..0f289730d2 100644 --- a/boards/cuav/nora/src/board_config.h +++ b/boards/cuav/nora/src/board_config.h @@ -127,8 +127,8 @@ #define GPIO_VDD_5V_RC_EN /* PG5 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN5) #define GPIO_VDD_3V3_SD_CARD_EN /* PG7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN7) -#define GPIO_VDD_5V_HIPOWER_OC /* PJ3 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTJ|GPIO_PIN3) -#define GPIO_nVDD_5V_PERIPH_OC /* PJ4 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTJ|GPIO_PIN4) +#define GPIO_VDD_5V_HIPOWER_OC /* PJ3 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTJ|GPIO_PIN3) +#define GPIO_nVDD_5V_PERIPH_OC /* PJ4 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTJ|GPIO_PIN4) /* Power switch controls ******************************************************/ #define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_nVDD_5V_PERIPH_EN, (on_true)) diff --git a/boards/cuav/x25-evo/default.px4board b/boards/cuav/x25-evo/default.px4board index a5cd2829ca..8c38f593a4 100644 --- a/boards/cuav/x25-evo/default.px4board +++ b/boards/cuav/x25-evo/default.px4board @@ -28,7 +28,6 @@ CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_DRIVERS_SAFETY_BUTTON=y diff --git a/boards/cuav/x25-evo/init/rc.board_defaults b/boards/cuav/x25-evo/init/rc.board_defaults index 8ef1ad0b40..bae8be59e1 100644 --- a/boards/cuav/x25-evo/init/rc.board_defaults +++ b/boards/cuav/x25-evo/init/rc.board_defaults @@ -15,10 +15,6 @@ param set-default MAV_2_UDP_PRT 14550 param set-default BAT1_V_DIV 18 param set-default BAT1_A_PER_V 24 -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - param set-default USB_MAV_MODE 5 param set-default UAVCAN_SUB_GPS 1 diff --git a/boards/cuav/x7pro/default.px4board b/boards/cuav/x7pro/default.px4board index eafa964372..b186910f98 100644 --- a/boards/cuav/x7pro/default.px4board +++ b/boards/cuav/x7pro/default.px4board @@ -27,7 +27,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/cubepilot/cubeorange/default.px4board b/boards/cubepilot/cubeorange/default.px4board index 83b60c54c1..59500b7c08 100644 --- a/boards/cubepilot/cubeorange/default.px4board +++ b/boards/cubepilot/cubeorange/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/cubepilot/cubeorangeplus/default.px4board b/boards/cubepilot/cubeorangeplus/default.px4board index f241768a2a..037449a578 100644 --- a/boards/cubepilot/cubeorangeplus/default.px4board +++ b/boards/cubepilot/cubeorangeplus/default.px4board @@ -25,7 +25,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/cubepilot/cubeyellow/default.px4board b/boards/cubepilot/cubeyellow/default.px4board index 28e3bc6f86..8be8d9c4d1 100644 --- a/boards/cubepilot/cubeyellow/default.px4board +++ b/boards/cubepilot/cubeyellow/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/gearup/airbrainh743/bootloader.px4board b/boards/gearup/airbrainh743/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/gearup/airbrainh743/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/gearup/airbrainh743/default.px4board b/boards/gearup/airbrainh743/default.px4board new file mode 100644 index 0000000000..1af794b76c --- /dev/null +++ b/boards/gearup/airbrainh743/default.px4board @@ -0,0 +1,86 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROOT_PATH="/fs/flash" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS5" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS2" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS1" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_DPS310=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_COMMON_LIGHT=y +CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y +CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y +CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y +CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_COMMON_OPTICAL_FLOW=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set +# CONFIG_EKF2_AUXVEL is not set +# CONFIG_EKF2_BARO_COMPENSATION is not set +# CONFIG_EKF2_DRAG_FUSION is not set +# CONFIG_EKF2_GNSS_YAW is not set +# CONFIG_EKF2_SIDESLIP is not set +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin b/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin new file mode 100755 index 0000000000..1363314125 Binary files /dev/null and b/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin differ diff --git a/boards/gearup/airbrainh743/firmware.prototype b/boards/gearup/airbrainh743/firmware.prototype new file mode 100644 index 0000000000..5fe46e9523 --- /dev/null +++ b/boards/gearup/airbrainh743/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 1209, + "magic": "PX4FWv1", + "description": "Firmware for the AirBrainH743 by Gear Up", + "image": "", + "build_time": 0, + "summary": "AirBrainH743", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1966080, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/gearup/airbrainh743/init/rc.board_defaults b/boards/gearup/airbrainh743/init/rc.board_defaults new file mode 100644 index 0000000000..4ef2ce41ee --- /dev/null +++ b/boards/gearup/airbrainh743/init/rc.board_defaults @@ -0,0 +1,17 @@ +#!/bin/sh +# +# AirBrainH743 board specific defaults +#------------------------------------------------------------------------------ + +# Battery voltage divider and current scale +param set-default BAT1_V_DIV 15.0 +param set-default BAT1_A_PER_V 101.0 + +# system_power unavailable +param set-default CBRK_SUPPLY_CHK 894281 + +param set-default IMU_GYRO_RATEMAX 2000 + +# W25N NAND flash with littlefs (128 MB): larger buffer, auto-rotate +set LOGGER_BUF 32 +param set-default SDLOG_DIRS_MAX 3 diff --git a/boards/gearup/airbrainh743/init/rc.board_extras b/boards/gearup/airbrainh743/init/rc.board_extras new file mode 100644 index 0000000000..43021eb51a --- /dev/null +++ b/boards/gearup/airbrainh743/init/rc.board_extras @@ -0,0 +1,6 @@ +#!/bin/sh +# +# AirBrainH743 specific board extras init +#------------------------------------------------------------------------------ + +# No extras configured by default diff --git a/boards/gearup/airbrainh743/init/rc.board_sensors b/boards/gearup/airbrainh743/init/rc.board_sensors new file mode 100644 index 0000000000..06eac2ea34 --- /dev/null +++ b/boards/gearup/airbrainh743/init/rc.board_sensors @@ -0,0 +1,16 @@ +#!/bin/sh +# +# AirBrainH743 specific board sensors init +#------------------------------------------------------------------------------ + +board_adc start + +# Internal SPI bus IMU - ICM42688P (Invensensev3) +icm42688p -R 2 -b 1 -s start + +# Internal I2C bus barometer - DPS310 @ 0x76 (118 decimal) +dps310 -I -a 118 start + +# Internal I2C bus magnetometer - LIS2MDL @ 0x1E (30 decimal) +# Using iis2mdc driver (functionally equivalent to LIS2MDL) +iis2mdc -I -R 2 -a 30 start diff --git a/boards/gearup/airbrainh743/nuttx-config/Kconfig b/boards/gearup/airbrainh743/nuttx-config/Kconfig new file mode 100644 index 0000000000..9cab44437b --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/Kconfig @@ -0,0 +1,3 @@ +# +# Board-specific Kconfig for AirBrainH743 +# diff --git a/boards/gearup/airbrainh743/nuttx-config/bootloader/defconfig b/boards/gearup/airbrainh743/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..a12f599183 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/bootloader/defconfig @@ -0,0 +1,89 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_SPI_EXCHANGE is not set +# CONFIG_STM32H7_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/gearup/airbrainh743/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=22114 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_PRODUCTID=0x004b +CONFIG_CDCACM_PRODUCTSTR="AirBrainH743 BL" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x3162 +CONFIG_CDCACM_VENDORSTR="Gear Up" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_USART1=y +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_TXBUFSIZE=300 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/gearup/airbrainh743/nuttx-config/include/board.h b/boards/gearup/airbrainh743/nuttx-config/include/board.h new file mode 100644 index 0000000000..56aafd3eaa --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/include/board.h @@ -0,0 +1,346 @@ +/************************************************************************************ + * nuttx-config/include/board.h + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#ifndef __NUTTX_CONFIG_AIRBRAINH743_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_AIRBRAINH743_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The AirBrainH743 board provides the following clock sources: + * + * X1: 8 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 8000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 8,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(5) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 5) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(2) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 + +/* FDCAN 1 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* LED definitions ******************************************************************/ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Alternate function pin selections ************************************************/ + +/* USART1 - Debug (PA9 TX, PA10 RX) */ +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PA10 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ + +/* USART2 - RC input (PD5 TX, PD6 RX) */ +#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ + +/* USART3 - DJI/MSP (PD8 TX, PD9 RX) */ +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +/* UART4 - General (PB9 TX, PB8 RX) */ +#define GPIO_UART4_RX GPIO_UART4_RX_3 /* PB8 */ +#define GPIO_UART4_TX GPIO_UART4_TX_3 /* PB9 */ + +/* UART5 - Companion (PB13 TX, PB12 RX) */ +#define GPIO_UART5_RX GPIO_UART5_RX_1 /* PB12 */ +#define GPIO_UART5_TX GPIO_UART5_TX_1 /* PB13 */ + +/* UART7 - ESC telemetry (PE8 TX, PE7 RX) */ +#define GPIO_UART7_RX GPIO_UART7_RX_3 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ + +/* UART8 - GPS (PE1 TX, PE0 RX) */ +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* SPI + * + * SPI1: IMU (PA5 SCK, PA6 MISO, PA7 MOSI) + * SPI2: W25N Flash (PD3 SCK, PB14 MISO, PC3 MOSI) + * SPI4: External (PE12 SCK, PE5 MISO, PE6 MOSI) + */ + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 /* PA7 */ +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 /* PA5 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_3 /* PC3 */ +#define GPIO_SPI2_SCK GPIO_SPI2_SCK_5 /* PD3 */ + +#define GPIO_SPI4_MISO GPIO_SPI4_MISO_2 /* PE5 */ +#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_2 /* PE6 */ +#define GPIO_SPI4_SCK GPIO_SPI4_SCK_1 /* PE12 */ + +/* I2C + * + * I2C1: Internal (PB6 SCL, PB7 SDA) + * I2C4: External (PD12 SCL, PD13 SDA) + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + +#define GPIO_I2C4_SCL GPIO_I2C4_SCL_1 /* PD12 */ +#define GPIO_I2C4_SDA GPIO_I2C4_SDA_1 /* PD13 */ + +#define GPIO_I2C4_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN12) +#define GPIO_I2C4_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN13) + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PD0 + */ + + +#endif /*__NUTTX_CONFIG_AIRBRAINH743_INCLUDE_BOARD_H */ diff --git a/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..2bd6646a83 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/include/board_dma_map.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +/* DMA mapping for SPI1 (IMU) */ +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1:37 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1:38 */ + +/* DMA mapping for SPI2 (W25N Flash) */ +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* DMA1:39 */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* DMA1:40 */ diff --git a/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..a31ca060ed --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/nsh/defconfig @@ -0,0 +1,258 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/gearup/airbrainh743/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=512 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0050 +CONFIG_CDCACM_PRODUCTSTR="AirBrainH743" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x3162 +CONFIG_CDCACM_VENDORSTR="Gear Up" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1 +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_W25N=y +CONFIG_W25N_SPIFREQUENCY=104000000 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_DMAMUX1=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C4=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_HSECLOCK=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI2=y +CONFIG_STM32H7_SPI2_DMA=y +CONFIG_STM32H7_SPI2_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI4=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM2=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_TIM8=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGTSTP=y +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART5_BAUD=57600 +CONFIG_UART5_RXBUFSIZE=600 +CONFIG_UART5_TXBUFSIZE=1500 +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_TXBUFSIZE=1500 +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_SERIAL_CONSOLE=y +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=1500 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=600 +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..fb877cc443 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,213 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Durandal-v1 uses an STM32H743II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Durandal has a Switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the swiutch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..a01eb2e2a8 --- /dev/null +++ b/boards/gearup/airbrainh743/nuttx-config/scripts/script.ld @@ -0,0 +1,228 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The board uses an STM32H743II and has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * There's a switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the switch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1792K /* params in last sector */ + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/gearup/airbrainh743/src/CMakeLists.txt b/boards/gearup/airbrainh743/src/CMakeLists.txt new file mode 100644 index 0000000000..63d047cdea --- /dev/null +++ b/boards/gearup/airbrainh743/src/CMakeLists.txt @@ -0,0 +1,67 @@ +############################################################################ +# +# Copyright (c) 2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_library(drivers_board + bootloader_main.c + usb.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + i2c.cpp + init.c + led.c + spi.cpp + timer_config.cpp + usb.c + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/gearup/airbrainh743/src/board_config.h b/boards/gearup/airbrainh743/src/board_config.h new file mode 100644 index 0000000000..f6317c8c0f --- /dev/null +++ b/boards/gearup/airbrainh743/src/board_config.h @@ -0,0 +1,223 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * AirBrainH743 (Gear Up) internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* Enable small flash logging support (for W25N NAND flash) */ +#ifdef CONFIG_MTD_W25N +# define BOARD_SMALL_FLASH_LOGGING 1 +#endif + +/* LEDs are active low + * STAT RGB LED: + * PB15 = Blue + * PD11 = Green + * PD15 = Red + * BAT LED (orange): hardwired to power input + */ +#define GPIO_nLED_BLUE /* PB15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN15) +#define GPIO_nLED_GREEN /* PD11 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN11) +#define GPIO_nLED_RED /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN15) + +#define BOARD_HAS_CONTROL_STATUS_LEDS 1 +#define BOARD_OVERLOAD_LED LED_RED +#define BOARD_ARMED_STATE_LED LED_GREEN + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ +#define ADC1_CH(n) (n) + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ +#define PX4_ADC_GPIO \ + /* PC4 */ GPIO_ADC12_INP4, \ + /* PC5 */ GPIO_ADC12_INP8 + +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PC4 */ ADC1_CH(4) +#define ADC_BATTERY_CURRENT_CHANNEL /* PC5 */ ADC1_CH(8) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL)) + + +/* Define Battery Voltage Divider and A per V + */ +#define BOARD_BATTERY1_V_DIV (15.0f) +#define BOARD_BATTERY1_A_PER_V (101.0f) + + +/* PWM + * 8 PWM outputs for motors + 1 for LED strip + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 9 +#define DIRECT_INPUT_TIMER_CHANNELS 9 + +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + + +/* Tone alarm output (directly connected to transistor switch of external buzzer) + * + * GPIO mode only (active buzzer) - passive buzzer with different tones is not + * supported because PA15 can only use TIM2, which is also used for motor outputs + * M7 (PB10, TIM2_CH3) and M8 (PB11, TIM2_CH4). The PWM tone alarm driver changes + * the timer's prescaler and auto-reload registers (shared across all channels), + * which would affect M7/M8 PWM frequency during tone playback. + */ +#define GPIO_TONE_ALARM_IDLE /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) +#define GPIO_TONE_ALARM_GPIO /* PA15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN15) + + +/* ICM42688P FSYNC - directly connected to IMU via GPIO (no timer). + * The driver clears TMST_FSYNC_EN and FIFO_TMST_FSYNC_EN, so FSYNC is unused. + * This GPIO is kept low to prevent spurious triggers. + */ +#define GPIO_42688P_FSYNC /* PC7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN7) + + +/* USB OTG FS + * + * PD0 VBUS sensing (active high input) + */ +#define GPIO_OTGFS_VBUS /* PD0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTD|GPIO_PIN0) + + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + + +/* + * Serial Port Mapping: + * + * UART Device Pins Function + * ---- ------ ---- -------- + * USART1 /dev/ttyS0 PA9/PA10 Console/Debug + * USART2 /dev/ttyS1 PD5/PD6 RC Input + * USART3 /dev/ttyS2 PD8/PD9 TEL4 (DJI/MSP) + * UART4 /dev/ttyS3 PA0/PA1 TEL1 + * UART5 /dev/ttyS4 PB13/PB12 TEL2 + * UART7 /dev/ttyS5 PE8/PE7 TEL3 (ESC Telemetry) + * UART8 /dev/ttyS6 PE1/PE0 GPS1 + */ + +/* RC Serial port - USART2 (PD5/PD6) */ +#define RC_SERIAL_PORT "/dev/ttyS1" +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ +#define BOARD_HAS_ON_RESET 1 + + +#define PX4_GPIO_INIT_LIST { \ + PX4_ADC_GPIO, \ + GPIO_nLED_RED, \ + GPIO_nLED_GREEN, \ + GPIO_nLED_BLUE, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_42688P_FSYNC, \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define BOARD_NUM_IO_TIMERS 4 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +/* Parameters stored in internal flash */ +#define FLASH_BASED_PARAMS + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/gearup/airbrainh743/src/bootloader_main.c b/boards/gearup/airbrainh743/src/bootloader_main.c new file mode 100644 index 0000000000..996370b00e --- /dev/null +++ b/boards/gearup/airbrainh743/src/bootloader_main.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * AirBrainH743-specific early startup code for bootloader + */ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +__EXPORT void board_on_reset(int status) {} + +__EXPORT void stm32_boardinitialize(void) +{ + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + return 0; +} + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/gearup/airbrainh743/src/hw_config.h b/boards/gearup/airbrainh743/src/hw_config.h new file mode 100644 index 0000000000..38e16b4059 --- /dev/null +++ b/boards/gearup/airbrainh743/src/hw_config.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,57600" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 1209 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (14) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 8 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +/* Reserve 128KB (1 sector) at end of flash for parameters */ +#define APP_RESERVATION_SIZE (1 * 128 * 1024) + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 diff --git a/boards/gearup/airbrainh743/src/i2c.cpp b/boards/gearup/airbrainh743/src/i2c.cpp new file mode 100644 index 0000000000..26e33dc7fe --- /dev/null +++ b/boards/gearup/airbrainh743/src/i2c.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * I2C bus configuration for AirBrainH743 + * + * I2C1: Internal bus - PB6 (SCL), PB7 (SDA) + * Devices: DPS310 baro @ 0x76, LIS2MDL compass @ 0x1E + * I2C4: External bus - PD12 (SCL), PD13 (SDA) + */ + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), + initI2CBusExternal(4), +}; diff --git a/boards/gearup/airbrainh743/src/init.c b/boards/gearup/airbrainh743/src/init.c new file mode 100644 index 0000000000..b2d2c23b52 --- /dev/null +++ b/boards/gearup/airbrainh743/src/init.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * AirBrainH743-specific early startup code. + */ + +#include "board_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(FLASH_BASED_PARAMS) +#include +#endif + +#ifdef CONFIG_MTD_W25N +extern FAR struct mtd_dev_s *w25n_initialize(FAR struct spi_dev_s *dev, uint32_t spi_devid); +#endif + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. + * + ************************************************************************************/ +__EXPORT void stm32_boardinitialize(void) +{ + /* Reset PWM first thing */ + board_on_reset(-1); + + /* configure LEDs */ + board_autoled_initialize(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Need hrt running before using the ADC */ + px4_platform_init(); + + /* configure SPI interfaces */ + stm32_spiinitialize(); + + /* configure the DMA allocator */ + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_off(LED_GREEN); + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + +#ifdef CONFIG_MTD_W25N + /* Initialize W25N01GV NAND Flash on SPI2 */ + struct spi_dev_s *spi2 = stm32_spibus_initialize(2); + + if (!spi2) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI2 for W25N\n"); + led_on(LED_RED); + + } else { + struct mtd_dev_s *mtd = w25n_initialize(spi2, 0); + + if (!mtd) { + syslog(LOG_ERR, "[boot] FAILED to initialize W25N MTD driver\n"); + led_on(LED_RED); + + } else { + int ret = register_mtddriver("/dev/mtd0", mtd, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to register MTD driver: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); + +#ifdef CONFIG_FS_LITTLEFS + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, NULL); + + if (ret == 0) { + /* Verify the filesystem is usable by creating a test file */ + int fd = open(CONFIG_BOARD_ROOT_PATH "/.mount_test", O_CREAT | O_WRONLY | O_TRUNC); + + if (fd >= 0) { + close(fd); + unlink(CONFIG_BOARD_ROOT_PATH "/.mount_test"); + + } else { + syslog(LOG_WARNING, "[boot] littlefs mounted but not usable, reformatting\n"); + nx_umount2(CONFIG_BOARD_ROOT_PATH, 0); + ret = -1; + } + } + + if (ret < 0) { + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, "forceformat"); + } + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] LittleFS mounted at %s\n", CONFIG_BOARD_ROOT_PATH); + } + +#endif + } + } + } + +#endif + +#if defined(FLASH_BASED_PARAMS) + /* Initialize parameters in internal flash (sector 15, 128KB at 0x081E0000) */ + static sector_descriptor_t params_sector_map[] = { + {15, 128 * 1024, 0x081E0000}, + {0, 0, 0}, + }; + + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + led_on(LED_RED); + } + +#endif + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + return OK; +} diff --git a/boards/gearup/airbrainh743/src/led.c b/boards/gearup/airbrainh743/src/led.c new file mode 100644 index 0000000000..016ef9f822 --- /dev/null +++ b/boards/gearup/airbrainh743/src/led.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // Indexed by BOARD_LED_RED + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_RED, // LED_RED + GPIO_nLED_GREEN, // LED_GREEN + GPIO_nLED_BLUE, // LED_BLUE +}; + +#endif + +__EXPORT void led_init(void) +{ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on (active low LEDs) */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (led < (int)(sizeof(g_ledmap) / sizeof(g_ledmap[0])) && g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE: + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/gearup/airbrainh743/src/spi.cpp b/boards/gearup/airbrainh743/src/spi.cpp new file mode 100644 index 0000000000..05559c44d2 --- /dev/null +++ b/boards/gearup/airbrainh743/src/spi.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +/* + * SPI bus configuration for AirBrainH743 + * + * SPI1: IMU (Invensensev3/ICM42688P) - PA5 SCK, PA6 MISO, PA7 MOSI, PA3 CS + * SPI2: W25N Flash - PD3 SCK, PB14 MISO, PC3 MOSI, PD4 CS + * SPI4: External/AUX - PE12 SCK, PE5 MISO, PE6 MOSI + */ + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortA, GPIO::Pin3}), + }), + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin4}), // W25N Flash + }), + initSPIBusExternal(SPI::Bus::SPI4, { + initSPIConfigExternal(SPI::CS{GPIO::PortB, GPIO::Pin3}), // User 1 GPIO as chip select + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/gearup/airbrainh743/src/timer_config.cpp b/boards/gearup/airbrainh743/src/timer_config.cpp new file mode 100644 index 0000000000..2fcea89362 --- /dev/null +++ b/boards/gearup/airbrainh743/src/timer_config.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* + * PWM output configuration for AirBrainH743 + * + * M1: PE14 (TIM1_CH4) + * M2: PE13 (TIM1_CH3) + * M3: PE11 (TIM1_CH2) + * M4: PE9 (TIM1_CH1) + * M5: PB0 (TIM3_CH3) + * M6: PB1 (TIM3_CH4) + * M7: PB10 (TIM2_CH3) + * M8: PB11 (TIM2_CH4) + * M9: PA2 (TIM5_CH3) - LED strip + * + * Note: TIM2 is shared with buzzer pin PA15 (TIM2_CH1). The buzzer is disabled + * by default because the tone alarm driver would change the timer prescaler/ARR + * which affects M7/M8 PWM frequency. See board_config.h for details. + */ + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index1, DMA::Stream0, DMA::Channel6}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1, DMA::Stream2, DMA::Channel5}), + initIOTimer(Timer::Timer2, DMA{DMA::Index1, DMA::Stream6, DMA::Channel3}), + initIOTimer(Timer::Timer5), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), // M1 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}), // M2 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), // M3 + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), // M4 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), // M5 + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}), // M6 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel3}, {GPIO::PortB, GPIO::Pin10}), // M7 + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel4}, {GPIO::PortB, GPIO::Pin11}), // M8 + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel3}, {GPIO::PortA, GPIO::Pin2}), // M9 (LED) +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/gearup/airbrainh743/src/usb.c b/boards/gearup/airbrainh743/src/usb.c new file mode 100644 index 0000000000..a1c5d345dc --- /dev/null +++ b/boards/gearup/airbrainh743/src/usb.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (C) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +#include "board_config.h" +#include +#include +#include +#include + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO */ +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * + ************************************************************************************/ +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/boards/hkust/nxt-dual/default.px4board b/boards/hkust/nxt-dual/default.px4board index 242c36bea0..368ed08d6e 100644 --- a/boards/hkust/nxt-dual/default.px4board +++ b/boards/hkust/nxt-dual/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/hkust/nxt-v1/default.px4board b/boards/hkust/nxt-v1/default.px4board index 90ff7f0e1b..19e96ca44d 100644 --- a/boards/hkust/nxt-v1/default.px4board +++ b/boards/hkust/nxt-v1/default.px4board @@ -23,7 +23,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU6500=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_DRIVERS_ROBOCLAW=y diff --git a/boards/holybro/durandal-v1/default.px4board b/boards/holybro/durandal-v1/default.px4board index 1e27fa6da8..94fc1f8c00 100644 --- a/boards/holybro/durandal-v1/default.px4board +++ b/boards/holybro/durandal-v1/default.px4board @@ -23,7 +23,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20689=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig index 88d57ea784..feb176891d 100644 --- a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig +++ b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig @@ -16,36 +16,36 @@ # CONFIG_NSH_DISABLE_CAT is not set # CONFIG_NSH_DISABLE_CD is not set # CONFIG_NSH_DISABLE_CP is not set -# CONFIG_NSH_DISABLE_DATE is not set -# CONFIG_NSH_DISABLE_DF is not set +CONFIG_NSH_DISABLE_DATE=y +CONFIG_NSH_DISABLE_DF=y # CONFIG_NSH_DISABLE_ECHO is not set # CONFIG_NSH_DISABLE_ENV is not set # CONFIG_NSH_DISABLE_EXEC is not set # CONFIG_NSH_DISABLE_EXIT is not set -# CONFIG_NSH_DISABLE_EXPORT is not set -# CONFIG_NSH_DISABLE_FREE is not set -# CONFIG_NSH_DISABLE_GET is not set +CONFIG_NSH_DISABLE_EXPORT=y +CONFIG_NSH_DISABLE_FREE=y +CONFIG_NSH_DISABLE_GET=y # CONFIG_NSH_DISABLE_HELP is not set # CONFIG_NSH_DISABLE_ITEF is not set # CONFIG_NSH_DISABLE_KILL is not set # CONFIG_NSH_DISABLE_LOOPS is not set # CONFIG_NSH_DISABLE_LS is not set -# CONFIG_NSH_DISABLE_MKDIR is not set +CONFIG_NSH_DISABLE_MKDIR=y # CONFIG_NSH_DISABLE_MKFATFS is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set -# CONFIG_NSH_DISABLE_PRINTF is not set -# CONFIG_NSH_DISABLE_PS is not set -# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set -# CONFIG_NSH_DISABLE_PWD is not set +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PS=y +CONFIG_NSH_DISABLE_PSSTACKUSAGE=y +CONFIG_NSH_DISABLE_PWD=y # CONFIG_NSH_DISABLE_RM is not set -# CONFIG_NSH_DISABLE_RMDIR is not set +CONFIG_NSH_DISABLE_RMDIR=y # CONFIG_NSH_DISABLE_SEMICOLON is not set # CONFIG_NSH_DISABLE_SET is not set # CONFIG_NSH_DISABLE_SLEEP is not set # CONFIG_NSH_DISABLE_SOURCE is not set # CONFIG_NSH_DISABLE_TEST is not set -# CONFIG_NSH_DISABLE_TIME is not set +CONFIG_NSH_DISABLE_TIME=y # CONFIG_NSH_DISABLE_UMOUNT is not set # CONFIG_NSH_DISABLE_UNSET is not set # CONFIG_NSH_DISABLE_USLEEP is not set diff --git a/boards/holybro/kakuteh7/default.px4board b/boards/holybro/kakuteh7/default.px4board index a7ee05d56d..90327456f6 100644 --- a/boards/holybro/kakuteh7/default.px4board +++ b/boards/holybro/kakuteh7/default.px4board @@ -19,7 +19,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y diff --git a/boards/holybro/kakuteh7dualimu/default.px4board b/boards/holybro/kakuteh7dualimu/default.px4board index 8ce5497dae..8b32733d60 100644 --- a/boards/holybro/kakuteh7dualimu/default.px4board +++ b/boards/holybro/kakuteh7dualimu/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/holybro/kakuteh7mini/default.px4board b/boards/holybro/kakuteh7mini/default.px4board index c24c605342..5e2ea7fb71 100644 --- a/boards/holybro/kakuteh7mini/default.px4board +++ b/boards/holybro/kakuteh7mini/default.px4board @@ -19,7 +19,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y diff --git a/boards/holybro/kakuteh7v2/default.px4board b/boards/holybro/kakuteh7v2/default.px4board index 3135103cb6..11a83271c8 100644 --- a/boards/holybro/kakuteh7v2/default.px4board +++ b/boards/holybro/kakuteh7v2/default.px4board @@ -1,5 +1,6 @@ CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROOT_PATH="/fs/flash" CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS0" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS1" @@ -19,7 +20,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y diff --git a/boards/holybro/kakuteh7v2/init/rc.board_defaults b/boards/holybro/kakuteh7v2/init/rc.board_defaults index f2534d1709..de1eecef02 100644 --- a/boards/holybro/kakuteh7v2/init/rc.board_defaults +++ b/boards/holybro/kakuteh7v2/init/rc.board_defaults @@ -38,5 +38,6 @@ param set-default SYS_DM_BACKEND 1 # Ignore that there is no SD card param set-default COM_ARM_SDCARD 0 -# Disable logging -param set-default SDLOG_BACKEND 0 +# W25N NAND flash with littlefs (128 MB): larger buffer, auto-rotate +set LOGGER_BUF 32 +param set-default SDLOG_DIRS_MAX 3 diff --git a/boards/holybro/kakuteh7v2/nuttx-config/include/board.h b/boards/holybro/kakuteh7v2/nuttx-config/include/board.h index 0c96869f01..9d23954dab 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/include/board.h +++ b/boards/holybro/kakuteh7v2/nuttx-config/include/board.h @@ -99,7 +99,7 @@ * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz * * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz - * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1Q = PLL1_VCO/5 = 960 MHz / 5 = 192 MHz (SPI123 clock, max 200 MHz) * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz */ @@ -111,12 +111,12 @@ #define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) #define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) #define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) -#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(5) #define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) #define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) #define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) -#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 5) #define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) /* PLL2 */ @@ -227,9 +227,9 @@ #define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI -/* SPI123 clock source */ +/* SPI123 clock source - PLL1Q = 192 MHz for W25N NAND flash (max 104 MHz) */ -#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL1 /* SPI45 clock source */ @@ -281,17 +281,17 @@ #define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq) - * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s +/* 25 MHz Max for now, 25 mHz = PLL1Q/(2*div), div = PLL1Q/(2*freq) + * PLL1Q = 192 MHz, div = 192 / 50 = 3.84, round up to 4 for 24 MHz */ #if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) -# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else # define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif #if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) -# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else # define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif diff --git a/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h b/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h index d23e0d4120..1a84c705b7 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h +++ b/boards/holybro/kakuteh7v2/nuttx-config/include/board_dma_map.h @@ -33,6 +33,10 @@ #pragma once +/* SPI1 DMA for W25N NAND Flash */ +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1 */ + #define DMAMAP_SPI4_RX DMAMAP_DMA12_SPI4RX_1 /* DMA2 */ #define DMAMAP_SPI4_TX DMAMAP_DMA12_SPI4TX_1 /* DMA2 */ diff --git a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig index 7e8e989a85..d76ab2b90c 100644 --- a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig +++ b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig @@ -104,6 +104,10 @@ CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y CONFIG_FS_PROCFS_MAX_TASKS=64 CONFIG_FS_PROCFS_REGISTER=y CONFIG_FS_ROMFS=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_READ_SIZE_FACTOR=1 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=1 CONFIG_GRAN=y CONFIG_GRAN_INTR=y CONFIG_HAVE_CXX=y @@ -126,7 +130,9 @@ CONFIG_MTD=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_PROGMEM=y -CONFIG_MTD_RAMTRON=y +# CONFIG_MTD_RAMTRON is not set +CONFIG_MTD_W25N=y +CONFIG_W25N_SPIFREQUENCY=104000000 CONFIG_NAME_MAX=40 CONFIG_NSH_ARCHINIT=y CONFIG_NSH_ARGCAT=y @@ -135,7 +141,7 @@ CONFIG_NSH_CMDPARMS=y CONFIG_NSH_CROMFSETC=y CONFIG_NSH_LINELEN=128 CONFIG_NSH_MAXARGUMENTS=15 -CONFIG_NSH_MMCSDSPIPORTNO=1 +# CONFIG_NSH_MMCSDSPIPORTNO is not set CONFIG_NSH_NESTDEPTH=8 CONFIG_NSH_QUOTE=y CONFIG_NSH_ROMFSETC=y @@ -148,9 +154,6 @@ CONFIG_PREALLOC_TIMERS=50 CONFIG_PRIORITY_INHERITANCE=y CONFIG_PTHREAD_MUTEX_ROBUST=y CONFIG_PTHREAD_STACK_MIN=512 -CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 -CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 -CONFIG_RAMTRON_SETSPEED=y CONFIG_RAM_SIZE=245760 CONFIG_RAM_START=0x20010000 CONFIG_RAW_BINARY=y @@ -188,6 +191,7 @@ CONFIG_STM32H7_BKPSRAM=y CONFIG_STM32H7_DMA1=y CONFIG_STM32H7_DMA2=y CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_DMAMUX1=y CONFIG_STM32H7_FLOWCONTROL_BROKEN=y CONFIG_STM32H7_I2C1=y CONFIG_STM32H7_I2C_DYNTIMEO=y @@ -202,6 +206,8 @@ CONFIG_STM32H7_SDMMC1=y CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 CONFIG_STM32H7_SPI2=y CONFIG_STM32H7_SPI4=y CONFIG_STM32H7_SPI4_DMA=y diff --git a/boards/holybro/kakuteh7v2/src/board_config.h b/boards/holybro/kakuteh7v2/src/board_config.h index c8ec2fabe1..292dc706ce 100644 --- a/boards/holybro/kakuteh7v2/src/board_config.h +++ b/boards/holybro/kakuteh7v2/src/board_config.h @@ -59,6 +59,11 @@ # define BOARD_HAS_NBAT_V 1 # define BOARD_HAS_NBAT_I 1 +/* Enable small flash logging support (for W25N NAND flash) */ +#ifdef CONFIG_MTD_W25N +# define BOARD_SMALL_FLASH_LOGGING 1 +#endif + /* Holybro KakuteH7 GPIOs ************************************************************************/ /* LEDs are driven with push open drain to support Anode to 5V or 3.3V */ diff --git a/boards/holybro/kakuteh7v2/src/init.c b/boards/holybro/kakuteh7v2/src/init.c index bff6e6535a..5cc65b069d 100644 --- a/boards/holybro/kakuteh7v2/src/init.c +++ b/boards/holybro/kakuteh7v2/src/init.c @@ -59,6 +59,8 @@ #include #include #include +#include +#include #include #include #include @@ -79,6 +81,10 @@ # include #endif +#ifdef CONFIG_MTD_W25N +extern FAR struct mtd_dev_s *w25n_initialize(FAR struct spi_dev_s *dev, uint32_t spi_devid); +#endif + /**************************************************************************** * Pre-Processor Definitions @@ -231,14 +237,49 @@ __EXPORT int board_app_initialize(uintptr_t arg) led_on(LED_RED); } - /* Get the SPI port for the microSD slot */ - struct spi_dev_s *spi_dev = stm32_spibus_initialize(CONFIG_NSH_MMCSDSPIPORTNO); +#ifdef CONFIG_MTD_W25N + /* Initialize W25N01GV NAND Flash on SPI1 */ + struct spi_dev_s *spi1 = stm32_spibus_initialize(1); - if (!spi_dev) { - syslog(LOG_ERR, "[boot] FAILED to initialize SPI port %d\n", CONFIG_NSH_MMCSDSPIPORTNO); - led_on(LED_BLUE); + if (!spi1) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI1 for W25N\n"); + led_on(LED_RED); + + } else { + struct mtd_dev_s *mtd = w25n_initialize(spi1, 0); + + if (!mtd) { + syslog(LOG_ERR, "[boot] FAILED to initialize W25N MTD driver\n"); + led_on(LED_RED); + + } else { + int ret = register_mtddriver("/dev/mtd0", mtd, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to register MTD driver: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] W25N MTD registered at /dev/mtd0\n"); + +#ifdef CONFIG_FS_LITTLEFS + ret = nx_mount("/dev/mtd0", CONFIG_BOARD_ROOT_PATH, "littlefs", 0, "autoformat"); + + if (ret < 0) { + syslog(LOG_ERR, "[boot] FAILED to mount littlefs: %d\n", ret); + led_on(LED_RED); + + } else { + syslog(LOG_INFO, "[boot] LittleFS mounted at %s\n", CONFIG_BOARD_ROOT_PATH); + } + +#endif + } + } } +#endif + up_udelay(20); diff --git a/boards/holybro/kakuteh7v2/src/spi.cpp b/boards/holybro/kakuteh7v2/src/spi.cpp index a8ce482c5d..80f1896c5f 100644 --- a/boards/holybro/kakuteh7v2/src/spi.cpp +++ b/boards/holybro/kakuteh7v2/src/spi.cpp @@ -37,7 +37,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { - initSPIDevice(SPIDEV_MMCSD(0), SPI::CS{GPIO::PortA, GPIO::Pin4}) + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortA, GPIO::Pin4}) // W25N01GV NAND Flash }), initSPIBus(SPI::Bus::SPI2, { initSPIDevice(DRV_OSD_DEVTYPE_ATXXXX, SPI::CS{GPIO::PortB, GPIO::Pin12}), diff --git a/boards/holybro/pix32v5/default.px4board b/boards/holybro/pix32v5/default.px4board index 566d4dea3a..b97b164322 100644 --- a/boards/holybro/pix32v5/default.px4board +++ b/boards/holybro/pix32v5/default.px4board @@ -25,7 +25,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/matek/h743-mini/default.px4board b/boards/matek/h743-mini/default.px4board index 965fec5459..956e16e6f9 100644 --- a/boards/matek/h743-mini/default.px4board +++ b/boards/matek/h743-mini/default.px4board @@ -14,7 +14,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42605=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/matek/h743-slim/default.px4board b/boards/matek/h743-slim/default.px4board index 9cf0909725..29b5956a4d 100644 --- a/boards/matek/h743-slim/default.px4board +++ b/boards/matek/h743-slim/default.px4board @@ -17,7 +17,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42605=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/matek/h743/default.px4board b/boards/matek/h743/default.px4board index e61c9b6014..5f2b2c974e 100644 --- a/boards/matek/h743/default.px4board +++ b/boards/matek/h743/default.px4board @@ -16,7 +16,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42605=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/micoair/h743-aio/default.px4board b/boards/micoair/h743-aio/default.px4board index d6dd734283..1a5e79726a 100644 --- a/boards/micoair/h743-aio/default.px4board +++ b/boards/micoair/h743-aio/default.px4board @@ -26,18 +26,15 @@ CONFIG_COMMON_HYGROMETERS=y CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_BOSCH_BMI270=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA220=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y CONFIG_DRIVERS_PPS_CAPTURE=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y -CONFIG_DRIVERS_RC_INPUT=y CONFIG_DRIVERS_ROBOCLAW=y CONFIG_COMMON_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y diff --git a/boards/micoair/h743-lite/bootloader.px4board b/boards/micoair/h743-lite/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/micoair/h743-lite/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/micoair/h743-lite/default.px4board b/boards/micoair/h743-lite/default.px4board new file mode 100644 index 0000000000..372825ced9 --- /dev/null +++ b/boards/micoair/h743-lite/default.px4board @@ -0,0 +1,105 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_URT6="/dev/ttyS6" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS2" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS1" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS7" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" +CONFIG_BOARD_PARAM_FILE="/fs/microsd/params" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_GOERTEK_SPA06=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_ASP5033=y +CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_ETS=y +CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_MS4515=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_DRIVERS_POWER_MONITOR_INA220=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y +CONFIG_DRIVERS_PPS_CAPTURE=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_COMMON_RC=y +CONFIG_COMMON_RPM=y +CONFIG_DRIVERS_SMART_BATTERY_BATMON=y +CONFIG_DRIVERS_TAP_ESC=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_COMMON_UWB=y +CONFIG_COMMON_WIND_SENSOR=y +CONFIG_MODULES_AIRSHIP_ATT_CONTROL=y +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_POS_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_PAYLOAD_DELIVERER=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BL_UPDATE=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_DUMPFILE=y +CONFIG_SYSTEMCMDS_FAILURE=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SD_STRESS=y +CONFIG_SYSTEMCMDS_SERIAL_PASSTHRU=y +CONFIG_SYSTEMCMDS_SERIAL_TEST=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TESTS=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/micoair/h743-lite/extras/micoair_h743-lite_bootloader.bin b/boards/micoair/h743-lite/extras/micoair_h743-lite_bootloader.bin new file mode 100755 index 0000000000..e9bf775cde Binary files /dev/null and b/boards/micoair/h743-lite/extras/micoair_h743-lite_bootloader.bin differ diff --git a/boards/micoair/h743-lite/firmware.prototype b/boards/micoair/h743-lite/firmware.prototype new file mode 100644 index 0000000000..6bf59c3712 --- /dev/null +++ b/boards/micoair/h743-lite/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 1202, + "magic": "PX4FWv1", + "description": "Firmware for the MicoAir743-Lite board", + "image": "", + "build_time": 0, + "summary": "MicoAir743-Lite", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1966080, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/micoair/h743-lite/init/rc.board_defaults b/boards/micoair/h743-lite/init/rc.board_defaults new file mode 100644 index 0000000000..6448d6d3ae --- /dev/null +++ b/boards/micoair/h743-lite/init/rc.board_defaults @@ -0,0 +1,28 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ +param set-default BAT1_A_PER_V 40 +param set-default BAT1_N_CELLS 4 +param set-default BAT1_V_CHARGED 4.2 +param set-default BAT1_V_DIV 21.12 +param set-default BAT1_V_EMPTY 3.2 + +param set-default SYS_HAS_MAG 0 +#param set-default SENS_EN_SPA06 1 +param set-default PWM_MAIN_TIM0 -4 +param set-default RC_INPUT_PROTO -1 + +param set-default MAV_2_CONFIG 104 +param set-default SER_TEL4_BAUD 115200 + +param set-default IMU_GYRO_CUTOFF 80 +param set-default SYS_AUTOSTART 4001 +param set-default MC_PITCHRATE_K 0.4 +param set-default MC_ROLLRATE_K 0.35 +param set-default MC_YAWRATE_K 1.2 +param set-default MC_YAWRATE_MAX 360 +param set-default MAV_TYPE 2 +param set-default CA_AIRFRAME 0 +param set-default CA_ROTOR_COUNT 4 +param set-default CBRK_SUPPLY_CHK 894281 diff --git a/boards/micoair/h743-lite/init/rc.board_extras b/boards/micoair/h743-lite/init/rc.board_extras new file mode 100644 index 0000000000..e7653077db --- /dev/null +++ b/boards/micoair/h743-lite/init/rc.board_extras @@ -0,0 +1,7 @@ +#!/bin/sh +# +# board specific extras init +#------------------------------------------------------------------------------ + +# enable onboard OSD chip +# atxxxx start -s diff --git a/boards/micoair/h743-lite/init/rc.board_sensors b/boards/micoair/h743-lite/init/rc.board_sensors new file mode 100644 index 0000000000..c9be0818b7 --- /dev/null +++ b/boards/micoair/h743-lite/init/rc.board_sensors @@ -0,0 +1,13 @@ +#!/bin/sh +# +# board specific sensors init +#------------------------------------------------------------------------------ + +board_adc start + +# # Internal SPI bus ICM45686 accel/gyro +icm45686 -s -b 3 -R 2 start + +# Internal baro +#spa06 -I -a 0x77 start +spa06 -X -a 0x77 -b 2 start diff --git a/boards/micoair/h743-lite/nuttx-config/bootloader/defconfig b/boards/micoair/h743-lite/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..d6a33ff9f7 --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/bootloader/defconfig @@ -0,0 +1,85 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_SPI_EXCHANGE is not set +# CONFIG_STM32H7_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/micoair/h743-lite/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x004b +CONFIG_CDCACM_PRODUCTSTR="MicoAir743-Lite" +CONFIG_CDCACM_RXBUFSIZE=6000 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x3162 +CONFIG_CDCACM_VENDORSTR="MicoAir" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_TIM1=y +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/micoair/h743-lite/nuttx-config/include/board.h b/boards/micoair/h743-lite/nuttx-config/include/board.h new file mode 100644 index 0000000000..12f99c9bb6 --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/include/board.h @@ -0,0 +1,414 @@ +/************************************************************************************ + * nuttx-configs/px4_fmu-v6u/include/board.h + * + * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved. + * Authors: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#ifndef __NUTTX_CONFIG_MICOAIR743_LITE_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_MICOAIR743_LITE_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The MicoAir743-Lite board provides the following clock sources: + * + * X1: 8 MHz crystal for HSE + * + * So we have these clock source available within the STM32 + * + * HSI: 64 MHz RC factory-trimmed + * HSE: 8 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 8000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 8,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * Subject to: + * + * 1 <= PLLM <= 63 + * 4 <= PLLN <= 512 + * 150 MHz <= PLL_VCOL <= 420MHz + * 192 MHz <= PLL_VCOH <= 836MHz + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + * Subject to + * + * PLLP1 = {2, 4, 6, 8, ..., 128} + * PLLP2,3 = {2, 3, 4, ..., 128} + * CPUCLK <= 480 MHz + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(2) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/4 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration + * + * Note: look at Table 54 in ST Manual + */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSEL RCC_D3CCIPR_ADCSEL_PLL2 + +/* FDCAN 1 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE /* FDCAN 1 2 clock source */ + +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states + * + * ------------ ---------- ----------- + * Vcore MAX ACLK WAIT STATES + * ------------ ---------- ----------- + * 1.15-1.26 V 70 MHz 0 + * (VOS1 level) 140 MHz 1 + * 210 MHz 2 + * 1.05-1.15 V 55 MHz 0 + * (VOS2 level) 110 MHz 1 + * 165 MHz 2 + * 220 MHz 3 + * 0.95-1.05 V 45 MHz 0 + * (VOS3 level) 90 MHz 1 + * 135 MHz 2 + * 180 MHz 3 + * 225 MHz 4 + * ------------ ---------- ----------- + */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* SDMMC definitions ********************************************************/ + +/* Init 480kHz, freq = PLL1Q/(2*div) div = PLL1Q/(2*freq) */ + +#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* 20 MHz Max for now - more reliable on some boards than 25 MHz + * 20 MHz = PLL1Q/(2*div), div = PLL1Q/(2*freq), div = 6 = 240 / 40 + */ + +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_MMCXFR_CLKDIV (6 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_SDXFR_CLKDIV (6 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE + +/* LED definitions ******************************************************************/ +/* The board has two, LED_GREEN a Green LED and LED_BLUE a Blue LED, + * that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Alternate function pin selections ************************************************/ + +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PA10 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ + +#define GPIO_USART2_RX GPIO_USART2_RX_1 /* PA3 */ +#define GPIO_USART2_TX GPIO_USART2_TX_1 /* PA2 */ + +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +#define GPIO_UART4_RX GPIO_UART4_RX_2 /* PA1 */ +#define GPIO_UART4_TX GPIO_UART4_TX_2 /* PA0 */ + +#define GPIO_UART5_RX GPIO_UART5_RX_2 /* PB5 */ +#define GPIO_UART5_TX GPIO_UART5_TX_2 /* PB6 */ + +#define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ +#define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ + +#define GPIO_UART7_RX GPIO_UART7_RX_3 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ + +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* SPI + * + + */ + +#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_2MHz)) + +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_1 /* PB4 */ +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_1 /* PD6 */ +#define GPIO_SPI3_SCK ADJ_SLEW_RATE(GPIO_SPI3_SCK_1) /* PB3 */ + +/* I2C + * + + * + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* PB8 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* PB9 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN8) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN9) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1 /* PB10 */ +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_1 /* PB11 */ + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN10) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN11) + +# define PROBE_INIT(mask) +# define PROBE(n,s) +# define PROBE_MARK(n) + +#endif /*__NUTTX_CONFIG_MICOAIR743_LITE_INCLUDE_BOARD_H */ diff --git a/boards/micoair/h743-lite/nuttx-config/include/board_dma_map.h b/boards/micoair/h743-lite/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..fd6a97722a --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/include/board_dma_map.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_0 +#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_0 diff --git a/boards/micoair/h743-lite/nuttx-config/nsh/defconfig b/boards/micoair/h743-lite/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..11a2d6967f --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/nsh/defconfig @@ -0,0 +1,244 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/micoair/h743-lite/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0036 +CONFIG_CDCACM_PRODUCTSTR="MicoAir743-Lite" +CONFIG_CDCACM_RXBUFSIZE=6000 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1B8C +CONFIG_CDCACM_VENDORSTR="MicoAir" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_NCHAINS=24 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_IOB=y +CONFIG_MM_REGIONS=4 +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_PULLUP=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_FLASH_OVERRIDE_I=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C2=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_HSECLOCK=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SDMMC1=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI3=y +CONFIG_STM32H7_SPI3_DMA=y +CONFIG_STM32H7_SPI3_DMA_BUFFER=2048 +CONFIG_STM32H7_SPI_DMATHRESHOLD=8 +CONFIG_STM32H7_TIM12=y +CONFIG_STM32H7_TIM15=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM4=y +CONFIG_STM32H7_TIM8=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART6=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=800 +CONFIG_UART5_RXBUFSIZE=600 +CONFIG_UART5_TXBUFSIZE=800 +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_TXBUFSIZE=800 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=800 +CONFIG_USART1_RXBUFSIZE=1200 +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=800 +CONFIG_USART3_RXBUFSIZE=600 +CONFIG_USART3_TXBUFSIZE=800 +CONFIG_USART6_BAUD=57600 +CONFIG_USART6_RXBUFSIZE=600 +CONFIG_USART6_TXBUFSIZE=800 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/micoair/h743-lite/nuttx-config/scripts/bootloader_script.ld b/boards/micoair/h743-lite/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..fb877cc443 --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,213 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The Durandal-v1 uses an STM32H743II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The Durandal has a Switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the swiutch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/micoair/h743-lite/nuttx-config/scripts/script.ld b/boards/micoair/h743-lite/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..85f4990724 --- /dev/null +++ b/boards/micoair/h743-lite/nuttx-config/scripts/script.ld @@ -0,0 +1,228 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2020 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The board uses an STM32H743II and has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * There's a switch on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the switch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743ZI also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1920K + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/micoair/h743-lite/src/CMakeLists.txt b/boards/micoair/h743-lite/src/CMakeLists.txt new file mode 100644 index 0000000000..c47215375d --- /dev/null +++ b/boards/micoair/h743-lite/src/CMakeLists.txt @@ -0,0 +1,68 @@ +############################################################################ +# +# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_library(drivers_board + bootloader_main.c + usb.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + i2c.cpp + init.c + led.c + sdio.c + spi.cpp + timer_config.cpp + usb.c + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/micoair/h743-lite/src/board_config.h b/boards/micoair/h743-lite/src/board_config.h new file mode 100644 index 0000000000..2eef26d59b --- /dev/null +++ b/boards/micoair/h743-lite/src/board_config.h @@ -0,0 +1,199 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * Board internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + + + +/* LEDs are driven with push open drain to support Anode to 5V or 3.3V */ + +# define GPIO_nLED_RED /* PE3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3) +# define GPIO_nLED_GREEN /* PE2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN2) +# define GPIO_nLED_BLUE /* PE4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4) + +# define BOARD_HAS_CONTROL_STATUS_LEDS 1 +# define BOARD_OVERLOAD_LED LED_RED +# define BOARD_ARMED_STATE_LED LED_BLUE + + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ +#define SYSTEM_ADC_BASE STM32_ADC1_BASE +#define ADC1_CH(n) (n) + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ +#define PX4_ADC_GPIO \ + /* PC0 */ GPIO_ADC123_INP10, \ + /* PC1 */ GPIO_ADC123_INP11 + + +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PC0 */ ADC1_CH(10) +#define ADC_BATTERY_CURRENT_CHANNEL /* PC1 */ ADC1_CH(11) + + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL)) + + +/* Define Battery 1 Voltage Divider and A per V + */ + +// #define BOARD_BATTERY1_V_DIV (11.0f) /* measured with the provided PM board */ +// #define BOARD_BATTERY1_A_PER_V (40.0f) +// #define BOARD_BATTERY2_V_DIV (11.0f) /* measured with the provided PM board */ + + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 14 +#define DIRECT_INPUT_TIMER_CHANNELS 14 + +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + +#define GPIO_TONE_ALARM_IDLE /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN15) +#define GPIO_TONE_ALARM_GPIO /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN15) + +/* USB OTG FS + * + * PA8 OTG_FS_VBUS VBUS sensing + */ + +#define GPIO_OTGFS_VBUS /* PA8 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN8) + + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + + +/* RC Serial port */ +#define RC_SERIAL_PORT "/dev/ttyS5" +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + +//#define GPIO_I2C2_DRDY1_SPA06 /* PD0 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD|GPIO_PIN0) + + +/* SD Card */ +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ +#define BOARD_HAS_ON_RESET 1 + +#define PX4_GPIO_INIT_LIST { \ + PX4_ADC_GPIO, \ + GPIO_TONE_ALARM_IDLE, \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + + +#define BOARD_NUM_IO_TIMERS 6 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void); + +/**************************************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/micoair/h743-lite/src/bootloader_main.c b/boards/micoair/h743-lite/src/bootloader_main.c new file mode 100644 index 0000000000..5670308a29 --- /dev/null +++ b/boards/micoair/h743-lite/src/bootloader_main.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +__EXPORT void board_on_reset(int status) {} + +__EXPORT void stm32_boardinitialize(void) +{ + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + return 0; +} + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/micoair/h743-lite/src/hw_config.h b/boards/micoair/h743-lite/src/hw_config.h new file mode 100644 index 0000000000..ac210d78d4 --- /dev/null +++ b/boards/micoair/h743-lite/src/hw_config.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +//#define USE_VBUS_PULL_DOWN +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,115200" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 1202 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (15) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 8 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif diff --git a/boards/micoair/h743-lite/src/i2c.cpp b/boards/micoair/h743-lite/src/i2c.cpp new file mode 100644 index 0000000000..bea7532cc3 --- /dev/null +++ b/boards/micoair/h743-lite/src/i2c.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusExternal(1), + initI2CBusExternal(2), +}; diff --git a/boards/micoair/h743-lite/src/init.c b/boards/micoair/h743-lite/src/init.c new file mode 100644 index 0000000000..c0e1f9776c --- /dev/null +++ b/boards/micoair/h743-lite/src/init.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * FMU-specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialisation. + */ + +#include "board_config.h" + +#include + +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +# if defined(FLASH_BASED_PARAMS) +# include +#endif + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + /* + * On resets invoked from system (not boot) ensure we establish a low + * output state on PWM pins to disarm the ESC and prevent the reset from potentially + * spinning up the motors. + */ + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ +__EXPORT void stm32_boardinitialize(void) +{ + /* Reset PWM first thing */ + board_on_reset(-1); + + /* configure LEDs */ + board_autoled_initialize(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure SPI interfaces */ + stm32_spiinitialize(); + + /* configure USB interfaces */ + stm32_usbinitialize(); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Need hrt running before using the ADC */ + px4_platform_init(); + + /* configure the DMA allocator */ + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_BLUE); + } + +#ifdef CONFIG_MMCSD + int ret = stm32_sdio_initialize(); + + if (ret != OK) { + led_on(LED_BLUE); + return ret; + } + +#endif + +// TODO:internal flash store parameters +#if defined(FLASH_BASED_PARAMS) + static sector_descriptor_t params_sector_map[] = { + {15, 128 * 1024, 0x081E0000}, + {0, 0, 0}, + }; + + /* Initialize the flashfs layer to use heap allocated memory */ + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + led_on(LED_RED); + } + +#endif + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + return OK; +} diff --git a/boards/micoair/h743-lite/src/led.c b/boards/micoair/h743-lite/src/led.c new file mode 100644 index 0000000000..d7794392db --- /dev/null +++ b/boards/micoair/h743-lite/src/led.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE + GPIO_nLED_RED, // Indexed by BOARD_LED_RED +}; + +__EXPORT void led_init(void) +{ + /* Configure LED GPIOs for output */ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on */ + if (g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} diff --git a/boards/micoair/h743-lite/src/sdio.c b/boards/micoair/h743-lite/src/sdio.c new file mode 100644 index 0000000000..869d757756 --- /dev/null +++ b/boards/micoair/h743-lite/src/sdio.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "board_config.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(GPIO_SDMMC1_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + + if (sdio_dev && present != g_sd_inserted) { + sdio_mediachange(sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDMMC1_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + sdio_dev = sdio_initialize(SDIO_SLOTNO); + + if (!sdio_dev) { + syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev); + + if (ret != OK) { + syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(sdio_dev, true); +#endif + + return OK; +} + +#endif /* CONFIG_MMCSD */ diff --git a/boards/micoair/h743-lite/src/spi.cpp b/boards/micoair/h743-lite/src/spi.cpp new file mode 100644 index 0000000000..148534ff85 --- /dev/null +++ b/boards/micoair/h743-lite/src/spi.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI3, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM45686, SPI::CS{GPIO::PortD, GPIO::Pin4}, SPI::DRDY{GPIO::PortD, GPIO::Pin5}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/micoair/h743-lite/src/timer_config.cpp b/boards/micoair/h743-lite/src/timer_config.cpp new file mode 100644 index 0000000000..050d3b0dc4 --- /dev/null +++ b/boards/micoair/h743-lite/src/timer_config.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index1}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1}), + initIOTimer(Timer::Timer4, DMA{DMA::Index1}), + initIOTimer(Timer::Timer12), + initIOTimer(Timer::Timer15), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel2}, {GPIO::PortA, GPIO::Pin7}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel1}, {GPIO::PortA, GPIO::Pin6}), + initIOTimerChannel(io_timers, {Timer::Timer15, Timer::Channel1}, {GPIO::PortE, GPIO::Pin5}), + initIOTimerChannel(io_timers, {Timer::Timer15, Timer::Channel2}, {GPIO::PortE, GPIO::Pin6}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel1}, {GPIO::PortD, GPIO::Pin12}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel2}, {GPIO::PortD, GPIO::Pin13}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel1}, {GPIO::PortB, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel2}, {GPIO::PortB, GPIO::Pin15}), + +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/micoair/h743-lite/src/usb.c b/boards/micoair/h743-lite/src/usb.c new file mode 100644 index 0000000000..9591784866 --- /dev/null +++ b/boards/micoair/h743-lite/src/usb.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +#include "board_config.h" +#include +#include +#include +#include + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ + +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/boards/micoair/h743-v2/default.px4board b/boards/micoair/h743-v2/default.px4board index 9f6d00a5d0..320f1d29e9 100644 --- a/boards/micoair/h743-v2/default.px4board +++ b/boards/micoair/h743-v2/default.px4board @@ -25,18 +25,15 @@ CONFIG_DRIVERS_GPS=y CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_BOSCH_BMI270=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA220=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y CONFIG_DRIVERS_PPS_CAPTURE=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y -CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_DRIVERS_TAP_ESC=y diff --git a/boards/micoair/h743/default.px4board b/boards/micoair/h743/default.px4board index d6769fa1d8..90c9b6e6f9 100644 --- a/boards/micoair/h743/default.px4board +++ b/boards/micoair/h743/default.px4board @@ -27,18 +27,15 @@ CONFIG_COMMON_HYGROMETERS=y CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_BOSCH_BMI270=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA220=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y CONFIG_DRIVERS_PPS_CAPTURE=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_COMMON_RC=y -CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_RPM=y CONFIG_DRIVERS_SMART_BATTERY_BATMON=y CONFIG_DRIVERS_TAP_ESC=y diff --git a/boards/modalai/fc-v1/default.px4board b/boards/modalai/fc-v1/default.px4board index 0f386cc2b3..e3c79f459e 100644 --- a/boards/modalai/fc-v1/default.px4board +++ b/boards/modalai/fc-v1/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_COMMON_OSD=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y diff --git a/boards/modalai/fc-v2/default.px4board b/boards/modalai/fc-v2/default.px4board index fb698d437a..f33dbc9002 100644 --- a/boards/modalai/fc-v2/default.px4board +++ b/boards/modalai/fc-v2/default.px4board @@ -19,7 +19,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_COMMON_OSD=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y diff --git a/boards/modalai/voxl2/cmake/init.cmake b/boards/modalai/voxl2/cmake/init.cmake index 357d1d45ec..4a60cb5d91 100644 --- a/boards/modalai/voxl2/cmake/init.cmake +++ b/boards/modalai/voxl2/cmake/init.cmake @@ -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() diff --git a/boards/modalai/voxl2/libfc-sensor-api b/boards/modalai/voxl2/libfc-sensor-api index 85151aaf6b..d5abf9cbbf 160000 --- a/boards/modalai/voxl2/libfc-sensor-api +++ b/boards/modalai/voxl2/libfc-sensor-api @@ -1 +1 @@ -Subproject commit 85151aaf6ba8b24ce82b387e088452c63f7e2096 +Subproject commit d5abf9cbbf07711db2a9166c2eec4a4a7682f921 diff --git a/boards/mro/ctrl-zero-classic/default.px4board b/boards/mro/ctrl-zero-classic/default.px4board index a9dc98219a..db9c47fa7c 100644 --- a/boards/mro/ctrl-zero-classic/default.px4board +++ b/boards/mro/ctrl-zero-classic/default.px4board @@ -23,7 +23,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/ctrl-zero-f7-oem/default.px4board b/boards/mro/ctrl-zero-f7-oem/default.px4board index 7dfdd1e8b0..a963f04af7 100644 --- a/boards/mro/ctrl-zero-f7-oem/default.px4board +++ b/boards/mro/ctrl-zero-f7-oem/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/ctrl-zero-f7/default.px4board b/boards/mro/ctrl-zero-f7/default.px4board index ee46ef85c8..5856c4e5a3 100644 --- a/boards/mro/ctrl-zero-f7/default.px4board +++ b/boards/mro/ctrl-zero-f7/default.px4board @@ -20,7 +20,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/ctrl-zero-h7-oem/default.px4board b/boards/mro/ctrl-zero-h7-oem/default.px4board index e53eb2e0fc..2d5fa58545 100644 --- a/boards/mro/ctrl-zero-h7-oem/default.px4board +++ b/boards/mro/ctrl-zero-h7-oem/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/ctrl-zero-h7/default.px4board b/boards/mro/ctrl-zero-h7/default.px4board index b564545e55..8c2eed4595 100644 --- a/boards/mro/ctrl-zero-h7/default.px4board +++ b/boards/mro/ctrl-zero-h7/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/pixracerpro/default.px4board b/boards/mro/pixracerpro/default.px4board index 401f42f36f..b37955adb3 100644 --- a/boards/mro/pixracerpro/default.px4board +++ b/boards/mro/pixracerpro/default.px4board @@ -1,8 +1,11 @@ CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" CONFIG_BOARD_ARCHITECTURE="cortex-m7" CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS3" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS6" CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS0" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS5" CONFIG_BOARD_PARAM_FILE="/fs/microsd/params" CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y @@ -23,7 +26,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/pixracerpro/neural.px4board b/boards/mro/pixracerpro/neural.px4board index f3105d2e5b..0bc416dc06 100644 --- a/boards/mro/pixracerpro/neural.px4board +++ b/boards/mro/pixracerpro/neural.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/mro/x21-777/default.px4board b/boards/mro/x21-777/default.px4board index 322d80227e..1219dc87fd 100644 --- a/boards/mro/x21-777/default.px4board +++ b/boards/mro/x21-777/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/mro/x21/default.px4board b/boards/mro/x21/default.px4board index 00d2c84743..a0b768addc 100644 --- a/boards/mro/x21/default.px4board +++ b/boards/mro/x21/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/narinfc/h7/default.px4board b/boards/narinfc/h7/default.px4board index c7c30b1a1e..d53d919a07 100644 --- a/boards/narinfc/h7/default.px4board +++ b/boards/narinfc/h7/default.px4board @@ -27,7 +27,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/narinfc/h7/nuttx-config/bootloader/defconfig b/boards/narinfc/h7/nuttx-config/bootloader/defconfig index 111c93fcc7..c2fbabfb8a 100644 --- a/boards/narinfc/h7/nuttx-config/bootloader/defconfig +++ b/boards/narinfc/h7/nuttx-config/bootloader/defconfig @@ -13,7 +13,7 @@ CONFIG_ARCH="arm" CONFIG_ARCH_BOARD_CUSTOM=y CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/narinfc/h7/nuttx-config" CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y -CONFIG_ARCH_BOARD_CUSTOM_NAME="PX4 NarinFC-H7" +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" CONFIG_ARCH_CHIP="stm32h7" CONFIG_ARCH_CHIP_STM32H743XI=y CONFIG_ARCH_CHIP_STM32H7=y @@ -31,11 +31,11 @@ CONFIG_BOARD_LOOPSPERMSEC=22114 CONFIG_BOARD_RESET_ON_ASSERT=2 CONFIG_CDCACM=y CONFIG_CDCACM_IFLOWCONTROL=y -CONFIG_CDCACM_PRODUCTID=0x004c -CONFIG_CDCACM_PRODUCTSTR="PX4 BL NarinFC H7" +CONFIG_CDCACM_PRODUCTID=0x0047 +CONFIG_CDCACM_PRODUCTSTR="PX4 BL VOLOLAND NarinFC-H7" CONFIG_CDCACM_RXBUFSIZE=600 CONFIG_CDCACM_TXBUFSIZE=12000 -CONFIG_CDCACM_VENDORID=0x3163 +CONFIG_CDCACM_VENDORID=0x3fc5 CONFIG_CDCACM_VENDORSTR="VOLOLAND" CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y diff --git a/boards/nxp/fmuk66-e/default.px4board b/boards/nxp/fmuk66-e/default.px4board index 3adae50a71..9f43614f90 100644 --- a/boards/nxp/fmuk66-e/default.px4board +++ b/boards/nxp/fmuk66-e/default.px4board @@ -23,7 +23,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/nxp/fmuk66-v3/default.px4board b/boards/nxp/fmuk66-v3/default.px4board index f9143c1b5e..b55bc72734 100644 --- a/boards/nxp/fmuk66-v3/default.px4board +++ b/boards/nxp/fmuk66-v3/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_LIGHTS_RGBLED=y CONFIG_DRIVERS_LIGHTS_RGBLED_NCP5623C=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/nxp/mr-canhubk3/fmu.px4board b/boards/nxp/mr-canhubk3/fmu.px4board index 366fac4e09..e89aeb1358 100644 --- a/boards/nxp/mr-canhubk3/fmu.px4board +++ b/boards/nxp/mr-canhubk3/fmu.px4board @@ -1,6 +1,8 @@ # CONFIG_BOARD_ROMFSROOT is not set CONFIG_DRIVERS_BAROMETER_BMP388=n CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=n +CONFIG_ARCH_CHIP_S32K3XX=y +CONFIG_BOARD_PWM_FREQ=1000000 CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS1" CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS4" CONFIG_BOARD_SERIAL_RC="/dev/ttyS5" @@ -12,7 +14,6 @@ CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y CONFIG_COMMON_DISTANCE_SENSOR=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_CYPHAL_BMS_SUBSCRIBER=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_CYPHAL=y @@ -20,6 +21,7 @@ CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_SF45_SERIAL=y CONFIG_DRIVERS_GPS=y CONFIG_DRIVERS_IRLOCK=y CONFIG_DRIVERS_RC_INPUT=y +CONFIG_DRIVERS_ROBOCLAW=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_UAVCAN=y CONFIG_EXAMPLES_FAKE_GPS=y @@ -33,9 +35,10 @@ CONFIG_MODULES_EVENTS=y CONFIG_MODULES_FLIGHT_MODE_MANAGER=y CONFIG_MODULES_FW_ATT_CONTROL=y CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y -CONFIG_MODULES_FW_MODE_MANAGER=y CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y CONFIG_MODULES_GYRO_FFT=y CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y @@ -50,8 +53,10 @@ CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y CONFIG_MODULES_MC_POS_CONTROL=y CONFIG_MODULES_MC_RATE_CONTROL=y -CONFIG_MODULES_NAVIGATOR=y CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_ROVER_ACKERMANN=y +CONFIG_MODULES_ROVER_DIFFERENTIAL=y +CONFIG_MODULES_ROVER_MECANUM=y CONFIG_MODULES_TEMPERATURE_COMPENSATION=y CONFIG_MODULES_UXRCE_DDS_CLIENT=y CONFIG_MODULES_VTOL_ATT_CONTROL=y diff --git a/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig b/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig index 45821d6c6f..65e28164f8 100644 --- a/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig +++ b/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig @@ -94,6 +94,7 @@ CONFIG_FAT_LFN_ALIAS_HASH=y CONFIG_FDCLONE_STDIO=y CONFIG_FS26_SPI_FREQUENCY=5000000 CONFIG_FSUTILS_IPCFG=y +CONFIG_FS_BINFS=y CONFIG_FS_CROMFS=y CONFIG_FS_FAT=y CONFIG_FS_FATTIME=y @@ -126,16 +127,24 @@ CONFIG_LPUART0_IFLOWCONTROL=y CONFIG_LPUART0_OFLOWCONTROL=y CONFIG_LPUART0_RXBUFSIZE=640 CONFIG_LPUART0_RXDMA=y +CONFIG_LPUART0_TXBUFSIZE=1100 CONFIG_LPUART0_TXDMA=y CONFIG_LPUART13_RXDMA=y CONFIG_LPUART13_TXDMA=y CONFIG_LPUART14_RXDMA=y CONFIG_LPUART14_TXDMA=y +CONFIG_LPUART1_RXBUFSIZE=600 CONFIG_LPUART1_RXDMA=y +CONFIG_LPUART1_TXBUFSIZE=1100 CONFIG_LPUART1_TXDMA=y CONFIG_LPUART2_RXDMA=y CONFIG_LPUART2_SERIAL_CONSOLE=y CONFIG_LPUART2_TXDMA=y +CONFIG_LPUART4_RXBUFSIZE=600 +CONFIG_LPUART4_TXBUFSIZE=600 +CONFIG_LPUART7_RXDMA=y +CONFIG_LPUART7_TXBUFSIZE=1500 +CONFIG_LPUART7_TXDMA=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y CONFIG_MMCSD=y @@ -213,6 +222,8 @@ CONFIG_PTHREAD_STACK_MIN=512 CONFIG_RAM_SIZE=272000 CONFIG_RAM_START=0x20400000 CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y CONFIG_S32K3XX_DTCM_HEAP=y CONFIG_S32K3XX_EDMA=y CONFIG_S32K3XX_EDMA_EDBG=y @@ -267,7 +278,6 @@ CONFIG_SCHED_INSTRUMENTATION_SWITCH=y CONFIG_SCHED_LPWORK=y CONFIG_SCHED_LPWORKPRIORITY=50 CONFIG_SCHED_LPWORKSTACKSIZE=1768 -CONFIG_SCHED_WAITPID=y CONFIG_SEM_PREALLOCHOLDERS=32 CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y CONFIG_SERIAL_TERMIOS=y @@ -280,7 +290,10 @@ CONFIG_STACK_COLORATION=y CONFIG_START_DAY=30 CONFIG_START_MONTH=11 CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_SYSTEM_CLE=y CONFIG_SYSTEM_DHCPC_RENEW=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_SYSTEM=y CONFIG_TASK_NAME_SIZE=24 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/nxp/mr-canhubk3/src/board_config.h b/boards/nxp/mr-canhubk3/src/board_config.h index 7ea2a91e8b..47f1ca3c36 100644 --- a/boards/nxp/mr-canhubk3/src/board_config.h +++ b/boards/nxp/mr-canhubk3/src/board_config.h @@ -112,7 +112,7 @@ __BEGIN_DECLS /* To detect MR-CANHUBK3-ADAP board */ #define BOARD_HAS_HW_VERSIONING 1 -#define CANHUBK3_ADAP_DETECT (PIN_PTA12 | GPIO_INPUT | GPIO_PULLUP) +#define CANHUBK3_ADAP_DETECT (PIN_PTA11 | GPIO_INPUT | GPIO_PULLUP) /* diff --git a/boards/nxp/mr-canhubk3/src/init.c b/boards/nxp/mr-canhubk3/src/init.c index 97a41f8430..15148c7845 100644 --- a/boards/nxp/mr-canhubk3/src/init.c +++ b/boards/nxp/mr-canhubk3/src/init.c @@ -105,18 +105,18 @@ __EXPORT int board_app_initialize(uintptr_t arg) /* Configure LPSPI1 peripheral chip select */ - s32k3xx_pinconfig(PIN_LPSPI2_PCS); + s32k3xx_pinconfig(PIN_LPSPI1_PCS); /* Initialize the SPI driver for LPSPI1 */ - struct spi_dev_s *g_lpspi2 = s32k3xx_lpspibus_initialize(2); + struct spi_dev_s *g_lpspi1 = s32k3xx_lpspibus_initialize(1); - if (g_lpspi2 == NULL) { - spierr("ERROR: FAILED to initialize LPSPI2\n"); + if (g_lpspi1 == NULL) { + spierr("ERROR: FAILED to initialize LPSPI1\n"); return -ENODEV; } - rv = mmcsd_spislotinitialize(0, 0, g_lpspi2); + rv = mmcsd_spislotinitialize(0, 0, g_lpspi1); if (rv < 0) { mcerr("ERROR: Failed to bind SPI port %d to SD slot %d\n", diff --git a/boards/nxp/mr-canhubk3/src/timer_config.cpp b/boards/nxp/mr-canhubk3/src/timer_config.cpp index 607917f614..24b29ca071 100644 --- a/boards/nxp/mr-canhubk3/src/timer_config.cpp +++ b/boards/nxp/mr-canhubk3/src/timer_config.cpp @@ -51,18 +51,25 @@ constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { - initIOTimer(Timer::EMIOS0) + initIOTimer(Timer::EMIOS0_Channel0, Timer::Channel0), + initIOTimer(Timer::EMIOS0_Channel1, Timer::Channel1), + initIOTimer(Timer::EMIOS0_Channel2, Timer::Channel2), + initIOTimer(Timer::EMIOS0_Channel3, Timer::Channel3), + initIOTimer(Timer::EMIOS0_Channel4, Timer::Channel4), + initIOTimer(Timer::EMIOS0_Channel5, Timer::Channel5), + initIOTimer(Timer::EMIOS0_Channel6, Timer::Channel6), + initIOTimer(Timer::EMIOS0_Channel7, Timer::Channel7), }; constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel0}, PIN_EMIOS0_CH0_1), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel1}, PIN_EMIOS0_CH1_1), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel2}, PIN_EMIOS0_CH2_1), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel3}, PIN_EMIOS0_CH3_2), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel4}, PIN_EMIOS0_CH4_2), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel5}, PIN_EMIOS0_CH5_2), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel6}, PIN_EMIOS0_CH6_1), - initIOTimerChannel(io_timers, {Timer::EMIOS0, Timer::Channel7}, PIN_EMIOS0_CH7_2), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel0, Timer::Channel0}, PIN_EMIOS0_CH0_1), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel1, Timer::Channel1}, PIN_EMIOS0_CH1_1), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel2, Timer::Channel2}, PIN_EMIOS0_CH2_1), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel3, Timer::Channel3}, PIN_EMIOS0_CH3_2), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel4, Timer::Channel4}, PIN_EMIOS0_CH4_2), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel5, Timer::Channel5}, PIN_EMIOS0_CH5_2), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel6, Timer::Channel6}, PIN_EMIOS0_CH6_1), + initIOTimerChannel(io_timers, {Timer::EMIOS0_Channel7, Timer::Channel7}, PIN_EMIOS0_CH7_2), }; constexpr io_timers_channel_mapping_t io_timers_channel_mapping = diff --git a/boards/nxp/mr-tropic/bootloader.px4board b/boards/nxp/mr-tropic/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/nxp/mr-tropic/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/nxp/mr-tropic/cmake/upload.cmake b/boards/nxp/mr-tropic/cmake/upload.cmake new file mode 100644 index 0000000000..79da5c60fd --- /dev/null +++ b/boards/nxp/mr-tropic/cmake/upload.cmake @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2024 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + + +set(PX4_FW_NAME ${PX4_BINARY_DIR}/${PX4_BOARD_VENDOR}_${PX4_BOARD_MODEL}_${PX4_BOARD_LABEL}.hex) + +add_custom_target(upload_teensy + COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/teensy_uploader.py --port ${serial_ports} ${PX4_FW_NAME} --vendor-id 0x1FC9 --product-id 0x0024 + DEPENDS ${PX4_FW_NAME} + COMMENT "uploading px4" + VERBATIM + USES_TERMINAL + WORKING_DIRECTORY ${PX4_BINARY_DIR} +) diff --git a/boards/nxp/mr-tropic/default.px4board b/boards/nxp/mr-tropic/default.px4board new file mode 100644 index 0000000000..4dcc0cb146 --- /dev/null +++ b/boards/nxp/mr-tropic/default.px4board @@ -0,0 +1,108 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ETHERNET=y +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS1" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS2" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS3" +CONFIG_BOARD_SERIAL_RC="/dev/ttyS6" +CONFIG_BOARD_PARAM_FILE="/fs/nor/mtd_params" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_BMP388=y +CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y +CONFIG_DRIVERS_BAROMETER_MS5611=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_SF45_SERIAL=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_BOSCH_BMI088=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y +CONFIG_COMMON_INS=y +CONFIG_COMMON_LIGHT=y +CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM350=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_SAFETY_BUTTON=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_INTERFACES=1 +CONFIG_COMMON_UWB=y +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y +CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000 +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_ROVER_POS_CONTROL=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_MODULES_ZENOH=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_DUMPFILE=y +CONFIG_SYSTEMCMDS_I2C_LAUNCHER=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_NETMAN=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SD_STRESS=y +CONFIG_SYSTEMCMDS_SERIAL_TEST=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/nxp/mr-tropic/extras/nxp_mr-tropic_bootloader.bin b/boards/nxp/mr-tropic/extras/nxp_mr-tropic_bootloader.bin new file mode 100755 index 0000000000..c972de6405 Binary files /dev/null and b/boards/nxp/mr-tropic/extras/nxp_mr-tropic_bootloader.bin differ diff --git a/boards/nxp/mr-tropic/firmware.prototype b/boards/nxp/mr-tropic/firmware.prototype new file mode 100644 index 0000000000..ae7bf83cb1 --- /dev/null +++ b/boards/nxp/mr-tropic/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 37, + "magic": "PX4FWv1", + "description": "Firmware for the MR-TROPIC board", + "image": "", + "build_time": 0, + "summary": "MR-TROPIC", + "version": "0.1", + "image_size": 0, + "image_maxsize": 3932160, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/nxp/mr-tropic/init/rc.board_defaults b/boards/nxp/mr-tropic/init/rc.board_defaults new file mode 100644 index 0000000000..5ed2a8e9d5 --- /dev/null +++ b/boards/nxp/mr-tropic/init/rc.board_defaults @@ -0,0 +1,34 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +# Mavlink ethernet (CFG 1000) +param set-default MAV_2_CONFIG 1000 +param set-default MAV_2_BROADCAST 1 +param set-default MAV_2_MODE 0 +param set-default MAV_2_RADIO_CTL 0 +param set-default MAV_2_RATE 100000 +param set-default MAV_2_REMOTE_PRT 14550 +param set-default MAV_2_UDP_PRT 14550 + +param set-default RC_CRSF_PRT_CFG 300 +param set-default RC_CRSF_TEL_EN 1 +param set-default RC_SBUS_PRT_CFG 0 + +if [ -f "/fs/microsd/ipcfg-eth0" ] +then +else + netman update -i eth0 +fi + +rgbled_pwm start +safety_button start + +if param greater -s UAVCAN_ENABLE 0 +then + ifup can0 +fi + +# Start the ESC telemetry +dshot telemetry -d /dev/ttyS5 -x diff --git a/boards/nxp/mr-tropic/init/rc.board_mavlink b/boards/nxp/mr-tropic/init/rc.board_mavlink new file mode 100644 index 0000000000..d789d908e8 --- /dev/null +++ b/boards/nxp/mr-tropic/init/rc.board_mavlink @@ -0,0 +1,4 @@ +#!/bin/sh +# +# Tropic Community specific board MAVLink startup script. +#------------------------------------------------------------------------------ diff --git a/boards/nxp/mr-tropic/init/rc.board_sensors b/boards/nxp/mr-tropic/init/rc.board_sensors new file mode 100644 index 0000000000..6dc213cc42 --- /dev/null +++ b/boards/nxp/mr-tropic/init/rc.board_sensors @@ -0,0 +1,68 @@ +#!/bin/sh +# +# PX4 board sensors init +#------------------------------------------------------------------------------ +# +# UART mapping on Tropic Community: +# +# LPUART5 /dev/ttyS0 CONSOLE +# LPUART3 /dev/ttyS1 GPS +# LPUART2 /dev/ttyS2 TELEM1 +# LPUART4 /dev/ttyS3 TELEM2 +# LPUART8 /dev/ttyS4 RC +# +#------------------------------------------------------------------------------ + +set INA_CONFIGURED no + +board_adc start + +if param compare SENS_EN_INA226 1 +then + # Start Digital power monitors + ina226 -X -b 3 -t 1 -k start + set INA_CONFIGURED yes +fi + +if param compare SENS_EN_INA228 1 +then + # Start Digital power monitors + ina228 -X -b 3 -t 1 -k start + set INA_CONFIGURED yes +fi + +if param compare SENS_EN_INA238 1 +then + # Start Digital power monitors + ina238 -X -b 3 -t 1 -k start + set INA_CONFIGURED yes +fi + +if [ $INA_CONFIGURED = no ] +then + # INA226, INA228, INA238 auto-start + i2c_launcher start -b 3 -t 1 +fi + +# Internal SPI bus icm45686 +icm45686 -R 2 -b 3 -s start + +# Internal on IMU SPI BMI088 +bmi088 -A -R 2 -b 4 -s start +bmi088 -G -R 2 -b 4 -s start + +# Internal magnetometer on I2c +bmm350 -I -b 4 -R 6 start + +# External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer) +ist8310 -X -b 1 -R 10 start + +# Possible internal Baro + +# Disable startup of internal baros if param is set to false +if param compare SENS_INT_BARO_EN 1 +then + bmp388 -I -b 4 start +fi + +unset INA_CONFIGURED diff --git a/boards/nxp/mr-tropic/nuttx-config/Kconfig b/boards/nxp/mr-tropic/nuttx-config/Kconfig new file mode 100644 index 0000000000..f72f3c094c --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/boards/nxp/mr-tropic/nuttx-config/bootloader/defconfig b/boards/nxp/mr-tropic/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..b6ab2f6b4b --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/bootloader/defconfig @@ -0,0 +1,107 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_SPI_EXCHANGE is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/nxp/mr-tropic/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_ITCM=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU=y +CONFIG_ARM_MPU_RESET=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=115000 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0025 +CONFIG_CDCACM_PRODUCTSTR="PX4 BL MR-TROPIC" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1FC9 +CONFIG_CDCACM_VENDORSTR="NXP SEMICONDUCTORS" +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEBUG_USAGEFAULT=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_EDMA=y +CONFIG_IMXRT_EDMA_EDBG=y +CONFIG_IMXRT_EDMA_ELINK=y +CONFIG_IMXRT_EDMA_NTCD=64 +CONFIG_IMXRT_ITCM=384 +CONFIG_IMXRT_LPUART3=y +CONFIG_IMXRT_SNVS_LPSRTC=y +CONFIG_IMXRT_USBDEV=y +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART3_BAUD=57600 +CONFIG_LPUART3_IFLOWCONTROL=y +CONFIG_LPUART3_OFLOWCONTROL=y +CONFIG_LPUART3_RXBUFSIZE=600 +CONFIG_LPUART3_RXDMA=y +CONFIG_LPUART3_TXBUFSIZE=1500 +CONFIG_LPUART3_TXDMA=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=1048576 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_DMA=y +CONFIG_USBDEV_DUALSPEED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/nxp/mr-tropic/nuttx-config/include/board.h b/boards/nxp/mr-tropic/nuttx-config/include/board.h new file mode 100644 index 0000000000..c096aa9886 --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/include/board.h @@ -0,0 +1,416 @@ +/************************************************************************************ + * nuttx-configs/nxp/nxp_mr-tropic/include/board.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __NUTTX_CONFIG_NXP_TROPIC_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_NXP_TROPIC_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ + +/* Set VDD_SOC to 1.25V */ + +#define IMXRT_VDD_SOC (0x12) + +/* Set Arm PLL (PLL1) to fOut = (24Mhz * ARM_PLL_DIV_SELECT/2) / ARM_PODF_DIVISOR + * 576Mhz = (24Mhz * ARM_PLL_DIV_SELECT/2) / ARM_PODF_DIVISOR + * ARM_PLL_DIV_SELECT = 96 + * ARM_PODF_DIVISOR = 2 + * 576Mhz = (24Mhz * 96/2) / 2 + * + * AHB_CLOCK_ROOT = PLL1fOut / IMXRT_AHB_PODF_DIVIDER + * 1Hz to 600 Mhz = 576Mhz / IMXRT_ARM_CLOCK_DIVIDER + * IMXRT_ARM_CLOCK_DIVIDER = 1 + * 576Mhz = 576Mhz / 1 + * + * PRE_PERIPH_CLK_SEL = PRE_PERIPH_CLK_SEL_PLL1 + * PERIPH_CLK_SEL = 1 (0 select PERIPH_CLK2_PODF, 1 select PRE_PERIPH_CLK_SEL_PLL1) + * PERIPH_CLK = 576Mhz + * + * IPG_CLOCK_ROOT = AHB_CLOCK_ROOT / IMXRT_IPG_PODF_DIVIDER + * IMXRT_IPG_PODF_DIVIDER = 4 + * 144Mhz = 576Mhz / 4 + * + * PRECLK_CLOCK_ROOT = IPG_CLOCK_ROOT / IMXRT_PERCLK_PODF_DIVIDER + * IMXRT_PERCLK_PODF_DIVIDER = 1 + * 16Mhz = 144Mhz / 9 + * + * SEMC_CLK_ROOT = 576Mhz / IMXRT_SEMC_PODF_DIVIDER (labeled AIX_PODF in 18.2) + * IMXRT_SEMC_PODF_DIVIDER = 8 + * 72Mhz = 576Mhz / 8 + * + * Set Sys PLL (PLL2) to fOut = (24Mhz * (20+(2*(DIV_SELECT))) + * 528Mhz = (24Mhz * (20+(2*(1))) + * + * Set USB1 PLL (PLL3) to fOut = (24Mhz * 20) + * 480Mhz = (24Mhz * 20) + * + * Set LPSPI PLL3 PFD0 to fOut = (480Mhz / 12 * 18) + * 720Mhz = (480Mhz / 12 * 18) + * 90Mhz = (720Mhz / LSPI_PODF_DIVIDER) + * + * Set LPI2C PLL3 / 8 to fOut = (480Mhz / 8) + * 60Mhz = (480Mhz / 8) + * 12Mhz = (60Mhz / LSPI_PODF_DIVIDER) + * + * Set USDHC1 PLL2 PFD2 to fOut = (528Mhz / 24 * 18) + * 396Mhz = (528Mhz / 24 * 18) + * 198Mhz = (396Mhz / IMXRT_USDHC1_PODF_DIVIDER) + */ + +#define BOARD_XTAL_FREQUENCY 24000000 +#define IMXRT_PRE_PERIPH_CLK_SEL CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL1 +#define IMXRT_PERIPH_CLK_SEL CCM_CBCDR_PERIPH_CLK_SEL_PRE_PERIPH +#define IMXRT_ARM_PLL_DIV_SELECT 96 +#define IMXRT_ARM_PODF_DIVIDER 2 +#define IMXRT_AHB_PODF_DIVIDER 1 +#define IMXRT_IPG_PODF_DIVIDER 4 +#define IMXRT_PERCLK_CLK_SEL CCM_CSCMR1_PERCLK_CLK_SEL_IPG_CLK_ROOT +#define IMXRT_PERCLK_PODF_DIVIDER 9 +#define IMXRT_SEMC_PODF_DIVIDER 8 +#define IMXRT_CAN_CLK_SELECT CCM_CSCMR2_CAN_CLK_SEL_PLL3_SW_80 +#define IMXRT_CAN_PODF_DIVIDER 1 + +#define IMXRT_LPSPI_CLK_SELECT CCM_CBCMR_LPSPI_CLK_SEL_PLL3_PFD0 +#define IMXRT_LSPI_PODF_DIVIDER 8 + +#define IMXRT_LPI2C_CLK_SELECT CCM_CSCDR2_LPI2C_CLK_SEL_PLL3_60M +#define IMXRT_LSI2C_PODF_DIVIDER 5 + +#define IMXRT_USDHC1_CLK_SELECT CCM_CSCMR1_USDHC1_CLK_SEL_PLL2_PFD0 +#define IMXRT_USDHC1_PODF_DIVIDER 2 + +#define IMXRT_USB1_PLL_DIV_SELECT CCM_ANALOG_PLL_USB1_DIV_SELECT_20 + +#define IMXRT_SYS_PLL_SELECT CCM_ANALOG_PLL_SYS_DIV_SELECT_22 + +#define IMXRT_USB1_PLL_DIV_SELECT CCM_ANALOG_PLL_USB1_DIV_SELECT_20 + +#define BOARD_CPU_FREQUENCY \ + (BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER + +#define BOARD_GPT_FREQUENCY \ + (BOARD_CPU_FREQUENCY / IMXRT_IPG_PODF_DIVIDER) / IMXRT_PERCLK_PODF_DIVIDER + + +/* 108Mhz clock for FlexIO using PLL3 PFD2 @ 520 */ +#define CONFIG_FLEXIO1_CLK 1 +#define CONFIG_FLEXIO1_PRED_DIVIDER 5 +#define CONFIG_FLEXIO1_PODF_DIVIDER 1 +#define CONFIG_PLL3_PFD2_FRAC 16 +#define BOARD_FLEXIO_PREQ 108000000 + +/* Define this to enable tracing */ +#if CONFIG_USE_TRACE +# define IMXRT_TRACE_PODF_DIVIDER 1 +# define IMXRT_TRACE_CLK_SELECT CCM_CBCMR_TRACE_CLK_SEL_PLL2_PFD0 +#endif + +/* SDIO *****************************************************************************/ + +/* Pin drive characteristics */ + +#define USDHC1_DATAX_IOMUX (IOMUX_SLEW_FAST | IOMUX_DRIVE_130OHM | IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER) +#define USDHC1_CMD_IOMUX (IOMUX_SLEW_FAST | IOMUX_DRIVE_130OHM | IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER) +#define USDHC1_CLK_IOMUX (IOMUX_SLEW_FAST | IOMUX_DRIVE_130OHM | IOMUX_SPEED_MAX) +#define USDHC1_CD_IOMUX (IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER) + +#define PIN_USDHC1_D0 (GPIO_USDHC1_DATA0_1 | USDHC1_DATAX_IOMUX) /* GPIO_SD_B0_02 */ +#define PIN_USDHC1_D1 (GPIO_USDHC1_DATA1_1 | USDHC1_DATAX_IOMUX) /* GPIO_SD_B0_03 */ +#define PIN_USDHC1_D2 (GPIO_USDHC1_DATA2_1 | USDHC1_DATAX_IOMUX) /* GPIO_SD_B0_04 */ +#define PIN_USDHC1_D3 (GPIO_USDHC1_DATA3_1 | USDHC1_DATAX_IOMUX) /* GPIO_SD_B0_05 */ +#define PIN_USDHC1_DCLK (GPIO_USDHC1_CLK_1 | USDHC1_CLK_IOMUX) /* GPIO_SD_B0_01 */ +#define PIN_USDHC1_CMD (GPIO_USDHC1_CMD_1 | USDHC1_CMD_IOMUX) /* GPIO_SD_B0_00 */ +#define PIN_USDHC1_CD (PIN_USDHC1_D3) + +/* #define PIN_USDHC1_CD (GPIO_USDHC1_CD_3 | USDHC1_CD_IOMUX) + * CD_B Pin works fine but somehow the driver has a timing issue with + * Thus use D3 instead + */ + +/* Ideal 400Khz for initial inquiry. + * Given input clock 198 Mhz. + * 386.71875 KHz = 198 Mhz / (256 * 2) + */ + +#define BOARD_USDHC_IDMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV256 +#define BOARD_USDHC_IDMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(2) + +/* Ideal 25 Mhz for other modes + * Given input clock 198 Mhz. + * 24.75 MHz = 198 Mhz / (8 * 1) + */ + +#define BOARD_USDHC_MMCMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_MMCMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +#define BOARD_USDHC_SD1MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_SD1MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +#define BOARD_USDHC_SD4MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 +#define BOARD_USDHC_SD4MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) + +/* ETH Disambiguation *******************************************************/ + +/* Ethernet Interrupt: GPIO_B0_15 + * + * This pin has a week pull-up within the PHY, is open-drain, and requires + * an external 1k ohm pull-up resistor (present on the EVK). A falling + * edge then indicates a change in state of the PHY. + */ + +#define GPIO_ENET_INT (IOMUX_ENET_INT_DEFAULT | \ + GPIO_PORT2 | GPIO_PIN15) /* B0_15 */ +#define GPIO_ENET_IRQ IMXRT_IRQ_GPIO2_15 + +/* Ethernet Reset: GPIO_B0_14 + * + * The #RST uses inverted logic. The initial value of zero will put the + * PHY into the reset state. + */ + +#define GPIO_ENET_RST (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT2 | GPIO_PIN14 | IOMUX_ENET_RST_DEFAULT) /* B0_14 */ + +#define GPIO_ENET_TX_DATA00 (GPIO_ENET_TX_DATA00_1| \ + IOMUX_ENET_DATA_DEFAULT) /* GPIO_B1_07 */ +#define GPIO_ENET_TX_DATA01 (GPIO_ENET_TX_DATA01_1| \ + IOMUX_ENET_DATA_DEFAULT) /* GPIO_B1_08 */ +#define GPIO_ENET_RX_DATA00 (GPIO_ENET_RX_DATA00_1| \ + IOMUX_ENET_DATA_DEFAULT) /* GPIO_B1_04 */ +#define GPIO_ENET_RX_DATA01 (GPIO_ENET_RX_DATA01_1| \ + IOMUX_ENET_DATA_DEFAULT) /* GPIO_B1_05 */ +#define GPIO_ENET_MDIO (GPIO_ENET_MDIO_1|IOMUX_ENET_MDIO_DEFAULT) /* GPIO_B1_15 */ +#define GPIO_ENET_MDC (GPIO_ENET_MDC_1|IOMUX_ENET_MDC_DEFAULT) /* GPIO_B1_14 */ +#define GPIO_ENET_RX_EN (GPIO_ENET_RX_EN_1|IOMUX_ENET_EN_DEFAULT) /* GPIO_B1_06 */ +#define GPIO_ENET_RX_ER (GPIO_ENET_RX_ER_1|IOMUX_ENET_RXERR_DEFAULT) /* GPIO_B1_11 */ +#define GPIO_ENET_TX_CLK (GPIO_ENET_REF_CLK_2|\ + IOMUX_ENET_TX_CLK_DEFAULT) /* GPIO_B1_10 */ +#define GPIO_ENET_TX_EN (GPIO_ENET_TX_EN_1|IOMUX_ENET_EN_DEFAULT) /* GPIO_B1_09 */ + +/* LED definitions ******************************************************************/ +/* The nxp fmutr1062 board has numerous LEDs but only three, LED_GREEN a Green LED, + * LED_BLUE a Blue LED and LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* PIO Disambiguation ***************************************************************/ +/* LPUARTs + */ +#define LPUART_IOMUX (IOMUX_PULL_UP_22K | IOMUX_DRIVE_40OHM | IOMUX_SLEW_SLOW | IOMUX_SPEED_LOW | IOMUX_SCHMITT_TRIGGER) +#define IOMUX_UART_CTS_DEFAULT (IOMUX_PULL_DOWN_100K | IOMUX_DRIVE_40OHM | IOMUX_SLEW_SLOW) + +/* Debug */ + +#define GPIO_LPUART6_RX (GPIO_LPUART6_RX_2 | LPUART_IOMUX) /* GPIO_EMC_26 */ +#define GPIO_LPUART6_TX (GPIO_LPUART6_TX_2 | LPUART_IOMUX) /* GPIO_EMC_25 */ + + +/* Telem 2 */ + +#define GPIO_LPUART5_RX (GPIO_LPUART5_RX_1 | LPUART_IOMUX) /* GPIO_B1_13 */ +#define GPIO_LPUART5_TX (GPIO_LPUART5_TX_1 | LPUART_IOMUX) /* GPIO_B1_12 */ +#define GPIO_LPUART5_CTS (GPIO_LPUART5_CTS_1 | IOMUX_UART_CTS_DEFAULT | PADMUX_SION) /* GPIO_EMC_28 GPIO4_IO27 */ +#define GPIO_LPUART5_RTS (GPIO_PORT4 | GPIO_PIN27 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) /* GPIO_EMC_27 GPIO4_IO27 (GPIO only, no HW Flow control) */ + +/* AUX */ + +#define GPIO_LPUART4_RX (GPIO_LPUART4_RX_1 | LPUART_IOMUX) /* GPIO_B1_01 */ +#define GPIO_LPUART4_TX (GPIO_LPUART4_TX_1 | LPUART_IOMUX) /* GPIO_B1_00 */ +#define GPIO_LPUART4_CTS (GPIO_PORT1 | GPIO_PIN15 | GPIO_INPUT | PADMUX_SION | IOMUX_UART_CTS_DEFAULT) /* GPIO_AD_B0_15 GPIO1_IO14 (Fixme Add GPIO Flow support in LPUART) */ +#define GPIO_LPUART4_RTS (GPIO_PORT1 | GPIO_PIN14 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) /* GPIO_AD_B0_14 GPIO1_IO14 (GPIO only, no HW Flow control) */ + +/* GPS 1 */ + +#define GPIO_LPUART2_RX (GPIO_LPUART2_RX_1 | LPUART_IOMUX) /* GPIO_AD_B1_03 */ +#define GPIO_LPUART2_TX (GPIO_LPUART2_TX_1 | LPUART_IOMUX) /* GPIO_AD_B1_02 */ + +/* Telem 1 */ + +#define GPIO_LPUART3_RX (GPIO_LPUART3_RX_1 | LPUART_IOMUX) /* GPIO_AD_B1_07 */ +#define GPIO_LPUART3_TX (GPIO_LPUART3_TX_1 | LPUART_IOMUX) /* GPIO_AD_B1_06 */ +#define GPIO_LPUART3_CTS (GPIO_LPUART3_CTS_1 | IOMUX_UART_CTS_DEFAULT | PADMUX_SION) /* GPIO_AD_B1_04 GPIO1_IO20 */ +#define GPIO_LPUART3_RTS (GPIO_PORT1 | GPIO_PIN21 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_UART_DEFAULT) /* GPIO_AD_B1_05 GPIO1_IO21 (GPIO only, no HW Flow control) */ +//TODO check RT7 partial HW handshake + +/* ESC ONEWIRE */ +#define GPIO_LPUART7_RX (GPIO_LPUART7_TX_1 | LPUART_IOMUX) /* GPIO_EMC_31 */ +#define GPIO_LPUART7_TX (GPIO_LPUART7_TX_1 | LPUART_IOMUX) /* GPIO_EMC_31 */ + + +/* RC INPUT single wire mode on Input on TX, for CRSF use TX and RX */ + +#define GPIO_LPUART8_RX (GPIO_LPUART8_RX_1 | LPUART_IOMUX) /* GPIO_AD_B1_11 */ +#define GPIO_LPUART8_TX (GPIO_LPUART8_TX_1 | LPUART_IOMUX) /* GPIO_AD_B1_10 */ + +/* CAN + * + * CAN1 is routed to transceiver. + * CAN2 is routed to transceiver. + * CAN3 is routed to transceiver. + */ +#define FLEXCAN_IOMUX (IOMUX_PULL_UP_100K | IOMUX_DRIVE_40OHM | IOMUX_SLEW_FAST | IOMUX_SPEED_MEDIUM) + +#define GPIO_FLEXCAN3_RX (GPIO_FLEXCAN3_RX_3 | FLEXCAN_IOMUX) /* GPIO_EMC_37 */ +#define GPIO_FLEXCAN3_TX (GPIO_FLEXCAN3_TX_3 | FLEXCAN_IOMUX) /* GPIO_EMC_36 */ + +/* LPSPI */ +#define LPSPI_IOMUX (IOMUX_PULL_UP_100K | IOMUX_DRIVE_33OHM | IOMUX_SLEW_FAST | IOMUX_SPEED_MAX) + + +#define GPIO_LPSPI3_SCK (GPIO_LPSPI3_SCK_1 | LPSPI_IOMUX) /* GPIO_AD_B1_15 */ +#define GPIO_LPSPI3_MISO (GPIO_LPSPI3_SDI_1 | LPSPI_IOMUX) /* GPIO_AD_B1_13 */ +#define GPIO_LPSPI3_MOSI (GPIO_LPSPI3_SDO_1 | LPSPI_IOMUX) /* GPIO_AD_B1_14 */ + +#define GPIO_LPSPI4_SCK (GPIO_LPSPI4_SCK_2 | LPSPI_IOMUX) /* GPIO_B0_03 */ +#define GPIO_LPSPI4_MISO (GPIO_LPSPI4_SDI_2 | LPSPI_IOMUX) /* GPIO_B0_01 */ +#define GPIO_LPSPI4_MOSI (GPIO_LPSPI4_SDO_2 | LPSPI_IOMUX) /* GPIO_B0_02 */ + +#define BOARD_SPI_BUS_MAX_BUS_ITEMS 2 + +/* LPI2Cs */ + +#define LPI2C_IOMUX (IOMUX_SPEED_MEDIUM | IOMUX_DRIVE_33OHM | IOMUX_OPENDRAIN | GPIO_SION_ENABLE) +#define LPI2C_IO_IOMUX (IOMUX_SPEED_MAX | IOMUX_SLEW_FAST | IOMUX_DRIVE_33OHM | IOMUX_OPENDRAIN | IOMUX_PULL_NONE) + +#define GPIO_LPI2C1_SDA (GPIO_LPI2C1_SDA_2 | LPI2C_IOMUX) /* EVK J24-9 R276 */ /* GPIO_AD_B1_01 */ +#define GPIO_LPI2C1_SCL (GPIO_LPI2C1_SCL_2 | LPI2C_IOMUX) /* EVK J24-10 R277 */ /* GPIO_AD_B1_00 */ + +#define GPIO_LPI2C1_SDA_RESET (GPIO_PORT1 | GPIO_PIN17 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_AD_B1_01 GPIO1_IO17 */ +#define GPIO_LPI2C1_SCL_RESET (GPIO_PORT1 | GPIO_PIN16 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_AD_B1_00 GPIO1_IO16 */ + +#define GPIO_LPI2C3_SDA (GPIO_LPI2C3_SDA_2 | LPI2C_IOMUX) /* GPIO_EMC_21 */ +#define GPIO_LPI2C3_SCL (GPIO_LPI2C3_SCL_2 | LPI2C_IOMUX) /* GPIO_EMC_22 */ + +#define GPIO_LPI2C3_SDA_RESET (GPIO_PORT4 | GPIO_PIN21 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_EMC_21 */ +#define GPIO_LPI2C3_SCL_RESET (GPIO_PORT4 | GPIO_PIN22 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_EMC_22 */ + +#define GPIO_LPI2C4_SDA (GPIO_LPI2C4_SDA_1 | LPI2C_IOMUX) /* GPIO_AD_B0_13 */ +#define GPIO_LPI2C4_SCL (GPIO_LPI2C4_SCL_1 | LPI2C_IOMUX) /* GPIO_AD_B0_12 */ + +#define GPIO_LPI2C4_SDA_RESET (GPIO_PORT1 | GPIO_PIN13 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_AD_B0_13 */ +#define GPIO_LPI2C4_SCL_RESET (GPIO_PORT1 | GPIO_PIN12 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LPI2C_IO_IOMUX) /* GPIO_AD_B0_12 */ + +#define BOARD_PHY_ADDR (18) + +/* Board doesn't provide GPIO or other Hardware for signaling to timing analyzer */ + +#define PROBE_INIT(mask) +#define PROBE(n,s) +#define PROBE_MARK(n) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __NUTTX_CONFIG_NXP_TROPIC_INCLUDE_BOARD_H */ diff --git a/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig b/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..1811763a82 --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/nsh/defconfig @@ -0,0 +1,270 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MW is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/nxp/mr-tropic/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_ITCM=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU=y +CONFIG_ARM_MPU_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_LOOPSPERMSEC=115000 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_PRODUCTID=0x0025 +CONFIG_CDCACM_PRODUCTSTR="PX4 MR-TROPIC" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1FC9 +CONFIG_CDCACM_VENDORSTR="NXP SEMICONDUCTORS" +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_DEV_URANDOM=y +CONFIG_ETH0_PHY_TJA1103=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FSUTILS_IPCFG=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_LITTLEFS=y +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=2 +CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=64 +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_DTCM_HEAP=y +CONFIG_IMXRT_DTCM_HEAP_SIZE=127 +CONFIG_IMXRT_EDMA=y +CONFIG_IMXRT_EDMA_EDBG=y +CONFIG_IMXRT_EDMA_ELINK=y +CONFIG_IMXRT_EDMA_NTCD=64 +CONFIG_IMXRT_ENET=y +CONFIG_IMXRT_ENET_NTXBUFFERS=8 +CONFIG_IMXRT_ENET_PHYINIT=y +CONFIG_IMXRT_FLEXCAN3=y +CONFIG_IMXRT_FLEXCAN_TXMB=1 +CONFIG_IMXRT_GPIO1_0_15_IRQ=y +CONFIG_IMXRT_GPIO1_16_31_IRQ=y +CONFIG_IMXRT_GPIO2_0_15_IRQ=y +CONFIG_IMXRT_GPIO2_16_31_IRQ=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_INIT_FLEXRAM=y +CONFIG_IMXRT_ITCM=384 +CONFIG_IMXRT_LPI2C1=y +CONFIG_IMXRT_LPI2C3=y +CONFIG_IMXRT_LPI2C4=y +CONFIG_IMXRT_LPI2C_DMA=y +CONFIG_IMXRT_LPI2C_DMA_MAXMSG=16 +CONFIG_IMXRT_LPI2C_DYNTIMEO=y +CONFIG_IMXRT_LPI2C_DYNTIMEO_STARTSTOP=10 +CONFIG_IMXRT_LPSPI3=y +CONFIG_IMXRT_LPSPI3_DMA=y +CONFIG_IMXRT_LPSPI4=y +CONFIG_IMXRT_LPSPI4_DMA=y +CONFIG_IMXRT_LPSPI_DMA=y +CONFIG_IMXRT_LPUART2=y +CONFIG_IMXRT_LPUART3=y +CONFIG_IMXRT_LPUART4=y +CONFIG_IMXRT_LPUART5=y +CONFIG_IMXRT_LPUART6=y +CONFIG_IMXRT_LPUART7=y +CONFIG_IMXRT_LPUART8=y +CONFIG_IMXRT_LPUART_INVERT=y +CONFIG_IMXRT_LPUART_SINGLEWIRE=y +CONFIG_IMXRT_PHY_POLLING=y +CONFIG_IMXRT_SNVS_LPSRTC=y +CONFIG_IMXRT_USBDEV=y +CONFIG_IMXRT_USDHC1=y +CONFIG_IMXRT_USDHC1_INVERT_CD=y +CONFIG_IMXRT_USDHC1_WIDTH_D1_D4=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=2944 +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_THROTTLE=0 +CONFIG_IPCFG_BINARY=y +CONFIG_IPCFG_PATH="/fs/nor" +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_LPI2C1_DMA=y +CONFIG_LPI2C3_DMA=y +CONFIG_LPI2C4_DMA=y +CONFIG_LPUART2_RXDMA=y +CONFIG_LPUART2_TXDMA=y +CONFIG_LPUART3_BAUD=57600 +CONFIG_LPUART3_IFLOWCONTROL=y +CONFIG_LPUART3_OFLOWCONTROL=y +CONFIG_LPUART3_RXBUFSIZE=600 +CONFIG_LPUART3_RXDMA=y +CONFIG_LPUART3_TXBUFSIZE=3000 +CONFIG_LPUART3_TXDMA=y +CONFIG_LPUART4_BAUD=57600 +CONFIG_LPUART4_IFLOWCONTROL=y +CONFIG_LPUART4_RXBUFSIZE=600 +CONFIG_LPUART4_RXDMA=y +CONFIG_LPUART4_TXBUFSIZE=3000 +CONFIG_LPUART4_TXDMA=y +CONFIG_LPUART5_BAUD=57600 +CONFIG_LPUART5_IFLOWCONTROL=y +CONFIG_LPUART5_OFLOWCONTROL=y +CONFIG_LPUART5_RXBUFSIZE=600 +CONFIG_LPUART5_RXDMA=y +CONFIG_LPUART5_TXBUFSIZE=3000 +CONFIG_LPUART5_TXDMA=y +CONFIG_LPUART6_BAUD=57600 +CONFIG_LPUART6_SERIAL_CONSOLE=y +CONFIG_LPUART7_RXDMA=y +CONFIG_LPUART7_TXBUFSIZE=128 +CONFIG_LPUART8_BAUD=420000 +CONFIG_LPUART8_RXBUFSIZE=600 +CONFIG_LPUART8_RXDMA=y +CONFIG_LPUART8_TXDMA=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MM_REGIONS=2 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_NAME_MAX=40 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDB_DNSSERVER_NOADDR=y +CONFIG_NETDEV_CAN_BITRATE_IOCTL=y +CONFIG_NETDEV_CAN_FILTER_IOCTL=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_DNSIPADDR=0XC0A800FE +CONFIG_NETINIT_DRIPADDR=0XC0A800FE +CONFIG_NETINIT_MONITOR=y +CONFIG_NETINIT_RETRY_MOUNTPATH=10 +CONFIG_NETINIT_THREAD=y +CONFIG_NETINIT_THREAD_PRIORITY=49 +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_ARP_IPIN=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_CAN=y +CONFIG_NET_CAN_EXTID=y +CONFIG_NET_CAN_NOTIFIER=y +CONFIG_NET_CAN_RAW_TX_DEADLINE=y +CONFIG_NET_CAN_SOCK_OPTS=y +CONFIG_NET_ETH_PKTSIZE=1518 +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_IGMP=y +CONFIG_NET_SOLINGER=y +CONFIG_NET_TCP=y +CONFIG_NET_TCPBACKLOG=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_KEEPALIVE=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_TIMESTAMP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NET_UDP_WRITE_BUFFERS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_READLINE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_TELNET_LOGIN=y +CONFIG_NSH_VARS=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=1048576 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1800 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=2032 +CONFIG_SDIO_BLOCKSETUP=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_CLE=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_DUALSPEED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/bootloader_script.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..81fb1e0c40 --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,177 @@ +/**************************************************************************** + * boards/nxp/mr-tropic/nuttx-config/scripts/bootloader_script.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Specify the memory areas */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x70000000, LENGTH = 128K + sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512K + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 384K + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +EXTERN(g_flash_config) +EXTERN(g_image_vector_table) +EXTERN(g_boot_data) +EXTERN(board_get_manifest) +EXTERN(_bootdelay_signature) + +ENTRY(_stext) + +SECTIONS +{ + /* Image Vector Table and Boot Data for booting from external flash */ + + .boot_hdr : ALIGN(4) + { + FILL(0xff) + __boot_hdr_start__ = ABSOLUTE(.) ; + KEEP(*(.boot_hdr.conf)) + . = 0x1000 ; + KEEP(*(.boot_hdr.ivt)) + . = 0x1020 ; + KEEP(*(.boot_hdr.boot_data)) + . = 0x1030 ; + KEEP(*(.boot_hdr.dcd_data)) + __boot_hdr_end__ = ABSOLUTE(.) ; + . = 0x2000 ; + } >flash + + .vectors : + { + KEEP(*(.vectors)) + *(.text .text.__start) + } >flash + + .itcmfunc : + { + . = ALIGN(8); + _sitcmfuncs = ABSOLUTE(.); + FILL(0xFF) + . = 0x40 ; + *(.ram_vectors) + . = ALIGN(8); + _eitcmfuncs = ABSOLUTE(.); + } > itcm AT > flash + + _fitcmfuncs = LOADADDR(.itcmfunc); + + .text : ALIGN(4) + { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + . = ALIGN(4096); + _etext = ABSOLUTE(.); + _srodata = ABSOLUTE(.); + *(.rodata .rodata.*) + . = ALIGN(4096); + _erodata = ABSOLUTE(.); + } > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : + { + *(.ARM.extab*) + } > flash + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } > flash + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .ramfunc ALIGN(4): + { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > sram AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + _boot_loadaddr = ORIGIN(flash); + _boot_size = LENGTH(flash); + _ram_size = LENGTH(sram); + _sdtcm = ORIGIN(dtcm); + _edtcm = ORIGIN(dtcm) + LENGTH(dtcm); +} diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_functions_includes.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_functions_includes.ld new file mode 100644 index 0000000000..36330c1e85 --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_functions_includes.ld @@ -0,0 +1,719 @@ +*(.text._ZN4uORB7Manager27orb_add_internal_subscriberE6ORB_IDhPj) +*(.text._ZN13MavlinkStream6updateERKy) +*(.text._ZN7Mavlink16update_rate_multEv) +*(.text._ZN3sym17PredictCovarianceIfEEN6matrix6MatrixIT_Lj23ELj23EEERKNS2_IS3_Lj24ELj1EEERKS4_RKNS2_IS3_Lj3ELj1EEES3_SC_SC_S3_S3_) /* itcm-check-ignore */ +*(.text._ZN13MavlinkStream12get_size_avgEv) +*(.text._ZN16ControlAllocator3RunEv) +*(.text._ZN22MulticopterRateControl3RunEv.part.0) +*(.text._ZN7Mavlink9task_mainEiPPc) +*(.text._ZN7sensors22VehicleAngularVelocity3RunEv) +*(.text._ZN4uORB12Subscription9subscribeEv.part.0) +*(.text._ZN4uORB7Manager13orb_data_copyEPvS1_Rjb) +*(.text._ZN4uORB10DeviceNode5writeEP4filePKcj) +*(.text._ZN4uORB10DeviceNode7publishEPK12orb_metadataPvPKv) +*(.text._ZN4uORB12DeviceMaster19getDeviceNodeLockedEPK12orb_metadatah) +*(.text._Z12get_orb_meta6ORB_ID) +*(.text._ZN9ICM42688P12ProcessAccelERKyPKN20InvenSense_ICM42688P4FIFO4DATAEh) +*(.text._ZN3px49WorkQueue3RunEv) +*(.text._ZN9ICM42688P11ProcessGyroERKyPKN20InvenSense_ICM42688P4FIFO4DATAEh) +*(.text._ZN4EKF23RunEv) +*(.text._ZN7sensors10VehicleIMU7PublishEv) +*(.text._ZN4math17WelfordMeanVectorIfLj3EE6updateERKN6matrix6VectorIfLj3EEE) +*(.text._ZN7sensors10VehicleIMU10UpdateGyroEv) +*(.text._ZN9ICM42688P8FIFOReadERKyh) +*(.text._ZN3Ekf20controlGravityFusionERKN9estimator9imuSampleE) +*(.text._ZN16PX4Accelerometer10updateFIFOER19sensor_accel_fifo_s) +*(.text._ZN7sensors22VehicleAngularVelocity19CalibrateAndPublishERKyRKN6matrix7Vector3IfEES7_) +*(.text._ZN4uORB12Subscription10advertisedEv) +*(.text._ZNK15AttitudeControl6updateERKN6matrix10QuaternionIfEE) +*(.text._ZN7sensors10VehicleIMU11UpdateAccelEv) +*(.text.perf_set_elapsed.part.0) +*(.text._ZN4uORB12Subscription6updateEPv) +*(.text._ZN12PX4Gyroscope10updateFIFOER18sensor_gyro_fifo_s) +*(.text._ZN7sensors10VehicleIMU3RunEv) +*(.text.__aeabi_l2f) +*(.text._ZN39ControlAllocationSequentialDesaturation23computeDesaturationGainERKN6matrix6VectorIfLj16EEES4_) +*(.text.pthread_mutex_timedlock) +*(.text._ZN7sensors22VehicleAngularVelocity21FilterAngularVelocityEiPfi) +*(.text._ZN26MulticopterAttitudeControl3RunEv.part.0) +*(.text._ZN6device3SPI9_transferEPhS1_j) +*(.text._ZN15OutputPredictor21calculateOutputStatesEyRKN6matrix7Vector3IfEEfS4_f) +*(.text._ZN7sensors18VotedSensorsUpdate7imuPollER17sensor_combined_s) +*(.text._Z9rotate_3i8RotationRsS0_S0_) +*(.text.fs_getfilep) +*(.text.MEM_DataCopy0_1) +*(.text._ZN7sensors19VehicleAcceleration3RunEv) +*(.text.uart_ioctl) +*(.text._ZN26MulticopterPositionControl3RunEv.part.0) +*(.text.pthread_mutex_take) +*(.text._ZN14ImuDownSampler6updateERKN9estimator9imuSampleE) +*(.text._ZN39ControlAllocationSequentialDesaturation6mixYawEv) +*(.text._ZN16ControlAllocator25publish_actuator_controlsEv.part.0) +*(.text._ZN9ICM42688P7RunImplEv) +*(.text._ZN4uORB12Subscription9subscribeEv) +*(.text.param_get) +*(.text._ZN7sensors22VehicleAngularVelocity21SensorSelectionUpdateERKyb) +*(.text._ZN3px49WorkQueue3AddEPNS_8WorkItemE) +*(.text._ZN4EKF220PublishLocalPositionERKy) +*(.text._mav_finalize_message_chan_send) +*(.text._ZN7sensors22VehicleAngularVelocity16ParametersUpdateEb) +*(.text._ZN6events12SendProtocol6updateERKy) +*(.text._ZN6device3SPI8transferEPhS1_j) +*(.text._ZN27MavlinkStreamDistanceSensor4sendEv) +*(.text.hrt_call_internal) +*(.text._ZN39ControlAllocationSequentialDesaturation18mixAirmodeDisabledEv) +*(.text._ZN7Mavlink15get_free_tx_bufEv) +*(.text.nx_poll) +*(.text._ZN15MavlinkReceiver3runEv) +*(.text._ZN9ICM42688P18ProcessTemperatureEPKN20InvenSense_ICM42688P4FIFO4DATAEh) +*(.text._ZN15OutputPredictor19correctOutputStatesEyRKN6matrix10QuaternionIfEERKNS0_7Vector3IfEERK9LatLonAltS8_S8_) +*(.text._ZN3Ekf12predictStateERKN9estimator9imuSampleE) +*(.text._ZN3px46logger6Logger3runEv) +*(.text._ZN4uORB20SubscriptionInterval7updatedEv) +*(.text._ZN24MavlinkStreamCommandLong4sendEv) +*(.text._ZN9Commander3runEv) +*(.text._ZN3Ekf17predictCovarianceERKN9estimator9imuSampleE) +*(.text.wd_cancel) +*(.text._ZN7Sensors3RunEv) +*(.text.perf_end) +*(.text._ZN4uORB12Subscription7updatedEv) +*(.text._ZN13land_detector12LandDetector3RunEv) +*(.text.sched_idletask) +*(.text.atanf) +*(.text.uart_write) +*(.text.pthread_mutex_unlock) +*(.text.__ieee754_asinf) +*(.text.MEM_DataCopy0_2) +*(.text._ZN20MavlinkCommandSender13check_timeoutE17mavlink_channel_t) +*(.text._ZN16ControlAllocator32publish_control_allocator_statusEi) +*(.text.__ieee754_atan2f) +*(.text._ZNK18DynamicSparseLayer3getEt) +*(.text.__udivmoddi4) +*(.text._ZN8Failsafe17checkStateAndModeERKyRKN12FailsafeBase5StateERK16failsafe_flags_s) +*(.text._ZN29MavlinkStreamHygrometerSensor4sendEv) +*(.text.pthread_mutex_give) +*(.text._ZN3Ekf18controlFusionModesERKN9estimator9imuSampleE) +*(.text._ZN4cdev4CDev11poll_notifyEm) +*(.text.file_vioctl) +*(.text._ZN7sensors18VotedSensorsUpdate11sensorsPollER17sensor_combined_s) +*(.text.nxsig_nanosleep) +*(.text.sem_wait) +*(.text.perf_count_interval.part.0) +*(.text._ZN16ControlAllocator37update_effectiveness_matrix_if_neededE25EffectivenessUpdateReason) +*(.text.MEM_LongCopyJump) +*(.text.px4_arch_adc_sample) +*(.text._ZN31MulticopterHoverThrustEstimator3RunEv) +*(.text._ZNK17ControlAllocation20clipActuatorSetpointERN6matrix6VectorIfLj16EEE) +*(.text._ZN4uORB7Manager17get_device_masterEv) +*(.text._ZN13DataValidator3putEyPKfmh) +*(.text.cdcuart_ioctl) +*(.text.cdcacm_sndpacket) +*(.text._ZN7sensors22VehicleAngularVelocity16SensorBiasUpdateEb) +*(.text._ZN13MavlinkStream11update_dataEv) +*(.text._ZN7sensors18VotedSensorsUpdate21calcGyroInconsistencyEv) +*(.text.param_set_used) +*(.text._ZN18EstimatorInterface10setIMUDataERKN9estimator9imuSampleE) +*(.text._ZN18DataValidatorGroup8get_bestEyPi) +*(.text._ZN4EKF218PublishInnovationsERKy) +*(.text._ZN21MavlinkMissionManager4sendEv) +*(.text._ZN22MulticopterRateControl28updateActuatorControlsStatusERK25vehicle_torque_setpoint_sf) +*(.text._ZN11RateControl6updateERKN6matrix7Vector3IfEES4_S4_fb) +*(.text._ZN39ControlAllocationSequentialDesaturation19desaturateActuatorsERN6matrix6VectorIfLj16EEERKS2_b) +*(.text.imxrt_lpi2c_transfer) +*(.text.uart_putxmitchar) +*(.text.clock_nanosleep) +*(.text.up_release_pending) +*(.text.MEM_DataCopy0) +*(.text._ZN22MavlinkStreamGPSRawInt4sendEv) +*(.text.dq_rem) +*(.text._ZN15GyroCalibration3RunEv.part.0) +*(.text._ZN7sensors18VotedSensorsUpdate22calcAccelInconsistencyEv) +*(.text._ZN24MavlinkStreamADSBVehicle4sendEv) +*(.text.sinf) +*(.text.hrt_call_after) +*(.text._ZN39ControlAllocationSequentialDesaturation8allocateEv) +*(.text.up_invalidate_dcache) +*(.text._ZN15PositionControl16_velocityControlEf) +*(.text._ZN4EKF222PublishAidSourceStatusERKy) +*(.text._ZN4ListIP13MavlinkStreamE8IteratorppEv) +*(.text._ZN20MavlinkStreamESCInfo4sendEv) +*(.text.sem_post) +*(.text._ZN3px417ScheduledWorkItem15ScheduleDelayedEm) +*(.text._ZN10FlightTaskC1Ev) +*(.text.usleep) +*(.text._ZN14FlightTaskAutoC1Ev) +*(.text.sem_getvalue) +*(.text._ZN23MavlinkStreamHighresIMU4sendEv) +*(.text.imxrt_gpio_write) +*(.text._ZN3Ekf6updateEv) +*(.text.__ieee754_acosf) +*(.text._ZN3Ekf20updateIMUBiasInhibitERKN9estimator9imuSampleE) +*(.text._ZN9Commander13dataLinkCheckEv) +*(.text._ZN17FlightModeManager10switchTaskE15FlightTaskIndex) +*(.text._ZN12PX4Gyroscope9set_scaleEf) +*(.text._ZN12FailsafeBase6updateERKyRKNS_5StateEbbRK16failsafe_flags_s) +*(.text._ZN18MavlinkStreamDebug4sendEv) +*(.text._ZN27MavlinkStreamServoOutputRawILi0EE4sendEv) +*(.text.asinf) +*(.text._ZN6matrix5EulerIfEC1ERKNS_3DcmIfEE) +*(.text._ZN4EKF227PublishInnovationTestRatiosERKy) +*(.text._ZN4EKF213PublishStatusERKy) +*(.text._ZN4EKF226PublishInnovationVariancesERKy) +*(.text._ZN13land_detector23MulticopterLandDetector25_get_ground_contact_stateEv) +*(.text.imxrt_dmach_start) +*(.text._ZN3ADC19update_system_powerEy) +*(.text._ZNK3Ekf19get_ekf_soln_statusEv) +*(.text._ZN3px46logger15watchdog_updateERNS0_15watchdog_data_tEb) +*(.text.imxrt_gpio_read) +*(.text._ZN32MavlinkStreamNavControllerOutput4sendEv) +*(.text._ZN39MavlinkStreamGimbalDeviceAttitudeStatus4sendEv) +*(.text._ZNK10ConstLayer3getEt) +*(.text.__aeabi_uldivmod) +*(.text.up_udelay) +*(.text.up_idle) +*(.text._ZN20MavlinkStreamGPS2Raw4sendEv) +*(.text._ZN4EKF217UpdateCalibrationERKyRNS_19InFlightCalibrationERKN6matrix7Vector3IfEES8_fbb) +*(.text._ZN28MavlinkStreamGpsGlobalOrigin4sendEv) +*(.text._ZN11ControlMath15bodyzToAttitudeEN6matrix7Vector3IfEEfR27vehicle_attitude_setpoint_s) +*(.text._ZN4EKF217UpdateRangeSampleER17ekf2_timestamps_s) +*(.text._ZN3Ekf24controlOpticalFlowFusionERKN9estimator9imuSampleE) +*(.text._ZN19MavlinkStreamRawRpm4sendEv) +*(.text._ZN13MavlinkStream10const_rateEv) +*(.text._ZN4EKF215PublishOdometryERKyRKN9estimator9imuSampleE) +*(.text._ZN15FailureDetector20updateAttitudeStatusERK16vehicle_status_s) +*(.text._ZN7Mavlink19configure_sik_radioEv) +*(.text._ZN13BatteryStatus8adc_pollEv) +*(.text.getpid) +*(.text._ZN13DataValidator10confidenceEy) +*(.text._ZN22MavlinkStreamGPSStatus4sendEv) +*(.text._ZN4EKF220UpdateAirspeedSampleER17ekf2_timestamps_s) +*(.text._ZN23MavlinkStreamStatustext4sendEv) +*(.text.uart_poll) +*(.text._ZN24MavlinkParametersManager4sendEv) +*(.text._ZN26MulticopterPositionControl18set_vehicle_statesERK24vehicle_local_position_sf) +*(.text.file_poll) +*(.text.hrt_elapsed_time) +*(.text._ZN7Mavlink11send_finishEv) +*(.text._ZNK3Ekf36estimateInertialNavFallingLikelihoodEv) +*(.text._ZN15PositionControl16_positionControlEv) +*(.text._ZN28MavlinkStreamDebugFloatArray4sendEv) +*(.text._ZN11ControlMath9limitTiltERN6matrix7Vector3IfEERKS2_f) +*(.text.pthread_mutex_lock) +*(.text._ZN21MavlinkStreamAltitude8get_sizeEv) +*(.text._ZN7Mavlink29check_requested_subscriptionsEv) +*(.text.imxrt_lpspi_setmode) +*(.text._ZN3Ekf34controlZeroInnovationHeadingUpdateEv) +*(.text.perf_begin) +*(.text.imxrt_lpspi_setfrequency) +*(.text._ZN17FlightModeManager9_initTaskE15FlightTaskIndex) +*(.text._ZN22MulticopterRateControl3RunEv) +*(.text.cosf) +*(.text._ZN22MavlinkStreamESCStatus4sendEv) +*(.text._ZN26MavlinkStreamCameraTrigger4sendEv) +*(.text._ZN36MavlinkStreamPositionTargetGlobalInt4sendEv) +*(.text._ZN4uORB12Subscription4copyEPv) +*(.text._ZN7sensors19VehicleAcceleration21SensorSelectionUpdateEb) +*(.text.crc_accumulate) +*(.text._ZN3px46logger6Logger13update_paramsEv) +*(.text._ZN11calibration14DeviceExternalEm) +*(.text._ZN25MavlinkStreamHomePosition8get_sizeEv) +*(.text.imxrt_lpspi_modifyreg32) +*(.text._ZN7sensors19VehicleAcceleration16SensorBiasUpdateEb) +*(.text.modifyreg32) +*(.text._ZNK6matrix6MatrixIfLj3ELj1EEmlEf) +*(.text._ZN6matrix5EulerIfEC1ERKNS_10QuaternionIfEE) +*(.text.imxrt_queuedtd) +*(.text._ZN27MavlinkStreamDistanceSensor8get_sizeEv) +*(.text._ZN3Ekf23controlBaroHeightFusionERKN9estimator9imuSampleE) +*(.text._ZN16PX4Accelerometer9set_scaleEf) +*(.text._ZN11ControlMath11constrainXYERKN6matrix7Vector2IfEES4_RKf) +*(.text._ZN22MavlinkStreamEfiStatus4sendEv) +*(.text._ZN22MavlinkStreamDebugVect4sendEv) +*(.text._ZN4EKF217PublishSensorBiasERKy) +*(.text._ZN17FlightModeManager3RunEv) +*(.text._ZN15PositionControl11_inputValidEv) +*(.text._ZN7sensors14VehicleAirData3RunEv) +*(.text.perf_count) +*(.text._ZN3Ekf16controlMagFusionERKN9estimator9imuSampleE) +*(.text.pthread_sem_give) +*(.text._ZN7sensors10VehicleIMU16ParametersUpdateEb) +*(.text._ZN4uORB20SubscriptionInterval4copyEPv) +*(.text._ZN12I2CSPIDriverI9ICM42688PE3RunEv) +*(.text.imxrt_epcomplete.constprop.0) +*(.text._ZNK6matrix6MatrixIfLj3ELj1EEmiERKS1_) +*(.text._ZN9Commander30handleModeIntentionAndFailsafeEv) +*(.text.perf_event_count) +*(.text._ZN4EKF215PublishAttitudeERKy) +*(.text._ZN19MavlinkStreamRawRpm8get_sizeEv) +*(.text._ZNK3px46atomicIbE4loadEv) +*(.text._ZN29MavlinkStreamHygrometerSensor8get_sizeEv) +*(.text.pthread_mutex_add) +*(.text._ZN12HomePosition6updateEbb) +*(.text.poll_fdsetup) +*(.text._ZN15PositionControl20_accelerationControlEv) +*(.text._ZN3Ekf19controlHeightFusionERKN9estimator9imuSampleE) +*(.text._ZN9Commander19control_status_ledsEbh) +*(.text._ZN6device3I2C8transferEPKhjPhj) +*(.text.orb_publish) +*(.text._ZN7sensors19VehicleAcceleration16ParametersUpdateEb) +*(.text._ZN22MavlinkStreamVibration8get_sizeEv) +*(.text._ZN15MavlinkReceiver15CheckHeartbeatsERKyb) +*(.text._ZNK6matrix7Vector3IfEmiES1_) +*(.text.__aeabi_f2ulz) +*(.text._ZN9ICM42688P26DataReadyInterruptCallbackEiPvS0_) +*(.text._ZN13land_detector23MulticopterLandDetector23_get_maybe_landed_stateEv) +*(.text.acosf) +*(.text._ZN14ImuDownSampler5resetEv) +*(.text._ZN3Ekf31checkVerticalAccelerationHealthERKN9estimator9imuSampleE) +*(.text._ZN6matrix6MatrixIfLj3ELj1EEC1ERKS1_) +*(.text.udp_pollsetup) +*(.text._ZL14timer_callbackPv) +*(.text._ZN3Ekf4fuseERKN6matrix6VectorIfLj24EEEf) +*(.text._ZN13land_detector23MulticopterLandDetector22_set_hysteresis_factorEi) +*(.text.nxsem_wait_irq) +*(.text._ZN20MavlinkCommandSender4lockEv) +*(.text.MEM_LongCopyEnd) +*(.text._ZThn24_N16ControlAllocator3RunEv) +*(.text._ZN15TimestampedListIN20MavlinkCommandSender14command_item_sELi3EE8get_nextEv) +*(.text._ZNK3Ekf21get_ekf_lpos_accuracyEPfS0_) +*(.text._ZN17FlightModeManager17start_flight_taskEv) +*(.text.MEM_DataCopyBytes) +*(.text._ZN29MavlinkStreamLocalPositionNED8get_sizeEv) +*(.text._ZN6SticksC1EP12ModuleParams) +*(.text._ZN27MavlinkStreamServoOutputRawILi1EE4sendEv) +*(.text._ZN3Ekf35updateHorizontalDeadReckoningstatusEv) +*(.text._ZN3Ekf20controlAirDataFusionERKN9estimator9imuSampleE) +*(.text._ZN24FlightTaskManualAltitudeC1Ev) +*(.text._ZN25MavlinkStreamHomePosition4sendEv) +*(.text._ZN24MavlinkParametersManager8send_oneEv) +*(.text._ZN15OutputPredictor29applyCorrectionToOutputBufferERKN6matrix7Vector3IfEES4_) +*(.text._ZN21HealthAndArmingChecks6updateEbb) +*(.text._ZThn24_N22MulticopterRateControl3RunEv) +*(.text._ZN26MavlinkStreamManualControl4sendEv) +*(.text._ZN27MavlinkStreamOpticalFlowRad4sendEv) +*(.text._ZN18mag_bias_estimator16MagBiasEstimator3RunEv) +*(.text._ZN4uORB7Manager11orb_publishEPK12orb_metadataPvPKv) +*(.text._ZN24MavlinkParametersManager18send_untransmittedEv) +*(.text._ZN10MavlinkFTP4sendEv) +*(.text._ZN3Ekf27controlExternalVisionFusionERKN9estimator9imuSampleE) +*(.text.clock_gettime) +*(.text._ZN3ADC17update_adc_reportEy) +*(.text._ZN32MavlinkStreamGimbalManagerStatus4sendEv) +*(.text._ZN9LockGuardD1Ev) /* itcm-check-ignore */ +*(.text._ZN4EKF213PublishStatesERKy) +*(.text._ZN3ADC3RunEv) +*(.text._ZN6BMP38815compensate_dataEhPK16bmp3_uncomp_dataP9bmp3_data) +*(.text._ZN3Ekf20controlFakePosFusionEv) +*(.text._ZN11calibration9Gyroscope13set_device_idEm) +*(.text._ZN24MavlinkStreamOrbitStatus8get_sizeEv) +*(.text.imxrt_progressep) +*(.text.imxrt_gpio_configinput) +*(.text._ZN17FlightModeManager26generateTrajectorySetpointEfRK24vehicle_local_position_s) +*(.text._ZN7Sensors14diff_pres_pollEv) +*(.text._ZN21MavlinkStreamAttitude4sendEv) +*(.text._ZN4EKF220UpdateMagCalibrationERKy) +*(.text._ZN22MavlinkStreamEfiStatus8get_sizeEv) +*(.text._ZN9ICM42688P9DataReadyEv) +*(.text._ZN21MavlinkMissionManager20check_active_missionEv) +*(.text._ZNK3Ekf20get_ekf_vel_accuracyEPfS0_) +*(.text._ZN4EKF216UpdateBaroSampleER17ekf2_timestamps_s) +*(.text._ZN4EKF223UpdateSystemFlagsSampleER17ekf2_timestamps_s) +*(.text._ZThn16_N7sensors22VehicleAngularVelocity3RunEv) +*(.text._ZN29MavlinkStreamObstacleDistance4sendEv) +*(.text._ZN24MavlinkStreamOrbitStatus4sendEv) +*(.text._ZN9Navigator3runEv) +*(.text._ZN24MavlinkParametersManager11send_paramsEv) +*(.text._ZN17MavlinkLogHandler4sendEv) +*(.text._ZN7control10SuperBlock5setDtEf) +*(.text._ZN29MavlinkStreamMountOrientation8get_sizeEv) +*(.text._ZN26MulticopterAttitudeControl3RunEv) +*(.text._ZThn16_N31ActuatorEffectivenessMultirotor22getEffectivenessMatrixERN21ActuatorEffectiveness13ConfigurationE25EffectivenessUpdateReason) +*(.text._ZN4EKF218PublishStatusFlagsERKy) +*(.text._ZN11WeatherVaneC1EP12ModuleParams) +*(.text._ZN15FailureDetector6updateERK16vehicle_status_sRK22vehicle_control_mode_s) +*(.text._ZN7Mavlink10send_startEi) +*(.text.imxrt_lpspi_setbits) +*(.text._ZN15OutputPredictor37applyCorrectionToVerticalOutputBufferEff) +*(.text._ZN4EKF222UpdateAccelCalibrationERKy) +*(.text._ZN7sensors19VehicleMagnetometer3RunEv) +*(.text._ZN29MavlinkStreamMountOrientation4sendEv) +*(.text._ZN13land_detector12LandDetector19UpdateVehicleAtRestEv) +*(.text._ZN10FlightTask29_evaluateVehicleLocalPositionEv) +*(.text.__aeabi_f2lz) +*(.text._ZN32MavlinkStreamCameraImageCaptured4sendEv) +*(.text._ZN21MavlinkStreamOdometry8get_sizeEv) +*(.text._ZN28MavlinkStreamNamedValueFloat4sendEv) +*(.text.__aeabi_ul2f) +*(.text.poll) +*(.text._ZN14FlightTaskAutoD1Ev) +*(.text._ZN4uORB10DeviceNode22get_initial_generationEv) +*(.text._ZN3Ekf23controlGnssHeightFusionERKN9estimator10gnssSampleE) +*(.text._ZN3Ekf40updateOnGroundMotionForOpticalFlowChecksEv) +*(.text._ZN6matrix6MatrixIfLj3ELj1EEC1Ev) +*(.text._ZN14ZeroGyroUpdate6updateER3EkfRKN9estimator9imuSampleE) +*(.text._ZN30MavlinkStreamOpenDroneIdSystem4sendEv) +*(.text._ZN22MavlinkStreamScaledIMU4sendEv) +*(.text.imxrt_ioctl) +*(.text._ZN36MavlinkStreamGimbalDeviceSetAttitude4sendEv) +*(.text._ZN4math13expo_deadzoneIfEEKT_RS2_S3_S3_.isra.0) +*(.text._ZN19StickAccelerationXYC1EP12ModuleParams) +*(.text.imxrt_epsubmit) +*(.text._ZN15PositionControl6updateEf) +*(.text._ZN23MavlinkStreamScaledIMU24sendEv) +*(.text.imxrt_dma_send) +*(.text._ZN20MavlinkStreamWindCov4sendEv) +*(.text._ZN7sensors18VotedSensorsUpdate13checkFailoverERNS0_10SensorDataEPKcN6events3px45enums13sensor_type_tE) +*(.text._ZN21MavlinkStreamOdometry4sendEv) +*(.text.vsprintf_internal.constprop.0) +*(.text.udp_pollteardown) +*(.text._ZN12MixingOutput6updateEv) +*(.text.clock_abstime2ticks) +*(.text._ZN13BatteryStatus3RunEv) +*(.text._ZN32MavlinkStreamGimbalManagerStatus8get_sizeEv) +*(.text._ZN10FlightTask15_resetSetpointsEv) +*(.text._ZN9systemlib10Hysteresis20set_state_and_updateEbRKy) +*(.text.devif_callback_free.part.0) +*(.text._ZN6Sticks25checkAndUpdateStickInputsEv) +*(.text.atan2f) +*(.text._ZN23MavlinkStreamRCChannels4sendEv) +*(.text._ZN4EKF221UpdateExtVisionSampleER17ekf2_timestamps_s) +*(.text.imxrt_dmach_stop) +*(.text._ZN9Commander16handleAutoDisarmEv) +*(.text._ZN9Commander11updateTunesEv) +*(.text._ZN4EKF215UpdateMagSampleER17ekf2_timestamps_s) +*(.text._ZN18DataValidatorGroup3putEjyPKfmh) +*(.text._ZNK3Ekf19get_ekf_ctrl_limitsEPfS0_S0_S0_S0_) +*(.text._ZN12FailsafeBase13checkFailsafeEibbRKNS_13ActionOptionsE) +*(.text._ZN17FlightTaskDescendD1Ev) +*(.text._ZN30MavlinkStreamOpenDroneIdSystem8get_sizeEv) +*(.text._ZNK3px46logger9LogWriter10is_startedENS0_7LogTypeE) +*(.text._ZN24FlightTaskManualAltitudeD1Ev) +*(.text._Z35px4_indicate_external_reset_lockout16LockoutComponentb) +*(.text.uart_pollnotify) +*(.text._ZN4EKF215PublishBaroBiasERKy) +*(.text._ZN4EKF221UpdateGyroCalibrationERKy) +*(.text._ZN6matrix9constrainIfLj3ELj1EEENS_6MatrixIT_XT0_EXT1_EEERKS3_S2_S2_) +*(.text._ZN4uORB22SubscriptionMultiArrayI16battery_status_sLh3EE16advertised_countEv) +*(.text._ZN23MavlinkStreamScaledIMU34sendEv) +*(.text.__aeabi_ldivmod) +*(.text._ZN15PositionControl16setInputSetpointERK21trajectory_setpoint_s) +*(.text.nxsig_pendingset) +*(.text.psock_poll) +*(.text._ZN15FailureInjector6updateEv) +*(.text.imxrt_writedtd) +*(.text.cdcacm_wrcomplete) +*(.text.cdcuart_txint) +*(.text._ZN3Ekf33updateVerticalDeadReckoningStatusEv) +*(.text._ZN33FlightTaskManualAltitudeSmoothVelC1Ev) +*(.text.powf) +*(.text._ZN4EKF217PublishEventFlagsERKy) +*(.text._ZN17FlightTaskDescend6updateEv) +*(.text.imxrt_iomux_configure) +*(.text.hrt_store_absolute_time) +*(.text.nxsem_set_protocol) +*(.text.write) +*(.text._ZN22MavlinkStreamSysStatus4sendEv) +*(.text._ZN4EKF216UpdateFlowSampleER17ekf2_timestamps_s) +*(.text._ZN4cdevL10cdev_ioctlEP4fileim) +*(.text._ZN7Mavlink10send_bytesEPKhj) +*(.text._ZNK8Failsafe17checkModeFallbackERK16failsafe_flags_sh) +*(.text.clock_systime_timespec) +*(.text._ZN4uORB10DeviceNode26remove_internal_subscriberEv) +*(.text._ZThn16_N4EKF23RunEv) +*(.text._ZNK3Ekf22computeYawInnovVarAndHEfRfRN6matrix6VectorIfLj24EEE) +*(.text._ZN12ActuatorTest6updateEif) +*(.text._ZN17VelocitySmoothingC1Efff) +*(.text._ZN13AnalogBattery19get_voltage_channelEv) +*(.text._ZN10FlightTask37_evaluateVehicleLocalPositionSetpointEv) +*(.text._ZN4uORB12Subscription11unsubscribeEv) +*(.text.net_lock) +*(.text.clock_time2ticks) +*(.text._ZN12FailsafeBase16updateStartDelayERKyb) +*(.text._ZN23MavlinkStreamStatustext8get_sizeEv) +*(.text._ZN11calibration13Accelerometer13set_device_idEm) +*(.text._ZN3px46logger6Logger18start_stop_loggingEv) +*(.text._ZN14FlightTaskAuto17_evaluateTripletsEv) +*(.text._ZN11calibration9Gyroscope23SensorCorrectionsUpdateEb) +*(.text._ZN25MavlinkStreamMagCalReport4sendEv) +*(.text.imxrt_config_gpio) +*(.text.nxsig_timeout) +*(.text._ZN11RateControl19setSaturationStatusERKN6matrix7Vector3IbEES4_) +*(.text._ZN3Ekf17measurementUpdateERN6matrix6VectorIfLj24EEERKS2_ff) +*(.text.dq_addlast) +*(.text._ZN19MavlinkStreamVFRHUD4sendEv) +*(.text.hrt_call_reschedule) +*(.text.nxsem_boost_priority) +*(.text._ZN4EKF215UpdateGpsSampleER17ekf2_timestamps_s) +*(.text._ZN8StickYawC1EP12ModuleParams) +*(.text._ZN7control12BlockLowPass6updateEf) +*(.text._ZN15FailureDetector26updateImbalancedPropStatusEv) +*(.text._ZN9systemlib10Hysteresis6updateERKy) +*(.text.nxsem_tickwait_uninterruptible) +*(.text._ZN12HomePosition31hasMovedFromCurrentHomeLocationEv) +*(.text.devif_callback_alloc) +*(.text._ZN28MavlinkStreamNamedValueFloat8get_sizeEv) +*(.text._ZN24MavlinkStreamADSBVehicle8get_sizeEv) +*(.text._ZN26MavlinkStreamBatteryStatus8get_sizeEv) +*(.text._ZN26MulticopterPositionControl17parameters_updateEb) +*(.text._ZN3px46logger6Logger29handle_vehicle_command_updateEv) +*(.text.imxrt_lpspi_send) +*(.text._ZN4uORB10DeviceNode23add_internal_subscriberEv) +*(.text._ZN6matrix6MatrixIfLj3ELj1EEaSERKS1_) +*(.text._ZNK6matrix6MatrixIfLj3ELj1EE5emultERKS1_) +*(.text.mallinfo_handler) +*(.text._ZN13land_detector23MulticopterLandDetector14_update_topicsEv) +*(.text._ZN24ManualVelocitySmoothingZC1Ev) /* itcm-check-ignore */ +*(.text._ZN3ADC6sampleEj) +*(.text._ZNK3Ekf22isTerrainEstimateValidEv) +*(.text._ZN15EstimatorChecks23setModeRequirementFlagsERK7ContextbbbRK24vehicle_local_position_sRK12sensor_gps_sR16failsafe_flags_sR6Report) +*(.text._ZN11ControlMath11addIfNotNanERff) +*(.text._ZN9Commander21checkForMissionUpdateEv) +*(.text._Z8set_tunei) +*(.text._ZNK6matrix7Vector3IfE5crossERKNS_6MatrixIfLj3ELj1EEE) +*(.text._ZN10FlightTask22_checkEkfResetCountersEv) +*(.text._ZNK6matrix6MatrixIfLj3ELj1EE11isAllFiniteEv) +*(.text._ZN14FlightTaskAuto24_evaluateGlobalReferenceEv) +*(.text._ZN6matrix9constrainIfLj2ELj1EEENS_6MatrixIT_XT0_EXT1_EEERKS3_S2_S2_) +*(.text._ZN3px46logger6Logger23handle_file_write_errorEv) +*(.text._ZN10FlightTask16updateInitializeEv) +*(.text._ZN11calibration9Gyroscope10set_offsetERKN6matrix7Vector3IfEE) +*(.text._ZNK6matrix6VectorIfLj3EE4normEv) +*(.text._ZN14FlightTaskAuto16updateInitializeEv) +*(.text.fabsf) +*(.text._ZN27MavlinkStreamAttitudeTarget8get_sizeEv) +*(.text.nxsem_get_value) +*(.text._ZN13AnalogBattery8is_validEv) +*(.text._ZN4uORB16SubscriptionDataI15home_position_sEC1EPK12orb_metadatah) +*(.text._ZN22MavlinkStreamGPSStatus8get_sizeEv) +*(.text.nxsem_destroyholder) +*(.text.psock_udp_cansend) +*(.text.MEM_DataCopy2_2) +*(.text._ZN10FlightTask8activateERK21trajectory_setpoint_s) +*(.text.sock_file_poll) +*(.text._ZN10Ringbuffer9pop_frontEPhj) +*(.text.nx_write) +*(.text._ZN9Commander18manualControlCheckEv) +*(.text._ZN31MavlinkStreamAttitudeQuaternion4sendEv) +*(.text.nxsem_canceled) +*(.text._ZN10FlightTask21getTrajectorySetpointEv) +*(.text.imxrt_dmach_getcount) +*(.text.sem_clockwait) +*(.text.inet_poll) +*(.text._ZN6BMP3887collectEv) +*(.text._ZNK15PositionControl24getLocalPositionSetpointER33vehicle_local_position_setpoint_s) +*(.text._ZN3Ekf16controlGpsFusionERKN9estimator9imuSampleE) +*(.text._ZN23MavlinkStreamRCChannels8get_sizeEv) +*(.text._ZN20MavlinkStreamESCInfo8get_sizeEv) +*(.text._ZNK6matrix6VectorIfLj2EE4normEv) +*(.text._Z15arm_auth_updateyb) +*(.text._ZN3LED5ioctlEP4fileim) /* itcm-check-ignore */ +*(.text._ZNK3px46logger9LogWriter20had_file_write_errorEv) +*(.text._ZN29MavlinkStreamLocalPositionNED4sendEv) +*(.text._ZNK6matrix6VectorIfLj3EE3dotERKNS_6MatrixIfLj3ELj1EEE) +*(.text.imxrt_lpi2c_setclock) +*(.text._ZN6matrix12typeFunction9constrainIfEET_S2_S2_S2_.part.0) +*(.text._ZN13MapProjection13initReferenceEddy) +*(.text._ZN11calibration13Accelerometer23SensorCorrectionsUpdateEb) +*(.text._ZN31MavlinkStreamAttitudeQuaternion8get_sizeEv) +*(.text._ZN30MavlinkStreamGlobalPositionInt4sendEv) +*(.text._ZN6SticksD1Ev) +*(.text._ZN13NavigatorMode3runEb) +*(.text._ZL19param_find_internalPKcb) +*(.text.uart_datasent) +*(.text._ZN4EKF221PublishOpticalFlowVelERKy) +*(.text.nxsem_destroy) +*(.text.file_write) +*(.text._ZN21MavlinkStreamAltitude4sendEv) +*(.text._ZN7sensors14VehicleAirData12UpdateStatusEv) +*(.text.imxrt_padmux_map) +*(.text._ZN6BMP38815get_sensor_dataEhP9bmp3_data) +*(.text._ZN18MavlinkRateLimiter5checkERKy) +*(.text._ZThn24_N26MulticopterAttitudeControl3RunEv) +*(.text.imxrt_periphclk_configure) +*(.text._ZN4EKF218UpdateAuxVelSampleER17ekf2_timestamps_s) +*(.text._ZN3RTL11on_inactiveEv) +*(.text._ZN12FailsafeBase10modeCanRunERK16failsafe_flags_sh) +*(.text._ZN4EKF216PublishEvPosBiasERKy) +*(.text._ZN21MavlinkStreamAttitude8get_sizeEv) +*(.text._ZThn16_N7sensors19VehicleAcceleration3RunEv) +*(.text._ZN33MavlinkStreamTimeEstimateToTarget4sendEv) +*(.text._ZN6matrix6MatrixIfLj3ELj1EE6setAllEf) +*(.text._ZN12ModuleParamsD1Ev) +*(.text._ZN3Ekf20controlFakeHgtFusionEv) +*(.text.imxrt_reqcomplete) +*(.text._ZNK6matrix7Vector3IfEmlEf) +*(.text._ZN18ZeroVelocityUpdate6updateER3EkfRKN9estimator9imuSampleE) +*(.text._ZN11ControlMath19addIfNotNanVector3fERN6matrix7Vector3IfEERKS2_) +*(.text._ZN11ControlMath16thrustToAttitudeERKN6matrix7Vector3IfEEfR27vehicle_attitude_setpoint_s) +*(.text.cos) +*(.text.net_unlock) +*(.text._ZN7sensors18VotedSensorsUpdate21setRelativeTimestampsER17sensor_combined_s) +*(.text._ZN12FailsafeBase13ActionOptionsC1ENS_6ActionE) +*(.text._ZN24FlightTaskManualAltitude16updateInitializeEv) +*(.text._ZN26MulticopterPositionControl3RunEv) +*(.text._ZN8Failsafe21fromQuadchuteActParamEi) +*(.text._ZN24VariableLengthRingbuffer9pop_frontEPhj) +*(.text._ZN7control15BlockDerivative6updateEf) /* itcm-check-ignore */ +*(.text._ZN9Commander18safetyButtonUpdateEv) +*(.text._ZN13BatteryChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN18DataValidatorGroup16get_sensor_stateEj) +*(.text.uart_xmitchars_done) +*(.text._ZN4EKF225PublishYawEstimatorStatusERKy) +*(.text.sin) +*(.text._ZN6Safety19safetyButtonHandlerEv) +*(.text._ZN3Ekf19controlAuxVelFusionERKN9estimator9imuSampleE) +*(.text._ZNK6matrix6MatrixIfLj2ELj1EEplERKS1_) +*(.text._ZThn24_N7Sensors3RunEv) +*(.text._ZN6matrix6MatrixIfLj2ELj1EEC1ERKS1_) +*(.text._ZN10FlightTask10reActivateEv) +*(.text._ZNK15PositionControl19getAttitudeSetpointER27vehicle_attitude_setpoint_s) +*(.text._ZN4cdev4CDev4pollEP4fileP6pollfdb) +*(.text._ZN9Commander20offboardControlCheckEv) +*(.text._ZN4EKF216PublishGpsStatusERKy) +*(.text._ZN4uORB12SubscriptionaSEOS0_) +*(.text._ZN15TakeoffHandling18updateTakeoffStateEbbbfbRKy) +*(.text._ZN10ModeChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN14FlightTaskAuto24_updateInternalWaypointsEv) +*(.text._ZN8Failsafe17updateArmingStateERKybRK16failsafe_flags_s) +*(.text.imxrt_lpi2c_modifyreg) +*(.text.up_flush_dcache) +*(.text._ZN15GyroCalibration3RunEv) +*(.text.mavlink_start_uart_send) +*(.text.MEM_DataCopy2) +*(.text._ZNK9Commander14getPrearmStateEv) +*(.text._ZN15EstimatorChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN28FlightTaskManualAccelerationD1Ev) +*(.text._ZN11RateControl20getRateControlStatusER18rate_ctrl_status_s) +*(.text._ZN4uORB10DeviceNode15poll_notify_oneEP6pollfdm) +*(.text._ZN3GPS21handleInjectDataTopicEv.part.0) +*(.text._ZN9Commander17systemPowerUpdateEv) +*(.text._ZN4EKF221PublishGlobalPositionERKy) +*(.text._ZNK12FailsafeBase17getSelectedActionERKNS_5StateERK16failsafe_flags_sbbRNS_19SelectedActionStateE) +*(.text.imxrt_padctl_address) +*(.text._ZNK6matrix6VectorIfLj2EE4unitEv) +*(.text._ZN19RcCalibrationChecks14checkAndReportERK7ContextR6Report) +*(.text.devif_conn_callback_free) +*(.text._ZN13InnovationLpf6updateEfff.isra.0) +*(.text._ZN9Commander18landDetectorUpdateEv) +*(.text._ZN3Ekf18updateGroundEffectEv) +*(.text.nxsem_init) +*(.text._ZN9Commander16vtolStatusUpdateEv) +*(.text._ZN6matrix6MatrixIfLj4ELj1EEC1EPKf) +*(.text._ZN11ControlMath20setZeroIfNanVector3fERN6matrix7Vector3IfEE) +*(.text._ZThn8_N3ADC3RunEv) +*(.text._ZN11StickTiltXYC1EP12ModuleParams) +*(.text._ZN12SafetyButton3RunEv) +*(.text._ZN6BMP38811set_op_modeEh) +*(.text._ZN3GPS8callbackE15GPSCallbackTypePviS1_) +*(.text._ZN13AnalogBattery19get_current_channelEv) +*(.text._ZN15EstimatorChecks20checkEstimatorStatusERK7ContextR6ReportRK18estimator_status_s8NavModes) +*(.text._ZN12FailsafeBase11updateDelayERKy) +*(.text._ZN10FlightTask25_evaluateDistanceToGroundEv) +*(.text._ZN4EKF218PublishGnssHgtBiasERKy) +*(.text._ZN6matrix6VectorIfLj3EE9normalizeEv) +*(.text._ZThn16_N7sensors10VehicleIMU3RunEv) +*(.text.__kernel_cos) +*(.text._ZN12SafetyButton19CheckPairingRequestEb) +*(.text.imxrt_dma_txavailable) +*(.text.perf_set_elapsed) +*(.text.pthread_sem_take) +*(.text._ZN8StickYawD1Ev) +*(.text._Z15blink_msg_statev) +*(.text._ZN19AccelerometerChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN8Failsafe14fromGfActParamEi) +*(.text._ZN3Ekf17controlBetaFusionERKN9estimator9imuSampleE) +*(.text._ZN36do_not_explicitly_use_this_namespace5ParamIfLN3px46paramsE919EEC1Ev) /* itcm-check-ignore */ +*(.text._ZN22MavlinkStreamHeartbeat8get_sizeEv) +*(.text._ZN6matrix6MatrixIfLj3ELj1EEdVEf) +*(.text._ZN17FlightTaskDescendC1Ev) +*(.text._ZN26MavlinkStreamCameraTrigger8get_sizeEv) +*(.text.iob_navail) +*(.text._ZN12FailsafeBase25removeNonActivatedActionsEv) +*(.text._ZN15TakeoffHandling10updateRampEff) +*(.text._Z7led_offi) +*(.text.led_off) +*(.text.udp_wrbuffer_test) +*(.text._ZNK4math17WelfordMeanVectorIfLj3EE8varianceEv) +*(.text._ZN27MavlinkStreamAttitudeTarget4sendEv) +*(.text._ZN12MixingOutput19updateSubscriptionsEb) +*(.text._ZN10FlightTaskD1Ev) +*(.text._ZThn24_N13land_detector12LandDetector3RunEv) +*(.text._ZN18MavlinkStreamDebug8get_sizeEv) +*(.text._ZN12GPSDriverUBX7receiveEj) +*(.text._ZN13BatteryStatus21parameter_update_pollEb) +*(.text._ZN3RTL18updateDatamanCacheEv) +*(.text.__ieee754_sqrtf) +*(.text._ZThn24_N18mag_bias_estimator16MagBiasEstimator3RunEv) +*(.text.__kernel_sin) +*(.text._ZN11MissionBase17parameters_updateEv) +*(.text.nx_start) +*(.text._ZN3Ekf17controlDragFusionERKN9estimator9imuSampleE) +*(.text._ZNK8Failsafe22modifyUserIntendedModeEN12FailsafeBase6ActionES1_h) +*(.text._ZN3px417ScheduledWorkItem19schedule_trampolineEPv) +*(.text.uart_xmitchars_dma) +*(.text._ZN13land_detector23MulticopterLandDetector19_get_freefall_stateEv) +*(.text._ZThn24_N31MulticopterHoverThrustEstimator3RunEv) +*(.text._ZN11MissionBase11on_inactiveEv) +*(.text._ZN21FailureDetectorChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN12SystemChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN6matrix6MatrixIfLj3ELj1EEC1EPKf) +*(.text.imxrt_padmux_address) +*(.text._ZN19MavlinkStreamVFRHUD8get_sizeEv) +*(.text._ZN15EstimatorChecks15checkSensorBiasERK7ContextR6Report8NavModes) +*(.text._ZN20ImuConsistencyChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN28MavlinkStreamGpsGlobalOrigin8get_sizeEv) +*(.text.MEM_DataCopy2_1) +*(.text._ZN6BMP3887measureEv) +*(.text._ZN4EKF217PublishRngHgtBiasERKy) +*(.text._ZN36MavlinkStreamPositionTargetGlobalInt8get_sizeEv) +*(.text._ZN28MavlinkStreamEstimatorStatus8get_sizeEv) +*(.text.up_clean_dcache) +*(.text._ZThn24_N26MulticopterPositionControl3RunEv) +*(.text._ZN16FlightTimeChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN13ManualControl12processInputEy) +*(.text._ZN17CpuResourceChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN10GyroChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN8Failsafe26fromImbalancedPropActParamEi) +*(.text._ZThn24_N13BatteryStatus3RunEv) +*(.text.mm_foreach) +*(.text._ZN35MavlinkStreamPositionTargetLocalNed8get_sizeEv) +*(.text._ZN32MavlinkStreamNavControllerOutput8get_sizeEv) +*(.text._ZN6matrix8wrap_2piIfEET_S1_) +*(.text._ZN4uORB7Manager30orb_remove_internal_subscriberEPv) +*(.text._ZN10BMP388_I2C7get_regEhPh) +*(.text._ZN4math17WelfordMeanVectorIfLj3EE5resetEv) +*(.text._ZN27MavlinkStreamScaledPressure8get_sizeEv) +*(.text._ZN3RTL17parameters_updateEv) +*(.text._ZN18EstimatorInterface11setBaroDataERKN9estimator10baroSampleE.part.0) +*(.text._ZN32MavlinkStreamOpenDroneIdLocation8get_sizeEv) +*(.text._ZN21MavlinkStreamTimesync4sendEv) +*(.text._ZN9Navigator23reset_position_setpointER19position_setpoint_s) +*(.text._ZN19RcAndDataLinkChecks14checkAndReportERK7ContextR6Report) +*(.text.imxrt_dma_txcallback) +*(.text._ZN24MavlinkParametersManager11send_uavcanEv) +*(.text._ZN4uORB10DeviceNode4readEP4filePcj) +*(.text._ZN4uORB10DeviceNode10poll_stateEP4file) +*(.text._ZN4uORB7Manager8orb_copyEPK12orb_metadataiPv) +*(.text._ZN27MavlinkStreamServoOutputRawILi0EE8get_sizeEv) +*(.text._ZN8Geofence3runEv) +*(.text._ZN15EstimatorChecks25checkEstimatorStatusFlagsERK7ContextR6ReportRK18estimator_status_sRK24vehicle_local_position_s) +*(.text._ZN18MagnetometerChecks14checkAndReportERK7ContextR6Report) +*(.text._ZN6events9SendEvent3RunEv) +*(.text._ZN30MavlinkStreamGlobalPositionInt8get_sizeEv) +*(.text._ZN22MavlinkStreamESCStatus8get_sizeEv) +*(.text._Z20px4_spi_bus_externalRK13px4_spi_bus_t) +*(.text.read) +*(.text._ZN4uORB15PublicationBaseD1Ev) +*(.text._ZN22MavlinkStreamDebugVect8get_sizeEv) +*(.text._ZN7Mission11on_inactiveEv) +*(.text._ZN7sensors19VehicleMagnetometer20UpdateMagCalibrationEv) +*(.text._ZN11calibration27FindCurrentCalibrationIndexEPKcm) +*(.text._ZN4cdevL9cdev_readEP4filePcj) +*(.text.sem_timedwait) +*(.text.snprintf) +*(.text._ZN27MavlinkStreamOpticalFlowRad8get_sizeEv) +*(.text._ZNK6matrix6MatrixIfLj3ELj1EE6copyToEPf) +*(.text._ZN6Report13healthFailureIJhEEEv8NavModes20HealthComponentIndexmRKN6events9LogLevelsEPKcDpT_.isra.0.constprop.0) +*(.text._ZN13BatteryChecks16rtlEstimateCheckERK7ContextR6Reportf) +*(.text.sigemptyset) +*(.text.nx_read) diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld new file mode 100644 index 0000000000..bc0b57099c --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/itcm_static_functions.ld @@ -0,0 +1,163 @@ +/* Static */ +*(.text.arm_ack_irq) +*(.text.arm_doirq) +*(.text.arm_svcall) +*(.text.arm_switchcontext) +*(.text.clock_timer) +*(.text.exception_common) +*(.text.flexio_irq_handler) +*(.text.hrt_absolute_time) +*(.text.hrt_call_enter) +*(.text.hrt_tim_isr) +*(.text.imxrt_configwaitints) +*(.text.imxrt_dma_callback) +*(.text.imxrt_dmach_interrupt) +*(.text.imxrt_dmach_xfrsetup) +*(.text.imxrt_dmaterminate) +*(.text.imxrt_dispatch) +*(.text.imxrt_edma_interrupt) +*(.text.imxrt_endwait) +*(.text.imxrt_enet_interrupt) +*(.text.imxrt_enet_interrupt_work) +*(.text.imxrt_interrupt) +*(.text.imxrt_gpio1_16_31_interrupt) +*(.text.imxrt_gpio2_0_15_interrupt) +*(.text.imxrt_lpi2c_isr) +*(.text.imxrt_lpspi3select) +*(.text.imxrt_lpspi4select) +*(.text.imxrt_lpspi_exchange) +*(.text.imxrt_recvdma) +*(.text.imxrt_tcd_free) +*(.text.imxrt_timerisr) +*(.text.imxrt_transmit) +*(.text.imxrt_txdone) +*(.text.imxrt_txtimeout_work) +*(.text.imxrt_txtimeout_expiry) +*(.text.imxrt_txpoll) +*(.text.imxrt_txringfull) +*(.text.imxrt_txavail_work) +*(.text.imxrt_txavail) +*(.text.imxrt_usbinterrupt) +*(.text.irq_dispatch) +*(.text.ioctl) +*(.text.memcpy) +*(.text.memset) +*(.text.nxsched_add_blocked) +*(.text.nxsched_add_prioritized) +*(.text.nxsched_add_readytorun) +*(.text.nxsched_get_files) +*(.text.nxsched_get_tcb) +*(.text.nxsched_merge_pending) +*(.text.nxsched_process_timer) +*(.text.nxsched_remove_blocked) +*(.text.nxsched_remove_readytorun) +*(.text.nxsched_resume_scheduler) +*(.text.nxsched_suspend_scheduler) +*(.text.nxsem_add_holder) +*(.text.nxsem_add_holder_tcb) +*(.text.nxsem_clockwait) +*(.text.nxsem_foreachholder) +*(.text.nxsem_freecount0holder) +*(.text.nxsem_freeholder) +*(.text.nxsem_post) +*(.text.nxsem_release_holder) +*(.text.nxsem_restore_baseprio) +*(.text.nxsem_tickwait) +*(.text.nxsem_timeout) +*(.text.nxsem_trywait) +*(.text.nxsem_wait) +*(.text.nxsem_wait_uninterruptible) +*(.text.nxsig_timedwait) +*(.text.sched_lock) +*(.text.sched_note_resume) +*(.text.sched_note_suspend) +*(.text.sched_unlock) +*(.text.strcmp) +*(.text.sq_addafter) +*(.text.sq_addlast) +*(.text.sq_rem) +*(.text.sq_remafter) +*(.text.sq_remfirst) +*(.text.uart_connected) +*(.text.up_block_task) +*(.text.up_unblock_task) +*(.text.wd_timer) +*(.text.wd_start) +*(.text.work_thread) +*(.text.work_queue) +*(.text._do_memcpy) + +/* Tropic Eth tune */ +*(.text.devif_poll) +*(.text.devif_poll_tcp_connections) +*(.text.tcp_poll) +*(.text.devif_poll_udp_connections) +*(.text.udp_nextconn) +*(.text.udp_poll) +*(.text.udp_ipv4_select) +*(.text.udp_callback) +*(.text.udp_datahandler) +*(.text.udp_send) +*(.text.udp_active) +*(.text.udp_ipv4_active) +*(.text.psock_udp_sendto) +*(.text.sendto_eventhandler) +*(.text.net_dataevent) +*(.text.devif_conn_event) +*(.text.devif_event_trigger) +*(.text.devif_poll_icmp) +*(.text.icmp_poll) +*(.text.arp_out) +*(.text.arp_find) +*(.text.arp_format) +*(.text.net_ipv4addr_hdrcmp) /* itcm-check-ignore */ +*(.text.net_ipv4addr_copy) /* itcm-check-ignore */ +*(.text.net_ipv4addr_broadcast) /* itcm-check-ignore */ +*(.text.wd_start) +*(.text.arp_arpin) +*(.text.ipv4_input) +*(.text.work_thread) +*(.text.work_queue) + +/* ICM45686 */ +*(.text._ZN8ICM4568612ProcessAccelERKyPKN19InvenSense_ICM456864FIFO4DATAEh) +*(.text._ZN8ICM4568611ProcessGyroERKyPKN19InvenSense_ICM456864FIFO4DATAEh) +*(.text._ZN8ICM456868FIFOReadERKy) +*(.text._ZN8ICM456867RunImplEv) +*(.text._ZN8ICM4568618ProcessTemperatureEPKN19InvenSense_ICM456864FIFO4DATAEh) +*(.text._ZN12I2CSPIDriverI8ICM45686E3RunEv) +*(.text._ZN8ICM4568613FIFOReadCountEv) + +/* BMI088 */ +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer12RegisterReadENS1_8RegisterE) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13FIFOReadCountEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer8FIFOReadERKyh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13RegisterCheckERKNS2_17register_config_tE) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13RegisterWriteENS1_8RegisterEh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer17UpdateTemperatureEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer23RegisterSetAndClearBitsENS1_8RegisterEhh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer26DataReadyInterruptCallbackEiPvS3_) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer7RunImplEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer9DataReadyEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD0Ev) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD1Ev) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD2Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope12RegisterReadENS1_8RegisterE) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope13RegisterCheckERKNS2_17register_config_tE) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope13RegisterWriteENS1_8RegisterEh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope23RegisterSetAndClearBitsENS1_8RegisterEhh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope26DataReadyInterruptCallbackEiPvS3_) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope7RunImplEv) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope8FIFOReadERKyh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope9DataReadyEv) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD0Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD1Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD2Ev) +*(.text._ZN12I2CSPIDriverI6BMI088E3RunEv) + +/* BMM350 */ +*(.text._ZN12I2CSPIDriverI6BMM350E3RunEv) +*(.text._ZN6BMM3507RunImplEv) +*(.text._ZN6BMM35013RegisterWriteEN12Bosch_BMM3508RegisterEh) +*(.text._ZN6BMM35012RegisterReadEN12Bosch_BMM3508RegisterEPh) +*(.text._ZN6BMM35014ReadOutRawDataEPf) diff --git a/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld b/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..8e5f852a82 --- /dev/null +++ b/boards/nxp/mr-tropic/nuttx-config/scripts/script.ld @@ -0,0 +1,187 @@ +/**************************************************************************** + * boards/nxp/mr-tropic/nuttx-config/scripts/script.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Specify the memory areas */ + +MEMORY +{ + flash (rx) : ORIGIN = 0x70020000, LENGTH = 4194304 - 256K + sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512K + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 384K + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 127K + dtcm_nocache (rwx) : ORIGIN = 0x2001FC00, LENGTH = 1K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +EXTERN(g_flash_config) +EXTERN(g_image_vector_table) +EXTERN(g_boot_data) +EXTERN(board_get_manifest) +EXTERN(_bootdelay_signature) + +ENTRY(_stext) + +SECTIONS +{ + /* Image Vector Table and Boot Data for booting from external flash */ + + .boot_hdr : ALIGN(4) + { + FILL(0xff) + __boot_hdr_start__ = ABSOLUTE(.) ; + KEEP(*(.boot_hdr.conf)) + . = 0x1000 ; + KEEP(*(.boot_hdr.ivt)) + . = 0x1020 ; + KEEP(*(.boot_hdr.boot_data)) + . = 0x1030 ; + KEEP(*(.boot_hdr.dcd_data)) + __boot_hdr_end__ = ABSOLUTE(.) ; + . = 0x2000 ; + } >flash + + /* Workaround for ethernet issue, by placing g_desc_pool into DTCM, + which effectively puts it into a no-cache region */ + .dtcm_nocache : { + *(.bss.g_desc_pool) + } > dtcm_nocache + + .vectors : + { + KEEP(*(.vectors)) + *(.text .text.__start) + } >flash + + .itcmfunc : + { + . = ALIGN(8); + _sitcmfuncs = ABSOLUTE(.); + FILL(0xFF) + . = 0x40 ; + *(.ram_vectors) + INCLUDE "itcm_static_functions.ld" + INCLUDE "itcm_functions_includes.ld" + . = ALIGN(8); + _eitcmfuncs = ABSOLUTE(.); + } > itcm AT > flash + + _fitcmfuncs = LOADADDR(.itcmfunc); + + .text : + { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + . = ALIGN(4096); + _etext = ABSOLUTE(.); + _srodata = ABSOLUTE(.); + *(.rodata .rodata.*) + . = ALIGN(4096); + _erodata = ABSOLUTE(.); + } > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP(*(.init_array .ctors)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : + { + *(.ARM.extab*) + } > flash + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } > flash + + _eronly = ABSOLUTE(.); + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .ramfunc ALIGN(4): + { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > sram AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + .bss : + { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + _boot_loadaddr = ORIGIN(flash); + _boot_size = LENGTH(flash); + _ram_size = LENGTH(sram); + _sdtcm = ORIGIN(dtcm); + _edtcm = ORIGIN(dtcm) + LENGTH(dtcm); +} diff --git a/boards/nxp/mr-tropic/src/CMakeLists.txt b/boards/nxp/mr-tropic/src/CMakeLists.txt new file mode 100644 index 0000000000..4f0710f546 --- /dev/null +++ b/boards/nxp/mr-tropic/src/CMakeLists.txt @@ -0,0 +1,86 @@ +############################################################################ +# +# Copyright (c) 2024 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_compile_definitions(BOOTLOADER) + add_library(drivers_board + bootloader_main.c + init.c + usb.c + imxrt_flexspi_nor_boot.c + imxrt_flexspi_nor_flash.c + timer_config.cpp + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer #gpio + arch_io_pins # iotimer + arch_board_romapi + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + + px4_add_library(drivers_board + i2c.cpp + init.c + sdhc.c + spi.cpp + timer_config.cpp + tropic_led_pwm.cpp + usb.c + imxrt_flexspi_nor_boot.c + imxrt_flexspi_nor_flash.c + imxrt_flexspi_storage.c + imxrt_ocram_initialize.c + hw_rev_ver_tropic.c + manifest.c + ) + + + # Force compiler not to use builtin functions (like memcpy) + # to optimize for loops in init.c (imxrt_ocram_initialize) + set_source_files_properties(imxrt_ocram_initialize.c PROPERTIES COMPILE_FLAGS -fno-builtin) + + target_link_libraries(drivers_board + PRIVATE + arch_board_romapi + arch_spi + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer + ) + +endif() diff --git a/boards/nxp/mr-tropic/src/board_config.h b/boards/nxp/mr-tropic/src/board_config.h new file mode 100644 index 0000000000..45e6eecd54 --- /dev/null +++ b/boards/nxp/mr-tropic/src/board_config.h @@ -0,0 +1,355 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * Tropic Community internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include +#include + +#include "imxrt_gpio.h" +#include "imxrt_iomuxc.h" +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_usb_analog.h" + +#include +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* Configuration ************************************************************************************/ + +/* FMURT1062 GPIOs ***********************************************************************************/ +/* LEDs */ +/* An RGB LED is connected through GPIO as shown below: + */ +#define LED_IOMUX (IOMUX_OPENDRAIN | IOMUX_PULL_NONE | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_SLOW) +#define GPIO_nLED_RED /* GPIO_EMC_33 GPIO3_IO19 */ (GPIO_PORT3 | GPIO_PIN19 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LED_IOMUX) +#define GPIO_nLED_BLUE /* GPIO_EMC_34 GPIO3_IO20 */ (GPIO_PORT3 | GPIO_PIN20 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LED_IOMUX) +#define GPIO_nLED_GREEN /* GPIO_EMC_38 GPIO3_IO24 */ (GPIO_PORT3 | GPIO_PIN24 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | LED_IOMUX) + +#define BOARD_HAS_CONTROL_STATUS_LEDS 1 +#define BOARD_OVERLOAD_LED LED_RED +#define BOARD_ARMED_STATE_LED LED_BLUE + +/* + * Define the ability to shut off off the sensor signals + * by changing the signals to inputs + */ + +#define _PIN_OFF(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT | IOMUX_PULL_DOWN_100K | IOMUX_CMOS_INPUT)) + +/* Define the Chip Selects, Data Ready and Control signals per SPI bus */ + +#define CS_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_UP_100K | IOMUX_DRIVE_33OHM | IOMUX_SPEED_LOW | IOMUX_SLEW_FAST) +#define OUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_UP_100K | IOMUX_DRIVE_50OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST) + + +/* SPI1 off */ + +#define _GPIO_LPSPI1_SCK /* GPIO_EMC_27 GPIO4_IO27 */ (GPIO_PORT4 | GPIO_PIN27 | CS_IOMUX) +#define _GPIO_LPSPI1_MISO /* GPIO_EMC_29 GPIO4_IO29 */ (GPIO_PORT4 | GPIO_PIN29 | CS_IOMUX) +#define _GPIO_LPSPI1_MOSI /* GPIO_EMC_28 GPIO4_IO28 */ (GPIO_PORT4 | GPIO_PIN28 | CS_IOMUX) + +#define GPIO_SPI1_SCK_OFF _PIN_OFF(_GPIO_LPSPI1_SCK) +#define GPIO_SPI1_MISO_OFF _PIN_OFF(_GPIO_LPSPI1_MISO) +#define GPIO_SPI1_MOSI_OFF _PIN_OFF(_GPIO_LPSPI1_MOSI) + +#define _GPIO_LPSPI3_SCK /* GPIO_AD_B1_15 GPIO1_IO27 */ (GPIO_PORT1 | GPIO_PIN31 | CS_IOMUX) +#define _GPIO_LPSPI3_MISO /* GPIO_AD_B1_13 GPIO1_IO27 */ (GPIO_PORT1 | GPIO_PIN29 | CS_IOMUX) +#define _GPIO_LPSPI3_MOSI /* GPIO_AD_B1_14 GPIO1_IO27 */ (GPIO_PORT1 | GPIO_PIN30 | CS_IOMUX) + +#define GPIO_SPI3_SCK_OFF _PIN_OFF(_GPIO_LPSPI3_SCK) +#define GPIO_SPI3_MISO_OFF _PIN_OFF(_GPIO_LPSPI3_MISO) +#define GPIO_SPI3_MOSI_OFF _PIN_OFF(_GPIO_LPSPI3_MOSI) + +/* Define the SPI4 Data Ready and Control signals */ + +#define GPIO_SPI4_DRDY7_EXTERNAL1 /* GPIO_EMC_35 GPIO3_IO21*/ (GPIO_PORT3 | GPIO_PIN21 | GPIO_INPUT | DRDY_IOMUX) + +#define GPIO_DRDY_OFF_SPI4_DRDY7_EXTERNAL1 _PIN_OFF(GPIO_SPI4_DRDY7_EXTERNAL1) + +#define ADC_IOMUX (IOMUX_CMOS_INPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_HIZ) + +#define ADC1_CH(n) (n) +#define ADC1_GPIO(n, p) (GPIO_PORT1 | GPIO_PIN##p | ADC_IOMUX) // + +/* Define GPIO pins used as ADC N.B. Channel numbers are for reference, */ + +#define PX4_ADC_GPIO \ + /* ADC_5V_RAIL_SENSE GPIO_AD_B1_08 GPIO1 Pin 24 */ ADC1_GPIO(0, 24) + +/* Define Channel numbers must match above GPIO pin IN(n)*/ + +#define ADC_5V_RAIL_SENSE /* GPIO_AD_B1_08 GPIO1 Pin 24 */ ADC1_CH(13) + +#define ADC_CHANNELS (1 << ADC_5V_RAIL_SENSE) + +/* Power supply control and monitoring GPIOs */ + +#define GENERAL_INPUT_IOMUX (IOMUX_CMOS_INPUT | IOMUX_PULL_UP_47K | IOMUX_DRIVE_HIZ) +#define GENERAL_OUTPUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST) + + +/* PWM + */ + +#define DIRECT_PWM_OUTPUT_CHANNELS 8 +#define BOARD_NUM_IO_TIMERS 4 + +// Input Capture not supported on MVP + +#define BOARD_HAS_NO_CAPTURE + +//#define BOARD_HAS_UI_LED_PWM 1 Not ported yet (Still Kinetis driver) +#define BOARD_HAS_LED_PWM 1 +#define BOARD_LED_PWM_DRIVE_ACTIVE_LOW 1 +#define BOARD_HAS_CUSTOM_LED_PWM 1 + +#define PWM_LED_RED /* GPIO_EMC_33 */ (GPIO_FLEXPWM3_PWMA02_1 | GENERAL_OUTPUT_IOMUX) +#define PWM_LED_BLUE /* GPIO_EMC_34 */ (GPIO_FLEXPWM3_PWMB02_1 | GENERAL_OUTPUT_IOMUX) +#define PWM_LED_GREEN /* GPIO_EMC_38 */ (GPIO_FLEXPWM1_PWMA03_2 | GENERAL_OUTPUT_IOMUX) + + +/* ETHERNET GPIO */ + +#define GPIO_ENET_RX_ER_CONFIG1 /* GPIO_B1_11 GPIO2_IO27 PHYAD18 Open */ (GPIO_PORT2 | GPIO_PIN27 | GPIO_INPUT | IOMUX_PULL_NONE) +#define GPIO_ENET_RX_DATA01_CONFIG4 /* GPIO_B1_05 GPIO2_IO21 (RMII-clkmode) High */ (GPIO_PORT2 | GPIO_PIN21 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | GENERAL_OUTPUT_IOMUX) +#define GPIO_ENET_RX_DATA00_CONFIG5 /* GPIO_B1_04 GPIO2_IO20 SLAVE:Auto Open */ (GPIO_PORT2 | GPIO_PIN20 | GPIO_INPUT | IOMUX_PULL_NONE) +#define GPIO_ENET_CRS_DV_CONFIG6 /* GPIO_B1_06 GPIO4_IO22 SLAVE:POl Corr Low */ (GPIO_PORT2 | GPIO_PIN22 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX) + +/* Tone alarm output */ + +//FIXME FlexPWM TONE DRIVER +#define TONE_ALARM_FLEXPWM PWMA_VAL +#define TONE_ALARM_TIMER 1 /* FlexPWM 3 */ +#define TONE_ALARM_CHANNEL 0 /* GPIO_EMC_23 PWM1_PWMA00 */ + +#define GPIO_BUZZER_1 /* GPIO_EMC_23 GPIO4_IO23 */ (GPIO_PORT4 | GPIO_PIN23 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX) + +#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1 +#define GPIO_TONE_ALARM (GPIO_FLEXPWM1_PWMA00_1 | GENERAL_OUTPUT_IOMUX) + +/* USB OTG FS + * + * VBUS_VALID is detected in USB_ANALOG_USB1_VBUS_DETECT_STAT + */ + +/* High-resolution timer */ +#define HRT_TIMER 1 /* use GPT1 for the HRT */ +#define HRT_TIMER_CHANNEL 1 /* use capture/compare channel 1 */ + +#define RC_SERIAL_PORT "/dev/ttyS6" +//#define RC_SERIAL_SINGLEWIRE 1 // Suport Single wire wiring +//#define RC_SERIAL_SWAP_RXTX 1 // Set Swap (but not supported in HW) to use Single wire +//#define RC_SERIAL_SWAP_USING_SINGLEWIRE 1 // Set to use Single wire swap as HW does not support swap +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + +/* Safety Switch is HW version dependent on having an PX4IO + * So we init to a benign state with the _INIT definition + * and provide the the non _INIT one for the driver to make a run time + * decision to use it. + */ +#define SAFETY_INIT_IOMUX (IOMUX_CMOS_INPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_HIZ) +#define SAFETY_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_SLOW) +#define SAFETY_SW_IOMUX (IOMUX_CMOS_INPUT | IOMUX_PULL_UP_22K | IOMUX_DRIVE_HIZ) + +/* Safety Switch is HW version dependent on having an PX4IO + * So we init to a benign state with the _INIT definition + * and provide the the non _INIT one for the driver to make a run time + * decision to use it. + */ +#define GPIO_nSAFETY_SWITCH_LED_OUT_INIT /* EMC_39 */ (GPIO_PORT3 | GPIO_PIN25 | GPIO_INPUT | SAFETY_INIT_IOMUX) +#define GPIO_nSAFETY_SWITCH_LED_OUT /* EMC_39 */ (GPIO_PORT3 | GPIO_PIN25 | GPIO_OUTPUT | GPIO_OUTPUT_ONE | SAFETY_IOMUX) + +/* Enable the FMU to control it if there is no px4io fixme:This should be BOARD_SAFETY_LED(__ontrue) */ +#define GPIO_LED_SAFETY GPIO_nSAFETY_SWITCH_LED_OUT + +#define GPIO_SAFETY_SWITCH_IN /* GPIO_B0_12 GPIO2_IO12 */ (GPIO_PORT2 | GPIO_PIN12 | GPIO_INPUT | SAFETY_SW_IOMUX) +/* Enable the FMU to use the switch it if there is no px4io fixme:This should be BOARD_SAFTY_BUTTON() */ +#define GPIO_BTN_SAFETY GPIO_SAFETY_SWITCH_IN /* Enable the FMU to control it if there is no px4io */ + +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 + +/* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ + +#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +#endif + +/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction) + * this board support the ADC system_power interface, and therefore + * provides the true logic GPIO BOARD_ADC_xxxx macros. + */ + +#define BOARD_NUMBER_BRICKS 1 +#define BOARD_NUMBER_DIGITAL_BRICKS 1 + +#define BOARD_ADC_BRICK_VALID 1 + +#define BOARD_ADC_USB_CONNECTED (board_read_VBUS_state() == 0) + +/* FMUv5 never powers odd the Servo rail */ + +#define BOARD_ADC_SERVO_VALID (1) + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ + +#define BOARD_HAS_ON_RESET 1 +#define BOARD_HAS_ISP_BOOTLOADER 1 + +#define PX4_GPIO_INIT_LIST { \ + GPIO_FLEXCAN3_TX, \ + GPIO_FLEXCAN3_RX, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_SAFETY_SWITCH_IN, \ + GPIO_ENET_RX_ER_CONFIG1, \ + GPIO_ENET_RX_DATA01_CONFIG4, \ + GPIO_ENET_RX_DATA00_CONFIG5, \ + GPIO_ENET_CRS_DV_CONFIG6, \ + GPIO_ENET_RST \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +/* To detect IMU */ +#define BOARD_HAS_HW_VERSIONING 1 +#define BOARD_HAS_HW_SPLIT_VERSIONING 1 +#define HW_INFO_INIT_PREFIX "TROPIC" + +#define BOARD_NUM_SPI_CFG_HW_VERSIONS 3 +// Base/FMUM +#define TROPIC_0 HW_FMUM_ID(0x0) // ICM45686 +#define TROPIC_1 HW_FMUM_ID(0x1) // ICM42688 +#define TROPIC_2 HW_FMUM_ID(0x2) // ICM42686 + +/* Flash instance for storage */ +#define NOR_INSTANCE 1 + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: fmurt1062_usdhc_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int fmurt1062_usdhc_initialize(void); + +/**************************************************************************************************** + * Name: imxrt_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the PX4FMU board. + * + ****************************************************************************************************/ + +extern void imxrt_spidev_initialize(void); + +/************************************************************************************ + * Name: imxrt_spi_bus_initialize + * + * Description: + * Called to configure SPI Buses. + * + ************************************************************************************/ + +extern int imxrt1062_spi_bus_initialize(void); + +/************************************************************************************ + * Name: imxrt_usb_initialize + * + * Description: + * Called to configure USB. + * + ************************************************************************************/ + +extern void imxrt_spiinitialize(void); + +extern int imxrt_usb_initialize(void); + +extern void imxrt_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +extern void fmurt1062_timer_initialize(void); + +#include + +void imxrt_flash_romapi_initialize(void); + +int imxrt_flexspi_storage_initialize(void); + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/nxp/mr-tropic/src/bootloader_main.c b/boards/nxp/mr-tropic/src/bootloader_main.c new file mode 100644 index 0000000000..04008aa2ff --- /dev/null +++ b/boards/nxp/mr-tropic/src/bootloader_main.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * + * Copyright (c) 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/nxp/mr-tropic/src/hw_config.h b/boards/nxp/mr-tropic/src/hw_config.h new file mode 100644 index 0000000000..22e0680203 --- /dev/null +++ b/boards/nxp/mr-tropic/src/hw_config.h @@ -0,0 +1,130 @@ +/* + * hw_config.h + * + * Created on: May 17, 2015 + * Author: david_s5 + */ + +#ifndef HW_CONFIG_H_ +#define HW_CONFIG_H_ + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x70020000 +#define APP_VECTOR_OFFSET 0x2000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" + +//#define USE_VBUS_PULL_DOWN +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,1500000" +#define BOOT_DELAY_ADDRESS 0x00039FA0 +#define BOARD_TYPE 37 +// The board has a 64 Mb part with 16384, 4K secors, but we artificialy limit it to 4 Mb +// as 1024, 4K sectors +#define BOARD_FLASH_SECTORS 960 // 1024 * 4k sectors, 128k for bootloader, 128k for storage +#define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 32 // We resreve 128K for the bootloader +#define BOARD_FLASH_SIZE (BOARD_FLASH_SECTORS * 4096) + +#define OSC_FREQ 24 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +/* + * Uncommenting this allows to force the bootloader through + * a PWM output pin. As this can accidentally initialize + * an ESC prematurely, it is not recommended. This feature + * has not been used and hence defaults now to off. + * + * # define BOARD_FORCE_BL_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN14) + * # define BOARD_FORCE_BL_PIN_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) + * + * # define BOARD_POWER_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4) + * # define BOARD_POWER_ON 1 + * # define BOARD_POWER_OFF 0 + * # undef BOARD_POWER_PIN_RELEASE // Leave pin enabling Power - un comment to release (disable power) + * +*/ + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#endif /* HW_CONFIG_H_ */ diff --git a/boards/nxp/mr-tropic/src/hw_rev_ver_tropic.c b/boards/nxp/mr-tropic/src/hw_rev_ver_tropic.c new file mode 100644 index 0000000000..7414c21a32 --- /dev/null +++ b/boards/nxp/mr-tropic/src/hw_rev_ver_tropic.c @@ -0,0 +1,165 @@ +/**************************************************************************** + * + * Copyright (C) 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file hw_rev_ver_canhubk3.c + * CANHUBK3 Hardware Revision and Version ID API + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#if defined(BOARD_HAS_HW_VERSIONING) + +#define HW_INFO_SIZE HW_INFO_VER_DIGITS + HW_INFO_REV_DIGITS + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int hw_revision = 0; +static char hw_info[HW_INFO_SIZE] = {0}; +#if defined(BOARD_HAS_HW_SPLIT_VERSIONING) +static char hw_base_info[HW_INFO_SIZE] = {0}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/************************************************************************************ + * Name: board_get_hw_type + * + * Description: + * Optional returns a 0 terminated string defining the HW type. + * + * Input Parameters: + * None + * + * Returned Value: + * a 0 terminated string defining the HW type. This my be a 0 length string "" + * + ************************************************************************************/ + +__EXPORT const char *board_get_hw_type_name() +{ + return (const char *) hw_info; +} + +#if defined(BOARD_HAS_HW_SPLIT_VERSIONING) +/************************************************************************************ + * Name: board_get_hw_base_type_name + * + * Description: + * Optional returns a 0 terminated string defining the base type. + * + * Input Parameters: + * None + * + * Returned Value: + * a 0 terminated string defining the HW type. This my be a 0 length string "" + * + ************************************************************************************/ + +__EXPORT const char *board_get_hw_base_type_name() +{ + return (const char *) hw_base_info; +} +#endif + +/************************************************************************************ + * Name: board_get_hw_version + * + * Description: + * Optional returns a integer HW version + * + * Input Parameters: + * None + * + * Returned Value: + * An integer value of this boards hardware version. + * A value of -1 is the default for boards not supporting the BOARD_HAS_VERSIONING API. + * A value of 0 is the default for boards supporting the API but not having version. + * + ************************************************************************************/ + +__EXPORT int board_get_hw_version() +{ + return 0; +} + +/************************************************************************************ + * Name: board_get_hw_revision + * + * Description: + * Optional returns a integer HW revision + * + * Input Parameters: + * None + * + * Returned Value: + * An integer value of this boards hardware revision. + * A value of -1 is the default for boards not supporting the BOARD_HAS_VERSIONING API. + * A value of 0 is the default for boards supporting the API but not having revision. + * + ************************************************************************************/ + +__EXPORT int board_get_hw_revision() +{ + return hw_revision; +} + +/************************************************************************************ + * Name: board_determine_hw_info + * + * Description: + * Uses GPIO to detect MR-CANHUBK3-ADAP + * + ************************************************************************************/ + +int board_determine_hw_info() +{ + hw_revision = 0; //TODO Read fuses + + sprintf(hw_info, "%03d", hw_revision); + + return 0; +} +#endif diff --git a/boards/nxp/mr-tropic/src/i2c.cpp b/boards/nxp/mr-tropic/src/i2c.cpp new file mode 100644 index 0000000000..a118a69d0f --- /dev/null +++ b/boards/nxp/mr-tropic/src/i2c.cpp @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * Copyright (C) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusExternal(1), + initI2CBusExternal(3), + initI2CBusInternal(4), +}; diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.c b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.c new file mode 100644 index 0000000000..894c959d33 --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "imxrt_flexspi_nor_boot.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +locate_data(".boot_hdr.ivt") +const struct ivt_s g_image_vector_table = { + IVT_HEADER, /* IVT Header */ + IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ + IVT_RSVD, /* Reserved = 0 */ + (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ + (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ + (uint32_t)IMAG_VECTOR_TABLE, /* Pointer to IVT Self (absolute address */ + (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ + IVT_RSVD /* Reserved = 0 */ +}; + +locate_data(".boot_hdr.boot_data") +const struct boot_data_s g_boot_data = { + IMAGE_DEST, /* boot start location */ + (IMAGE_DEST_END - IMAGE_DEST), /* size */ + PLUGIN_FLAG, /* Plugin flag */ + 0xffffffff /* empty - extra data word */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* None */ diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.h b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.h new file mode 100644 index 0000000000..ca6b9cf8b3 --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_boot.h @@ -0,0 +1,166 @@ +/**************************************************************************** + * boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor_boot.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_IMXRT_IMXRT1060_EVK_SRC_IMXRT_FLEXSPI_NOR_BOOT_H +#define __BOARDS_ARM_IMXRT_IMXRT1060_EVK_SRC_IMXRT_FLEXSPI_NOR_BOOT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* IVT Data */ + +#define IVT_MAJOR_VERSION 0x4 +#define IVT_MAJOR_VERSION_SHIFT 0x4 +#define IVT_MAJOR_VERSION_MASK 0xf +#define IVT_MINOR_VERSION 0x1 +#define IVT_MINOR_VERSION_SHIFT 0x0 +#define IVT_MINOR_VERSION_MASK 0xf + +#define IVT_VERSION(major, minor) \ + ((((major) & IVT_MAJOR_VERSION_MASK) << IVT_MAJOR_VERSION_SHIFT) | \ + (((minor) & IVT_MINOR_VERSION_MASK) << IVT_MINOR_VERSION_SHIFT)) + +#define IVT_TAG_HEADER (0xd1) /* Image Vector Table */ +#define IVT_SIZE 0x2000 +#define IVT_PAR IVT_VERSION(IVT_MAJOR_VERSION, IVT_MINOR_VERSION) + +#define IVT_HEADER (IVT_TAG_HEADER | (IVT_SIZE << 8) | (IVT_PAR << 24)) +#define IVT_RSVD (uint32_t)(0x00000000) + +/* DCD Data */ + +#define DCD_TAG_HEADER (0xd2) +#define DCD_TAG_HEADER_SHIFT (24) +#define DCD_VERSION (0x40) +#define DCD_ARRAY_SIZE 1 + +#define FLASH_BASE 0x70000000 +#define FLASH_END 0x70400000 + +/* This needs to take into account the memory configuration at boot + * bootloader + */ + +#define ROM_BOOTLOADER_OCRAM_RES 0x8000 +#define OCRAM_BASE (0x20200000 + ROM_BOOTLOADER_OCRAM_RES) +#define OCRAM_END (OCRAM_BASE + (512 * 1024) + (256 * 1024) \ + - ROM_BOOTLOADER_OCRAM_RES) + +#define SCLK 1 +#if defined(CONFIG_BOOT_RUNFROMFLASH) +# define IMAGE_DEST FLASH_BASE +# define IMAGE_DEST_END FLASH_END +# define IMAGE_DEST_OFFSET 0 +#else +# define IMAGE_DEST OCRAM_BASE +# define IMAGE_DEST_END OCRAM_END +# define IMAGE_DEST_OFFSET IVT_SIZE +#endif + +#define LOCATE_IN_DEST(x) (((uint32_t)(x)) - FLASH_BASE + IMAGE_DEST) +#define LOCATE_IN_SRC(x) (((uint32_t)(x)) - IMAGE_DEST + FLASH_BASE) + +#ifdef CONFIG_IMXRT1064_EVK_SDRAM +# define DCD_ADDRESS &g_dcd_data +#else +# define DCD_ADDRESS 0 +#endif +#define BOOT_DATA_ADDRESS LOCATE_IN_DEST(&g_boot_data) +#define CSF_ADDRESS 0 +#define PLUGIN_FLAG (uint32_t)0 + +/* Located in Destination Memory */ + +#define IMAGE_ENTRY_ADDRESS ((uint32_t)&_vectors) +#define IMAG_VECTOR_TABLE LOCATE_IN_DEST(&g_image_vector_table) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* IVT Data */ + +struct ivt_s { + /* Header with tag #HAB_TAG_IVT, length and HAB version fields + * (see data) + */ + + uint32_t hdr; + + /* Absolute address of the first instruction to execute from the + * image + */ + + uint32_t entry; + + /* Reserved in this version of HAB: should be NULL. */ + + uint32_t reserved1; + + /* Absolute address of the image DCD: may be NULL. */ + + uint32_t dcd; + + /* Absolute address of the Boot Data: may be NULL, but not interpreted + * any further by HAB + */ + + uint32_t boot_data; + + /* Absolute address of the IVT. */ + + uint32_t self; + + /* Absolute address of the image CSF. */ + + uint32_t csf; + + /* Reserved in this version of HAB: should be zero. */ + + uint32_t reserved2; +}; + +/* Boot Data */ + +struct boot_data_s { + uint32_t start; /* boot start location */ + uint32_t size; /* size */ + uint32_t plugin; /* plugin flag - 1 if downloaded application is plugin */ + uint32_t placeholder; /* placeholder to make even 0x10 size */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const struct boot_data_s g_boot_data; +#ifdef CONFIG_IMXRT1064_EVK_SDRAM +extern const uint8_t g_dcd_data[]; +#endif +extern const uint32_t _vectors[]; + +#endif /* __BOARDS_ARM_IMXRT_IMXRT1060_EVK_SRC_IMXRT_FLEXSPI_NOR_BOOT_H */ diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c new file mode 100644 index 0000000000..25fcd2e2a1 --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * boards/arm/imxrt/teensy-4.x/src/imxrt_flexspi_nor_flash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "imxrt_flexspi_nor_flash.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +enum { + /* SPI instructions */ + + READ_FAST = 0, + READ_STATUS_REG = 1, + WRITE_ENABLE = 3, + SECTOR_ERASE_4K = 5, + READ_FAST_QUAD_OUTPUT = 6, + PAGE_PROGRAM_QUAD_INPUT = 7, + ERASE_BLOCK = 8, + PAGE_PROGRAM = 9, + CHIP_ERASE = 11, +}; + +locate_data(".boot_hdr.conf") +const struct flexspi_nor_config_s g_flash_config = { + .mem_config = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .read_sample_clksrc = FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_DQSPAD, + .cs_hold_time = 3u, + .cs_setup_time = 3u, + .column_address_width = 0u, + .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, + .sflash_pad_type = SERIAL_FLASH_4PADS, + .serial_clk_freq = FLEXSPI_SERIAL_CLKFREQ_133MHz, + .sflash_a1size = 4u * 1024u * 1024u, + .lookup_table = + { + [4 * READ_FAST] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xeb, + RADDR_SDR, FLEXSPI_4PAD, 0x18), + [4 * READ_FAST + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, + READ_SDR, FLEXSPI_4PAD, 0x04), + + [4 * READ_STATUS_REG] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, + READ_SDR, FLEXSPI_1PAD, 0x04), + + [4 * WRITE_ENABLE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, + STOP, FLEXSPI_1PAD, 0), + + [4 * SECTOR_ERASE_4K] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + + [4 * CHIP_ERASE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, + STOP, FLEXSPI_1PAD, 0), + + [4 * ERASE_BLOCK] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xd8, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + + [4 * PAGE_PROGRAM] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * PAGE_PROGRAM + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, + STOP, FLEXSPI_1PAD, 0x0), + + [4 * READ_FAST_QUAD_OUTPUT] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6b, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * READ_FAST_QUAD_OUTPUT + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, + READ_SDR, FLEXSPI_4PAD, 0x04), + + [4 * PAGE_PROGRAM_QUAD_INPUT] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * PAGE_PROGRAM_QUAD_INPUT + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, + STOP, FLEXSPI_1PAD, 0), + + }, + }, + + .page_size = 256u, + .sector_size = 4u * 1024u, + .blocksize = 64u * 1024u, + .is_uniform_blocksize = false, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.h b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.h new file mode 100644 index 0000000000..1fb3f41cce --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_nor_flash.h @@ -0,0 +1,349 @@ +/**************************************************************************** + * boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor_flash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_IMXRT_IMXRT1064_EVK_SRC_IMXRT_FLEXSPI_NOR_FLASH_H +#define __BOARDS_ARM_IMXRT_IMXRT1064_EVK_SRC_IMXRT_FLEXSPI_NOR_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* FLEXSPI memory config block related definitions */ + +#define FLEXSPI_CFG_BLK_TAG (0x42464346ul) +#define FLEXSPI_CFG_BLK_VERSION (0x56010400ul) +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ + +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ + +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0a +#define LEARN_DDR 0x2a +#define DATSZ_SDR 0x0b +#define DATSZ_DDR 0x2b +#define DUMMY_SDR 0x0c +#define DUMMY_DDR 0x2c +#define DUMMY_RWDS_SDR 0x0d +#define DUMMY_RWDS_DDR 0x2d +#define JMP_ON_CS 0x1f +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_OPERAND0_MASK (0xffu) +#define FLEXSPI_LUT_OPERAND0_SHIFT (0U) +#define FLEXSPI_LUT_OPERAND0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPERAND0_SHIFT)) & \ + FLEXSPI_LUT_OPERAND0_MASK) +#define FLEXSPI_LUT_NUM_PADS0_MASK (0x300u) +#define FLEXSPI_LUT_NUM_PADS0_SHIFT (8u) +#define FLEXSPI_LUT_NUM_PADS0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS0_SHIFT)) & \ + FLEXSPI_LUT_NUM_PADS0_MASK) +#define FLEXSPI_LUT_OPCODE0_MASK (0xfc00u) +#define FLEXSPI_LUT_OPCODE0_SHIFT (10u) +#define FLEXSPI_LUT_OPCODE0(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPCODE0_SHIFT)) & \ + FLEXSPI_LUT_OPCODE0_MASK) +#define FLEXSPI_LUT_OPERAND1_MASK (0xff0000u) +#define FLEXSPI_LUT_OPERAND1_SHIFT (16U) +#define FLEXSPI_LUT_OPERAND1(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_OPERAND1_SHIFT)) & \ + FLEXSPI_LUT_OPERAND1_MASK) +#define FLEXSPI_LUT_NUM_PADS1_MASK (0x3000000u) +#define FLEXSPI_LUT_NUM_PADS1_SHIFT (24u) +#define FLEXSPI_LUT_NUM_PADS1(x) (((uint32_t) \ + (((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS1_SHIFT)) & \ + FLEXSPI_LUT_NUM_PADS1_MASK) +#define FLEXSPI_LUT_OPCODE1_MASK (0xfc000000u) +#define FLEXSPI_LUT_OPCODE1_SHIFT (26u) +#define FLEXSPI_LUT_OPCODE1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE1_SHIFT)) & \ + FLEXSPI_LUT_OPCODE1_MASK) + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | \ + FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +/* */ + +#define NOR_CMD_INDEX_READ CMD_INDEX_READ +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE +#define NOR_CMD_INDEX_ERASESECTOR 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE +#define NOR_CMD_INDEX_CHIPERASE 5 +#define NOR_CMD_INDEX_DUMMY 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 + +/* READ LUT sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ + +/* Read Status LUT sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS CMD_LUT_SEQ_IDX_READSTATUS + +/* 2 Read status DPI/QPI/OPI sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 2 + +/* 3 Write Enable sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE CMD_LUT_SEQ_IDX_WRITEENABLE + +/* 4 Write Enable DPI/QPI/OPI sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI 4 + +/* 5 Erase Sector sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 + +/* 8 Erase Block sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 + +/* 9 Program sequence id in lookupTable stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM CMD_LUT_SEQ_IDX_WRITE + +/* 11 Chip Erase sequence in lookupTable id stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 + +/* 13 Read SFDP sequence in lookupTable id stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 + +/* 14 Restore 0-4-4/0-8-8 mode sequence id in LUT stored in config block */ + +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD 14 + +/* 15 Exit 0-4-4/0-8-8 mode sequence id in LUT stored in config blobk */ + +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD 15 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Definitions for FlexSPI Serial Clock Frequency */ + +enum flexspi_serial_clkfreq_e { + FLEXSPI_SERIAL_CLKFREQ_30MHz = 1, + FLEXSPI_SERIAL_CLKFREQ_50MHz = 2, + FLEXSPI_SERIAL_CLKFREQ_60MHz = 3, + FLEXSPI_SERIAL_CLKFREQ_75MHz = 4, + FLEXSPI_SERIAL_CLKFREQ_80MHz = 5, + FLEXSPI_SERIAL_CLKFREQ_100MHz = 6, + FLEXSPI_SERIAL_CLKFREQ_120MHz = 7, + FLEXSPI_SERIAL_CLKFREQ_133MHz = 8, + FLEXSPI_SERIAL_CLKFREQ_166MHz = 9, +}; + +/* FlexSPI clock configuration type */ + +enum flexspi_serial_clockmode_e { + FLEXSPI_CLKMODE_SDR, + FLEXSPI_CLKMODE_DDR, +}; + +/* FlexSPI Read Sample Clock Source definition */ + +enum flash_read_sample_clk_e { + FLASH_READ_SAMPLE_CLK_LOOPBACK_INTERNELLY = 0, + FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_DQSPAD = 1, + FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_SCKPAD = 2, + FLASH_READ_SAMPLE_CLK_EXT_INPUT_FROM_DQSPAD = 3, +}; + +/* Misc feature bit definitions */ + +enum flash_misc_feature_e { + FLEXSPIMISC_OFFSET_DIFFCLKEN = 0, /* Bit for Differential clock enable */ + FLEXSPIMISC_OFFSET_CK2EN = 1, /* Bit for CK2 enable */ + FLEXSPIMISC_OFFSET_PARALLELEN = 2, /* Bit for Parallel mode enable */ + FLEXSPIMISC_OFFSET_WORD_ADDRESSABLE_EN = 3, /* Bit for Word Addressable enable */ + FLEXSPIMISC_OFFSET_SAFECONFIG_FREQ_EN = 4, /* Bit for Safe Configuration Frequency enable */ + FLEXSPIMISC_OFFSET_PAD_SETTING_OVERRIDE_EN = 5, /* Bit for Pad setting override enable */ + FLEXSPIMISC_OFFSET_DDR_MODE_EN = 6, /* Bit for DDR clock confiuration indication. */ +}; + +/* Flash Type Definition */ + +enum flash_flash_type_e { + FLEXSPI_DEVICE_TYPE_SERIAL_NOR = 1, /* Flash devices are Serial NOR */ + FLEXSPI_DEVICE_TYPE_SERIAL_NAND = 2, /* Flash devices are Serial NAND */ + FLEXSPI_DEVICE_TYPE_SERIAL_RAM = 3, /* Flash devices are Serial RAM/HyperFLASH */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_NAND = 0x12, /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_RAM = 0x13, /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs */ +}; + +/* Flash Pad Definitions */ + +enum flash_flash_pad_e { + SERIAL_FLASH_1PAD = 1, + SERIAL_FLASH_2PADS = 2, + SERIAL_FLASH_4PADS = 4, + SERIAL_FLASH_8PADS = 8, +}; + +/* Flash Configuration Command Type */ + +enum flash_config_cmd_e { + DEVICE_CONFIG_CMD_TYPE_GENERIC, /* Generic command, for example: configure dummy cycles, drive strength, etc */ + DEVICE_CONFIG_CMD_TYPE_QUADENABLE, /* Quad Enable command */ + DEVICE_CONFIG_CMD_TYPE_SPI2XPI, /* Switch from SPI to DPI/QPI/OPI mode */ + DEVICE_CONFIG_CMD_TYPE_XPI2SPI, /* Switch from DPI/QPI/OPI to SPI mode */ + DEVICE_CONFIG_CMD_TYPE_SPI2NO_CMD, /* Switch to 0-4-4/0-8-8 mode */ + DEVICE_CONFIG_CMD_TYPE_RESET, /* Reset device command */ +}; + +/* FlexSPI LUT Sequence structure */ + +struct flexspi_lut_seq_s { + uint8_t seq_num; /* Sequence Number, valid number: 1-16 */ + uint8_t seq_id; /* Sequence Index, valid number: 0-15 */ + uint16_t reserved; +}; + +/* FlexSPI Memory Configuration Block */ + +struct flexspi_mem_config_s { + uint32_t tag; + uint32_t version; + uint32_t reserved0; + uint8_t read_sample_clksrc; + uint8_t cs_hold_time; + uint8_t cs_setup_time; + uint8_t column_address_width; /* [0x00f-0x00f] Column Address with, for + * HyperBus protocol, it is fixed to 3, + * For Serial NAND, need to refer to + * datasheet + */ + uint8_t device_mode_cfg_enable; + uint8_t device_mode_type; + uint16_t wait_time_cfg_commands; + struct flexspi_lut_seq_s device_mode_seq; + uint32_t device_mode_arg; + uint8_t config_cmd_enable; + uint8_t config_mode_type[3]; + struct flexspi_lut_seq_s config_cmd_seqs[3]; + uint32_t reserved1; + uint32_t config_cmd_args[3]; + uint32_t reserved2; + uint32_t controller_misc_option; + uint8_t device_type; + uint8_t sflash_pad_type; + uint8_t serial_clk_freq; + uint8_t lut_custom_seq_enable; + uint32_t reserved3[2]; + uint32_t sflash_a1size; + uint32_t sflash_a2size; + uint32_t sflash_b1size; + uint32_t sflash_b2size; + uint32_t cspad_setting_override; + uint32_t sclkpad_setting_override; + uint32_t datapad_setting_override; + uint32_t dqspad_setting_override; + uint32_t timeout_in_ms; + uint32_t command_interval; + uint16_t data_valid_time[2]; + uint16_t busy_offset; + uint16_t busybit_polarity; + uint32_t lookup_table[64]; + struct flexspi_lut_seq_s lut_customseq[12]; + uint32_t reserved4[4]; +}; + +/* Serial NOR configuration block */ + +struct flexspi_nor_config_s { + struct flexspi_mem_config_s mem_config; /* Common memory configuration info + * via FlexSPI + */ + + uint32_t page_size; /* Page size of Serial NOR */ + uint32_t sector_size; /* Sector size of Serial NOR */ + uint8_t ipcmd_serial_clkfreq; /* Clock frequency for IP command */ + uint8_t is_uniform_blocksize; /* Sector/Block size is the same */ + uint8_t reserved0[2]; /* Reserved for future use */ + uint8_t serial_nor_type; /* Serial NOR Flash type: 0/1/2/3 */ + uint8_t need_exit_nocmdmode; /* Need to exit NoCmd mode before + * other IP command + */ + + uint8_t halfclk_for_nonreadcmd; /* Half the Serial Clock for non-read + * command: true/false + */ + + uint8_t need_restore_nocmdmode; /* Need to Restore NoCmd mode after IP + * command execution + */ + + uint32_t blocksize; /* Block size */ + uint32_t reserve2[11]; /* Reserved for future use */ +}; + +extern const struct flexspi_nor_config_s g_flash_config; + +#endif /* __BOARDS_ARM_IMXRT_IMXRT1064_EVK_SRC_IMXRT_FLEXSPI_NOR_FLASH_H */ diff --git a/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c b/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c new file mode 100644 index 0000000000..2b505176b4 --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c @@ -0,0 +1,411 @@ +/**************************************************************************** + * boards/nxp/mr-tropic/src/imxrt_flexspi_storage.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "px4_log.h" + +#include +#include +#include "board_config.h" +#include "hardware/imxrt_pinmux.h" +#include "barriers.h" + +/* Used sectors must be multiple of the flash block size + * i.e. W25Q32JV has a block size of 64KB +*/ + +#define NOR_USED_SECTORS (0x40U) /* 64 * 4KB = 256KB */ +#define NOR_TOTAL_SECTORS (0x0400U) +#define NOR_PAGE_SIZE (0x0100U) /* 256 bytes */ +#define NOR_SECTOR_SIZE (0x1000U) /* 4KB */ +#define NOR_START_SECTOR (NOR_TOTAL_SECTORS - NOR_USED_SECTORS) +#define NOR_START_PAGE ((NOR_START_SECTOR * NOR_SECTOR_SIZE) / NOR_PAGE_SIZE) +#define NOR_STORAGE_ADDR (IMXRT_FLEX2CIPHER_BASE + NOR_START_SECTOR * NOR_SECTOR_SIZE) +#define NOR_STORAGE_END (IMXRT_FLEX2CIPHER_BASE + (NOR_START_SECTOR + NOR_TOTAL_SECTORS) * NOR_SECTOR_SIZE) + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +extern struct flexspi_nor_config_s g_bootConfig; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* FlexSPI NOR device private data */ + +struct imxrt_flexspi_storage_dev_s { + struct mtd_dev_s mtd; + uint8_t *ahb_base; +}; + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +/* MTD driver methods */ + +static int imxrt_flexspi_storage_erase(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks); +static ssize_t imxrt_flexspi_storage_read(struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + uint8_t *buffer); +static ssize_t imxrt_flexspi_storage_bread(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + uint8_t *buffer); +static ssize_t imxrt_flexspi_storage_bwrite(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + const uint8_t *buffer); +static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, + int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct imxrt_flexspi_storage_dev_s g_flexspi_nor = { + .mtd = + { + .erase = imxrt_flexspi_storage_erase, + .bread = imxrt_flexspi_storage_bread, + .bwrite = imxrt_flexspi_storage_bwrite, + .read = imxrt_flexspi_storage_read, + .ioctl = imxrt_flexspi_storage_ioctl, +#ifdef CONFIG_MTD_BYTE_WRITE + .write = NULL, +#endif + .name = "imxrt_flexspi_storage" + }, + .ahb_base = (uint8_t *) NOR_STORAGE_ADDR, +}; + +/* Ensure exclusive access to the driver */ + +static sem_t g_exclsem = SEM_INITIALIZER(1); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int imxrt_flexspi_storage_erase_chip( + const struct imxrt_flexspi_storage_dev_s *dev) +{ + /* We can't erase the chip we're executing from */ + return -EINVAL; +} + +static ssize_t imxrt_flexspi_storage_read(struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + uint8_t *buffer) +{ + ssize_t ret; + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; + uint8_t *src; + + finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + + if (offset < 0) { + return -EIO; + } + + src = priv->ahb_base + offset; + + if (src + nbytes > (uint8_t *)NOR_STORAGE_END) { + return -EIO; + } + + ret = nxsem_wait(&g_exclsem); + + if (ret < 0) { + return ret; + } + + memcpy(buffer, src, nbytes); + + nxsem_post(&g_exclsem); + + finfo("return nbytes: %d\n", (int)nbytes); + return (ssize_t)nbytes; +} + +static ssize_t imxrt_flexspi_storage_bread(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + uint8_t *buffer) +{ + ssize_t nbytes; + + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* On this device, we can handle the block read just like the byte-oriented + * read + */ + + nbytes = imxrt_flexspi_storage_read(dev, startblock * NOR_PAGE_SIZE, + nblocks * NOR_PAGE_SIZE, buffer); + + if (nbytes > 0) { + nbytes /= NOR_PAGE_SIZE; + } + + return nbytes; +} + +locate_code(".ramfunc") +static ssize_t imxrt_flexspi_storage_bwrite(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + const uint8_t *buffer) +{ + ssize_t ret; + struct flexspi_nor_config_s *pConfig = &g_bootConfig; + size_t len = nblocks * NOR_PAGE_SIZE; + off_t offset = (startblock + NOR_START_PAGE) * NOR_PAGE_SIZE; + uint8_t *src = (uint8_t *) buffer; +#ifdef CONFIG_ARMV7M_DCACHE + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; + uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE; +#endif + int i; + + if (((uintptr_t)buffer % 4) != 0) { + return -EINVAL; // Byte aligned write not supported + } + + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + ret = nxsem_wait(&g_exclsem); + + if (ret < 0) { + return ret; + } + + while (len) { + i = MIN(NOR_PAGE_SIZE, len); + cpsid(); // Disable interrupts +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + volatile uint32_t status = ROM_FLEXSPI_NorFlash_ProgramPage(NOR_INSTANCE, pConfig, offset, (const uint32_t *)src); +#pragma GCC diagnostic pop + cpsie(); // Enable interrupts + usleep(0); // Yield to scheduler + UNUSED(status); + + offset += i; + src += i; + len -= i; + } + +#ifdef CONFIG_ARMV7M_DCACHE + up_invalidate_dcache((uintptr_t)dst, + (uintptr_t)dst + nblocks * NOR_PAGE_SIZE); +#endif + + nxsem_post(&g_exclsem); + + return nblocks; +} + +locate_code(".ramfunc") +static int imxrt_flexspi_storage_erase(struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks) +{ + struct flexspi_nor_config_s *pConfig = &g_bootConfig; + size_t blocksleft = nblocks; +#ifdef CONFIG_ARMV7M_DCACHE + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; + uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE; +#endif + ssize_t ret; + + startblock += NOR_START_SECTOR; + + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + ret = nxsem_wait(&g_exclsem); + + if (ret < 0) { + return ret; + } + + while (blocksleft-- > 0) { + /* Erase each sector */ + cpsid(); // Disable interrupts + volatile uint32_t status = ROM_FLEXSPI_NorFlash_Erase(NOR_INSTANCE, pConfig, + (startblock * NOR_SECTOR_SIZE), NOR_SECTOR_SIZE); + cpsie(); // Enable interrupts + usleep(0); // Yield to scheduler + UNUSED(status); + startblock++; + } + +#ifdef CONFIG_ARMV7M_DCACHE + up_invalidate_dcache((uintptr_t)dst, + (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE); +#endif + nxsem_post(&g_exclsem); + + return (int)nblocks; +} + +static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, + int cmd, + unsigned long arg) +{ + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + finfo("cmd: %d\n", cmd); + + switch (cmd) { + case MTDIOC_GEOMETRY: { + struct mtd_geometry_s *geo = + (struct mtd_geometry_s *)((uintptr_t)arg); + + if (geo) { + /* Populate the geometry structure with information need to + * know the capacity and how to access the device. + * + * NOTE: + * that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but the + * client will expect the device logic to do whatever is + * necessary to make it appear so. + */ + + geo->blocksize = (NOR_PAGE_SIZE); + geo->erasesize = (NOR_SECTOR_SIZE); + geo->neraseblocks = (NOR_USED_SECTORS); + + ret = OK; + + finfo("blocksize: %lu erasesize: %lu neraseblocks: %lu\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + break; + + case BIOC_PARTINFO: { + struct partition_info_s *info = + (struct partition_info_s *)arg; + + if (info != NULL) { + info->numsectors = (NOR_USED_SECTORS * NOR_SECTOR_SIZE) / NOR_PAGE_SIZE; + info->sectorsize = NOR_PAGE_SIZE; + info->startsector = 0; + info->parent[0] = '\0'; + ret = OK; + } + } + break; + + case MTDIOC_BULKERASE: { + /* Erase the entire device */ + + imxrt_flexspi_storage_erase_chip(priv); + ret = OK; + } + break; + + default: + ret = -ENOTTY; /* Bad/unsupported command */ + break; + } + + finfo("return %d\n", ret); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + +/**************************************************************************** + * Name: imxrt_flexspi_storage_initialize + * + * Description: + * This function is called by board-bringup logic to configure the + * flash device. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int imxrt_flexspi_storage_initialize(void) +{ + struct mtd_dev_s *mtd_dev = &g_flexspi_nor.mtd; + int ret = -ENODEV; + + /* Register the MTD driver so that it can be accessed from the + * VFS. + */ + + ret = register_mtddriver("/dev/nor", mtd_dev, 0755, NULL); + + if (ret < 0) { + syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n", + ret); + } + +#ifdef CONFIG_FS_LITTLEFS + + /* Mount the LittleFS file system */ + + ret = nx_mount("/dev/nor", "/fs/nor", "littlefs", 0, + "autoformat"); + + if (ret < 0) { + syslog(LOG_ERR, + "ERROR: Failed to mount LittleFS at /mnt/lfs: %d\n", + ret); + } + +#endif + + return ret; +} diff --git a/boards/nxp/mr-tropic/src/imxrt_ocram_initialize.c b/boards/nxp/mr-tropic/src/imxrt_ocram_initialize.c new file mode 100644 index 0000000000..67c1a4ca36 --- /dev/null +++ b/boards/nxp/mr-tropic/src/imxrt_ocram_initialize.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (c) 2018-2019, 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file imxrt_ocram_initialize.c + * + * PX4 fmu-v6xrt RAM startup early startup code. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "arm_internal.h" +#include "imxrt_iomuxc.h" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +__BEGIN_DECLS +extern const uint64_t _fitcmfuncs; /* Copy source address in FLASH */ +extern uint64_t _sitcmfuncs; /* Copy destination start address in ITCM */ +extern uint64_t _eitcmfuncs; /* Copy destination end address in ITCM */ +extern uint64_t _sdtcm; /* Copy destination start address in DTCM */ +extern uint64_t _edtcm; /* Copy destination end address in DTCM */ +__END_DECLS + +/**************************************************************************** + * Name: imxrt_ocram_initialize + * + * Description: + * Called off reset vector to reconfigure the flexRAM + * and finish the FLASH to RAM Copy. + * CMakeLists.txt Forces compiler not to use builtin functions using -fno-builtin + * + ****************************************************************************/ + +__EXPORT void imxrt_ocram_initialize(void) +{ + uint32_t regval; + register uint64_t *src; + register uint64_t *dest; + + /* FlexRAM Configuration + * F = 64K ITCM + * A = 64K DTCM + * 5 = 64K OCRAM + * So 0xFFFFFFAA is + * 384K FlexRAM ITCM + * 128K FlexRAM DTCM + * */ + + putreg32(0xFFFFFFAA, IMXRT_IOMUXC_GPR_GPR17); + regval = getreg32(IMXRT_IOMUXC_GPR_GPR16); + putreg32(regval | GPR_GPR16_FLEXRAM_BANK_CFG_SEL, IMXRT_IOMUXC_GPR_GPR16); + + /* Copy any necessary code sections from FLASH to ITCM. The process is the + * same as the code copying from FLASH to RAM above. */ + for (src = (uint64_t *)&_fitcmfuncs, dest = (uint64_t *)&_sitcmfuncs; + dest < (uint64_t *)&_eitcmfuncs;) { + *dest++ = *src++; + } + + /* Clear .dtcm. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sdtcm; dest < &_edtcm;) { + *dest++ = 0; + } +} diff --git a/boards/nxp/mr-tropic/src/init.c b/boards/nxp/mr-tropic/src/init.c new file mode 100644 index 0000000000..7c71fbbef0 --- /dev/null +++ b/boards/nxp/mr-tropic/src/init.c @@ -0,0 +1,400 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * NXP imxrt1062-v1 specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "board_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arm_internal.h" +#include "imxrt_flexspi_nor_boot.h" +#include +#include "imxrt_iomuxc.h" +#include "imxrt_flexcan.h" +#include "imxrt_enet.h" +#include +#include "board_config.h" + +#include +#undef FLEXSPI_LUT_COUNT +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Configuration ************************************************************/ + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); + +extern uint32_t _srodata; /* Start of .rodata */ +extern uint32_t _erodata; /* End of .rodata */ +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + +} +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ + +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_gpio_output(i))); + } + + /* + * On resets invoked from system (not boot) ensure we establish a low + * output state on PWM pins to disarm the ESC and prevent the reset from potentially + * spinning up the motors. + */ + if (status >= 0) { + up_mdelay(100); + } +} + +/**************************************************************************** + * Name: imxrt_flash_romapi_initialize + * + * Description: + * + ****************************************************************************/ +struct flexspi_nor_config_s g_bootConfig; + +locate_code(".ramfunc") +void imxrt_flash_romapi_initialize(void) +{ + memcpy((struct flexspi_nor_config_s *)&g_bootConfig, &g_flash_config, + sizeof(struct flexspi_nor_config_s)); + g_bootConfig.memConfig.tag = FLEXSPI_CFG_BLK_TAG; + + ROM_API_Init(); + + ROM_FLEXSPI_NorFlash_Init(NOR_INSTANCE, (struct flexspi_nor_config_s *)&g_bootConfig); + ROM_FLEXSPI_NorFlash_ClearCache(NOR_INSTANCE); + + ARM_DSB(); + ARM_ISB(); + ARM_DMB(); +} + +locate_code(".ramfunc") +void imxrt_flash_setup_prefetch_partition(void) +{ +//Prefetch tuning to be determined +#if 0 + putreg32((uint32_t)&_srodata, IMXRT_FLEXSPI1_AHBBUFREGIONSTART0); + putreg32((uint32_t)&_erodata, IMXRT_FLEXSPI1_AHBBUFREGIONEND0); + /*putreg32((uint32_t)&_stext, IMXRT_FLEXSPI1_AHBBUFREGIONSTART1); + putreg32((uint32_t)&_etext, IMXRT_FLEXSPI1_AHBBUFREGIONEND1); + putreg32((uint32_t)&_stext, IMXRT_FLEXSPI1_AHBBUFREGIONSTART2); + putreg32((uint32_t)&_etext, IMXRT_FLEXSPI1_AHBBUFREGIONEND2); + putreg32((uint32_t)&_stext, IMXRT_FLEXSPI1_AHBBUFREGIONSTART3); + putreg32((uint32_t)&_etext, IMXRT_FLEXSPI1_AHBBUFREGIONEND3);*/ +#endif +#if 0 + struct flexspi_type_s *g_flexspi = (struct flexspi_type_s *)IMXRT_FLEXSPIC_BASE; + /* RODATA */ + g_flexspi->AHBRXBUFCR0[0] = FLEXSPI_AHBRXBUFCR0_BUFSZ(48) | + FLEXSPI_AHBRXBUFCR0_MSTRID(0) | + FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | + FLEXSPI_AHBRXBUFCR0_REGIONEN(1); + + + /* All Text */ + g_flexspi->AHBRXBUFCR0[1] = FLEXSPI_AHBRXBUFCR0_BUFSZ(80) | + FLEXSPI_AHBRXBUFCR0_MSTRID(0) | + FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | + FLEXSPI_AHBRXBUFCR0_REGIONEN(1); + + /* Disable 2 */ + g_flexspi->AHBRXBUFCR0[2] = FLEXSPI_AHBRXBUFCR0_BUFSZ(0) | + FLEXSPI_AHBRXBUFCR0_MSTRID(0) | + FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | + FLEXSPI_AHBRXBUFCR0_REGIONEN(0); + + /* Disable 3 */ + g_flexspi->AHBRXBUFCR0[3] = FLEXSPI_AHBRXBUFCR0_BUFSZ(0) | + FLEXSPI_AHBRXBUFCR0_MSTRID(0) | + FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | + FLEXSPI_AHBRXBUFCR0_REGIONEN(0); +#endif + + ARM_DSB(); + ARM_ISB(); + ARM_DMB(); +} + +/**************************************************************************** + * Name: imxrt_boardinitialize + * + * Description: + * All i.MX RT architectures must provide the following entry point. This + * entry point is called early in the initialization -- after clocking and + * memory have been configured but before caches have been enabled and + * before any devices have been initialized. + * + ****************************************************************************/ + +__EXPORT void imxrt_boardinitialize(void) +{ + imxrt_flash_setup_prefetch_partition(); + + imxrt_flash_romapi_initialize(); + + board_on_reset(-1); /* Reset PWM first thing */ + + /* configure LEDs */ + + board_autoled_initialize(); + + /* configure pins */ + + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + imxrt_usb_initialize(); + + fmurt1062_timer_initialize(); +} + +/**************************************************************************** + * Function: imxrt_phy_boardinitialize + * + * Description: + * Some boards require specialized initialization of the PHY before it can + * be used. This may include such things as configuring GPIOs, resetting + * the PHY, etc. + * If CONFIG_IMXRT_ENET_PHYINIT is defined in the configuration then the + * board specific logic must provide imxrt_phyinitialize(); + * The i.MX RT Ethernet driver will call this function one time before it + * first uses the PHY. + * + * Input Parameters: + * intf - Always zero for now. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int imxrt_phy_boardinitialize(int intf) +{ +#ifdef CONFIG_IMXRT_GPIO1_0_15_IRQ + /* Configure the PHY interrupt pin */ + + printf("Configuring interrupt: %08x\n", GPIO_ENET_INT); + imxrt_config_gpio(GPIO_ENET_INT); +#endif + return OK; +} + +void imxrt_flexio_clocking(void) +{ + uint32_t reg; + + /* Init USB PLL3 PFD2 */ + + reg = getreg32(IMXRT_CCM_ANALOG_PFD_480); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_USB1) & + CCM_ANALOG_PLL_USB1_LOCK) == 0) { + } + + reg &= ~CCM_ANALOG_PFD_480_PFD2_FRAC_MASK; + + /* Set PLL3 PFD2 to 480 * 18 / CONFIG_PLL3_PFD2_FRAC */ + + reg |= ((uint32_t)(CONFIG_PLL3_PFD2_FRAC) << CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT); + + putreg32(reg, IMXRT_CCM_ANALOG_PFD_480); + + reg = getreg32(IMXRT_CCM_CDCDR); + reg &= ~(CCM_CDCDR_FLEXIO1_CLK_SEL_MASK | + CCM_CDCDR_FLEXIO1_CLK_PODF_MASK | + CCM_CDCDR_FLEXIO1_CLK_PRED_MASK); + reg |= CCM_CDCDR_FLEXIO1_CLK_SEL(CONFIG_FLEXIO1_CLK); + reg |= CCM_CDCDR_FLEXIO1_CLK_PODF + (CCM_PODF_FROM_DIVISOR(CONFIG_FLEXIO1_PODF_DIVIDER)); + reg |= CCM_CDCDR_FLEXIO1_CLK_PRED + (CCM_PRED_FROM_DIVISOR(CONFIG_FLEXIO1_PRED_DIVIDER)); + putreg32(reg, IMXRT_CCM_CDCDR); +} + + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + int ret = OK; + +#if !defined(BOOTLOADER) + + imxrt_flexio_clocking(); + + /* Power on Interfaces */ + + px4_platform_init(); + + imxrt_spiinitialize(); + + board_determine_hw_info(); + + /* configure the DMA allocator */ + + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + +#if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)imxrt_serial_dma_poll, NULL); +#endif + +#if defined(CONFIG_IMXRT_USDHC) + ret = fmurt1062_usdhc_initialize(); +#endif + + imxrt_spiinitialize(); + + board_spi_reset(10, 0xffff); + +#ifdef CONFIG_IMXRT_ENET + imxrt_gpio_write(GPIO_ENET_RST, true); + + usleep(2000); + + imxrt_netinitialize(0); +#endif + +#ifdef CONFIG_IMXRT_FLEXCAN3 + imxrt_caninitialize(3); +#endif + + ret = imxrt_flexspi_storage_initialize(); + + if (ret < 0) { + syslog(LOG_ERR, + "ERROR: imxrt_flexspi_nor_initialize failed: %d\n", ret); + } + +#endif /* !defined(BOOTLOADER) */ + + return ret; +} diff --git a/boards/nxp/mr-tropic/src/manifest.c b/boards/nxp/mr-tropic/src/manifest.c new file mode 100644 index 0000000000..afd3de58e5 --- /dev/null +++ b/boards/nxp/mr-tropic/src/manifest.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * + * Copyright (c) 2023 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file manifest.c + * + * This module supplies the interface to the manifest of hardware that is + * optional and dependent on the HW REV and HW VER IDs + * + * The manifest allows the system to know whether a hardware option + * say for example the PX4IO is an no-pop option vs it is broken. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "systemlib/px4_macros.h" +#include "px4_log.h" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + + +/************************************************************************************ + * Name: board_query_manifest + * + * Description: + * Optional returns manifest item. + * + * Input Parameters: + * manifest_id - the ID for the manifest item to retrieve + * + * Returned Value: + * 0 - item is not in manifest => assume legacy operations + * pointer to a manifest item + * + ************************************************************************************/ + +__EXPORT px4_hw_mft_item board_query_manifest(px4_hw_mft_item_id_t id) +{ + return px4_hw_mft_unsupported; +} diff --git a/boards/nxp/mr-tropic/src/sdhc.c b/boards/nxp/mr-tropic/src/sdhc.c new file mode 100644 index 0000000000..df2f92cc1c --- /dev/null +++ b/boards/nxp/mr-tropic/src/sdhc.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * + * Copyright (C) 2016-2018 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/* A micro Secure Digital (SD) card slot is available on the board connected to + * the SD Host Controller (USDHC1) signals of the MCU. This slot will accept + * micro format SD memory cards. + * + * ------------ ------------- -------- + * SD Card Slot Board Signal IMXRT Pin + * ------------ ------------- -------- + * DAT0 USDHC1_DATA0 GPIO_SD_B0_02 + * DAT1 USDHC1_DATA1 GPIO_SD_B0_03 + * DAT2 USDHC1_DATA2 GPIO_SD_B0_04 + * CD/DAT3 USDHC1_DATA3 GPIO_SD_B0_05 + * CMD USDHC1_CMD GPIO_SD_B0_00 + * CLK USDHC1_CLK GPIO_SD_B0_01 + * CD USDHC1_CD GPIO_B1_12 + * ------------ ------------- -------- + * + * There are no Write Protect available to the IMXRT. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "imxrt_usdhc.h" + +#include "board_config.h" + +#ifdef CONFIG_IMXRT_USDHC +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fmurt1062_usdhc_initialize + * + * Description: + * Inititialize the SDHC SD card slot + * + ****************************************************************************/ + +int fmurt1062_usdhc_initialize(void) +{ + int ret; + + /* Mount the SDHC-based MMC/SD block driver */ + /* First, get an instance of the SDHC interface */ + + struct sdio_dev_s *sdhc = imxrt_usdhc_initialize(CONFIG_NSH_MMCSDSLOTNO); + + if (!sdhc) { + PX4_ERR("ERROR: Failed to initialize SDHC slot %d\n", CONFIG_NSH_MMCSDSLOTNO); + return -ENODEV; + } + + /* Now bind the SDHC interface to the MMC/SD driver */ + + ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdhc); + + if (ret != OK) { + PX4_ERR("ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n", ret); + return ret; + } + + syslog(LOG_INFO, "Successfully bound SDHC to the MMC/SD driver\n"); + + return OK; +} +#endif /* CONFIG_IMXRT_USDHC */ diff --git a/boards/nxp/mr-tropic/src/spi.cpp b/boards/nxp/mr-tropic/src/spi.cpp new file mode 100644 index 0000000000..afea0032a5 --- /dev/null +++ b/boards/nxp/mr-tropic/src/spi.cpp @@ -0,0 +1,95 @@ +/************************************************************************************ + * + * Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include "imxrt_lpspi.h" +#include "imxrt_gpio.h" +#include "board_config.h" +#include + +constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSIONS] = { + initSPIFmumID(TROPIC_0, { + initSPIBus(SPI::Bus::LPSPI3, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM45686, SPI::CS{GPIO::Port1, GPIO::Pin28}, SPI::DRDY{GPIO::Port3, GPIO::Pin18}), /* GPIO_AD_B1_12 GPIO1_IO28 */ + }), + initSPIBus(SPI::Bus::LPSPI4, { + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin18}, SPI::DRDY{GPIO::Port2, GPIO::Pin10}), /* GPIO_B1_02 GPIO2_IO18 */ + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin0}, SPI::DRDY{GPIO::Port1, GPIO::Pin25}), /* GPIO_B0_00 GPIO2_IO00 */ + }), + }), + + initSPIFmumID(TROPIC_1, { + initSPIBus(SPI::Bus::LPSPI3, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::Port1, GPIO::Pin28}), /* GPIO_AD_B1_12 GPIO1_IO28 */ + }), + initSPIBus(SPI::Bus::LPSPI4, { + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin18}), /* GPIO_B1_02 GPIO2_IO18 */ + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin0}), /* GPIO_B0_00 GPIO2_IO00 */ + }), + }), + + initSPIFmumID(TROPIC_2, { + initSPIBus(SPI::Bus::LPSPI3, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42686P, SPI::CS{GPIO::Port1, GPIO::Pin28}), /* GPIO_AD_B1_12 GPIO1_IO28 */ + }), + initSPIBus(SPI::Bus::LPSPI4, { + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin18}), /* GPIO_B1_02 GPIO2_IO18 */ + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::Port2, GPIO::Pin0}), /* GPIO_B0_00 GPIO2_IO00 */ + }), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses_all_hw); diff --git a/boards/nxp/mr-tropic/src/timer_config.cpp b/boards/nxp/mr-tropic/src/timer_config.cpp new file mode 100644 index 0000000000..a15a7e83fb --- /dev/null +++ b/boards/nxp/mr-tropic/src/timer_config.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** + * + * Copyright (C) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include + +#include +#include "hardware/imxrt_tmr.h" +#include "hardware/imxrt_flexpwm.h" +#include "imxrt_gpio.h" +#include "imxrt_iomuxc.h" +#include "hardware/imxrt_pinmux.h" +#include "imxrt_xbar.h" +#include "imxrt_periphclks.h" + +#include +#include + +#include "board_config.h" + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* Register accessors */ + +#define _REG(_addr) (*(volatile uint16_t *)(_addr)) + +/* QTimer3 register accessors */ + +#define REG(_reg) _REG(IMXRT_QTIMER3_BASE + IMXRT_TMR_OFFSET(IMXRT_TMR_CH0,(_reg))) + +#define rCOMP1 REG(IMXRT_TMR_COMP1_OFFSET) +#define rCOMP2 REG(IMXRT_TMR_COMP2_OFFSET) +#define rCAPT REG(IMXRT_TMR_CAPT_OFFSET) +#define rLOAD REG(IMXRT_TMR_LOAD_OFFSET) +#define rHOLD REG(IMXRT_TMR_HOLD_OFFSET) +#define rCNTR REG(IMXRT_TMR_CNTR_OFFSET) +#define rCTRL REG(IMXRT_TMR_CTRL_OFFSET) +#define rSCTRL REG(IMXRT_TMR_SCTRL_OFFSET) +#define rCMPLD1 REG(IMXRT_TMR_CMPLD1_OFFSET) +#define rCMPLD2 REG(IMXRT_TMR_CMPLD2_OFFSET) +#define rCSCTRL REG(IMXRT_TMR_CSCTRL_OFFSET) +#define rFILT REG(IMXRT_TMR_FILT_OFFSET) +#define rDMA REG(IMXRT_TMR_DMA_OFFSET) +#define rENBL REG(IMXRT_TMR_ENBL_OFFSET) + + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOPWMDshot(PWM::FlexPWM2, PWM::Submodule0), // PWM_1, PMW_2 + initIOPWMDshot(PWM::FlexPWM2, PWM::Submodule1), // PWM_3, PWM_4 + initIOPWMDshot(PWM::FlexPWM4, PWM::Submodule1), // PWM_5, PWM_6 + initIOPWMDshot(PWM::FlexPWM4, PWM::Submodule2), // PWM_7, PWM_8 +}; + +#define FXIO_IOMUX (IOMUX_SLEW_FAST | IOMUX_DRIVE_130OHM | IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER) + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannelDshot(io_timers, {PWM::PWM2_PWM_A, PWM::Submodule0}, IOMUX::Pad::GPIO_EMC_06, GPIO_FLEXIO1_FLEXIO06_1 | FXIO_IOMUX, 6), + initIOTimerChannelDshot(io_timers, {PWM::PWM2_PWM_B, PWM::Submodule0}, IOMUX::Pad::GPIO_EMC_07, GPIO_FLEXIO1_FLEXIO07_1 | FXIO_IOMUX, 7), + initIOTimerChannelDshot(io_timers, {PWM::PWM2_PWM_A, PWM::Submodule1}, IOMUX::Pad::GPIO_EMC_08, GPIO_FLEXIO1_FLEXIO08_1 | FXIO_IOMUX, 8), + initIOTimerChannelDshot(io_timers, {PWM::PWM2_PWM_B, PWM::Submodule1}, IOMUX::Pad::GPIO_EMC_09, GPIO_FLEXIO1_FLEXIO09_1 | FXIO_IOMUX, 9), + initIOTimerChannelDshot(io_timers, {PWM::PWM4_PWM_A, PWM::Submodule1}, IOMUX::Pad::GPIO_EMC_02, GPIO_FLEXIO1_FLEXIO02_1 | FXIO_IOMUX, 2), + initIOTimerChannelDshot(io_timers, {PWM::PWM4_PWM_B, PWM::Submodule1}, IOMUX::Pad::GPIO_EMC_03, GPIO_FLEXIO1_FLEXIO03_1 | FXIO_IOMUX, 3), + initIOTimerChannelDshot(io_timers, {PWM::PWM4_PWM_A, PWM::Submodule2}, IOMUX::Pad::GPIO_EMC_04, GPIO_FLEXIO1_FLEXIO04_1 | FXIO_IOMUX, 4), + initIOTimerChannelDshot(io_timers, {PWM::PWM4_PWM_B, PWM::Submodule2}, IOMUX::Pad::GPIO_EMC_05, GPIO_FLEXIO1_FLEXIO05_1 | FXIO_IOMUX, 5), +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); + +constexpr io_timers_t led_pwm_timers[MAX_LED_TIMERS] = { +}; + +constexpr timer_io_channels_t led_pwm_channels[MAX_TIMER_LED_CHANNELS] = { +}; + +#include +void fmurt1062_timer_initialize(void) +{ + /* We must configure Qtimer 3 as the IPG divide by to yield 16 Mhz + * and deliver that clock to the eFlexPWM234 via XBAR + * + * IPG = 144 Mhz + * 16Mhz = 144 / 9 + * COMP 1 = 5, COMP2 = 4 + * + * */ + + /* Enable Block Clocks for Qtimer and XBAR1 */ + + imxrt_clockall_timer3(); + imxrt_clockall_xbar1(); + + /* Disable Timer */ + + rCTRL = 0; + rCOMP1 = 5 - 1; // N - 1 + rCOMP2 = 4 - 1; + + rCAPT = 0; + rLOAD = 0; + rCNTR = 0; + + rSCTRL = TMR_SCTRL_OEN; + + rCMPLD1 = 0; + rCMPLD2 = 0; + rCSCTRL = 0; + rFILT = 0; + rDMA = 0; + + /* Count rising edges of primary source, + * Prescaler is /1 + * Count UP until compare, then re-initialize. a successful compare occurs when the counter reaches a COMP1 value. + * Toggle OFLAG output using alternating compare registers + */ + rCTRL = (TMR_CTRL_CM_MODE1 | TMR_CTRL_PCS_DIV1 | TMR_CTRL_LENGTH | TMR_CTRL_OUTMODE_TOG_ALT); + + /* QTIMER3_TIMER0 -> Flexpwm234ExtClk */ + + imxrt_xbar_connect(IMXRT_XBARA1_OUT_FLEXPWM234_EXT_CLK_SEL_OFFSET, IMXRT_XBARA1_IN_QTIMER3_TMR0_OUT); + imxrt_xbar_connect(IMXRT_XBARA1_OUT_FLEXPWM1_EXT_CLK_SEL_OFFSET, IMXRT_XBARA1_IN_QTIMER3_TMR0_OUT); +} diff --git a/boards/nxp/mr-tropic/src/tropic_led_pwm.cpp b/boards/nxp/mr-tropic/src/tropic_led_pwm.cpp new file mode 100644 index 0000000000..45598fc787 --- /dev/null +++ b/boards/nxp/mr-tropic/src/tropic_led_pwm.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Airmind nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** +* @file tropic_led_pwm.cpp +*/ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include "imxrt_xbar.h" +#include "imxrt_periphclks.h" +#include "hardware/imxrt_tmr.h" +#include "hardware/imxrt_flexpwm.h" + +#define LED_PWM_FREQ 1000 +#define FLEXPWM_FREQ 1000000 +#define QTMR_FREQ (144000000/128) + +#define SM_SPACING (IMXRT_FLEXPWM_SM1CNT_OFFSET-IMXRT_FLEXPWM_SM0CNT_OFFSET) + +#define FLEXPWM_TIMER_BASE IMXRT_FLEXPWM2_BASE + +/* Register accessors */ +#define _REG(_addr) (*(volatile uint16_t *)(_addr)) +#define _REG16(_base, _reg) (*(volatile uint16_t *)(_base + _reg)) +#define FLEXPWMREG(_tmr, _sm, _reg) _REG16(_tmr + ((_sm) * SM_SPACING), (_reg)) + +/* FlexPWM Registers for LED_G */ +#define rINIT(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0INIT_OFFSET) /* Initial Count Register */ +#define rCTRL(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0CTRL_OFFSET) /* Control Register */ +#define rCTRL2(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0CTRL2_OFFSET) /* Control 2 Register */ +#define rFSTS0(_tim) FLEXPWMREG(_tim, 0, IMXRT_FLEXPWM_FSTS0_OFFSET) /* Fault Status Register */ +#define rVAL0(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL0_OFFSET) /* Value Register 0 */ +#define rVAL1(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL1_OFFSET) /* Value Register 1 */ +#define rVAL2(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL2_OFFSET) /* Value Register 2 */ +#define rVAL3(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL3_OFFSET) /* Value Register 3 */ +#define rVAL4(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL4_OFFSET) /* Value Register 4 */ +#define rVAL5(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0VAL5_OFFSET) /* Value Register 5 */ +#define rFFILT0(_tim) FLEXPWMREG(_tim, 0, IMXRT_FLEXPWM_FFILT0_OFFSET) /* Fault Filter Register */ +#define rDISMAP0(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0DISMAP0_OFFSET) /* Fault Disable Mapping Register 0 */ +#define rDISMAP1(_tim, _sm) FLEXPWMREG(_tim, _sm,IMXRT_FLEXPWM_SM0DISMAP1_OFFSET) /* Fault Disable Mapping Register 1 */ +#define rOUTEN(_tim) FLEXPWMREG(_tim, 0, IMXRT_FLEXPWM_OUTEN_OFFSET) /* Output Enable Register */ +#define rDTSRCSEL(_tim) FLEXPWMREG(_tim, 0, IMXRT_FLEXPWM_DTSRCSEL_OFFSET) /* PWM Source Select Register */ +#define rMCTRL(_tim) FLEXPWMREG(_tim, 0, IMXRT_FLEXPWM_MCTRL_OFFSET) /* Master Control Register */ + +#define OUTEN_A_MASK 0x1 +#define OUTEN_B_MASK 0x2 + +#define FREQ + +static void flexpwm_led(uint32_t timer, uint32_t sm, uint16_t cvalue, uint32_t gpio_mux, uint32_t pwm_mux, + uint32_t out_mask) +{ + if (cvalue == 0) { + //rMCTRL(timer) &= ~MCTRL_RUN(1 << sm); + px4_arch_configgpio(gpio_mux); + + } else { + rMCTRL(timer) |= (1 << (sm + MCTRL_CLDOK_SHIFT)); + rVAL1(timer, sm) = (FLEXPWM_FREQ / LED_PWM_FREQ) - 1; + + if (out_mask & OUTEN_A_MASK) { + rVAL3(timer, sm) = (FLEXPWM_FREQ / LED_PWM_FREQ) - (cvalue); + + } else if (out_mask & OUTEN_B_MASK) { + rVAL5(timer, sm) = (FLEXPWM_FREQ / LED_PWM_FREQ) - (cvalue); + } + + rMCTRL(timer) |= MCTRL_LDOK(1 << sm) | MCTRL_RUN(1 << sm); + px4_arch_configgpio(pwm_mux); + } +} + +int +led_pwm_servo_set(unsigned channel, uint8_t cvalue) +{ + if (channel == 0) { + flexpwm_led(IMXRT_FLEXPWM3_BASE, 2, cvalue, GPIO_nLED_RED, PWM_LED_RED, OUTEN_A_MASK); + + } else if (channel == 1) { + flexpwm_led(IMXRT_FLEXPWM1_BASE, 3, cvalue, GPIO_nLED_GREEN, PWM_LED_GREEN, OUTEN_A_MASK); + + } else if (channel == 2) { + flexpwm_led(IMXRT_FLEXPWM3_BASE, 2, cvalue * 3, GPIO_nLED_BLUE, PWM_LED_BLUE, OUTEN_B_MASK); + } + + return 0; +} + +void flexpwm_init(uint32_t timer, uint32_t sm, uint32_t out_mask) +{ + /* Clear all Faults */ + rFSTS0(timer) = FSTS_FFLAG_MASK; + rMCTRL(timer) |= (1 << (sm + MCTRL_CLDOK_SHIFT)); + + rCTRL2(timer, sm) = SMCTRL2_CLK_SEL_EXT_CLK | SMCTRL2_DBGEN | SMCTRL2_INDEP; + rCTRL(timer, sm) = SMCTRL_PRSC_DIV16 | SMCTRL_FULL; + /* Edge aligned at 0 */ + rINIT(timer, sm) = 0; + rVAL0(timer, sm) = 0; + rVAL2(timer, sm) = 0; + rVAL4(timer, sm) = 0; + rFFILT0(timer) &= ~FFILT_FILT_PER_MASK; + rDISMAP0(timer, sm) = 0xf000; + rDISMAP1(timer, sm) = 0xf000; + + + if (out_mask & OUTEN_A_MASK) { + rOUTEN(timer) |= OUTEN_PWMA_EN(1 << sm); + } + + if (out_mask & OUTEN_B_MASK) { + rOUTEN(timer) |= OUTEN_PWMB_EN(1 << sm); + } + + rDTSRCSEL(timer) = 0; + rMCTRL(timer) |= MCTRL_LDOK(1 << sm); +} + +int led_pwm_servo_init() +{ + /* PWM_LED_GREEN - FLEXPWM2_PWMB03 */ + imxrt_clockall_pwm1(); + imxrt_clockall_pwm3(); + + flexpwm_init(IMXRT_FLEXPWM3_BASE, 2, OUTEN_A_MASK | OUTEN_B_MASK); // GPIO_FLEXPWM3_PWMA02_1 + flexpwm_init(IMXRT_FLEXPWM1_BASE, 3, OUTEN_A_MASK); // GPIO_FLEXPWM1_PWMA03_2 + + + + return OK; +} diff --git a/boards/nxp/mr-tropic/src/usb.c b/boards/nxp/mr-tropic/src/usb.c new file mode 100644 index 0000000000..cae9750e9c --- /dev/null +++ b/boards/nxp/mr-tropic/src/usb.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * + * Copyright (C) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include "board_config.h" +#include "imxrt_periphclks.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int imxrt_usb_initialize(void) +{ + imxrt_clockall_usboh3(); + return 0; +} +/************************************************************************************ + * Name: imxrt_usbpullup + * + * Description: + * If USB is supported and the board supports a pullup via GPIO (for USB software + * connect and disconnect), then the board software must provide imxrt_usbpullup. + * See include/nuttx/usb/usbdev.h for additional description of this method. + * Alternatively, if no pull-up GPIO the following EXTERN can be redefined to be + * NULL. + * + ************************************************************************************/ + +__EXPORT +int imxrt_usbpullup(FAR struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + return OK; +} + +/************************************************************************************ + * Name: imxrt_usbsuspend + * + * Description: + * Board logic must provide the imxrt_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +__EXPORT +void imxrt_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} + +/************************************************************************************ + * Name: board_read_VBUS_state + * + * Description: + * All boards must provide a way to read the state of VBUS, this my be simple + * digital input on a GPIO. Or something more complicated like a Analong input + * or reading a bit from a USB controller register. + * + * Returns - 0 if connected. + * + ************************************************************************************/ + +int board_read_VBUS_state(void) +{ + + return (getreg32(IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT) & USB_ANALOG_USB_VBUS_DETECT_STAT_VBUS_VALID) ? 0 : 1; +} diff --git a/boards/nxp/tropic-community/default.px4board b/boards/nxp/tropic-community/default.px4board index abbef2d0c0..4d16067dc7 100644 --- a/boards/nxp/tropic-community/default.px4board +++ b/boards/nxp/tropic-community/default.px4board @@ -14,6 +14,7 @@ CONFIG_DRIVERS_CAMERA_TRIGGER=y CONFIG_DRIVERS_CDCACM_AUTOSTART=y CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_SF45_SERIAL=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_GNSS_SEPTENTRIO=y CONFIG_DRIVERS_GPS=y @@ -25,13 +26,12 @@ CONFIG_COMMON_INS=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y -CONFIG_COMMON_OSD=y +CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y CONFIG_DRIVERS_PWM_OUT=y -CONFIG_DRIVERS_RC_INPUT=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y @@ -44,13 +44,15 @@ CONFIG_MODULES_CAMERA_FEEDBACK=y CONFIG_MODULES_COMMANDER=y CONFIG_MODULES_CONTROL_ALLOCATOR=y CONFIG_MODULES_DATAMAN=y +CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000 CONFIG_MODULES_EKF2=y CONFIG_MODULES_ESC_BATTERY=y CONFIG_MODULES_EVENTS=y CONFIG_MODULES_FLIGHT_MODE_MANAGER=y CONFIG_MODULES_FW_ATT_CONTROL=y CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y -CONFIG_MODULES_FW_POS_CONTROL=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y CONFIG_MODULES_FW_RATE_CONTROL=y CONFIG_MODULES_GIMBAL=y CONFIG_MODULES_GYRO_CALIBRATION=y @@ -100,3 +102,4 @@ CONFIG_SYSTEMCMDS_UORB=y CONFIG_SYSTEMCMDS_USB_CONNECTED=y CONFIG_SYSTEMCMDS_VER=y CONFIG_SYSTEMCMDS_WORK_QUEUE=y +CONFIG_ARCH_CHIP_IMXRT=y diff --git a/boards/nxp/tropic-community/init/rc.board_defaults b/boards/nxp/tropic-community/init/rc.board_defaults index 8a49eca594..31ed136105 100644 --- a/boards/nxp/tropic-community/init/rc.board_defaults +++ b/boards/nxp/tropic-community/init/rc.board_defaults @@ -12,10 +12,6 @@ param set-default MAV_2_RATE 100000 param set-default MAV_2_REMOTE_PRT 14550 param set-default MAV_2_UDP_PRT 14550 -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - param set-default BAT1_V_DIV 18.000000000 param set-default BAT1_A_PER_V 38.462030303 diff --git a/boards/nxp/tropic-community/nuttx-config/nsh/defconfig b/boards/nxp/tropic-community/nuttx-config/nsh/defconfig index 051887c166..4c2720028b 100644 --- a/boards/nxp/tropic-community/nuttx-config/nsh/defconfig +++ b/boards/nxp/tropic-community/nuttx-config/nsh/defconfig @@ -62,7 +62,9 @@ CONFIG_FS_CROMFS=y CONFIG_FS_FAT=y CONFIG_FS_FATTIME=y CONFIG_FS_LITTLEFS=y -CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=2 +CONFIG_FS_LITTLEFS_CACHE_SIZE_FACTOR=2 +CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=64 +CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR=1 CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_MAX_TASKS=64 CONFIG_FS_PROCFS_REGISTER=y @@ -75,6 +77,7 @@ CONFIG_I2C=y CONFIG_I2C_RESET=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_DTCM_HEAP=y +CONFIG_IMXRT_DTCM_HEAP_SIZE=127 CONFIG_IMXRT_EDMA=y CONFIG_IMXRT_EDMA_EDBG=y CONFIG_IMXRT_EDMA_ELINK=y @@ -84,8 +87,6 @@ CONFIG_IMXRT_ENET_NTXBUFFERS=8 CONFIG_IMXRT_ENET_PHYINIT=y CONFIG_IMXRT_FLEXCAN3=y CONFIG_IMXRT_FLEXCAN_TXMB=1 -CONFIG_IMXRT_FLEXSPI1=y -CONFIG_IMXRT_FLEXSPI1_XIP=y CONFIG_IMXRT_GPIO1_0_15_IRQ=y CONFIG_IMXRT_GPIO1_16_31_IRQ=y CONFIG_IMXRT_GPIO2_0_15_IRQ=y diff --git a/boards/nxp/tropic-community/nuttx-config/scripts/itcm_functions_includes.ld b/boards/nxp/tropic-community/nuttx-config/scripts/itcm_functions_includes.ld index 0e6701aae2..36330c1e85 100644 --- a/boards/nxp/tropic-community/nuttx-config/scripts/itcm_functions_includes.ld +++ b/boards/nxp/tropic-community/nuttx-config/scripts/itcm_functions_includes.ld @@ -1,4 +1,3 @@ -/* Auto-generated */ *(.text._ZN4uORB7Manager27orb_add_internal_subscriberE6ORB_IDhPj) *(.text._ZN13MavlinkStream6updateERKy) *(.text._ZN7Mavlink16update_rate_multEv) @@ -394,7 +393,7 @@ *(.text._ZN4EKF215PublishBaroBiasERKy) *(.text._ZN4EKF221UpdateGyroCalibrationERKy) *(.text._ZN6matrix9constrainIfLj3ELj1EEENS_6MatrixIT_XT0_EXT1_EEERKS3_S2_S2_) -*(.text._ZN4uORB22SubscriptionMultiArrayI16battery_status_sLh4EE16advertised_countEv) +*(.text._ZN4uORB22SubscriptionMultiArrayI16battery_status_sLh3EE16advertised_countEv) *(.text._ZN23MavlinkStreamScaledIMU34sendEv) *(.text.__aeabi_ldivmod) *(.text._ZN15PositionControl16setInputSetpointERK21trajectory_setpoint_s) diff --git a/boards/nxp/tropic-community/nuttx-config/scripts/itcm_static_functions.ld b/boards/nxp/tropic-community/nuttx-config/scripts/itcm_static_functions.ld index a14521a6b5..509d820fd4 100644 --- a/boards/nxp/tropic-community/nuttx-config/scripts/itcm_static_functions.ld +++ b/boards/nxp/tropic-community/nuttx-config/scripts/itcm_static_functions.ld @@ -115,18 +115,29 @@ *(.text.work_thread) *(.text.work_queue) -/* Flash Storage */ -*(.text.imxrt_flexspi_transfer_blocking) -*(.text.imxrt_flexspi_transfer_blocking_private) -*(.text.imxrt_flexspi_write_blocking) -*(.text.imxrt_flexspi_read_blocking) -*(.text.imxrt_flexspi_check_and_clear_error) -*(.text.imxrt_flexspi_get_bus_idle_status) -*(.text.imxrt_flexspi_configure_prefetch) -*(.text.imxrt_flexspi_configure_prefetch_private) -*(.text.imxrt_flexspi_storage_write_enable) -*(.text.imxrt_flexspi_storage_wait_bus_busy) -*(.text.imxrt_flexspi_storage_read_status) -*(.text.imxrt_flexspi_storage_erase) -*(.text.imxrt_flexspi_storage_bwrite) -*(.text.imxrt_flexspi_storage_page_program) +/* BMI088 */ +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer12RegisterReadENS1_8RegisterE) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13FIFOReadCountEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer8FIFOReadERKyh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13RegisterCheckERKNS2_17register_config_tE) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer13RegisterWriteENS1_8RegisterEh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer17UpdateTemperatureEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer23RegisterSetAndClearBitsENS1_8RegisterEhh) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer26DataReadyInterruptCallbackEiPvS3_) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer7RunImplEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_Accelerometer9DataReadyEv) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD0Ev) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD1Ev) +*(.text._ZN5Bosch6BMI08813Accelerometer20BMI088_AccelerometerD2Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope12RegisterReadENS1_8RegisterE) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope13RegisterCheckERKNS2_17register_config_tE) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope13RegisterWriteENS1_8RegisterEh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope23RegisterSetAndClearBitsENS1_8RegisterEhh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope26DataReadyInterruptCallbackEiPvS3_) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope7RunImplEv) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope8FIFOReadERKyh) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_Gyroscope9DataReadyEv) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD0Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD1Ev) +*(.text._ZN5Bosch6BMI0889Gyroscope16BMI088_GyroscopeD2Ev) +*(.text._ZN12I2CSPIDriverI6BMI088E3RunEv) diff --git a/boards/nxp/tropic-community/nuttx-config/scripts/script.ld b/boards/nxp/tropic-community/nuttx-config/scripts/script.ld index 9c25a7e1a2..1e4ae18285 100644 --- a/boards/nxp/tropic-community/nuttx-config/scripts/script.ld +++ b/boards/nxp/tropic-community/nuttx-config/scripts/script.ld @@ -22,10 +22,11 @@ MEMORY { - flash (rx) : ORIGIN = 0x60000000, LENGTH = 7936K - 128K + flash (rx) : ORIGIN = 0x60000000, LENGTH = 7936K - 256K sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512K itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 384K - dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 127K + dtcm_nocache (rwx) : ORIGIN = 0x2001FC00, LENGTH = 1K } OUTPUT_ARCH(arm) @@ -55,6 +56,12 @@ SECTIONS . = 0x2000 ; } >flash + /* Workaround for ethernet issue, by placing g_desc_pool into DTCM, + which effectively puts it into a no-cache region */ + .dtcm_nocache : { + *(.bss.g_desc_pool) + } > dtcm_nocache + .vectors : { KEEP(*(.vectors)) @@ -162,6 +169,10 @@ SECTIONS .debug_line 0 : { *(.debug_line) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_aranges 0 : { *(.debug_aranges) } + + _boot_loadaddr = ORIGIN(flash); + _boot_size = LENGTH(flash); + _ram_size = LENGTH(sram); _sdtcm = ORIGIN(dtcm); _edtcm = ORIGIN(dtcm) + LENGTH(dtcm); } diff --git a/boards/nxp/tropic-community/src/CMakeLists.txt b/boards/nxp/tropic-community/src/CMakeLists.txt index 6c37994652..f77e6b4a84 100644 --- a/boards/nxp/tropic-community/src/CMakeLists.txt +++ b/boards/nxp/tropic-community/src/CMakeLists.txt @@ -51,6 +51,8 @@ set_source_files_properties(imxrt_ocram_initialize.c PROPERTIES COMPILE_FLAGS -f target_link_libraries(drivers_board PRIVATE + arch_board_romapi + arch_spi nuttx_arch # sdio nuttx_drivers # sdio px4_layer diff --git a/boards/nxp/tropic-community/src/board_config.h b/boards/nxp/tropic-community/src/board_config.h index 83bbd101e2..4d422f9650 100644 --- a/boards/nxp/tropic-community/src/board_config.h +++ b/boards/nxp/tropic-community/src/board_config.h @@ -112,7 +112,6 @@ #define GPIO_DRDY_OFF_SPI4_DRDY7_EXTERNAL1 _PIN_OFF(GPIO_SPI4_DRDY7_EXTERNAL1) - #define ADC_IOMUX (IOMUX_CMOS_INPUT | IOMUX_PULL_NONE | IOMUX_DRIVE_HIZ) #define ADC1_CH(n) (n) @@ -262,6 +261,10 @@ static inline int board_read_usb2_vbus_state(void) } #define BOARD_ENABLE_CONSOLE_BUFFER + +/* Flash instance for storage */ +#define NOR_INSTANCE 0 + __BEGIN_DECLS /**************************************************************************************************** @@ -316,6 +319,8 @@ extern int imxrt1062_spi_bus_initialize(void); * ************************************************************************************/ +extern void imxrt_spiinitialize(void); + extern int imxrt_usb_initialize(void); extern void imxrt_usbinitialize(void); @@ -326,6 +331,8 @@ extern void fmurt1062_timer_initialize(void); #include +void imxrt_flash_romapi_initialize(void); + int imxrt_flexspi_storage_initialize(void); #endif /* __ASSEMBLY__ */ diff --git a/boards/nxp/tropic-community/src/imxrt_flexspi_nor_flash.c b/boards/nxp/tropic-community/src/imxrt_flexspi_nor_flash.c index f7ffe4e46d..39460ffaf9 100644 --- a/boards/nxp/tropic-community/src/imxrt_flexspi_nor_flash.c +++ b/boards/nxp/tropic-community/src/imxrt_flexspi_nor_flash.c @@ -28,55 +28,71 @@ * Public Data ****************************************************************************/ +enum { + /* SPI instructions */ + + READ_FAST = 0, + READ_STATUS_REG = 1, + WRITE_ENABLE = 3, + SECTOR_ERASE_4K = 5, + READ_FAST_QUAD_OUTPUT = 6, + PAGE_PROGRAM_QUAD_INPUT = 7, + ERASE_BLOCK = 8, + PAGE_PROGRAM = 9, + CHIP_ERASE = 11, +}; + locate_data(".boot_hdr.conf") const struct flexspi_nor_config_s g_flash_config = { .mem_config = { - .tag = FLEXSPI_CFG_BLK_TAG, - .version = FLEXSPI_CFG_BLK_VERSION, - .read_sample_clksrc = FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_SCKPAD, - .cs_hold_time = 1u, - .cs_setup_time = 1u, - .column_address_width = 0u, - .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, - .sflash_pad_type = SERIAL_FLASH_4PADS, - .serial_clk_freq = FLEXSPI_SERIAL_CLKFREQ_133MHz, - .sflash_a1size = 8u * 1024u * 1024u, - .data_valid_time = + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .read_sample_clksrc = FLASH_READ_SAMPLE_CLK_LOOPBACK_FROM_SCKPAD, + .cs_hold_time = 1u, + .cs_setup_time = 1u, + .column_address_width = 0u, + .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, + .sflash_pad_type = SERIAL_FLASH_4PADS, + .serial_clk_freq = FLEXSPI_SERIAL_CLKFREQ_133MHz, + .sflash_a1size = 8u * 1024u * 1024u, + .lookup_table = { - 0u, 0u - }, - .lookup_table = - { - /* Fast Read Quad I/O */ - [0 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xeb, - RADDR_SDR, FLEXSPI_4PAD, 0x18), - [0 + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, - READ_SDR, FLEXSPI_4PAD, 0x04), + [4 * READ_FAST] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xeb, + RADDR_SDR, FLEXSPI_4PAD, 0x18), + [4 * READ_FAST + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, + READ_SDR, FLEXSPI_4PAD, 0x04), - /* Read Status Register-1 */ - [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, - READ_SDR, FLEXSPI_1PAD, 0x04), + [4 * READ_STATUS_REG] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, + READ_SDR, FLEXSPI_1PAD, 0x04), - /* Write Status Register-1 */ - [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x0), + [4 * WRITE_ENABLE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, + STOP, FLEXSPI_1PAD, 0), - /* Sector Erase (4KB) */ - [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, - RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * SECTOR_ERASE_4K] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, + RADDR_SDR, FLEXSPI_1PAD, 0x18), - /* Block Erase (64KB) */ - [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xd8, - RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * CHIP_ERASE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, + STOP, FLEXSPI_1PAD, 0), - /* Page Program */ - [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, - RADDR_SDR, FLEXSPI_1PAD, 0x18), - [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, - STOP, FLEXSPI_1PAD, 0x0), + [4 * ERASE_BLOCK] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xd8, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + + [4 * PAGE_PROGRAM] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * PAGE_PROGRAM + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, + STOP, FLEXSPI_1PAD, 0x0), + + [4 * READ_FAST_QUAD_OUTPUT] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6b, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * READ_FAST_QUAD_OUTPUT + 1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, + READ_SDR, FLEXSPI_4PAD, 0x04), + + [4 * PAGE_PROGRAM_QUAD_INPUT] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, + RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * PAGE_PROGRAM_QUAD_INPUT + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, + STOP, FLEXSPI_1PAD, 0), - /* Chip Erase */ - [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0), }, }, diff --git a/boards/nxp/tropic-community/src/imxrt_flexspi_storage.c b/boards/nxp/tropic-community/src/imxrt_flexspi_storage.c index f3ac06804f..605688afa4 100644 --- a/boards/nxp/tropic-community/src/imxrt_flexspi_storage.c +++ b/boards/nxp/tropic-community/src/imxrt_flexspi_storage.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/px4/fmu-v6xrt/src/imxrt_flexspi_storage.c + * boards/nxp/tropic-community/src/imxrt_flexspi_storage.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -36,104 +36,28 @@ #include #include "px4_log.h" -#include "imxrt_flexspi.h" +#include +#include #include "board_config.h" #include "hardware/imxrt_pinmux.h" - -#ifdef CONFIG_IMXRT_FLEXSPI +#include "barriers.h" /* Used sectors must be multiple of the flash block size * i.e. W25Q32JV has a block size of 64KB */ -#define NOR_USED_SECTORS (0x20U) /* 32 * 4KB = 128KB */ +#define NOR_USED_SECTORS (0x40U) /* 64 * 4KB = 256KB */ #define NOR_TOTAL_SECTORS (0x0800U) #define NOR_PAGE_SIZE (0x0100U) /* 256 bytes */ #define NOR_SECTOR_SIZE (0x1000U) /* 4KB */ #define NOR_START_SECTOR (NOR_TOTAL_SECTORS - NOR_USED_SECTORS) #define NOR_START_PAGE ((NOR_START_SECTOR * NOR_SECTOR_SIZE) / NOR_PAGE_SIZE) #define NOR_STORAGE_ADDR (IMXRT_FLEXCIPHER_BASE + NOR_START_SECTOR * NOR_SECTOR_SIZE) +#define NOR_STORAGE_END (IMXRT_FLEXCIPHER_BASE + (NOR_START_SECTOR + NOR_TOTAL_SECTORS) * NOR_SECTOR_SIZE) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -enum { - /* SPI instructions */ - - READ_FAST = 0, - READ_STATUS_REG = 1, - WRITE_STATUS_REG = 3, - WRITE_ENABLE = 4, - SECTOR_ERASE_4K = 5, - READ_FAST_QUAD_OUTPUT = 6, - PAGE_PROGRAM_QUAD_INPUT = 7, - PAGE_PROGRAM = 9, - CHIP_ERASE = 11, -}; - -static const uint32_t g_flexspi_nor_lut[][4] = { - [READ_FAST] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xeb, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_4PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x06, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), - }, - - [READ_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x05, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x01, - FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_ENABLE] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x06, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [SECTOR_ERASE_4K] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x20, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - }, - - [CHIP_ERASE] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xc7, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [PAGE_PROGRAM] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x02, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0x0), - }, - - [READ_FAST_QUAD_OUTPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x6b, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x08, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), - }, - - [PAGE_PROGRAM_QUAD_INPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x32, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_4PAD, 0x04, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - -}; +extern struct flexspi_nor_config_s g_bootConfig; /**************************************************************************** * Private Types @@ -143,10 +67,7 @@ static const uint32_t g_flexspi_nor_lut[][4] = { struct imxrt_flexspi_storage_dev_s { struct mtd_dev_s mtd; - struct flexspi_dev_s *flexspi; /* Saved FlexSPI interface instance */ uint8_t *ahb_base; - enum flexspi_port_e port; - struct flexspi_device_config_s *config; }; /**************************************************************************** @@ -178,26 +99,6 @@ static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, * Private Data ****************************************************************************/ -static struct flexspi_device_config_s g_flexspi_device_config = { - .flexspi_root_clk = 4000000, - .is_sck2_enabled = 0, - .flash_size = NOR_USED_SECTORS * NOR_SECTOR_SIZE / 4, - .cs_interval_unit = FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE, - .cs_interval = 0, - .cs_hold_time = 3, - .cs_setup_time = 3, - .data_valid_time = 0, - .columnspace = 0, - .enable_word_address = 0, - .awr_seq_index = 0, - .awr_seq_number = 0, - .ard_seq_index = READ_FAST, - .ard_seq_number = 1, - .ahb_write_wait_unit = FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE, - .ahb_write_wait_interval = 0, - .rx_sample_clock = FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD, -}; - static struct imxrt_flexspi_storage_dev_s g_flexspi_nor = { .mtd = { @@ -211,90 +112,17 @@ static struct imxrt_flexspi_storage_dev_s g_flexspi_nor = { #endif .name = "imxrt_flexspi_storage" }, - .flexspi = (void *)0, .ahb_base = (uint8_t *) NOR_STORAGE_ADDR, - .port = FLEXSPI_PORT_A1, - .config = &g_flexspi_device_config }; +/* Ensure exclusive access to the driver */ + +static sem_t g_exclsem = SEM_INITIALIZER(1); + /**************************************************************************** * Private Functions ****************************************************************************/ -static int imxrt_flexspi_storage_read_status( - const struct imxrt_flexspi_storage_dev_s *dev, - uint32_t *status) -{ - int stat; - - struct flexspi_transfer_s transfer = { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_READ, - .seq_number = 1, - .seq_index = READ_STATUS_REG, - .data = status, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - - if (stat != 0) { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_storage_write_enable( - const struct imxrt_flexspi_storage_dev_s *dev) -{ - int stat; - - struct flexspi_transfer_s transfer = { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = WRITE_ENABLE, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - - if (stat != 0) { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_storage_erase_sector( - const struct imxrt_flexspi_storage_dev_s *dev, - off_t offset) -{ - int stat; - struct flexspi_transfer_s transfer = { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = SECTOR_ERASE_4K, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - - if (stat != 0) { - return -EIO; - } - - - return 0; -} - static int imxrt_flexspi_storage_erase_chip( const struct imxrt_flexspi_storage_dev_s *dev) { @@ -302,69 +130,38 @@ static int imxrt_flexspi_storage_erase_chip( return -EINVAL; } -static int imxrt_flexspi_storage_page_program( - const struct imxrt_flexspi_storage_dev_s *dev, - off_t offset, - const void *buffer, - size_t len) -{ - int stat; - - struct flexspi_transfer_s transfer = { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_WRITE, - .seq_number = 1, - .seq_index = PAGE_PROGRAM_QUAD_INPUT, - .data = (uint32_t *) buffer, - .data_size = len, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - - if (stat != 0) { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_storage_wait_bus_busy( - const struct imxrt_flexspi_storage_dev_s *dev) -{ - uint32_t status = 0; - int ret; - - do { - ret = imxrt_flexspi_storage_read_status(dev, &status); - - if (ret) { - return ret; - } - } while (status & 1); - - return 0; -} - static ssize_t imxrt_flexspi_storage_read(struct mtd_dev_s *dev, off_t offset, size_t nbytes, uint8_t *buffer) { + ssize_t ret; struct imxrt_flexspi_storage_dev_s *priv = (struct imxrt_flexspi_storage_dev_s *)dev; uint8_t *src; finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); - if (priv->port >= FLEXSPI_PORT_COUNT) { + if (offset < 0) { return -EIO; } src = priv->ahb_base + offset; + if (src + nbytes > (uint8_t *)NOR_STORAGE_END) { + return -EIO; + } + + ret = nxsem_wait(&g_exclsem); + + if (ret < 0) { + return ret; + } + memcpy(buffer, src, nbytes); + nxsem_post(&g_exclsem); + finfo("return nbytes: %d\n", (int)nbytes); return (ssize_t)nbytes; } @@ -392,85 +189,102 @@ static ssize_t imxrt_flexspi_storage_bread(struct mtd_dev_s *dev, return nbytes; } +locate_code(".ramfunc") static ssize_t imxrt_flexspi_storage_bwrite(struct mtd_dev_s *dev, off_t startblock, size_t nblocks, const uint8_t *buffer) { - struct imxrt_flexspi_storage_dev_s *priv = - (struct imxrt_flexspi_storage_dev_s *)dev; + ssize_t ret; + struct flexspi_nor_config_s *pConfig = &g_bootConfig; size_t len = nblocks * NOR_PAGE_SIZE; off_t offset = (startblock + NOR_START_PAGE) * NOR_PAGE_SIZE; uint8_t *src = (uint8_t *) buffer; #ifdef CONFIG_ARMV7M_DCACHE + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE; #endif int i; + if (((uintptr_t)buffer % 4) != 0) { + return -EINVAL; // Byte aligned write not supported + } + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, false); + ret = nxsem_wait(&g_exclsem); - irqstate_t flags = enter_critical_section(); + if (ret < 0) { + return ret; + } while (len) { i = MIN(NOR_PAGE_SIZE, len); - imxrt_flexspi_storage_write_enable(priv); - imxrt_flexspi_storage_page_program(priv, offset, src, i); - imxrt_flexspi_storage_wait_bus_busy(priv); + cpsid(); // Disable interrupts +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + volatile uint32_t status = ROM_FLEXSPI_NorFlash_ProgramPage(NOR_INSTANCE, pConfig, offset, (const uint32_t *)src); +#pragma GCC diagnostic pop + cpsie(); // Enable interrupts + usleep(0); // Yield to scheduler + UNUSED(status); + offset += i; src += i; len -= i; } - FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, true); - - leave_critical_section(flags); - #ifdef CONFIG_ARMV7M_DCACHE up_invalidate_dcache((uintptr_t)dst, (uintptr_t)dst + nblocks * NOR_PAGE_SIZE); #endif + nxsem_post(&g_exclsem); + return nblocks; } +locate_code(".ramfunc") static int imxrt_flexspi_storage_erase(struct mtd_dev_s *dev, off_t startblock, size_t nblocks) { - struct imxrt_flexspi_storage_dev_s *priv = - (struct imxrt_flexspi_storage_dev_s *)dev; + struct flexspi_nor_config_s *pConfig = &g_bootConfig; size_t blocksleft = nblocks; #ifdef CONFIG_ARMV7M_DCACHE + struct imxrt_flexspi_storage_dev_s *priv = + (struct imxrt_flexspi_storage_dev_s *)dev; uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE; #endif + ssize_t ret; startblock += NOR_START_SECTOR; finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, false); + ret = nxsem_wait(&g_exclsem); - irqstate_t flags = enter_critical_section(); + if (ret < 0) { + return ret; + } while (blocksleft-- > 0) { /* Erase each sector */ - - imxrt_flexspi_storage_write_enable(priv); - imxrt_flexspi_storage_erase_sector(priv, startblock * NOR_SECTOR_SIZE); - imxrt_flexspi_storage_wait_bus_busy(priv); + cpsid(); // Disable interrupts + volatile uint32_t status = ROM_FLEXSPI_NorFlash_Erase(NOR_INSTANCE, pConfig, + (startblock * NOR_SECTOR_SIZE), NOR_SECTOR_SIZE); + cpsie(); // Enable interrupts + usleep(0); // Yield to scheduler + UNUSED(status); startblock++; } - FLEXSPI_CONFIGURE_PREFETCH(priv->flexspi, true); - - leave_critical_section(flags); - #ifdef CONFIG_ARMV7M_DCACHE up_invalidate_dcache((uintptr_t)dst, (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE); #endif + nxsem_post(&g_exclsem); return (int)nblocks; } @@ -530,9 +344,7 @@ static int imxrt_flexspi_storage_ioctl(struct mtd_dev_s *dev, case MTDIOC_BULKERASE: { /* Erase the entire device */ - imxrt_flexspi_storage_write_enable(priv); imxrt_flexspi_storage_erase_chip(priv); - imxrt_flexspi_storage_wait_bus_busy(priv); ret = OK; } break; @@ -569,20 +381,6 @@ int imxrt_flexspi_storage_initialize(void) struct mtd_dev_s *mtd_dev = &g_flexspi_nor.mtd; int ret = -ENODEV; - /* Select FlexSPI1 */ - - g_flexspi_nor.flexspi = imxrt_flexspi_initialize(0); - - if (g_flexspi_nor.flexspi) { - ret = OK; - - - FLEXSPI_UPDATE_LUT(g_flexspi_nor.flexspi, - 0, - (const uint32_t *)g_flexspi_nor_lut, - sizeof(g_flexspi_nor_lut) / 4); - } - /* Register the MTD driver so that it can be accessed from the * VFS. */ @@ -611,4 +409,3 @@ int imxrt_flexspi_storage_initialize(void) return ret; } -#endif /* CONFIG_IMXRT_FLEXSPI */ diff --git a/boards/nxp/tropic-community/src/init.c b/boards/nxp/tropic-community/src/init.c index a9c326f39c..f6caf0c816 100644 --- a/boards/nxp/tropic-community/src/init.c +++ b/boards/nxp/tropic-community/src/init.c @@ -64,9 +64,9 @@ #include #include -#include "arm_internal.h" #include "arm_internal.h" #include "imxrt_flexspi_nor_boot.h" +#include #include "imxrt_iomuxc.h" #include "imxrt_flexcan.h" #include "imxrt_enet.h" @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +145,30 @@ __EXPORT void board_on_reset(int status) } } +/**************************************************************************** + * Name: imxrt_flash_romapi_initialize + * + * Description: + * + ****************************************************************************/ +struct flexspi_nor_config_s g_bootConfig; + +locate_code(".ramfunc") +void imxrt_flash_romapi_initialize(void) +{ + memcpy((struct flexspi_nor_config_s *)&g_bootConfig, &g_flash_config, + sizeof(struct flexspi_nor_config_s)); + g_bootConfig.memConfig.tag = FLEXSPI_CFG_BLK_TAG; + + ROM_API_Init(); + + ROM_FLEXSPI_NorFlash_Init(NOR_INSTANCE, (struct flexspi_nor_config_s *)&g_bootConfig); + ROM_FLEXSPI_NorFlash_ClearCache(NOR_INSTANCE); + + ARM_DSB(); + ARM_ISB(); + ARM_DMB(); +} locate_code(".ramfunc") void imxrt_flash_setup_prefetch_partition(void) @@ -207,6 +232,8 @@ __EXPORT void imxrt_boardinitialize(void) { imxrt_flash_setup_prefetch_partition(); + imxrt_flash_romapi_initialize(); + board_on_reset(-1); /* Reset PWM first thing */ /* configure LEDs */ @@ -218,10 +245,6 @@ __EXPORT void imxrt_boardinitialize(void) const uint32_t gpio[] = PX4_GPIO_INIT_LIST; px4_gpio_init(gpio, arraySize(gpio)); - /* configure SPI interfaces */ - - imxrt_spidev_initialize(); - imxrt_usb_initialize(); fmurt1062_timer_initialize(); @@ -330,14 +353,18 @@ void imxrt_flexio_clocking(void) ****************************************************************************/ __EXPORT int board_app_initialize(uintptr_t arg) { + int ret = OK; + +#if !defined(BOOTLOADER) + imxrt_flexio_clocking(); /* Power on Interfaces */ - board_spi_reset(10, 0xffff); - px4_platform_init(); + imxrt_spiinitialize(); + /* configure the DMA allocator */ if (board_dma_alloc_init() < 0) { @@ -350,14 +377,13 @@ __EXPORT int board_app_initialize(uintptr_t arg) hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)imxrt_serial_dma_poll, NULL); #endif - int ret = OK; #if defined(CONFIG_IMXRT_USDHC) ret = fmurt1062_usdhc_initialize(); #endif - /* Configure SPI-based devices */ + imxrt_spiinitialize(); - ret = imxrt1062_spi_bus_initialize(); + board_spi_reset(10, 0xffff); #ifdef CONFIG_IMXRT_ENET imxrt_netinitialize(0); @@ -367,7 +393,6 @@ __EXPORT int board_app_initialize(uintptr_t arg) imxrt_caninitialize(3); #endif -#ifdef CONFIG_IMXRT_FLEXSPI ret = imxrt_flexspi_storage_initialize(); if (ret < 0) { @@ -375,7 +400,7 @@ __EXPORT int board_app_initialize(uintptr_t arg) "ERROR: imxrt_flexspi_nor_initialize failed: %d\n", ret); } -#endif +#endif /* !defined(BOOTLOADER) */ return ret; } diff --git a/boards/nxp/tropic-community/src/spi.cpp b/boards/nxp/tropic-community/src/spi.cpp index b267b18d06..a5e0f847b6 100644 --- a/boards/nxp/tropic-community/src/spi.cpp +++ b/boards/nxp/tropic-community/src/spi.cpp @@ -62,7 +62,6 @@ #if defined(CONFIG_IMXRT_LPSPI3) || defined(CONFIG_IMXRT_LPSPI4) - constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::LPSPI3, { initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::Port1, GPIO::Pin28}), /* GPIO_AD_B1_12 GPIO1_IO28 */ @@ -75,241 +74,4 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { static constexpr bool unused = validateSPIConfig(px4_spi_buses); -#define _PIN_OFF(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT | IOMUX_PULL_DOWN_100K | IOMUX_CMOS_INPUT)) - -/************************************************************************************ - * Public Functions - ************************************************************************************/ -/************************************************************************************ - * Name: fmurt1062_spidev_initialize - * - * Description: - * Called to configure SPI chip select GPIO pins for the NXP FMUKRT1062-V1 board. - * - ************************************************************************************/ - -void imxrt_spidev_initialize(void) -{ - for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { - px4_arch_configgpio(px4_spi_buses[bus].devices[i].cs_gpio); - } - } - } -} - -/************************************************************************************ - * Name: imxrt_spi_bus_initialize - * - * Description: - * Called to configure SPI chip select GPIO pins for the NXP FMUKRT1062-V1 board. - * - ************************************************************************************/ - -static const px4_spi_bus_t *_spi_bus3; -static const px4_spi_bus_t *_spi_bus4; - -__EXPORT int imxrt1062_spi_bus_initialize(void) -{ - for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { - switch (px4_spi_buses[i].bus) { - case 3: _spi_bus3 = &px4_spi_buses[i]; break; - - case 4: _spi_bus4 = &px4_spi_buses[i]; break; - } - } - - /* Configure SPI-based devices */ - - struct spi_dev_s *spi_icm = px4_spibus_initialize(3); - - if (!spi_icm) { - PX4_ERR("[boot] FAILED to initialize SPI port %d\n", 1); - return -ENODEV; - } - - /* Default bus 1 to 8MHz and de-assert the known chip selects. - */ - - SPI_SETFREQUENCY(spi_icm, 8 * 1000 * 1000); - SPI_SETBITS(spi_icm, 8); - SPI_SETMODE(spi_icm, SPIDEV_MODE3); - - /* Get the SPI port for the BMI088 */ - - struct spi_dev_s *spi_bmi = px4_spibus_initialize(4); - - if (!spi_bmi) { - PX4_ERR("[boot] FAILED to initialize SPI port %d\n", 4); - return -ENODEV; - } - - /* Default ext bus to 8MHz and de-assert the known chip selects. - */ - - SPI_SETFREQUENCY(spi_bmi, 8 * 1000 * 1000); - SPI_SETBITS(spi_bmi, 8); - SPI_SETMODE(spi_bmi, SPIDEV_MODE3); - - /* deselect all */ - for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { - SPI_SELECT(spi_bmi, px4_spi_buses[bus].devices[i].devid, false); - } - } - } - - return OK; - -} - -/**************************************************************************** - * Name: imxrt_lpspi1/2/3select and imxrt_lpspi1/2/3status - * - * Description: - * The external functions, imxrt_lpspi1/2/3select and imxrt_lpspi1/2/3status must be - * provided by board-specific logic. They are implementations of the select - * and status methods of the SPI interface defined by struct spi_ops_s (see - * include/nuttx/spi/spi.h). All other methods (including imxrt_lpspibus_initialize()) - * are provided by common STM32 logic. To use this common SPI logic on your - * board: - * - * 1. Provide logic in imxrt_boardinitialize() to configure SPI chip select - * pins. - * 2. Provide imxrt_lpspi1/2/3select() and imxrt_lpspi1/2/3status() functions in your - * board-specific logic. These functions will perform chip selection and - * status operations using GPIOs in the way your board is configured. - * 3. Add a calls to imxrt_lpspibus_initialize() in your low level application - * initialization logic - * 4. The handle returned by imxrt_lpspibus_initialize() may then be used to bind the - * SPI driver to higher level logic (e.g., calling - * mmcsd_spislotinitialize(), for example, will bind the SPI driver to - * the SPI MMC/SD driver). - * - ****************************************************************************/ - -static inline void imxrt_spixselect(const px4_spi_bus_t *bus, struct spi_dev_s *dev, uint32_t devid, bool selected) -{ - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (bus->devices[i].cs_gpio == 0) { - break; - } - - if (devid == bus->devices[i].devid) { - // SPI select is active low, so write !selected to select the device - imxrt_gpio_write(bus->devices[i].cs_gpio, !selected); - } - } -} - -#if defined(CONFIG_IMXRT_LPSPI3) -__EXPORT void imxrt_lpspi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) -{ - imxrt_spixselect(_spi_bus3, dev, devid, selected); -} - -__EXPORT uint8_t imxrt_lpspi3status(FAR struct spi_dev_s *dev, uint32_t devid) -{ - return SPI_STATUS_PRESENT; -} -#endif - -#if defined(CONFIG_IMXRT_LPSPI4) -__EXPORT void imxrt_lpspi4select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) -{ - imxrt_spixselect(_spi_bus4, dev, devid, selected); -} - -__EXPORT uint8_t imxrt_lpspi4status(FAR struct spi_dev_s *dev, uint32_t devid) -{ - return SPI_STATUS_PRESENT; -} -#endif - -/************************************************************************************ - * Name: board_spi_reset - * - * Description: - * - * - ************************************************************************************/ - -__EXPORT void board_spi_reset(int ms, int bus_mask) -{ -#ifdef CONFIG_IMXRT_LPSPI1 - - /* Goal not to back feed the chips on the bus via IO lines */ - for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { - if (px4_spi_buses[bus].bus == 1 || px4_spi_buses[bus].bus == 3) { - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { - imxrt_config_gpio(_PIN_OFF(px4_spi_buses[bus].devices[i].cs_gpio)); - } - - if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) { - imxrt_config_gpio(_PIN_OFF(px4_spi_buses[bus].devices[i].drdy_gpio)); - } - } - } - } - - imxrt_config_gpio(GPIO_SPI1_SCK_OFF); - imxrt_config_gpio(GPIO_SPI1_MISO_OFF); - imxrt_config_gpio(GPIO_SPI1_MOSI_OFF); - - imxrt_config_gpio(GPIO_SPI3_SCK_OFF); - imxrt_config_gpio(GPIO_SPI3_MISO_OFF); - imxrt_config_gpio(GPIO_SPI3_MOSI_OFF); - - - imxrt_config_gpio(_PIN_OFF(GPIO_LPI2C3_SDA_RESET)); - imxrt_config_gpio(_PIN_OFF(GPIO_LPI2C3_SCL_RESET)); - - /* set the sensor rail off */ - imxrt_gpio_write(GPIO_VDD_3V3_SENSORS_EN, 0); - - /* wait for the sensor rail to reach GND */ - usleep(ms * 1000); - warnx("reset done, %d ms", ms); - - /* re-enable power */ - - /* switch the sensor rail back on */ - imxrt_gpio_write(GPIO_VDD_3V3_SENSORS_EN, 1); - - /* wait a bit before starting SPI, different times didn't influence results */ - usleep(100); - - /* reconfigure the SPI pins */ - for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { - if (px4_spi_buses[bus].bus == 1 || px4_spi_buses[bus].bus == 3) { - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { - if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { - imxrt_config_gpio(px4_spi_buses[bus].devices[i].cs_gpio); - } - - if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) { - imxrt_config_gpio(px4_spi_buses[bus].devices[i].drdy_gpio); - } - } - } - } - - imxrt_config_gpio(GPIO_LPSPI1_SCK); - imxrt_config_gpio(GPIO_LPSPI1_MISO); - imxrt_config_gpio(GPIO_LPSPI1_MOSI); - - imxrt_config_gpio(GPIO_LPSPI3_SCK); - imxrt_config_gpio(GPIO_LPSPI3_MISO); - imxrt_config_gpio(GPIO_LPSPI3_MOSI); - - imxrt_config_gpio(GPIO_LPI2C3_SDA); - imxrt_config_gpio(GPIO_LPI2C3_SCL); - -#endif /* CONFIG_IMXRT_LPSPI1 */ - -} - #endif /* CONFIG_IMXRT_LPSPI3 || CONFIG_IMXRT_LPSPI4 */ diff --git a/boards/px4/fmu-v3/default.px4board b/boards/px4/fmu-v3/default.px4board index cb25c33762..051dcd345b 100644 --- a/boards/px4/fmu-v3/default.px4board +++ b/boards/px4/fmu-v3/default.px4board @@ -28,7 +28,6 @@ CONFIG_DRIVERS_IMU_ST_LSM303D=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/px4/fmu-v4/default.px4board b/boards/px4/fmu-v4/default.px4board index c2f3c26b7f..2a5b8547f8 100644 --- a/boards/px4/fmu-v4/default.px4board +++ b/boards/px4/fmu-v4/default.px4board @@ -26,7 +26,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_INPUT=y diff --git a/boards/px4/fmu-v4pro/default.px4board b/boards/px4/fmu-v4pro/default.px4board index bea7aceac8..5ff29fb78a 100644 --- a/boards/px4/fmu-v4pro/default.px4board +++ b/boards/px4/fmu-v4pro/default.px4board @@ -25,7 +25,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/px4/fmu-v5/default.px4board b/boards/px4/fmu-v5/default.px4board index 9a36ff1fe7..b49baa86e2 100644 --- a/boards/px4/fmu-v5/default.px4board +++ b/boards/px4/fmu-v5/default.px4board @@ -27,7 +27,6 @@ CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_DRIVERS_LIGHTS_RGBLED_PWM=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_COMMON_OSD=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y @@ -77,8 +76,6 @@ CONFIG_MODULES_RC_UPDATE=y CONFIG_MODULES_SENSORS=y CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y CONFIG_MODULES_TEMPERATURE_COMPENSATION=y -CONFIG_MODULES_UUV_ATT_CONTROL=y -CONFIG_MODULES_UUV_POS_CONTROL=y CONFIG_MODULES_UXRCE_DDS_CLIENT=y CONFIG_MODULES_VTOL_ATT_CONTROL=y CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y diff --git a/boards/px4/fmu-v5x/default.px4board b/boards/px4/fmu-v5x/default.px4board index d9aa91eae6..b964ccbc90 100644 --- a/boards/px4/fmu-v5x/default.px4board +++ b/boards/px4/fmu-v5x/default.px4board @@ -34,12 +34,11 @@ CONFIG_DRIVERS_IMU_INVENSENSE_IIM42652=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y +CONFIG_DRIVERS_AUTERION_AUTOSTARTER=y CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y @@ -74,7 +73,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 diff --git a/boards/px4/fmu-v5x/init/rc.board_defaults b/boards/px4/fmu-v5x/init/rc.board_defaults index 57f2620cfe..1757657cad 100644 --- a/boards/px4/fmu-v5x/init/rc.board_defaults +++ b/boards/px4/fmu-v5x/init/rc.board_defaults @@ -3,10 +3,6 @@ # board specific defaults #------------------------------------------------------------------------------ -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - if ver hwbasecmp 008 009 00a 010 011 then # Skynode: use the "custom participant", IP=10.41.10.1 config for uxrce_dds_client @@ -33,9 +29,9 @@ safety_button start if ver hwbasecmp 009 then # No USB - mcp23009 start -b 3 -X -D 0xf0 -O 0xf0 -P 0x0f -U 10 + mcp23009 start -b 3 -X -D 0xf0 -O 0xf0 -P 0x0f -M 0 -U 10 fi if ver hwbasecmp 00a 008 then - mcp23009 start -b 3 -X -D 0xf1 -O 0xf0 -P 0x0f -U 10 + mcp23009 start -b 3 -X -D 0xf1 -O 0xf0 -P 0x0f -M 0 -U 10 fi diff --git a/boards/px4/fmu-v5x/init/rc.board_sensors b/boards/px4/fmu-v5x/init/rc.board_sensors index a19bcdb8cc..50e3530df9 100644 --- a/boards/px4/fmu-v5x/init/rc.board_sensors +++ b/boards/px4/fmu-v5x/init/rc.board_sensors @@ -72,8 +72,8 @@ then # Internal magnetometer on I2c bmm150 -I -R 6 start - # Auto start power monitors - pm_selector_auterion start + # Auterion auto starter + auterion_autostarter start # Auterion's INA238 uses a shunt value of 0.0003 instead of 0.0005. param set-default INA238_SHUNT 0.0003 diff --git a/boards/px4/fmu-v5x/src/CMakeLists.txt b/boards/px4/fmu-v5x/src/CMakeLists.txt index 311b7c9be8..d64d950d80 100644 --- a/boards/px4/fmu-v5x/src/CMakeLists.txt +++ b/boards/px4/fmu-v5x/src/CMakeLists.txt @@ -43,8 +43,6 @@ add_library(drivers_board usb.c ) -add_dependencies(drivers_board platform_gpio_mcp23009) - target_link_libraries(drivers_board PRIVATE arch_io_pins @@ -54,5 +52,5 @@ target_link_libraries(drivers_board nuttx_arch # sdio nuttx_drivers # sdio px4_layer - platform_gpio_mcp23009 + platform_gpio_mcp ) diff --git a/boards/px4/fmu-v5x/src/init.cpp b/boards/px4/fmu-v5x/src/init.cpp index b743bf1310..1aacfd6ebd 100644 --- a/boards/px4/fmu-v5x/src/init.cpp +++ b/boards/px4/fmu-v5x/src/init.cpp @@ -74,7 +74,6 @@ #include #include #include -#include /**************************************************************************** * Pre-Processor Definitions @@ -280,12 +279,5 @@ __EXPORT int board_app_initialize(uintptr_t arg) #endif /* CONFIG_MMCSD */ - ret = mcp23009_register_gpios(3, 0x25); - - if (ret != OK) { - led_on(LED_RED); - return ret; - } - return OK; } diff --git a/boards/px4/fmu-v6c/default.px4board b/boards/px4/fmu-v6c/default.px4board index a60c2f65eb..f468fcd4ce 100644 --- a/boards/px4/fmu-v6c/default.px4board +++ b/boards/px4/fmu-v6c/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y diff --git a/boards/px4/fmu-v6c/neural.px4board b/boards/px4/fmu-v6c/neural.px4board index f54d152869..52e47f1644 100644 --- a/boards/px4/fmu-v6c/neural.px4board +++ b/boards/px4/fmu-v6c/neural.px4board @@ -20,10 +20,8 @@ CONFIG_DRIVERS_HEATER=y CONFIG_DRIVERS_IMU_BOSCH_BMI055=y CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y -CONFIG_COMMON_INS=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y diff --git a/boards/px4/fmu-v6c/raptor.px4board b/boards/px4/fmu-v6c/raptor.px4board new file mode 100644 index 0000000000..4a55c90d38 --- /dev/null +++ b/boards/px4/fmu-v6c/raptor.px4board @@ -0,0 +1,94 @@ +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS5" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2 +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_COMMON_LIGHT=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_ACTUATORS_VERTIQ_IO=y +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_MS5611=y +CONFIG_DRIVERS_BATT_SMBUS=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_HEATER=y +CONFIG_DRIVERS_IMU_BOSCH_BMI055=y +CONFIG_DRIVERS_IMU_BOSCH_BMI088=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_LIB_RL_TOOLS=y +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RAPTOR=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000 +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y +CONFIG_USE_IFCI_CONFIGURATION=y diff --git a/boards/px4/fmu-v6u/default.px4board b/boards/px4/fmu-v6u/default.px4board index 7402fbd25e..8a56154345 100644 --- a/boards/px4/fmu-v6u/default.px4board +++ b/boards/px4/fmu-v6u/default.px4board @@ -24,7 +24,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42605=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/px4/fmu-v6x/default.px4board b/boards/px4/fmu-v6x/default.px4board index a6ba8a5b6e..fdbb86dc58 100644 --- a/boards/px4/fmu-v6x/default.px4board +++ b/boards/px4/fmu-v6x/default.px4board @@ -12,23 +12,18 @@ CONFIG_DRIVERS_ADC_ADS1115=y CONFIG_DRIVERS_ADC_BOARD_ADC=y CONFIG_DRIVERS_BAROMETER_BMP388=y CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y -CONFIG_DRIVERS_BAROMETER_MS5611=y -CONFIG_DRIVERS_CAMERA_CAPTURE=n -CONFIG_DRIVERS_CAMERA_TRIGGER=n +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y CONFIG_DRIVERS_CDCACM_AUTOSTART=y CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y -CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_AUAV=y CONFIG_COMMON_DISTANCE_SENSOR=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_GNSS_SEPTENTRIO=y -CONFIG_DRIVERS_GPIO_MCP23009=y 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 @@ -36,14 +31,13 @@ CONFIG_DRIVERS_IMU_INVENSENSE_IIM42652=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y CONFIG_DRIVERS_OSD_MSP_OSD=y -CONFIG_DRIVERS_POWER_MONITOR_INA226=n -CONFIG_DRIVERS_POWER_MONITOR_INA228=n -CONFIG_DRIVERS_POWER_MONITOR_INA238=n -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y -CONFIG_DRIVERS_PWM_INPUT=n -CONFIG_DRIVERS_PWM_OUT=n -CONFIG_DRIVERS_PX4IO=n -CONFIG_COMMON_RC=n +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_INPUT=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_COMMON_RC=y CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_DRIVERS_UAVCAN=y @@ -74,7 +68,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 diff --git a/boards/px4/fmu-v6x/init/rc.board_defaults b/boards/px4/fmu-v6x/init/rc.board_defaults index 2d9a6ea49a..92da057ef2 100644 --- a/boards/px4/fmu-v6x/init/rc.board_defaults +++ b/boards/px4/fmu-v6x/init/rc.board_defaults @@ -3,41 +3,13 @@ # board specific defaults #------------------------------------------------------------------------------ -# By disabling all 3 INA modules, we use the -# i2c_launcher instead. -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - -if ver hwbasecmp 009 010 011 -then - # Skynode: use the "custom participant", IP=10.41.10.1 config for uxrce_dds_client - param set-default UXRCE_DDS_PTCFG 2 - param set-default UXRCE_DDS_AG_IP 170461697 - param set-default UXRCE_DDS_CFG 1000 - - # The buzzer draws too much power (0.2A) on the GPS power rail (limit 0.45A). - param set-default CBRK_BUZZER 782097 -else - # Mavlink ethernet (CFG 1000) - param set-default MAV_2_CONFIG 1000 - param set-default MAV_2_BROADCAST 1 - param set-default MAV_2_MODE 0 - param set-default MAV_2_RADIO_CTL 0 - param set-default MAV_2_RATE 100000 - param set-default MAV_2_REMOTE_PRT 14550 - param set-default MAV_2_UDP_PRT 14550 -fi +# Mavlink ethernet (CFG 1000) +param set-default MAV_2_CONFIG 1000 +param set-default MAV_2_BROADCAST 1 +param set-default MAV_2_MODE 0 +param set-default MAV_2_RADIO_CTL 0 +param set-default MAV_2_RATE 100000 +param set-default MAV_2_REMOTE_PRT 14550 +param set-default MAV_2_UDP_PRT 14550 safety_button start - -# GPIO Expander driver on external I2C3 -if ver hwbasecmp 009 -then - # No USB - mcp23009 start -b 3 -X -D 0xf0 -O 0xf0 -P 0x0f -U 10 -fi -if ver hwbasecmp 00a 008 -then - mcp23009 start -b 3 -X -D 0xf1 -O 0xf0 -P 0x0f -U 10 -fi diff --git a/boards/px4/fmu-v6x/init/rc.board_mavlink b/boards/px4/fmu-v6x/init/rc.board_mavlink deleted file mode 100644 index 713d7a41b7..0000000000 --- a/boards/px4/fmu-v6x/init/rc.board_mavlink +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# -# PX4 FMUv6X specific board MAVLink startup script. -#------------------------------------------------------------------------------ - -# if skynode base board is detected start Mavlink on Telem2 -if ver hwbasecmp 009 010 011 -then - mavlink start -d /dev/ttyS4 -b 3000000 -r 290000 -m onboard_low_bandwidth -x -z - - # Ensure nothing else starts on TEL2 (ttyS4) - set PRT_TEL2_ 1 -fi diff --git a/boards/px4/fmu-v6x/init/rc.board_sensors b/boards/px4/fmu-v6x/init/rc.board_sensors index 100c674108..98f6b0168b 100644 --- a/boards/px4/fmu-v6x/init/rc.board_sensors +++ b/boards/px4/fmu-v6x/init/rc.board_sensors @@ -55,22 +55,13 @@ then set INA_CONFIGURED yes fi -#Start Auterion Power Module selector for Skynode boards -if ver hwbasecmp 009 010 011 +if [ $INA_CONFIGURED = no ] then - pm_selector_auterion start - - # Auterion's INA238 uses a shunt value of 0.0003 instead of 0.0005. - param set-default INA238_SHUNT 0.0003 -else - if [ $INA_CONFIGURED = no ] + # INA226, INA228, INA238 auto-start + i2c_launcher start -b 1 + if [ $HAVE_PM2 = yes ] then - # INA226, INA228, INA238 auto-start - i2c_launcher start -b 1 - if [ $HAVE_PM2 = yes ] - then - i2c_launcher start -b 2 - fi + i2c_launcher start -b 2 fi fi @@ -96,33 +87,22 @@ else icm20649 -s -R 6 start else # Internal SPI BMI088 - if ver hwbasecmp 009 010 011 + if ver hwtypecmp V6X010 then - bmi088 -A -R 6 -s start - bmi088 -G -R 6 -s start + bmi088 -A -R 0 -s start + bmi088 -G -R 0 -s start else - if ver hwtypecmp V6X010 - then - bmi088 -A -R 0 -s start - bmi088 -G -R 0 -s start - else - bmi088 -A -R 4 -s start - bmi088 -G -R 4 -s start - fi + bmi088 -A -R 4 -s start + bmi088 -G -R 4 -s start fi fi # Internal SPI bus ICM42688p - if ver hwbasecmp 009 010 011 + if ver hwtypecmp V6X010 then - icm42688p -R 12 -s start + icm42688p -R 14 -s start else - if ver hwtypecmp V6X010 - then - icm42688p -R 14 -s start - else - icm42688p -R 6 -s start - fi + icm42688p -R 6 -s start fi if ver hwtypecmp V6X003 V6X004 @@ -130,13 +110,8 @@ else # Internal SPI bus ICM-42670-P (hard-mounted) icm42670p -R 10 -s start else - if ver hwbasecmp 009 010 011 - then - icm20602 -R 6 -s start - else - # Internal SPI bus ICM-20649 (hard-mounted) - icm20649 -R 14 -s start - fi + # Internal SPI bus ICM-20649 (hard-mounted) + icm20649 -R 14 -s start fi fi @@ -171,8 +146,5 @@ else bmp388 -X start fi -# Don't try to start external baro on I2C3 as it can conflict with the MS5525DSO airspeed sensor. -#ms5611 -X start - unset INA_CONFIGURED unset HAVE_PM2 diff --git a/boards/px4/fmu-v6x/mavlink-dev.px4board b/boards/px4/fmu-v6x/mavlink-dev.px4board new file mode 100644 index 0000000000..6987a53279 --- /dev/null +++ b/boards/px4/fmu-v6x/mavlink-dev.px4board @@ -0,0 +1,2 @@ +CONFIG_MAVLINK_DIALECT="development" +CONFIG_MODULES_UXRCE_DDS_CLIENT=n diff --git a/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig b/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig index f0a8d6ae86..a99d28ebaa 100644 --- a/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig +++ b/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig @@ -91,7 +91,6 @@ CONFIG_DEBUG_SYMBOLS=y CONFIG_DEBUG_TCBINFO=y CONFIG_DEFAULT_SMALL=y CONFIG_DEV_FIFO_SIZE=0 -CONFIG_DEV_GPIO=y CONFIG_DEV_PIPE_MAXSIZE=1024 CONFIG_DEV_PIPE_SIZE=70 CONFIG_DEV_URANDOM=y @@ -190,6 +189,7 @@ CONFIG_PIPES=y CONFIG_PREALLOC_TIMERS=50 CONFIG_PRIORITY_INHERITANCE=y CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_MUTEX_TYPES=y CONFIG_PTHREAD_STACK_MIN=512 CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 diff --git a/boards/px4/fmu-v6x/spacecraft.px4board b/boards/px4/fmu-v6x/spacecraft.px4board index 968a674740..997a9054a2 100644 --- a/boards/px4/fmu-v6x/spacecraft.px4board +++ b/boards/px4/fmu-v6x/spacecraft.px4board @@ -6,7 +6,8 @@ CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n CONFIG_MODULES_FW_MODE_MANAGER=n CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n CONFIG_MODULES_FW_RATE_CONTROL=n -CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LAND_DETECTOR=n +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=n CONFIG_MODULES_MC_ATT_CONTROL=n CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n diff --git a/boards/px4/fmu-v6x/src/CMakeLists.txt b/boards/px4/fmu-v6x/src/CMakeLists.txt index 39ec808e1e..605cf16ac9 100644 --- a/boards/px4/fmu-v6x/src/CMakeLists.txt +++ b/boards/px4/fmu-v6x/src/CMakeLists.txt @@ -71,6 +71,5 @@ else() nuttx_arch # sdio nuttx_drivers # sdio px4_layer - platform_gpio_mcp23009 ) endif() diff --git a/boards/px4/fmu-v6x/src/board_config.h b/boards/px4/fmu-v6x/src/board_config.h index a57610545c..3259c421d5 100644 --- a/boards/px4/fmu-v6x/src/board_config.h +++ b/boards/px4/fmu-v6x/src/board_config.h @@ -270,11 +270,6 @@ #define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2) #define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13) -/* MCP23009 GPIO expander */ -#define BOARD_GPIO_VDD_5V_COMP_VALID "/dev/gpio4" -#define BOARD_GPIO_VDD_5V_CAN1_GPS1_VALID "/dev/gpio5" - - /* Spare GPIO */ #define GPIO_PG6 /* PG6 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN6) diff --git a/boards/px4/fmu-v6x/src/init.cpp b/boards/px4/fmu-v6x/src/init.cpp index d914b75497..5d2a614206 100644 --- a/boards/px4/fmu-v6x/src/init.cpp +++ b/boards/px4/fmu-v6x/src/init.cpp @@ -74,7 +74,6 @@ #include #include #include -#include /**************************************************************************** * Pre-Processor Definitions @@ -286,13 +285,6 @@ __EXPORT int board_app_initialize(uintptr_t arg) # endif /* CONFIG_MMCSD */ - ret = mcp23009_register_gpios(3, 0x25); - - if (ret != OK) { - led_on(LED_RED); - return ret; - } - #endif /* !defined(BOOTLOADER) */ return OK; diff --git a/boards/px4/fmu-v6x/src/spi.cpp b/boards/px4/fmu-v6x/src/spi.cpp index 8c633dd78f..eb85a8b7a9 100644 --- a/boards/px4/fmu-v6x/src/spi.cpp +++ b/boards/px4/fmu-v6x/src/spi.cpp @@ -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}), diff --git a/boards/px4/fmu-v6x/uuv.px4board b/boards/px4/fmu-v6x/uuv.px4board index 6caf8e8514..3a7b00f13d 100644 --- a/boards/px4/fmu-v6x/uuv.px4board +++ b/boards/px4/fmu-v6x/uuv.px4board @@ -6,7 +6,8 @@ CONFIG_MODULES_FW_POS_CONTROL=n CONFIG_MODULES_FW_RATE_CONTROL=n CONFIG_MODULES_FW_MODE_MANAGER=n CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n -CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LAND_DETECTOR=n +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=n CONFIG_MODULES_MC_ATT_CONTROL=n CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n diff --git a/boards/px4/fmu-v6x/zenoh.px4board b/boards/px4/fmu-v6x/zenoh.px4board index cb14fde935..4cd6071e6d 100644 --- a/boards/px4/fmu-v6x/zenoh.px4board +++ b/boards/px4/fmu-v6x/zenoh.px4board @@ -1,4 +1,5 @@ # CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE is not set CONFIG_DRIVERS_UAVCAN=n CONFIG_MODULES_UXRCE_DDS_CLIENT=n +CONFIG_BOARD_CONSTRAINED_FLASH=y CONFIG_MODULES_ZENOH=y diff --git a/boards/px4/fmu-v6xrt/default.px4board b/boards/px4/fmu-v6xrt/default.px4board index 84e76cd888..2f9d8479b3 100644 --- a/boards/px4/fmu-v6xrt/default.px4board +++ b/boards/px4/fmu-v6xrt/default.px4board @@ -19,6 +19,7 @@ CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_AUAV=y CONFIG_COMMON_DISTANCE_SENSOR=y CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_SF45_SERIAL=y +CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_GRF_SERIAL=y CONFIG_DRIVERS_DSHOT=y CONFIG_DRIVERS_GNSS_SEPTENTRIO=y CONFIG_DRIVERS_GPS=y @@ -40,7 +41,6 @@ CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_COMMON_RC=y @@ -48,6 +48,7 @@ CONFIG_DRIVERS_SAFETY_BUTTON=y CONFIG_COMMON_TELEMETRY=y CONFIG_DRIVERS_TONE_ALARM=y CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_INTERFACES=3 CONFIG_COMMON_UWB=y CONFIG_MODULES_AIRSPEED_SELECTOR=y CONFIG_MODULES_BATTERY_STATUS=y diff --git a/boards/px4/fmu-v6xrt/extras/px4_fmu-v6xrt_bootloader.bin b/boards/px4/fmu-v6xrt/extras/px4_fmu-v6xrt_bootloader.bin index 42e7c4b9d0..5a0bc80093 100755 Binary files a/boards/px4/fmu-v6xrt/extras/px4_fmu-v6xrt_bootloader.bin and b/boards/px4/fmu-v6xrt/extras/px4_fmu-v6xrt_bootloader.bin differ diff --git a/boards/px4/fmu-v6xrt/init/rc.board_defaults b/boards/px4/fmu-v6xrt/init/rc.board_defaults index a5a3dc1016..81ebca27ae 100644 --- a/boards/px4/fmu-v6xrt/init/rc.board_defaults +++ b/boards/px4/fmu-v6xrt/init/rc.board_defaults @@ -12,12 +12,6 @@ param set-default MAV_2_RATE 100000 param set-default MAV_2_REMOTE_PRT 14550 param set-default MAV_2_UDP_PRT 14550 -# By disabling all 3 INA modules, we use the -# i2c_launcher instead. -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - safety_button start if param greater -s UAVCAN_ENABLE 0 diff --git a/boards/px4/fmu-v6xrt/init/rc.board_sensors b/boards/px4/fmu-v6xrt/init/rc.board_sensors index ae60e13536..99248dde72 100644 --- a/boards/px4/fmu-v6xrt/init/rc.board_sensors +++ b/boards/px4/fmu-v6xrt/init/rc.board_sensors @@ -69,19 +69,13 @@ then set INA_CONFIGURED yes fi -#Start Auterion Power Module selector for Skynode boards -if ver hwbasecmp 009 010 +if [ $INA_CONFIGURED = no ] then - pm_selector_auterion start -else - if [ $INA_CONFIGURED = no ] + # INA226, INA228, INA238 auto-start + i2c_launcher start -b 1 + if [ $HAVE_PM2 = yes ] then - # INA226, INA228, INA238 auto-start - i2c_launcher start -b 1 - if [ $HAVE_PM2 = yes ] - then - i2c_launcher start -b 2 - fi + i2c_launcher start -b 2 fi fi diff --git a/boards/px4/fmu-v6xrt/nuttx-config/nsh/defconfig b/boards/px4/fmu-v6xrt/nuttx-config/nsh/defconfig index 0ab458bed6..32c89ba577 100644 --- a/boards/px4/fmu-v6xrt/nuttx-config/nsh/defconfig +++ b/boards/px4/fmu-v6xrt/nuttx-config/nsh/defconfig @@ -54,6 +54,7 @@ CONFIG_DEBUG_MEMFAULT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEBUG_TCBINFO=y CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_GPIO=y CONFIG_DEV_PIPE_SIZE=70 CONFIG_DEV_URANDOM=y CONFIG_ETH0_PHY_MULTI=y @@ -78,7 +79,8 @@ CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y CONFIG_I2C_RESET=y CONFIG_IDLETHREAD_STACKSIZE=2048 -CONFIG_IMXRT_DTCM=0 +CONFIG_IMXRT_DTCM=256 +CONFIG_IMXRT_DTCM_HEAP=y CONFIG_IMXRT_EDMA=y CONFIG_IMXRT_EDMA_EDBG=y CONFIG_IMXRT_EDMA_ELINK=y @@ -104,7 +106,7 @@ CONFIG_IMXRT_GPIO6_0_15_IRQ=y CONFIG_IMXRT_GPIO6_16_31_IRQ=y CONFIG_IMXRT_GPIO_IRQ=y CONFIG_IMXRT_INIT_FLEXRAM=y -CONFIG_IMXRT_ITCM=0 +CONFIG_IMXRT_ITCM=256 CONFIG_IMXRT_LPI2C1=y CONFIG_IMXRT_LPI2C2=y CONFIG_IMXRT_LPI2C3=y @@ -190,6 +192,7 @@ CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MM_REGIONS=2 CONFIG_MTD=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/px4/fmu-v6xrt/nuttx-config/scripts/itcm_functions_includes.ld b/boards/px4/fmu-v6xrt/nuttx-config/scripts/itcm_functions_includes.ld index a52a3b46b0..4d676a6998 100644 --- a/boards/px4/fmu-v6xrt/nuttx-config/scripts/itcm_functions_includes.ld +++ b/boards/px4/fmu-v6xrt/nuttx-config/scripts/itcm_functions_includes.ld @@ -1,4 +1,3 @@ -/* Auto-generated */ *(.text._ZN4uORB7Manager27orb_add_internal_subscriberE6ORB_IDhPj) *(.text._ZN13MavlinkStream6updateERKy) *(.text._ZN7Mavlink16update_rate_multEv) @@ -402,7 +401,7 @@ *(.text._ZN4EKF215PublishBaroBiasERKy) *(.text._ZN4EKF221UpdateGyroCalibrationERKy) *(.text._ZN6matrix9constrainIfLj3ELj1EEENS_6MatrixIT_XT0_EXT1_EEERKS3_S2_S2_) -*(.text._ZN4uORB22SubscriptionMultiArrayI16battery_status_sLh4EE16advertised_countEv) +*(.text._ZN4uORB22SubscriptionMultiArrayI16battery_status_sLh3EE16advertised_countEv) *(.text._ZN23MavlinkStreamScaledIMU34sendEv) *(.text.__aeabi_ldivmod) *(.text._ZN15PositionControl16setInputSetpointERK21trajectory_setpoint_s) diff --git a/boards/px4/fmu-v6xrt/nuttx-config/scripts/script.ld b/boards/px4/fmu-v6xrt/nuttx-config/scripts/script.ld index 70d861f30a..f9eb6915d0 100644 --- a/boards/px4/fmu-v6xrt/nuttx-config/scripts/script.ld +++ b/boards/px4/fmu-v6xrt/nuttx-config/scripts/script.ld @@ -35,7 +35,7 @@ MEMORY { flash (rx) : ORIGIN = 0x30020000, LENGTH = 4M-128K /* We have 64M but we do not want to wait to program it all */ - sram (rwx) : ORIGIN = 0x20240000, LENGTH = 2M-256k-512k + sram (rwx) : ORIGIN = 0x20240000, LENGTH = 2M-256k itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 256K /* TODO FlexRAM partition */ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K } @@ -83,6 +83,7 @@ SECTIONS _sitcmfuncs = ABSOLUTE(.); FILL(0xFF) . = 0x40 ; + *(.ram_vectors) INCLUDE "itcm_static_functions.ld" INCLUDE "itcm_functions_includes.ld" . = ALIGN(8); @@ -91,12 +92,6 @@ SECTIONS _fitcmfuncs = LOADADDR(.itcmfunc); - /* The RAM vector table (if present) should lie at the beginning of SRAM */ - - .ram_vectors (COPY) : { - *(.ram_vectors) - } > dtcm - .text : ALIGN(4) { _stext = ABSOLUTE(.); diff --git a/boards/px4/fmu-v6xrt/src/led.c b/boards/px4/fmu-v6xrt/src/led.c index 45aae15827..3b8439f274 100644 --- a/boards/px4/fmu-v6xrt/src/led.c +++ b/boards/px4/fmu-v6xrt/src/led.c @@ -92,7 +92,7 @@ static bool phy_get_led(int led) { if (g_ledmap[led] != 0) { - return imxrt_gpio_read(!g_ledmap[led]); + return !imxrt_gpio_read(g_ledmap[led]); } return false; diff --git a/boards/px4/sitl/default.px4board b/boards/px4/sitl/default.px4board index ebe4f4ca5b..e2a3996ca3 100644 --- a/boards/px4/sitl/default.px4board +++ b/boards/px4/sitl/default.px4board @@ -35,7 +35,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 diff --git a/boards/px4/sitl/mavlink-dev.px4board b/boards/px4/sitl/mavlink-dev.px4board new file mode 100644 index 0000000000..83cac6e17b --- /dev/null +++ b/boards/px4/sitl/mavlink-dev.px4board @@ -0,0 +1 @@ +CONFIG_MAVLINK_DIALECT="development" diff --git a/boards/px4/sitl/neural.px4board b/boards/px4/sitl/neural.px4board index c94a8fc12a..c68649e18a 100644 --- a/boards/px4/sitl/neural.px4board +++ b/boards/px4/sitl/neural.px4board @@ -34,7 +34,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 diff --git a/boards/px4/sitl/raptor.px4board b/boards/px4/sitl/raptor.px4board new file mode 100644 index 0000000000..b00735efc2 --- /dev/null +++ b/boards/px4/sitl/raptor.px4board @@ -0,0 +1,89 @@ +CONFIG_BOARD_ETHERNET=y +CONFIG_BOARD_ROOT_PATH="." +CONFIG_BOARD_TESTING=y +CONFIG_COMMON_SIMULATION=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_EKF2_VERBOSE_STATUS=y +CONFIG_EXAMPLES_DYN_HELLO=y +CONFIG_EXAMPLES_FAKE_GPS=y +CONFIG_EXAMPLES_FAKE_IMU=y +CONFIG_EXAMPLES_FAKE_MAGNETOMETER=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_PX4_MAVLINK_DEBUG=y +CONFIG_EXAMPLES_PX4_SIMPLE_APP=y +CONFIG_EXAMPLES_WORK_ITEM=y +CONFIG_FIGURE_OF_EIGHT=y +CONFIG_LIB_RL_TOOLS=y +CONFIG_MAVLINK_DIALECT="development" +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y +CONFIG_MODULES_AIRSHIP_ATT_CONTROL=y +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RAPTOR=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_PAYLOAD_DELIVERER=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_REPLAY=y +CONFIG_MODULES_ROVER_ACKERMANN=y +CONFIG_MODULES_ROVER_DIFFERENTIAL=y +CONFIG_MODULES_ROVER_MECANUM=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_SIMULATION_GZ_BRIDGE=y +CONFIG_MODULES_SIMULATION_GZ_MSGS=y +CONFIG_MODULES_SIMULATION_GZ_PLUGINS=y +CONFIG_MODULES_SIMULATION_SENSOR_AGP_SIM=y +CONFIG_MODULES_SPACECRAFT=n +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UUV_ATT_CONTROL=y +CONFIG_MODULES_UUV_POS_CONTROL=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_NUM_MISSION_ITMES_SUPPORTED=10000 +CONFIG_PLATFORM_POSIX=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DYN=y +CONFIG_SYSTEMCMDS_FAILURE=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SHUTDOWN=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/radiolink/PIX6/default.px4board b/boards/radiolink/PIX6/default.px4board new file mode 100644 index 0000000000..ce993b4a59 --- /dev/null +++ b/boards/radiolink/PIX6/default.px4board @@ -0,0 +1,106 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" +CONFIG_DRIVERS_ADC_ADS1115=y +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_GOERTEK_SPA06=y +CONFIG_DRIVERS_BAROMETER_MS5611=y +CONFIG_DRIVERS_BATT_SMBUS=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_BOSCH_BMI088=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y +CONFIG_DRIVERS_IMU_INVENSENSE_MPU6500=y +CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y +CONFIG_DRIVERS_IRLOCK=y +CONFIG_COMMON_LIGHT=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_COMMON_OSD=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_INPUT=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_RC_INPUT=y +CONFIG_DRIVERS_SMART_BATTERY_BATMON=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=6 +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_POS_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y +CONFIG_MODULES_PAYLOAD_DELIVERER=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_ROVER_POS_CONTROL=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UUV_ATT_CONTROL=y +CONFIG_MODULES_UUV_POS_CONTROL=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BL_UPDATE=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_DUMPFILE=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_REFLECT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/radiolink/PIX6/extras/px4_io-v2_default.bin b/boards/radiolink/PIX6/extras/px4_io-v2_default.bin new file mode 100755 index 0000000000..145089ae0d Binary files /dev/null and b/boards/radiolink/PIX6/extras/px4_io-v2_default.bin differ diff --git a/boards/radiolink/PIX6/firmware.prototype b/boards/radiolink/PIX6/firmware.prototype new file mode 100644 index 0000000000..28c9d11fb5 --- /dev/null +++ b/boards/radiolink/PIX6/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 1410, + "magic": "PX4FWv1", + "description": "Firmware for the RadiolinkPIX6 board", + "image": "", + "build_time": 0, + "summary": "RadiolinkPIX6", + "version": "0.1", + "image_size": 0, + "image_maxsize": 2064384, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/radiolink/PIX6/init/rc.board_defaults b/boards/radiolink/PIX6/init/rc.board_defaults new file mode 100644 index 0000000000..6e48130e10 --- /dev/null +++ b/boards/radiolink/PIX6/init/rc.board_defaults @@ -0,0 +1,14 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +param set-default BAT1_V_DIV 18.1 +param set-default BAT2_V_DIV 18.1 + +param set-default BAT1_A_PER_V 36.367515152 +param set-default BAT2_A_PER_V 36.367515152 + +param set-default EKF2_MULTI_IMU 2 +param set-default SENS_IMU_MODE 0 +#safety_button start diff --git a/boards/radiolink/PIX6/init/rc.board_extras b/boards/radiolink/PIX6/init/rc.board_extras new file mode 100644 index 0000000000..a6dadf5699 --- /dev/null +++ b/boards/radiolink/PIX6/init/rc.board_extras @@ -0,0 +1,9 @@ +#!/bin/sh +# +# board extras init +#------------------------------------------------------------------------------ + +if ! param compare OSD_ATXXXX_CFG 0 +then + atxxxx start -s +fi diff --git a/boards/radiolink/PIX6/init/rc.board_sensors b/boards/radiolink/PIX6/init/rc.board_sensors new file mode 100644 index 0000000000..abd52fe183 --- /dev/null +++ b/boards/radiolink/PIX6/init/rc.board_sensors @@ -0,0 +1,53 @@ +#!/bin/sh +# +# board sensors init +#------------------------------------------------------------------------------ + +set HAVE_PM2 yes + +board_adc start + +if param compare SENS_EN_INA226 1 +then + if [ $HAVE_PM2 = yes ] + then + ina226 -X -b 2 -t 2 -k start + fi + +fi + +if param compare SENS_EN_INA228 1 +then + if [ $HAVE_PM2 = yes ] + then + ina228 -X -b 2 -t 2 -k start + fi + +fi + +if param compare SENS_EN_INA238 1 +then + if [ $HAVE_PM2 = yes ] + then + ina238 -X -b 2 -t 2 -k start + fi + +fi + +# Internal SPI bus ICM42688p +icm42688p -R 2 -s start + +# Internal SPI BMI088 +bmi088 -A -R 4 -s start +bmi088 -G -R 4 -s start + +spa06 -I start + +# internal compass +ist8310 -I start + +# External compass on GPS1/I2C1 +ist8310 -X start + +# Possible internal Baro +unset HAVE_PM2 diff --git a/boards/radiolink/PIX6/nuttx-config/Kconfig b/boards/radiolink/PIX6/nuttx-config/Kconfig new file mode 100644 index 0000000000..520c5abadb --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# +config BOARD_HAS_PROBES + bool "Board provides GPIO or other Hardware for signaling to timing analyze." + default y + ---help--- + This board provides GPIO FMU-CH1-8, CAP1 as PROBE_1-9 to provide timing signals from selected drivers. + +config BOARD_USE_PROBES + bool "Enable the use the board provided FMU-CH1-8, CAP1 as PROBE_1-9" + default n + depends on BOARD_HAS_PROBES + + ---help--- + Select to use GPIO FMU-CH1-8, CAP1 to provide timing signals from selected drivers. diff --git a/boards/radiolink/PIX6/nuttx-config/include/board.h b/boards/radiolink/PIX6/nuttx-config/include/board.h new file mode 100644 index 0000000000..186af298dd --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/include/board.h @@ -0,0 +1,455 @@ +/************************************************************************************ + * + * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved. + * Authors: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * +/************************************************************************************ + * Included Files + ************************************************************************************/ +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The radiolink_pix6 board provides the following clock sources: + * + * 24 MHz crystal for HSE + * + * So we have these clock source available within the STM32 + * + * HSI: 16 MHz RC factory-trimmed + * HSE: 24 MHz crystal for HSE + */ +#define STM32_BOARD_XTAL 24000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 24,000,000 + * + * PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * Subject to: + * + * 2 <= PLLM <= 63 + * 192 <= PLLN <= 432 + * 192 MHz <= PLL_VCO <= 432MHz + * + * SYSCLK = PLL_VCO / PLLP + * Subject to + * + * PLLP = {2, 4, 6, 8} + * SYSCLK <= 216 MHz + * + * USB OTG FS, SDMMC and RNG Clock = PLL_VCO / PLLQ + * Subject to + * The USB OTG FS requires a 48 MHz clock to work correctly. The SDMMC + * and the random number generator need a frequency lower than or equal + * to 48 MHz to work correctly. + * + * 2 <= PLLQ <= 15 + */ + +/* Highest SYSCLK with USB OTG FS clock = 48 MHz + * + * PLL_VCO = (24,000,000 / 24) * 432 = 432 MHz + * SYSCLK = 432 MHz / 2 = 216 MHz + * USB OTG FS, SDMMC and RNG Clock = 432 MHz / 9 = 48 MHz + */ + +#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(24) +#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(432) +#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2 +#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(9) + +#define STM32_VCO_FREQUENCY ((STM32_HSE_FREQUENCY / 24) * 432) +#define STM32_SYSCLK_FREQUENCY (STM32_VCO_FREQUENCY / 2) +#define STM32_OTGFS_FREQUENCY (STM32_VCO_FREQUENCY / 9) + +/* Configure factors for PLLSAI clock */ +#define CONFIG_STM32F7_PLLSAI 1 +#define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(192) +#define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(8) +#define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(4) +#define STM32_RCC_PLLSAICFGR_PLLSAIR RCC_PLLSAICFGR_PLLSAIR(2) + +/* Configure Dedicated Clock Configuration Register */ +#define STM32_RCC_DCKCFGR1_PLLI2SDIVQ RCC_DCKCFGR1_PLLI2SDIVQ(1) +#define STM32_RCC_DCKCFGR1_PLLSAIDIVQ RCC_DCKCFGR1_PLLSAIDIVQ(1) +#define STM32_RCC_DCKCFGR1_PLLSAIDIVR RCC_DCKCFGR1_PLLSAIDIVR(0) +#define STM32_RCC_DCKCFGR1_SAI1SRC RCC_DCKCFGR1_SAI1SEL(0) +#define STM32_RCC_DCKCFGR1_SAI2SRC RCC_DCKCFGR1_SAI2SEL(0) +#define STM32_RCC_DCKCFGR1_TIMPRESRC 0 +#define STM32_RCC_DCKCFGR1_DFSDM1SRC 0 +#define STM32_RCC_DCKCFGR1_ADFSDM1SRC 0 + +/* Configure factors for PLLI2S clock */ +#define CONFIG_STM32F7_PLLI2S 1 +#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) +#define STM32_RCC_PLLI2SCFGR_PLLI2SP RCC_PLLI2SCFGR_PLLI2SP(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) +#define STM32_RCC_PLLI2SCFGR_PLLI2SR RCC_PLLI2SCFGR_PLLI2SR(2) + +/* Configure Dedicated Clock Configuration Register 2 */ +#define STM32_RCC_DCKCFGR2_USART1SRC RCC_DCKCFGR2_USART1SEL_APB +#define STM32_RCC_DCKCFGR2_USART2SRC RCC_DCKCFGR2_USART2SEL_APB +#define STM32_RCC_DCKCFGR2_UART4SRC RCC_DCKCFGR2_UART4SEL_APB +#define STM32_RCC_DCKCFGR2_UART5SRC RCC_DCKCFGR2_UART5SEL_APB +#define STM32_RCC_DCKCFGR2_USART6SRC RCC_DCKCFGR2_USART6SEL_APB +#define STM32_RCC_DCKCFGR2_UART7SRC RCC_DCKCFGR2_UART7SEL_APB +#define STM32_RCC_DCKCFGR2_UART8SRC RCC_DCKCFGR2_UART8SEL_APB +#define STM32_RCC_DCKCFGR2_I2C1SRC RCC_DCKCFGR2_I2C1SEL_HSI +#define STM32_RCC_DCKCFGR2_I2C2SRC RCC_DCKCFGR2_I2C2SEL_HSI +#define STM32_RCC_DCKCFGR2_I2C3SRC RCC_DCKCFGR2_I2C3SEL_HSI +#define STM32_RCC_DCKCFGR2_I2C4SRC RCC_DCKCFGR2_I2C4SEL_HSI +#define STM32_RCC_DCKCFGR2_LPTIM1SRC RCC_DCKCFGR2_LPTIM1SEL_APB +#define STM32_RCC_DCKCFGR2_CECSRC RCC_DCKCFGR2_CECSEL_HSI +#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLL +#define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ +#define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ +#define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_PHY + + + +/* Several prescalers allow the configuration of the two AHB buses, the + * high-speed APB (APB2) and the low-speed APB (APB1) domains. The maximum + * frequency of the two AHB buses is 216 MHz while the maximum frequency of + * the high-speed APB domains is 108 MHz. The maximum allowed frequency of + * the low-speed APB domain is 54 MHz. + */ + +/* AHB clock (HCLK) is SYSCLK (216 MHz) */ + +#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ +#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/4 (54 MHz) */ + +#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4) + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* APB2 clock (PCLK2) is HCLK/2 (108MHz) */ + +#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* SDMMC dividers. Note that slower clocking is required when DMA is disabled + * in order to avoid RX overrun/TX underrun errors due to delayed responses + * to service FIFOs in interrupt driven mode. These values have not been + * tuned!!! + * + * SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(118+2)=400 KHz + */ + +/* Use the Falling edge of the SDIO_CLK clock to change the edge the + * data and commands are change on + */ + +#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE + +#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* DMA ON: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(1+2)=16 MHz + * DMA OFF: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(2+2)=12 MHz + */ + +#ifdef CONFIG_STM32F7_SDMMC_DMA +# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +/* DMA ON: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(1+2)=16 MHz + * DMA OFF: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(2+2)=12 MHz + */ +//TODO #warning "Check Freq for 24mHz" + +#ifdef CONFIG_STM32F7_SDMMC_DMA +# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +/* FLASH wait states + * + * --------- ---------- ----------- + * VDD MAX SYSCLK WAIT STATES + * --------- ---------- ----------- + * 1.7-2.1 V 180 MHz 8 + * 2.1-2.4 V 216 MHz 9 + * 2.4-2.7 V 216 MHz 8 + * 2.7-3.6 V 216 MHz 7 + * --------- ---------- ----------- + */ + +#define BOARD_FLASH_WAITSTATES 7 + +/* LED definitions ******************************************************************/ +/* The radiolink_pix6 board has numerous LEDs but only three, LED_GREEN a Green LED, LED_BLUE + * a Blue LED and LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Alternate function pin selections ************************************************/ + +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PB7 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PB6 */ + +#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ +#define GPIO_USART2_RTS GPIO_USART2_RTS_2 /* PD4 */ +#define GPIO_USART2_CTS GPIO_USART2_CTS_2 /* PD3 */ + +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ +#define GPIO_USART3_RTS GPIO_USART3_RTS_2 /* PD12 */ +#define GPIO_USART3_CTS GPIO_USART3_CTS_2 /* PD11 */ + +#define GPIO_UART4_RX GPIO_UART4_RX_1 /* PA1 */ +#define GPIO_UART4_TX GPIO_UART4_TX_1 /* PA0 */ + +#define GPIO_UART7_RX GPIO_UART7_RX_1 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_1 /* PE8 */ + +/* UART8: has no remap + * + * GPIO_UART8_RX PE0 + * GPIO_UART8_TX PE1 + */ + + +/* CAN + * + * CAN1 is routed to transceiver. + * CAN2 is routed to transceiver. + */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_3 /* PD0 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_3 /* PD1 */ +#define GPIO_CAN2_RX GPIO_CAN2_RX_2 /* PB13 */ +#define GPIO_CAN2_TX GPIO_CAN2_TX_1 /* PB5 */ + +/* SPI + * SPI1 is sensors + * SPI2 is OSD & RAMTRON + * SPI4 is EXTERNAL1 + * + */ + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_3 /* PD7 */ +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_2 /* PB3 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1 /* PB15 */ +#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1 /* PA9 */ + +#define GPIO_SPI4_MISO GPIO_SPI4_MISO_2 /* PE13 */ +#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_1 /* PE6 */ +#define GPIO_SPI4_SCK GPIO_SPI4_SCK_1 /* PE2 */ + +/* I2C + * + * The optional _GPIO configurations allow the I2C driver to manually + * reset the bus to clear stuck slaves. They match the pin configuration, + * but are normally-high GPIOs. + * + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* PB8 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* PB9 */ + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1 /* PB10 */ +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_1 /* PB11 */ + + +/* SDMMC1 + * + * VDD 3.3 + * GND + * SDMMC1_CK PC12 + * SDMMC1_CMD PD2 + * SDMMC1_D0 PC8 + * SDMMC1_D1 PC9 + * SDMMC1_D2 PC10 + * SDMMC1_D3 PC11 + */ + +// #define GPIO_SDMMC1_D0 GPIO_SDMMC1_D0 +// #define GPIO_SDMMC1_D1 GPIO_SDMMC1_D1 +// #define GPIO_SDMMC1_D2 GPIO_SDMMC1_D2 +// #define GPIO_SDMMC1_D3 GPIO_SDMMC1_D3 + +/* The STM32 F7 connects to a TI DP83848TSQ/NOPB + * using RMII + * + * STM32 F7 BOARD DP83848TSQ/NOPB + * GPIO SIGNAL PIN NAME + * -------- ------------ ------------- + * PA7 ETH_CRS_DV CRS_DV + * PC1 ETH_MDC MDC + * PA2 ETH_MDIO MDIO + * PA1 ETH_REF_CL X1 + * PC4 ETH_RXD0 RX_D0 + * PC5 ETH_RXD1 RX_D1 + * PB11 ETH_TX_EN TX_EN + * PG13 ETH_TXD0 TX_D0 + * PB13 ETH_TXD1 TX_D1 + * + * The PHY address is 1, since COL/PHYAD0 features a pull up. + */ + +// #define GPIO_ETH_RMII_TX_EN GPIO_ETH_RMII_TX_EN_1 +// #define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2 +// #define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_1 + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PA9 + */ + + +/* Board provides GPIO or other Hardware for signaling to timing analyzer */ + +#if defined(CONFIG_BOARD_USE_PROBES) +# include "stm32_gpio.h" +# define PROBE_N(n) (1<<((n)-1)) +# define PROBE_1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN14) /* PE14 AUX1 */ +# define PROBE_2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN10) /* PA10 AUX2 */ +# define PROBE_3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN11) /* PE11 AUX3 */ +# define PROBE_4 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN9) /* PE9 AUX4 */ +# define PROBE_5 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15) /* PA15 AUX5 */ +# define PROBE_6 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7) /* PA7 AUX6 */ +# define PROBE_7 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN6) /* PC6 AUX7 */ +# define PROBE_8 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN3) /* PA3 AUX8 */ +# //define PROBE_9 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTI|GPIO_PIN0) /* PI0 CAP1 */ + +# define PROBE_INIT(mask) \ + do { \ + if ((mask)& PROBE_N(1)) { stm32_configgpio(PROBE_1); } \ + if ((mask)& PROBE_N(2)) { stm32_configgpio(PROBE_2); } \ + if ((mask)& PROBE_N(3)) { stm32_configgpio(PROBE_3); } \ + if ((mask)& PROBE_N(4)) { stm32_configgpio(PROBE_4); } \ + if ((mask)& PROBE_N(5)) { stm32_configgpio(PROBE_5); } \ + if ((mask)& PROBE_N(6)) { stm32_configgpio(PROBE_6); } \ + if ((mask)& PROBE_N(7)) { stm32_configgpio(PROBE_7); } \ + if ((mask)& PROBE_N(8)) { stm32_configgpio(PROBE_8); } \ + /*if ((mask)& PROBE_N(9)) { stm32_configgpio(PROBE_9); } \*/ + +} while (0) + +# define PROBE(n,s) do {stm32_gpiowrite(PROBE_##n,(s));}while(0) +# define PROBE_MARK(n) PROBE(n,false);PROBE(n,true) +#else +# define PROBE_INIT(mask) +# define PROBE(n,s) +# define PROBE_MARK(n) +#endif diff --git a/boards/radiolink/PIX6/nuttx-config/include/board_dma_map.h b/boards/radiolink/PIX6/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..3e4eb5c326 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/include/board_dma_map.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#define DMAMAP_USART3_TX DMAMAP_USART3_TX_1 // DMA1, Stream 3, Channel 4 (TELEM2 RX) +#define DMAMAP_SDMMC1 DMAMAP_SDMMC1_2 // DMA2, Stream 6, Channel 11 +#define DMAMAP_SPI1_RX DMAMAP_SPI1_RX_1 // DMA2, Stream 0, Channel 3 (SPI sensors RX) +#define DMAMAP_SPI1_TX DMAMAP_SPI1_TX_1 // DMA2, Stream 3, Channel 3 (SPI sensors TX) diff --git a/boards/radiolink/PIX6/nuttx-config/nsh/defconfig b/boards/radiolink/PIX6/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..f69b7b84b8 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/nsh/defconfig @@ -0,0 +1,257 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_IFUPDOWN is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TELNETD is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/radiolink/PIX6/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="radiolink" +CONFIG_ARCH_CHIP="stm32f7" +CONFIG_ARCH_CHIP_STM32F765II=y +CONFIG_ARCH_CHIP_STM32F7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_ITCM=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=22114 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0032 +CONFIG_CDCACM_PRODUCTSTR="radiolink PIX6" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x26ac +CONFIG_CDCACM_VENDORSTR="radiolink" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_GPIO=y +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXAMPLES_CALIB_UDELAY=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_REGIONS=3 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_RAMTRON=y +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 +CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 +CONFIG_RAMTRON_SETSPEED=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_MODE=y +CONFIG_SDMMC1_SDIO_PULLUP=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32F7_ADC1=y +CONFIG_STM32F7_BBSRAM=y +CONFIG_STM32F7_BBSRAM_FILES=5 +CONFIG_STM32F7_BKPSRAM=y +CONFIG_STM32F7_DMA1=y +CONFIG_STM32F7_DMA2=y +CONFIG_STM32F7_DMACAPABLE=y +CONFIG_STM32F7_FLOWCONTROL_BROKEN=y +CONFIG_STM32F7_I2C1=y +CONFIG_STM32F7_I2C2=y +CONFIG_STM32F7_I2C_DYNTIMEO=y +CONFIG_STM32F7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32F7_OTGFS=y +CONFIG_STM32F7_PROGMEM=y +CONFIG_STM32F7_PWR=y +CONFIG_STM32F7_RTC=y +CONFIG_STM32F7_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY=y +CONFIG_STM32F7_RTC_MAGIC_REG=1 +CONFIG_STM32F7_SAVE_CRASHDUMP=y +CONFIG_STM32F7_SDMMC1=y +CONFIG_STM32F7_SDMMC_DMA=y +CONFIG_STM32F7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32F7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32F7_SPI1=y +CONFIG_STM32F7_SPI1_DMA=y +CONFIG_STM32F7_SPI1_DMA_BUFFER=1024 +CONFIG_STM32F7_SPI2=y +CONFIG_STM32F7_SPI4=y +CONFIG_STM32F7_SPI_DMATHRESHOLD=8 +CONFIG_STM32F7_TIM5=y +CONFIG_STM32F7_UART4=y +CONFIG_STM32F7_UART7=y +CONFIG_STM32F7_UART8=y +CONFIG_STM32F7_USART1=y +CONFIG_STM32F7_USART2=y +CONFIG_STM32F7_USART3=y +CONFIG_STM32F7_USART_BREAKS=y +CONFIG_STM32F7_USART_INVERT=y +CONFIG_STM32F7_USART_SINGLEWIRE=y +CONFIG_STM32F7_USART_SWAP=y +CONFIG_STM32F7_WWDG=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_RXBUFSIZE=180 +CONFIG_UART7_SERIAL_CONSOLE=y +CONFIG_UART7_TXBUFSIZE=1500 +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_RXDMA=y +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_IFLOWCONTROL=y +CONFIG_USART2_OFLOWCONTROL=y +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_RXDMA=y +CONFIG_USART2_TXBUFSIZE=3000 +CONFIG_USART3_IFLOWCONTROL=y +CONFIG_USART3_OFLOWCONTROL=y +CONFIG_USART3_RXBUFSIZE=600 +CONFIG_USART3_RXDMA=y +CONFIG_USART3_TXBUFSIZE=3000 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/radiolink/PIX6/nuttx-config/scripts/kernel-space.ld b/boards/radiolink/PIX6/nuttx-config/scripts/kernel-space.ld new file mode 100644 index 0000000000..8ad6e7bf44 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/scripts/kernel-space.ld @@ -0,0 +1,146 @@ +/**************************************************************************** + * kernel-space.ld + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) +/* + * TODO: Fill in the signature location into TOC from user-space elf +EXTERN(_main_toc) +*/ + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + /* + *(.main_toc) + */ + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > kflash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > kflash + + + .ARM.extab : { + *(.ARM.extab*) + } > kflash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > kflash + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > ksram AT > kflash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > ksram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + .ramfunc : { + _sramfuncs = .; + *(.ramfunc .ramfunc.*) + . = ALIGN(4); + _eramfuncs = .; + } > ksram AT > kflash + + _framfuncs = LOADADDR(.ramfunc); +} diff --git a/boards/radiolink/PIX6/nuttx-config/scripts/memory.ld b/boards/radiolink/PIX6/nuttx-config/scripts/memory.ld new file mode 100644 index 0000000000..23e536e9c5 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/scripts/memory.ld @@ -0,0 +1,98 @@ +/**************************************************************************** + * scripts/memory.ld + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F765IIT6 has 2048 KiB of main FLASH memory. This FLASH memory + * can be accessed from either the AXIM interface at address 0x0800:0000 or + * from the ITCM interface at address 0x0020:0000. + * + * Additional information, including the option bytes, is available at at + * FLASH at address 0x1ff0:0000 (AXIM) or 0x0010:0000 (ITCM). + * + * In the STM32F765IIT6, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash on ITCM at 0x0020:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x0010:0000 + * + * NuttX does not modify these option byes. On the unmodified NUCLEO-144 + * board, the BOOT0 pin is at ground so by default, the STM32F765IIT6 will + * boot from address 0x0020:0000 in ITCM FLASH. + * + * The STM32F765IIT6 also has 512 KiB of data SRAM (in addition to ITCM SRAM). + * SRAM is split up into three blocks: + * + * 1) 128 KiB of DTCM SRM beginning at address 0x2000:0000 + * 2) 368 KiB of SRAM1 beginning at address 0x2002:0000 + * 3) 16 KiB of SRAM2 beginning at address 0x2007:c000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * Bootloader reserves the first 32K bank (2 Mbytes Flash memory single bank) + * organization (256 bits read width) + */ + +MEMORY +{ + /* ITCM boot address */ + + itcm (rwx) : ORIGIN = 0x00208000, LENGTH = 2048K-32K + + /* 2048KB FLASH, bootloader reserves the first 32kb */ + + kflash (rx) : ORIGIN = 0x08008000, LENGTH = 1024K-32K + uflash (rx) : ORIGIN = 0x08100000, LENGTH = 1024K + + /* ITCM RAM */ + + itcm_ram (rwx) : ORIGIN = 0x00000000, LENGTH = 16K + + /* DTCM SRAM */ + + dtcm_ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + + /* 368KB of contiguous SRAM1 */ + + ksram (rwx) : ORIGIN = 0x20020000, LENGTH = 128K + usram (rwx) : ORIGIN = 0x20040000, LENGTH = 368K-128K + + /* 16KB of SRAM2 */ + + sram2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 16K +} diff --git a/boards/radiolink/PIX6/nuttx-config/scripts/script.ld b/boards/radiolink/PIX6/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..db0f740cf0 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/scripts/script.ld @@ -0,0 +1,181 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The STM32F765IIT6 has 2048 KiB of main FLASH memory. This FLASH memory + * can be accessed from either the AXIM interface at address 0x0800:0000 or + * from the ITCM interface at address 0x0020:0000. + * + * Additional information, including the option bytes, is available at at + * FLASH at address 0x1ff0:0000 (AXIM) or 0x0010:0000 (ITCM). + * + * In the STM32F765IIT6, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash on ITCM at 0x0020:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x0010:0000 + * + * NuttX does not modify these option byes. On the unmodified NUCLEO-144 + * board, the BOOT0 pin is at ground so by default, the STM32F765IIT6 will + * boot from address 0x0020:0000 in ITCM FLASH. + * + * The STM32F765IIT6 also has 512 KiB of data SRAM (in addition to ITCM SRAM). + * SRAM is split up into three blocks: + * + * 1) 128 KiB of DTCM SRM beginning at address 0x2000:0000 + * 2) 368 KiB of SRAM1 beginning at address 0x2002:0000 + * 3) 16 KiB of SRAM2 beginning at address 0x2007:c000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * Bootloader reserves the first 32K bank (2 Mbytes Flash memory single bank) + * organization (256 bits read width) + */ + +MEMORY +{ + FLASH_ITCM (rx) : ORIGIN = 0x00208000, LENGTH = 2016K + FLASH_AXIM (rx) : ORIGIN = 0x08008000, LENGTH = 2016K + + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 16K + DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + SRAM1 (rwx) : ORIGIN = 0x20020000, LENGTH = 368K + SRAM2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 16K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH_AXIM + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH_AXIM + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH_AXIM + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH_AXIM + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > SRAM1 AT > FLASH_AXIM + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > SRAM1 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + .ramfunc : { + _sramfuncs = .; + *(.ramfunc .ramfunc.*) + . = ALIGN(4); + _eramfuncs = .; + } > ITCM_RAM AT > FLASH_AXIM + + _framfuncs = LOADADDR(.ramfunc); +} diff --git a/boards/radiolink/PIX6/nuttx-config/scripts/user-space.ld b/boards/radiolink/PIX6/nuttx-config/scripts/user-space.ld new file mode 100644 index 0000000000..e19ddea756 --- /dev/null +++ b/boards/radiolink/PIX6/nuttx-config/scripts/user-space.ld @@ -0,0 +1,124 @@ +/**************************************************************************** + * user-space.ld + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ +EXTERN(userspace) +OUTPUT_ARCH(arm) +SECTIONS +{ + .userspace : { + *(.userspace) + } > uflash + + .text : { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > uflash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > uflash + + + .ARM.extab : { + *(.ARM.extab*) + } > uflash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > uflash + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > usram AT > uflash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + /* Kernel heap start at _ebss, make _ebss MPU-friendly aligned */ + . = ALIGN(0x1000); + _ebss = ABSOLUTE(.); + } > usram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + /* Start of the image signature. This + * has to be in the end of the image + */ + .signature : { + _boot_signature = ALIGN(4); + } > uflash +} diff --git a/boards/radiolink/PIX6/src/CMakeLists.txt b/boards/radiolink/PIX6/src/CMakeLists.txt new file mode 100644 index 0000000000..7fbfb7b94d --- /dev/null +++ b/boards/radiolink/PIX6/src/CMakeLists.txt @@ -0,0 +1,55 @@ +############################################################################ +# +# Copyright (c) 2016 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(drivers_board + can.c + i2c.cpp + init.cpp + led.c + mtd.cpp + sdio.c + spi.cpp + timer_config.cpp + usb.c +) +add_dependencies(drivers_board arch_board_hw_info) +target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led # drv_led_start + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer +) diff --git a/boards/radiolink/PIX6/src/board_config.h b/boards/radiolink/PIX6/src/board_config.h new file mode 100644 index 0000000000..845d5d7bd4 --- /dev/null +++ b/boards/radiolink/PIX6/src/board_config.h @@ -0,0 +1,293 @@ +/**************************************************************************** + * + * Copyright (c) 2016-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * board internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* PX4IO connection configuration */ + +#define BOARD_USES_PX4IO_VERSION 2 +#define PX4IO_SERIAL_DEVICE "/dev/ttyS5" +#define PX4IO_SERIAL_TX_GPIO GPIO_UART8_TX +#define PX4IO_SERIAL_RX_GPIO GPIO_UART8_RX +#define PX4IO_SERIAL_BASE STM32_UART8_BASE +#define PX4IO_SERIAL_VECTOR STM32_IRQ_UART8 +#define PX4IO_SERIAL_TX_DMAMAP DMAMAP_UART8_TX +#define PX4IO_SERIAL_RX_DMAMAP DMAMAP_UART8_RX +#define PX4IO_SERIAL_RCC_REG STM32_RCC_APB1ENR +#define PX4IO_SERIAL_RCC_EN RCC_APB1ENR_UART8EN +#define PX4IO_SERIAL_CLOCK STM32_PCLK1_FREQUENCY +#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */ + +/* Configuration ************************************************************************************/ + +#define BOARD_HAS_STATIC_MANIFEST 1 + +#define BOARD_HAS_LTC44XX_VALIDS 0 // No LTC or N Bricks +#define BOARD_HAS_USB_VALID 0 // LTC Has No USB valid +#define BOARD_HAS_NBAT_V 1 // Only one Vbat to ADC +#define BOARD_HAS_NBAT_I 0 // No Ibat ADC + +/* LEDs */ +#define GPIO_LED1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_25MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN14) +#define GPIO_LED2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_25MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN1) +#define GPIO_LED3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_25MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN7) + +#define GPIO_LED_RED GPIO_LED1 +#define GPIO_LED_GREEN GPIO_LED2 +#define GPIO_LED_BLUE GPIO_LED3 + +#define BOARD_HAS_CONTROL_STATUS_LEDS 1 +#define BOARD_OVERLOAD_LED LED_RED +#define BOARD_ARMED_LED LED_BLUE +#define BOARD_ARMED_STATE_LED LED_GREEN + +/* Safety Switch is HW version dependent on having an PX4IO + * So we init to a benign state with the _INIT definition + * and provide the the non _INIT one for the driver to make a run time + * decision to use it. + */ +#define GPIO_nSAFETY_SWITCH_LED_OUT_INIT /* PB0 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0) +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ + +#define ADC1_CH(n) (n) +#define ADC1_GPIO(n) GPIO_ADC1_IN##n + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ + +#define PX4_ADC_GPIO \ + /* PA2 */ ADC1_GPIO(2), \ + /* PA4 */ ADC1_GPIO(4), \ + /* PA5 */ ADC1_GPIO(5), \ + /* PC0 */ ADC1_GPIO(10), \ + /* PC2 */ ADC1_GPIO(12), \ + /* PC3 */ ADC1_GPIO(13) + +/* Define Channel numbers must match above GPIO pin IN(n)*/ + +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PA2 */ ADC1_CH(2) +#define ADC_BATTERY_CURRENT_CHANNEL /* PA5 */ ADC1_CH(5) +#define ADC_SCALED_V5_CHANNEL /* PC0 */ ADC1_CH(10) +#define ADC_ADC1_6V6_CHANNEL /* PC2 */ ADC1_CH(12) +#define ADC_ADC1_3V3_CHANNEL1 /* PC3 */ ADC1_CH(13) +#define ADC_ADC1_3V3_CHANNEL2 /* PA4 */ ADC1_CH(4) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL) | \ + (1 << ADC_SCALED_V5_CHANNEL) | \ + (1 << ADC_ADC1_3V3_CHANNEL2) | \ + (1 << ADC_ADC1_6V6_CHANNEL) | \ + (1 << ADC_ADC1_3V3_CHANNEL1)) + +/* HW has to large of R termination on ADC todo:change when HW value is chosen */ + +#define SYSTEM_ADC_BASE STM32_ADC1_BASE + +#define BOARD_ADC_OPEN_CIRCUIT_V (5.6f) + +//#define UAVCAN_NUM_IFACES_RUNTIME 1 + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 8 + + +#define GPIO_VDD_5V_PERIPH_nEN /* PC4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN4) +#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_PULLUP|GPIO_PORTE|GPIO_PIN15) +#define GPIO_VDD_5V_HIPOWER_nEN /* PD13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN13) +#define GPIO_VDD_5V_HIPOWER_nOC /* PE10 */ (GPIO_INPUT |GPIO_PULLUP|GPIO_PORTE|GPIO_PIN10) +#define GPIO_VDD_3V3_SENSORS_EN /* PE3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN3) +#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PE4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN4) + +/* Define True logic Power Control in arch agnostic form */ + +#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true)) +#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true)) +#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, (on_true)) +#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true)) +#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN) + + +/* Tone alarm output */ + +#define TONE_ALARM_TIMER 9 /* Timer 14 */ +#define TONE_ALARM_CHANNEL 1 /* PE5 GPIO_TIM14_CH1OUT_2 */ + +#define GPIO_BUZZER_1 /* PE5 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN5) + +#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1 +#define GPIO_TONE_ALARM GPIO_TIM9_CH1OUT_2 + +#define HRT_TIMER 5 /* use timer5 for the HRT */ +#define HRT_TIMER_CHANNEL 4 /* use capture/compare channel 4 */ +/* USB OTG FS + * + * PA9 OTG_FS_VBUS VBUS sensing + */ +#define GPIO_nVDD_USB_VALID /* PB2 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PORTB|GPIO_PIN2) + +/* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2 */ +#define PWMIN_TIMER 2 +#define PWMIN_TIMER_CHANNEL /* T2C1 */ 1 +#define GPIO_PWM_IN /* PA15 */ GPIO_TIM2_CH1IN_2 +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 + +/* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ + +#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +#endif + +/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction) + * this board support the ADC system_power interface, and therefore + * provides the true logic GPIO BOARD_ADC_xxxx macros. + */ +#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_nVDD_USB_VALID)) +#define BOARD_ADC_USB_VALID BOARD_ADC_USB_CONNECTED + +#define BOARD_ADC_PERIPH_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_PERIPH_nOC)) +#define BOARD_ADC_HIPOWER_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_HIPOWER_nOC)) + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ + +#define BOARD_HAS_ON_RESET 1 + +#define PX4_GPIO_INIT_LIST { \ + PX4_ADC_GPIO, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN2_TX, \ + GPIO_CAN2_RX, \ + GPIO_VDD_5V_PERIPH_nEN, \ + GPIO_VDD_5V_PERIPH_nOC, \ + GPIO_VDD_5V_HIPOWER_nEN, \ + GPIO_VDD_5V_HIPOWER_nOC, \ + GPIO_VDD_3V3_SENSORS_EN, \ + GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_nVDD_USB_VALID, \ + PX4_MAKE_GPIO_OUTPUT_CLEAR(GPIO_I2C1_SCL), \ + PX4_MAKE_GPIO_OUTPUT_CLEAR(GPIO_I2C1_SDA), \ + PX4_MAKE_GPIO_OUTPUT_CLEAR(GPIO_I2C2_SCL), \ + PX4_MAKE_GPIO_OUTPUT_CLEAR(GPIO_I2C2_SDA), \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define BOARD_NUM_IO_TIMERS 3 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void); + +/**************************************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/radiolink/PIX6/src/can.c b/boards/radiolink/PIX6/src/can.c new file mode 100644 index 0000000000..4f97951860 --- /dev/null +++ b/boards/radiolink/PIX6/src/can.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file can.c + * + * Board-specific CAN functions. + */ + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "chip.h" +#include "stm32_can.h" +#include "board_config.h" + +#ifdef CONFIG_CAN + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} + +#endif diff --git a/boards/radiolink/PIX6/src/i2c.cpp b/boards/radiolink/PIX6/src/i2c.cpp new file mode 100644 index 0000000000..2b708954d5 --- /dev/null +++ b/boards/radiolink/PIX6/src/i2c.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), + initI2CBusExternal(2), +}; diff --git a/boards/radiolink/PIX6/src/init.cpp b/boards/radiolink/PIX6/src/init.cpp new file mode 100644 index 0000000000..6db9aea80f --- /dev/null +++ b/boards/radiolink/PIX6/src/init.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * PX4FMU-specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "board_config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ +#define _GPIO_PULL_DOWN_INPUT(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_2MHz)) + +/* Configuration ************************************************************/ + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + /* set the peripheral rails off */ + + VDD_5V_PERIPH_EN(false); + board_control_spi_sensors_power(false, 0xffff); + VDD_3V3_SENSORS4_EN(false); + + bool last = READ_VDD_3V3_SPEKTRUM_POWER_EN(); + /* Keep Spektum on to discharge rail*/ + VDD_3V3_SPEKTRUM_POWER_EN(false); + + /* wait for the peripheral rail to reach GND */ + usleep(ms * 1000); + syslog(LOG_DEBUG, "reset done, %d ms\n", ms); + + /* re-enable power */ + + /* switch the peripheral rail back on */ + VDD_3V3_SPEKTRUM_POWER_EN(last); + board_control_spi_sensors_power(true, 0xffff); + VDD_3V3_SENSORS4_EN(true); + VDD_5V_PERIPH_EN(true); + +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +extern "C" __EXPORT void +stm32_boardinitialize(void) +{ + board_on_reset(-1); /* Reset PWM first thing */ + + /* configure LEDs */ + + board_autoled_initialize(); + + /* configure pins */ + + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + board_control_spi_sensors_power_configgpio(); + + /* configure USB interfaces */ + stm32_usbinitialize(); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ +static struct spi_dev_s *spi4; +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Power on Interfaces */ + VDD_5V_PERIPH_EN(true); + VDD_5V_HIPOWER_EN(true); + board_control_spi_sensors_power(true, 0xffff); + VDD_3V3_SENSORS4_EN(true); + VDD_3V3_SPEKTRUM_POWER_EN(true); + + /* Need hrt running before using the ADC */ + + px4_platform_init(); + + /* Configure the Actual SPI interfaces (after we determined the HW version) */ + + stm32_spiinitialize(); + + spi4 = px4_spibus_initialize(4); + + if (!spi4) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 4\n"); + board_autoled_on(LED_AMBER); + } + + /* Default SPI4 to 10MHz and de-assert the known chip selects. */ + SPI_SETFREQUENCY(spi4, 10000000); + SPI_SETBITS(spi4, 8); + SPI_SETMODE(spi4, SPIDEV_MODE3); + up_udelay(20); + + //board_spi_reset(10, 0xffff); + + /* Configure the DMA allocator */ + + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + +#if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); +#endif + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_on(LED_GREEN); // Indicate Power. + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + +#ifdef CONFIG_MMCSD + int ret = stm32_sdio_initialize(); + + if (ret != OK) { + led_on(LED_RED); + } + +#endif /* CONFIG_MMCSD */ + + /* Configure the HW based on the manifest */ + + px4_platform_configure(); + + return OK; +} diff --git a/boards/radiolink/PIX6/src/led.c b/boards/radiolink/PIX6/src/led.c new file mode 100644 index 0000000000..178c373637 --- /dev/null +++ b/boards/radiolink/PIX6/src/led.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * + * Copyright (c) 2013 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * PX4FMU LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +// B R S G +// 0 1 2 3 +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_LED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_LED_BLUE, // Indexed by BOARD_LED_BLUE + GPIO_LED_RED, // Indexed by BOARD_LED_RED +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_LED_BLUE, // Indexed by LED_BLUE + GPIO_LED_RED, // Indexed by LED_RED, LED_AMBER + GPIO_nSAFETY_SWITCH_LED_OUT_INIT, // Indexed by LED_SAFETY (defaulted to an input) + GPIO_LED_GREEN, // Indexed by LED_GREEN +}; + +#endif + +__EXPORT void led_init(void) +{ + + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + stm32_configgpio(g_ledmap[l]); + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on */ + + stm32_gpiowrite(g_ledmap[led], !state); +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + return !stm32_gpioread(g_ledmap[led]); +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/3dr/ctrl-zero-h7-oem-revg/src/mtd.cpp b/boards/radiolink/PIX6/src/mtd.cpp similarity index 91% rename from boards/3dr/ctrl-zero-h7-oem-revg/src/mtd.cpp rename to boards/radiolink/PIX6/src/mtd.cpp index c1b0f1bac3..450dcdaf2b 100644 --- a/boards/3dr/ctrl-zero-h7-oem-revg/src/mtd.cpp +++ b/boards/radiolink/PIX6/src/mtd.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * Copyright (C) 2020 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,11 +30,12 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ +//TODO:Prepare for NxtDual #include #include // KiB BS nB -static const px4_mft_device_t spi2 = { // FM25V01A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32) +static const px4_mft_device_t spi2 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32) .bus_type = px4_mft_device_t::SPI, .devid = SPIDEV_FLASH(0) }; @@ -46,14 +47,15 @@ static const px4_mtd_entry_t fmum_fram = { { .type = MTD_PARAMETERS, .path = "/fs/mtd_params", - .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_PAGE_SHIFT)) - }, + .nblocks = 1024 + } }, }; + static const px4_mtd_manifest_t board_mtd_config = { - .nconfigs = 1, - .entries = { + .nconfigs = 1, + .entries = { &fmum_fram } }; diff --git a/boards/radiolink/PIX6/src/sdio.c b/boards/radiolink/PIX6/src/sdio.c new file mode 100644 index 0000000000..869d757756 --- /dev/null +++ b/boards/radiolink/PIX6/src/sdio.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "board_config.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(GPIO_SDMMC1_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + + if (sdio_dev && present != g_sd_inserted) { + sdio_mediachange(sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDMMC1_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + sdio_dev = sdio_initialize(SDIO_SLOTNO); + + if (!sdio_dev) { + syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev); + + if (ret != OK) { + syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(sdio_dev, true); +#endif + + return OK; +} + +#endif /* CONFIG_MMCSD */ diff --git a/boards/radiolink/PIX6/src/spi.cpp b/boards/radiolink/PIX6/src/spi.cpp new file mode 100644 index 0000000000..0c47fe1e6b --- /dev/null +++ b/boards/radiolink/PIX6/src/spi.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** + * + * Copyright (C) 2019-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortB, GPIO::Pin12}), + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortE, GPIO::Pin12}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortB, GPIO::Pin4}), + }), + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin10}), + initSPIDevice(DRV_OSD_DEVTYPE_ATXXXX, SPI::CS{GPIO::PortA, GPIO::Pin8}), + }), + initSPIBusExternal(SPI::Bus::SPI4, { + initSPIConfigExternal(SPI::CS{GPIO::PortC, GPIO::Pin14}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), + initSPIConfigExternal(SPI::CS{GPIO::PortC, GPIO::Pin15}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/radiolink/PIX6/src/timer_config.cpp b/boards/radiolink/PIX6/src/timer_config.cpp new file mode 100644 index 0000000000..e4c42e6599 --- /dev/null +++ b/boards/radiolink/PIX6/src/timer_config.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index2, DMA::Stream5, DMA::Channel6}), + initIOTimer(Timer::Timer2, DMA{DMA::Index1, DMA::Stream7, DMA::Channel3}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1, DMA::Stream2, DMA::Channel5}), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortA, GPIO::Pin10}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel1}, {GPIO::PortA, GPIO::Pin15}), + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel4}, {GPIO::PortA, GPIO::Pin3}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel2}, {GPIO::PortA, GPIO::Pin7}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel1}, {GPIO::PortC, GPIO::Pin6}), +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/radiolink/PIX6/src/usb.c b/boards/radiolink/PIX6/src/usb.c new file mode 100644 index 0000000000..4d2949c789 --- /dev/null +++ b/boards/radiolink/PIX6/src/usb.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * + * Copyright (C) 2016 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file px4fmu_usb.c + * + * Board-specific USB functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include "board_config.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the PX4FMU board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ + +#ifdef CONFIG_STM32F7_OTGFS + //stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} + +__EXPORT int board_read_VBUS_state(void) +{ + return 0; +} diff --git a/boards/siyi/n7/default.px4board b/boards/siyi/n7/default.px4board index 0fda7adec4..3510122754 100644 --- a/boards/siyi/n7/default.px4board +++ b/boards/siyi/n7/default.px4board @@ -18,7 +18,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM20689=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y diff --git a/boards/sky-drones/smartap-airlink/default.px4board b/boards/sky-drones/smartap-airlink/default.px4board index 8c8afa6080..b515bd555b 100644 --- a/boards/sky-drones/smartap-airlink/default.px4board +++ b/boards/sky-drones/smartap-airlink/default.px4board @@ -23,7 +23,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/spracing/h7extreme/default.px4board b/boards/spracing/h7extreme/default.px4board index aa97905609..cc99e6f7c1 100644 --- a/boards/spracing/h7extreme/default.px4board +++ b/boards/spracing/h7extreme/default.px4board @@ -13,7 +13,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/svehicle/e2/CMakeLists.txt b/boards/svehicle/e2/CMakeLists.txt new file mode 100644 index 0000000000..8756f63e64 --- /dev/null +++ b/boards/svehicle/e2/CMakeLists.txt @@ -0,0 +1,34 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_subdirectory(pwm_voltage) diff --git a/boards/svehicle/e2/bootloader.px4board b/boards/svehicle/e2/bootloader.px4board new file mode 100644 index 0000000000..19b6e662be --- /dev/null +++ b/boards/svehicle/e2/bootloader.px4board @@ -0,0 +1,3 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" diff --git a/boards/svehicle/e2/default.px4board b/boards/svehicle/e2/default.px4board new file mode 100644 index 0000000000..751fc835dc --- /dev/null +++ b/boards/svehicle/e2/default.px4board @@ -0,0 +1,98 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ETHERNET=y +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS7" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1" +CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3" +CONFIG_DRIVERS_ADC_ADS1115=y +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_BMP388=y +CONFIG_DRIVERS_BAROMETER_MS5611=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_COMMON_DISTANCE_SENSOR=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_HEATER=y +CONFIG_DRIVERS_IMU_BOSCH_BMI088=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y +CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=y +CONFIG_DRIVERS_GNSS_SEPTENTRIO=y +CONFIG_COMMON_LIGHT=y +CONFIG_COMMON_MAGNETOMETER=y +CONFIG_DRIVERS_OSD_MSP_OSD=y +CONFIG_DRIVERS_POWER_MONITOR_INA226=y +CONFIG_DRIVERS_POWER_MONITOR_INA228=y +CONFIG_DRIVERS_POWER_MONITOR_INA238=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_COMMON_RC=y +CONFIG_DRIVERS_SAFETY_BUTTON=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2 +CONFIG_MODULES_AIRSPEED_SELECTOR=y +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_ESC_BATTERY=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_UXRCE_DDS_CLIENT=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2C_LAUNCHER=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NETMAN=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y diff --git a/boards/svehicle/e2/extras/px4_io-v2_default.bin b/boards/svehicle/e2/extras/px4_io-v2_default.bin new file mode 100644 index 0000000000..145089ae0d Binary files /dev/null and b/boards/svehicle/e2/extras/px4_io-v2_default.bin differ diff --git a/boards/svehicle/e2/extras/svehicle_e2_bootloader.bin b/boards/svehicle/e2/extras/svehicle_e2_bootloader.bin new file mode 100644 index 0000000000..44df59e2be Binary files /dev/null and b/boards/svehicle/e2/extras/svehicle_e2_bootloader.bin differ diff --git a/boards/svehicle/e2/firmware.prototype b/boards/svehicle/e2/firmware.prototype new file mode 100644 index 0000000000..b515e66fdb --- /dev/null +++ b/boards/svehicle/e2/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 6110, + "magic": "PX4FWv1", + "description": "Firmware for the SVehicleE2 board", + "image": "", + "build_time": 0, + "summary": "SVehicleE2", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1966080, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/svehicle/e2/init/rc.board_defaults b/boards/svehicle/e2/init/rc.board_defaults new file mode 100644 index 0000000000..98337fdf17 --- /dev/null +++ b/boards/svehicle/e2/init/rc.board_defaults @@ -0,0 +1,23 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +# Mavlink ethernet (CFG 1000) +param set-default MAV_2_CONFIG 1000 +param set-default MAV_2_BROADCAST 1 +param set-default MAV_2_MODE 0 +param set-default MAV_2_RADIO_CTL 0 +param set-default MAV_2_RATE 100000 +param set-default MAV_2_REMOTE_PRT 14550 +param set-default MAV_2_UDP_PRT 14550 + +param set-default BAT1_V_DIV 21.5 +param set-default BAT1_A_PER_V 33.33 + +param set-default SENS_EXT_I2C_PRB 0 + +safety_button start + +# pwm voltage 3.3V/5V switch +pwm_voltage_apply start diff --git a/boards/svehicle/e2/init/rc.board_sensors b/boards/svehicle/e2/init/rc.board_sensors new file mode 100644 index 0000000000..2a7e1c08b3 --- /dev/null +++ b/boards/svehicle/e2/init/rc.board_sensors @@ -0,0 +1,34 @@ +#!/bin/sh +# +# SVehicle E2 specific board sensors init +#------------------------------------------------------------------------------ + +if param compare -s ADC_ADS1115_EN 1 +then + ads1115 start -X + board_adc start -n +else + board_adc start +fi + +if param compare SENS_EN_INA228 1 +then + # Start Digital power monitors + ina228 -X start +fi + +bmi088 -A -R 4 -s -b 3 start +bmi088 -G -R 4 -s -b 3 start + +icm42688p -R 6 -s start + +# Internal SPI bus ICM-20649 (hard-mounted) +icm20649 -R 14 -s start + +# Internal magnetometer on I2c +rm3100 -I -R 12 start + +bmm150 -I -R 4 start + +icp201xx -X start +icp201xx -I -a 0x64 start diff --git a/boards/svehicle/e2/nuttx-config/Kconfig b/boards/svehicle/e2/nuttx-config/Kconfig new file mode 100644 index 0000000000..bb33d3cfda --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# +config BOARD_HAS_PROBES + bool "Board provides GPIO or other Hardware for signaling to timing analyze." + default y + ---help--- + This board provides GPIO FMU-CH1-5, CAP1-6 as PROBE_1-11 to provide timing signals from selected drivers. + +config BOARD_USE_PROBES + bool "Enable the use the board provided FMU-CH1-5, CAP1-6 as PROBE_1-11" + default n + depends on BOARD_HAS_PROBES + + ---help--- + Select to use GPIO FMU-CH1-5, CAP1-6 to provide timing signals from selected drivers. diff --git a/boards/svehicle/e2/nuttx-config/bootloader/defconfig b/boards/svehicle/e2/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..d6db9a0c8b --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/bootloader/defconfig @@ -0,0 +1,95 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_SPI_EXCHANGE is not set +# CONFIG_STM32H7_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/svehicle/e2/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="svehicle" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H753II=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x41F8 +CONFIG_CDCACM_PRODUCTSTR="SVehicle BL E2.x" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x20A3 +CONFIG_CDCACM_VENDORSTR="SVehicle" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_UART5=y +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_UART5_RXBUFSIZE=512 +CONFIG_UART5_RXDMA=y +CONFIG_UART5_TXBUFSIZE=512 +CONFIG_UART5_TXDMA=y +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/svehicle/e2/nuttx-config/include/board.h b/boards/svehicle/e2/nuttx-config/include/board.h new file mode 100644 index 0000000000..5133175ff7 --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/include/board.h @@ -0,0 +1,562 @@ +/************************************************************************************ + * nuttx-configs/px4_fmu-v6x/include/board.h + * + * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved. + * Authors: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#ifndef __NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The px4_fmu-v6X board provides the following clock sources: + * + * X1: 16 MHz crystal for HSE + * + * So we have these clock source available within the STM32 + * + * HSI: 16 MHz RC factory-trimmed + * HSE: 16 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 16000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 16,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * Subject to: + * + * 1 <= PLLM <= 63 + * 4 <= PLLN <= 512 + * 150 MHz <= PLL_VCOL <= 420MHz + * 192 MHz <= PLL_VCOH <= 836MHz + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + * Subject to + * + * PLLP1 = {2, 4, 6, 8, ..., 128} + * PLLP2,3 = {2, 3, 4, ..., 128} + * CPUCLK <= 480 MHz + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (16,000,000 / 1) * 60 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(60) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 60) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(4) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(4) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/4 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration + * + * Note: look at Table 54 in ST Manual + */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 + +/* UART clock selection */ +/* reset to default to overwrite any changes done by any bootloader */ + +#define STM32_RCC_D2CCIP2R_USART234578_SEL RCC_D2CCIP2R_USART234578SEL_RCC +#define STM32_RCC_D2CCIP2R_USART16_SEL RCC_D2CCIP2R_USART16SEL_RCC + +/* FDCAN 1 2 clock source */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE /* FDCAN 1 2 clock source */ + +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states + * + * ------------ ---------- ----------- + * Vcore MAX ACLK WAIT STATES + * ------------ ---------- ----------- + * 1.15-1.26 V 70 MHz 0 + * (VOS1 level) 140 MHz 1 + * 210 MHz 2 + * 1.05-1.15 V 55 MHz 0 + * (VOS2 level) 110 MHz 1 + * 165 MHz 2 + * 220 MHz 3 + * 0.95-1.05 V 45 MHz 0 + * (VOS3 level) 90 MHz 1 + * 135 MHz 2 + * 180 MHz 3 + * 225 MHz 4 + * ------------ ---------- ----------- + */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* SDMMC definitions ********************************************************/ + +/* Init 400kHz, freq = PLL1Q/(2*div) div = PLL1Q/(2*freq) */ + +#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq) + * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s + */ + +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE + +/* LED definitions ******************************************************************/ +/* The PX4 FMUV6X board has three, LED_GREEN a Green LED, LED_BLUE a Blue LED and + * LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +/* LED definitions ******************************************************************/ +/* The px4_fmu-v6x board has three, LED_GREEN a Green LED, LED_BLUE a Blue LED and + * LED_RED a Red LED, that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Alternate function pin selections ************************************************/ + +#define GPIO_USART1_RX GPIO_USART1_RX_3 /* PB7 */ +#define GPIO_USART1_TX GPIO_USART1_TX_3 /* PB6 */ + +#define GPIO_USART2_RX GPIO_USART2_RX_1 /* PA3 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ +#define GPIO_USART2_RTS GPIO_USART2_RTS_2 /* PD4 */ +#define GPIO_USART2_CTS GPIO_USART2_CTS_NSS_2 /* PD3 */ + +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +#define GPIO_UART4_RX GPIO_UART4_RX_6 /* PH14 */ +#define GPIO_UART4_TX GPIO_UART4_TX_6 /* PH13 */ + +#define GPIO_UART5_RX GPIO_UART5_RX_3 /* PD2 */ +#define GPIO_UART5_TX GPIO_UART5_TX_3 /* PC12 */ +#undef GPIO_UART5_CTS +#define GPIO_UART5_CTS ((GPIO_ALT|GPIO_AF8|GPIO_PORTC|GPIO_PIN9) | GPIO_PULLDOWN) /* PC9 */ + +#define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ +#define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ + +#define GPIO_UART7_RX GPIO_UART7_RX_4 /* PF6 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ +#define GPIO_UART7_RTS (GPIO_UART7_RTS_2 | GPIO_PULLDOWN) /* PF8 */ +#define GPIO_UART7_CTS (GPIO_UART7_CTS_1 | GPIO_PULLDOWN) /* PE10 */ + +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + + +/* CAN + * + * CAN1 is routed to transceiver. + * CAN2 is routed to transceiver. + */ +#define GPIO_CAN1_RX GPIO_CAN1_RX_3 /* PD0 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_3 /* PD1 */ +#define GPIO_CAN2_RX GPIO_CAN2_RX_1 /* PB12 */ +#define GPIO_CAN2_TX GPIO_CAN2_TX_1 /* PB13 */ + +/* SPI + * SPI1 is sensors1 + * SPI2 is sensors2 + * SPI3 is sensors3 + * SPI4 is Not Used + * SPI5 is FRAM + * SPI6 is EXTERNAL1 + * + */ + +#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_2MHz)) + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_3 /* PG9 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_2 /* PB5 */ +#define GPIO_SPI1_SCK ADJ_SLEW_RATE(GPIO_SPI1_SCK_1) /* PA5 */ + +#define GPIO_SPI2_MISO GPIO_SPI2_MISO_3 /* PI2 */ +#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_4 /* PI3 */ +#define GPIO_SPI2_SCK ADJ_SLEW_RATE(GPIO_SPI2_SCK_6) /* PI1 */ + +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 /* PC11 */ +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_3 /* PB2 */ +#define GPIO_SPI3_SCK ADJ_SLEW_RATE(GPIO_SPI3_SCK_2) /* PC10 */ + +#define GPIO_SPI5_MISO GPIO_SPI5_MISO_2 /* PH7 */ +#define GPIO_SPI5_MOSI GPIO_SPI5_MOSI_1 /* PF11 */ +#define GPIO_SPI5_SCK ADJ_SLEW_RATE(GPIO_SPI5_SCK_1) /* PF7 */ + +#define GPIO_SPI6_MISO GPIO_SPI6_MISO_2 /* PA6 */ +#define GPIO_SPI6_MOSI GPIO_SPI6_MOSI_1 /* PG14 */ +#define GPIO_SPI6_SCK ADJ_SLEW_RATE(GPIO_SPI6_SCK_3) /* PB3 */ + +/* I2C + * + * The optional _GPIO configurations allow the I2C driver to manually + * reset the bus to clear stuck slaves. They match the pin configuration, + * but are normally-high GPIOs. + * + */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* PB8 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* PB9 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN8) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN9) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_2 /* PF1 */ +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_2 /* PF0 */ + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN1) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN0) + +#define GPIO_I2C3_SCL GPIO_I2C3_SCL_1 /* PA8 */ +#define GPIO_I2C3_SDA GPIO_I2C3_SDA_2 /* PH8 */ + +#define GPIO_I2C3_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTA | GPIO_PIN8) +#define GPIO_I2C3_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTH | GPIO_PIN8) + +#define GPIO_I2C4_SCL GPIO_I2C4_SCL_2 /* PF14 */ +#define GPIO_I2C4_SDA GPIO_I2C4_SDA_2 /* PF15 */ + +#define GPIO_I2C4_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN14) +#define GPIO_I2C4_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN15) + +/* SDMMC2 + * + * VDD 3.3 + * GND + * SDMMC2_CK PD6 + * SDMMC2_CMD PD7 + * SDMMC2_D0 PB14 + * SDMMC2_D1 PB15 + * SDMMC2_D2 PG11 + * SDMMC2_D3 PB4 + */ + +#define GPIO_SDMMC2_CK GPIO_SDMMC2_CK_1 /* PD6 */ +#define GPIO_SDMMC2_CMD GPIO_SDMMC2_CMD_1 /* PD7 */ +// GPIO_SDMMC2_D0 No Remap /* PB14 */ +// GPIO_SDMMC2_D1 No Remap /* PB15 */ +#define GPIO_SDMMC2_D2 GPIO_SDMMC2_D2_1 /* PG11 */ +// GPIO_SDMMC2_D3 No Remap /* PB4 */ + +/* The STM32 H7 connects to a TI DP83848TSQ/NOPB + * using RMII + * + * STM32 H7 BOARD DP83848TSQ/NOPB + * GPIO SIGNAL PIN NAME + * -------- ------------ ------------- + * PA7 ETH_CRS_DV CRS_DV + * PC1 ETH_MDC MDC + * PA2 ETH_MDIO MDIO + * PA1 ETH_REF_CL X1 + * PC4 ETH_RXD0 RX_D0 + * PC5 ETH_RXD1 RX_D1 + * PB11 ETH_TX_EN TX_EN + * PG13 ETH_TXD0 TX_D0 + * PG12 ETH_TXD1 TX_D1 + * + * The PHY address is 1, since COL/PHYAD0 features a pull up. + */ + +#define GPIO_ETH_RMII_TX_EN GPIO_ETH_RMII_TX_EN_1 /* PB11 */ +#define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2 /* PG13 */ +#define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_2 /* PG12 */ + + +/* USB + * + * OTG_FS_DM PA11 + * OTG_FS_DP PA12 + * VBUS PA9 + */ + + +/* Board provides GPIO or other Hardware for signaling to timing analyzer */ + +#if defined(CONFIG_BOARD_USE_PROBES) +# include "stm32_gpio.h" +# define PROBE_N(n) (1<<((n)-1)) +# define PROBE_1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTI|GPIO_PIN0) /* PI0 AUX1 */ +# define PROBE_2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN12) /* PH12 AUX2 */ +# define PROBE_3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN11) /* PH11 AUX3 */ +# define PROBE_4 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN10) /* PH10 AUX4 */ +# define PROBE_5 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN13) /* PD13 AUX5 */ +# define PROBE_6 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTD|GPIO_PIN14) /* PD14 AUX6 */ +# define PROBE_7 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN11) /* PE11 CAP1 */ + +# define PROBE_INIT(mask) \ + do { \ + if ((mask)& PROBE_N(1)) { stm32_configgpio(PROBE_1); } \ + if ((mask)& PROBE_N(2)) { stm32_configgpio(PROBE_2); } \ + if ((mask)& PROBE_N(3)) { stm32_configgpio(PROBE_3); } \ + if ((mask)& PROBE_N(4)) { stm32_configgpio(PROBE_4); } \ + if ((mask)& PROBE_N(5)) { stm32_configgpio(PROBE_5); } \ + if ((mask)& PROBE_N(6)) { stm32_configgpio(PROBE_6); } \ + if ((mask)& PROBE_N(7)) { stm32_configgpio(PROBE_7); } \ + if ((mask)& PROBE_N(8)) { stm32_configgpio(PROBE_8); } \ + if ((mask)& PROBE_N(9)) { stm32_configgpio(PROBE_9); } \ + } while(0) + +# define PROBE(n,s) do {stm32_gpiowrite(PROBE_##n,(s));}while(0) +# define PROBE_MARK(n) PROBE(n,false);PROBE(n,true) +#else +# define PROBE_INIT(mask) +# define PROBE(n,s) +# define PROBE_MARK(n) +#endif + +#endif /*__NUTTX_CONFIG_PX4_FMU_V6X_INCLUDE_BOARD_H */ diff --git a/boards/svehicle/e2/nuttx-config/include/board_dma_map.h b/boards/svehicle/e2/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..1f45efc569 --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/include/board_dma_map.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMAMUX1 Using at most 8 Channels on DMA1 -------- Assigned +// V + +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* 1 DMA1:37 ICM-20649 */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* 2 DMA1:38 ICM-20649 */ + +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* 3 DMA1:39 ICM-42688-P */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* 4 DMA1:40 ICM-42688-P */ + +//#define DMAMAP_USART1_RX DMAMAP_DMA12_USART1RX_0 /* DMA1:41 GPS1 */ +//#define DMAMAP_USART1_TX DMAMAP_DMA12_USART1TX_0 /* DMA1:42 GPS1 */ + +//#define DMAMAP_USART2_RX DMAMAP_DMA12_USART2RX_0 /* DMA1:43 Telem3 */ +//#define DMAMAP_USART2_TX DMAMAP_DMA12_USART2TX_0 /* DMA1:44 Telem3 */ + +//#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_0 /* DMA1:45 DEBUG */ +//#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_0 /* DMA1:46 DEBUG */ + +//#define DMAMAP_UART4_RX DMAMAP_DMA12_UART4RX_0 /* DMA1:63 EXT2 */ +//#define DMAMAP_UART4_TX DMAMAP_DMA12_UART4TX_0 /* DMA1:64 EXT2 */ + +#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 /* 5 DMA1:71 PX4IO */ +#define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 /* 6 DMA1:72 PX4IO */ + +// Assigned in timer_config.cpp + +// Timer 4 /* 7 DMA1:32 TIM4UP */ +// Timer 5 /* 8 DMA1:50 TIM5UP */ + +// DMAMUX2 Using at most 8 Channels on DMA2 -------- Assigned +// V + +#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_1 /* 1 DMA2:61 BMI088 */ +#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_1 /* 2 DMA2:62 BMI088 */ + +#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_1 /* 3 DMA2:45 DEBUG */ +#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_1 /* 4 DMA2:46 DEBUG */ + +#define DMAMAP_UART5_RX DMAMAP_DMA12_UART5RX_1 /* 5 DMA2:65 TELEM2 */ +#define DMAMAP_UART5_TX DMAMAP_DMA12_UART5TX_1 /* 6 DMA2:66 TELEM2 */ + +#define DMAMAP_UART7_RX DMAMAP_DMA12_UART7RX_1 /* 7 DMA1:79 TELEM1 */ +#define DMAMAP_UART7_TX DMAMAP_DMA12_UART7TX_1 /* 8 DMA1:80 TELEM1 */ + +//#define DMAMAP_UART8_RX DMAMAP_DMA12_UART8RX_1 /* DMA1:81 GPS2 */ +//#define DMAMAP_UART8_TX DMAMAP_DMA12_UART8TX_1 /* DMA1:82 GPS2 */ + +// DMAMUX2 Using at most 8 Channels on BDMA -------- Assigned +// V + +#define DMAMAP_SPI6_RX DMAMAP_BDMA_SPI6_RX /* 1 BDMA:11 SPI J11 */ +#define DMAMAP_SPI6_TX DMAMAP_BDMA_SPI6_TX /* 2 BDMA:12 SPI J11 */ diff --git a/boards/svehicle/e2/nuttx-config/nsh/defconfig b/boards/svehicle/e2/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..6c6d9c6edb --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/nsh/defconfig @@ -0,0 +1,330 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ARP is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_IFUPDOWN is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_NSLOOKUP is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TELNETD is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/svehicle/e2/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="svehicle" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H753II=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95751 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x41F8 +CONFIG_CDCACM_PRODUCTSTR="SVehicle E2.x" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x20A3 +CONFIG_CDCACM_VENDORSTR="SVehicle" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_ETH0_PHY_LAN8742A=y +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FSUTILS_IPCFG=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_THROTTLE=0 +CONFIG_IPCFG_BINARY=y +CONFIG_IPCFG_CHARDEV=y +CONFIG_IPCFG_PATH="/fs/mtd_net" +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_RAMTRON=y +CONFIG_NAME_MAX=40 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDB_DNSCLIENT_ENTRIES=8 +CONFIG_NETDB_DNSSERVER_NOADDR=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_DNSIPADDR=0xA290AFE +CONFIG_NETINIT_DRIPADDR=0xA290AFE +CONFIG_NETINIT_MONITOR=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETINIT_THREAD_PRIORITY=49 +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_ARP_IPIN=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1518 +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_NACTIVESOCKETS=16 +CONFIG_NET_SOLINGER=y +CONFIG_NET_TCP=y +CONFIG_NET_TCPBACKLOG=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NET_UDP_WRITE_BUFFERS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_TELNET=y +CONFIG_NSH_TELNET_LOGIN=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5 +CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5 +CONFIG_RAMTRON_SETSPEED=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SDMMC2_SDIO_PULLUP=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_FLASH_OVERRIDE_I=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C2=y +CONFIG_STM32H7_I2C3=y +CONFIG_STM32H7_I2C4=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100MBPS=0x8 +CONFIG_STM32H7_PHYSR_FULLDUPLEX=0x10 +CONFIG_STM32H7_PHYSR_MODE=0x10 +CONFIG_STM32H7_PHYSR_SPEED=0x8 +CONFIG_STM32H7_PHY_POLLING=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SDMMC2=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=1024 +CONFIG_STM32H7_SPI2=y +CONFIG_STM32H7_SPI2_DMA=y +CONFIG_STM32H7_SPI2_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI3=y +CONFIG_STM32H7_SPI3_DMA=y +CONFIG_STM32H7_SPI3_DMA_BUFFER=1024 +CONFIG_STM32H7_SPI5=y +CONFIG_STM32H7_SPI6=y +CONFIG_STM32H7_SPI6_DMA=y +CONFIG_STM32H7_SPI6_DMA_BUFFER=1024 +CONFIG_STM32H7_TIM12=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM4=y +CONFIG_STM32H7_TIM5=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART5=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART6=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART4_BAUD=57600 +CONFIG_UART4_RXBUFSIZE=600 +CONFIG_UART4_TXBUFSIZE=1500 +CONFIG_UART5_IFLOWCONTROL=y +CONFIG_UART5_OFLOWCONTROL=y +CONFIG_UART5_RXDMA=y +CONFIG_UART5_TXBUFSIZE=10000 +CONFIG_UART5_TXDMA=y +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_IFLOWCONTROL=y +CONFIG_UART7_OFLOWCONTROL=y +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_RXDMA=y +CONFIG_UART7_TXBUFSIZE=3000 +CONFIG_UART7_TXDMA=y +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_TXBUFSIZE=1500 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_IFLOWCONTROL=y +CONFIG_USART2_OFLOWCONTROL=y +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=3000 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=180 +CONFIG_USART3_RXDMA=y +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USART3_TXDMA=y +CONFIG_USART6_BAUD=57600 +CONFIG_USART6_RXBUFSIZE=600 +CONFIG_USART6_TXBUFSIZE=1500 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y diff --git a/boards/svehicle/e2/nuttx-config/scripts/bootloader_script.ld b/boards/svehicle/e2/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..2e6eba3607 --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,215 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The PX4 FMUV6X uses an STM32H753II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The PX4 FMUV6X has a test point on board, the BOOT0 pin is at ground so by + * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test + * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000 + * + * The STM32H743II also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + * + * The bootloader uses the first sector of the flash, which is 128K in length. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 128K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/svehicle/e2/nuttx-config/scripts/script.ld b/boards/svehicle/e2/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..b6b341d4e8 --- /dev/null +++ b/boards/svehicle/e2/nuttx-config/scripts/script.ld @@ -0,0 +1,229 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The PX4 FMUV6X uses an STM32H753II has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743II, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The PX4 FMUV6X has a test point on board, the BOOT0 pin is at ground so by + * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test + * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000 + * + * The STM32H743II also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1920K + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) +EXTERN(board_get_manifest) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/svehicle/e2/pwm_voltage/CMakeLists.txt b/boards/svehicle/e2/pwm_voltage/CMakeLists.txt new file mode 100644 index 0000000000..6db1696208 --- /dev/null +++ b/boards/svehicle/e2/pwm_voltage/CMakeLists.txt @@ -0,0 +1,42 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE modules__pwm_voltage_apply + MAIN pwm_voltage_apply + + SRCS + pwm_voltage.cpp + DEPENDS + px4_work_queue + ) diff --git a/boards/svehicle/e2/pwm_voltage/parameters.c b/boards/svehicle/e2/pwm_voltage/parameters.c new file mode 100644 index 0000000000..728bcc7a55 --- /dev/null +++ b/boards/svehicle/e2/pwm_voltage/parameters.c @@ -0,0 +1,43 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * Control PWM output voltage + * + * @value 0 3.3V + * @value 1 5.0V + * + * @reboot_required true + * @group PWM Outputs + */ +PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0); diff --git a/boards/svehicle/e2/pwm_voltage/pwm_voltage.cpp b/boards/svehicle/e2/pwm_voltage/pwm_voltage.cpp new file mode 100644 index 0000000000..2bef9ae0f6 --- /dev/null +++ b/boards/svehicle/e2/pwm_voltage/pwm_voltage.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "board_config.h" + +extern "C" int pwm_voltage_apply_main(int argc, char *argv[]) +{ + int32_t pwm_volt_sel = 0; + + param_get(param_find("PWM_VOLT_SEL"), &pwm_volt_sel); + + if (pwm_volt_sel != 0) { + PWM_5V_VOLT_SEL(true); + + } else { + PWM_5V_VOLT_SEL(false); + } + + return 0; +} diff --git a/boards/svehicle/e2/src/CMakeLists.txt b/boards/svehicle/e2/src/CMakeLists.txt new file mode 100644 index 0000000000..a120ebe336 --- /dev/null +++ b/boards/svehicle/e2/src/CMakeLists.txt @@ -0,0 +1,75 @@ +############################################################################ +# +# Copyright (c) 2016 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_compile_definitions(BOOTLOADER) + add_library(drivers_board + bootloader_main.c + init.c + usb.c + timer_config.cpp + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer #gpio + arch_io_pins # iotimer + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + can.c + i2c.cpp + init.c + led.c + mtd.cpp + sdio.c + spi.cpp + timer_config.cpp + usb.c + ) + add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led # drv_led_start + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer + ) +endif() diff --git a/boards/svehicle/e2/src/board_config.h b/boards/svehicle/e2/src/board_config.h new file mode 100644 index 0000000000..98677855c9 --- /dev/null +++ b/boards/svehicle/e2/src/board_config.h @@ -0,0 +1,484 @@ +/**************************************************************************** + * + * Copyright (c) 2016-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * PX4FMU-v6x internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +#undef TRACE_PINS + +/* PX4IO connection configuration */ + +#define BOARD_USES_PX4IO_VERSION 2 +#define PX4IO_SERIAL_DEVICE "/dev/ttyS5" +#define PX4IO_SERIAL_TX_GPIO GPIO_USART6_TX +#define PX4IO_SERIAL_RX_GPIO GPIO_USART6_RX +#define PX4IO_SERIAL_BASE STM32_USART6_BASE +#define PX4IO_SERIAL_VECTOR STM32_IRQ_USART6 +#define PX4IO_SERIAL_TX_DMAMAP DMAMAP_USART6_TX +#define PX4IO_SERIAL_RX_DMAMAP DMAMAP_USART6_RX +#define PX4IO_SERIAL_RCC_REG STM32_RCC_APB2ENR +#define PX4IO_SERIAL_RCC_EN RCC_APB2ENR_USART6EN +#define PX4IO_SERIAL_CLOCK STM32_PCLK2_FREQUENCY +#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */ + +/* Configuration ************************************************************************************/ + +#define BOARD_HAS_LTC44XX_VALIDS 2 // N Bricks +#define BOARD_HAS_USB_VALID 1 // LTC Has USB valid +#define BOARD_HAS_NBAT_V 2 // one is adc,another is Digital Voltage(iic or can) +#define BOARD_HAS_NBAT_I 2 // one is adc,another is Digital Current(iic or can) + +/* PX4FMU GPIOs ***********************************************************************************/ + +/* Trace Clock and D0-D3 are available on the trace connector + * + * TRACECLK PE2 - Dedicated - Trace Connector Pin 1 + * TRACED0 PE3 - nLED_RED - Trace Connector Pin 3 + * TRACED1 PE4 - nLED_GREEN - Trace Connector Pin 5 + * TRACED2 PE5 - nLED_BLUE - Trace Connector Pin 7 + * TRACED3 PE6 - nARMED - Trace Connector Pin 8 + + */ + +/* LEDs are driven with push open drain to support Anode to 5V or 3.3V or used as TRACE0-2 */ + +#if !defined(TRACE_PINS) +# define GPIO_nLED_RED /* PE3 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN3) +# define GPIO_nLED_GREEN /* PE4 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN4) +# define GPIO_nLED_BLUE /* PE5 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN5) + +# define BOARD_HAS_CONTROL_STATUS_LEDS 1 +# define BOARD_OVERLOAD_LED LED_RED +# define BOARD_ARMED_STATE_LED LED_BLUE + +#else + +# define GPIO_TRACECLK1 (GPIO_TRACECLK |GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN2) +# define GPIO_TRACED0 (GPIO_TRACED0_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN3) +# define GPIO_TRACED1 (GPIO_TRACED1_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN4) +# define GPIO_TRACED2 (GPIO_TRACED2_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN5) +# define GPIO_TRACED3 (GPIO_TRACED3_2|GPIO_PULLUP|GPIO_SPEED_100MHz|GPIO_PUSHPULL) //(GPIO_ALT|GPIO_AF0|GPIO_PORTE|GPIO_PIN6) +//#define GPIO_TRACESWO //(GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3) + +# undef BOARD_HAS_CONTROL_STATUS_LEDS +# undef BOARD_OVERLOAD_LED +# undef BOARD_ARMED_STATE_LED + +# define GPIO_nLED_RED GPIO_TRACED0 +# define GPIO_nLED_GREEN GPIO_TRACED1 +# define GPIO_nLED_BLUE GPIO_TRACED2 +# define GPIO_nARMED GPIO_TRACED3 +# define GPIO_nARMED_INIT GPIO_TRACED3 +#endif + +/* I2C busses */ + +/* Devices on the onboard buses. + * + * Note that these are unshifted addresses. + */ +#define BOARD_MTD_NUM_EEPROM 2 /* MTD: base_eeprom, imu_eeprom*/ + +#define PX4_I2C_OBDEV_SE050 0x48 + +#define GPIO_I2C2_DRDY1_BMP388 /* PG5 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN5) + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ + +#define ADC1_CH(n) (n) + +/* N.B. there is no offset mapping needed for ADC3 because */ +#define ADC3_CH(n) (n) + +/* We are only use ADC3 for REV/VER. + * ADC3_6V6 and ADC3_3V3 are mapped back to ADC1 + * To do this We are relying on PC2_C, PC3_C being connected to PC2, PC3 + * respectively by the SYSCFG_PMCR default of setting for PC3SO PC2SO PA1SO + * PA0SO of 0. + * + * 0 Analog switch closed (pads are connected through the analog switch) + * + * So ADC3_INP0 is GPIO_ADC123_INP12 + * ADC3_INP1 is GPIO_ADC12_INP13 + */ + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ + +#define PX4_ADC_GPIO \ + /* PA0 */ GPIO_ADC1_INP16, \ + /* PA4 */ GPIO_ADC12_INP18, \ + /* PB0 */ GPIO_ADC12_INP9, \ + /* PB1 */ GPIO_ADC12_INP5, \ + /* PC2 */ GPIO_ADC123_INP12, \ + /* PC3 */ GPIO_ADC12_INP13, \ + /* PF12 */ GPIO_ADC1_INP6, \ + /* PH3 */ GPIO_ADC3_INP14, \ + /* PH4 */ GPIO_ADC3_INP15 + +/* Define Channel numbers must match above GPIO pin IN(n)*/ + +#define ADC_BATTERY_VOLTAGE_CHANNEL /* PF12 */ ADC1_CH(6) +#define ADC_BATTERY_CURRENT_CHANNEL /* PB0 */ ADC1_CH(9) +#define ADC_SCALED_VDD_3V3_SENSORS1_CHANNEL /* PA0 */ ADC1_CH(16) +#define ADC_SCALED_VDD_3V3_SENSORS2_CHANNEL /* PA4 */ ADC1_CH(18) +#define ADC_SCALED_V5_CHANNEL /* PB1 */ ADC1_CH(5) +#define ADC_ADC3_6V6_CHANNEL /* PC2 */ ADC3_CH(12) +#define ADC_ADC3_3V3_CHANNEL /* PC3 */ ADC3_CH(13) +#define ADC_HW_VER_SENSE_CHANNEL /* PH3 */ ADC3_CH(14) +#define ADC_HW_REV_SENSE_CHANNEL /* PH4 */ ADC3_CH(15) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL) | \ + (1 << ADC_SCALED_VDD_3V3_SENSORS1_CHANNEL) | \ + (1 << ADC_SCALED_V5_CHANNEL) | \ + (1 << ADC_ADC3_6V6_CHANNEL) | \ + (1 << ADC_ADC3_3V3_CHANNEL)) | \ + (1 << ADC_SCALED_VDD_3V3_SENSORS2_CHANNEL) + + +/* HW has to large of R termination on ADC todo:change when HW value is chosen */ + +#define HW_REV_VER_ADC_BASE STM32_ADC3_BASE + +#define SYSTEM_ADC_BASE STM32_ADC1_BASE + +/* HW has to large of R termination on ADC todo:change when HW value is chosen */ +#define BOARD_ADC_OPEN_CIRCUIT_V (5.6f) + +// // /* HW Version and Revision drive signals Default to 1 to detect */ +// #define BOARD_HAS_HW_SPLIT_VERSIONING + +#define BOARD_HAS_STATIC_MANIFEST 1 + +#define PX4_MFT_HW_SUPPORTED_PX4_MFT_CAN2 1 + +#define GPIO_HW_VER_REV_DRIVE /* PG0 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN0) +#define GPIO_HW_REV_SENSE /* PH4 */ GPIO_ADC3_INP15 +#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14 + +#define UAVCAN_NUM_IFACES_RUNTIME 1 + +/* HEATER + * PWM in future + */ +#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10) +#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true)) + +/* PE6 is nARMED + * The GPIO will be set as input while not armed HW will have external HW Pull UP. + * While armed it shall be configured at a GPIO OUT set LOW + */ +#if !defined(TRACE_PINS) +#define GPIO_nARMED_INIT /* PE6 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN6) +#define GPIO_nARMED /* PE6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6) +#define BOARD_INDICATE_EXTERNAL_LOCKOUT_STATE(enabled) px4_arch_configgpio((enabled) ? GPIO_nARMED : GPIO_nARMED_INIT) +#define BOARD_GET_EXTERNAL_LOCKOUT_STATE() px4_arch_gpioread(GPIO_nARMED) +#endif + + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 9 + +/* PWM Power */ +#define GPIO_PWM_VOLT_SEL /* PG6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN6) +#define PWM_5V_VOLT_SEL(on_true) px4_arch_gpiowrite(GPIO_PWM_VOLT_SEL, (on_true)) + +/* Power supply control and monitoring GPIOs */ + +#define GPIO_nPOWER_IN_A /* PG1 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN1) +#define GPIO_nPOWER_IN_B /* PG2 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN2) +#define GPIO_nPOWER_IN_C /* PG3 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN3) + +#define GPIO_nVDD_BRICK1_VALID GPIO_nPOWER_IN_A /* Brick 1 Is Chosen */ +#define GPIO_nVDD_BRICK2_VALID GPIO_nPOWER_IN_B /* Brick 2 Is Chosen */ +#define BOARD_NUMBER_BRICKS 1 +#define GPIO_nVDD_USB_VALID GPIO_nPOWER_IN_C /* USB Is Chosen */ + +#define GPIO_VDD_5V_PERIPH_nEN /* PG4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN4) +#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15) +#define GPIO_VDD_5V_HIPOWER_nEN /* PG10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10) +#define GPIO_VDD_5V_HIPOWER_nOC /* PF13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13) +#define GPIO_VDD_3V3_SENSORS4_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8) +#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2) +#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13) + +/* ETHERNET GPIO */ + +#define GPIO_ETH_POWER_EN /* PG15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN15) + +/* NFC GPIO */ + +#define GPIO_NFC_GPIO /* PC0 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTC|GPIO_PIN0) + + +/* Define True logic Power Control in arch agnostic form */ + +#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true)) +#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true)) +#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS4_EN, (on_true)) +#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true)) +#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN) +#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true)) +#define VDD_3V3_ETH_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_ETH_POWER_EN, (on_true)) + + +/* Tone alarm output */ + +#define TONE_ALARM_TIMER 14 /* Timer 14 */ +#define TONE_ALARM_CHANNEL 1 /* PF9 GPIO_TIM14_CH1OUT_2 */ + +#define GPIO_BUZZER_1 /* PF9 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN9) + +#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1 +#define GPIO_TONE_ALARM GPIO_TIM14_CH1OUT_2 + +/* USB OTG FS + * + * PA9 OTG_FS_VBUS VBUS sensing + */ +#define GPIO_OTGFS_VBUS /* PA9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN9) + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer8 for the HRT */ +#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */ + +#define HRT_PPM_CHANNEL /* T8C1 */ 1 /* use capture/compare channel 1 */ +#define GPIO_PPM_IN /* PI5 T8C1 */ GPIO_TIM8_CH1IN_2 + +/* RC Serial port */ + +#define RC_SERIAL_PORT "/dev/ttyS5" +#define RC_SERIAL_SINGLEWIRE + +/* Input Capture Channels. */ +#define INPUT_CAP1_TIMER 1 +#define INPUT_CAP1_CHANNEL /* T1C2 */ 2 +#define GPIO_INPUT_CAP1 /* PE11 */ GPIO_TIM1_CH2IN + +/* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2 */ +#define PWMIN_TIMER 4 +#define PWMIN_TIMER_CHANNEL /* T4C2 */ 2 +#define GPIO_PWM_IN /* PD13 */ GPIO_TIM4_CH2IN_2 + +/* Safety Switch is HW version dependent on having an PX4IO + * So we init to a benign state with the _INIT definition + * and provide the the non _INIT one for the driver to make a run time + * decision to use it. + */ +#define GPIO_nSAFETY_SWITCH_LED_OUT_INIT /* PD10 */ (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN10) +#define GPIO_nSAFETY_SWITCH_LED_OUT /* PD10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN10) + +/* Enable the FMU to control it if there is no px4io fixme:This should be BOARD_SAFETY_LED(__ontrue) */ +#define GPIO_LED_SAFETY GPIO_nSAFETY_SWITCH_LED_OUT + +#define GPIO_SAFETY_SWITCH_IN /* PF5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTF|GPIO_PIN5) +/* Enable the FMU to use the switch it if there is no px4io fixme:This should be BOARD_SAFTY_BUTTON() */ +#define GPIO_BTN_SAFETY GPIO_SAFETY_SWITCH_IN /* Enable the FMU to control it if there is no px4io */ + +/* Power switch controls ******************************************************/ + +#define SPEKTRUM_POWER(_on_true) VDD_3V3_SPEKTRUM_POWER_EN(_on_true) + +/* + * FMUv6X has a separate RC_IN + * + * GPIO PPM_IN on PI5 T8CH1 + * SPEKTRUM_RX (it's TX or RX in Bind) on UART6 PC7 + * Inversion is possible in the UART and can drive GPIO PPM_IN as an output + */ + +#define GPIO_PPM_IN_AS_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTI|GPIO_PIN5) +#define SPEKTRUM_RX_AS_GPIO_OUTPUT() px4_arch_configgpio(GPIO_PPM_IN_AS_OUT) +#define SPEKTRUM_RX_AS_UART() /* Can be left as uart */ +#define SPEKTRUM_OUT(_one_true) px4_arch_gpiowrite(GPIO_PPM_IN_AS_OUT, (_one_true)) + +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 + +/* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ + +#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +#endif + +/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction) + * this board support the ADC system_power interface, and therefore + * provides the true logic GPIO BOARD_ADC_xxxx macros. + */ +#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_OTGFS_VBUS)) +#define BOARD_ADC_USB_VALID (!px4_arch_gpioread(GPIO_nVDD_USB_VALID)) + +/* FMUv6X never powers off the Servo rail */ + +#define BOARD_ADC_SERVO_VALID (1) + + +#define BOARD_ADC_BRICK_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK1_VALID)) + +#define BOARD_ADC_PERIPH_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_PERIPH_nOC)) +#define BOARD_ADC_HIPOWER_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_HIPOWER_nOC)) + + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ + +#define BOARD_HAS_ON_RESET 1 + +#if defined(TRACE_PINS) +#define GPIO_TRACE \ + GPIO_TRACECLK1, \ + GPIO_TRACED0, \ + GPIO_TRACED1, \ + GPIO_TRACED2, \ + GPIO_TRACED3 +#else +#define GPIO_TRACE (GPIO_OUTPUT|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN2) +#endif + +#define PX4_GPIO_INIT_LIST { \ + GPIO_TRACE, \ + PX4_ADC_GPIO, \ + GPIO_HW_VER_REV_DRIVE, \ + GPIO_CAN1_TX, \ + GPIO_CAN1_RX, \ + GPIO_CAN2_TX, \ + GPIO_CAN2_RX, \ + GPIO_HEATER_OUTPUT, \ + GPIO_nPOWER_IN_A, \ + GPIO_nPOWER_IN_B, \ + GPIO_nPOWER_IN_C, \ + GPIO_VDD_5V_PERIPH_nEN, \ + GPIO_VDD_5V_PERIPH_nOC, \ + GPIO_VDD_5V_HIPOWER_nEN, \ + GPIO_VDD_5V_HIPOWER_nOC, \ + GPIO_VDD_3V3_SENSORS4_EN, \ + GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \ + GPIO_VDD_3V3_SD_CARD_EN, \ + GPIO_ETH_POWER_EN, \ + GPIO_NFC_GPIO, \ + GPIO_TONE_ALARM_IDLE, \ + GPIO_nSAFETY_SWITCH_LED_OUT_INIT, \ + GPIO_SAFETY_SWITCH_IN, \ + GPIO_nARMED_INIT, \ + GPIO_PWM_VOLT_SEL \ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define PX4_I2C_BUS_MTD 4,5 + + +#define BOARD_NUM_IO_TIMERS 5 + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void); + +/**************************************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the PX4FMU board. + * + ****************************************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/svehicle/e2/src/bootloader_main.c b/boards/svehicle/e2/src/bootloader_main.c new file mode 100644 index 0000000000..77df9e78bc --- /dev/null +++ b/boards/svehicle/e2/src/bootloader_main.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * + * Copyright (c) 2019-2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/svehicle/e2/src/can.c b/boards/svehicle/e2/src/can.c new file mode 100644 index 0000000000..1f4e1f28a3 --- /dev/null +++ b/boards/svehicle/e2/src/can.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file px4fmu_can.c + * + * Board-specific CAN functions. + */ + +#if !defined(CONFIG_CAN) + +#include + +#include "board_config.h" + + +__EXPORT +uint16_t board_get_can_interfaces(void) +{ + uint16_t enabled_interfaces = 0x3; + + if (!PX4_MFT_HW_SUPPORTED(PX4_MFT_CAN2)) { + enabled_interfaces &= ~(1 << 1); + } + + return enabled_interfaces; +} + +#else + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "chip.h" +#include "stm32_can.h" +#include "board_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} +#endif /* CONFIG_CAN */ diff --git a/boards/svehicle/e2/src/hw_config.h b/boards/svehicle/e2/src/hw_config.h new file mode 100644 index 0000000000..73d4ec88df --- /dev/null +++ b/boards/svehicle/e2/src/hw_config.h @@ -0,0 +1,128 @@ +/* + * hw_config.h + * + * Created on: May 17, 2015 + * Author: david_s5 + */ + +#ifndef HW_CONFIG_H_ +#define HW_CONFIG_H_ + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +//#define USE_VBUS_PULL_DOWN +#define INTERFACE_USART 1 +#define INTERFACE_USART_CONFIG "/dev/ttyS0,1500000" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 6110 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (15) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024)//1024 + +#define OSC_FREQ 16 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN +#define BOARD_LED_ON 0 +#define BOARD_LED_OFF 1 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +/* + * Uncommenting this allows to force the bootloader through + * a PWM output pin. As this can accidentally initialize + * an ESC prematurely, it is not recommended. This feature + * has not been used and hence defaults now to off. + * + * # define BOARD_FORCE_BL_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN14) + * # define BOARD_FORCE_BL_PIN_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) + * + * # define BOARD_POWER_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4) + * # define BOARD_POWER_ON 1 + * # define BOARD_POWER_OFF 0 + * # undef BOARD_POWER_PIN_RELEASE // Leave pin enabling Power - un comment to release (disable power) + * +*/ + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#endif /* HW_CONFIG_H_ */ diff --git a/boards/svehicle/e2/src/i2c.cpp b/boards/svehicle/e2/src/i2c.cpp new file mode 100644 index 0000000000..8a557078e0 --- /dev/null +++ b/boards/svehicle/e2/src/i2c.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusExternal(1), + initI2CBusExternal(2), + initI2CBusExternal(3), + initI2CBusInternal(4), +}; diff --git a/boards/svehicle/e2/src/init.c b/boards/svehicle/e2/src/init.c new file mode 100644 index 0000000000..585bb41d5e --- /dev/null +++ b/boards/svehicle/e2/src/init.c @@ -0,0 +1,276 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * PX4FMU-specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "board_config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + /* set the peripheral rails off */ + + VDD_5V_PERIPH_EN(false); + board_control_spi_sensors_power(false, 0xffff); + + /* wait for the peripheral rail to reach GND */ + usleep(ms * 1000); + syslog(LOG_DEBUG, "reset done, %d ms\n", ms); + + /* re-enable power */ + + /* switch the peripheral rail back on */ + board_control_spi_sensors_power(true, 0xffff); + VDD_5V_PERIPH_EN(true); + +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(io_timer_channel_get_gpio_output(i)); + } + + /* + * On resets invoked from system (not boot) ensure we establish a low + * output state on PWM pins to disarm the ESC and prevent the reset from potentially + * spinning up the motors. + */ + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void +stm32_boardinitialize(void) +{ + board_on_reset(-1); /* Reset PWM first thing */ + + /* configure LEDs */ + + board_autoled_initialize(); + + /* configure pins */ + + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure USB interfaces */ + + stm32_usbinitialize(); + + VDD_3V3_ETH_POWER_EN(true); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +__EXPORT int board_app_initialize(uintptr_t arg) +{ +#if !defined(BOOTLOADER) + + /* Power on Interfaces */ + VDD_3V3_SD_CARD_EN(true); + VDD_5V_PERIPH_EN(true); + VDD_5V_HIPOWER_EN(true); + VDD_3V3_SENSORS4_EN(true); + VDD_3V3_SPEKTRUM_POWER_EN(true); + + /* Need hrt running before using the ADC */ + + px4_platform_init(); + + // Use the default HW_VER_REV(0x0,0x0) for Ramtron + + stm32_spiinitialize(); + + /* Configure the HW based on the manifest */ + + px4_platform_configure(); + + /* Configure the Actual SPI interfaces (after we determined the HW version) */ + + stm32_spiinitialize(); + + board_spi_reset(10, 0xffff); + + /* Configure the DMA allocator */ + + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + +# if defined(SERIAL_HAVE_RXDMA) + // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event. + static struct hrt_call serial_dma_call; + hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL); +# endif + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_on(LED_GREEN); // Indicate Power. + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_RED); + } + + // Ensure Power is off for > 10 mS + usleep(15 * 1000); + VDD_3V3_SD_CARD_EN(true); + usleep(500 * 1000); + +# ifdef CONFIG_MMCSD + int ret = stm32_sdio_initialize(); + + if (ret != OK) { + led_on(LED_RED); + return ret; + } + +# endif /* CONFIG_MMCSD */ + +#endif /* !defined(BOOTLOADER) */ + + return OK; +} diff --git a/boards/svehicle/e2/src/led.c b/boards/svehicle/e2/src/led.c new file mode 100644 index 0000000000..bff4b09864 --- /dev/null +++ b/boards/svehicle/e2/src/led.c @@ -0,0 +1,235 @@ +/**************************************************************************** + * + * Copyright (c) 2013 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file px4fmu2_led.c + * + * PX4FMU LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +#ifdef CONFIG_ARCH_LEDS +static bool nuttx_owns_leds = true; +// B R S G +// 0 1 2 3 +static const uint8_t xlatpx4[] = {1, 2, 4, 0}; +# define xlat(p) xlatpx4[(p)] +static uint32_t g_ledmap[] = { + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE + GPIO_nLED_RED, // Indexed by BOARD_LED_RED + GPIO_nSAFETY_SWITCH_LED_OUT, // Indexed by LED_SAFETY by xlatpx4 +}; + +#else + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_BLUE, // Indexed by LED_BLUE + GPIO_nLED_RED, // Indexed by LED_RED, LED_AMBER + 0, // Indexed by LED_SAFETY (defaulted to an input) + GPIO_nLED_GREEN, // Indexed by LED_GREEN +}; + +#endif + +__EXPORT void led_init(void) +{ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on */ + + if (g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} + +#ifdef CONFIG_ARCH_LEDS +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + led_init(); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_HEAPALLOCATE: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_IRQSENABLED: + phy_set_led(BOARD_LED_BLUE, false); + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_STACKCREATED: + phy_set_led(BOARD_LED_GREEN, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, true); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, true); + phy_set_led(BOARD_LED_BLUE, true); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, true); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, true); + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (!nuttx_owns_leds) { + return; + } + + switch (led) { + default: + break; + + case LED_SIGNAL: + phy_set_led(BOARD_LED_GREEN, false); + break; + + case LED_INIRQ: + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_ASSERTION: + phy_set_led(BOARD_LED_RED, false); + phy_set_led(BOARD_LED_BLUE, false); + break; + + case LED_PANIC: + phy_set_led(BOARD_LED_RED, false); + break; + + case LED_IDLE : /* IDLE */ + phy_set_led(BOARD_LED_RED, false); + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/svehicle/e2/src/mtd.cpp b/boards/svehicle/e2/src/mtd.cpp new file mode 100644 index 0000000000..d6c8278a24 --- /dev/null +++ b/boards/svehicle/e2/src/mtd.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include +// KiB BS nB +static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32) + .bus_type = px4_mft_device_t::SPI, + .devid = SPIDEV_FLASH(0) +}; +static const px4_mft_device_t i2c3 = { // 24LC64T on Base 8K 32 X 256 + .bus_type = px4_mft_device_t::I2C, + .devid = PX4_MK_I2C_DEVID(3, 0x51) +}; +static const px4_mft_device_t i2c4 = { // 24LC64T on IMU 8K 32 X 256 + .bus_type = px4_mft_device_t::I2C, + .devid = PX4_MK_I2C_DEVID(4, 0x50) +}; + + +static const px4_mtd_entry_t fmum_fram = { + .device = &spi5, + .npart = 1, + .partd = { + { + .type = MTD_PARAMETERS, + .path = "/fs/mtd_params", + .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT)) + } + }, +}; + +static const px4_mtd_entry_t base_eeprom = { + .device = &i2c3, + .npart = 2, + .partd = { + { + .type = MTD_MFT_VER, + .path = "/fs/mtd_mft_ver", + .nblocks = 248 + }, + { + .type = MTD_NET, + .path = "/fs/mtd_net", + .nblocks = 8 // 256 = 32 * 8 + + } + }, +}; + +static const px4_mtd_entry_t imu_eeprom = { + .device = &i2c4, + .npart = 3, + .partd = { + { + .type = MTD_CALDATA, + .path = "/fs/mtd_caldata", + .nblocks = 240 + }, + { + .type = MTD_MFT_REV, + .path = "/fs/mtd_mft_rev", + .nblocks = 8 + }, + { + .type = MTD_ID, + .path = "/fs/mtd_id", + .nblocks = 8 // 256 = 32 * 8 + } + }, +}; + +static const px4_mtd_manifest_t board_mtd_config = { + .nconfigs = 3, + .entries = { + &fmum_fram, + &base_eeprom, + &imu_eeprom + } +}; + +static const px4_mft_entry_s mtd_mft = { + .type = MTD, + .pmft = (void *) &board_mtd_config, +}; + +static const px4_mft_s mft = { + .nmft = 1, + .mfts = { + &mtd_mft, + } +}; + +const px4_mft_s *board_get_manifest(void) +{ + return &mft; +} diff --git a/boards/svehicle/e2/src/sdio.c b/boards/svehicle/e2/src/sdio.c new file mode 100644 index 0000000000..869d757756 --- /dev/null +++ b/boards/svehicle/e2/src/sdio.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "board_config.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(GPIO_SDMMC1_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + + if (sdio_dev && present != g_sd_inserted) { + sdio_mediachange(sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDMMC1_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + sdio_dev = sdio_initialize(SDIO_SLOTNO); + + if (!sdio_dev) { + syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev); + + if (ret != OK) { + syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(sdio_dev, true); +#endif + + return OK; +} + +#endif /* CONFIG_MMCSD */ diff --git a/boards/svehicle/e2/src/spi.cpp b/boards/svehicle/e2/src/spi.cpp new file mode 100644 index 0000000000..d8609d65f8 --- /dev/null +++ b/boards/svehicle/e2/src/spi.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * + * Copyright (C) 2020, 2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, 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}), + }, {GPIO::PortF, GPIO::Pin4}), + initSPIBus(SPI::Bus::SPI3, { + initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}), + initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}), + }, {GPIO::PortE, GPIO::Pin7}), + initSPIBus(SPI::Bus::SPI5, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7}) + }), + initSPIBusExternal(SPI::Bus::SPI6, { + initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}), + initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}), + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/svehicle/e2/src/timer_config.cpp b/boards/svehicle/e2/src/timer_config.cpp new file mode 100644 index 0000000000..928f4916f0 --- /dev/null +++ b/boards/svehicle/e2/src/timer_config.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +/* Timer allocation + * + * TIM5_CH4 T FMU_CH1 + * TIM5_CH3 T FMU_CH2 + * TIM5_CH2 T FMU_CH3 + * TIM5_CH1 T FMU_CH4 + * + * TIM4_CH2 T FMU_CH5 + * TIM4_CH3 T FMU_CH6 + * + * TIM12_CH1 T FMU_CH7 + * TIM12_CH2 T FMU_CH8 + * + * TIM1_CH2 T FMU_CAP1 < Capture + * TIM1_CH3 T SPI2_DRDY2_ISM330_INT2 < Capture or GPIO INT + * TIM1_CH1 T SPIX_SYNC > Pulse or GPIO strobe + * + * TIM2_CH3 T HEATER > PWM OUT or GPIO + * + * TIM14_CH1 T BUZZER_1 - Driven by other driver + * TIM8_CH1_IN T FMU_PPM_INPUT - Sampled byt HRT by other driver + */ + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer5, DMA{DMA::Index1}), + initIOTimer(Timer::Timer4, DMA{DMA::Index1}), + initIOTimer(Timer::Timer12), + initIOTimer(Timer::Timer1), + initIOTimer(Timer::Timer2), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel4}, {GPIO::PortI, GPIO::Pin0}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel3}, {GPIO::PortH, GPIO::Pin12}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel2}, {GPIO::PortH, GPIO::Pin11}), + initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel1}, {GPIO::PortH, GPIO::Pin10}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel2}, {GPIO::PortD, GPIO::Pin13}), + initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel3}, {GPIO::PortD, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel1}, {GPIO::PortH, GPIO::Pin6}), + initIOTimerChannel(io_timers, {Timer::Timer12, Timer::Channel2}, {GPIO::PortH, GPIO::Pin9}), + initIOTimerChannelCapture(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/svehicle/e2/src/usb.c b/boards/svehicle/e2/src/usb.c new file mode 100644 index 0000000000..6d42476b71 --- /dev/null +++ b/boards/svehicle/e2/src/usb.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * + * Copyright (C) 2016 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file px4fmu_usb.c + * + * Board-specific USB functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include "board_config.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the PX4FMU board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ + +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/boards/thepeach/k1/default.px4board b/boards/thepeach/k1/default.px4board index d542a2c1b0..6eb341d697 100644 --- a/boards/thepeach/k1/default.px4board +++ b/boards/thepeach/k1/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/thepeach/r1/default.px4board b/boards/thepeach/r1/default.px4board index d542a2c1b0..6eb341d697 100644 --- a/boards/thepeach/r1/default.px4board +++ b/boards/thepeach/r1/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y CONFIG_DRIVERS_IRLOCK=y CONFIG_COMMON_LIGHT=y CONFIG_COMMON_MAGNETOMETER=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PCA9685_PWM_OUT=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y diff --git a/boards/uvify/core/default.px4board b/boards/uvify/core/default.px4board index 8c144aa606..fb7f41c76f 100644 --- a/boards/uvify/core/default.px4board +++ b/boards/uvify/core/default.px4board @@ -22,7 +22,6 @@ CONFIG_DRIVERS_LIGHTS_RGBLED_NCP5623C=y CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_INPUT=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y diff --git a/boards/x-mav/ap-h743r1/CMakeLists.txt b/boards/x-mav/ap-h743r1/CMakeLists.txt new file mode 100644 index 0000000000..8756f63e64 --- /dev/null +++ b/boards/x-mav/ap-h743r1/CMakeLists.txt @@ -0,0 +1,34 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_subdirectory(pwm_voltage) diff --git a/boards/x-mav/ap-h743r1/bootloader.px4board b/boards/x-mav/ap-h743r1/bootloader.px4board new file mode 100644 index 0000000000..cc68214fa3 --- /dev/null +++ b/boards/x-mav/ap-h743r1/bootloader.px4board @@ -0,0 +1,4 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_ROMFSROOT="" +CONFIG_ARCH_CHIP_STM32H7=y diff --git a/boards/x-mav/ap-h743r1/default.px4board b/boards/x-mav/ap-h743r1/default.px4board new file mode 100644 index 0000000000..031e7520f4 --- /dev/null +++ b/boards/x-mav/ap-h743r1/default.px4board @@ -0,0 +1,92 @@ +CONFIG_BOARD_TOOLCHAIN="arm-none-eabi" +CONFIG_BOARD_ARCHITECTURE="cortex-m7" +CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" +CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS1" +CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS2" +CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS3" +CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS5" +CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS6" +CONFIG_DRIVERS_ADC_BOARD_ADC=y +CONFIG_DRIVERS_BAROMETER_DPS310=y +CONFIG_DRIVERS_BAROMETER_GOERTEK_SPL06=y +CONFIG_DRIVERS_CAMERA_CAPTURE=y +CONFIG_DRIVERS_CAMERA_TRIGGER=y +CONFIG_DRIVERS_CDCACM_AUTOSTART=y +CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y +CONFIG_DRIVERS_DISTANCE_SENSOR_TF02PRO=y +CONFIG_DRIVERS_DISTANCE_SENSOR_TFMINI=y +CONFIG_DRIVERS_DSHOT=y +CONFIG_DRIVERS_GPS=y +CONFIG_DRIVERS_IMU_BOSCH_BMI270=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y +CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y +CONFIG_DRIVERS_MAGNETOMETER_QMC5883P=y +CONFIG_COMMON_OSD=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_DRIVERS_PX4IO=y +CONFIG_COMMON_RC=y +CONFIG_COMMON_TELEMETRY=y +CONFIG_DRIVERS_TONE_ALARM=y +CONFIG_DRIVERS_UAVCAN=y +CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=4 +CONFIG_MODULES_BATTERY_STATUS=y +CONFIG_MODULES_CAMERA_FEEDBACK=y +CONFIG_MODULES_COMMANDER=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +CONFIG_MODULES_EKF2=y +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_FLIGHT_MODE_MANAGER=y +CONFIG_MODULES_FW_ATT_CONTROL=y +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=y +CONFIG_MODULES_FW_MODE_MANAGER=y +CONFIG_MODULES_FW_RATE_CONTROL=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_GYRO_CALIBRATION=y +CONFIG_MODULES_GYRO_FFT=y +CONFIG_MODULES_LAND_DETECTOR=y +CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y +CONFIG_MODULES_LOGGER=y +CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y +CONFIG_MODULES_MANUAL_CONTROL=y +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_MC_ATT_CONTROL=y +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y +CONFIG_MODULES_MC_POS_CONTROL=y +CONFIG_MODULES_MC_RATE_CONTROL=y +CONFIG_MODULES_NAVIGATOR=y +CONFIG_MODULES_RC_UPDATE=y +CONFIG_MODULES_SENSORS=y +CONFIG_MODULES_TEMPERATURE_COMPENSATION=y +CONFIG_MODULES_VTOL_ATT_CONTROL=y +CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y +CONFIG_SYSTEMCMDS_BL_UPDATE=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_DUMPFILE=y +CONFIG_SYSTEMCMDS_GPIO=y +CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_LED_CONTROL=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SD_STRESS=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_TUNE_CONTROL=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_USB_CONNECTED=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y +CONFIG_EXAMPLES_FAKE_GPS=y +CONFIG_ARCH_CHIP_STM32H7=y diff --git a/boards/x-mav/ap-h743r1/extras/px4_io-v2_default.bin b/boards/x-mav/ap-h743r1/extras/px4_io-v2_default.bin new file mode 100644 index 0000000000..145089ae0d Binary files /dev/null and b/boards/x-mav/ap-h743r1/extras/px4_io-v2_default.bin differ diff --git a/boards/x-mav/ap-h743r1/extras/x-mav_ap-h743r1_bootloader.bin b/boards/x-mav/ap-h743r1/extras/x-mav_ap-h743r1_bootloader.bin new file mode 100755 index 0000000000..0082f4f805 Binary files /dev/null and b/boards/x-mav/ap-h743r1/extras/x-mav_ap-h743r1_bootloader.bin differ diff --git a/boards/x-mav/ap-h743r1/firmware.prototype b/boards/x-mav/ap-h743r1/firmware.prototype new file mode 100644 index 0000000000..81aeb5622b --- /dev/null +++ b/boards/x-mav/ap-h743r1/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 1203, + "magic": "PX4FWv1", + "description": "Firmware for the AP-H743r1 board", + "image": "", + "build_time": 0, + "summary": "AP-H743r1", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1966080, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/x-mav/ap-h743r1/init/rc.board_defaults b/boards/x-mav/ap-h743r1/init/rc.board_defaults new file mode 100644 index 0000000000..af3cd672e1 --- /dev/null +++ b/boards/x-mav/ap-h743r1/init/rc.board_defaults @@ -0,0 +1,29 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ +param set-default BAT1_A_PER_V 17 +param set-default BAT1_N_CELLS 4 +param set-default BAT1_V_CHARGED 4.2 +param set-default BAT1_V_DIV 10.1 +param set-default BAT1_V_EMPTY 3.2 + +param set-default SYS_HAS_MAG 1 +param set-default PWM_MAIN_TIM0 -4 +param set-default RC_INPUT_PROTO -1 + +param set-default IMU_GYRO_RATEMAX 2000 +param set-default SYS_AUTOSTART 4001 +param set-default MC_PITCHRATE_K 0.4 +param set-default MC_ROLLRATE_K 0.35 +param set-default MC_YAWRATE_K 1.2 +param set-default MC_YAWRATE_MAX 360 +param set-default MAV_TYPE 2 +param set-default CA_AIRFRAME 0 +param set-default CA_ROTOR_COUNT 4 +param set-default CBRK_SUPPLY_CHK 894281 + +param set-default USB_MAV_MODE 5 + +# pwm voltage 3.3V/5V switch +pwm_voltage_apply start diff --git a/boards/x-mav/ap-h743r1/init/rc.board_extras b/boards/x-mav/ap-h743r1/init/rc.board_extras new file mode 100644 index 0000000000..cccb4ed416 --- /dev/null +++ b/boards/x-mav/ap-h743r1/init/rc.board_extras @@ -0,0 +1,4 @@ +#!/bin/sh +# +# board specific extras init +#------------------------------------------------------------------------------ diff --git a/boards/x-mav/ap-h743r1/init/rc.board_sensors b/boards/x-mav/ap-h743r1/init/rc.board_sensors new file mode 100644 index 0000000000..d34c45e4c4 --- /dev/null +++ b/boards/x-mav/ap-h743r1/init/rc.board_sensors @@ -0,0 +1,26 @@ +#!/bin/sh +# +# board specific sensors init +#------------------------------------------------------------------------------ + +board_adc start + +# IMU +if ! icm42688p -s -b 1 -R 4 start +then + bmi270 -s -b 1 -R 2 start +fi + +if ! icm42688p -s -b 4 -R 4 start +then + bmi270 -s -b 4 -R 2 start +fi + +# baro +if ! dps310 -I start -a 0x76 +then + spl06 -I start -a 0x76 +fi + +# internal mag +qmc5883p -I -R 4 start diff --git a/boards/x-mav/ap-h743r1/nuttx-config/Kconfig b/boards/x-mav/ap-h743r1/nuttx-config/Kconfig new file mode 100644 index 0000000000..bb33d3cfda --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# +config BOARD_HAS_PROBES + bool "Board provides GPIO or other Hardware for signaling to timing analyze." + default y + ---help--- + This board provides GPIO FMU-CH1-5, CAP1-6 as PROBE_1-11 to provide timing signals from selected drivers. + +config BOARD_USE_PROBES + bool "Enable the use the board provided FMU-CH1-5, CAP1-6 as PROBE_1-11" + default n + depends on BOARD_HAS_PROBES + + ---help--- + Select to use GPIO FMU-CH1-5, CAP1-6 to provide timing signals from selected drivers. diff --git a/boards/x-mav/ap-h743r1/nuttx-config/bootloader/defconfig b/boards/x-mav/ap-h743r1/nuttx-config/bootloader/defconfig new file mode 100644 index 0000000000..b4128c5932 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/bootloader/defconfig @@ -0,0 +1,90 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_SPI_EXCHANGE is not set +# CONFIG_STM32H7_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/x-mav/ap-h743r1/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARDCTL=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_INITTHREAD_PRIORITY=254 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0036 +CONFIG_CDCACM_PRODUCTSTR="X-MAV AP-H743r1 Bootloader" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1B8C +CONFIG_CDCACM_VENDORSTR="X-MAV" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXPERIMENTAL=y +CONFIG_FDCLONE_DISABLE=y +CONFIG_FDCLONE_STDIO=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="bootloader_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SPI=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_USART6=y +CONFIG_SYSTEMTICK_HOOK=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TTY_SIGINT=y +CONFIG_TTY_SIGINT_CHAR=0x03 +CONFIG_TTY_SIGTSTP=y +CONFIG_USART6_RXBUFSIZE=600 +CONFIG_USART6_TXBUFSIZE=300 +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/x-mav/ap-h743r1/nuttx-config/include/board.h b/boards/x-mav/ap-h743r1/nuttx-config/include/board.h new file mode 100644 index 0000000000..e6ff9ec362 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/include/board.h @@ -0,0 +1,442 @@ +/************************************************************************************ + * nuttx-configs/px4_fmu-v6u/include/board.h + * + * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved. + * Authors: David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ +#ifndef __NUTTX_CONFIG_APH743R1_INCLUDE_BOARD_H +#define __NUTTX_CONFIG_APH743R1_INCLUDE_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "board_dma_map.h" + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "stm32_rcc.h" +#include "stm32_sdmmc.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* The AP-H743 R1 board provides the following clock sources: + * + * X1: 8 MHz crystal for HSE + * + * So we have these clock source available within the STM32 + * + * HSI: 16 MHz RC factory-trimmed + * HSE: 16 MHz crystal for HSE + */ + +#define STM32_BOARD_XTAL 8000000ul + +#define STM32_HSI_FREQUENCY 16000000ul +#define STM32_LSI_FREQUENCY 32000 +#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL +#define STM32_LSE_FREQUENCY 32768 + +/* Main PLL Configuration. + * + * PLL source is HSE = 16,000,000 + * + * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN + * Subject to: + * + * 1 <= PLLM <= 63 + * 4 <= PLLN <= 512 + * 150 MHz <= PLL_VCOL <= 420MHz + * 192 MHz <= PLL_VCOH <= 836MHz + * + * SYSCLK = PLL_VCO / PLLP + * CPUCLK = SYSCLK / D1CPRE + * Subject to + * + * PLLP1 = {2, 4, 6, 8, ..., 128} + * PLLP2,3 = {2, 3, 4, ..., 128} + * CPUCLK <= 480 MHz + */ + +#define STM32_BOARD_USEHSE + +#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE + +/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (8,000,000 / 1) * 120 = 960 MHz + * + * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz + * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz + * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz + */ + +#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP1EN | \ + RCC_PLLCFGR_DIVQ1EN | \ + RCC_PLLCFGR_DIVR1EN) +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(120) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) + +#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 120) +#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) +#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) +#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) + +/* PLL2 */ + +#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN) +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2) + +#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2) + +/* PLL3 */ + +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE | \ + RCC_PLLCFGR_PLL3RGE_4_8_MHZ | \ + RCC_PLLCFGR_DIVQ3EN) +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(2) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2) + +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2) + +/* SYSCLK = PLL1P = 480MHz + * CPUCLK = SYSCLK / 1 = 480 MHz + */ + +#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) +#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) +#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) + +/* Configure Clock Assignments */ + +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) + * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240 + */ + +#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ +#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ +#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ +#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */ + +/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */ +#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */ +#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */ + +#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */ +#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* APB4 clock (PCLK4) is HCLK/4 (120 MHz) */ + +#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */ +#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2) + +/* Timer clock frequencies */ + +/* Timers driven from APB1 will be twice PCLK1 */ + +#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) +#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) + +/* Timers driven from APB2 will be twice PCLK2 */ + +#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) +#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) + +/* Kernel Clock Configuration + * + * Note: look at Table 54 in ST Manual + */ + +/* I2C123 clock source */ + +#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI + +/* I2C4 clock source */ + +#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI + +/* SPI123 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 + +/* SPI45 clock source */ + +#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 + +/* SPI6 clock source */ + +#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 + +/* USB 1 and 2 clock source */ + +#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 + +/* ADC 1 2 3 clock source */ + +#define STM32_RCC_D3CCIPR_ADCSEL RCC_D3CCIPR_ADCSEL_PLL2 + +/* FDCAN 1 clock source */ + +// #define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE /* FDCAN 1 2 clock source */ + +#define STM32_FDCANCLK STM32_HSE_FREQUENCY + +/* FLASH wait states + * + * ------------ ---------- ----------- + * Vcore MAX ACLK WAIT STATES + * ------------ ---------- ----------- + * 1.15-1.26 V 70 MHz 0 + * (VOS1 level) 140 MHz 1 + * 210 MHz 2 + * 1.05-1.15 V 55 MHz 0 + * (VOS2 level) 110 MHz 1 + * 165 MHz 2 + * 220 MHz 3 + * 0.95-1.05 V 45 MHz 0 + * (VOS3 level) 90 MHz 1 + * 135 MHz 2 + * 180 MHz 3 + * 225 MHz 4 + * ------------ ---------- ----------- + */ + +#define BOARD_FLASH_WAITSTATES 2 + +/* SDMMC definitions ********************************************************/ + +/* Init 400kHz, freq = PLL1Q/(2*div) div = PLL1Q/(2*freq) */ + +#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq) + * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s + */ + +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif +#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA) +# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE + +/* LED definitions ******************************************************************/ +/* The board has two, LED_GREEN a Green LED and LED_BLUE a Blue LED, + * that can be controlled by software. + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way. + * The following definitions are used to access individual LEDs. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED1 0 +#define BOARD_LED2 1 +#define BOARD_LED3 2 +#define BOARD_NLEDS 3 + +#define BOARD_LED_RED BOARD_LED1 +#define BOARD_LED_GREEN BOARD_LED2 +#define BOARD_LED_BLUE BOARD_LED3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in + * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related + * events as follows: + * + * + * SYMBOL Meaning LED state + * Red Green Blue + * ---------------------- -------------------------- ------ ------ ----*/ + +#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */ +#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */ +#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */ +#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */ +#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */ +#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */ + +/* Thus if the Green LED is statically on, NuttX has successfully booted and + * is, apparently, running normally. If the Red LED is flashing at + * approximately 2Hz, then a fatal error has been detected and the system + * has halted. + */ + +/* Alternate function pin selections ************************************************/ + +#define GPIO_USART1_RX GPIO_USART1_RX_2 /* PA10 */ +#define GPIO_USART1_TX GPIO_USART1_TX_2 /* PA9 */ + +#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ +#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ + +#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PD9 */ +#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PD8 */ + +#define GPIO_UART4_RX GPIO_UART4_RX_3 /* PB8 */ +#define GPIO_UART4_TX GPIO_UART4_TX_3 /* PB9 */ + +#define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ +#define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ + +#define GPIO_UART7_RX GPIO_UART7_RX_3 /* PE7 */ +#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */ + +#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */ +#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */ + +/* SPI + * + */ +#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_2MHz)) + +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1 /* PA7 */ +#define GPIO_SPI1_SCK ADJ_SLEW_RATE(GPIO_SPI1_SCK_1) /* PA5 */ + +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 /* PC11 */ +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2 /* PC12 */ +#define GPIO_SPI3_SCK ADJ_SLEW_RATE(GPIO_SPI3_SCK_2) /* PC10 */ + +#define GPIO_SPI4_MISO GPIO_SPI4_MISO_2 /* PE5 */ +#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_2 /* PE6 */ +#define GPIO_SPI4_SCK ADJ_SLEW_RATE(GPIO_SPI4_SCK_2) /* PE2 */ + +/* I2C + * + */ +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +#define GPIO_I2C1_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN6) +#define GPIO_I2C1_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN7) + +#define GPIO_I2C2_SCL GPIO_I2C2_SCL_1 /* PB10 */ +#define GPIO_I2C2_SDA GPIO_I2C2_SDA_1 /* PB11 */ + +#define GPIO_I2C2_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN10) +#define GPIO_I2C2_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN11) + + +#define GPIO_I2C4_SCL GPIO_I2C4_SCL_1 /* PD12 */ +#define GPIO_I2C4_SDA GPIO_I2C4_SDA_1 /* PD13 */ + +#define GPIO_I2C4_SCL_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN12) +#define GPIO_I2C4_SDA_GPIO (GPIO_OUTPUT | GPIO_OPENDRAIN |GPIO_SPEED_2MHz | GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN13) + +#define GPIO_CAN1_RX GPIO_CAN1_RX_3 /* PD0 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_3 /* PD1 */ + +#define GPIO_CAN2_RX GPIO_CAN2_RX_1 /* PB12 */ +#define GPIO_CAN2_TX GPIO_CAN2_TX_1 /* PB13 */ + +/* SDMMC2 + * + * VDD 3.3 + * GND + * SDMMC2_CK PD6 + * SDMMC2_CMD PD7 + * SDMMC2_D0 PB14 + * SDMMC2_D1 PB15 + * SDMMC2_D2 PG11 + * SDMMC2_D3 PB4 + */ + +#define GPIO_SDMMC2_CK GPIO_SDMMC2_CK_2 /* PC1 */ +#define GPIO_SDMMC2_CMD GPIO_SDMMC2_CMD_1 /* PD7 */ +// #define GPIO_SDMMC2_D0 GPIO_SDMMC2_D0 /* PB14 */ +// #define GPIO_SDMMC2_D1 GPIO_SDMMC2_D1 /* PB15 */ +#define GPIO_SDMMC2_D2 GPIO_SDMMC2_D2_2 /* PB3 */ +// #define GPIO_SDMMC2_D3 GPIO_SDMMC2_D3 /* PB4 */ + + +#endif /*__NUTTX_CONFIG_APH743R1_INCLUDE_BOARD_H */ diff --git a/boards/x-mav/ap-h743r1/nuttx-config/include/board_dma_map.h b/boards/x-mav/ap-h743r1/nuttx-config/include/board_dma_map.h new file mode 100644 index 0000000000..33219bffc1 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/include/board_dma_map.h @@ -0,0 +1,61 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +// DMAMUX1 Using at most 8 Channels on DMA1 -------- Assigned +// V + +#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* 1 DMA1:37 IMU */ +#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* 2 DMA1:38 IMU */ + +#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* DMA1:39 */ +#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* DMA1:40 */ + +#define DMAMAP_SPI4_RX DMAMAP_DMA12_SPI4RX_1 /* 3 DMA2:83 IMU */ +#define DMAMAP_SPI4_TX DMAMAP_DMA12_SPI4TX_1 /* 4 DMA2:84 IMU */ + +// #define DMAMAP_USART1_RX DMAMAP_DMA12_USART1RX_0 /* DMA1:41 GPS1 */ +// #define DMAMAP_USART1_TX DMAMAP_DMA12_USART1TX_0 /* DMA1:42 GPS1 */ + +// #define DMAMAP_USART2_RX DMAMAP_DMA12_USART2RX_0 /* DMA1:43 GPS2 */ +// #define DMAMAP_USART2_TX DMAMAP_DMA12_USART2TX_0 /* DMA1:44 GPS2 */ + +#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_0 /* DMA1:45 TELEM1 */ +#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_0 /* DMA1:46 TELEM1 */ + +#define DMAMAP_UART4_RX DMAMAP_DMA12_UART4RX_1 /* DMA2:63 TELEM2 */ +#define DMAMAP_UART4_TX DMAMAP_DMA12_UART4TX_1 /* DMA2:64 TELEM2 */ + +#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 /* DMA1:71 PX4IO */ +#define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 /* DMA1:72 PX4IO */ diff --git a/boards/x-mav/ap-h743r1/nuttx-config/nsh/defconfig b/boards/x-mav/ap-h743r1/nuttx-config/nsh/defconfig new file mode 100644 index 0000000000..dc9d2800d1 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/nsh/defconfig @@ -0,0 +1,269 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_EXPORT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOOPS is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_SOURCE is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/x-mav/ap-h743r1/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="px4" +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_INTERRUPTSTACK=768 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_BASEPRI_WAR=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_MEMCPY=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_ARM_MPU_EARLY_RESET=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_ASSERT_RESET_VALUE=0 +CONFIG_BOARD_CRASHDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=95150 +CONFIG_BOARD_RESET_ON_ASSERT=2 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_IFLOWCONTROL=y +CONFIG_CDCACM_PRODUCTID=0x0036 +CONFIG_CDCACM_PRODUCTSTR="X-MAV AP-H743r1" +CONFIG_CDCACM_RXBUFSIZE=600 +CONFIG_CDCACM_TXBUFSIZE=12000 +CONFIG_CDCACM_VENDORID=0x1B8C +CONFIG_CDCACM_VENDORSTR="X-MAV" +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_HARDFAULT_ALERT=y +CONFIG_DEBUG_MEMFAULT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FDCLONE_STDIO=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y +CONFIG_FS_PROCFS_MAX_TASKS=64 +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_I2C_RESET=y +CONFIG_IDLETHREAD_STACKSIZE=750 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3194 +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_NCHAINS=24 +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_LONG_LONG=y +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_LIBC_STRERROR=y +CONFIG_MEMSET_64BIT=y +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_IOB=y +CONFIG_MM_REGIONS=4 +CONFIG_MTD=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_PROGMEM=y +CONFIG_MTD_RAMTRON=y +CONFIG_NAME_MAX=40 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_STRERROR=y +CONFIG_NSH_VARS=y +CONFIG_OTG_ID_GPIO_DISABLE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_ROBUST=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_RAMTRON_SETSPEED=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_RTC_DATETIME=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIORITY=50 +CONFIG_SCHED_LPWORKSTACKSIZE=1632 +CONFIG_SCHED_WAITPID=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=4 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=256 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC2=y +CONFIG_STM32H7_ADC3=y +CONFIG_STM32H7_BBSRAM=y +CONFIG_STM32H7_BBSRAM_FILES=5 +CONFIG_STM32H7_BDMA=y +CONFIG_STM32H7_BKPSRAM=y +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_DMA2=y +CONFIG_STM32H7_DMACAPABLE=y +CONFIG_STM32H7_FLASH_OVERRIDE_I=y +CONFIG_STM32H7_FLOWCONTROL_BROKEN=y +CONFIG_STM32H7_I2C1=y +CONFIG_STM32H7_I2C2=y +CONFIG_STM32H7_I2C4=y +CONFIG_STM32H7_I2C_DYNTIMEO=y +CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10 +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PROGMEM=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_RTC_HSECLOCK=y +CONFIG_STM32H7_RTC_MAGIC_REG=1 +CONFIG_STM32H7_SAVE_CRASHDUMP=y +CONFIG_STM32H7_SDMMC2=y +CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y +CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y +CONFIG_STM32H7_SPI1=y +CONFIG_STM32H7_SPI1_DMA=y +CONFIG_STM32H7_SPI1_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI3=y +CONFIG_STM32H7_SPI4=y +CONFIG_STM32H7_SPI4_DMA=y +CONFIG_STM32H7_SPI4_DMA_BUFFER=4096 +CONFIG_STM32H7_SPI_DMATHRESHOLD=8 +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM2=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM4=y +CONFIG_STM32H7_TIM8=y +CONFIG_STM32H7_UART4=y +CONFIG_STM32H7_UART7=y +CONFIG_STM32H7_UART8=y +CONFIG_STM32H7_USART1=y +CONFIG_STM32H7_USART2=y +CONFIG_STM32H7_USART3=y +CONFIG_STM32H7_USART6=y +CONFIG_STM32H7_USART_BREAKS=y +CONFIG_STM32H7_USART_INVERT=y +CONFIG_STM32H7_USART_SINGLEWIRE=y +CONFIG_STM32H7_USART_SWAP=y +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART4_BAUD=921600 +CONFIG_UART4_RXBUFSIZE=3000 +CONFIG_UART4_RXDMA=y +CONFIG_UART4_TXBUFSIZE=3000 +CONFIG_UART4_TXDMA=y +CONFIG_UART7_BAUD=57600 +CONFIG_UART7_RXBUFSIZE=600 +CONFIG_UART7_TXBUFSIZE=3000 +CONFIG_UART8_BAUD=57600 +CONFIG_UART8_RXBUFSIZE=600 +CONFIG_UART8_SERIAL_CONSOLE=y +CONFIG_UART8_TXBUFSIZE=3000 +CONFIG_USART1_BAUD=57600 +CONFIG_USART1_RXBUFSIZE=600 +CONFIG_USART1_TXBUFSIZE=1500 +CONFIG_USART2_BAUD=57600 +CONFIG_USART2_RXBUFSIZE=600 +CONFIG_USART2_TXBUFSIZE=3000 +CONFIG_USART3_BAUD=57600 +CONFIG_USART3_RXBUFSIZE=180 +CONFIG_USART3_RXDMA=y +CONFIG_USART3_TXBUFSIZE=1500 +CONFIG_USART3_TXDMA=y +CONFIG_USART6_BAUD=57600 +CONFIG_USART6_RXBUFSIZE=600 +CONFIG_USART6_RXDMA=y +CONFIG_USART6_TXBUFSIZE=1500 +CONFIG_USART6_TXDMA=y +CONFIG_USBDEV=y +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USEC_PER_TICK=1000 +CONFIG_WATCHDOG=y +CONFIG_WQUEUE_NOTIFIER=y diff --git a/boards/x-mav/ap-h743r1/nuttx-config/scripts/bootloader_script.ld b/boards/x-mav/ap-h743r1/nuttx-config/scripts/bootloader_script.ld new file mode 100644 index 0000000000..abd27222b9 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/scripts/bootloader_script.ld @@ -0,0 +1,213 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The X-MAV AP-H743-R1 uses an STM32H743VIT6 has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743VIT6, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * The AP-H743-R1 has a Button on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the button has been pressed, + * then the boot will be from 0x1FF0:0000 + * + * The STM32H743VIT6 also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K + sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K + sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K + sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K + sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K + bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > flash + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/x-mav/ap-h743r1/nuttx-config/scripts/script.ld b/boards/x-mav/ap-h743r1/nuttx-config/scripts/script.ld new file mode 100644 index 0000000000..ace39a1bd7 --- /dev/null +++ b/boards/x-mav/ap-h743r1/nuttx-config/scripts/script.ld @@ -0,0 +1,228 @@ +/**************************************************************************** + * scripts/script.ld + * + * Copyright (C) 2020 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* The board uses an STM32H743VIT6 and has 2048Kb of main FLASH memory. + * The flash memory is partitioned into a User Flash memory and a System + * Flash memory. Each of these memories has two banks: + * + * 1) User Flash memory: + * + * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each + * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each + * + * 2) System Flash memory: + * + * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector + * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector + * + * 3) User option bytes for user configuration, only in Bank 1. + * + * In the STM32H743VIT6, two different boot spaces can be selected through + * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and + * BOOT_ADD1 option bytes: + * + * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0]. + * ST programmed value: Flash memory at 0x0800:0000 + * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0]. + * ST programmed value: System bootloader at 0x1FF0:0000 + * + * There's a button on board, the BOOT0 pin is at ground so by default, + * the STM32 will boot to address 0x0800:0000 in FLASH unless the switch is + * drepresed, then the boot will be from 0x1FF0:0000 + * + * The STM32H743VIT6 also has 1024Kb of data SRAM. + * SRAM is split up into several blocks and into three power domains: + * + * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with + * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus + * + * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000 + * + * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit + * DTCM ports. The DTCM-RAM could be used for critical real-time + * data, such as interrupt service routines or stack / heap memory. + * Both DTCM-RAMs can be used in parallel (for load/store operations) + * thanks to the Cortex-M7 dual issue capability. + * + * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000 + * + * This RAM is connected to ITCM 64-bit interface designed for + * execution of critical real-times routines by the CPU. + * + * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA + * through D1 domain AXI bus matrix + * + * 2.1) 512Kb of SRAM beginning at address 0x2400:0000 + * + * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA + * through D2 domain AHB bus matrix + * + * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000 + * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000 + * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000 + * + * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000 + * + * 4) AHB SRAM (D3 domain) accessible by most of system masters + * through D3 domain AHB bus matrix + * + * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000 + * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000 + * + * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000 + * where the code expects to begin execution by jumping to the entry point in + * the 0x0800:0000 address range. + */ + +MEMORY +{ + ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1920K + + DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K + AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */ + SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */ + SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */ + SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */ + BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +/* + * Ensure that abort() is present in the final object. The exception handling + * code pulled in by libgcc.a requires it (and that code cannot be easily avoided). + */ +EXTERN(abort) +EXTERN(_bootdelay_signature) + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + . = ALIGN(32); + /* + This signature provides the bootloader with a way to delay booting + */ + _bootdelay_signature = ABSOLUTE(.); + FILL(0xffecc2925d7d05c5) + . += 8; + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + + } > FLASH + + /* + * Init functions (static constructors and the like) + */ + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > FLASH + + + .ARM.extab : { + *(.ARM.extab*) + } > FLASH + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > FLASH + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + + /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */ + . = ALIGN(16); + FILL(0xffff) + . += 16; + } > AXI_SRAM AT > FLASH = 0xffff + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > AXI_SRAM + + /* Emit the the D3 power domain section for locating BDMA data */ + + .sram4_reserve (NOLOAD) : + { + *(.sram4) + . = ALIGN(4); + _sram4_heap_start = ABSOLUTE(.); + } > SRAM4 + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/x-mav/ap-h743r1/pwm_voltage/CMakeLists.txt b/boards/x-mav/ap-h743r1/pwm_voltage/CMakeLists.txt new file mode 100644 index 0000000000..6db1696208 --- /dev/null +++ b/boards/x-mav/ap-h743r1/pwm_voltage/CMakeLists.txt @@ -0,0 +1,42 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE modules__pwm_voltage_apply + MAIN pwm_voltage_apply + + SRCS + pwm_voltage.cpp + DEPENDS + px4_work_queue + ) diff --git a/boards/x-mav/ap-h743r1/pwm_voltage/parameters.c b/boards/x-mav/ap-h743r1/pwm_voltage/parameters.c new file mode 100644 index 0000000000..728bcc7a55 --- /dev/null +++ b/boards/x-mav/ap-h743r1/pwm_voltage/parameters.c @@ -0,0 +1,43 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * Control PWM output voltage + * + * @value 0 3.3V + * @value 1 5.0V + * + * @reboot_required true + * @group PWM Outputs + */ +PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0); diff --git a/boards/x-mav/ap-h743r1/pwm_voltage/pwm_voltage.cpp b/boards/x-mav/ap-h743r1/pwm_voltage/pwm_voltage.cpp new file mode 100644 index 0000000000..2bef9ae0f6 --- /dev/null +++ b/boards/x-mav/ap-h743r1/pwm_voltage/pwm_voltage.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "board_config.h" + +extern "C" int pwm_voltage_apply_main(int argc, char *argv[]) +{ + int32_t pwm_volt_sel = 0; + + param_get(param_find("PWM_VOLT_SEL"), &pwm_volt_sel); + + if (pwm_volt_sel != 0) { + PWM_5V_VOLT_SEL(true); + + } else { + PWM_5V_VOLT_SEL(false); + } + + return 0; +} diff --git a/boards/x-mav/ap-h743r1/rover.px4board b/boards/x-mav/ap-h743r1/rover.px4board new file mode 100644 index 0000000000..e105ef2772 --- /dev/null +++ b/boards/x-mav/ap-h743r1/rover.px4board @@ -0,0 +1,15 @@ +CONFIG_MODULES_FLIGHT_MODE_MANAGER=n +CONFIG_MODULES_FW_ATT_CONTROL=n +CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_FW_LATERAL_LONGITUDINAL_CONTROL=n +CONFIG_MODULES_FW_MODE_MANAGER=n +CONFIG_MODULES_FW_RATE_CONTROL=n +CONFIG_MODULES_MC_ATT_CONTROL=n +CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n +CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=n +CONFIG_MODULES_MC_POS_CONTROL=n +CONFIG_MODULES_MC_RATE_CONTROL=n +CONFIG_MODULES_VTOL_ATT_CONTROL=n +CONFIG_MODULES_ROVER_ACKERMANN=y +CONFIG_MODULES_ROVER_DIFFERENTIAL=y +CONFIG_MODULES_ROVER_MECANUM=y diff --git a/boards/x-mav/ap-h743r1/src/CMakeLists.txt b/boards/x-mav/ap-h743r1/src/CMakeLists.txt new file mode 100644 index 0000000000..123bc75b16 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/CMakeLists.txt @@ -0,0 +1,70 @@ +############################################################################ +# +# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +if("${PX4_BOARD_LABEL}" STREQUAL "bootloader") + add_library(drivers_board + bootloader_main.c + usb.c + ) + target_link_libraries(drivers_board + PRIVATE + nuttx_arch + nuttx_drivers + bootloader + ) + target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common) + +else() + add_library(drivers_board + i2c.cpp + init.c + led.c + sdio.c + spi.cpp + timer_config.cpp + usb.c + mtd.cpp + can.c + ) + # add_dependencies(drivers_board arch_board_hw_info) + + target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + arch_board_hw_info + drivers__led + nuttx_arch + nuttx_drivers + px4_layer + ) +endif() diff --git a/boards/x-mav/ap-h743r1/src/board_config.h b/boards/x-mav/ap-h743r1/src/board_config.h new file mode 100644 index 0000000000..254261ba1a --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/board_config.h @@ -0,0 +1,226 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * Board internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************************************** + * Definitions + ****************************************************************************************************/ + +/* PX4IO connection configuration */ +#define BOARD_USES_PX4IO_VERSION 2 +#define PX4IO_SERIAL_DEVICE "/dev/ttyS4" +#define PX4IO_SERIAL_TX_GPIO GPIO_USART6_TX +#define PX4IO_SERIAL_RX_GPIO GPIO_USART6_RX +#define PX4IO_SERIAL_BASE STM32_USART6_BASE +#define PX4IO_SERIAL_VECTOR STM32_IRQ_USART6 +#define PX4IO_SERIAL_TX_DMAMAP DMAMAP_USART6_TX +#define PX4IO_SERIAL_RX_DMAMAP DMAMAP_USART6_RX +#define PX4IO_SERIAL_RCC_REG STM32_RCC_APB2ENR +#define PX4IO_SERIAL_RCC_EN RCC_APB2ENR_USART6EN +#define PX4IO_SERIAL_CLOCK STM32_PCLK2_FREQUENCY +#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */ + +/* LEDs are driven with push open drain to support Anode to 5V or 3.3V */ + +# define GPIO_nLED_RED /* PD15 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN15) +# define GPIO_nLED_GREEN /* PD11 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN11) +# define GPIO_nLED_BLUE /* PD10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN10) + +# define BOARD_HAS_CONTROL_STATUS_LEDS 1 +# define BOARD_OVERLOAD_LED LED_RED +# define BOARD_ARMED_STATE_LED LED_BLUE + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that + * can be used by the Px4 Firmware in the adc driver + */ + +/* ADC defines to be used in sensors.cpp to read from a particular channel */ + +#define SYSTEM_ADC_BASE STM32_ADC1_BASE + +#define ADC12_CH(n) (n) +#define ADC3_CH(n) (n) + +#define ANALOG_PC3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) + +#define PX4_ADC_GPIO \ + /* PC4 */ GPIO_ADC12_INP4, \ + /* PC5 */ GPIO_ADC12_INP8 + +/* Define GPIO pins used as ADC N.B. Channel numbers must match below */ +/* Define Channel numbers must match above GPIO pin IN(n)*/ +#define ADC_BATTERY_VOLTAGE_CHANNEL ADC12_CH(4) +#define ADC_BATTERY_CURRENT_CHANNEL ADC12_CH(8) + +#define ADC_CHANNELS \ + ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \ + (1 << ADC_BATTERY_CURRENT_CHANNEL)) + +#define BOARD_ADC_OPEN_CIRCUIT_V (1.6f) + +#define BOARD_HAS_STATIC_MANIFEST 1 + +#define UAVCAN_NUM_IFACES_RUNTIME 1 + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 7 + +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + +/* PWM Power */ +#define GPIO_PWM_VOLT_SEL /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8) +#define PWM_5V_VOLT_SEL(on_true) px4_arch_gpiowrite(GPIO_PWM_VOLT_SEL, (on_true)) + +/* Tone alarm output */ +#define TONE_ALARM_TIMER 5 /* Timer 5 */ +#define TONE_ALARM_CHANNEL 4 /* PA3 GPIO_TIM5_CH4 */ +#define GPIO_BUZZER_1 /* PA3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN3) + +#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1 +#define GPIO_TONE_ALARM GPIO_BUZZER_1 + +/* USB OTG FS + * + * PE15 OTG_FS_VBUS VBUS sensing + */ +#define GPIO_OTGFS_VBUS /* PE15 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTE|GPIO_PIN15) +#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_OTGFS_VBUS)) + +/* High-resolution timer */ +#define HRT_TIMER 8 /* use timer1 for the HRT */ +#define HRT_TIMER_CHANNEL 1 /* use capture/compare channel 1 */ + +/* RC Serial port */ +#define RC_SERIAL_PORT "/dev/ttyS4" +#define BOARD_SUPPORTS_RC_SERIAL_PORT_OUTPUT + +/* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_LIB_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ +#define SDIO_SLOTNO 0 /* Only one slot */ +#define SDIO_MINOR 0 +#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_LIB_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +#endif + +/* This board provides a DMA pool and APIs */ +#define BOARD_DMA_ALLOC_POOL_SIZE 5120 + +/* This board provides the board_on_reset interface */ +#define BOARD_HAS_ON_RESET 1 + +#define PX4_GPIO_INIT_LIST { \ + GPIO_CAN1_TX,\ + GPIO_CAN1_RX,\ + GPIO_CAN2_TX,\ + GPIO_CAN2_RX,\ + PX4_ADC_GPIO,\ + GPIO_TONE_ALARM_IDLE,\ + GPIO_PWM_VOLT_SEL\ + } + +#define BOARD_ENABLE_CONSOLE_BUFFER + +#define BOARD_NUM_IO_TIMERS 5 + + +__BEGIN_DECLS + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public data + ****************************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************************************** + * Public Functions + ****************************************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void); + +/**************************************************************************************************** + * Name: stm32_spiinitialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the board. + * + ****************************************************************************************************/ + +extern void stm32_spiinitialize(void); + +extern void stm32_usbinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/x-mav/ap-h743r1/src/bootloader_main.c b/boards/x-mav/ap-h743r1/src/bootloader_main.c new file mode 100644 index 0000000000..5670308a29 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/bootloader_main.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file bootloader_main.c + * + * FMU-specific early startup code for bootloader +*/ + +#include "board_config.h" +#include "bl.h" + +#include +#include +#include +#include +#include +#include "arm_internal.h" +#include + +extern int sercon_main(int c, char **argv); + +__EXPORT void board_on_reset(int status) {} + +__EXPORT void stm32_boardinitialize(void) +{ + /* configure USB interfaces */ + stm32_usbinitialize(); +} + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + return 0; +} + +void board_late_initialize(void) +{ + sercon_main(0, NULL); +} + +extern void sys_tick_handler(void); +void board_timerhook(void) +{ + sys_tick_handler(); +} diff --git a/boards/x-mav/ap-h743r1/src/can.c b/boards/x-mav/ap-h743r1/src/can.c new file mode 100644 index 0000000000..71a89955e2 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/can.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * + * Copyright (C) 2012 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file px4fmu_can.c + * + * Board-specific CAN functions. + */ + +#if !defined(CONFIG_CAN) + +#include + +#include "board_config.h" + + +__EXPORT +uint16_t board_get_can_interfaces(void) +{ + uint16_t enabled_interfaces = 0x3; + + enabled_interfaces &= ~(1 << 1); + + return enabled_interfaces; +} + +#else + +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_internal.h" + +#include "chip.h" +#include "stm32_can.h" +#include "board_config.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2) +# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1." +# undef CONFIG_STM32_CAN2 +#endif + +#ifdef CONFIG_STM32_CAN1 +# define CAN_PORT 1 +#else +# define CAN_PORT 2 +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ +int can_devinit(void); + +/************************************************************************************ + * Name: can_devinit + * + * Description: + * All STM32 architectures must provide the following interface to work with + * examples/can. + * + ************************************************************************************/ + +int can_devinit(void) +{ + static bool initialized = false; + struct can_dev_s *can; + int ret; + + /* Check if we have already initialized */ + + if (!initialized) { + /* Call stm32_caninitialize() to get an instance of the CAN interface */ + + can = stm32_caninitialize(CAN_PORT); + + if (can == NULL) { + canerr("ERROR: Failed to get CAN interface\n"); + return -ENODEV; + } + + /* Register the CAN driver at "/dev/can0" */ + + ret = can_register("/dev/can0", can); + + if (ret < 0) { + canerr("ERROR: can_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} +#endif /* CONFIG_CAN */ diff --git a/boards/x-mav/ap-h743r1/src/hw_config.h b/boards/x-mav/ap-h743r1/src/hw_config.h new file mode 100644 index 0000000000..faffbab701 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/hw_config.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +/**************************************************************************** + * 10-8--2016: + * To simplify the ripple effect on the tools, we will be using + * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore + * moving forward all Bootloaders must contain the prefix "PX4 BL " + * in the USBDEVICESTRING + * This Change will be made in an upcoming BL release + ****************************************************************************/ +/* + * Define usage to configure a bootloader + * + * + * Constant example Usage + * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed + * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request + * BOARD_FMUV2 + * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading + * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading + * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string + * USBPRODUCTID 0x0011 - PID Should match defconfig + * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom + * delay provided by an APP FW + * BOARD_TYPE 9 - Must match .prototype boad_id + * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection + * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector + * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector + * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time. + * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted + * programmatically + * + * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing. + * This is to allow sectors to be reserved for app fw usage. That will NOT be erased + * during a FW upgrade. + * The default is 0, and selects the first sector to be erased, as the 0th entry in the + * flash_sectors table. Which is the second physical sector of FLASH in the device. + * The first physical sector of FLASH is used by the bootloader, and is not defined + * in the table. + * + * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus + * BOOTLOADER_RESERVATION_SIZE will be deducted from + * BOARD_FLASH_SIZE to determine the size of the App FW + * and hence the address space of FLASH to erase and program. + * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.) + * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL + * + * * Other defines are somewhat self explanatory. + */ + +/* Boot device selection list*/ +#define USB0_DEV 0x01 +#define SERIAL0_DEV 0x02 +#define SERIAL1_DEV 0x04 + +#define APP_LOAD_ADDRESS 0x08020000 +#define BOOTLOADER_DELAY 5000 +#define INTERFACE_USB 1 +#define INTERFACE_USB_CONFIG "/dev/ttyACM0" +#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS) + +//#define USE_VBUS_PULL_DOWN +// #define INTERFACE_USART 6 +#define INTERFACE_USART_CONFIG "/dev/ttyS5,57600" +#define BOOT_DELAY_ADDRESS 0x000001a0 +#define BOARD_TYPE 1203 +#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880) +#define BOARD_FLASH_SECTORS (15) +#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024) + +#define OSC_FREQ 8 + +#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE +#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_RED // RED +#define BOARD_LED_ON 1 +#define BOARD_LED_OFF 0 + +#define SERIAL_BREAK_DETECT_DISABLED 1 + +#if !defined(ARCH_SN_MAX_LENGTH) +# define ARCH_SN_MAX_LENGTH 12 +#endif + +#if !defined(APP_RESERVATION_SIZE) +# define APP_RESERVATION_SIZE 0 +#endif + +#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE) +# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1 +#endif + +#if !defined(USB_DATA_ALIGN) +# define USB_DATA_ALIGN +#endif + +#ifndef BOOT_DEVICES_SELECTION +# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif + +#ifndef BOOT_DEVICES_FILTER_ONUSB +# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV +#endif diff --git a/boards/x-mav/ap-h743r1/src/i2c.cpp b/boards/x-mav/ap-h743r1/src/i2c.cpp new file mode 100644 index 0000000000..d836ada04f --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/i2c.cpp @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), + initI2CBusExternal(2), + initI2CBusExternal(4), +}; diff --git a/boards/x-mav/ap-h743r1/src/init.c b/boards/x-mav/ap-h743r1/src/init.c new file mode 100644 index 0000000000..6b41d489bf --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/init.c @@ -0,0 +1,211 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * FMU-specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialisation. + */ + +#include "board_config.h" + +#include + +#include +#include +#include +#include +#include +#include "arm_internal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +# if defined(FLASH_BASED_PARAMS) +# include +#endif + +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i))); + } + + /* + * On resets invoked from system (not boot) ensure we establish a low + * output state on PWM pins to disarm the ESC and prevent the reset from potentially + * spinning up the motors. + */ + if (status >= 0) { + up_mdelay(100); + } +} + +/************************************************************************************ + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ +__EXPORT void stm32_boardinitialize(void) +{ + /* Reset PWM first thing */ + board_on_reset(-1); + + /* configure LEDs */ + board_autoled_initialize(); + + /* configure pins */ + const uint32_t gpio[] = PX4_GPIO_INIT_LIST; + px4_gpio_init(gpio, arraySize(gpio)); + + /* configure SPI interfaces */ + stm32_spiinitialize(); + + /* configure USB interfaces */ + stm32_usbinitialize(); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ +__EXPORT int board_app_initialize(uintptr_t arg) +{ + /* Need hrt running before using the ADC */ + px4_platform_init(); + + /* configure the DMA allocator */ + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "[boot] DMA alloc FAILED\n"); + } + + /* initial LED state */ + drv_led_start(); + led_off(LED_RED); + led_off(LED_BLUE); + + if (board_hardfault_init(2, true) != 0) { + led_on(LED_BLUE); + } + +#ifdef CONFIG_MMCSD + int ret = stm32_sdio_initialize(); + + if (ret != OK) { + led_on(LED_BLUE); + return ret; + } + +#endif + +// TODO:internal flash store parameters +#if defined(FLASH_BASED_PARAMS) + static sector_descriptor_t params_sector_map[] = { + {15, 128 * 1024, 0x081E0000}, + {0, 0, 0}, + }; + + /* Initialize the flashfs layer to use heap allocated memory */ + int result = parameter_flashfs_init(params_sector_map, NULL, 0); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to init params in FLASH %d\n", result); + led_on(LED_RED); + } + +#endif + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + return OK; +} diff --git a/boards/x-mav/ap-h743r1/src/led.c b/boards/x-mav/ap-h743r1/src/led.c new file mode 100644 index 0000000000..0420c1da2e --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/led.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * LED backend. + */ + +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "board_config.h" + +#include +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + +# define xlat(p) (p) +static uint32_t g_ledmap[] = { + GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN + GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE + GPIO_nLED_RED, // Indexed by BOARD_LED_RED +}; + +__EXPORT void led_init(void) +{ + /* Configure LED GPIOs for output */ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + if (g_ledmap[l] != 0) { + stm32_configgpio(g_ledmap[l]); + } + } +} + +static void phy_set_led(int led, bool state) +{ + /* Drive Low to switch on */ + if (g_ledmap[led] != 0) { + stm32_gpiowrite(g_ledmap[led], !state); + } +} + +static bool phy_get_led(int led) +{ + /* If Low it is on */ + if (g_ledmap[led] != 0) { + return !stm32_gpioread(g_ledmap[led]); + } + + return false; +} + +__EXPORT void led_on(int led) +{ + phy_set_led(xlat(led), true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(xlat(led), false); +} + +__EXPORT void led_toggle(int led) +{ + phy_set_led(xlat(led), !phy_get_led(xlat(led))); +} diff --git a/boards/x-mav/ap-h743r1/src/mtd.cpp b/boards/x-mav/ap-h743r1/src/mtd.cpp new file mode 100644 index 0000000000..e374a9be7e --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/mtd.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +//TODO:Prepare for NxtDual + +#include +#include +// KiB BS nB +static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32) + .bus_type = px4_mft_device_t::SPI, + .devid = SPIDEV_FLASH(0) +}; + +static const px4_mtd_entry_t fmum_fram = { + .device = &spi5, + .npart = 1, + .partd = { + { + .type = MTD_PARAMETERS, + .path = "/fs/mtd_params", + .nblocks = 32 + } + }, +}; + +static const px4_mtd_manifest_t board_mtd_config = { + .nconfigs = 1, + .entries = { + &fmum_fram + } +}; + +static const px4_mft_entry_s mtd_mft = { + .type = MTD, + .pmft = (void *) &board_mtd_config, +}; + +static const px4_mft_s mft = { + .nmft = 1, + .mfts = { + &mtd_mft + } +}; + +const px4_mft_s *board_get_manifest(void) +{ + return &mft; +} diff --git a/boards/x-mav/ap-h743r1/src/sdio.c b/boards/x-mav/ap-h743r1/src/sdio.c new file mode 100644 index 0000000000..869d757756 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/sdio.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "board_config.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(GPIO_SDMMC1_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + + if (sdio_dev && present != g_sd_inserted) { + sdio_mediachange(sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDMMC1_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + sdio_dev = sdio_initialize(SDIO_SLOTNO); + + if (!sdio_dev) { + syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev); + + if (ret != OK) { + syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(sdio_dev, true); +#endif + + return OK; +} + +#endif /* CONFIG_MMCSD */ diff --git a/boards/x-mav/ap-h743r1/src/spi.cpp b/boards/x-mav/ap-h743r1/src/spi.cpp new file mode 100644 index 0000000000..4b262023ea --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/spi.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { + initSPIBus(SPI::Bus::SPI1, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortA, GPIO::Pin2}, SPI::DRDY{GPIO::PortA, GPIO::Pin4}), + initSPIDevice(DRV_IMU_DEVTYPE_BMI270, SPI::CS{GPIO::PortA, GPIO::Pin2}, SPI::DRDY{GPIO::PortA, GPIO::Pin4}) + }), + initSPIBus(SPI::Bus::SPI3, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin4}) + }), + initSPIBus(SPI::Bus::SPI4, { + initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortC, GPIO::Pin13}, SPI::DRDY{GPIO::PortE, GPIO::Pin4}), + initSPIDevice(DRV_IMU_DEVTYPE_BMI270, SPI::CS{GPIO::PortC, GPIO::Pin13}, SPI::DRDY{GPIO::PortE, GPIO::Pin4}) + }), +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/x-mav/ap-h743r1/src/timer_config.cpp b/boards/x-mav/ap-h743r1/src/timer_config.cpp new file mode 100644 index 0000000000..73cee06f31 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/timer_config.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer1, DMA{DMA::Index1}), + initIOTimer(Timer::Timer2, DMA{DMA::Index1}), + initIOTimer(Timer::Timer3, DMA{DMA::Index1}), +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}), + initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}), + initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}), + initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel1}, {GPIO::PortA, GPIO::Pin0}) +}; + +constexpr io_timers_channel_mapping_t io_timers_channel_mapping = + initIOTimerChannelMapping(io_timers, timer_io_channels); diff --git a/boards/x-mav/ap-h743r1/src/usb.c b/boards/x-mav/ap-h743r1/src/usb.c new file mode 100644 index 0000000000..9591784866 --- /dev/null +++ b/boards/x-mav/ap-h743r1/src/usb.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +#include "board_config.h" +#include +#include +#include +#include + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the board. + * + ************************************************************************************/ + +__EXPORT void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ + +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); +#endif +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ +__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/boards/x-mav/ap-h743v2/default.px4board b/boards/x-mav/ap-h743v2/default.px4board index adc930268c..538f252ae0 100644 --- a/boards/x-mav/ap-h743v2/default.px4board +++ b/boards/x-mav/ap-h743v2/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_COMMON_OSD=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y diff --git a/boards/xc-fly/xc-slam/default.px4board b/boards/xc-fly/xc-slam/default.px4board index 7a7cb9d880..77fa872875 100644 --- a/boards/xc-fly/xc-slam/default.px4board +++ b/boards/xc-fly/xc-slam/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/xc-fly/xc-slim/default.px4board b/boards/xc-fly/xc-slim/default.px4board index 7a7cb9d880..77fa872875 100644 --- a/boards/xc-fly/xc-slim/default.px4board +++ b/boards/xc-fly/xc-slim/default.px4board @@ -21,7 +21,6 @@ CONFIG_DRIVERS_IMU_BOSCH_BMI088=y CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y -CONFIG_COMMON_OPTICAL_FLOW=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_RC_INPUT=y CONFIG_COMMON_TELEMETRY=y diff --git a/boards/zeroone/x6/default.px4board b/boards/zeroone/x6/default.px4board index 809a97f7fa..af7e91fb9a 100644 --- a/boards/zeroone/x6/default.px4board +++ b/boards/zeroone/x6/default.px4board @@ -29,7 +29,6 @@ CONFIG_DRIVERS_OSD_MSP_OSD=y CONFIG_DRIVERS_POWER_MONITOR_INA226=y CONFIG_DRIVERS_POWER_MONITOR_INA228=y CONFIG_DRIVERS_POWER_MONITOR_INA238=y -CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y CONFIG_DRIVERS_PWM_OUT=y CONFIG_DRIVERS_PX4IO=y CONFIG_DRIVERS_RC_INPUT=y @@ -61,7 +60,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 diff --git a/boards/zeroone/x6/init/rc.board_defaults b/boards/zeroone/x6/init/rc.board_defaults index 0300654d6a..702a38153d 100644 --- a/boards/zeroone/x6/init/rc.board_defaults +++ b/boards/zeroone/x6/init/rc.board_defaults @@ -3,12 +3,6 @@ # board specific defaults #------------------------------------------------------------------------------ -# By disabling all 3 INA modules, we use the -# i2c_launcher instead. -param set-default SENS_EN_INA238 0 -param set-default SENS_EN_INA228 0 -param set-default SENS_EN_INA226 0 - if ver hwbasecmp 009 010 011 then # Skynode: use the "custom participant", IP=10.41.10.1 config for uxrce_dds_client diff --git a/cmake/metadata.cmake b/cmake/metadata.cmake index 82b2042701..803d14c9e2 100644 --- a/cmake/metadata.cmake +++ b/cmake/metadata.cmake @@ -71,18 +71,15 @@ add_custom_target(metadata_parameters COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py --src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d` ${generated_params_dir} - --inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml --markdown ${PX4_BINARY_DIR}/docs/parameters.md COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py --src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d` ${generated_params_dir} - --inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml --json ${PX4_BINARY_DIR}/docs/parameters.json --compress COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py --src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d` ${generated_params_dir} - --inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml --xml ${PX4_BINARY_DIR}/docs/parameters.xml COMMENT "Generating full parameter metadata (markdown, xml, and json)" diff --git a/docs/.gitignore b/docs/.gitignore index 91aeac442c..3a8178b2ae 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -16,6 +16,9 @@ logs #Yarn log yarn-error.log +# npm lockfile (project uses yarn) +package-lock.json + # Generated alternative _summary.md # **/*/_summary.md diff --git a/docs/.prettierrc b/docs/.prettierrc new file mode 100644 index 0000000000..8018f0709d --- /dev/null +++ b/docs/.prettierrc @@ -0,0 +1,8 @@ +{ + "proseWrap": "preserve", + "tabWidth": 2, + "useTabs": false, + "printWidth": 9999, + "endOfLine": "lf", + "embeddedLanguageFormatting": "off" +} diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index a0f2bd6caf..c12b4e27ef 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -31,6 +31,7 @@ export default defineConfig({ tabsPlugin(md); //https://github.com/Red-Asuka/vitepress-plugin-tabs }, }, + cleanUrls: true, vite: { plugins: [ @@ -197,7 +198,8 @@ export default defineConfig({ text: "Version", items: [ { text: "main", link: "https://docs.px4.io/main/en/" }, - { text: "v1.15 (stable)", link: "https://docs.px4.io/v1.15/en/" }, + { text: "v1.16 (stable)", link: "https://docs.px4.io/v1.16/en/" }, + { text: "v1.15", link: "https://docs.px4.io/v1.15/en/" }, { text: "v1.14", link: "https://docs.px4.io/v1.14/en/" }, { text: "v1.13", link: "https://docs.px4.io/v1.13/en/" }, { text: "v1.12", link: "https://docs.px4.io/v1.12/en/" }, @@ -252,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; @@ -274,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: { diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css index d3862762c0..161b1f383b 100644 --- a/docs/.vitepress/theme/style.css +++ b/docs/.vitepress/theme/style.css @@ -160,3 +160,44 @@ .vp-doc img { display: inline; /* block by default set by vitepress */ } + + +/** + * Custom styles for wide pages + * -------------------------------------------------------------------------- */ + +.is-wide-page .content-container { + max-width: 100% !important; +} +@media (min-width: 1280px) { + .is-wide-page .content { + min-width: 940px !important; + } +} + +/* Make page width larger */ +@media (min-width: 1440px) { + .is-wide-page .VPSidebar { + padding-left: 32px !important; + width: var(--vp-sidebar-width) !important; + } + .is-wide-page .VPContent.has-sidebar { + padding-left: var(--vp-sidebar-width) !important; + padding-right: 0 !important; + } + + .is-wide-page .VPNavBar.has-sidebar .title { + padding-left: 32px !important; + } + + .is-wide-page .VPNavBar.has-sidebar .content { + padding-left: var(--vp-sidebar-width) !important; + padding-right: 32px !important; + } + + /* Very hacky */ + .is-wide-page .VPNavBar.has-sidebar #local-search { + z-index: 10; + } + +} diff --git a/docs/assets/advanced/neural_networks/raptor/method.jpg b/docs/assets/advanced/neural_networks/raptor/method.jpg new file mode 100644 index 0000000000..935da7683d Binary files /dev/null and b/docs/assets/advanced/neural_networks/raptor/method.jpg differ diff --git a/docs/assets/advanced/neural_networks/raptor/results_figure_eight.svg b/docs/assets/advanced/neural_networks/raptor/results_figure_eight.svg new file mode 100644 index 0000000000..81d3a51286 --- /dev/null +++ b/docs/assets/advanced/neural_networks/raptor/results_figure_eight.svg @@ -0,0 +1 @@ + diff --git a/docs/assets/advanced/neural_networks/raptor/results_line.svg b/docs/assets/advanced/neural_networks/raptor/results_line.svg new file mode 100644 index 0000000000..0d7d142013 --- /dev/null +++ b/docs/assets/advanced/neural_networks/raptor/results_line.svg @@ -0,0 +1 @@ + diff --git a/docs/assets/advanced/neural_networks/raptor/visual_abstract.jpg b/docs/assets/advanced/neural_networks/raptor/visual_abstract.jpg new file mode 100644 index 0000000000..40ba52877a Binary files /dev/null and b/docs/assets/advanced/neural_networks/raptor/visual_abstract.jpg differ diff --git a/docs/assets/airframes/multicopter/amovlab_f410/amovlabf410_drone_v1.15.4.params b/docs/assets/airframes/multicopter/amovlab_f410/amovlabf410_drone_v1.15.4.params index f80c1b5a3a..4cea5fc9d4 100644 --- a/docs/assets/airframes/multicopter/amovlab_f410/amovlabf410_drone_v1.15.4.params +++ b/docs/assets/airframes/multicopter/amovlab_f410/amovlabf410_drone_v1.15.4.params @@ -1,8 +1,8 @@ # Onboard parameters for Vehicle 1 # # Stack: PX4 Pro -# Vehicle: -# Version: 1.15.4 +# Vehicle: Multi-Rotor +# Version: 1.15.4 # Git Revision: 99c40407ff000000 # # Vehicle-Id Component-Id Name Value Type @@ -318,7 +318,6 @@ 1 1 COM_OBS_AVOID 0 6 1 1 COM_OF_LOSS_T 1.000000000000000000 9 1 1 COM_PARACHUTE 0 6 -1 1 COM_POSCTL_NAVL 0 6 1 1 COM_POS_FS_DELAY 1 6 1 1 COM_POS_FS_EPH 5.000000000000000000 9 1 1 COM_POS_LOW_EPH -1.000000000000000000 9 @@ -326,7 +325,6 @@ 1 1 COM_PREARM_MODE 0 6 1 1 COM_QC_ACT 0 6 1 1 COM_RCL_EXCEPT 0 6 -1 1 COM_RC_ARM_HYST 1000 6 1 1 COM_RC_IN_MODE 3 6 1 1 COM_RC_LOSS_T 0.500000000000000000 9 1 1 COM_RC_OVERRIDE 1 6 @@ -572,7 +570,6 @@ 1 1 MAV_FWDEXTSP 1 6 1 1 MAV_HASH_CHK_EN 1 6 1 1 MAV_HB_FORW_EN 1 6 -1 1 MAV_PROTO_VER 0 6 1 1 MAV_RADIO_TOUT 5 6 1 1 MAV_SIK_RADIO_ID 0 6 1 1 MAV_SYS_ID 1 6 @@ -646,7 +643,6 @@ 1 1 MPC_ACC_HOR_MAX 5.000000000000000000 9 1 1 MPC_ACC_UP_MAX 4.000000000000000000 9 1 1 MPC_ALT_MODE 2 6 -1 1 MPC_HOLD_DZ 0.100000001490116119 9 1 1 MPC_HOLD_MAX_XY 0.800000011920928955 9 1 1 MPC_HOLD_MAX_Z 0.600000023841857910 9 1 1 MPC_JERK_AUTO 4.000000000000000000 9 @@ -679,7 +675,6 @@ 1 1 MPC_VEL_MAN_SIDE -1.000000000000000000 9 1 1 MPC_XY_CRUISE 5.000000000000000000 9 1 1 MPC_XY_ERR_MAX 2.000000000000000000 9 -1 1 MPC_XY_MAN_EXPO 0.600000023841857910 9 1 1 MPC_XY_P 0.949999988079071045 9 1 1 MPC_XY_TRAJ_P 0.500000000000000000 9 1 1 MPC_XY_VEL_ALL -10.000000000000000000 9 @@ -689,9 +684,7 @@ 1 1 MPC_XY_VEL_P_ACC 1.799999952316284180 9 1 1 MPC_YAWRAUTO_ACC 60.000000000000000000 9 1 1 MPC_YAWRAUTO_MAX 45.000000000000000000 9 -1 1 MPC_YAW_EXPO 0.600000023841857910 9 1 1 MPC_YAW_MODE 0 6 -1 1 MPC_Z_MAN_EXPO 0.600000023841857910 9 1 1 MPC_Z_P 1.000000000000000000 9 1 1 MPC_Z_VEL_ALL -3.000000000000000000 9 1 1 MPC_Z_VEL_D_ACC 0.000000000000000000 9 @@ -809,92 +802,74 @@ 1 1 PWM_MAIN_TIM1 400 6 1 1 PWM_MAIN_TIM2 -1 6 1 1 PWM_SBUS_MODE 0 6 -1 1 RC10_DZ 0.000000000000000000 9 1 1 RC10_MAX 2000.000000000000000000 9 1 1 RC10_MIN 1000.000000000000000000 9 1 1 RC10_REV 1.000000000000000000 9 1 1 RC10_TRIM 1500.000000000000000000 9 -1 1 RC11_DZ 0.000000000000000000 9 1 1 RC11_MAX 2000.000000000000000000 9 1 1 RC11_MIN 1000.000000000000000000 9 1 1 RC11_REV 1.000000000000000000 9 1 1 RC11_TRIM 1500.000000000000000000 9 -1 1 RC12_DZ 0.000000000000000000 9 1 1 RC12_MAX 2000.000000000000000000 9 1 1 RC12_MIN 1000.000000000000000000 9 1 1 RC12_REV 1.000000000000000000 9 1 1 RC12_TRIM 1500.000000000000000000 9 -1 1 RC13_DZ 0.000000000000000000 9 1 1 RC13_MAX 2000.000000000000000000 9 1 1 RC13_MIN 1000.000000000000000000 9 1 1 RC13_REV 1.000000000000000000 9 1 1 RC13_TRIM 1500.000000000000000000 9 -1 1 RC14_DZ 0.000000000000000000 9 1 1 RC14_MAX 2000.000000000000000000 9 1 1 RC14_MIN 1000.000000000000000000 9 1 1 RC14_REV 1.000000000000000000 9 1 1 RC14_TRIM 1500.000000000000000000 9 -1 1 RC15_DZ 0.000000000000000000 9 1 1 RC15_MAX 2000.000000000000000000 9 1 1 RC15_MIN 1000.000000000000000000 9 1 1 RC15_REV 1.000000000000000000 9 1 1 RC15_TRIM 1500.000000000000000000 9 -1 1 RC16_DZ 0.000000000000000000 9 1 1 RC16_MAX 2000.000000000000000000 9 1 1 RC16_MIN 1000.000000000000000000 9 1 1 RC16_REV 1.000000000000000000 9 1 1 RC16_TRIM 1500.000000000000000000 9 -1 1 RC17_DZ 0.000000000000000000 9 1 1 RC17_MAX 2000.000000000000000000 9 1 1 RC17_MIN 1000.000000000000000000 9 1 1 RC17_REV 1.000000000000000000 9 1 1 RC17_TRIM 1500.000000000000000000 9 -1 1 RC18_DZ 0.000000000000000000 9 1 1 RC18_MAX 2000.000000000000000000 9 1 1 RC18_MIN 1000.000000000000000000 9 1 1 RC18_REV 1.000000000000000000 9 1 1 RC18_TRIM 1500.000000000000000000 9 -1 1 RC1_DZ 10.000000000000000000 9 1 1 RC1_MAX 1996.000000000000000000 9 1 1 RC1_MIN 999.000000000000000000 9 1 1 RC1_REV 1.000000000000000000 9 1 1 RC1_TRIM 1498.000000000000000000 9 -1 1 RC2_DZ 10.000000000000000000 9 1 1 RC2_MAX 1998.000000000000000000 9 1 1 RC2_MIN 1000.000000000000000000 9 1 1 RC2_REV 1.000000000000000000 9 1 1 RC2_TRIM 1499.000000000000000000 9 -1 1 RC3_DZ 10.000000000000000000 9 1 1 RC3_MAX 1997.000000000000000000 9 1 1 RC3_MIN 1000.000000000000000000 9 1 1 RC3_REV 1.000000000000000000 9 1 1 RC3_TRIM 1000.000000000000000000 9 -1 1 RC4_DZ 10.000000000000000000 9 1 1 RC4_MAX 1997.000000000000000000 9 1 1 RC4_MIN 1000.000000000000000000 9 1 1 RC4_REV 1.000000000000000000 9 1 1 RC4_TRIM 1498.000000000000000000 9 -1 1 RC5_DZ 10.000000000000000000 9 1 1 RC5_MAX 2000.000000000000000000 9 1 1 RC5_MIN 1000.000000000000000000 9 1 1 RC5_REV 1.000000000000000000 9 1 1 RC5_TRIM 1500.000000000000000000 9 -1 1 RC6_DZ 10.000000000000000000 9 1 1 RC6_MAX 2000.000000000000000000 9 1 1 RC6_MIN 1000.000000000000000000 9 1 1 RC6_REV 1.000000000000000000 9 1 1 RC6_TRIM 1500.000000000000000000 9 -1 1 RC7_DZ 10.000000000000000000 9 1 1 RC7_MAX 2000.000000000000000000 9 1 1 RC7_MIN 1000.000000000000000000 9 1 1 RC7_REV 1.000000000000000000 9 1 1 RC7_TRIM 1500.000000000000000000 9 -1 1 RC8_DZ 10.000000000000000000 9 1 1 RC8_MAX 2000.000000000000000000 9 1 1 RC8_MIN 1000.000000000000000000 9 1 1 RC8_REV 1.000000000000000000 9 1 1 RC8_TRIM 1500.000000000000000000 9 -1 1 RC9_DZ 0.000000000000000000 9 1 1 RC9_MAX 2000.000000000000000000 9 1 1 RC9_MIN 1000.000000000000000000 9 1 1 RC9_REV 1.000000000000000000 9 @@ -1081,9 +1056,6 @@ 1 1 UAVCAN_EC_REV 0 6 1 1 UAVCAN_ENABLE 2 6 1 1 UAVCAN_LGT_ANTCL 2 6 -1 1 UAVCAN_LGT_LAND 0 6 -1 1 UAVCAN_LGT_NAV 3 6 -1 1 UAVCAN_LGT_STROB 1 6 1 1 UAVCAN_NODE_ID 1 6 1 1 UAVCAN_PUB_ARM 0 6 1 1 UAVCAN_PUB_MBD 0 6 diff --git a/docs/assets/airframes/rover/rover_simulation.png b/docs/assets/airframes/rover/rover_simulation.png index e57bb0861a..f19e512812 100644 Binary files a/docs/assets/airframes/rover/rover_simulation.png and b/docs/assets/airframes/rover/rover_simulation.png differ diff --git a/docs/assets/airframes/types/FreeFlyer.svg b/docs/assets/airframes/types/FreeFlyer.svg new file mode 100644 index 0000000000..aba991c424 --- /dev/null +++ b/docs/assets/airframes/types/FreeFlyer.svg @@ -0,0 +1,197 @@ + + + +image/svg+xmlQuadRotorXQuadRotorX + 12345678 diff --git a/docs/assets/config/actuators/pwm_center_output.png b/docs/assets/config/actuators/pwm_center_output.png new file mode 100644 index 0000000000..ef83e96d88 Binary files /dev/null and b/docs/assets/config/actuators/pwm_center_output.png differ diff --git a/docs/assets/config/actuators/qgc_actuators_gimbal.png b/docs/assets/config/actuators/qgc_actuators_gimbal.png index e19434e678..a062d88da7 100644 Binary files a/docs/assets/config/actuators/qgc_actuators_gimbal.png and b/docs/assets/config/actuators/qgc_actuators_gimbal.png differ diff --git a/docs/assets/config/actuators/servo_pwm_center.png b/docs/assets/config/actuators/servo_pwm_center.png new file mode 100644 index 0000000000..c1d92b7676 Binary files /dev/null and b/docs/assets/config/actuators/servo_pwm_center.png differ diff --git a/docs/assets/config/actuators/servo_pwm_linear.png b/docs/assets/config/actuators/servo_pwm_linear.png new file mode 100644 index 0000000000..176beab77e Binary files /dev/null and b/docs/assets/config/actuators/servo_pwm_linear.png differ diff --git a/docs/assets/config/fw/autotune.png b/docs/assets/config/fw/autotune.png new file mode 100644 index 0000000000..6ceb2ed3ba Binary files /dev/null and b/docs/assets/config/fw/autotune.png differ diff --git a/docs/assets/config/fw/gain_compression_diagram.png b/docs/assets/config/fw/gain_compression_diagram.png new file mode 100644 index 0000000000..e2ea2f09f7 Binary files /dev/null and b/docs/assets/config/fw/gain_compression_diagram.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/gps.png b/docs/assets/flight_controller/accton-godwit/ga1/gps.png new file mode 100644 index 0000000000..eea6e25899 Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/gps.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/motor_servo.png b/docs/assets/flight_controller/accton-godwit/ga1/motor_servo.png new file mode 100644 index 0000000000..13022124b5 Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/motor_servo.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/orientation.png b/docs/assets/flight_controller/accton-godwit/ga1/orientation.png new file mode 100644 index 0000000000..7cbcb9e835 Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/orientation.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/outlook.png b/docs/assets/flight_controller/accton-godwit/ga1/outlook.png new file mode 100644 index 0000000000..32dc8f28ea Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/outlook.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/pin_definition.png b/docs/assets/flight_controller/accton-godwit/ga1/pin_definition.png new file mode 100644 index 0000000000..2ba66107cf Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/pin_definition.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/power.png b/docs/assets/flight_controller/accton-godwit/ga1/power.png new file mode 100644 index 0000000000..a7d5525fec Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/power.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/radio.png b/docs/assets/flight_controller/accton-godwit/ga1/radio.png new file mode 100644 index 0000000000..6f1aef9e75 Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/radio.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/sdcard.png b/docs/assets/flight_controller/accton-godwit/ga1/sdcard.png new file mode 100644 index 0000000000..796664b4dd Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/sdcard.png differ diff --git a/docs/assets/flight_controller/accton-godwit/ga1/wiring.png b/docs/assets/flight_controller/accton-godwit/ga1/wiring.png new file mode 100644 index 0000000000..54ab5d1bcf Binary files /dev/null and b/docs/assets/flight_controller/accton-godwit/ga1/wiring.png differ diff --git a/docs/assets/flight_controller/micoair743_lite/back_view.png b/docs/assets/flight_controller/micoair743_lite/back_view.png new file mode 100644 index 0000000000..eee3282114 Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/back_view.png differ diff --git a/docs/assets/flight_controller/micoair743_lite/front_view.png b/docs/assets/flight_controller/micoair743_lite/front_view.png new file mode 100644 index 0000000000..eda05065fe Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/front_view.png differ diff --git a/docs/assets/flight_controller/micoair743_lite/interfaces_diagram.png b/docs/assets/flight_controller/micoair743_lite/interfaces_diagram.png new file mode 100644 index 0000000000..d552afbde9 Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/interfaces_diagram.png differ diff --git a/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx b/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx new file mode 100644 index 0000000000..2324eb064d Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx differ diff --git a/docs/assets/flight_controller/micoair743_lite/size.png b/docs/assets/flight_controller/micoair743_lite/size.png new file mode 100644 index 0000000000..09cfdc00c1 Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/size.png differ diff --git a/docs/assets/flight_controller/micoair743_lite/wiring_diagram.png b/docs/assets/flight_controller/micoair743_lite/wiring_diagram.png new file mode 100644 index 0000000000..ca6fd57ea2 Binary files /dev/null and b/docs/assets/flight_controller/micoair743_lite/wiring_diagram.png differ diff --git a/docs/assets/flight_controller/radiolink_pix6/left_view.png b/docs/assets/flight_controller/radiolink_pix6/left_view.png new file mode 100644 index 0000000000..9fc02eb309 Binary files /dev/null and b/docs/assets/flight_controller/radiolink_pix6/left_view.png differ diff --git a/docs/assets/flight_controller/radiolink_pix6/radiolink_power_modules.png b/docs/assets/flight_controller/radiolink_pix6/radiolink_power_modules.png new file mode 100644 index 0000000000..f802aad0ce Binary files /dev/null and b/docs/assets/flight_controller/radiolink_pix6/radiolink_power_modules.png differ diff --git a/docs/assets/flight_controller/radiolink_pix6/rear_view.png b/docs/assets/flight_controller/radiolink_pix6/rear_view.png new file mode 100644 index 0000000000..1132fde1b9 Binary files /dev/null and b/docs/assets/flight_controller/radiolink_pix6/rear_view.png differ diff --git a/docs/assets/flight_controller/radiolink_pix6/right_view.png b/docs/assets/flight_controller/radiolink_pix6/right_view.png new file mode 100644 index 0000000000..c7032c0967 Binary files /dev/null and b/docs/assets/flight_controller/radiolink_pix6/right_view.png differ diff --git a/docs/assets/flight_controller/radiolink_pix6/top_view.png b/docs/assets/flight_controller/radiolink_pix6/top_view.png new file mode 100644 index 0000000000..91fd2e6c3a Binary files /dev/null and b/docs/assets/flight_controller/radiolink_pix6/top_view.png differ diff --git a/docs/assets/flight_controller/svehicle_e2/back.jpeg b/docs/assets/flight_controller/svehicle_e2/back.jpeg new file mode 100644 index 0000000000..6e38b365bd Binary files /dev/null and b/docs/assets/flight_controller/svehicle_e2/back.jpeg differ diff --git a/docs/assets/flight_controller/svehicle_e2/left.png b/docs/assets/flight_controller/svehicle_e2/left.png new file mode 100644 index 0000000000..4b68dd0665 Binary files /dev/null and b/docs/assets/flight_controller/svehicle_e2/left.png differ diff --git a/docs/assets/flight_controller/svehicle_e2/main.png b/docs/assets/flight_controller/svehicle_e2/main.png new file mode 100644 index 0000000000..ea500e137e Binary files /dev/null and b/docs/assets/flight_controller/svehicle_e2/main.png differ diff --git a/docs/assets/flight_controller/svehicle_e2/right.png b/docs/assets/flight_controller/svehicle_e2/right.png new file mode 100644 index 0000000000..b6d8f66748 Binary files /dev/null and b/docs/assets/flight_controller/svehicle_e2/right.png differ diff --git a/docs/assets/flight_controller/svehicle_e2/top.png b/docs/assets/flight_controller/svehicle_e2/top.png new file mode 100644 index 0000000000..ff000e2b47 Binary files /dev/null and b/docs/assets/flight_controller/svehicle_e2/top.png differ diff --git a/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png new file mode 100644 index 0000000000..56efaa40a3 Binary files /dev/null and b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png differ diff --git a/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png new file mode 100644 index 0000000000..f4daf38a03 Binary files /dev/null and b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png differ diff --git a/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png new file mode 100644 index 0000000000..8796767c25 Binary files /dev/null and b/docs/assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png differ diff --git a/docs/assets/flight_log_analysis/foxglove/foxglove_px4.png b/docs/assets/flight_log_analysis/foxglove/foxglove_px4.png new file mode 100644 index 0000000000..86aeee45fb Binary files /dev/null and b/docs/assets/flight_log_analysis/foxglove/foxglove_px4.png differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg b/docs/assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg deleted file mode 100644 index 95773124e4..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png b/docs/assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png new file mode 100644 index 0000000000..9e2c728d8c Binary files /dev/null and b/docs/assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png b/docs/assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png new file mode 100644 index 0000000000..f2ad61629f Binary files /dev/null and b/docs/assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg b/docs/assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg deleted file mode 100644 index baa39c19c6..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/radio-1.png b/docs/assets/hardware/complete_vehicles/modalai_starling/radio-1.png deleted file mode 100644 index 1c99ea15ae..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/radio-1.png and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/radio-2.png b/docs/assets/hardware/complete_vehicles/modalai_starling/radio-2.png deleted file mode 100644 index b5298b55b8..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/radio-2.png and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png b/docs/assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png deleted file mode 100644 index d74c6d439c..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/starling-photo.png b/docs/assets/hardware/complete_vehicles/modalai_starling/starling-photo.png deleted file mode 100644 index a9cf9b985e..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/starling-photo.png and /dev/null differ diff --git a/docs/assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg b/docs/assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg deleted file mode 100644 index 5d1cb04c0b..0000000000 Binary files a/docs/assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg and /dev/null differ diff --git a/docs/assets/hardware/esc/ark/ark_4_in_1_esc.jpg b/docs/assets/hardware/esc/ark/ark_4_in_1_esc.jpg new file mode 100644 index 0000000000..30e47baf15 Binary files /dev/null and b/docs/assets/hardware/esc/ark/ark_4_in_1_esc.jpg differ diff --git a/docs/assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg b/docs/assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg new file mode 100644 index 0000000000..031763d980 Binary files /dev/null and b/docs/assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg differ diff --git a/docs/assets/hardware/gps/ark/ark_dan_gps.jpg b/docs/assets/hardware/gps/ark/ark_dan_gps.jpg new file mode 100644 index 0000000000..559487abcd Binary files /dev/null and b/docs/assets/hardware/gps/ark/ark_dan_gps.jpg differ diff --git a/docs/assets/hardware/gps/ark/ark_g5_rtk_gps.png b/docs/assets/hardware/gps/ark/ark_g5_rtk_gps.png new file mode 100644 index 0000000000..78ba78bac5 Binary files /dev/null and b/docs/assets/hardware/gps/ark/ark_g5_rtk_gps.png differ diff --git a/docs/assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg b/docs/assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg new file mode 100644 index 0000000000..3011875389 Binary files /dev/null and b/docs/assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg differ diff --git a/docs/assets/hardware/gps/ark/ark_sam_gps_mini.jpg b/docs/assets/hardware/gps/ark/ark_sam_gps_mini.jpg new file mode 100644 index 0000000000..5f540b43a5 Binary files /dev/null and b/docs/assets/hardware/gps/ark/ark_sam_gps_mini.jpg differ diff --git a/docs/assets/hardware/gps/ark/ark_x20_rtk_gps.jpg b/docs/assets/hardware/gps/ark/ark_x20_rtk_gps.jpg new file mode 100644 index 0000000000..b93bf4980a Binary files /dev/null and b/docs/assets/hardware/gps/ark/ark_x20_rtk_gps.jpg differ diff --git a/docs/assets/hardware/power_module/ark_power_modules/ark_12s_payload_power.jpg b/docs/assets/hardware/power_module/ark_power_modules/ark_12s_payload_power.jpg new file mode 100644 index 0000000000..c0ab7670c2 Binary files /dev/null and b/docs/assets/hardware/power_module/ark_power_modules/ark_12s_payload_power.jpg differ diff --git a/docs/assets/hardware/power_module/ark_power_modules/ark_pab_power_no_connector.jpg b/docs/assets/hardware/power_module/ark_power_modules/ark_pab_power_no_connector.jpg new file mode 100644 index 0000000000..5f98f7987f Binary files /dev/null and b/docs/assets/hardware/power_module/ark_power_modules/ark_pab_power_no_connector.jpg differ diff --git a/docs/assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png b/docs/assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png new file mode 100644 index 0000000000..617f2e676c Binary files /dev/null and b/docs/assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png differ diff --git a/docs/assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png b/docs/assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png new file mode 100644 index 0000000000..5670c47c82 Binary files /dev/null and b/docs/assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png differ diff --git a/docs/assets/hardware/sensors/lidar_lightware/grf_500.png b/docs/assets/hardware/sensors/lidar_lightware/grf_500.png new file mode 100644 index 0000000000..baccec33a3 Binary files /dev/null and b/docs/assets/hardware/sensors/lidar_lightware/grf_500.png differ diff --git a/docs/assets/hardware/sensors/optical_flow/ark_dist.jpg b/docs/assets/hardware/sensors/optical_flow/ark_dist.jpg new file mode 100644 index 0000000000..a1882d2ee6 Binary files /dev/null and b/docs/assets/hardware/sensors/optical_flow/ark_dist.jpg differ diff --git a/docs/assets/middleware/ros2/px4_ros2_interface_lib/mode_requirements_diagram.png b/docs/assets/middleware/ros2/px4_ros2_interface_lib/mode_requirements_diagram.png index 29f3b0333d..1875eb83b9 100644 Binary files a/docs/assets/middleware/ros2/px4_ros2_interface_lib/mode_requirements_diagram.png and b/docs/assets/middleware/ros2/px4_ros2_interface_lib/mode_requirements_diagram.png differ diff --git a/docs/assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg b/docs/assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg index a26e1ca92f..45acc7593f 100644 --- a/docs/assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg +++ b/docs/assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg @@ -1 +1 @@ - + diff --git a/docs/assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg b/docs/assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg new file mode 100644 index 0000000000..7d40a33dfa --- /dev/null +++ b/docs/assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg @@ -0,0 +1,4 @@ + + + +
Position Setpoint
Speed Setpoint
Throttle Setpoint
Attitude Setpoint
Rate Setpoint
Steering Setpoint
Actuator Setpoints
Position Controller
Speed Controller
Attitude Controller
Rate Controller
Actuator Controller
Position Setpoint
position_ned
(Optional) start_ned
(Optional) cruising_speed
(Optional) arrival_speed
(Optional) yaw (mecanum only)
Speed Setpoint
speed_body_x
speed_body_y (mecanum only)
Attitude Setpoint
yaw_setpoint
Throttle Setpoint
throttle_body_x
throttle_body_x (mecanum only)
Rate Setpoint
yaw_rate_setpoint
Steering Setpoint
normalized_steering_setpoint
Publish
Subscribe
diff --git a/docs/assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg b/docs/assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg new file mode 100644 index 0000000000..79a358aec5 --- /dev/null +++ b/docs/assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg @@ -0,0 +1,4 @@ + + + +
Default Actions
MissionExecutor
JSON Mission Definition
MissionFileMonitor
/path/to/mission.json
MAVFTP / Cloud / ...
Define mission inside application
Or
Register
TrajectoryExecutorInterface
multicopter::
WaypointTrajectoryExecutor
Inherits
MyTrajectoryExecutor
Register
ActionInterface
MyCustomAction
Rtl
Land
Takeoff
Hold
OnResume
OnFailure
ChangeSettings
Inherits
diff --git a/docs/assets/middleware/zenoh/architecture-px4-zenoh.svg b/docs/assets/middleware/zenoh/architecture-px4-zenoh.svg new file mode 100644 index 0000000000..e3d0fcc2fe --- /dev/null +++ b/docs/assets/middleware/zenoh/architecture-px4-zenoh.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + + Rectangle + Zenoh RMW implementation rmw_zenoh + + + + + + + Zenoh RMW implementationrmw_zenoh + + Rectangle.2 + ROS Middleware (RMW) API + + + + + + + ROS Middleware (RMW) API + + Rectangle.4 + ROS 2 Node + + + + + + + ROS 2Node + + Rectangle.5 + ROS 2 Node + + + + + + + ROS 2Node + + Rectangle.6 + PX4 Zenoh-Pico Node + + + + + + + PX4 Zenoh-Pico Node + + Rectangle.7 + uORB Topic α + + + + + + + uORB Topic α + + Rectangle.8 + uORB Topic β + + + + + + + uORB Topic β + + Rectangle.9 + uORB Topic γ + + + + + + + uORB Topic γ + + Rectangle.10 + ROS2 Topic α + + + + + + + ROS2 Topic α + + Rectangle.11 + ROS2 Topic β + + + + + + + ROS2 Topic β + + Rectangle.12 + ROS2 Topic γ + + + + + + + ROS2 Topic γ + + Rectangle.18 + PX4 + + + + + + + PX4 + + Rectangle.19 + Zenoh Router zenohd + + + + + + + Zenoh Routerzenohd + + Rectangle.20 + Linux + + + + + + + Linux + + Dynamic connector + + + + Dynamic connector.22 + + + + Dynamic connector.23 + + + + Sheet.24 + UART TCP UDP + + + + UARTTCPUDP + + diff --git a/docs/assets/simulation/gazebo/vehicles/rover_ackermann.png b/docs/assets/simulation/gazebo/vehicles/rover_ackermann.png index d6b305c000..c0c487efac 100644 Binary files a/docs/assets/simulation/gazebo/vehicles/rover_ackermann.png and b/docs/assets/simulation/gazebo/vehicles/rover_ackermann.png differ diff --git a/docs/assets/simulation/gazebo/vehicles/rover_differential.png b/docs/assets/simulation/gazebo/vehicles/rover_differential.png index 4d439029cb..5fa4c40a5f 100644 Binary files a/docs/assets/simulation/gazebo/vehicles/rover_differential.png and b/docs/assets/simulation/gazebo/vehicles/rover_differential.png differ diff --git a/docs/assets/simulation/gazebo/vehicles/rover_mecanum.png b/docs/assets/simulation/gazebo/vehicles/rover_mecanum.png new file mode 100644 index 0000000000..aff7b556c8 Binary files /dev/null and b/docs/assets/simulation/gazebo/vehicles/rover_mecanum.png differ diff --git a/docs/assets/simulation/px4_sitl_overview.svg b/docs/assets/simulation/px4_sitl_overview.svg index 56b514146f..3669177c63 100644 --- a/docs/assets/simulation/px4_sitl_overview.svg +++ b/docs/assets/simulation/px4_sitl_overview.svg @@ -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 + style="font-size:3.88056px;writing-mode:lr-tb;stroke-width:0.264583px">SimulatorMavlink.cpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/assets/site/px4_logo.svg b/docs/assets/site/px4_logo.svg new file mode 100644 index 0000000000..ade96659ab --- /dev/null +++ b/docs/assets/site/px4_logo.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index d3ae165ee6..041f0955da 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -7,6 +7,7 @@ - [Position Mode (MC)](flight_modes_mc/position.md) - [Position Slow Mode (MC)](flight_modes_mc/position_slow.md) - [Altitude Mode (MC)](flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](flight_modes_mc/manual_stabilized.md) - [Acro Mode (MC)](flight_modes_mc/acro.md) - [Orbit Mode (MC)](flight_modes_mc/orbit.md) @@ -34,7 +35,7 @@ - [Static Pressure Buildup](advanced_config/static_pressure_buildup.md) - [Flying (Basics)](flying/basic_flying_mc.md) - [Complete Vehicles](complete_vehicles_mc/index.md) - - [ModalAI Starling (PX4 Dev Kit)](complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling](complete_vehicles_mc/modalai_starling.md) - [PX4 Vision Kit](complete_vehicles_mc/px4_vision_kit.md) - [MindRacer BNF & RTF](complete_vehicles_mc/mindracer_BNF_RTF.md) - [MindRacer 210](complete_vehicles_mc/mindracer210.md) @@ -55,11 +56,14 @@ - [DJI F450 (CUAV v5 nano)](frames_multicopter/dji_f450_cuav_5nano.md) - [Planes (Fixed-Wing)](frames_plane/index.md) + - [Features](features_fw/index.md) + - [Gain compression](features_fw/gain_compression.md) - [Assembly](assembly/assembly_fw.md) - [Config/Tuning](config_fw/index.md) - [Auto-tune](config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](flying/basic_flying_fw.md) @@ -89,6 +93,7 @@ - [Back-transition Tuning](config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [Flight Modes](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -124,7 +129,7 @@ - [LED Meanings](getting_started/led_meanings.md) - [Tune/Sound Meanings](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) - + - [Asset Tracking](debug/asset_tracking.md) - [Hardware Selection & Setup](hardware/drone_parts.md) - [Flight Controllers (Autopilots)](flight_controller/index.md) - [Flight Controller Selection](getting_started/flight_controller_selection.md) @@ -157,6 +162,7 @@ - [mRo (3DR) Pixhawk Wiring Quickstart](assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](flight_controller/mindpx.md) - [AirMind MindRacer](flight_controller/mindracer.md) - [ARK Electronics ARKV6X](flight_controller/ark_v6x.md) @@ -172,6 +178,7 @@ - [CubePilot Cube Orange (CubePilot)](flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](flight_controller/cubepilot_cube_yellow.md) - [Cube Wiring Quickstart](assembly/quick_start_cube.md) + - [Gear Up AirBrainH743](flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](flight_controller/kakuteh7.md) @@ -180,12 +187,16 @@ - [Wiring Quickstart](assembly/quick_start_durandal.md) - [Holybro Pix32 v5](flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](assembly/quick_start_holybro_pix32_v5.md) + - [MicoAir H743 Lite](flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](flight_controller/modalai_voxl_2.md) - [mRo Control Zero F7](flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](flight_controller/spracingh7extreme.md) + - [SVehicle E2](flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](flight_controller/thepeach_r1.md) + - [AP-H743-R1](flight_controller/x-mav_ap-h743r1.md) - [Experimental Autopilots](flight_controller/autopilot_experimental.md) - [BeagleBone Blue](flight_controller/beaglebone_blue.md) - [Raspberry Pi 2/3 Navio2](flight_controller/raspberry_pi_navio2.md) @@ -236,18 +247,23 @@ - [TFSlot Airspeed Sensor](sensor/airspeed_tfslot.md) - [Barometers](sensor/barometer.md) - [Distance Sensors \(Rangefinders\)](sensor/rangefinders.md) - - [Lightware Lidars (SF/LW)](sensor/sfxx_lidar.md) - - [Lightware SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md) - [Ainstein US-D1 Standard Radar Altimeter](sensor/ulanding_radar.md) - - [LeddarOne Lidar](sensor/leddar_one.md) + - [ARK DIST SR (CAN/UART)](dronecan/ark_dist.md) + - [ARK DIST MR (CAN/UART)](dronecan/ark_dist_mr.md) - [Benewake TFmini Lidar](sensor/tfmini.md) + - [LeddarOne Lidar](sensor/leddar_one.md) - [Lidar-Lite](sensor/lidar_lite.md) + - [Lightware Lidars (SF/LW/GRF)](sensor/sfxx_lidar.md) + - [Lightware SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md) + - [Lightware GRF250/GRF500 Gimbal Lidar](sensor/grf_lidar.md) - [TeraRanger](sensor/teraranger.md) - [✘ Lanbao PSK-CM8JL65-CC5](sensor/cm8jl65_ir_distance_sensor.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface (CAN)](dronecan/avanon_laser_interface.md) - [GNSS (GPS)](gps_compass/index.md) - [ARK GPS (CAN)](dronecan/ark_gps.md) + - [ARK DAN GPS](gps_compass/ark_dan_gps.md) - [ARK SAM GPS](gps_compass/ark_sam_gps.md) + - [ARK SAM GPS MINI](gps_compass/ark_sam_gps_mini.md) - [ARK TESEO GPS](dronecan/ark_teseo_gps.md) - [CUAV NEO 3 GPS](gps_compass/gps_cuav_neo_3.md) - [CUAV NEO 3 Pro GPS (CAN)](gps_compass/gps_cuav_neo_3pro.md) @@ -258,7 +274,11 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) + - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) + - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) - [ARK MOSAIC-X5 RTK GPS (CAN)](dronecan/ark_mosaic__rtk_gps.md) - [RTK GPS Heading with Dual u-blox F9P](gps_compass/u-blox_f9p_heading.md) - [CUAV C-RTK](gps_compass/rtk_gps_cuav_c-rtk.md) @@ -281,6 +301,8 @@ - [CubePilot Here+ (Discontined)](gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](sensor/inertial_navigation_systems.md) - [InertialLabs](sensor/inertiallabs.md) + - [MicroStrain](sensor/microstrain.md) + - [sbgECom](sensor/sbgecom.md) - [VectorNav](sensor/vectornav.md) - [Optical Flow](sensor/optical_flow.md) - [ARK Flow](dronecan/ark_flow.md) @@ -295,15 +317,17 @@ - [Actuator Allocation](config/actuators.md) - [ESC Calibration](advanced_config/esc_calibration.md) - [ESCs & Motors](peripherals/esc_motors.md) + - [ESC Protocols](esc/esc_protocols.md) - [PWM ESCs and Servos](peripherals/pwm_escs_and_servo.md) - [DShot ESCs](peripherals/dshot.md) - [OneShot ESCs and Servos](peripherals/oneshot.md) - [DroneCAN ESCs](dronecan/escs.md) - - [Zubax Telega](dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](dronecan/sapog.md) - - [Holybro Kotleta](dronecan/holybro_kotleta.md) - - [Vertiq](peripherals/vertiq.md) - - [VESC](peripherals/vesc.md) + - [ARK 4IN1 ESC](esc/ark_4in1_esc.md) + - [Holybro Kotleta](dronecan/holybro_kotleta.md) + - [Vertiq Motor/ESC Modules](peripherals/vertiq.md) + - [VESC Project ESCs](peripherals/vesc.md) + - [Zubax Telega ESCs](dronecan/zubax_telega.md) - [Radio Control (RC)](getting_started/rc_transmitter_receiver.md) - [Radio Setup](config/radio.md) - [Flight Modes](config/flight_mode.md) @@ -329,18 +353,20 @@ - [FrSky Telemetry](peripherals/frsky_telemetry.md) - [TBS Crossfire (CRSF) Telemetry](telemetry/crsf_telemetry.md) - [Satellite Comms (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) - [Power Systems](power_systems/index.md) - [Battery Estimation Tuning](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) - [Power Modules/PDB](power_module/index.md) + - [ARK PAB Power Module](power_module/ark_pab_power_module.md) + - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](power_module/ark_12s_payload_power_module.md) - [CUAV HV pm](power_module/cuav_hv_pm.md) - [CUAV CAN PMU](dronecan/cuav_can_pmu.md) - [Holybro PM02](power_module/holybro_pm02.md) - [Holybro PM07](power_module/holybro_pm07_pixhawk4_power_module.md) - [Holybro PM06 V2](power_module/holybro_pm06_pixhawk4mini_power_module.md) - - [ARK PAB Power Module](power_module/ark_pab_power_module.md) - - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) - [Holybro PM02D (digital)](power_module/holybro_pm02d.md) - [Holybro PM03D (digital)](power_module/holybro_pm03d.md) - [Pomegranate Systems Power Module](dronecan/pomegranate_systems_pm.md) @@ -412,6 +438,7 @@ - [Attitude Tuning](config_rover/attitude_tuning.md) - [Velocity Tuning](config_rover/velocity_tuning.md) - [Position Tuning](config_rover/position_tuning.md) + - [Apps & API](flight_modes_rover/api.md) - [Complete Vehicles](complete_vehicles_rover/index.md) - [Aion Robotics R1](complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](frames_sub/index.md) @@ -477,8 +504,10 @@ - [UART/Serial Ports](uart/index.md) - [Port-Configurable Serial Drivers](uart/user_configurable_serial_driver.md) - [RTK GPS (Integration)](advanced/rtk_gps.md) + - [PPS Time Synchronization](advanced/pps_time_sync.md) - [Middleware](middleware/index.md) - [uORB Messaging](middleware/uorb.md) + - [uORB Docs Standard](uorb/uorb_documentation.md) - [uORB Graph](middleware/uorb_graph.md) - [uORB Message Reference](msg_docs/index.md) - [Versioned](msg_docs/versioned_messages.md) @@ -541,6 +570,7 @@ - [DebugKeyValue](msg_docs/DebugKeyValue.md) - [DebugValue](msg_docs/DebugValue.md) - [DebugVect](msg_docs/DebugVect.md) + - [DeviceInformation](msg_docs/DeviceInformation.md) - [DifferentialPressure](msg_docs/DifferentialPressure.md) - [DistanceSensor](msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](msg_docs/DistanceSensorModeChangeRequest.md) @@ -573,6 +603,7 @@ - [FollowTargetEstimator](msg_docs/FollowTargetEstimator.md) - [FollowTargetStatus](msg_docs/FollowTargetStatus.md) - [FuelTankStatus](msg_docs/FuelTankStatus.md) + - [GainCompression](msg_docs/GainCompression.md) - [GeneratorStatus](msg_docs/GeneratorStatus.md) - [GeofenceResult](msg_docs/GeofenceResult.md) - [GeofenceStatus](msg_docs/GeofenceStatus.md) @@ -659,10 +690,10 @@ - [RoverPositionSetpoint](msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](msg_docs/RoverVelocityStatus.md) - [Rpm](msg_docs/Rpm.md) - [RtlStatus](msg_docs/RtlStatus.md) - [RtlTimeEstimate](msg_docs/RtlTimeEstimate.md) @@ -674,6 +705,7 @@ - [SensorCombined](msg_docs/SensorCombined.md) - [SensorCorrection](msg_docs/SensorCorrection.md) - [SensorGnssRelative](msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](msg_docs/SensorGnssStatus.md) - [SensorGps](msg_docs/SensorGps.md) - [SensorGyro](msg_docs/SensorGyro.md) - [SensorGyroFft](msg_docs/SensorGyroFft.md) @@ -683,6 +715,7 @@ - [SensorOpticalFlow](msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](msg_docs/SensorPreflightMag.md) - [SensorSelection](msg_docs/SensorSelection.md) + - [SensorTemp](msg_docs/SensorTemp.md) - [SensorUwb](msg_docs/SensorUwb.md) - [SensorsStatus](msg_docs/SensorsStatus.md) - [SensorsStatusImu](msg_docs/SensorsStatusImu.md) @@ -719,9 +752,13 @@ - [YawEstimatorStatus](msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](msg_docs/AirspeedValidatedV0.md) - [ArmingCheckReplyV0](msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](msg_docs/ArmingCheckRequestV0.md) - [BatteryStatusV0](msg_docs/BatteryStatusV0.md) + - [ConfigOverridesV0](msg_docs/ConfigOverridesV0.md) - [EventV0](msg_docs/EventV0.md) - [HomePositionV0](msg_docs/HomePositionV0.md) + - [RegisterExtComponentReplyV0](msg_docs/RegisterExtComponentReplyV0.md) + - [RegisterExtComponentRequestV0](msg_docs/RegisterExtComponentRequestV0.md) - [VehicleAttitudeSetpointV0](msg_docs/VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](msg_docs/VehicleStatusV0.md) @@ -734,6 +771,7 @@ - [Standard Modes Protocol](mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](middleware/uxrce_dds.md) - [UORB Bridged to ROS 2](middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](middleware/zenoh.md) - [Modules & Commands](modules/modules_main.md) - [Autotune](modules/modules_autotune.md) - [Commands](modules/modules_command.md) @@ -751,6 +789,7 @@ - [Rpm Sensor](modules/modules_driver_rpm_sensor.md) - [Radio Control](modules/modules_driver_radio_control.md) - [Transponder](modules/modules_driver_transponder.md) + - [adc](modules/modules_driver_adc.md) - [Estimators](modules/modules_estimator.md) - [Simulations](modules/modules_simulation.md) - [System](modules/modules_system.md) @@ -787,9 +826,11 @@ - [Camera Integration/Architecture](camera/camera_architecture.md) - [Computer Vision](advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [Installing driver for Intel RealSense R200](advanced/realsense_intel_driver.md) - [Switching State Estimators](advanced/switching_state_estimators.md) - [Out-of-Tree Modules](advanced/out_of_tree_modules.md) @@ -823,8 +864,10 @@ - [Test MC_04 - Failsafe Testing](test_cards/mc_04_failsafe_testing.md) - [Test MC_05 - Manual Modes (Inside)](test_cards/mc_05_indoor_flight_manual_modes.md) - [Test MC_06 - Optical Flow (Inside)](test_cards/mc_06_optical_flow.md) - - [Test MC_07 - VIO (Inside)](test_cards/mc_07_vio.md) + - [Test MC_07 - Optical Flow Low Mount](test_cards/mc_07_optical_flow_low_mount.md) - [Test MC_08 - DSHOT ESC](test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](test_cards/mc_10_optical_flow_gps_mixed.md) - [Unit Tests](test_and_ci/unit_tests.md) - [Fuzz Tests](test_and_ci/fuzz_tests.md) - [Continuous Integration](test_and_ci/continous_integration.md) @@ -844,6 +887,7 @@ - [PX4 ROS 2 Interface Library](ros2/px4_ros2_interface_lib.md) - [Control Interface](ros2/px4_ros2_control_interface.md) - [Navigation Interface](ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](ros/ros1.md) - [ROS/MAVROS Installation Guide](ros/mavros_installation.md) @@ -865,7 +909,9 @@ - [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) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/en/_sidebar.md b/docs/en/_sidebar.md index e8807c40eb..e4d2991d98 100644 --- a/docs/en/_sidebar.md +++ b/docs/en/_sidebar.md @@ -1,15 +1,15 @@ -- [Introduction](/index.md) +- [Introduction](/index.md) - [Basic Concepts](/getting_started/px4_basic_concepts.md) - [Multicopters](/frames_multicopter/index.md) - - [Features](/features_mc/index.md) - [Flight Modes](/flight_modes_mc/index.md) - [Position Mode (MC)](/flight_modes_mc/position.md) - [Position Slow Mode (MC)](/flight_modes_mc/position_slow.md) - [Altitude Mode (MC)](/flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](/flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](/flight_modes_mc/manual_stabilized.md) - [Acro Mode (MC)](/flight_modes_mc/acro.md) - [Orbit Mode (MC)](/flight_modes_mc/orbit.md) @@ -58,12 +58,14 @@ - [DJI F450 (CUAV v5 nano)](/frames_multicopter/dji_f450_cuav_5nano.md) - [Planes (Fixed-Wing)](/frames_plane/index.md) - + - [Features](/features_fw/index.md) + - [Gain compression](/features_fw/gain_compression.md) - [Assembly](/assembly/assembly_fw.md) - [Config/Tuning](/config_fw/index.md) - [Auto-tune](/config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](/config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](/config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](/config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](/config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](/config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](/flying/basic_flying_fw.md) @@ -86,7 +88,6 @@ - [Wing Wing Z84 (Pixracer)](/frames_plane/wing_wing_z84.md) - [VTOL](/frames_vtol/index.md) - - [Assembly](/assembly/assembly_vtol.md) - [VTOL Config/Tuning](/config_vtol/index.md) - [Auto-tune](/config/autotune_vtol.md) @@ -111,7 +112,6 @@ - [Complete Vehicles](/complete_vehicles_vtol/index.md) - [Operations](/config/operations.md) - - [Safety](/config/safety_intro.md) - [Safety Configuration (Failsafes)](/config/safety.md) - [Failsafe Simulation](/config/safety_simulation.md) @@ -132,7 +132,6 @@ - [QGroundControl Flight-Readiness Status](/flying/pre_flight_checks.md) - [Hardware Selection & Setup](/hardware/drone_parts.md) - - [Flight Controllers (Autopilots)](/flight_controller/index.md) - [Flight Controller Selection](/getting_started/flight_controller_selection.md) - [Pixhawk Series](/flight_controller/pixhawk_series.md) @@ -164,18 +163,18 @@ - [mRo (3DR) Pixhawk Wiring Quickstart](/assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](/flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](/flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](/flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](/flight_controller/mindpx.md) - [AirMind MindRacer](/flight_controller/mindracer.md) - [ARK Electronics ARKV6X](/flight_controller/ark_v6x.md) - [ARK FPV Flight Controller](/flight_controller/ark_fpv.md) - [ARK Pi6X Flow Flight Controller](/flight_controller/ark_pi6x.md) - - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV Nora](/flight_controller/cuav_nora.md) - [CUAV V5+ (FMUv5)](/flight_controller/cuav_v5_plus.md) - [Wiring Quickstart](/assembly/quick_start_cuav_v5_plus.md) - [CUAV V5 nano (FMUv5)](/flight_controller/cuav_v5_nano.md) - [CUAV V5 nano Wiring Quickstart](/assembly/quick_start_cuav_v5_nano.md) - - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) + - [CUAV X25 EVO](/flight_controller/cuav_x25-evo.md) - [CubePilot Cube Orange+ (CubePilot)](/flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange (CubePilot)](/flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](/flight_controller/cubepilot_cube_yellow.md) @@ -188,13 +187,13 @@ - [Wiring Quickstart](/assembly/quick_start_durandal.md) - [Holybro Pix32 v5](/flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](/assembly/quick_start_holybro_pix32_v5.md) - - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) - - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [MicoAir H743 Lite](/flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](/flight_controller/modalai_voxl_2.md) - - [mRobotics-X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - - [mRo Control Zero F7)](/flight_controller/mro_control_zero_f7.md) + - [mRo Control Zero F7](/flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](/flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](/flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](/flight_controller/spracingh7extreme.md) + - [SVehicle E2](/flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](/flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](/flight_controller/thepeach_r1.md) - [Experimental Autopilots](/flight_controller/autopilot_experimental.md) @@ -206,18 +205,20 @@ - [Discontinued Autopilots/Vehicles](/flight_controller/autopilot_discontinued.md) - [Drotek Dropix (FMUv2)](/flight_controller/dropix.md) - [Omnibus F4 SD](/flight_controller/omnibus_f4_sd.md) - - [BetaFPV Beta75X 2S Brushless Whoop](/complete_vehicles_mc/betafpv_beta75x.md) - [Bitcraze Crazyflie 2.0 ](/complete_vehicles_mc/crazyflie2.md) - [Aerotenna OcPoC-Zynq Mini](/flight_controller/ocpoc_zynq.md) + - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV v5](/flight_controller/cuav_v5.md) + - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) - [Holybro Kakute F7](/flight_controller/kakutef7.md) - [Holybro Pixfalcon](/flight_controller/pixfalcon.md) - [Holybro pix32 (FMUv2)](/flight_controller/holybro_pix32.md) + - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) + - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [mRo X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - [mRo AUAV-X2](/flight_controller/auav_x2.md) - [NXP RDDRONE-FMUK66 FMU](/flight_controller/nxp_rddrone_fmuk66.md) - [3DR Pixhawk 1](/flight_controller/pixhawk.md) - - [Snapdragon Flight](/flight_controller/snapdragon_flight.md) - - [Intel® Aero RTF Drone](/complete_vehicles_mc/intel_aero.md) - [Pixhawk Autopilot Bus (PAB) & Carriers](/flight_controller/pixhawk_autopilot_bus.md) - [ARK Electronics Pixhawk Autopilot Bus Carrier](/flight_controller/ark_pab.md) - [Mounting the Flight Controller](/assembly/mount_and_orient_controller.md) @@ -241,21 +242,26 @@ - [Compass Power Compensation](/advanced_config/compass_power_compensation.md) - [Airspeed Sensors](/sensor/airspeed.md) - [Calibration](/config/airspeed.md) + - [Airspeed Validation](/advanced_config/airspeed_validation.md) - [TFSlot Airspeed Sensor](/sensor/airspeed_tfslot.md) - [Barometers](/sensor/barometer.md) - [Distance Sensors \(Rangefinders\)](/sensor/rangefinders.md) + - [Ainstein US-D1 Standard Radar Altimeter](/sensor/ulanding_radar.md) + - [ARK DIST SR (CAN/UART)](/dronecan/ark_dist.md) + - [ARK DIST MR (CAN/UART)](/dronecan/ark_dist_mr.md) + - [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 SF45 Rotary Lidar](/sensor/sf45_rotating_lidar.md) - - [Ainstein US-D1 Standard Radar Altimeter](/sensor/ulanding_radar.md) - - [LeddarOne Lidar](/sensor/leddar_one.md) - - [Benewake TFmini Lidar](/sensor/tfmini.md) - - [Lidar-Lite](/sensor/lidar_lite.md) - [TeraRanger](/sensor/teraranger.md) - [✘ Lanbao PSK-CM8JL65-CC5](/sensor/cm8jl65_ir_distance_sensor.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface (CAN)](/dronecan/avanon_laser_interface.md) - [GNSS (GPS)](/gps_compass/index.md) - [ARK GPS (CAN)](/dronecan/ark_gps.md) + - [ARK DAN GPS](/gps_compass/ark_dan_gps.md) - [ARK SAM GPS](/gps_compass/ark_sam_gps.md) + - [ARK SAM GPS MINI](/gps_compass/ark_sam_gps_mini.md) - [ARK TESEO GPS](/dronecan/ark_teseo_gps.md) - [CUAV NEO 3 GPS](/gps_compass/gps_cuav_neo_3.md) - [CUAV NEO 3 Pro GPS (CAN)](/gps_compass/gps_cuav_neo_3pro.md) @@ -267,11 +273,14 @@ - [Sky-Drones SmartAP GPS](/gps_compass/gps_smartap.md) - [RTK GNSS](/gps_compass/rtk_gps.md) - [ARK RTK GPS (CAN)](/dronecan/ark_rtk_gps.md) + - [ARK RTK GPS L1 L5 (CAN)](/dronecan/ark_rtk_gps_l1_l2.md) + - [ARK X20 RTK GPS (CAN)](/dronecan/ark_x20_rtk_gps.md) - [ARK MOSAIC-X5 RTK GPS (CAN)](/dronecan/ark_mosaic__rtk_gps.md) - [RTK GPS Heading with Dual u-blox F9P](/gps_compass/u-blox_f9p_heading.md) - [CUAV C-RTK](/gps_compass/rtk_gps_cuav_c-rtk.md) - [CUAV C-RTK2 PPK/RTK GNSS](/gps_compass/rtk_gps_cuav_c-rtk2.md) - [CUAV C-RTK 9Ps](/gps_compass/rtk_gps_cuav_c-rtk-9ps.md) + - [DATAGNSS NANO HRTK GNSS](/gps_compass/rtk_gps_datagnss_nano_hrtk.md) - [DATAGNSS GEM1305 RTK GNSS](/gps_compass/rtk_gps_gem1305.md) - [Femtones MINI2 Receiver](/gps_compass/rtk_gps_fem_mini2.md) - [Freefly RTK GPS](/gps_compass/rtk_gps_freefly.md) @@ -287,6 +296,9 @@ - [Trimble MB-Two](/gps_compass/rtk_gps_trimble_mb_two.md) - [CubePilot Here+ (Discontined)](/gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](/sensor/inertial_navigation_systems.md) + - [InertialLabs](/sensor/inertiallabs.md) + - [MicroStrain](/sensor/microstrain.md) + - [sbgECom](/sensor/sbgecom.md) - [VectorNav](/sensor/vectornav.md) - [Optical Flow](/sensor/optical_flow.md) - [ARK Flow](/dronecan/ark_flow.md) @@ -308,7 +320,6 @@ - [Zubax Telega](/dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](/dronecan/sapog.md) - [Holybro Kotleta](/dronecan/holybro_kotleta.md) - - [Zubax Orel](/dronecan/zubax_orel.md) - [Vertiq](/peripherals/vertiq.md) - [VESC](/peripherals/vesc.md) - [Radio Control (RC)](/getting_started/rc_transmitter_receiver.md) @@ -320,6 +331,7 @@ - [Telemetry Radios](/telemetry/index.md) - [SiK Radio](/telemetry/sik_radio.md) - [RFD900 (SiK) Telemetry Radio](/telemetry/rfd900_telemetry.md) + - [ThunderFly TFSIK01 Telemetry Radio](/telemetry/tfsik_telemetry.md) - [HolyBro (SIK) Telemetry Radio](/telemetry/holybro_sik_radio.md) - [Telemetry Wifi](/telemetry/telemetry_wifi.md) - [ESP8266 WiFi Module](/telemetry/esp8266_wifi_module.md) @@ -335,17 +347,19 @@ - [FrSky Telemetry](/peripherals/frsky_telemetry.md) - [TBS Crossfire (CRSF) Telemetry](/telemetry/crsf_telemetry.md) - [Satellite Comms (Iridium/RockBlock)](/advanced_features/satcom_roadblock.md) + - [Power Systems](/power_systems/index.md) - [Battery Estimation Tuning](/config/battery.md) - [Battery Chemistry Overview](/power_systems/battery_chemistry.md) - [Power Modules/PDB](/power_module/index.md) + - [ARK PAB Power Module](/power_module/ark_pab_power_module.md) + - [ARK 12S PAB Power Module](/power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](/power_module/ark_12s_payload_power_module.md) - [CUAV HV pm](/power_module/cuav_hv_pm.md) - [CUAV CAN PMU](/dronecan/cuav_can_pmu.md) - [Holybro PM02](/power_module/holybro_pm02.md) - [Holybro PM07](/power_module/holybro_pm07_pixhawk4_power_module.md) - [Holybro PM06 V2](/power_module/holybro_pm06_pixhawk4mini_power_module.md) - - [ARK PAB Power Module](/power_module/ark_pab_power_module.md) - - [ARK 12S PAB Power Module](/power_module/ark_12s_pab_power_module.md) - [Holybro PM02D (digital)](/power_module/holybro_pm02d.md) - [Holybro PM03D (digital)](/power_module/holybro_pm03d.md) - [Pomegranate Systems Power Module](/dronecan/pomegranate_systems_pm.md) @@ -401,7 +415,6 @@ - [Full Parameter Reference](/advanced_config/parameter_reference.md) - [Other Vehicles](/airframes/index.md) - - [Airships (experimental)](/frames_airship/index.md) - [Autogyros (experimental)](/frames_autogyro/index.md) - [ThunderFly Auto-G2 (Holybro pix32)](/frames_autogyro/thunderfly_auto_g2.md) @@ -409,17 +422,18 @@ - [Helicopter (experimental)](/frames_helicopter/index.md) - [Helicopter Config/Tuning](/config_heli/index.md) - [Rovers (experimental)](/frames_rover/index.md) - - [Ackermann Rovers](/frames_rover/ackermann.md) - - [Drive Modes](/flight_modes_rover/ackermann.md) - - [Configuration/Tuning](/config_rover/ackermann.md) - - [Differential Rovers](/frames_rover/differential.md) - - [Drive Modes](/flight_modes_rover/differential.md) - - [Configuration/Tuning](/config_rover/differential.md) - - [Aion Robotics R1](/frames_rover/aion_r1.md) - - [Mecanum Rovers](/frames_rover/mecanum.md) - - [Drive Modes](/flight_modes_rover/mecanum.md) - - [Configuration/Tuning](/config_rover/mecanum.md) - - [(Deprecated) Rover Position Control](/frames_rover/rover_position_control.md) + - [Drive Modes](/flight_modes_rover/index.md) + - [Manual](/flight_modes_rover/manual.md) + - [Auto](/flight_modes_rover/auto.md) + - [Configuration/Tuning](/config_rover/index.md) + - [Basic Setup](/config_rover/basic_setup.md) + - [Rate Tuning](/config_rover/rate_tuning.md) + - [Attitude Tuning](/config_rover/attitude_tuning.md) + - [Velocity Tuning](/config_rover/velocity_tuning.md) + - [Position Tuning](/config_rover/position_tuning.md) + - [Apps & API](/flight_modes_rover/api.md) + - [Complete Vehicles](/complete_vehicles_rover/index.md) + - [Aion Robotics R1](/complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](/frames_sub/index.md) - [BlueROV2](/frames_sub/bluerov2.md) - [Airframes Reference](/airframes/airframe_reference.md) @@ -483,6 +497,7 @@ - [UART/Serial Ports](/uart/index.md) - [Port-Configurable Serial Drivers](/uart/user_configurable_serial_driver.md) - [RTK GPS (Integration)](/advanced/rtk_gps.md) + - [PPS Time Synchronization](/advanced/pps_time_sync.md) - [Middleware](/middleware/index.md) - [uORB Messaging](/middleware/uorb.md) - [uORB Graph](/middleware/uorb_graph.md) @@ -531,6 +546,7 @@ - [Airspeed](/msg_docs/Airspeed.md) - [AirspeedWind](/msg_docs/AirspeedWind.md) - [AutotuneAttitudeControlStatus](/msg_docs/AutotuneAttitudeControlStatus.md) + - [BatteryInfo](/msg_docs/BatteryInfo.md) - [ButtonEvent](/msg_docs/ButtonEvent.md) - [CameraCapture](/msg_docs/CameraCapture.md) - [CameraStatus](/msg_docs/CameraStatus.md) @@ -549,6 +565,7 @@ - [DifferentialPressure](/msg_docs/DifferentialPressure.md) - [DistanceSensor](/msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](/msg_docs/DistanceSensorModeChangeRequest.md) + - [DronecanNodeStatus](/msg_docs/DronecanNodeStatus.md) - [Ekf2Timestamps](/msg_docs/Ekf2Timestamps.md) - [EscReport](/msg_docs/EscReport.md) - [EscStatus](/msg_docs/EscStatus.md) @@ -577,6 +594,7 @@ - [FollowTargetEstimator](/msg_docs/FollowTargetEstimator.md) - [FollowTargetStatus](/msg_docs/FollowTargetStatus.md) - [FuelTankStatus](/msg_docs/FuelTankStatus.md) + - [GainCompression](/msg_docs/GainCompression.md) - [GeneratorStatus](/msg_docs/GeneratorStatus.md) - [GeofenceResult](/msg_docs/GeofenceResult.md) - [GeofenceStatus](/msg_docs/GeofenceStatus.md) @@ -623,6 +641,7 @@ - [MountOrientation](/msg_docs/MountOrientation.md) - [NavigatorMissionItem](/msg_docs/NavigatorMissionItem.md) - [NavigatorStatus](/msg_docs/NavigatorStatus.md) + - [NeuralControl](/msg_docs/NeuralControl.md) - [NormalizedUnsignedSetpoint](/msg_docs/NormalizedUnsignedSetpoint.md) - [ObstacleDistance](/msg_docs/ObstacleDistance.md) - [OffboardControlMode](/msg_docs/OffboardControlMode.md) @@ -662,10 +681,10 @@ - [RoverPositionSetpoint](/msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](/msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](/msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](/msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](/msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](/msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](/msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](/msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](/msg_docs/RoverVelocityStatus.md) - [Rpm](/msg_docs/Rpm.md) - [RtlStatus](/msg_docs/RtlStatus.md) - [RtlTimeEstimate](/msg_docs/RtlTimeEstimate.md) @@ -677,6 +696,7 @@ - [SensorCombined](/msg_docs/SensorCombined.md) - [SensorCorrection](/msg_docs/SensorCorrection.md) - [SensorGnssRelative](/msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](/msg_docs/SensorGnssStatus.md) - [SensorGps](/msg_docs/SensorGps.md) - [SensorGyro](/msg_docs/SensorGyro.md) - [SensorGyroFft](/msg_docs/SensorGyroFft.md) @@ -686,6 +706,7 @@ - [SensorOpticalFlow](/msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](/msg_docs/SensorPreflightMag.md) - [SensorSelection](/msg_docs/SensorSelection.md) + - [SensorTemp](/msg_docs/SensorTemp.md) - [SensorUwb](/msg_docs/SensorUwb.md) - [SensorsStatus](/msg_docs/SensorsStatus.md) - [SensorsStatusImu](/msg_docs/SensorsStatusImu.md) @@ -721,7 +742,16 @@ - [Wind](/msg_docs/Wind.md) - [YawEstimatorStatus](/msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](/msg_docs/AirspeedValidatedV0.md) + - [ArmingCheckReplyV0](/msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](/msg_docs/ArmingCheckRequestV0.md) + - [BatteryStatusV0](/msg_docs/BatteryStatusV0.md) + - [ConfigOverridesV0](/msg_docs/ConfigOverridesV0.md) + - [EventV0](/msg_docs/EventV0.md) + - [HomePositionV0](/msg_docs/HomePositionV0.md) + - [RegisterExtComponentReplyV0](/msg_docs/RegisterExtComponentReplyV0.md) + - [RegisterExtComponentRequestV0](/msg_docs/RegisterExtComponentRequestV0.md) - [VehicleAttitudeSetpointV0](/msg_docs/VehicleAttitudeSetpointV0.md) + - [VehicleLocalPositionV0](/msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](/msg_docs/VehicleStatusV0.md) - [MAVLink Messaging](/mavlink/index.md) - [Adding Messages](/mavlink/adding_messages.md) @@ -732,6 +762,7 @@ - [Standard Modes Protocol](/mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](/middleware/uxrce_dds.md) - [UORB Bridged to ROS 2](/middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](/middleware/zenoh.md) - [Modules & Commands](/modules/modules_main.md) - [Autotune](/modules/modules_autotune.md) - [Commands](/modules/modules_command.md) @@ -749,6 +780,7 @@ - [Rpm Sensor](/modules/modules_driver_rpm_sensor.md) - [Radio Control](/modules/modules_driver_radio_control.md) - [Transponder](/modules/modules_driver_transponder.md) + - [adc](/modules/modules_driver_adc.md) - [Estimators](/modules/modules_estimator.md) - [Simulations](/modules/modules_simulation.md) - [System](/modules/modules_system.md) @@ -761,7 +793,7 @@ - [Debugging with GDB](/debug/gdb_debugging.md) - [SWD Debug Port](/debug/swd_debug.md) - [JLink Probe](/debug/probe_jlink.md) - - [Black Magic/DroneCode Probe](/debug/probe_bmp.md) + - [Black Magic/Zubax BugFace BF1 Probe](/debug/probe_bmp.md) - [STLink Probe](/debug/probe_stlink.md) - [MCU-Link Probe](/debug/probe_mculink.md) - [Hardfault Debugging](/debug/gdb_hardfault.md) @@ -785,6 +817,9 @@ - [Camera Integration/Architecture](/camera/camera_architecture.md) - [Computer Vision](/advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](/tutorials/motion-capture.md) + - [Neural Networks](/advanced/neural_networks.md) + - [Neural Network Module Utilities](/advanced/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](/advanced/tflm.md) - [Installing driver for Intel RealSense R200](/advanced/realsense_intel_driver.md) - [Switching State Estimators](/advanced/switching_state_estimators.md) - [Out-of-Tree Modules](/advanced/out_of_tree_modules.md) @@ -816,8 +851,14 @@ - [Test MC_02 - Full Autonomous](/test_cards/mc_02_full_autonomous.md) - [Test MC_03 - Auto Manual Mix](/test_cards/mc_03_auto_manual_mix.md) - [Test MC_04 - Failsafe Testing](/test_cards/mc_04_failsafe_testing.md) - - [Test MC_05 - Indoor Flight (Manual Modes)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_05 - Manual Modes (Inside)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_06 - Optical Flow (Inside)](/test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](/test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](/test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](/test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](/test_cards/mc_10_optical_flow_gps_mixed.md) - [Unit Tests](/test_and_ci/unit_tests.md) + - [Fuzz Tests](/test_and_ci/fuzz_tests.md) - [Continuous Integration](/test_and_ci/continous_integration.md) - [Integration Testing](/test_and_ci/integration_testing.md) - [MAVSDK Integration Testing](/test_and_ci/integration_testing_mavsdk.md) @@ -835,6 +876,7 @@ - [PX4 ROS 2 Interface Library](/ros2/px4_ros2_interface_lib.md) - [Control Interface](/ros2/px4_ros2_control_interface.md) - [Navigation Interface](/ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](/ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](/ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](/ros/ros1.md) - [ROS/MAVROS Installation Guide](/ros/mavros_installation.md) diff --git a/docs/en/advanced/gimbal_control.md b/docs/en/advanced/gimbal_control.md index b5a7596ec2..f449b74587 100644 --- a/docs/en/advanced/gimbal_control.md +++ b/docs/en/advanced/gimbal_control.md @@ -74,7 +74,7 @@ For example, you might have the following settings to assign the gimbal roll, pi ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -The PWM values to use for the disarmed, maximum and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low and high position in the slider. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. The values may also be provided in gimbal documentation. ## Gimbal Control in Missions diff --git a/docs/en/advanced/neural_networks.md b/docs/en/advanced/neural_networks.md index 4f85ee7e63..039259fd5f 100644 --- a/docs/en/advanced/neural_networks.md +++ b/docs/en/advanced/neural_networks.md @@ -1,115 +1 @@ -# Neural Networks - - - -::: warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Input - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### Output - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/en/advanced/pps_time_sync.md b/docs/en/advanced/pps_time_sync.md new file mode 100644 index 0000000000..fcd4291f70 --- /dev/null +++ b/docs/en/advanced/pps_time_sync.md @@ -0,0 +1,133 @@ +# PPS Time Synchronization (PX4 Integration) + +[Pulse Per Second](https://en.wikipedia.org/wiki/Pulse-per-second_signal) (PPS) time synchronization provides high-precision timing for GNSS receivers. +This page explains how PPS is integrated into PX4 and how to configure it. + +## Overview + +PPS (Pulse Per Second) is a timing signal provided by GNSS receivers that outputs an electrical pulse once per second, synchronized to UTC time. +The PPS signal provides a highly accurate timing reference that PX4 can use to: + +- Refine GNSS time measurements and compensate for clock drift +- Provide precise UTC timestamps for camera capture events (for photogrammetry and mapping applications) +- Enable offline position refinement through accurate time correlation + +## Supported Hardware + +PPS time synchronization can be supported on flight controllers that have a hardware timer input pin that can be configured for PPS capture, by [enabling the PPS capture driver](#enable-pps-driver-in-board-configuration) in the board configuration. + +Supported boards include (at time of writing): + +- [Ark FMUv6x](../flight_controller/ark_v6x.md) +- Auterion FMUv6x +- Auterion FMUv6s + +## Setup + +### Enable PPS Driver in Board Configuration + +The [PPS capture driver](../modules/modules_driver.md#pps-capture) must be enabled in the board configuration. +This is done by adding the following to your board's configuration: + +```ini +CONFIG_DRIVERS_PPS_CAPTURE=y +``` + +### Configure PPS Parameters + +The configuration varies depending on your flight controller hardware. + +#### FMUv6X + +For FMUv6X-based flight controllers, configure PWM AUX Timer 3 and Function 9: + +```sh +param set PWM_AUX_TIM3 -2 +param set PWM_AUX_FUNC9 2064 +param set PPS_CAP_ENABLE 1 +``` + +#### FMUv6S + +For FMUv6S-based flight controllers, configure PWM MAIN Timer 3 and Function 10: + +```sh +param set PWM_MAIN_TIM3 -2 +param set PWM_MAIN_FUNC10 2064 +param set PPS_CAP_ENABLE 1 +``` + +### Wiring + +The wiring configuration depends on your specific flight controller. + +#### Skynode X (FMUv6x) + +Connect the PPS signal from your GNSS module to the flight controller using the 11-pin or 6-pin GPS connector: + +For detailed pinout information, refer to: + +- [Skynode GPS Peripherals - Pinouts](https://docs.auterion.com/hardware-integration/skynode/peripherals/gps#pinouts) + +#### Skynode S (FMUv6S) + +For FMUv6S, you need to route the PPS signal separately: + +1. Connect your GNSS module using the standard 6-pin GPS connector: [Skynode S GPS Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#gps) +2. Connect the PPS signal from your GNSS module to the **PPM_IN** pin: [Skynode S Extras 1 Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#extras-1) + +#### ARK Jetson Carrier Board (FMUv6x) + +For ARK FMUv6X on the Jetson carrier board: + +1. Connect your GNSS module using either the 10-pin or 6-pin GPS connector: [ARK PAB GPS1 Interface](../flight_controller/ark_pab#gps1) +2. Connect the PPS signal to the **FMU_CAP** pin: [ARK PAB ADIO Interface](../flight_controller/ark_pab.md#adio) + +## Verification + +After configuring PPS, you can verify that it is working correctly: + +1. Connect to the [PX4 System Console](../debug/system_console.md) (via MAVLink shell or serial console). +2. Wait for GNSS fix. +3. Check the PPS capture status to confirm it is up and running: + + ```sh + pps_capture status + ``` + +4. You can also check the [PpsCapture](../msg_docs/PpsCapture.md) uORB topic + + ```sh + listener pps_capture + ``` + + Where you should see: `timestamp`, `rtc_timestamp`, and `pps_rate_exceeded_counter`. + +### PPS Capture Driver + +The PPS capture driver is located in `src/drivers/pps_capture` and uses hardware timer input capture to precisely measure the arrival time of each PPS pulse. + +Key features: + +- Sub-microsecond pulse capture precision (hardware-dependent) +- Automatic drift calculation and compensation +- Integration with the GNSS driver for refined time stamping + +See also: + +- [PPS Capture Driver Documentation](../modules/modules_driver.md#pps-capture) +- [PpsCapture Message](../msg_docs/PpsCapture.md) + +### Time Synchronization Flow + +1. GNSS module sends position/time data at ~1-20 Hz. +2. GNSS module outputs PPS pulse at 1 Hz, precisely aligned to UTC second boundary. +3. PPS capture driver measures the exact time of the PPS pulse arrival using hardware timer. +4. Driver calculates the offset between GNSS time (from UART data) and autopilot clock (from PPS measurement). +5. This offset is used to correct GNSS timestamps and improve sensor fusion accuracy. + +The PPS signal provides much higher temporal precision than the transmitted time data, which has latency and jitter from serial communication. + +::: warning +If the PPS driver does not sending any data for 5 seconds (despite having `PPS_CAP_ENABLE` set to 1), the `EKF2_GPS_DELAY` will be used instead for estimating the latency. +::: diff --git a/docs/en/advanced/px4_metadata.md b/docs/en/advanced/px4_metadata.md index bc0c61dca7..065b5fcf10 100644 --- a/docs/en/advanced/px4_metadata.md +++ b/docs/en/advanced/px4_metadata.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: ![Actuators Metadata](../../assets/diagrams/actuator_metadata_processing.svg) + - **Left**: the metadata is defined in `module.yml` files in different modules. diff --git a/docs/en/advanced_config/advanced_flight_controller_orientation_leveling.md b/docs/en/advanced_config/advanced_flight_controller_orientation_leveling.md index c960ab5eb7..28007b730f 100644 --- a/docs/en/advanced_config/advanced_flight_controller_orientation_leveling.md +++ b/docs/en/advanced_config/advanced_flight_controller_orientation_leveling.md @@ -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. - diff --git a/docs/en/advanced_config/airspeed_validation.md b/docs/en/advanced_config/airspeed_validation.md index f2cd82ea6a..7b4a708ea3 100644 --- a/docs/en/advanced_config/airspeed_validation.md +++ b/docs/en/advanced_config/airspeed_validation.md @@ -10,36 +10,13 @@ By default, the [Missing Data](#missing-data-check), [Data Stuck](#data-stuck-ch You can configure which checks are active using the [ASPD_DO_CHECKS](#aspd_do_checks_table) parameter. ::: -## Airspeed in PX4 - -PX4 handles multiple types of airspeed: - -- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). - -- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. - -- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. - While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. - -- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). - -The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. - ## CAS Scale Estimation -PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. -To compute the final TAS, standard environment conversions are applied (CAS → TAS). - -This CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. +Calibrated Airspeed (CAS) is the measured Indicated Airspeed (IAS) scaled to correct for sensor-specific and installation-related errors. +CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. If the estimated CAS scale is inaccurate, it can mask real airspeed faults or trigger false positives. -If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, you can manually set it using [ASPD_SCALE_n](#aspd_scale_n_table) (where `n` is the sensor number). -[ASPD_SCALE_APPLY](#aspd_scale_apply_table) can be used to configure when/if the estimated scale is applied. - -::: info -For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). -The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for [ASPD_SCALE_n](#aspd_scale_n_table). -::: +If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, follow the steps outlined in [Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md#recommended-first-flight-process). ## Validation Checks diff --git a/docs/en/advanced_config/bootloader_update_from_betaflight.md b/docs/en/advanced_config/bootloader_update_from_betaflight.md index 8c6cd1c2ad..e2b17103db 100644 --- a/docs/en/advanced_config/bootloader_update_from_betaflight.md +++ b/docs/en/advanced_config/bootloader_update_from_betaflight.md @@ -85,7 +85,7 @@ Flight controllers that have bootloader PX4-Autopilot `make` targets, can build The list of controllers for which this applies can be obtained by running the following `make` command, and noting the `make` targets that end in `_bootloader` ``` -$make list_config_targets +$ make list_config_targets ... cuav_nora_bootloader diff --git a/docs/en/advanced_config/bootloader_update_v6xrt.md b/docs/en/advanced_config/bootloader_update_v6xrt.md index a868f8e9db..9d7f92a4aa 100644 --- a/docs/en/advanced_config/bootloader_update_v6xrt.md +++ b/docs/en/advanced_config/bootloader_update_v6xrt.md @@ -63,7 +63,6 @@ The tool is available for Windows, Linux and macOS. ![Flash bootloader through Secure provisioning - Step 6](../../assets/advanced_config/bootloader_6xrt/bootloader_update_v6xrt_step6.png) 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" diff --git a/docs/en/advanced_config/esc_calibration.md b/docs/en/advanced_config/esc_calibration.md index 45409b9937..c8133ec870 100644 --- a/docs/en/advanced_config/esc_calibration.md +++ b/docs/en/advanced_config/esc_calibration.md @@ -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. diff --git a/docs/en/advanced_config/ethernet_setup.md b/docs/en/advanced_config/ethernet_setup.md index 5d0edf75b5..cc90e4aa3a 100644 --- a/docs/en/advanced_config/ethernet_setup.md +++ b/docs/en/advanced_config/ethernet_setup.md @@ -25,6 +25,7 @@ It may also be supported on other boards. Supported flight controllers include: +- [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) - [CUAV Pixhawk V6X](../flight_controller/cuav_pixhawk_v6x.md) - [Holybro Pixhawk 5X](../flight_controller/pixhawk5x.md) - [Holybro Pixhawk 6X](../flight_controller/pixhawk6x.md) diff --git a/docs/en/advanced_config/parameter_reference.md b/docs/en/advanced_config/parameter_reference.md index 1a7acb4363..2a179899a5 100644 --- a/docs/en/advanced_config/parameter_reference.md +++ b/docs/en/advanced_config/parameter_reference.md @@ -10,263 +10,47 @@ If a listed parameter is missing from the Firmware see: [Finding/Updating Parame -## UAVCAN Motor Parameters +## ADC -### ctl_bw (`INT32`) {#ctl_bw} +### ADC_ADS7953_EN (`INT32`) {#ADC_ADS7953_EN} -Speed controller bandwidth. +Enable ADS7953. -Speed controller bandwidth, in Hz. Higher values result in faster speed and current rise times, but may result in overshoot and higher current consumption. For fixed-wing aircraft, this value should be less than 50 Hz; for multirotors, values up to 100 Hz may provide improvements in responsiveness. +Enable the driver for the ADS7953 board -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 10 | 250 | | 75 | Hz | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | -### ctl_dir (`INT32`) {#ctl_dir} +### ADC_ADS7953_REFV (`FLOAT`) {#ADC_ADS7953_REFV} -Reverse direction. +Applied reference Voltage. -Motor spin direction as detected during initial enumeration. Use 0 or 1 to reverse direction. +The voltage applied to the ADS7953 board as reference -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | | 1 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 2.0 | 3.0 | 0.01 | 2.5 | V | -### ctl_gain (`FLOAT`) {#ctl_gain} +### ADC_TLA2528_EN (`INT32`) {#ADC_TLA2528_EN} -Speed (RPM) controller gain. +Enable TLA2528. -Determines controller -aggressiveness; units are amp-seconds per radian. Systems with -higher rotational inertia (large props) will need gain increased; -systems with low rotational inertia (small props) may need gain -decreased. Higher values result in faster response, but may result -in oscillation and excessive overshoot. Lower values result in a -slower, smoother response. +Enable the driver for the TLA2528 -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ----- | -|   | 0.00 | 1.00 | | 1 | C/rad | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | -### ctl_hz_idle (`FLOAT`) {#ctl_hz_idle} +### ADC_TLA2528_REFV (`FLOAT`) {#ADC_TLA2528_REFV} -Idle speed (e Hz). +Applied reference Voltage. -Idle speed (e Hz) +The voltage applied to the TLA2528 board as reference -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 3.5 | Hz | - -### ctl_start_rate (`INT32`) {#ctl_start_rate} - -Spin-up rate (e Hz/s). - -Spin-up rate (e Hz/s) - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ----- | -|   | 5 | 1000 | | 25 | 1/s^2 | - -### esc_index (`INT32`) {#esc_index} - -Index of this ESC in throttle command messages. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 15 | | 0 | - -### id_ext_status (`INT32`) {#id_ext_status} - -Extended status ID. - -Extended status ID - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 1 | 1000000 | | 20034 | - -### int_ext_status (`INT32`) {#int_ext_status} - -Extended status interval (µs). - -Extended status interval (µs) - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1000000 | | 50000 | us | - -### int_status (`INT32`) {#int_status} - -ESC status interval (µs). - -ESC status interval (µs) - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | 1000000 | | 50000 | us | - -### mot_i_max (`FLOAT`) {#mot_i_max} - -Motor current limit in amps. - -This determines the maximum -current controller setpoint, as well as the maximum allowable -current setpoint slew rate. This value should generally be set to -the continuous current rating listed in the motor’s specification -sheet, or set equal to the motor’s specified continuous power -divided by the motor voltage limit. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 1 | 80 | | 12 | A | - -### mot_kv (`INT32`) {#mot_kv} - -Motor Kv in RPM per volt. - -This can be taken from the motor’s -specification sheet; accuracy will help control performance but -some deviation from the specified value is acceptable. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ----- | -|   | 0 | 4000 | | 2300 | rpm/V | - -### mot_ls (`FLOAT`) {#mot_ls} - -READ ONLY: Motor inductance in henries. - -This is measured on start-up. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | H | - -### mot_num_poles (`INT32`) {#mot_num_poles} - -Number of motor poles. - -Used to convert mechanical speeds to -electrical speeds. This number should be taken from the motor’s -specification sheet. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 2 | 40 | | 14 | - -### mot_rs (`FLOAT`) {#mot_rs} - -READ ONLY: Motor resistance in ohms. - -This is measured on start-up. When -tuning a new motor, check that this value is approximately equal -to the value shown in the motor’s specification sheet. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | Ohm | - -### mot_v_accel (`FLOAT`) {#mot_v_accel} - -Acceleration limit (V). - -Acceleration limit (V) - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.01 | 1.00 | | 0.5 | V | - -### mot_v_max (`FLOAT`) {#mot_v_max} - -Motor voltage limit in volts. - -The current controller’s -commanded voltage will never exceed this value. Note that this may -safely be above the nominal voltage of the motor; to determine the -actual motor voltage limit, divide the motor’s rated power by the -motor current limit. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | | | 14.8 | V | - -## UAVCAN GNSS - -### gnss.dyn_model (`INT32`) {#gnss.dyn_model} - -GNSS dynamic model. - -Dynamic model used in the GNSS positioning engine. 0 – -Automotive, 1 – Sea, 2 – Airborne. - -**Values:** - -- `0`: Automotive -- `1`: Sea -- `2`: Airborne - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 2 | | 2 | - -### gnss.old_fix_msg (`INT32`) {#gnss.old_fix_msg} - -Broadcast old GNSS fix message. - -Broadcast the old (deprecated) GNSS fix message -uavcan.equipment.gnss.Fix alongside the new alternative -uavcan.equipment.gnss.Fix2. It is recommended to -disable this feature to reduce the CAN bus traffic. - -**Values:** - -- `0`: Fix2 -- `1`: Fix and Fix2 - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | | 1 | - -### gnss.warn_dimens (`INT32`) {#gnss.warn_dimens} - -device health warning. - -Set the device health to Warning if the dimensionality of -the GNSS solution is less than this value. 3 for the full (3D) -solution, 2 for planar (2D) solution, 1 for time-only solution, -0 disables the feature. - -**Values:** - -- `0`: disables the feature -- `1`: time-only solution -- `2`: planar (2D) solution -- `3`: full (3D) solution - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 3 | | 0 | - -### gnss.warn_sats (`INT32`) {#gnss.warn_sats} - -Set the device health to Warning if the number of satellites -used in the GNSS solution is below this threshold. Zero -disables the feature - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | - -### uavcan.pubp-pres (`INT32`) {#uavcan.pubp-pres} - -Set the device health to Warning if the number of satellites -used in the GNSS solution is below this threshold. Zero -disables the feature - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1000000 | | 0 | us | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 2.0 | 3.0 | 0.01 | 2.5 | V | ## ADSB @@ -692,6 +476,16 @@ to 0 and 4096. Other standard params follows the same rule. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 65535 | | 0 | +### PCA9685_EN_BUS (`INT32`) {#PCA9685_EN_BUS} + +Enable the PCA9685 output driver. + +The integer refers to the I2C bus number where PCA9685 is connected. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 10 | | 0 | + ### PCA9685_FAIL1 (`INT32`) {#PCA9685_FAIL1} PCA9685 Output Channel 1 Failsafe Value. @@ -2004,6 +1798,16 @@ The default failsafe value is set according to the selected function: | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0 | +### PCA9685_I2C_ADDR (`INT32`) {#PCA9685_I2C_ADDR} + +I2C address of PCA9685. + +The default address is 0x40 (64). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 1 | 127 | | 64 | + ### PCA9685_MAX1 (`INT32`) {#PCA9685_MAX1} PCA9685 Output Channel 1 Maximum Value. @@ -2383,6 +2187,116 @@ output latency, or completely block I2C bus. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 50.0 | 400.0 | | 50.0 | +### PWM_AUX_CENT1 (`INT32`) {#PWM_AUX_CENT1} + +PWM Aux 1 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT10 (`INT32`) {#PWM_AUX_CENT10} + +PWM Capture 2 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT11 (`INT32`) {#PWM_AUX_CENT11} + +PWM Capture 3 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT2 (`INT32`) {#PWM_AUX_CENT2} + +PWM Aux 2 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT3 (`INT32`) {#PWM_AUX_CENT3} + +PWM Aux 3 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT4 (`INT32`) {#PWM_AUX_CENT4} + +PWM Aux 4 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT5 (`INT32`) {#PWM_AUX_CENT5} + +PWM Aux 5 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT6 (`INT32`) {#PWM_AUX_CENT6} + +PWM Aux 6 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT7 (`INT32`) {#PWM_AUX_CENT7} + +PWM Aux 7 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT8 (`INT32`) {#PWM_AUX_CENT8} + +PWM Aux 8 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + +### PWM_AUX_CENT9 (`INT32`) {#PWM_AUX_CENT9} + +PWM Capture 1 Center Value. + +Servo Center output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 2200 | | -1 | + ### PWM_AUX_DIS1 (`INT32`) {#PWM_AUX_DIS1} PWM Aux 1 Disarmed Value. @@ -5010,6 +4924,83 @@ Note that non-motor outputs might already be active in prearm state if COM_PREAR | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 0 | +### SIM_GZ_EC_DIS10 (`INT32`) {#SIM_GZ_EC_DIS10} + +SIM_GZ ESC 10 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS11 (`INT32`) {#SIM_GZ_EC_DIS11} + +SIM_GZ ESC 11 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS12 (`INT32`) {#SIM_GZ_EC_DIS12} + +SIM_GZ ESC 12 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS13 (`INT32`) {#SIM_GZ_EC_DIS13} + +SIM_GZ ESC 13 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS14 (`INT32`) {#SIM_GZ_EC_DIS14} + +SIM_GZ ESC 14 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS15 (`INT32`) {#SIM_GZ_EC_DIS15} + +SIM_GZ ESC 15 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_DIS16 (`INT32`) {#SIM_GZ_EC_DIS16} + +SIM_GZ ESC 16 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + ### SIM_GZ_EC_DIS2 (`INT32`) {#SIM_GZ_EC_DIS2} SIM_GZ ESC 2 Disarmed Value. @@ -5087,6 +5078,17 @@ Note that non-motor outputs might already be active in prearm state if COM_PREAR | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 0 | +### SIM_GZ_EC_DIS9 (`INT32`) {#SIM_GZ_EC_DIS9} + +SIM_GZ ESC 9 Disarmed Value. + +This is the output value that is set when not armed. +Note that non-motor outputs might already be active in prearm state if COM_PREARM_MODE is set. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + ### SIM_GZ_EC_FAIL1 (`INT32`) {#SIM_GZ_EC_FAIL1} SIM_GZ ESC 1 Failsafe Value. @@ -5098,6 +5100,83 @@ When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC1 | ------ | -------- | -------- | --------- | ------- | ---- | |   | -1 | 1000 | | -1 | +### SIM_GZ_EC_FAIL10 (`INT32`) {#SIM_GZ_EC_FAIL10} + +SIM_GZ ESC 10 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC10). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL11 (`INT32`) {#SIM_GZ_EC_FAIL11} + +SIM_GZ ESC 11 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC11). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL12 (`INT32`) {#SIM_GZ_EC_FAIL12} + +SIM_GZ ESC 12 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC12). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL13 (`INT32`) {#SIM_GZ_EC_FAIL13} + +SIM_GZ ESC 13 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC13). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL14 (`INT32`) {#SIM_GZ_EC_FAIL14} + +SIM_GZ ESC 14 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC14). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL15 (`INT32`) {#SIM_GZ_EC_FAIL15} + +SIM_GZ ESC 15 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC15). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + +### SIM_GZ_EC_FAIL16 (`INT32`) {#SIM_GZ_EC_FAIL16} + +SIM_GZ ESC 16 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC16). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + ### SIM_GZ_EC_FAIL2 (`INT32`) {#SIM_GZ_EC_FAIL2} SIM_GZ ESC 2 Failsafe Value. @@ -5175,6 +5254,17 @@ When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC8 | ------ | -------- | -------- | --------- | ------- | ---- | |   | -1 | 1000 | | -1 | +### SIM_GZ_EC_FAIL9 (`INT32`) {#SIM_GZ_EC_FAIL9} + +SIM_GZ ESC 9 Failsafe Value. + +This is the output value that is set when in failsafe mode. +When set to -1 (default), the value depends on the function (see SIM_GZ_EC_FUNC9). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | -1 | 1000 | | -1 | + ### SIM_GZ_EC_FUNC1 (`INT32`) {#SIM_GZ_EC_FUNC1} SIM_GZ ESC 1 Output Function. @@ -5246,6 +5336,503 @@ The default failsafe value is set according to the selected function: | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0 | +### SIM_GZ_EC_FUNC10 (`INT32`) {#SIM_GZ_EC_FUNC10} + +SIM_GZ ESC 10 Output Function. + +Select what should be output on SIM_GZ ESC 10. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC11 (`INT32`) {#SIM_GZ_EC_FUNC11} + +SIM_GZ ESC 11 Output Function. + +Select what should be output on SIM_GZ ESC 11. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC12 (`INT32`) {#SIM_GZ_EC_FUNC12} + +SIM_GZ ESC 12 Output Function. + +Select what should be output on SIM_GZ ESC 12. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC13 (`INT32`) {#SIM_GZ_EC_FUNC13} + +SIM_GZ ESC 13 Output Function. + +Select what should be output on SIM_GZ ESC 13. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC14 (`INT32`) {#SIM_GZ_EC_FUNC14} + +SIM_GZ ESC 14 Output Function. + +Select what should be output on SIM_GZ ESC 14. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC15 (`INT32`) {#SIM_GZ_EC_FUNC15} + +SIM_GZ ESC 15 Output Function. + +Select what should be output on SIM_GZ ESC 15. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### SIM_GZ_EC_FUNC16 (`INT32`) {#SIM_GZ_EC_FUNC16} + +SIM_GZ ESC 16 Output Function. + +Select what should be output on SIM_GZ ESC 16. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + ### SIM_GZ_EC_FUNC2 (`INT32`) {#SIM_GZ_EC_FUNC2} SIM_GZ ESC 2 Output Function. @@ -5743,6 +6330,77 @@ The default failsafe value is set according to the selected function: | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0 | +### SIM_GZ_EC_FUNC9 (`INT32`) {#SIM_GZ_EC_FUNC9} + +SIM_GZ ESC 9 Output Function. + +Select what should be output on SIM_GZ ESC 9. +The default failsafe value is set according to the selected function: + +- 'Min' for ConstantMin +- 'Max' for ConstantMax +- 'Max' for Parachute +- ('Max'+'Min')/2 for Servos +- 'Disarmed' for the rest + +**Values:** + +- `0`: Disabled +- `1`: Constant Min +- `2`: Constant Max +- `101`: Motor 1 +- `102`: Motor 2 +- `103`: Motor 3 +- `104`: Motor 4 +- `105`: Motor 5 +- `106`: Motor 6 +- `107`: Motor 7 +- `108`: Motor 8 +- `109`: Motor 9 +- `110`: Motor 10 +- `111`: Motor 11 +- `112`: Motor 12 +- `201`: Servo 1 +- `202`: Servo 2 +- `203`: Servo 3 +- `204`: Servo 4 +- `205`: Servo 5 +- `206`: Servo 6 +- `207`: Servo 7 +- `208`: Servo 8 +- `301`: Peripheral via Actuator Set 1 +- `302`: Peripheral via Actuator Set 2 +- `303`: Peripheral via Actuator Set 3 +- `304`: Peripheral via Actuator Set 4 +- `305`: Peripheral via Actuator Set 5 +- `306`: Peripheral via Actuator Set 6 +- `400`: Landing Gear +- `401`: Parachute +- `402`: RC Roll +- `403`: RC Pitch +- `404`: RC Throttle +- `405`: RC Yaw +- `406`: RC Flaps +- `407`: RC AUX 1 +- `408`: RC AUX 2 +- `409`: RC AUX 3 +- `410`: RC AUX 4 +- `411`: RC AUX 5 +- `412`: RC AUX 6 +- `420`: Gimbal Roll +- `421`: Gimbal Pitch +- `422`: Gimbal Yaw +- `430`: Gripper +- `440`: Landing Gear Wheel +- `450`: IC Engine Ignition +- `451`: IC Engine Throttle +- `452`: IC Engine Choke +- `453`: IC Engine Starter + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + ### SIM_GZ_EC_MAX1 (`INT32`) {#SIM_GZ_EC_MAX1} SIM_GZ ESC 1 Maximum Value. @@ -5753,6 +6411,76 @@ Maxmimum output value (when not disarmed). | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 1000 | +### SIM_GZ_EC_MAX10 (`INT32`) {#SIM_GZ_EC_MAX10} + +SIM_GZ ESC 10 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX11 (`INT32`) {#SIM_GZ_EC_MAX11} + +SIM_GZ ESC 11 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX12 (`INT32`) {#SIM_GZ_EC_MAX12} + +SIM_GZ ESC 12 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX13 (`INT32`) {#SIM_GZ_EC_MAX13} + +SIM_GZ ESC 13 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX14 (`INT32`) {#SIM_GZ_EC_MAX14} + +SIM_GZ ESC 14 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX15 (`INT32`) {#SIM_GZ_EC_MAX15} + +SIM_GZ ESC 15 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + +### SIM_GZ_EC_MAX16 (`INT32`) {#SIM_GZ_EC_MAX16} + +SIM_GZ ESC 16 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + ### SIM_GZ_EC_MAX2 (`INT32`) {#SIM_GZ_EC_MAX2} SIM_GZ ESC 2 Maximum Value. @@ -5823,6 +6551,16 @@ Maxmimum output value (when not disarmed). | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 1000 | +### SIM_GZ_EC_MAX9 (`INT32`) {#SIM_GZ_EC_MAX9} + +SIM_GZ ESC 9 Maximum Value. + +Maxmimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 1000 | + ### SIM_GZ_EC_MIN1 (`INT32`) {#SIM_GZ_EC_MIN1} SIM_GZ ESC 1 Minimum Value. @@ -5833,6 +6571,76 @@ Minimum output value (when not disarmed). | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 0 | +### SIM_GZ_EC_MIN10 (`INT32`) {#SIM_GZ_EC_MIN10} + +SIM_GZ ESC 10 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN11 (`INT32`) {#SIM_GZ_EC_MIN11} + +SIM_GZ ESC 11 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN12 (`INT32`) {#SIM_GZ_EC_MIN12} + +SIM_GZ ESC 12 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN13 (`INT32`) {#SIM_GZ_EC_MIN13} + +SIM_GZ ESC 13 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN14 (`INT32`) {#SIM_GZ_EC_MIN14} + +SIM_GZ ESC 14 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN15 (`INT32`) {#SIM_GZ_EC_MIN15} + +SIM_GZ ESC 15 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + +### SIM_GZ_EC_MIN16 (`INT32`) {#SIM_GZ_EC_MIN16} + +SIM_GZ ESC 16 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + ### SIM_GZ_EC_MIN2 (`INT32`) {#SIM_GZ_EC_MIN2} SIM_GZ ESC 2 Minimum Value. @@ -5903,6 +6711,16 @@ Minimum output value (when not disarmed). | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1000 | | 0 | +### SIM_GZ_EC_MIN9 (`INT32`) {#SIM_GZ_EC_MIN9} + +SIM_GZ ESC 9 Minimum Value. + +Minimum output value (when not disarmed). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1000 | | 0 | + ### SIM_GZ_EC_REV (`INT32`) {#SIM_GZ_EC_REV} Reverse Output Range for SIM_GZ. @@ -5920,10 +6738,18 @@ Note: this is only useful for servos. - `5`: SIM_GZ ESC 6 - `6`: SIM_GZ ESC 7 - `7`: SIM_GZ ESC 8 +- `8`: SIM_GZ ESC 9 +- `9`: SIM_GZ ESC 10 +- `10`: SIM_GZ ESC 11 +- `11`: SIM_GZ ESC 12 +- `12`: SIM_GZ ESC 13 +- `13`: SIM_GZ ESC 14 +- `14`: SIM_GZ ESC 15 +- `15`: SIM_GZ ESC 16 | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 255 | | 0 | +|   | 0 | 65535 | | 0 | ### SIM_GZ_SV_DIS1 (`INT32`) {#SIM_GZ_SV_DIS1} @@ -14203,9 +15029,9 @@ Scale of airspeed sensor 1. This is the scale IAS --> CAS of the first airspeed sensor instance -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0.5 | 2.0 | | 1.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.5 | 2.0 | | 1.0 | ### ASPD_SCALE_2 (`FLOAT`) {#ASPD_SCALE_2} @@ -14213,9 +15039,9 @@ Scale of airspeed sensor 2. This is the scale IAS --> CAS of the second airspeed sensor instance -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0.5 | 2.0 | | 1.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.5 | 2.0 | | 1.0 | ### ASPD_SCALE_3 (`FLOAT`) {#ASPD_SCALE_3} @@ -14223,9 +15049,9 @@ Scale of airspeed sensor 3. This is the scale IAS --> CAS of the third airspeed sensor instance -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0.5 | 2.0 | | 1.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.5 | 2.0 | | 1.0 | ### ASPD_SCALE_APPLY (`INT32`) {#ASPD_SCALE_APPLY} @@ -14435,9 +15261,9 @@ Set bits in the following positions to enable: ### FW_AT_MAN_AUX (`INT32`) {#FW_AT_MAN_AUX} -Enable/disable auto tuning using an RC AUX input. +Enable/disable auto tuning using a manual control AUX input. -Defines which RC_MAP_AUXn parameter maps the RC channel used to enable/disable auto tuning. +Defines which RC_MAP_AUXn parameter maps the manual control channel used to enable/disable auto tuning. **Values:** @@ -14453,35 +15279,6 @@ Defines which RC_MAP_AUXn parameter maps the RC channel used to enable/disable a | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 6 | | 0 | -### FW_AT_START (`INT32`) {#FW_AT_START} - -Start the autotuning sequence. - -WARNING: this will inject steps to the rate controller -and can be dangerous. Only activate if you know what you -are doing, and in a safe environment. -Any motion of the remote stick will abort the signal -injection and reset this parameter -Best is to perform the identification in position or -hold mode. -Increase the amplitude of the injected signal using -FW_AT_SYSID_AMP for more signal/noise ratio - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------------ | ---- | -|   | | | | Disabled (0) | - -### FW_AT_SYSID_AMP (`FLOAT`) {#FW_AT_SYSID_AMP} - -Amplitude of the injected signal. - -This parameter scales the signal sent to the -rate controller during system identification. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.1 | 6.0 | | 1.0 | - ### FW_AT_SYSID_F0 (`FLOAT`) {#FW_AT_SYSID_F0} Start frequency of the injected signal. @@ -14500,7 +15297,7 @@ Can be set lower or higher than the start frequency | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.1 | 30.0 | | 20. | Hz | +|   | 0.1 | 30.0 | | 10. | Hz | ### FW_AT_SYSID_TIME (`FLOAT`) {#FW_AT_SYSID_TIME} @@ -14526,7 +15323,7 @@ Type of signal used during system identification to excite the system. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +|   | | | | 1 | ### MC_AT_APPLY (`INT32`) {#MC_AT_APPLY} @@ -14565,24 +15362,6 @@ Desired angular rate closed-loop rise time. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0.01 | 0.5 | | 0.14 | s | -### MC_AT_START (`INT32`) {#MC_AT_START} - -Start the autotuning sequence. - -WARNING: this will inject steps to the rate controller -and can be dangerous. Only activate if you know what you -are doing, and in a safe environment. -Any motion of the remote stick will abort the signal -injection and reset this parameter -Best is to perform the identification in position or -hold mode. -Increase the amplitude of the injected signal using -MC_AT_SYSID_AMP for more signal/noise ratio - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------------ | ---- | -|   | | | | Disabled (0) | - ### MC_AT_SYSID_AMP (`FLOAT`) {#MC_AT_SYSID_AMP} Amplitude of the injected signal. @@ -14686,16 +15465,21 @@ If non-negative, then this will be used instead of the online estimated internal Battery 1 monitoring source. -This parameter controls the source of battery data. The value 'Power Module' -means that measurements are expected to come from a power module. If the value is set to -'External' then the system expects to receive mavlink battery status messages. +This parameter controls the source of battery data. The value 'Power Module / Analog' +means that measurements are expected to come from either analog (ADC) inputs +or an I2C power monitor (e.g. INA226). Analog inputs are voltage and current +measurements read from the board's ADC channels, typically from an onboard +voltage divider and current shunt, or an external analog power module. +I2C power monitors are digital sensors on the I2C bus. +If the value is set to 'External' then the system expects to receive MAVLink +or CAN battery status messages, or the battery data is published by an external driver. If the value is set to 'ESCs', the battery information are taken from the esc_status message. -This requires the ESC to provide both voltage as well as current. +This requires the ESC to provide both voltage as well as current (via ESC telemetry). **Values:** - `-1`: Disabled -- `0`: Power Module +- `0`: Power Module / Analog - `1`: External - `2`: ESCs @@ -14846,16 +15630,21 @@ If non-negative, then this will be used instead of the online estimated internal Battery 2 monitoring source. -This parameter controls the source of battery data. The value 'Power Module' -means that measurements are expected to come from a power module. If the value is set to -'External' then the system expects to receive mavlink battery status messages. +This parameter controls the source of battery data. The value 'Power Module / Analog' +means that measurements are expected to come from either analog (ADC) inputs +or an I2C power monitor (e.g. INA226). Analog inputs are voltage and current +measurements read from the board's ADC channels, typically from an onboard +voltage divider and current shunt, or an external analog power module. +I2C power monitors are digital sensors on the I2C bus. +If the value is set to 'External' then the system expects to receive MAVLink +or CAN battery status messages, or the battery data is published by an external driver. If the value is set to 'ESCs', the battery information are taken from the esc_status message. -This requires the ESC to provide both voltage as well as current. +This requires the ESC to provide both voltage as well as current (via ESC telemetry). **Values:** - `-1`: Disabled -- `0`: Power Module +- `0`: Power Module / Analog - `1`: External - `2`: ESCs @@ -14967,16 +15756,21 @@ If non-negative, then this will be used instead of the online estimated internal Battery 3 monitoring source. -This parameter controls the source of battery data. The value 'Power Module' -means that measurements are expected to come from a power module. If the value is set to -'External' then the system expects to receive mavlink battery status messages. +This parameter controls the source of battery data. The value 'Power Module / Analog' +means that measurements are expected to come from either analog (ADC) inputs +or an I2C power monitor (e.g. INA226). Analog inputs are voltage and current +measurements read from the board's ADC channels, typically from an onboard +voltage divider and current shunt, or an external analog power module. +I2C power monitors are digital sensors on the I2C bus. +If the value is set to 'External' then the system expects to receive MAVLink +or CAN battery status messages, or the battery data is published by an external driver. If the value is set to 'ESCs', the battery information are taken from the esc_status message. -This requires the ESC to provide both voltage as well as current. +This requires the ESC to provide both voltage as well as current (via ESC telemetry). **Values:** - `-1`: Disabled -- `0`: Power Module +- `0`: Power Module / Analog - `1`: External - `2`: ESCs @@ -15565,8 +16359,7 @@ disabled, warn only or deny arming. Arm switch is a momentary button. 0: Arming/disarming triggers on switch transition. -1: Arming/disarming triggers when holding the momentary button down -for COM_RC_ARM_HYST like the stick gesture. +1: Arming/disarming triggers when holding the momentary button down like the stick gesture. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------------ | ---- | @@ -15574,15 +16367,17 @@ for COM_RC_ARM_HYST like the stick gesture. ### COM_ARM_WO_GPS (`INT32`) {#COM_ARM_WO_GPS} -GPS preflight check. +Arming without GNSS configuration. -Measures taken when a check defined by EKF2_GPS_CHECK is failing. +Configures whether arming is allowed without GNSS, for modes that require a global position +(specifically, in those modes when a check defined by EKF2_GPS_CHECK fails). +The settings deny arming and warn, allow arming and warn, or silently allow arming. **Values:** - `0`: Deny arming -- `1`: Warning only -- `2`: Disabled +- `1`: Allow arming (with warning) +- `2`: Allow arming (no warning) | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -15641,17 +16436,20 @@ A negative value disables autmoatic disarming triggered by a pre-takeoff timeout Datalink loss exceptions. -Specify modes in which datalink loss is ignored and the failsafe action not triggered. +Specify modes in which ground control station connection loss is ignored and no failsafe action is triggered. +See also COM_RCL_EXCEPT. **Bitmask:** - `0`: Mission -- `1`: Hold +- `1`: Auto modes - `2`: Offboard +- `3`: External Mode +- `4`: Altitude Cruise | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 7 | | 0 | +|   | 0 | 31 | | 0 | ### COM_DL_LOSS_T (`INT32`) {#COM_DL_LOSS_T} @@ -15713,6 +16511,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -15750,6 +16549,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -15787,6 +16587,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -15824,6 +16625,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -15861,6 +16663,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -15898,6 +16701,7 @@ selected flight mode will be applied. - `11`: Land - `12`: Follow Me - `13`: Precision Land +- `16`: Altitude Cruise - `100`: External Mode 1 - `101`: External Mode 2 - `102`: External Mode 3 @@ -16242,21 +17046,6 @@ Expect and require a healthy MAVLink parachute system. | ------ | -------- | -------- | --------- | ------------ | ---- | |   | | | | Disabled (0) | -### COM_POSCTL_NAVL (`INT32`) {#COM_POSCTL_NAVL} - -Position mode navigation loss response. - -This sets the flight mode that will be used if navigation accuracy is no longer adequate for position control in manual Position mode. - -**Values:** - -- `0`: Altitude mode -- `1`: Land mode (descend) - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | - ### COM_POS_FS_EPH (`FLOAT`) {#COM_POS_FS_EPH} Horizontal position error threshold for hovering systems. @@ -16363,57 +17152,56 @@ A negative value disables the check. ### COM_RCL_EXCEPT (`INT32`) {#COM_RCL_EXCEPT} -RC loss exceptions. +Manual control loss exceptions. -Specify modes where manual control loss is ignored and no failsafe is triggered. +Specify modes in which stick input is ignored and no failsafe action is triggered. External modes requiring stick input will still failsafe. +Auto modes are: Hold, Takeoff, Land, RTL, Descend, Follow Target, Precland, Orbit. **Bitmask:** - `0`: Mission -- `1`: Hold +- `1`: Auto modes - `2`: Offboard - `3`: External Mode +- `4`: Altitude Cruise | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 15 | | 0 | - -### COM_RC_ARM_HYST (`INT32`) {#COM_RC_ARM_HYST} - -RC input arm/disarm command duration. - -The default value of 1000 requires the stick to be held in the arm or disarm position for 1 second. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 100 | 1500 | | 1000 | ms | +|   | 0 | 31 | | 0 | ### COM_RC_IN_MODE (`INT32`) {#COM_RC_IN_MODE} -RC control input mode. +Manual control input source configuration. -A value of 0 enables RC transmitter control (only). A valid RC transmitter calibration is required. -A value of 1 allows joystick control only. RC input handling and the associated checks are disabled. -A value of 2 allows either RC Transmitter or Joystick input. The first valid input is used, will fallback to other sources if the input stream becomes invalid. -A value of 3 allows either input from RC or joystick. The first available source is selected and used until reboot. -A value of 4 ignores any stick input. -A value of 5 allows either RC Transmitter or Joystick input. But RC has priority and whenever avaiable is immedietely used. -A value of 6 allows either RC Transmitter or Joystick input. But Joystick has priority and whenever avaiable is immedietely used. +Selects stick input selection behavior: +either a traditional remote control receiver (RC) or a MAVLink joystick (MANUAL_CONTROL message) +Priority sources are immediately switched to whenever they get valid. +0 RC only. Requires valid RC calibration. +1 MAVLink only. RC and related checks are disabled. +2 Switches only if current source becomes invalid. +3 Locks to the first valid source until reboot. +4 Ignores all sources. +5 RC priority, then MAVLink (lower instance before higher) +6 MAVLink priority (lower instance before higher), then RC +7 RC priority, then MAVLink (higher instance before lower) +8 MAVLink priority (higher instance before lower), then RC **Values:** -- `0`: RC Transmitter only -- `1`: Joystick only -- `2`: RC and Joystick with fallback -- `3`: RC or Joystick keep first -- `4`: Stick input disabled -- `5`: RC priority, Joystick fallback -- `6`: Joystick priority, RC fallback +- `0`: RC only +- `1`: MAVLink only +- `2`: RC or MAVLink with fallback +- `3`: RC or MAVLink keep first +- `4`: Disable manual control +- `5`: Prio: RC > MAVL 1 > MAVL 2 +- `6`: Prio: MAVL 1 > MAVL 2 > RC +- `7`: Prio: RC > MAVL 2 > MAVL 1 +- `8`: Prio: MAVL 2 > MAVL 1 > RC | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 4 | | 3 | +|   | 0 | 8 | | 3 | ### COM_RC_LOSS_T (`FLOAT`) {#COM_RC_LOSS_T} @@ -16429,9 +17217,9 @@ Ensure the value is not set lower than the update interval of the RC or Joystick ### COM_RC_OVERRIDE (`INT32`) {#COM_RC_OVERRIDE} -Enable RC stick override of auto and/or offboard modes. +Enable manual control stick override. -When RC stick override is enabled, moving the RC sticks more than COM_RC_STICK_OV +When enabled, moving the sticks more than COM_RC_STICK_OV immediately gives control back to the pilot by switching to Position mode and if position is unavailable Altitude mode. Note: Only has an effect on multicopters, and VTOLs in multicopter mode. @@ -16447,7 +17235,7 @@ Note: Only has an effect on multicopters, and VTOLs in multicopter mode. ### COM_RC_STICK_OV (`FLOAT`) {#COM_RC_STICK_OV} -RC stick override threshold. +Stick override threshold. If COM_RC_OVERRIDE is enabled and the joystick input is moved more than this threshold the autopilot the pilot takes over control. @@ -16591,11 +17379,10 @@ action will be executed. ### NAV_RCL_ACT (`INT32`) {#NAV_RCL_ACT} -Set RC loss failsafe mode. +Set manual control loss failsafe mode. -The RC loss failsafe will only be entered after a timeout, -set by COM_RC_LOSS_T in seconds. If RC input checks have been disabled -by setting the COM_RC_IN_MODE param it will not be triggered. +The manual control loss failsafe will only be entered after a timeout, +set by COM_RC_LOSS_T in seconds. **Values:** @@ -16876,7 +17663,7 @@ armed. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | 0.01 | 0.055 | % | +|   | 0 | 1 | 0.01 | 0.055 | norm | ### DSHOT_TEL_CFG (`INT32`) {#DSHOT_TEL_CFG} @@ -17217,6 +18004,16 @@ EKF2 enable. | ------ | -------- | -------- | --------- | ----------- | ---- | |   | | | | Enabled (1) | +### EKF2_ENGINE_WRM (`INT32`) {#EKF2_ENGINE_WRM} + +Enable constant position fusion during engine warmup. + +When enabled, constant position fusion is enabled when the vehicle is landed and armed. This is intended for IC engine warmup (e.g., fuel engines on catapult) to allow mode transitions to auto/takeoff despite vibrations from running engines. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + ### EKF2_EVA_NOISE (`FLOAT`) {#EKF2_EVA_NOISE} Measurement noise for vision angle measurements. @@ -17404,10 +18201,11 @@ Each threshold value is defined by the parameter indicated next to the check. Dr - `8`: Vertical speed offset (EKF2_REQ_VDRIFT) - `9`: Spoofing - `10`: GPS fix type (EKF2_REQ_FIX) +- `11`: Jamming | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 2047 | | 2047 | +|   | 0 | 4095 | | 2047 | ### EKF2_GPS_CTRL (`INT32`) {#EKF2_GPS_CTRL} @@ -17428,7 +18226,9 @@ Set bits in the following positions to enable: 0 : Longitude and latitude fusion ### EKF2_GPS_DELAY (`FLOAT`) {#EKF2_GPS_DELAY} -GPS measurement delay relative to IMU measurements. +GPS measurement delay relative to IMU measurement. + +GPS measurement delay relative to IMU measurement if PPS time correction is not available/enabled (PPS_CAP_ENABLE). | Reboot | minValue | maxValue | increment | default | unit | | ------- | -------- | -------- | --------- | ------- | ---- | @@ -17438,7 +18238,7 @@ GPS measurement delay relative to IMU measurements. Fusion reset mode. -Automatic: reset on fusion timeout if no other source of position is available Dead-reckoning: reset on fusion timeout if no source of velocity is available +Automatic: reset on fusion timeout if no other source of position is available. Dead-reckoning: reset on fusion timeout if no source of velocity is available. **Values:** @@ -17785,7 +18585,7 @@ If the vehicle is on ground, is not moving as determined by the motion test and | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.01 | | | 0.1 | m | +|   | 0.01 | | | 0.01 | m | ### EKF2_MULTI_IMU (`INT32`) {#EKF2_MULTI_IMU} @@ -18796,6 +19596,18 @@ Launch is detected when acceleration in body forward direction is above FW_LAUN_ | ------ | -------- | -------- | --------- | ------- | ----- | |   | 0 | | 0.5 | 30.0 | m/s^2 | +### FW_LAUN_CS_LK_DY (`FLOAT`) {#FW_LAUN_CS_LK_DY} + +Control surface launch delay. + +Locks control surfaces during pre-launch (armed) and until this time since launch has passed. +Only affects control surfaces that have corresponding flag set, and not active for runway takeoff. +Set to 0 to disable any surface locking after arming. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | | 0.1 | 0. | s | + ### FW_LAUN_DETCN_ON (`INT32`) {#FW_LAUN_DETCN_ON} Fixed-wing launch detection. @@ -19566,6 +20378,24 @@ This increment is added to TRIM_YAW when airspeed is FW_AIRSPD_MIN. | ------ | -------- | -------- | --------- | ------- | ---- | |   | -0.5 | 0.5 | 0.01 | 0.0 | +### FW_GC_EN (`INT32`) {#FW_GC_EN} + +Enable rate gain compression. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ----------- | ---- | +|   | | | | Enabled (1) | + +### FW_GC_GAIN_MIN (`FLOAT`) {#FW_GC_GAIN_MIN} + +Compression gain lower limit. + +The range of the compression gain is between this parameter and 1.0 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | 1.0 | 0.01 | 0.3 | + ### FW_MAN_P_SC (`FLOAT`) {#FW_MAN_P_SC} Manual pitch scale. @@ -19780,25 +20610,48 @@ If enabled, failure detector will verify that for motors, a minimum amount of ES level is being consumed. Otherwise this indicates an motor failure. -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ----------- | ---- | -| ✓ | | | | Enabled (1) | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | -### FD_ACT_MOT_C2T (`FLOAT`) {#FD_ACT_MOT_C2T} +### FD_ACT_HIGH_OFF (`FLOAT`) {#FD_ACT_HIGH_OFF} -Motor Failure Current/Throttle Threshold. +Overcurrent motor failure limit offset. -Motor failure triggers only below this current value +threshold = FD_ACT_MOT_C2T \* thrust + FD_ACT_HIGH_OFF | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 50.0 | 1 | 2.0 | A/% | +|   | 0 | 30 | 1 | 10. | A | + +### FD_ACT_LOW_OFF (`FLOAT`) {#FD_ACT_LOW_OFF} + +Undercurrent motor failure limit offset. + +threshold = FD_ACT_MOT_C2T \* thrust - FD_ACT_LOW_OFF + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 30 | 1 | 10. | A | + +### FD_ACT_MOT_C2T (`FLOAT`) {#FD_ACT_MOT_C2T} + +Motor Failure Current/Throttle Scale. + +Determines the slope between expected steady state current and linearized, normalized thrust command. +E.g. FD_ACT_MOT_C2T A represents the expected steady state current at 100%. +FD_ACT_LOW_OFF and FD_ACT_HIGH_OFF offset the threshold from that slope. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | 50.0 | 1 | 35. | A/% | ### FD_ACT_MOT_THR (`FLOAT`) {#FD_ACT_MOT_THR} -Motor Failure Throttle Threshold. +Motor Failure Thrust Threshold. -Motor failure triggers only above this throttle value. +Failure detection per motor only triggers above this thrust value. +Set to 1 to disable the detection. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -19806,14 +20659,13 @@ Motor failure triggers only above this throttle value. ### FD_ACT_MOT_TOUT (`INT32`) {#FD_ACT_MOT_TOUT} -Motor Failure Time Threshold. +Motor Failure Hysteresis Time. -Motor failure triggers only if the throttle threshold and the -current to throttle threshold are violated for this time. +Motor failure only triggers after current thresholds are exceeded for this time. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 10 | 10000 | 100 | 100 | ms | +|   | 10 | 10000 | 100 | 1000 | ms | ### FD_ESCS_EN (`INT32`) {#FD_ESCS_EN} @@ -19929,7 +20781,7 @@ Yaw behaviour during orbit flight. - `1`: Hold Initial Heading - `2`: Uncontrolled - `3`: Hold Front Tangent to Circle -- `4`: RC Controlled +- `4`: Manually (yaw stick) Controlled | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -20236,6 +21088,16 @@ u-blox protocol configuration for interfaces. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 32 | | 0 | +### GPS_UBX_DGNSS_TO (`INT32`) {#GPS_UBX_DGNSS_TO} + +u-blox GPS DGNSS timeout. + +When set to 0 (default), default DGNSS timeout set by u-blox will be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 255 | | 0 | s | + ### GPS_UBX_DYNMODEL (`INT32`) {#GPS_UBX_DYNMODEL} u-blox GPS dynamic platform model. @@ -20255,6 +21117,39 @@ the expected application environment. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 9 | | 7 | +### GPS_UBX_JAM_DET (`INT32`) {#GPS_UBX_JAM_DET} + +u-blox GPS jamming detection high sensitivity mode. + +Enables or disables the high sensitivity mode for the u-blox jamming detection +(CFG-SEC-JAMDET_SENSITIVITY_HI). When enabled, the receiver uses a +more sensitive algorithm to detect jamming. Disabling this may reduce false +positives in electrically noisy environments. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### GPS_UBX_MIN_CNO (`INT32`) {#GPS_UBX_MIN_CNO} + +u-blox GPS minimum satellite signal level for navigation. + +When set to 0 (default), default minimum satellite signal level set by u-blox wll be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 255 | | 0 | dBHz | + +### GPS_UBX_MIN_ELEV (`INT32`) {#GPS_UBX_MIN_ELEV} + +u-blox GPS minimum elevation for a GNSS satellite to be used in navigation. + +When set to 0 (default), default minimum elevation set by u-blox will be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 127 | | 0 | deg | + ### GPS_UBX_MODE (`INT32`) {#GPS_UBX_MODE} u-blox GPS Mode. @@ -20268,6 +21163,7 @@ Modes 1 and 2 require each F9P UART1 to be connected to the Autopilot. In additi F9P units are connected to each other. Modes 3 and 4 only require UART1 on each F9P connected to the Autopilot or Can Node. UART RX DMA is required. RTK is still possible with this setup. +Mode 6 is intended for use with a ground control station (not necessarily an RTK correction base). **Values:** @@ -20277,11 +21173,35 @@ RTK is still possible with this setup. - `3`: Heading (Rover With Moving Base UART1 Connected to Autopilot Or Can Node At 921600) - `4`: Moving Base (Moving Base UART1 Connected to Autopilot Or Can Node At 921600) - `5`: Rover with Static Base on UART2 (similar to Default, except coming in on UART2) +- `6`: Ground Control Station (UART2 outputs NMEA) | Reboot | minValue | maxValue | increment | default | unit | | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 1 | | 0 | +### GPS_UBX_PPK (`INT32`) {#GPS_UBX_PPK} + +Enable MSM7 message output for PPK workflow. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + +### GPS_UBX_RATE (`INT32`) {#GPS_UBX_RATE} + +u-blox GPS output rate. + +Configure the output rate of u-blox GPS receivers (protocol v27+). +When set to 0, automatic rate selection is used based on the receiver model. +Default rates: M9N=8Hz, F9P L1L2=5Hz, F9P L1L5=5Hz, Others=10Hz. +Note: Higher rates reduce satellite count (e.g., >8Hz limits to 16 SVs on M9N). +Max rates vary by model and RTK mode: F9P L1L2=5-7Hz, F9P L1L5=7-8Hz, X20=25Hz. +High rates at 115200 baud may cause dropouts. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 25 | | 0 | Hz | + ### GPS_YAW_OFFSET (`FLOAT`) {#GPS_YAW_OFFSET} Heading/Yaw offset for dual antenna GPS. @@ -20417,6 +21337,27 @@ Some are generic, while others are specifically fit to a certain vehicle with a | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0 | +### CA_CS_LAUN_LK (`INT32`) {#CA_CS_LAUN_LK} + +Control surface launch lock enabled. + +If actuator launch lock is enabled, this surface is kept at the disarmed value. + +**Bitmask:** + +- `0`: Control Surface 1 +- `1`: Control Surface 2 +- `2`: Control Surface 3 +- `3`: Control Surface 4 +- `4`: Control Surface 5 +- `5`: Control Surface 6 +- `6`: Control Surface 7 +- `7`: Control Surface 8 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 255 | | 0 | + ### CA_FAILURE_MODE (`INT32`) {#CA_FAILURE_MODE} Motor failure handling mode. @@ -20621,6 +21562,21 @@ tail_output += CA_HELI_YAW_TH_S \* throttle | ------ | -------- | -------- | --------- | ------- | ---- | |   | -2 | 2 | 0.1 | 0.0 | +### CA_ICE_PERIOD (`FLOAT`) {#CA_ICE_PERIOD} + +Ice shedding cycle period. + +Ice shedding prevents ice buildup in VTOL aircraft motors by +periodically spinning inactive rotors. When enabled (period + +> 0), every cycle lasts for the defined period and includes +> a 2‑second spin at 0.01 motor output. If period <= 0, the +> feature is disabled. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | | 0.1 | 0.0 | s | + ### CA_MAX_SVO_THROW (`FLOAT`) {#CA_MAX_SVO_THROW} Throw angle of swashplate servo at maximum commands for linearization. @@ -22206,6 +23162,8 @@ Control Surface 0 configuration as spoiler. Control Surface 0 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22286,6 +23244,8 @@ Control Surface 1 configuration as spoiler. Control Surface 1 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22366,6 +23326,8 @@ Control Surface 2 configuration as spoiler. Control Surface 2 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22446,6 +23408,8 @@ Control Surface 3 configuration as spoiler. Control Surface 3 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22526,6 +23490,8 @@ Control Surface 4 configuration as spoiler. Control Surface 4 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22606,6 +23572,8 @@ Control Surface 5 configuration as spoiler. Control Surface 5 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22686,6 +23654,8 @@ Control Surface 6 configuration as spoiler. Control Surface 6 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22766,6 +23736,8 @@ Control Surface 7 configuration as spoiler. Control Surface 7 trim. Can be used to add an offset to the servo control. +NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. +This parameter can only be set if all PWM Center parameters are set to default. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -22845,6 +23817,14 @@ Total number of Control Surfaces. | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0 | +### CA_SV_FLAP_SLEW (`FLOAT`) {#CA_SV_FLAP_SLEW} + +Control Surface slew rate for normalized flaps setpoint. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | 5.0 | | 0.5 | + ### CA_SV_TL0_CT (`INT32`) {#CA_SV_TL0_CT} Tilt 0 is used for control. @@ -23379,6 +24359,7 @@ Engine start/stop input source. - `0`: On arming - disarming - `1`: Aux1 - `2`: Aux2 +- `3`: On Vtol Transitions | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -24657,13 +25638,12 @@ MAVLink protocol version. **Values:** -- `0`: Default to 1, switch to 2 if GCS sends version 2 -- `1`: Always use version 1 -- `2`: Always use version 2 +- `1`: Version 1 with auto-upgrade to v2 if detected +- `2`: Version 2 | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +|   | | | | 2 | ### MAV_RADIO_TOUT (`INT32`) {#MAV_RADIO_TOUT} @@ -24698,6 +25678,36 @@ MAVLink system ID. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 1 | 250 | | 1 | +### MAV_S_FORWARD (`INT32`) {#MAV_S_FORWARD} + +Enable MAVLink forwarding on TELEM2. + +TELEM2 on Skynode only. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + +### MAV_S_MODE (`INT32`) {#MAV_S_MODE} + +MAVLink Mode for SOM to FMU communication channel. + +The MAVLink Mode defines the set of streamed messages (for example the +vehicle's attitude) and their sending rates. + +**Values:** + +- `0`: Normal +- `2`: Onboard +- `5`: Config +- `7`: Minimal +- `11`: Onboard Low Bandwidth +- `13`: Low Bandwidth + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 11 | + ### MAV_TYPE (`INT32`) {#MAV_TYPE} MAVLink airframe type. @@ -24825,6 +25835,19 @@ arms and to the lower left disarms the vehicle. | ------ | -------- | -------- | --------- | ----------- | ---- | |   | | | | Enabled (1) | +### MAN_DEADZONE (`FLOAT`) {#MAN_DEADZONE} + +Deadzone for sticks (only specific use cases). + +Range around stick center ignored to prevent +vehicle drift from stick hardware inaccuracy. +Does not apply to any precise constant input like +throttle and attitude or rate piloting. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | 0.01 | 0.1 | + ### MAN_KILL_GEST_T (`FLOAT`) {#MAN_KILL_GEST_T} Trigger time for kill stick gesture. @@ -25152,10 +26175,11 @@ and relies on the IMU's attitude estimation. - `0`: Disable - `1`: Stabilize all axis - `2`: Stabilize yaw for absolute/lock mode. +- `3`: Stabilize pitch for absolute/lock mode. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 2 | | 0 | +|   | | | | 0 | ### MNT_LND_P_MAX (`FLOAT`) {#MNT_LND_P_MAX} @@ -25247,6 +26271,26 @@ If MNT_MODE_OUT is MAVLink gimbal protocol v1, mount configure/control commands | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 1 | +### MNT_MAX_PITCH (`FLOAT`) {#MNT_MAX_PITCH} + +Max positive angle of pitch setpoint (only in MNT_MODE_OUT=AUX). + +Use output driver settings to calibrate (e.g. PWM_CENT/\_MIN/\_MAX). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 45.0 | deg | + +### MNT_MIN_PITCH (`FLOAT`) {#MNT_MIN_PITCH} + +Min negative angle of pitch setpoint (only in MNT_MODE_OUT=AUX). + +Use output driver settings to calibrate (e.g. PWM_CENT/\_MIN/\_MAX). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | -45.0 | deg | + ### MNT_MODE_IN (`INT32`) {#MNT_MODE_IN} Mount input mode. @@ -25285,41 +26329,11 @@ Recommended is the MAVLink gimbal protocol v2 if the gimbal supports it. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 2 | | 0 | -### MNT_OFF_PITCH (`FLOAT`) {#MNT_OFF_PITCH} - -Offset for pitch channel output in degrees. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | -360.0 | 360.0 | | 0.0 | deg | - -### MNT_OFF_ROLL (`FLOAT`) {#MNT_OFF_ROLL} - -Offset for roll channel output in degrees. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | -360.0 | 360.0 | | 0.0 | deg | - -### MNT_OFF_YAW (`FLOAT`) {#MNT_OFF_YAW} - -Offset for yaw channel output in degrees. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | -360.0 | 360.0 | | 0.0 | deg | - -### MNT_RANGE_PITCH (`FLOAT`) {#MNT_RANGE_PITCH} - -Range of pitch channel output in degrees (only in AUX output mode). - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 1.0 | 720.0 | | 90.0 | deg | - ### MNT_RANGE_ROLL (`FLOAT`) {#MNT_RANGE_ROLL} -Range of roll channel output in degrees (only in AUX output mode). +Range of roll channel output (only in MNT_MODE_OUT=AUX). + +Use output driver settings to calibrate (e.g. PWM_CENT/\_MIN/\_MAX). Note that only symmetric angular ranges are supported. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -25327,7 +26341,9 @@ Range of roll channel output in degrees (only in AUX output mode). ### MNT_RANGE_YAW (`FLOAT`) {#MNT_RANGE_YAW} -Range of yaw channel output in degrees (only in AUX output mode). +Range of yaw channel output (only in MNT_MODE_OUT=AUX). + +Use output driver settings to calibrate (e.g. PWM_CENT/\_MIN/\_MAX). Note that only symmetric angular ranges are supported. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -25366,6 +26382,18 @@ Input mode for RC gimbal input. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1 | | 1 | +### MNT_TAU (`FLOAT`) {#MNT_TAU} + +Alpha filter time constant defining the convergence rate (in seconds) for open-loop AUX mount control. + +Use when no angular position feedback is available. +With MNT_MODE_OUT set to AUX, the mount operates in open-loop and directly commands the servo output. +Parameters must be tuned for the specific servo to approximate its speed and response. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | | | 0.3 | + ## Multicopter Acro Mode ### MC_ACRO_EXPO (`FLOAT`) {#MC_ACRO_EXPO} @@ -25676,16 +26704,6 @@ The speed threshold is MPC_HOLD_MAX_XY | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 2 | | 2 | -### MPC_HOLD_DZ (`FLOAT`) {#MPC_HOLD_DZ} - -Deadzone for sticks in manual piloted modes. - -Does not apply to manual throttle and direct attitude piloting by stick. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | 0.01 | 0.1 | - ### MPC_HOLD_MAX_XY (`FLOAT`) {#MPC_HOLD_MAX_XY} Maximum horizontal velocity for which position hold is enabled (use 0 to disable check). @@ -25779,12 +26797,16 @@ Used below MPC_LAND_ALT3 if distance sensor data is availabe. User assisted landing radius. -When nudging is enabled (see MPC_LAND_RC_HELP), this controls -the maximum allowed horizontal displacement from the original landing point. +When nudging is enabled (see MPC_LAND_RC_HELP), this defines the maximum +allowed horizontal displacement from the original landing point. + +- If inside of the radius, only allow nudging inputs that do not move the vehicle outside of it. +- If outside of the radius, only allow nudging inputs that move the vehicle back towards it. + Set it to -1 for infinite radius. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | | 1 | 1000. | m | +|   | -1 | | 1 | -1.0 | m | ### MPC_LAND_RC_HELP (`INT32`) {#MPC_LAND_RC_HELP} @@ -25828,7 +26850,7 @@ Airmode is used to keep torque authority with zero thrust (see MC_AIRMODE). ### MPC_MAN_TILT_MAX (`FLOAT`) {#MPC_MAN_TILT_MAX} -Maximal tilt angle in Stabilized or Altitude mode. +Maximal tilt angle in Stabilized, Altitude and Altitude Cruise mode. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -26096,19 +27118,6 @@ capabilities of the vehicle. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0.1 | 10 | 1 | 2. | -### MPC_XY_MAN_EXPO (`FLOAT`) {#MPC_XY_MAN_EXPO} - -Manual position control stick exponential curve sensitivity. - -The higher the value the less sensitivity the stick has around zero -while still reaching the maximum value with full stick deflection. -0 Purely linear input curve -1 Purely cubic input curve - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | 0.01 | 0.6 | - ### MPC_XY_P (`FLOAT`) {#MPC_XY_P} Proportional gain for horizontal position error. @@ -26181,32 +27190,6 @@ Defined as corrective acceleration in m/s^2 per m/s velocity error | ------ | -------- | -------- | --------- | ------- | ---- | |   | 1.2 | 5 | 0.1 | 1.8 | -### MPC_YAW_EXPO (`FLOAT`) {#MPC_YAW_EXPO} - -Manual control stick yaw rotation exponential curve. - -The higher the value the less sensitivity the stick has around zero -while still reaching the maximum value with full stick deflection. -0 Purely linear input curve -1 Purely cubic input curve - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | 0.01 | 0.6 | - -### MPC_Z_MAN_EXPO (`FLOAT`) {#MPC_Z_MAN_EXPO} - -Manual control stick vertical exponential curve. - -The higher the value the less sensitivity the stick has around zero -while still reaching the maximum value with full stick deflection. -0 Purely linear input curve -1 Purely cubic input curve - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0 | 1 | 0.01 | 0.6 | - ### MPC_Z_P (`FLOAT`) {#MPC_Z_P} Proportional gain for vertical position error. @@ -26489,6 +27472,55 @@ The lowest input maps and is clamped to this rate. | ------ | -------- | -------- | --------- | ------- | ----- | |   | 1 | | 0.1 | 3. | deg/s | +## Multicopter Raptor + +### MC_RAPTOR_ENABLE (`INT32`) {#MC_RAPTOR_ENABLE} + +Enable Raptor flight mode. + +When enabled, the Raptor flight mode will be available. Please set MC_RAPTOR_OFFB according to your use case. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + +### MC_RAPTOR_INTREF (`INT32`) {#MC_RAPTOR_INTREF} + +Use internal reference instead of trajectory_setpoint. + +When enabled, instead of using the trajectory_setpoint, the position and yaw of the vehicle at the point when the Raptor mode is activated will be used as reference. +Use `mc_raptor intref lissajous ` to configure the trajectory. + +**Values:** + +- `0`: None +- `1`: Lissajous + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### MC_RAPTOR_OFFB (`INT32`) {#MC_RAPTOR_OFFB} + +Enable Offboard mode replacement. + +When enabled, the Raptor mode will replace the Offboard mode. +If disabled, the Raptor mode will be available as a separate external mode. In the latter case, Raptor will just hold the position, without requiring external setpoints. When Raptor replaces the Offboard mode, it requires external setpoints to be activated. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + +### MC_RAPTOR_VERBOS (`INT32`) {#MC_RAPTOR_VERBOS} + +Enable verbose output. + +When enabled, the Raptor flight mode will print verbose output to the console. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + ## Multicopter Rate Control ### MC_BAT_SCALE_EN (`INT32`) {#MC_BAT_SCALE_EN} @@ -27083,16 +28115,6 @@ Select your RC input protocol or auto to scan. ## Radio Calibration -### RC10_DZ (`FLOAT`) {#RC10_DZ} - -RC channel 10 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC10_MAX (`FLOAT`) {#RC10_MAX} RC channel 10 maximum. @@ -27138,16 +28160,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC11_DZ (`FLOAT`) {#RC11_DZ} - -RC channel 11 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC11_MAX (`FLOAT`) {#RC11_MAX} RC channel 11 maximum. @@ -27193,16 +28205,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC12_DZ (`FLOAT`) {#RC12_DZ} - -RC channel 12 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC12_MAX (`FLOAT`) {#RC12_MAX} RC channel 12 maximum. @@ -27248,16 +28250,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC13_DZ (`FLOAT`) {#RC13_DZ} - -RC channel 13 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC13_MAX (`FLOAT`) {#RC13_MAX} RC channel 13 maximum. @@ -27303,16 +28295,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC14_DZ (`FLOAT`) {#RC14_DZ} - -RC channel 14 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC14_MAX (`FLOAT`) {#RC14_MAX} RC channel 14 maximum. @@ -27358,16 +28340,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC15_DZ (`FLOAT`) {#RC15_DZ} - -RC channel 15 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC15_MAX (`FLOAT`) {#RC15_MAX} RC channel 15 maximum. @@ -27413,16 +28385,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC16_DZ (`FLOAT`) {#RC16_DZ} - -RC channel 16 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC16_MAX (`FLOAT`) {#RC16_MAX} RC channel 16 maximum. @@ -27468,16 +28430,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC17_DZ (`FLOAT`) {#RC17_DZ} - -RC channel 17 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC17_MAX (`FLOAT`) {#RC17_MAX} RC channel 17 maximum. @@ -27523,16 +28475,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC18_DZ (`FLOAT`) {#RC18_DZ} - -RC channel 18 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC18_MAX (`FLOAT`) {#RC18_MAX} RC channel 18 maximum. @@ -27578,16 +28520,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC1_DZ (`FLOAT`) {#RC1_DZ} - -RC channel 1 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | us | - ### RC1_MAX (`FLOAT`) {#RC1_MAX} RC channel 1 maximum. @@ -27633,16 +28565,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500.0 | us | -### RC2_DZ (`FLOAT`) {#RC2_DZ} - -RC channel 2 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | us | - ### RC2_MAX (`FLOAT`) {#RC2_MAX} RC channel 2 maximum. @@ -27688,16 +28610,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500.0 | us | -### RC3_DZ (`FLOAT`) {#RC3_DZ} - -RC channel 3 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | us | - ### RC3_MAX (`FLOAT`) {#RC3_MAX} RC channel 3 maximum. @@ -27743,16 +28655,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC4_DZ (`FLOAT`) {#RC4_DZ} - -RC channel 4 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | us | - ### RC4_MAX (`FLOAT`) {#RC4_MAX} RC channel 4 maximum. @@ -27798,16 +28700,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC5_DZ (`FLOAT`) {#RC5_DZ} - -RC channel 5 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | - ### RC5_MAX (`FLOAT`) {#RC5_MAX} RC channel 5 maximum. @@ -27853,16 +28745,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC6_DZ (`FLOAT`) {#RC6_DZ} - -RC channel 6 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | - ### RC6_MAX (`FLOAT`) {#RC6_MAX} RC channel 6 maximum. @@ -27908,16 +28790,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC7_DZ (`FLOAT`) {#RC7_DZ} - -RC channel 7 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | - ### RC7_MAX (`FLOAT`) {#RC7_MAX} RC channel 7 maximum. @@ -27963,16 +28835,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC8_DZ (`FLOAT`) {#RC8_DZ} - -RC channel 8 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 10.0 | - ### RC8_MAX (`FLOAT`) {#RC8_MAX} RC channel 8 maximum. @@ -28018,16 +28880,6 @@ Mid point value | ------ | -------- | -------- | --------- | ------- | ---- | |   | 800.0 | 2200.0 | | 1500 | us | -### RC9_DZ (`FLOAT`) {#RC9_DZ} - -RC channel 9 dead zone. - -The +- range of this value around the trim value will be considered as zero. - -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | 0.0 | 100.0 | | 0.0 | - ### RC9_MAX (`FLOAT`) {#RC9_MAX} RC channel 9 maximum. @@ -29338,10 +30190,11 @@ Return mode destination and flight path (home location, rally point, mission lan **Values:** - `0`: Return to closest safe point (home or rally point) via direct path. -- `1`: Return to closest safe point other than home (mission landing pattern or rally point), via direct path. If no mission landing or rally points are defined return home via direct path. Always chose closest safe landing point if vehicle is a VTOL in hover mode. +- `1`: Return to closest safe point other than home (mission landing pattern or rally point), via direct path. If no mission landing or rally points are defined return home via direct path. Always choose closest safe landing point if vehicle is a VTOL in hover mode. - `2`: Return to a planned mission landing, if available, using the mission path, else return to home via the reverse mission path. Do not consider rally points. - `3`: Return via direct path to closest destination: home, start of mission landing pattern or safe point. If the destination is a mission landing pattern, follow the pattern to land. - `4`: Return to the planned mission landing, or to home via the reverse mission path, whichever is closer by counting waypoints. Do not consider rally points. +- `5`: Return directly to safe landing point (do not consider mission landing and Home) | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -29542,6 +30395,16 @@ Distance from the center of the right wheel to the center of the left wheel. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 100 | 0.001 | 0 | m | +### RD_YAW_STK_GAIN (`FLOAT`) {#RD_YAW_STK_GAIN} + +Yaw stick gain for Manual mode. + +Assign value <1.0 to decrease stick response for yaw control. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.1 | 1 | 0.01 | 1 | + ## Rover Mecanum ### RM_COURSE_CTL_TH (`FLOAT`) {#RM_COURSE_CTL_TH} @@ -29567,6 +30430,16 @@ Distance from the center of the right wheel to the center of the left wheel. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 100 | 0.001 | 0 | m | +### RM_YAW_STK_GAIN (`FLOAT`) {#RM_YAW_STK_GAIN} + +Yaw stick gain for Manual mode. + +Assign value <1.0 to decrease stick response for yaw control. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.1 | 1 | 0.01 | 1 | + ## Rover Rate Control ### RO_YAW_ACCEL_LIM (`FLOAT`) {#RO_YAW_ACCEL_LIM} @@ -29591,6 +30464,18 @@ Set to -1 to disable. | ------ | -------- | -------- | --------- | ------- | ------- | |   | -1 | 10000 | 0.01 | -1. | deg/s^2 | +### RO_YAW_EXPO (`FLOAT`) {#RO_YAW_EXPO} + +Yaw rate expo factor. + +Exponential factor for tuning the input curve shape. +0 Purely linear input curve +1 Purely cubic input curve + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | | 0. | + ### RO_YAW_RATE_CORR (`FLOAT`) {#RO_YAW_RATE_CORR} Yaw rate correction factor. @@ -29651,6 +30536,19 @@ Percentage of stick input range that will be interpreted as zero around the stic | ------ | -------- | -------- | --------- | ------- | ---- | |   | 0 | 1 | 0.01 | 0.1 | +### RO_YAW_SUPEXPO (`FLOAT`) {#RO_YAW_SUPEXPO} + +Yaw rate super expo factor. + +"Superexponential" factor for refining the input curve shape tuned using RO_YAW_EXPO. +0 Pure Expo function +0.7 reasonable shape enhancement for intuitive stick feel +0.95 very strong bent input curve only near maxima have effect + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 0.95 | | 0. | + ## Rover Velocity Control ### RO_ACCEL_LIM (`FLOAT`) {#RO_ACCEL_LIM} @@ -29838,15 +30736,26 @@ Selects the algorithm used for logfile encryption | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 2 | +### SDLOG_BACKEND (`INT32`) {#SDLOG_BACKEND} + +Logging Backend (integer bitmask). + +If no logging is set the logger will not be started. Set bits true to enable: 0: SD card logging 1: Mavlink logging + +**Bitmask:** + +- `0`: SD card logging +- `1`: Mavlink logging + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 3 | | 3 | + ### SDLOG_BOOT_BAT (`INT32`) {#SDLOG_BOOT_BAT} Battery-only Logging. -When enabled, logging will not start from boot if battery power is not detected -(e.g. powered via USB on a test bench). This prevents extraneous flight logs from -being created during bench testing. -Note that this only applies to log-from-boot modes. This has no effect on arm-based -modes. +When enabled, logging will not start from boot if battery power is not detected (e.g. powered via USB on a test bench). This prevents extraneous flight logs from being created during bench testing. Note that this only applies to log-from-boot modes. This has no effect on arm-based modes. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------------ | ---- | @@ -29856,13 +30765,7 @@ modes. Maximum number of log directories to keep. -If there are more log directories than this value, -the system will delete the oldest directories during startup. -In addition, the system will delete old logs if there is not enough free space left. -The minimum amount is 300 MB. -If this is set to 0, old directories will only be removed if the free space falls below -the minimum. -Note: this does not apply to mission log files. +If there are more log directories than this value, the system will delete the oldest directories during startup. In addition, the system will delete old logs if there is not enough free space left. The minimum amount is 300 MB. If this is set to 0, old directories will only be removed if the free space falls below the minimum. Note: this does not apply to mission log files. | Reboot | minValue | maxValue | increment | default | unit | | ------- | -------- | -------- | --------- | ------- | ---- | @@ -29872,9 +30775,7 @@ Note: this does not apply to mission log files. Logfile Encryption key exchange key. -If the logfile is encrypted using a symmetric key algorithm, -the used encryption key is generated at logging start and stored -on the sdcard RSA2048 encrypted using this key. +If the logfile is encrypted using a symmetric key algorithm, the used encryption key is generated at logging start and stored on the sdcard RSA2048 encrypted using this key. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -29884,12 +30785,7 @@ on the sdcard RSA2048 encrypted using this key. Logfile Encryption key index. -Selects the key in keystore, used for encrypting the log. When using -a symmetric encryption algorithm, the key is generated at logging start -and kept stored in this index. For symmetric algorithms, the key is -volatile and valid only for the duration of logging. The key is stored -in encrypted format on the sdcard alongside the logfile, using an RSA2048 -key defined by the SDLOG_EXCHANGE_KEY +Selects the key in keystore, used for encrypting the log. When using a symmetric encryption algorithm, the key is generated at logging start and kept stored in this index. For symmetric algorithms, the key is volatile and valid only for the duration of logging. The key is stored in encrypted format on the sdcard alongside the logfile, using an RSA2048 key defined by the SDLOG_EXCHANGE_KEY | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -29899,14 +30795,7 @@ key defined by the SDLOG_EXCHANGE_KEY Mission Log. -If enabled, a small additional "mission" log file will be written to the SD card. -The log contains just those messages that are useful for tasks like -generating flight statistics and geotagging. -The different modes can be used to further reduce the logged data -(and thus the log file size). For example, choose geotagging mode to -only log data required for geotagging. -Note that the normal/full log is still created, and contains all -the data in the mission log (and more). +If enabled, a small additional "mission" log file will be written to the SD card. The log contains just those messages that are useful for tasks like generating flight statistics and geotagging. The different modes can be used to further reduce the logged data (and thus the log file size). For example, choose geotagging mode to only log data required for geotagging. Note that the normal/full log is still created, and contains all the data in the mission log (and more). **Values:** @@ -29922,12 +30811,10 @@ the data in the mission log (and more). Logging Mode. -Determines when to start and stop logging. By default, logging is started -when arming the system, and stopped when disarming. +Determines when to start and stop logging. By default, logging is started when arming the system, and stopped when disarming. Note: The logging start/end points that can be configured here only apply to SD logging. The mavlink backend is started/stopped independently of these points. **Values:** -- `-1`: disabled - `0`: when armed until disarm (default) - `1`: from boot until disarm - `2`: from boot until shutdown @@ -29942,23 +30829,7 @@ when arming the system, and stopped when disarming. Logging topic profile (integer bitmask). -This integer bitmask controls the set and rates of logged topics. -The default allows for general log analysis while keeping the -log file size reasonably small. -Enabling multiple sets leads to higher bandwidth requirements and larger log -files. -Set bits true to enable: -0 : Default set (used for general log analysis) -1 : Full rate estimator (EKF2) replay topics -2 : Topics for thermal calibration (high rate raw IMU and Baro sensor data) -3 : Topics for system identification (high rate actuator control and IMU data) -4 : Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators) -5 : Debugging topics (debug\_\*.msg topics, for custom code) -6 : Topics for sensor comparison (low rate raw IMU, Baro and magnetometer data) -7 : Topics for computer vision and collision prevention -8 : Raw FIFO high-rate IMU (Gyro) -9 : Raw FIFO high-rate IMU (Accel) -10: Logging of mavlink tunnel message (useful for payload communication debugging) +This integer bitmask controls the set and rates of logged topics. The default allows for general log analysis while keeping the log file size reasonably small. Enabling multiple sets leads to higher bandwidth requirements and larger log files. Set bits true to enable: 0 : Default set (used for general log analysis) 1 : Full rate estimator (EKF2) replay topics 2 : Topics for thermal calibration (high rate raw IMU and Baro sensor data) 3 : Topics for system identification (high rate actuator control and IMU data) 4 : Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators) 5 : Debugging topics (debug\_\*.msg topics, for custom code) 6 : Topics for sensor comparison (low rate raw IMU, Baro and magnetometer data) 7 : Topics for computer vision and collision prevention 8 : Raw FIFO high-rate IMU (Gyro) 9 : Raw FIFO high-rate IMU (Accel) 10: Logging of mavlink tunnel message (useful for payload communication debugging) **Bitmask:** @@ -29983,11 +30854,7 @@ Set bits true to enable: UTC offset (unit: min). -the difference in hours and minutes from Coordinated -Universal Time (UTC) for a your place and date. -for example, In case of South Korea(UTC+09:00), -UTC offset is 540 min (9\*60) -refer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets +the difference in hours and minutes from Coordinated Universal Time (UTC) for a your place and date. for example, In case of South Korea(UTC+09:00), UTC offset is 540 min (9\*60) refer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | @@ -32244,6 +33111,44 @@ Use SENS_MAG_SIDES instead | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 63 | +### GRF_RATE_CFG (`INT32`) {#GRF_RATE_CFG} + +Lightware GRF lidar update rate. + +The Lightware GRF distance sensor can increase the update rate to enable greater resolution. + +**Values:** + +- `1`: 1 Hz +- `2`: 2 Hz +- `3`: 4 Hz +- `4`: 5 Hz +- `5`: 10 Hz +- `6`: 20 Hz +- `7`: 30 Hz +- `8`: 40 Hz +- `9`: 50 Hz + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 4 | + +### GRF_SENS_MODEL (`INT32`) {#GRF_SENS_MODEL} + +GRF Sensor model. + +GRF Sensor Model used to distinush between the GRF250 and GRF500 since both have different max distance range. + +**Values:** + +- `0`: disable +- `1`: GRF250 +- `2`: GRF500 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ### ILABS_MODE (`INT32`) {#ILABS_MODE} InertialLabs INS sensor mode configuration. @@ -32600,331 +33505,423 @@ INA238 Power Monitor Shunt. ### MS_ACCEL_RANGE (`INT32`) {#MS_ACCEL_RANGE} -Sets the range of the accelerometer. +MicroStrain accelerometer range. --1 = Will not be configured, and will use the device default range, -Each adjustable range has a corresponding integer setting. Refer to the device's User Manual to check the available adjustment ranges. -https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com -Restart required -This parameter is specific to the MicroStrain driver. +-1 = Will not be configured, and will use the device default range. +Ranges vary by device and map to integer codes. Check the device's [User Manual](https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com) for supported ranges and set the corresponding integer. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | -1 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | -1 | ### MS_ALIGNMENT (`INT32`) {#MS_ALIGNMENT} -Alignment type. +MicroStrain heading alignment type. -Select the source of heading alignment -This is a bitfield, you can use more than 1 source -Bit 0 - Dual-antenna GNSS -Bit 1 - GNSS kinematic (requires motion, e.g. a GNSS velocity) -Bit 2 - Magnetometer -Bit 3 - External Heading (first valid external heading will be used to initialize the filter) -Restart required -This parameter is specific to the MicroStrain driver. +Select the source of heading alignment. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 2 | +**Bitmask:** + +- `0`: Dual-antenna GNSS +- `1`: GNSS kinematic (requires motion, e.g. a GNSS velocity) +- `2`: Magnetometer +- `3`: External Heading (first valid external heading will be used to initialize the filter) + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 1 | 15 | | 2 | ### MS_BARO_RATE_HZ (`INT32`) {#MS_BARO_RATE_HZ} -Barometer data rate. +MicroStrain barometer data rate. -Barometer data rate -Max Limit: 1000 -0 - Disable barometer datastream -The max limit should be divisible by the rate -eg: 1000 % MS_BARO_RATE_HZ = 0 -Restart required -This parameter is specific to the MicroStrain driver. +Barometer data rate (Hz). +Valid rates: 0 or any factor of 1000. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 50 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 1000 | | 50 | + +### MS_EHEAD_YAW (`FLOAT`) {#MS_EHEAD_YAW} + +MicroStrain External Heading Orientation (Yaw). + +The orientation of the device (Radians) with respect to the vehicle frame around the z axis. +Requires MS_EXT_HEAD_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_EMAG_PTCH (`FLOAT`) {#MS_EMAG_PTCH} + +MicroStrain External Magnetometer Orientation (Pitch). + +The orientation of the device (Radians) with respect to the vehicle frame around the y axis. +Requires MS_EXT_MAG_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_EMAG_ROLL (`FLOAT`) {#MS_EMAG_ROLL} + +MicroStrain External Magnetometer Orientation (Roll). + +The orientation of the device (Radians) with respect to the vehicle frame around the x axis. +Requires MS_EXT_MAG_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_EMAG_UNCERT (`FLOAT`) {#MS_EMAG_UNCERT} + +MicroStrain external magnetometer uncertainty. + +The 1-sigma uncertainty (in Gauss) for all axes, which will remain constant across all aiding measurements. +Requires MS_EXT_MAG_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.1 | + +### MS_EMAG_YAW (`FLOAT`) {#MS_EMAG_YAW} + +MicroStrain External Magnetometer Orientation (Yaw). + +The orientation of the device (Radians) with respect to the vehicle frame around the z axis. +Requires MS_EXT_MAG_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_EXT_HEAD_EN (`INT32`) {#MS_EXT_HEAD_EN} +Enable MicroStrain external heading aiding. + Toggles external heading as an aiding measurement. - -0 = Disabled, -1 = Enabled If enabled, the filter will be configured to accept external heading as an aiding meaurement. -Restart required -This parameter is specific to the MicroStrain driver. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + +### MS_EXT_MAG_EN (`INT32`) {#MS_EXT_MAG_EN} + +Enable MicroStrain external magnetometer aiding. + +Toggles external magnetometer aiding in the device filter. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | ### MS_FILT_RATE_HZ (`INT32`) {#MS_FILT_RATE_HZ} -EKF data Rate. +MicroStrain EKF data rate. -EKF data rate -Max Limit: 1000 -0 - Disable EKF datastream -The max limit should be divisible by the rate -eg: 1000 % MS_FILT_RATE_HZ = 0 -Restart required -This parameter is specific to the MicroStrain driver. +The rate at which the INS data is published (Hz). +Valid rates: 0 or any factor of 1000. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 250 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 1000 | | 250 | ### MS_GNSS_AID_SRC (`INT32`) {#MS_GNSS_AID_SRC} -GNSS aiding source control. +MicroStrain GNSS aiding source control. -Select the source of gnss aiding (GNSS/INS) -1 = All internal receivers, -2 = External GNSS messages, -3 = GNSS receiver 1 only -4 = GNSS receiver 2 only -Restart required -This parameter is specific to the MicroStrain driver. +Select the source of gnss aiding (GNSS/INS). -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 1 | +**Values:** + +- `1`: All internal receivers +- `2`: External GNSS messages +- `3`: GNSS receiver 1 only +- `4`: GNSS receiver 2 only + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 1 | ### MS_GNSS_OFF1_X (`FLOAT`) {#MS_GNSS_OFF1_X} -GNSS lever arm offset 1 (X). +MicroStrain GNSS lever arm offset 1 (X). -Lever arm offset (m) in the X direction for the external GNSS receiver -In the case of a dual antenna setup, this is antenna 1 -Restart required -This parameter is specific to the MicroStrain driver. +Lever arm offset (m) in the X direction for the external GNSS receiver. +In the case of a dual antenna setup, this is antenna 1. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_OFF1_Y (`FLOAT`) {#MS_GNSS_OFF1_Y} -GNSS lever arm offset 1 (Y). +MicroStrain GNSS lever arm offset 1 (Y). -Lever arm offset (m) in the Y direction for the external GNSS receiver -In the case of a dual antenna setup, this is antenna 1 -Restart required -This parameter is specific to the MicroStrain driver. +Lever arm offset (m) in the Y direction for the external GNSS receiver. +In the case of a dual antenna setup, this is antenna 1. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_OFF1_Z (`FLOAT`) {#MS_GNSS_OFF1_Z} -GNSS lever arm offset 1 (Z). +MicroStrain GNSS lever arm offset 1 (Z). -Lever arm offset (m) in the Z direction for the external GNSS receiver -In the case of a dual antenna setup, this is antenna 1 -Restart required -This parameter is specific to the MicroStrain driver. +Lever arm offset (m) in the Z direction for the external GNSS receiver. +In the case of a dual antenna setup, this is antenna 1. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_OFF2_X (`FLOAT`) {#MS_GNSS_OFF2_X} -GNSS lever arm offset 2 (X). +MicroStrain GNSS lever arm offset 2 (X). Lever arm offset (m) in the X direction for antenna 2 -This will only be used if the device supports a dual antenna setup -Restart required -This parameter is specific to the MicroStrain driver. +This will only be used if the device supports a dual antenna setup. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_OFF2_Y (`FLOAT`) {#MS_GNSS_OFF2_Y} -GNSS lever arm offset 2 (Y). +MicroStrain GNSS lever arm offset 2 (Y). -Lever arm offset (m) in the Y direction for antenna 2 -This will only be used if the device supports a dual antenna setup -Restart required -This parameter is specific to the MicroStrain driver. +Lever arm offset (m) in the Y direction for antenna 2. +This will only be used if the device supports a dual antenna setup. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_OFF2_Z (`FLOAT`) {#MS_GNSS_OFF2_Z} -GNSS lever arm offset 2 (Z). +MicroStrain GNSS lever arm offset 2 (Z). -Lever arm offset (m) in the X direction for antenna 2 -This will only be used if the device supports a dual antenna setup -Restart required -This parameter is specific to the MicroStrain driver. +Lever arm offset (m) in the X direction for antenna 2. +This will only be used if the device supports a dual antenna setup. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_GNSS_RATE_HZ (`INT32`) {#MS_GNSS_RATE_HZ} -GNSS data Rate. +MicroStrain GNSS data rate. -GNSS receiver 1 and 2 data rate -Max Limit: 5 -The max limit should be divisible by the rate -0 - Disable GNSS datastream -eg: 5 % MS_GNSS_RATE_HZ = 0 -Restart required -This parameter is specific to the MicroStrain driver. +GNSS receiver 1 and 2 data rate (Hz). +Valid rates: 0, 1 or 5. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 5 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 5 | | 5 | ### MS_GYRO_RANGE (`INT32`) {#MS_GYRO_RANGE} -Sets the range of the gyro. +MicroStrain gyroscope range. --1 = Will not be configured, and will use the device default range, -Each adjustable range has a corresponding integer setting. Refer to the device's User Manual to check the available adjustment ranges. -https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com -Restart required -This parameter is specific to the MicroStrain driver. +-1 = Will not be configured, and will use the device default range. +Ranges vary by device and map to integer codes. Check the device's [User Manual](https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com) for supported ranges and set the corresponding integer. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | -1 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | -1 | ### MS_IMU_RATE_HZ (`INT32`) {#MS_IMU_RATE_HZ} -IMU Data Rate. +MicroStrain IMU data rate. -IMU (Accelerometer and Gyroscope) data rate -The INS driver will be scheduled at a rate 2\*MS_IMU_RATE_HZ -Max Limit: 1000 -0 - Disable IMU datastream -The max limit should be divisible by the rate -eg: 1000 % MS_IMU_RATE_HZ = 0 -Restart required -This parameter is specific to the MicroStrain driver. +Accelerometer and Gyroscope data rate (Hz). +Valid rates: 0 or any factor of 1000. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 500 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 1000 | | 500 | ### MS_INT_HEAD_EN (`INT32`) {#MS_INT_HEAD_EN} +Enable MicroStrain internal heading aiding. + Toggles internal heading as an aiding measurement. - -0 = Disabled, -1 = Enabled If dual antennas are supported (CV7-GNSS/INS). The filter will be configured to use dual antenna heading as an aiding measurement. -Restart required -This parameter is specific to the MicroStrain driver. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | ### MS_INT_MAG_EN (`INT32`) {#MS_INT_MAG_EN} +Enable MicroStrain internal magnetometer. + Toggles internal magnetometer aiding in the device filter. -0 = Disabled, -1 = Enabled -Restart required -This parameter is specific to the MicroStrain driver. +**Values:** -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | ### MS_MAG_RATE_HZ (`INT32`) {#MS_MAG_RATE_HZ} -Magnetometer Data Rate. +MicroStrain magnetometer data rate. -Magnetometer data rate -Max Limit: 1000 -0 - Disable magnetometer datastream -The max limit should be divisible by the rate -eg: 1000 % MS_MAG_RATE_HZ = 0 -Restart required -This parameter is specific to the MicroStrain driver. +Magnetometer data rate (Hz). +Valid rates: 0 or any factor of 1000. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 50 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 1000 | | 50 | ### MS_MODE (`INT32`) {#MS_MODE} -Toggles using the device as the primary EKF. +MicroStrain device mode. -Setting to 1 will publish data from the device to the vehicle topics (global_position, attitude, local_position, odometry), estimator_status and sensor_selection -Setting to 0 will publish data from the device to the external_ins topics (global position, attitude, local position) -Restart Required -This parameter is specific to the MicroStrain driver. +Sensor mode publishes raw IMU data to be used by EKF2. INS data from the device is published to the external INS topics. +INS mode publishes the INS data to the vehicle topics to be used for navigation. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 1 | +**Values:** + +- `0`: Sensor Mode +- `1`: INS Mode + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + +### MS_OFLW_OFF_X (`FLOAT`) {#MS_OFLW_OFF_X} + +MicroStrain optical flow offset (X). + +Offset (m) in the X direction if an Optical Flow sensor is connected. +Requires MS_OPT_FLOW_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_OFLW_OFF_Y (`FLOAT`) {#MS_OFLW_OFF_Y} + +MicroStrain optical flow offset (Y). + +Offset (m) in the Y direction if an Optical Flow sensor is connected. +Requires MS_OPT_FLOW_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_OFLW_OFF_Z (`FLOAT`) {#MS_OFLW_OFF_Z} + +MicroStrain optical flow offset (Z). + +Offset (m) in the Z direction if an Optical Flow sensor is connected. +Requires MS_OPT_FLOW_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | + +### MS_OFLW_UNCERT (`FLOAT`) {#MS_OFLW_UNCERT} + +MicroStrain optical flow uncertainty. + +The 1-sigma uncertainty (in m/s) for the X and Y axes, which will remain constant across all aiding measurements. +The Z axis is not used for aiding. +Requires MS_OPT_FLOW_EN to be enabled to be used. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.1 | + +### MS_OPT_FLOW_EN (`INT32`) {#MS_OPT_FLOW_EN} + +Enable MicroStrain optical flow aiding. + +Toggles body frame velocity as an aiding measurement. +The driver uses the body frame velocity from the optical flow sensor as the aiding measurements. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | ### MS_SENSOR_PTCH (`FLOAT`) {#MS_SENSOR_PTCH} -Sensor to Vehicle Transform (Pitch). +MicroStrain Sensor to Vehicle Transform (Pitch). -The orientation of the device (Radians) with respect to the vehicle frame around the y axis -Requires MS_SVT_EN to be enabled to be used -Restart required -This parameter is specific to the MicroStrain driver. +The orientation of the device (Radians) with respect to the vehicle frame around the y axis. +Requires MS_SVT_EN to be enabled to be used. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_SENSOR_ROLL (`FLOAT`) {#MS_SENSOR_ROLL} -Sensor to Vehicle Transform (Roll). +MicroStrain Sensor to vehicle transform (Roll). -The orientation of the device (Radians) with respect to the vehicle frame around the x axis -Requires MS_SVT_EN to be enabled to be used -Restart required -This parameter is specific to the MicroStrain driver. +The orientation of the device (Radians) with respect to the vehicle frame around the x axis. +Requires MS_SVT_EN to be enabled to be used. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_SENSOR_YAW (`FLOAT`) {#MS_SENSOR_YAW} -Sensor to Vehicle Transform (Yaw). +MicroStrain Sensor to Vehicle Transform (Yaw). -The orientation of the device (Radians) with respect to the vehicle frame around the z axis -Requires MS_SVT_EN to be enabled to be used -Restart required -This parameter is specific to the MicroStrain driver. +The orientation of the device (Radians) with respect to the vehicle frame around the z axis. +Requires MS_SVT_EN to be enabled to be used. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0.0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0.0 | ### MS_SVT_EN (`INT32`) {#MS_SVT_EN} -Enables sensor to vehicle transform. +Enables Microstrain sensor to vehicle transform. -0 = Disabled, -1 = Enabled If the sensor has a different orientation with respect to the vehicle. This will enable a transform to correct itself. -The transform is described by MS_SENSOR_ROLL, MS_SENSOR_PITCH, MS_SENSOR_YAW -Restart required -This parameter is specific to the MicroStrain driver. +The transform is described by MS_SENSOR_ROLL, MS_SENSOR_PITCH, MS_SENSOR_YAW. -| Reboot | minValue | maxValue | increment | default | unit | -| ------ | -------- | -------- | --------- | ------- | ---- | -|   | | | | 0 | +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | ### PCF8583_MAGNET (`INT32`) {#PCF8583_MAGNET} @@ -32959,6 +33956,49 @@ reset of counter takes some time - measurement with reset has worse accuracy. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | | | | 500000 | +### SBG_BAUDRATE (`INT32`) {#SBG_BAUDRATE} + +sbgECom driver baudrate. + +Baudrate used by default for serial communication between PX4 +and SBG Systems INS through sbgECom driver. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 9600 | 921600 | | 921600 | + +### SBG_CONFIGURE_EN (`INT32`) {#SBG_CONFIGURE_EN} + +sbgECom driver INS configuration enable. + +Enable SBG Systems INS configuration through sbgECom driver +on start. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + +### SBG_MODE (`INT32`) {#SBG_MODE} + +sbgECom driver mode. + +Modes available for sbgECom driver. +In Sensors Only mode, use external IMU and magnetometer. +In GNSS mode, use external GNSS in addition to sensors only mode. +In INS mode, use external Kalman Filter in addition to GNSS mode. +In INS mode, requires EKF2_EN 0. Keeping both enabled +can lead to an unexpected behavior and vehicle instability. + +**Values:** + +- `0`: Sensors Only +- `1`: GNSS +- `2`: INS (default) + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 2 | + ### SENS_AFBR_HYSTER (`INT32`) {#SENS_AFBR_HYSTER} AFBR Rangefinder Short/Long Range Threshold Hysteresis. @@ -33018,6 +34058,31 @@ The mode will switch from long to short range when the distance is less than the | ------ | -------- | -------- | --------- | ------- | ---- | |   | 1 | 50 | | 4 | m | +### SENS_BAHRS_CFG (`INT32`) {#SENS_BAHRS_CFG} + +Serial Configuration for EULER-NAV BAHRS. + +Configure on which serial port to run EULER-NAV BAHRS. + +**Values:** + +- `0`: Disabled +- `6`: UART 6 +- `101`: TELEM 1 +- `102`: TELEM 2 +- `103`: TELEM 3 +- `104`: TELEM/SERIAL 4 +- `201`: GPS 1 +- `202`: GPS 2 +- `203`: GPS 3 +- `300`: Radio Controller +- `301`: Wifi Port +- `401`: EXT2 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ### SENS_BARO_QNH (`FLOAT`) {#SENS_BARO_QNH} QNH for barometer. @@ -33292,6 +34357,31 @@ Enable simulated GPS sinstance. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 1 | | 0 | +### SENS_EN_GRF_CFG (`INT32`) {#SENS_EN_GRF_CFG} + +Serial Configuration for Lightware GRF Rangefinder (serial). + +Configure on which serial port to run Lightware GRF Rangefinder (serial). + +**Values:** + +- `0`: Disabled +- `6`: UART 6 +- `101`: TELEM 1 +- `102`: TELEM 2 +- `103`: TELEM 3 +- `104`: TELEM/SERIAL 4 +- `201`: GPS 1 +- `202`: GPS 2 +- `203`: GPS 3 +- `300`: Radio Controller +- `301`: Wifi Port +- `401`: EXT2 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ### SENS_EN_INA220 (`INT32`) {#SENS_EN_INA220} Enable INA220 Power Monitor. @@ -33375,6 +34465,14 @@ Maxbotix Sonar (mb12xx). | ------- | -------- | -------- | --------- | ------------ | ---- | | ✓ | | | | Disabled (0) | +### SENS_EN_MCP9808 (`INT32`) {#SENS_EN_MCP9808} + +Enable MCP9808 temperature sensor (external I2C). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + ### SENS_EN_MPDT (`INT32`) {#SENS_EN_MPDT} Enable Mappydot rangefinder (i2c). @@ -33509,7 +34607,7 @@ Lightware Laser Rangefinder hardware model (serial). ### SENS_EN_SF1XX (`INT32`) {#SENS_EN_SF1XX} -Lightware SF1xx/SF20/LW20 laser rangefinder (i2c). +Lightware laser rangefinder (i2c). **Values:** @@ -33521,10 +34619,12 @@ Lightware SF1xx/SF20/LW20 laser rangefinder (i2c). - `5`: SF/LW20/b - `6`: SF/LW20/c - `7`: SF/LW30/d +- `8`: GRF250 +- `9`: GRF500 | Reboot | minValue | maxValue | increment | default | unit | | ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0 | 6 | | 0 | +| ✓ | 0 | 9 | | 0 | ### SENS_EN_SF45_CFG (`INT32`) {#SENS_EN_SF45_CFG} @@ -33605,6 +34705,16 @@ Thermal control of sensor temperature. | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | -1 | +### SENS_EN_TMP102 (`INT32`) {#SENS_EN_TMP102} + +Enable TMP102. + +Enable the driver for the TMP102 temperature sensor + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + ### SENS_EN_TRANGER (`INT32`) {#SENS_EN_TRANGER} TeraRanger Rangefinder (i2c). @@ -33741,13 +34851,16 @@ When no blending is active, this defines the preferred GPS receiver instance. The GPS selection logic waits until the primary receiver is available to send data to the EKF even if a secondary instance is already available. The secondary instance is then only used if the primary one times out. -To have an equal priority of all the instances, set this parameter to -1 and -the best receiver will be used. +Accepted values: +-1 : Auto (equal priority for all instances) +0 : Main serial GPS instance +1 : Secondary serial GPS instance +2-127 : UAVCAN module node ID This parameter has no effect if blending is active. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | -1 | 1 | | 0 | +|   | -1 | 127 | | 0 | ### SENS_GPS_TAU (`FLOAT`) {#SENS_GPS_TAU} @@ -34457,6 +35570,31 @@ This parameter defines the rotation of the Mappydot sensor relative to the platf | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 7 | | 0 | +### SENS_MS_CFG (`INT32`) {#SENS_MS_CFG} + +Serial Configuration for MICROSTRAIN. + +Configure on which serial port to run MICROSTRAIN. + +**Values:** + +- `0`: Disabled +- `6`: UART 6 +- `101`: TELEM 1 +- `102`: TELEM 2 +- `103`: TELEM 3 +- `104`: TELEM/SERIAL 4 +- `201`: GPS 1 +- `202`: GPS 2 +- `203`: GPS 3 +- `300`: Radio Controller +- `301`: Wifi Port +- `401`: EXT2 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ### SENS_OR_ADIS164X (`INT32`) {#SENS_OR_ADIS164X} Analog Devices ADIS16448 IMU Orientation(external SPI). @@ -34470,6 +35608,31 @@ Analog Devices ADIS16448 IMU Orientation(external SPI). | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 101 | | 0 | +### SENS_SBG_CFG (`INT32`) {#SENS_SBG_CFG} + +Serial Configuration for sbgECom. + +Configure on which serial port to run sbgECom. + +**Values:** + +- `0`: Disabled +- `6`: UART 6 +- `101`: TELEM 1 +- `102`: TELEM 2 +- `103`: TELEM 3 +- `104`: TELEM/SERIAL 4 +- `201`: GPS 1 +- `202`: GPS 2 +- `203`: GPS 3 +- `300`: Radio Controller +- `301`: Wifi Port +- `401`: EXT2 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ### SENS_SF0X_CFG (`INT32`) {#SENS_SF0X_CFG} Serial Configuration for Lightware Laser Rangefinder (serial). @@ -34619,6 +35782,26 @@ Configure on which serial port to run VectorNav (VN-100, VN-200, VN-300). | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | | | | 0 | +### SF1XX_ROT (`INT32`) {#SF1XX_ROT} + +Lightware laser rangefinder Rotation. + +Distance sensor orientation as MAV_SENSOR_ORIENTATION enum. +Applies to all models supported by SENS_EN_SF1XX. + +**Values:** + +- `0`: Forward +- `2`: Right +- `4`: Backward +- `6`: Left +- `24`: Upward +- `25`: Downward + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 25 | | 25 | + ### SF45_ORIENT_CFG (`INT32`) {#SF45_ORIENT_CFG} Orientation upright or facing downward. @@ -35562,6 +36745,86 @@ Note: certain drivers such as the GPS can determine the Baudrate automatically. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | | | | 1 | +## Simulation + +### SIM_GZ_EN_ASPD (`INT32`) {#SIM_GZ_EN_ASPD} + +Enable airspeed sensor in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### SIM_GZ_EN_BARO (`INT32`) {#SIM_GZ_EN_BARO} + +Enable barometer/air pressure sensor in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### SIM_GZ_EN_FLOW (`INT32`) {#SIM_GZ_EN_FLOW} + +Enable optical flow sensor in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### SIM_GZ_EN_GPS (`INT32`) {#SIM_GZ_EN_GPS} + +Enable GPS/NavSat sensor in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### SIM_GZ_EN_LIDAR (`INT32`) {#SIM_GZ_EN_LIDAR} + +Enable laser/lidar sensors in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + +### SIM_GZ_EN_ODOM (`INT32`) {#SIM_GZ_EN_ODOM} + +Enable odometry in Gazebo bridge. + +**Values:** + +- `0`: Disabled +- `1`: Enabled + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | | | Enabled (1) | + ## Simulation In Hardware ### SIH_DISTSNSR_MAX (`FLOAT`) {#SIH_DISTSNSR_MAX} @@ -38977,6 +40240,25 @@ UAVCAN CAN bus bitrate. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 20000 | 1000000 | | 1000000 | +### CANNODE_NODE_ID (`INT32`) {#CANNODE_NODE_ID} + +UAVCAN CAN node ID (0 for dynamic allocation). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 127 | | 0 | + +### CANNODE_PUB_BAR (`INT32`) {#CANNODE_PUB_BAR} + +Enable barometer publication. + +Enables publication of static pressure and static temperature +from the barometer sensor over UAVCAN. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | 1 | | Enabled (1) | + ### CANNODE_PUB_IMU (`INT32`) {#CANNODE_PUB_IMU} Enable RawIMU pub. @@ -38985,6 +40267,17 @@ Enable RawIMU pub. | ------ | -------- | -------- | --------- | ------------ | ---- | |   | | 1 | | Disabled (0) | +### CANNODE_PUB_MAG (`INT32`) {#CANNODE_PUB_MAG} + +Enable magnetometer publication. + +Enables publication of magnetic field strength +from the magnetometer sensor over UAVCAN. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ----------- | ---- | +| ✓ | | 1 | | Enabled (1) | + ### CANNODE_PUB_MBD (`INT32`) {#CANNODE_PUB_MBD} Enable MovingBaselineData publication. @@ -39111,7 +40404,7 @@ starve other nodes on the bus. UAVCAN ANTI_COLLISION light operating mode. This parameter defines the minimum condition under which the system will command -the ANTI_COLLISION lights on +lights with anti-collision function to turn on (white). 0 - Always off 1 - When autopilot is armed 2 - When autopilot is prearmed @@ -39128,67 +40421,97 @@ the ANTI_COLLISION lights on | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 3 | | 2 | -### UAVCAN_LGT_LAND (`INT32`) {#UAVCAN_LGT_LAND} +### UAVCAN_LGT_FN0 (`INT32`) {#UAVCAN_LGT_FN0} -UAVCAN LIGHT_ID_LANDING light operating mode. +Light 0 function. -This parameter defines the minimum condition under which the system will command -the LIGHT_ID_LANDING lights on -0 - Always off -1 - When autopilot is armed -2 - When autopilot is prearmed -3 - Always on +Function assigned to light 0. +0: Status - displays system status colors +1: Anti-collision - white beacon controlled by LGT_ANTCL parameter **Values:** -- `0`: Always off -- `1`: When autopilot is armed -- `2`: When autopilot is prearmed -- `3`: Always on +- `0`: Status Light +- `1`: Anti-collision Light -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0 | 3 | | 0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | | 0 | -### UAVCAN_LGT_NAV (`INT32`) {#UAVCAN_LGT_NAV} +### UAVCAN_LGT_FN1 (`INT32`) {#UAVCAN_LGT_FN1} -UAVCAN RIGHT_OF_WAY light operating mode. +Light 1 function. -This parameter defines the minimum condition under which the system will command -the RIGHT_OF_WAY lights on -0 - Always off -1 - When autopilot is armed -2 - When autopilot is prearmed -3 - Always on +Function assigned to light 1. +0: Status - displays system status colors +1: Anti-collision - white beacon controlled by LGT_ANTCL parameter **Values:** -- `0`: Always off -- `1`: When autopilot is armed -- `2`: When autopilot is prearmed -- `3`: Always on +- `0`: Status Light +- `1`: Anti-collision Light -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | 0 | 3 | | 3 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | | 0 | -### UAVCAN_LGT_STROB (`INT32`) {#UAVCAN_LGT_STROB} +### UAVCAN_LGT_FN2 (`INT32`) {#UAVCAN_LGT_FN2} -UAVCAN STROBE light operating mode. +Light 2 function. -This parameter defines the minimum condition under which the system will command -the STROBE lights on -0 - Always off -1 - When autopilot is armed -2 - When autopilot is prearmed -3 - Always on +Function assigned to light 2. +0: Status - displays system status colors +1: Anti-collision - white beacon controlled by LGT_ANTCL parameter **Values:** -- `0`: Always off -- `1`: When autopilot is armed -- `2`: When autopilot is prearmed -- `3`: Always on +- `0`: Status Light +- `1`: Anti-collision Light + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | | 0 | + +### UAVCAN_LGT_ID0 (`INT32`) {#UAVCAN_LGT_ID0} + +Light 0 ID. + +specifies the light_id value for light 0 in UAVCAN LightsCommand messages. +This determines which physical LED responds to commands for this light slot. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 255 | | 0 | + +### UAVCAN_LGT_ID1 (`INT32`) {#UAVCAN_LGT_ID1} + +Light 1 ID. + +specifies the light_id value for light 1 in UAVCAN LightsCommand messages. +This determines which physical LED responds to commands for this light slot. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 255 | | 0 | + +### UAVCAN_LGT_ID2 (`INT32`) {#UAVCAN_LGT_ID2} + +Light 2 ID. + +specifies the light_id value for light 2 in UAVCAN LightsCommand messages. +This determines which physical LED responds to commands for this light slot. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 255 | | 0 | + +### UAVCAN_LGT_NUM (`INT32`) {#UAVCAN_LGT_NUM} + +Number of UAVCAN lights to configure. + +Number of lights to control via UAVCAN LightsCommand messages. +Set to 0 to disable UAVCAN light control. +Each light uses two parameters: LGT_IDx for the light_id and LGT_FNx for the function. | Reboot | minValue | maxValue | increment | default | unit | | ------- | -------- | -------- | --------- | ------- | ---- | @@ -39415,6 +40738,17 @@ uavcan::equipment::ahrs::MagneticFieldStrength2 | ------- | -------- | -------- | --------- | ----------- | ---- | | ✓ | | | | Enabled (1) | +### UAVCAN_SUB_MBD (`INT32`) {#UAVCAN_SUB_MBD} + +subscription MovingBaselineData. + +Enable UAVCAN MovingBaselineData subscription. +ardupilot::gnss::MovingBaselineData + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + ### UAVCAN_SUB_RNG (`INT32`) {#UAVCAN_SUB_RNG} subscription range finder. @@ -39564,6 +40898,14 @@ Maximum time (in seconds) before resetting setpoint. | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 2.0 | +### UUV_STICK_MODE (`INT32`) {#UUV_STICK_MODE} + +Stick mode selector (0=Heave/sway control, roll/pitch leveled; 1=Pitch/roll control). + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 1 | | 0 | + ### UUV_THRUST_SAT (`FLOAT`) {#UUV_THRUST_SAT} UUV Thrust setpoint Saturation. @@ -39851,6 +41193,17 @@ uXRCE-DDS domain ID | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | | | | 0 | +### UXRCE_DDS_FLCTRL (`INT32`) {#UXRCE_DDS_FLCTRL} + +Enable serial flow control for UXRCE interface. + +This is used to enable flow control for the serial uXRCE instance. +Used for reliable high bandwidth communication. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | + ### UXRCE_DDS_KEY (`INT32`) {#UXRCE_DDS_KEY} uXRCE-DDS session key. @@ -39863,6 +41216,17 @@ must have a unique session key. | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | | | | 1 | +### UXRCE_DDS_NS_IDX (`INT32`) {#UXRCE_DDS_NS_IDX} + +Define an index-based message namespace. + +Defines an index-based namespace for DDS messages, e.g, uav_0, uav_1, up to uav_9999 +A value less than zero leaves the namespace empty + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | -1 | 9999 | | -1 | + ### UXRCE_DDS_PRT (`INT32`) {#UXRCE_DDS_PRT} uXRCE-DDS UDP port. @@ -39948,6 +41312,21 @@ Default rate is 250Kbps, which is used in off-the-shelf MoadalAI ESC products. | ------ | -------- | -------- | --------- | ------- | ----- | |   | | | | 250000 | bit/s | +### VOXL_ESC_CMD (`INT32`) {#VOXL_ESC_CMD} + +UART ESC command type. + +Selects between RPM or PWM commands + +**Values:** + +- `0`: - RPM +- `1`: - PWM + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | 0 | 1 | | 0 | + ### VOXL_ESC_CONFIG (`INT32`) {#VOXL_ESC_CONFIG} UART ESC configuration. @@ -40007,6 +41386,18 @@ Only applicable to ESCs that report total battery voltage and current | ------- | -------- | -------- | --------- | ------- | ---- | | ✓ | 0 | 1 | | 1 | +### VOXL_ESC_PWR_MIN (`FLOAT`) {#VOXL_ESC_PWR_MIN} + +UART ESC Minimum motor power. + +Minimum motor power for ESC when VOXL_ESC_CMD is set for PWM. +Make sure to set this high enough so that the motors are always spinning +while armed. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0.0 | 1.0 | | 0.05 | + ### VOXL_ESC_RPM_MAX (`INT32`) {#VOXL_ESC_RPM_MAX} UART ESC RPM Max. @@ -40256,7 +41647,7 @@ Time in seconds it takes to tilt form VT_TILT_FW to VT_TILT_MC. ### VT_B_DEC_I (`FLOAT`) {#VT_B_DEC_I} -Backtransition deceleration setpoint to pitch I gain. +Backtransition deceleration setpoint to tilt I gain. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ------- | @@ -40474,7 +41865,7 @@ During landing it can be beneficial to reduce the pitch angle to reduce the gene | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | -10.0 | 45.0 | 0.1 | -5.0 | deg | +|   | -10.0 | 45.0 | 0.1 | 0.0 | deg | ### VT_PITCH_MIN (`FLOAT`) {#VT_PITCH_MIN} @@ -40485,7 +41876,7 @@ VT_FWD_TRHUST_EN is set. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | -|   | -10.0 | 45.0 | 0.1 | -5.0 | deg | +|   | -10.0 | 45.0 | 0.1 | 0.0 | deg | ### VT_PSHER_SLEW (`FLOAT`) {#VT_PSHER_SLEW} @@ -40626,6 +42017,187 @@ Altitude relative to home at which vehicle will loiter after front transition. | ------ | -------- | -------- | --------- | ------- | ---- | |   | 20 | 300 | 1 | 80 | m | +## VTX + +### VTX_BAND (`INT32`) {#VTX_BAND} + +VTX band. + +VTX table band 1-24 + +**Values:** + +- `0`: Band 1 +- `1`: Band 2 +- `2`: Band 3 +- `3`: Band 4 +- `4`: Band 5 +- `5`: Band 6 +- `6`: Band 7 +- `7`: Band 8 +- `8`: Band 9 +- `9`: Band 10 +- `10`: Band 11 +- `11`: Band 12 +- `12`: Band 13 +- `13`: Band 14 +- `14`: Band 15 +- `15`: Band 16 +- `16`: Band 17 +- `17`: Band 18 +- `18`: Band 19 +- `19`: Band 20 +- `20`: Band 21 +- `21`: Band 22 +- `22`: Band 23 +- `23`: Band 24 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### VTX_CHANNEL (`INT32`) {#VTX_CHANNEL} + +VTX channel. + +VTX table channel 1-16 + +**Values:** + +- `0`: Channel 1 +- `1`: Channel 2 +- `2`: Channel 3 +- `3`: Channel 4 +- `4`: Channel 5 +- `5`: Channel 6 +- `6`: Channel 7 +- `7`: Channel 8 +- `8`: Channel 9 +- `9`: Channel 10 +- `10`: Channel 11 +- `11`: Channel 12 +- `12`: Channel 13 +- `13`: Channel 14 +- `14`: Channel 15 +- `15`: Channel 16 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### VTX_DEVICE (`INT32`) {#VTX_DEVICE} + +VTX device. + +Specific VTX device useful for workarounds and optimizations + +**Values:** + +- `0`: SmartAudio v1, v2, v2.1 Protocol +- `100`: Tramp Protocol +- `5120`: Peak THOR T67 +- `10240`: Rush MAX SOLO + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + +### VTX_FREQUENCY (`INT32`) {#VTX_FREQUENCY} + +VTX frequency in MHz. + +If the VTX frequency is set, it will overwrite the band and channel +settings. Set to 0 to use band and channel settings. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 32000 | | 0 | + +### VTX_MAP_CONFIG (`INT32`) {#VTX_MAP_CONFIG} + +VTX mapping configuration. + +Configure how VTX settings are controlled. Options include using +MSP commands, AUX channels or a combination of both. To use MSP +commands, you must use a CRSF receiver with MSP support enabled in +the PX4 build. + +**Values:** + +- `0`: Disabled +- `1`: MSP for Power, Band and Channel +- `2`: MSP for Band and Channel, AUX for Power +- `3`: MSP for Power, AUX for Band and Channel +- `4`: AUX for Power, Band and Channel + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### VTX_PIT_MODE (`INT32`) {#VTX_PIT_MODE} + +VTX pit mode. + +VTX pit mode reduces power to the minimum + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------------ | ---- | +|   | | | | Disabled (0) | + +### VTX_POWER (`INT32`) {#VTX_POWER} + +VTX power level. + +VTX transmission power level 1-16 + +**Values:** + +- `0`: Level 1 +- `1`: Level 2 +- `2`: Level 3 +- `3`: Level 4 +- `4`: Level 5 +- `5`: Level 6 +- `6`: Level 7 +- `7`: Level 8 +- `8`: Level 9 +- `9`: Level 10 +- `10`: Level 11 +- `11`: Level 12 +- `12`: Level 13 +- `13`: Level 14 +- `14`: Level 15 +- `15`: Level 16 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | | | | 0 | + +### VTX_SER_CFG (`INT32`) {#VTX_SER_CFG} + +Serial Configuration for VTX Serial Port. + +Configure on which serial port to run VTX Serial Port. + +**Values:** + +- `0`: Disabled +- `6`: UART 6 +- `101`: TELEM 1 +- `102`: TELEM 2 +- `103`: TELEM 3 +- `104`: TELEM/SERIAL 4 +- `201`: GPS 1 +- `202`: GPS 2 +- `203`: GPS 3 +- `300`: Radio Controller +- `301`: Wifi Port +- `401`: EXT2 + +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------- | ---- | +| ✓ | | | | 0 | + ## Vertiq IO ### VERTIQ_IO_CFG (`INT32`) {#VERTIQ_IO_CFG} @@ -40992,13 +42564,15 @@ The encoder angle at which theta is zero. Adjust this number to change the locat ### ZENOH_ENABLE (`INT32`) {#ZENOH_ENABLE} -Zenoh Enable. +Enable Zenoh. -Zenoh +Set true (1) to start the Zenoh driver module (a.k.a the "Zenoh-Pico Node"). +See https://docs.px4.io/main/en/middleware/zenoh and +https://docs.px4.io/main/en/modules/modules_driver.html#zenoh -| Reboot | minValue | maxValue | increment | default | unit | -| ------- | -------- | -------- | --------- | ------- | ---- | -| ✓ | | | | 0 | +| Reboot | minValue | maxValue | increment | default | unit | +| ------- | -------- | -------- | --------- | ------------ | ---- | +| ✓ | | | | Disabled (0) | ## Miscellaneous @@ -41056,7 +42630,7 @@ Gyro filter settings. ### SF1XX_MODE (`INT32`) {#SF1XX_MODE} -Lightware SF1xx/SF20/LW20 Operation Mode. +Lightware laser rangefinder Operation Mode. **Values:** @@ -41075,3 +42649,11 @@ SPC_VEHICLE_RESP. | Reboot | minValue | maxValue | increment | default | unit | | ------ | -------- | -------- | --------- | ------- | ---- | |   | | | | 0.5 | + +### ZENOH_DOMAIN_ID (`INT32`) {#ZENOH_DOMAIN_ID} + +ROS2 RMW_ZENOH_CPP Domain id. + +| Reboot | minValue | maxValue | increment | default | unit | +| ------ | -------- | -------- | --------- | ------- | ---- | +|   | 0 | 232 | | 0 | diff --git a/docs/en/advanced_config/prearm_arm_disarm.md b/docs/en/advanced_config/prearm_arm_disarm.md index e9e01f180f..ec4ce4c7e2 100644 --- a/docs/en/advanced_config/prearm_arm_disarm.md +++ b/docs/en/advanced_config/prearm_arm_disarm.md @@ -52,19 +52,17 @@ RC controllers will use different sticks for throttle and yaw [based on their mo - _Arm:_ Left-stick to right, right-stick to bottom. - _Disarm:_ Left-stick to left, right-stick to the bottom. -The required hold time can be configured using [COM_RC_ARM_HYST](#COM_RC_ARM_HYST). Note that by default ([COM_DISARM_MAN](#COM_DISARM_MAN)) you can also disarm in flight using gestures/buttons: you may choose to disable this to avoid accidental disarming. | Parameter | Description | | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | | [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | -| [COM_RC_ARM_HYST](../advanced_config/parameter_reference.md#COM_RC_ARM_HYST) | Time that RC stick must be held in arm/disarm position before arming/disarming occurs (default: `1` second). | ## Arming Button/Switch {#arm_disarm_switch} An _arming button_ or "momentary switch" can be configured to trigger arm/disarm _instead_ of [gesture-based arming](#arm_disarm_gestures) (setting an arming switch disables arming gestures). -The button should be held down for ([nominally](#COM_RC_ARM_HYST)) one second to arm (when disarmed) or disarm (when armed). +The button should be held down for one second to arm (when disarmed) or disarm (when armed). A two-position switch can also be used for arming/disarming, where the respective arm/disarm commands are sent on switch _transitions_. @@ -77,7 +75,7 @@ The switch or button is assigned (and enabled) using [RC_MAP_ARM_SW](#RC_MAP_ARM | Parameter | Description | | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [RC_MAP_ARM_SW](../advanced_config/parameter_reference.md#RC_MAP_ARM_SW) | RC arm switch channel (default: 0 - unassigned). If defined, the specified RC channel (button/switch) is used for arming instead of a stick gesture.
**Note:**
- This setting _disables the stick gesture_!
- This setting applies to RC controllers. It does not apply to Joystick controllers that are connected via _QGroundControl_. | -| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Arm switch is a momentary button.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a button or momentary button where the arm/disarm command ae sent after holding down button for set time ([COM_RC_ARM_HYST](#COM_RC_ARM_HYST)). | +| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Arm switch is a momentary button.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a momentary button where the arm/disarm command is sent after holding down the button for one second. | ::: info The switch can also be set as part of _QGroundControl_ [Flight Mode](../config/flight_mode.md) configuration. diff --git a/docs/en/advanced_config/tuning_the_ecl_ekf.md b/docs/en/advanced_config/tuning_the_ecl_ekf.md index 8a68bc05dc..d2c0ada7fb 100644 --- a/docs/en/advanced_config/tuning_the_ecl_ekf.md +++ b/docs/en/advanced_config/tuning_the_ecl_ekf.md @@ -348,6 +348,60 @@ The `hpos_drift_rate`, `vpos_drift_rate` and `hspd` are calculated over a period Note that `ekf2_gps_drift` is not logged! ::: +#### GNSS Fault Detection + +PX4's GNSS fault detection protects against malicious or erroneous GNSS signals using selective fusion control based on measurement validation. + +The fault detection logic depends on the GPS mode, and also operates differently for horizontal position and altitude measurements. +The mode is set using the [EKF2_GPS_MODE](../advanced_config/parameter_reference.md#EKF2_GPS_MODE) parameter: + +- **Automatic (`0`)** (Default): Assumes that GNSS is generally reliable and is likely to be recovered. + EKF2 resets on fusion timeouts if no other source of position is available. +- **Dead-reckoning (`1`)**: Assumes that GNSS might be lost indefinitely, so resets should be avoided while we have other estimates of position data. + EKF2 may reset if no other sources of position or velocity are available. + If GNSS altitude OR horizontal position data drifts, the system disables fusion of both measurements simultaneously (even if one would still pass validation) and avoids performing resets. + +##### Detection Logic + +Horizontal Position: + +- **Automatic mode**: Horizontal position resets to GNSS data if no other horizontal position source is currently being fused (e.g., Auxiliary Global Position - AGP). +- **Dead-reckoning mode**: Horizontal position resets to GNSS data only if no other horizontal position OR velocity source is currently being fused (e.g., AGP, airspeed, optical flow). + +Altitude: + +- The altitude logic is more complex due to the height reference sensor ([EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)) parameter, which is typically set to GNSS or baro in GNSS-denied scenarios. +- If height reference is set to baro, GNSS-based height resets are prevented (except when baro fusion fails completely and height reference automatically switches to GNSS). +- When height reference is set to GNSS: +- **Automatic mode**: Resets occur on drifting GNSS altitude measurements. +- **Dead-reckoning mode**: When validation starts failing, the system prevents GNSS altitude resets and labels the GNSS data as faulty. + +##### Faulty GNSS Data During Boot + +The system cannot automatically detect faulty GNSS data during vehicle boot as no baseline comparison exists. + +If GNSS fusion is enabled ([EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL)), operators will observe incorrect positions on maps and should disable GNSS fusion, then manually set the correct position via ground control station. +The global position gets corrected, and if [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) was enabled, baro offsets are automatically adjusted (through bias correction, not parameter changes). + +##### Enabling GNSS Fusion Mid-Flight + +With Faulty GNSS Data: + +- **Automatic mode**: Vehicle will reset to faulty position - potentially dangerous. +- **Dead-reckoning mode**: Large measurement differences cause GNSS rejection and fault detection activation. + +With Valid GNSS Data: + +- **Automatic mode**: Vehicle will reset to GNSS measurements. +- **Dead-reckoning mode**: If estimated position/altitude is close enough to measurements, fusion resumes; if too far apart, data gets labeled as faulty. + +##### Notes + +- **Dual Detection**: Horizontal and altitude checks run completely separately but both lead to the same result when triggered - all GNSS fusion gets disabled. +- **Recovery**: Only the specific check that labeled data as invalid can re-enable fusion. +- **Alternative Sources**: Dead-reckoning mode provides enhanced protection by requiring absence of alternative navigation sources before allowing resets. +- **Boot Vulnerability**: Initial faulty GNSS data cannot be detected automatically; requires operator intervention and manual position correction. + ### Range Finder [Range finder](../sensor/rangefinders.md) distance to ground is used by a single state filter to estimate the vertical position of the terrain relative to the height datum. diff --git a/docs/en/airframes/airframe_reference.md b/docs/en/airframes/airframe_reference.md index 4ede6221a5..2067c8f6a5 100644 --- a/docs/en/airframes/airframe_reference.md +++ b/docs/en/airframes/airframe_reference.md @@ -615,6 +615,10 @@ div.frame_variant td, div.frame_variant th { Axial SCX10 2 Trail Honcho Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 51001

+ + NXP B3RB Rover Ackermann + Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 51002

+ Generic Rover Mecanum Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 52000

@@ -628,7 +632,16 @@ div.frame_variant td, div.frame_variant th { ### Free-Flyer
- + + + + + + + + + +
Common Outputs
  • Motor1: back left thruster, +x thrust
  • Motor2: front left thruster, -x thrust
  • Motor3: back right thruster, +x thrust
  • Motor4: front right thruster, -x thrust
  • Motor5: front left thruster, +y thrust
  • Motor6: front right thruster, -y thrust
  • Motor7: back left thruster, +y thrust
  • Motor8: back right thruster, -y thrust
@@ -638,7 +651,7 @@ div.frame_variant td, div.frame_variant th { - KTH-ATMOS + KTH-ATMOS Maintainer: DISCOWER

SYS_AUTOSTART = 70000

diff --git a/docs/en/assembly/_assembly.md b/docs/en/assembly/_assembly.md index ef641c6a70..b5082bedd1 100644 --- a/docs/en/assembly/_assembly.md +++ b/docs/en/assembly/_assembly.md @@ -284,13 +284,13 @@ A particular vehicle might have more/fewer motors and actuators, but the wiring The following sections explain each part in more detail. ::: tip -If you're using [DroneCAN ESC](../peripherals/esc_motors.md#dronecan) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. +If you're using [DroneCAN ESC](../dronecan/escs.md) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. ::: ### Flight Controller Power Pixhawk FCs require a regulated power supply that can supply at around 5V/3A continuous (check your specific FC)! -This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC transmitter, and low power telemetry radio, but not for motors, actuators, and other peripherals. +This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC receiver, and low power telemetry radio, but not for motors, actuators, and other peripherals. [Power modules](../power_module/index.md) are commonly used to "split off" this regulated power supply for the FC and also to provide measurements of the battery voltage and total current to the whole system — which PX4 can use to estimate power levels. The power module is connected to the FC power port, which is normally labeled `POWER` (or `POWER 1` or `POWER 2` for FCs that have redundant power supply). @@ -425,7 +425,6 @@ They recommend sensors, power systems, and other components from the same manufa - [Drone Components & Parts](../getting_started/px4_basic_concepts.md#drone-components-parts) (Basic Concepts) - [Payloads](../getting_started/px4_basic_concepts.md#payloads) (Basic Concepts) - [Hardware Selection & Setup](../hardware/drone_parts.md) — information about connecting and configuring specific flight controllers, sensors and other peripherals (e.g. airspeed sensor for planes). - - [Mounting the Flight Controller](../assembly/mount_and_orient_controller.md) - [Vibration Isolation](../assembly/vibration_isolation.md) - [Mounting a Compass](../assembly/mount_gps_compass.md) diff --git a/docs/en/can/index.md b/docs/en/can/index.md index 7335c5b7a8..cf33b7a8c4 100644 --- a/docs/en/can/index.md +++ b/docs/en/can/index.md @@ -1,9 +1,19 @@ -# CAN +# CAN (DroneCAN & Cyphal) [Controller Area Network (CAN)](https://en.wikipedia.org/wiki/CAN_bus) is a robust wired network that allows drone components such as flight controller, ESCs, sensors, and other peripherals, to communicate with each other. -Because it is designed to be democratic and uses differential signaling, it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. + +It is particularly recommended on larger vehicles. + +## Overview + +CAN it is designed to be democratic and uses differential signaling. +For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN also allows status feedback from peripherals and convenient firmware upgrades over the bus. +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 supports two software protocols for communicating with CAN devices: - [DroneCAN](../dronecan/index.md): PX4 recommends this for most common setups. @@ -18,29 +28,35 @@ In 2022 the project split into two: the original version of UAVCAN (UAVCAN v0) w The differences between the two protocols are outlined in [Cyphal vs. DroneCAN](https://forum.opencyphal.org/t/cyphal-vs-dronecan/1814). ::: -:::warning PX4 does not support other CAN software protocols for drones such as KDECAN (at time of writing). -::: ## Wiring The wiring for CAN networks is the same for both DroneCAN and Cyphal/CAN (in fact, for all CAN networks). -Devices are connected in a chain in any order. +Devices within a network are connected in a _daisy-chain_ in any order (this differs from UARTs peripherals, where you attach just one component per port). + +:::warning Don't connect each CAN peripheral to a separate CAN port! +Unlike UARTs, CAN peripherals are designed to be daisy chained, with additional ports such as `CAN2` used for [redundancy](redundancy). +::: + At either end of the chain, a 120Ω termination resistor should be connected between the two data lines. Flight controllers and some GNSS modules have built in termination resistors for convenience, thus should be placed at opposite ends of the chain. Otherwise, you can use a termination resistor such as [this one from Zubax Robotics](https://shop.zubax.com/products/uavcan-micro-termination-plug?variant=6007985111069), or solder one yourself if you have access to a JST-GH crimper. The following diagram shows an example of a CAN bus connecting a flight controller to 4 CAN ESCs and a GNSS. +It includes a redundant bus connected to `CAN 2`. ![CAN Wiring](../../assets/can/uavcan_wiring.svg) The diagram does not show any power wiring. Refer to your manufacturer instructions to confirm whether components require separate power or can be powered from the CAN bus itself. +::: info For more information, see [Cyphal/CAN device interconnection](https://wiki.zubax.com/public/cyphal/CyphalCAN-device-interconnection?pageId=2195476) (kb.zubax.com). While the article is written with the Cyphal protocol in mind, it applies equally to DroneCAN hardware and any other CAN setup. For more advanced scenarios, consult with [On CAN bus topology and termination](https://forum.opencyphal.org/t/on-can-bus-topology-and-termination/1685). +::: ### Connectors @@ -54,7 +70,30 @@ However, as long as the device firmware supports DroneCAN or Cyphal, it can be u DroneCAN and Cyphal/CAN support using a second (redundant) CAN interface. This is completely optional but increases the robustness of the connection. -All Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +### Flight Controllers with Multiple CAN Ports + +[Flight Controllers](../flight_controller/index.md) may have up to three independent CAN ports, such as `CAN1`, `CAN2`, `CAN3` (neither DroneCAN or Cyphal support more than three). +Note that you can't have both DroneCAN and Cyphal running on PX4 at the same time. + +::: tip +You only _need_ one CAN port to support an arbitrary number of CAN devices using a particular CAN protocol. +Don't connect each CAN peripheral to a separate CAN port! +::: + +Generally you'll daisy all CAN peripherals off a single port, and if there is more than one CAN port, use the second one for [redundancy](redundancy). +If three are three ports, you might use the remaining network for devices that support another CAN protocol. + +The documentation for your flight controller should indicate which ports are supported/enabled. +At runtime you can check what DroneCAN ports are enabled and their status using the following command on the [MAVLink Shell](../debug/mavlink_shell.md) (or some other console): + +```sh +uavcan status +``` + +Note that you can also check the number of supported CAN interfaces for a board by searching for `CONFIG_BOARD_UAVCAN_INTERFACES` in its [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#) configuration file. ## Firmware diff --git a/docs/en/companion_computer/ark_jetson_pab_carrier.md b/docs/en/companion_computer/ark_jetson_pab_carrier.md index ffb7931a7b..33463f5ca0 100644 --- a/docs/en/companion_computer/ark_jetson_pab_carrier.md +++ b/docs/en/companion_computer/ark_jetson_pab_carrier.md @@ -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 diff --git a/docs/en/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md b/docs/en/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md index 3cdab57030..565b68eebb 100644 --- a/docs/en/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md +++ b/docs/en/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md @@ -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: ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) 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` diff --git a/docs/en/companion_computer/pixhawk_rpi.md b/docs/en/companion_computer/pixhawk_rpi.md index 218a48c3a2..b998f897a1 100644 --- a/docs/en/companion_computer/pixhawk_rpi.md +++ b/docs/en/companion_computer/pixhawk_rpi.md @@ -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. diff --git a/docs/en/complete_vehicles_mc/modalai_starling.md b/docs/en/complete_vehicles_mc/modalai_starling.md index 766f353761..b2fb8ef588 100644 --- a/docs/en/complete_vehicles_mc/modalai_starling.md +++ b/docs/en/complete_vehicles_mc/modalai_starling.md @@ -1,126 +1,39 @@ -# ModalAI Starling (PX4 Autonomy Developer Kit) +# ModalAI Starling 2 -The [Starlings](https://www.modalai.com/pages/starlings) are SLAM development drones supercharged by [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -Powered by Blue UAS Framework autopilot, VOXL 2, the Starling weighs only 275g and boasts an impressive 30 minutes of autonomous indoor flight time. +The [Starlings](https://www.modalai.com/pages/starlings) are NDAA-compliant SLAM development drones based on the [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -![Overview](../../assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg) +## Overview -The ModalAI PX4 Autonomy Developer Kit is a Starling-based development drone. -It houses a [VOXL 2](../flight_controller/modalai_voxl_2.md), which is a powerful companion computer and PX4 flight controller in one small package, image sensors, GPS, and connectivity modem, and is ready-to-fly out-of-the-box. -The Starling features ModalAI's [open SDK](https://docs.modalai.com/voxl-developer-bootcamp/) that has pre-configured autonomy models for computer vision assisted flight. -This development drone is meant to help you get to market faster and accelerate your application development and prototyping. +Starling drones house _VOXL 2_, which is a powerful companion computer, a PX4 flight controller, image sensors, GPS, and connectivity modem, in one small package. +The Starlings feature ModalAI's open source [VOXL SDK](https://gitlab.com/voxl-public/voxl-sdk) that has pre-configured autonomy models for computer vision assisted flight. -This guide explains the minimal additional setup required to get the UAV ready to fly. -It also covers a hardware overview, first flight, setting up WiFi, and more. - -::: info -For complete and regularly updated documentation, please visit . -::: +These development drones are ready-to-fly out-of-the-box. +They are designed to help you get to market faster and accelerate your application development and prototyping. ::: info If you are new to VOXL, be sure to familiarize yourself with the core features of VOXL hardware and software by reviewing the [VOXL Bootcamp](https://docs.modalai.com/voxl-developer-bootcamp/). ::: +::: info +For complete and regularly updated documentation, please visit and . +::: + +## Starling 2 + +The [Starling 2](https://www.modalai.com/products/starling-2) is an NDAA-compliant development drone supercharged by the VOXL SDK and equipped with a new image sensor suite for precise, indoor visual navigation and SLAM. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 weighs 280g and boasts an impressive 40 minutes of autonomous flight time. + +![Image of the front of Starling 2](../../assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png) + +## Starling 2 Max + +The [Starling 2 Max](https://www.modalai.com/products/starling-2-max) is VOXL 2-powered, NDAA-compliant development drone supercharged by VOXL SDK specifically designed for computer vision-based, long-range dead reckoning with a 500g payload capacity. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 Max weighs 500g and boasts an impressive 55 minutes of autonomous flight time. + +![Image of front of a Starling 2 Max](../../assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png) + ## Where to Buy -[ModalAI PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit?variant=46969885950256) +[ModalAI Starling 2](https://www.modalai.com/products/starling-2) -## Hardware Overview - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg) - -| Callout | Description | MPN | -| ------- | ------------------------------------- | ---------------- | -| A | VOXL 2 | MDK-M0054-1 | -| B | VOXL 4-in-1 ESC | MDK-M0117-1 | -| C | Barometer Shield Cap | M10000533 | -| D | ToF Image Sensor (PMD) | MDK-M0040 | -| E | Tracking Image Sensor (OV7251) | M0014 | -| F | Hires Image Sensor (IMX214) | M0025-2 | -| G | AC600 WiFi Dongle | AWUS036EACS | -| H | GNSS GPS Module & Compass | M10-5883 | -| I | 915MHz ELRS Receiver | BetaFPV Nano RX | -| J | USB C Connector on VOXL 2 (not shown) | | -| K | VOXL Power Module | MCCA-M0041-5-B-T | -| L | 4726FM Propellor | M10000302 | -| M | Motor 1504 | | -| N | XT30 Power Connector | | - -## Datasheet - -### Specifications - -| Component | Specification | -| --------------- | ----------------------------------------------------------------- | -| Autopilot | VOXL2 | -| Take-off Weight | 275g (172g without battery) | -| Diagonal Size | 211mm | -| Flight Time | >30 minutes | -| Motors | 1504 | -| Propellers | 120mm | -| Frame | 3mm Carbon Fiber | -| ESC | ModalAI VOXL 4-in-1 ESC V2 | -| GPS | UBlox M10 | -| RC Receiver | 915mhz ELRS | -| Power Module | ModalAI Power Module v3 - 5V/6A | -| Battery | Sony VTC6 3000mah 2S, or any 2S 18650 battery with XT30 connector | -| Height | 83mm | -| Width | 187mm (Props folded) | -| Length | 142mm (Props folded) | - -### Hardware Wiring Diagram - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg) - -## Tutorials - -### ELRS Set Up - -Binding your ELRS (ExpressLRS) receiver to a transmitter is a crucial step in preparing your VOXL 2 based PX4 Autonomy Developer Kit by ModalAI for flight. -This process ensures a secure and responsive connection between your drone and its control system. - -Follow this guide to bind your ELRS receiver to your transmitter. - -#### Setting up the Receiver - -1. **Power On the Receiver**: Once your drone is powered on, you'll notice the ELRS receiver's blue LED flashing. - This is an indication that the receiver is on but has not yet established a connection with a transmitter. - - ![Starling Receiver](../../assets/hardware/complete_vehicles/modalai_starling/starling-photo.png) - -2. **Enter Binding Mode**: To initiate binding, open a terminal and execute the `adb shell` and `voxl-elrs -bind` commands. - You'll observe the receiver's LED switch to a flashing in a heartbeat pattern, signaling that it is now in binding mode. - - ![Boot Screenshot](../../assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png) - -#### Setting up the Transmitter - -1. **Access the Menu**: On your Commando 8 radio transmitter included in the kit, press the left mode button to open the menu system. - - ![Press Menu on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-1.png) - -2. **Navigate to ExpressLRS**: Use the right button to select the first menu entry, which should be "ExpressLRS." -3. **Find the Bind Option**: With the "ExpressLRS" option selected, scroll down to the bottom of the menu to locate the "Bind" section. This can be done by pressing the right button downwards until you reach the "Bind" option. - - ![Press Binding on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-2.png) - -4. **Initiate Binding**: Select "Bind" to put the transmitter into binding mode. You will know the process has been successful when the transmitter emits a beep, indicating a successful bind. - -#### Completing the Binding Process - -Once the transmitter is set to bind mode, the ELRS receiver on the drone will change its LED from flashing to a steady light, signifying a successful connection between the receiver and the transmitter. - -- **Power Cycle**: After the binding process is complete, it's essential to power cycle the VOXL 2 before attempting to fly. - This means turning off the VOXL 2 and then turning it back on. - This step ensures that all settings are properly applied and that the system recognizes the newly established connection. - -You should now have a successfully bound ELRS receiver to your transmitter, ready for use with the PX4 Autonomy Kit by ModalAI. -A secure connection is vital for the reliable operation of your drone, so always confirm the binding status before flight. - -### Videos - -- [VOXL 2 Starling Hardware Overview](https://youtu.be/M9OiMpbEYOg) -- [VOXL 2 Starling First Flight Tutorial](https://youtu.be/Cpbbye3Z6co) -- [VOXL 2 Starling ELRS Set Up](https://youtu.be/7OwGS-kcFVg) +[ModalAI Starling 2 Max](https://www.modalai.com/products/starling-2-max) diff --git a/docs/en/computer_vision/collision_prevention.md b/docs/en/computer_vision/collision_prevention.md index d2ebb4597a..1fad93be3d 100644 --- a/docs/en/computer_vision/collision_prevention.md +++ b/docs/en/computer_vision/collision_prevention.md @@ -60,7 +60,7 @@ Configure collision prevention by [setting the following parameters](../advanced | [CP_DELAY](../advanced_config/parameter_reference.md#CP_DELAY) | Set the sensor and velocity setpoint tracking delay. See [Delay Tuning](#delay_tuning) below. | | [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. | | [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`). | -| [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Must be set to `Acceleration based`. | +| [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 diff --git a/docs/en/concept/flight_tasks.md b/docs/en/concept/flight_tasks.md index fad2dca6fe..242a1e96fe 100644 --- a/docs/en/concept/flight_tasks.md +++ b/docs/en/concept/flight_tasks.md @@ -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 diff --git a/docs/en/concept/sd_card_layout.md b/docs/en/concept/sd_card_layout.md index 648614e1ea..e379dee52a 100644 --- a/docs/en/concept/sd_card_layout.md +++ b/docs/en/concept/sd_card_layout.md @@ -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 | diff --git a/docs/en/concept/system_startup.md b/docs/en/concept/system_startup.md index 76bf291956..d425d35173 100644 --- a/docs/en/concept/system_startup.md +++ b/docs/en/concept/system_startup.md @@ -1,7 +1,7 @@ # System Startup The PX4 startup is controlled by shell scripts. -On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/MacOS). +On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/macOS). The scripts that are only used on Posix are located in [ROMFS/px4fmu_common/init.d-posix](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d-posix). All files starting with a number and underscore (e.g. `10000_airplane`) are predefined airframe configurations. @@ -13,9 +13,9 @@ The first executed file is the [init.d/rcS](https://github.com/PX4/PX4-Autopilot The following sections are split according to the operating system that PX4 runs on. -## Posix (Linux/MacOS) +## POSIX (Linux/macOS) -On Posix, the system shell is used as script interpreter (e.g. /bin/sh, being symlinked to dash on Ubuntu). +On POSIX, the system shell is used as script interpreter (e.g. /bin/sh, being symlinked to dash on Ubuntu). For that to work, a few things are required: - PX4 modules need to look like individual executables to the system. @@ -54,7 +54,7 @@ cd /build/px4_sitl_default/bin ### Dynamic Modules Normally, all modules are compiled into a single PX4 executable. -However, on Posix, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. +However, on POSIX, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. ```sh dyn ./test.px4mod @@ -90,7 +90,7 @@ This is documented below. The best way to customize the system startup is to introduce a [new frame configuration](../dev_airframes/adding_a_new_frame.md). The frame configuration file can be included in the firmware or on an SD Card. -#### Dynamic customization +#### Dynamic Customization If you only need to "tweak" the existing configuration, such as starting one more application or setting the value of a few parameters, you can specify these by creating two files in the `/etc/` directory of the SD Card: @@ -148,27 +148,36 @@ The following example shows how to start custom applications: mandatory_app start # Will abort boot if mandatory_app is unknown or fails ``` -#### Additional customization +#### Additional Init-File Customization -In rare cases where the desired setup cannot be achieved through frame configuration or dynamic customization, -you can add a script that will be contained in the binary. +In rare cases where the desired setup cannot be achieved through frame configuration or dynamic customization, you can add a script that will be compiled into the binary for a particular `make` target build variant. -**Note**: In almost all cases, you should use a frame configuration. This method should only be used for -edge-cases such as customizing `cannode` based boards. +::: warning +In almost all cases, you should use a frame configuration. +This method should only be used for edge-cases such as customizing `cannode` based boards. +::: + +The steps are: + +- Add a new init script in `boards///init` that will run during board startup. + For example: -- Add a new init script in `boards///init` that will run during board startup. For example: ```sh # File: boards///init/rc.additional param set-default ``` -- Add a new board variant in `boards///.px4board` that includes the additional script. For example: +- Add a new board variant in `boards///.px4board` that includes the additional script. + For example: + ```sh # File: boards///var.px4board CONFIG_BOARD_ADDITIONAL_INIT="rc.additional" ``` -- Compile the firmware with your new variant by appending the variant name to the compile target. For example: +- Compile the firmware with your new variant by appending the variant name to the compile target. + For example: + ```sh make _var ``` diff --git a/docs/en/config/_autotune.md b/docs/en/config/_autotune.md index 0a87201c7a..fe5373b169 100644 --- a/docs/en/config/_autotune.md +++ b/docs/en/config/_autotune.md @@ -82,18 +82,20 @@ 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.
- 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: - ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) + ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) 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. +
4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. The progress is shown in the progress bar, next to the _Autotune_ button. +
+ +4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. When [`FW_AT_SYSID_TYPE`](../advanced_config/parameter_reference.md#FW_AT_SYSID_TYPE) is set to linear/logarithmic sine sweep (recommended), the max rates reached during the maneuvers are 75% of the maximum configured roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. The progress is shown in the progress bar, next to the _Autotune_ button. + +
5. Manually land and disarm to apply the new tuning parameters. @@ -104,6 +106,13 @@ The test steps are: 5. The tuning will be immediately/automatically be applied and tested in flight (by default). PX4 will then run a 4 second test and revert the new tuning if a problem is detected. +The figure below shows how steps 4 and 5 might look in flight on the pitch axis. +The pitch rate gradually increases up until it reaches the target. +This amplitude is then held while the signal frequency is increased. +You can then see how the tuned system is able to follow the setpoint in the test signal. + + +
::: warning @@ -170,9 +179,20 @@ Fast oscillations (more than 1 oscillation per second): this is because the gain ### The auto-tuning sequence fails +
+ If the drone was not moving enough during auto-tuning, the system identification algorithm might have issues to find the correct coefficients. -Increase the
[MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP)
[FW_AT_SYSID_AMP](../advanced_config/parameter_reference.md#FW_AT_SYSID_AMP)
parameter by steps of 1 and trigger the auto-tune again. +Increase the [MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP) parameter by steps of 1 and trigger the auto-tune again. + +
+
+ +By default, the autotune maneuvers ensure that a sufficient angular rate is reached for system identification, corresponding to 75% of the configured maximum roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. + +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. + +
### The drone oscillates after auto-tuning diff --git a/docs/en/config/actuators.md b/docs/en/config/actuators.md index 3eec8f2dd2..e15e5d1608 100644 --- a/docs/en/config/actuators.md +++ b/docs/en/config/actuators.md @@ -160,6 +160,7 @@ The fields are: [Generally you should use the default actuator value](#actuator-roll-pitch-and-yaw-scaling). - `Trim`: An offset added to the actuator so that it is centered without input. This might be determined by trial and error. + Prefer using the improved `PWM_CENT` instead: [PWM control surfaces](actuators.md#pwm-control-surfaces-that-move-both-directions-about-a-neutral-point). - (Advanced) `Slew Rate`: Limits the minimum time in which the motor/servo signal is allowed to pass through its full output range, in seconds. - The setting limits the rate of change of an actuator (if not specified then no rate limit is applied). It is intended for actuators that may be damaged or cause flight disturbance if they move too fast — such as the tilting actuators on a tiltrotor VTOL vehicle, or fast moving flaps, respectively. @@ -535,12 +536,41 @@ If you're using PWM servos, PWM50 is far more common. If a high rate servo is _really_ needed, DShot offers better value. ::: -#### Control surfaces that move both directions about a neutral point +##### PWM: Control surfaces that move both directions about a neutral point + +To facilitate setting the neutral point of the servos, a bilinear curve function can be defined using the following parameters `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` for each servo. This allows for unequal deflections in the positive and negative direction: + +![Asymmetric Servo Deflections](../../assets/config/actuators/servo_pwm_center.png) + +To set this up: + +1. Set all surface `Trim` to `0.00` for all surfaces: + + ![PWM Trimming](../../assets/config/actuators/control_surface_trim.png) + +2. Set the `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` value so that the surface will stay at the neutral (aligned with airfoil) position. + This is usually around `1500` for PWM servos (near the center of the servo range). + + ![Control Surface Trimming](../../assets/config/actuators/pwm_center_output.png) + +3. Gradually increase the `Maximum` for each servo until the desired deflection is reached. Check the deflection with a remote manual mode while [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) is set to `Always` or use the sliders. +4. Gradually decrease the `Minimum` for each servo, until the desired deflection is reached. +5. Set `Disarmed` value to the desired value. It is usually desirable to have it the same as the `Center` value. + +::: info +If you want to retain the linear behaviour of the servo after setting the `Center`, make sure to adjust the `Minimum` or `Maximum`, such that both intervals (`min` to `cent` & `cent` to `max`) are equally large. + +![Linear PWM Adjustment](../../assets/config/actuators/servo_pwm_linear.png) +::: + +#### Non-PWM: Control surfaces that move both directions about a neutral point Control surfaces that move either direction around a neutral point include: ailerons, elevons, V-tails, A-tails, and rudders. To set these up: +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. + 1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. This is usually around `1500` for PWM servos (near the centre of the servo range). @@ -559,14 +589,17 @@ To set these up: 3. Move the slider again to the middle and check if the Control Surfaces are aligned in the neutral position of the wing. - If it is not aligned, you can set the **Trim** value for the control surface. - ::: info - This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". - ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) - ::: - + ::: info + This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". + ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) + ::: - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. Confirm that surface is in the neutral position. +::: tip +If any servo has a `PWM_MAIN_CENTx` or `PWM_AUX_CENTx` not set to default (-1), the system will automatically remove `Trim` from all surfaces. This is done to prevent mixing of old and new trimming tools. +::: + ::: info Another way to test without using the sliders would be to set the [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) parameter to `Always`: @@ -585,6 +618,7 @@ For a flap, that is when the flap is fully retracted and flush with the wing. One approach for setting these up is: +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. 1. Set values `Disarmed` to `1500`, `Min` to `1200`, `Max` to `1700` so that the values are around the centre of the servo range. 2. Move the corresponding slider up and check the control moves and that it is extending (moving away from the disarmed position). If not, click on the `Rev Range` checkbox to reverse the range. @@ -594,6 +628,7 @@ One approach for setting these up is: - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. 4. The value that you did _not_ set to match `Disarmed` controls the maximum amount that the control surface can extend. Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. +5. (Only PWM servos) Set the `Center` value to the middle between `Min` and `Max`. ::: info Special note for flaps In some vehicle builds, flaps may be configured such that both flaps are controlled from a single output. @@ -631,6 +666,11 @@ For each of the tilt servos: - Standard VTOL : Motors defined as multicopter motors will be turned off - Tiltrotors : Motors that have no associated tilt servo will turn off - Tailsitters do not turn off any motors in fixed-wing flight +- The following formula can be used to migrate from surface trim to PWM trim: + + ```plain + PWM_MAIN_CENTx = ((PWM_MAX - PWM_MIN) / 2) * CA_SV_CSx_TRIM + PWM_MIN + ((PWM_MAX - PWM_MIN) / 2) + ``` ### Reversing Motors diff --git a/docs/en/config/compass.md b/docs/en/config/compass.md index d3b0df3864..0ad2622cbb 100644 --- a/docs/en/config/compass.md +++ b/docs/en/config/compass.md @@ -10,7 +10,7 @@ If you have [mounted the compass](../assembly/mount_gps_compass.md#compass-orien ## Overview -You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to recalibrate it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. +You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to [recalibrate](#recalibration) it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. :::tip Indications of a poor compass calibration include multicopter circling during hover, toilet bowling (circling at increasing radius/spiraling-out, usually constant altitude, leading to fly-way), or veering off-path when attempting to fly straight. @@ -20,13 +20,16 @@ _QGroundControl_ should also notify the error `mag sensors inconsistent`. The process calibrates all compasses and autodetects the orientation of any external compasses. If any external magnetometers are available, it then disables the internal magnetometers (these are primarily needed for automatic rotation detection of external magnetometers). +### Types of Calibration + Several types of compass calibration are available: 1. [Complete](#complete-calibration): This calibration is required after installing the autopilot on an airframe for the first time or when the configuration of the vehicle has changed significantly. It compensates for hard and soft iron effects by estimating an offset and a scale factor for each axis. 1. [Partial](#partial-quick-calibration): This calibration can be performed as a routine when preparing the vehicle for a flight, after changing the payload, or simply when the compass rose seems inaccurate. This type of calibration only estimates the offsets to compensate for a hard iron effect. -1. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. This type of calibration only estimates the offsets to compensate for a hard iron effect. +1. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. + This type of calibration only estimates the offsets to compensate for a hard iron effect. ## Performing the Calibration @@ -48,23 +51,27 @@ Before starting the calibration: The calibration steps are: 1. Start _QGroundControl_ and connect the vehicle. -1. Select **"Q" icon > Vehicle Setup > Sensors** (sidebar) to open _Sensor Setup_. -1. Click the **Compass** sensor button. +2. Select **"Q" icon > Vehicle Setup > Sensors** (sidebar) to open _Sensor Setup_. +3. Click the **Compass** sensor button. ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) ::: info - You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). If not, you can also set it here. + You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). + If not, you can also set it here. ::: -1. Click **OK** to start the calibration. -1. Place the vehicle in any of the orientations shown in red (incomplete) and hold it still. Once prompted (the orientation-image turns yellow) rotate the vehicle around the specified axis in either/both directions. Once the calibration is complete for the current orientation the associated image on the screen will turn green. +4. Click **OK** to start the calibration. +5. Place the vehicle in any of the orientations shown in red (incomplete) and hold it still. + Once prompted (the orientation-image turns yellow) rotate the vehicle around the specified axis in either/both directions. + Once the calibration is complete for the current orientation the associated image on the screen will turn green. ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) -1. Repeat the calibration process for all vehicle orientations. +6. Repeat the calibration process for all vehicle orientations. -Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). You can then proceed to the next sensor. +Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). +You can then proceed to the next sensor. ### Partial "Quick" Calibration @@ -87,7 +94,8 @@ Notes: This calibration process leverages external knowledge of vehicle's orientation and location, and a World Magnetic Model (WMM) to calibrate the hard iron biases. -1. Ensure GNSS Fix. This is required to find the expected Earth magnetic field in WMM tables. +1. Ensure GNSS Fix. + This is required to find the expected Earth magnetic field in WMM tables. 2. Align the vehicle to face True North. Be as accurate as possible for best results. 3. Open the [QGroundControl MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) and send the following command: @@ -107,6 +115,30 @@ Notes: After the calibration is complete, check that the heading indicator and the heading of the arrow on the map are stable and match the orientation of the vehicle when turning it e.g. to the cardinal directions. +## Recalibration + +Recalibration is recommended whenever the magnetic environment of the vehicle has changed or when heading behavior appears unreliable. + +You can use either complete calibration or mag quick calibration depending on the size of the vehicle and your ability to rotate it through the required orientations. +Complete calibration provides the most accurate soft-iron compensation. + +Recalibrate the compass when: + +- _The compass module or its mounting orientation has changed._ + This includes replacing the GPS or mag unit, rotating the mast, or altering how the module is fixed to the airframe. +- _The vehicle has been exposed to a strong magnetic disturbance._ + Examples include transport or storage near large steel structures, welding operations near the airframe, or operation close to high-current equipment. +- _Structural, wiring, or payload changes may have altered the magnetic field around the sensors._ + New payloads, rerouted wires, additional batteries, or metal fasteners can introduce soft-iron effects that affect heading accuracy. +- _The vehicle is operated in a region with significantly different magnetic characteristics._ + Large changes in latitude, longitude, or magnetic inclination can require re-estimation of offsets. +- _QGroundControl reports magnetometer inconsistencies_. + For example, if you see the error `mag sensors inconsistent`. +- _Heading behavior does not match the vehicle’s observed orientation._ + Symptoms include drifting yaw, sudden heading jumps when attempting to fly straight, and toilet bowling +- _QGroundControl_ sends the error `mag sensors inconsistent`. + This indicates that multiple magnetometers are reporting different headings. + ## Additional Calibration/Configuration The process above will autodetect, [set default rotations](../advanced_config/parameter_reference.md#SENS_MAG_AUTOROT), calibrate, and prioritise, all available magnetometers. diff --git a/docs/en/config/flight_mode.md b/docs/en/config/flight_mode.md index 545f1a2acc..71be6f1990 100644 --- a/docs/en/config/flight_mode.md +++ b/docs/en/config/flight_mode.md @@ -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_. ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) -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). - ### 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: ![Taranis - Map channel to switch](../../assets/qgc/setup/flight_modes/single_channel_mode_selection_1.png) -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. ![Taranis - Configure channel](../../assets/qgc/setup/flight_modes/single_channel_mode_selection_2.png) 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. -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 diff --git a/docs/en/config/level_horizon_calibration.md b/docs/en/config/level_horizon_calibration.md index 6eb708b16a..30c2fc0a71 100644 --- a/docs/en/config/level_horizon_calibration.md +++ b/docs/en/config/level_horizon_calibration.md @@ -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. diff --git a/docs/en/config/safety.md b/docs/en/config/safety.md index 92a302ad3e..f89914c9b0 100644 --- a/docs/en/config/safety.md +++ b/docs/en/config/safety.md @@ -106,7 +106,7 @@ The settings and underlying parameters are shown below. | Setting | Parameter | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe @@ -121,36 +121,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Additional (and underlying) parameter settings are shown below. | Parameter | Setting | Description | | ----------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [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 old manual control setpoint until the timeout triggers. | +| [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. | | [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. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | Failsafe Action | Disabled, Loiter, Return, Land, Disarm, Terminate. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set the modes in which manual control loss is ignored: Mission, Hold, Offboard. | +| [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 -The Data Link Loss failsafe is triggered if a telemetry link (connection to ground station) is lost. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) 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. | - -The following settings also apply, but are not displayed in the QGC UI. - -| Setting | Parameter | Description | -| ----------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| 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. | +| 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 @@ -185,17 +181,22 @@ The following settings also apply, but are not displayed in the QGC UI. | Preemptive geofence triggering | [GF_PREDICT](../advanced_config/parameter_reference.md#GF_PREDICT) | (Experimental) Trigger geofence if current motion of the vehicle is predicted to trigger the breach (rather than late triggering after the breach). | | Circuit breaker for flight termination | [CBRK_FLIGHTTERM](../advanced_config/parameter_reference.md#CBRK_FLIGHTTERM) | Enables/Disables flight termination action (disabled by default). | -## Position (GNSS) Loss Failsafe +## Position Estimation Failsafes + +This section describes failsafes related to the quality of the vehicle's position estimate. + +### Position Loss Failsafe The _Position Loss Failsafe_ is triggered if the quality of the PX4 position estimate falls below acceptable levels (this might be caused by GPS loss) while in a mode that requires an acceptable position estimate. -The sections below cover first the trigger and then the failsafe action taken by the controller. ### Position Loss Failsafe Trigger -There are basically two mechanisms in PX4 to trigger position failsafes: +The position loss failsafe triggers if the position estimate becomes _invalid_. There are two mechanisms in PX4 to invalidate the position estimate: -- A timeout since the last sensor data was fused that provides direct speed or horizontal position measurements. Sensors that fall into that category are: GNSS, optical flow, airspeed, VIO, auxiliary global position. -- The estimated horizontal position accuracy exceeds a certain threshold. This check is only done on hovering systems (rotary wing vehicles or VTOLs in hover phase). +- A timeout since the last sensor data was fused that provides direct speed or horizontal position measurements. + - Sensors that fall into that category are: GNSS, optical flow, airspeed, VIO, auxiliary global position. +- The estimated horizontal position inaccuracy exceeds the threshold [COM_POS_LOW_EPH](../advanced_config/parameter_reference.md#COM_POS_LOW_EPH) + - This check is only done on hovering systems (rotary-wing vehicles or VTOLs in hover phase). For fixed-wing vehicles, refer to the [Position Accuracy Low](#position-accuracy-low-failsafe) section. The relevant parameters shown below. @@ -206,29 +207,29 @@ The relevant parameters shown below. ### Position Loss Failsafe Action -The failure action is controlled by [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL), based on whether RC control is assumed to be available (and altitude information): - -- `0`: Remote control available. - Switch to _Altitude mode_ if a height estimate is available, otherwise _Stabilized mode_. -- `1`: Remote control _not_ available. - Switch to _Descend mode_ if a height estimate is available, otherwise enter flight termination. - _Descend mode_ is a landing mode that does not require a position estimate. +Multicopters will switch to [Altitude mode](../flight_modes_mc/altitude.md) if a height estimate is available, otherwise [Stabilized mode](../flight_modes_mc/manual_stabilized.md). Fixed-wing planes, and VTOLs not configured to land in hover ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)), have a parameter ([FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT)) that defines how long they will loiter (circle with a constant roll angle ([FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R)) at the current altitude) after losing position before attempting to land. If VTOLs have are configured to switch to hover for landing ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)) then they will first transition and then descend. -The relevant parameters for all vehicles shown below. +The relevant parameters are: -| Parameter | Description | -| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL) | Position control navigation loss response during mission. Values: `0` - assume use of RC, `1` - Assume no RC. | +| Parameter | Description | +| ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| [FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT) | Fixed-wing only: Loiter time (waiting at current altitude for position estimation recovery before starting to descend). Set to 0 to disable. | +| [FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R) | Fixed roll/bank angle while circling. | +| [NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT) | If true, force VTOL takeoff and landing, even in `Descend` failsafe. | -Parameters that only affect Fixed-wing vehicles: +### Position Accuracy Low Failsafe -| Parameter | Description | -| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -| [FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT) | Loiter time (waiting for GPS recovery before it goes into land or flight termination). Set to 0 to disable. | -| [FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R) | Fixed roll/bank angle while circling. | +In Fixed-wing, the position estimate is never strictly invalidated as long as we have a horizontal aiding source, such as an airspeed sensor. In that case, a separate failsafe can be configured that triggers if the position estimate inacuraccy exceeds the threshold [COM_POS_LOW_EPH](../advanced_config/parameter_reference.md#COM_POS_LOW_EPH). The failsafe action is taken if the vehicle is in mission or hold mode, otherwise it is only a warning. The relevant parameters are: + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| [COM_POS_LOW_EPH](../advanced_config/parameter_reference.md#COM_POS_LOW_EPH) | Position inaccuracy threshold above which COM_POS_LOW_ACT is taken. | +| [COM_POS_LOW_ACT](../advanced_config/parameter_reference.md#COM_POS_LOW_ACT) | Failsafe action taken when position inaccuracy is above configured threshold. | + +Note that if there is no horizontal aiding source anymore, the position estimate is invalidated after `EKF2_NOAID_TOUT`, and the standard position loss failsafe applies. ## Offboard Loss Failsafe @@ -286,18 +287,18 @@ The relevant parameters are listed in the table below. ## Failure Detector -The failure detector allows a vehicle to take protective action(s) if it unexpectedly flips, or if it is notified by an external failure detection system. +The failure detector allows a vehicle to take protective actions if it unexpectedly flips, detects a motor failure, or if it is notified by an external failure detection system. During **flight**, the failure detector can be used to trigger [flight termination](../advanced_config/flight_termination.md) if failure conditions are met, which may then launch a [parachute](../peripherals/parachute.md) or perform some other action. ::: info -Failure detection during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). +Acting on a detected failure during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). ::: During **takeoff** the failure detector [attitude trigger](#attitude-trigger) invokes the [disarm action](#act_disarm) if the vehicle flips (disarm kills the motors but, unlike flight termination, will not launch a parachute or perform other failure actions). Note that this check is _always enabled on takeoff_, irrespective of the `CBRK_FLIGHTTERM` parameter. -The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/altitude.md), [Acro mode (FW)](../flight_modes_fw/altitude.md), and [Manual (FW)](../flight_modes_fw/manual.md)). +The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/acro.md), [Acro mode (FW)](../flight_modes_fw/acro.md), and [Manual (FW)](../flight_modes_fw/manual.md)). ### Attitude Trigger @@ -313,6 +314,26 @@ The relevant parameters are shown below: | [FD_FAIL_P_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_P_TTRI) | Time to exceed [FD_FAIL_P](#FD_FAIL_P) for failure detection (default 0.3s). | | [FD_FAIL_R_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_R_TTRI) | Time to exceed [FD_FAIL_R](#FD_FAIL_R) for failure detection (default 0.3s). | +### Motor Failure Trigger + +The failure detector can be configured to detect a motor failure while armed (and trigger an associated action) in the following conditions: + +- A 300 ms timeout occurs in telemetry from an ESC that was previously available. +- The input current in the telemetry of an ESC which was previously positive gets too low for more than [`FD_ACT_MOT_TOUT`](FD_ACT_MOT_TOUT) ms. + The "too low" condition is defined by: + + ```text + {esc current} < {parameter FD_ACT_MOT_C2T} * {motor command between 0 and 1} + ``` + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [FD_ACT_EN](../advanced_config/parameter_reference.md#FD_ACT_EN) | Enable/disable the motor failure trigger completely. | +| [FD_ACT_MOT_THR](../advanced_config/parameter_reference.md#FD_ACT_MOT_THR) | Minimum normalized [0,1] motor command below which motor under current is ignored. | +| [FD_ACT_MOT_C2T](../advanced_config/parameter_reference.md#FD_ACT_MOT_C2T) | Scale between normalized [0,1] motor command and expected minimally reported currrent when the rotor is healthy. | +| [FD_ACT_MOT_TOUT](../advanced_config/parameter_reference.md#FD_ACT_MOT_TOUT) | Time in miliseconds for which the under current detection condition needs to stay true. | +| [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) | Configure to not only warn about a motor failure but remove the first motor that detects a failure from the allocation effectiveness which turns off the motor and tries to operate the vehicle without it until disarming the next time. | + ### External Automatic Trigger System (ATS) The [failure detector](#failure-detector), if [enabled](#CBRK_FLIGHTTERM), can also be triggered by an external ATS system. diff --git a/docs/en/config/safety_intro.md b/docs/en/config/safety_intro.md index 771f113d73..2c4fdeec33 100644 --- a/docs/en/config/safety_intro.md +++ b/docs/en/config/safety_intro.md @@ -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_. diff --git a/docs/en/config_fw/airspeed_scale_handling.md b/docs/en/config_fw/airspeed_scale_handling.md new file mode 100644 index 0000000000..2fb8290c20 --- /dev/null +++ b/docs/en/config_fw/airspeed_scale_handling.md @@ -0,0 +1,109 @@ +# Airspeed Scale Handling + +::: info +This section complements the existing [Airspeed Validation](../advanced_config/airspeed_validation.md) documentation. +::: + +The airspeed scale is used by PX4 to convert the measured airspeed (indicated airspeed) to the calibrated airspeed. +This scale can be set by [ASPD_SCALE_n](../advanced_config/parameter_reference.md#ASPD_SCALE_1) (where `n` is the sensor number), and logged in [AirspeedWind.msg](../msg_docs/AirspeedWind.md). + +Note that the airspeed scale is different from the airspeed sensor offset calibration done on the ground at 0 m/s. The airspeed scale accounts for errors in the airspeed measurement during flight, such as those caused by sensor placement or installation effects. + +This topic describes how to set an initial airspeed scale for a new fixed-wing vehicle during its first flight. Correct scale calibration ensures reliable airspeed data, accurate TAS calculation, robust PX4 airspeed validation, and consistent controller performance. + +## Airspeed in PX4 + +PX4 handles multiple types of airspeed: + +- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). +- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. +- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. + While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. +- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). + +The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. + +## CAS Scale Estimation + +PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. +To compute the final TAS, standard environment conversions are applied (CAS → TAS). + +:::warning Important +A GNSS is required for scale estimation. +::: + +PX4 uses a two-stage approach to robustly estimate the scale: + +1. **Continuous EKF Estimation**: A wind estimator constantly compares your measured airspeed against what it expects based on ground velocity (from GNSS) and estimated wind. + If there's a consistent bias, it adjusts the scale estimate. + The estimated scale is logged in the `AirspeedWind.msg` as the `tas_scale_raw`. +2. **Validation**: To ensure robustness, PX4 collects airspeed and ground speed data across 12 different heading segments (every 30°). + This averages out wind estimation errors. + The validated scale is only updated when the new estimate demonstrably reduces the error between predicted and actual ground speeds across all headings. + The validated scale is logged in the `AirspeedWind.msg` as the `tas_scale_validated`. + +### Understanding the Scale: Physical Intuition + +The CAS scale is essentially a correction factor that accounts for systematic errors in your airspeed sensor installation. + +- A scale of 1.0 means your sensor reads perfectly (no correction needed) +- A scale > 1.0 (e.g., 1.1) means your sensor _under-reads_ by 10%, so measured airspeed (IAS) must be multiplied by 1.1 +- A scale < 1.0 (e.g., 0.9) means your sensor _over-reads_ by ~11%, so measured airspeed (IAS) must be multiplied by 0.9 + +### What Affects the Airspeed Scale + +The primary factor influencing the airspeed scale is **sensor placement**. + +Biased readings can be reflected in the scale estimate for pitot tubes installed: + +- In regions experiencing disturbed flow (commonly near blunt aircraft noses) +- Near propellers +- Under aerodynamic surfaces +- At an angle with respect to the airflow + +### Symptoms of Incorrect Scale + +Symptoms of an incorrectly scaled airspeed measurement include: + +- Stalling or overspeeding +- Persistent under- or overestimation of the TAS relative to wind-corrected groundspeed +- False positives or missed detections in [airspeed innovation checks](../advanced_config/airspeed_validation.md#innovation-check) +- Degraded tracking of the rate controllers + +## Recommended First Flight Process + +During the first flight of a new fixed-wing vehicle, allocate time for the CAS scale to converge to a reasonable initial estimate. +Follow these steps: + +1. **Set an Initial Scale** + + Set the CAS scale (`ASPD_SCALE_n`) to 1.0 (the default value). + When the scale is at exactly 1.0, PX4 automatically accelerates the learning process during the first 5 minutes of flight, allowing faster convergence to the correct scale value. + +2. **Perform a Flight** + + After takeoff, place the vehicle in loiter for about 15 minutes to allow the scale estimation to converge. + + ::: tip + Flying in circles (loiter/hold mode) is important as the scale-validation algorithm requires the aircraft to pass through multiple heading segments (12 segments covering all compass directions). + If these heading segments aren’t completed, PX4 cannot validate the estimated scale. + ::: + +3. **Check Scale Convergence** + + After the flight, review the estimated scale in logs. + Verify that: + - `tas_scale_validated` in `AirspeedWind.msg` converged during flight. + - `true_airspeed_m_s` (TAS) in [AirspeedValidated.msg](../msg_docs/AirspeedValidated.md) is consistent with groundspeed corrected for wind. + +4. **Update the Airframe Configuration** + + If using an [airframe configuration file](../dev_airframes/adding_a_new_frame.md): update `ASPD_SCALE_n`with the estimated CAS scale for future flights. + For similar vehicles with similarly mounted sensors, this value is typically a reliable starting point. + +::: info +If you are not able to perform the steps outlined above ... + +For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). +The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for `ASPD_SCALE_n`. +::: diff --git a/docs/en/config_fw/index.md b/docs/en/config_fw/index.md index 4dbc48ecb1..a81760edf6 100644 --- a/docs/en/config_fw/index.md +++ b/docs/en/config_fw/index.md @@ -3,7 +3,7 @@ Fixed-wing configuration and calibration follows the same high level steps as other frames: selection of firmware, configuration of the frame including actuator/motor geometry and output mappings, sensor configuration and calibration, configuration of safety and other features, and finally tuning. ::: info -This topic is the recommended entry point when performing first-time configuration and calibration of a new multicopter frame. +This topic is the recommended entry point when performing first-time configuration and calibration of a new fixed-wing frame. ::: The main steps are: @@ -17,3 +17,4 @@ The main steps are: - [Fixed-wing Altitude/Position Controller Tuning Guide](../config_fw/position_tuning_guide_fixedwing.md) - [Fixed-wing Trimming Guide](../config_fw/trimming_guide_fixedwing.md) +- [Fixed-Wing Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md) diff --git a/docs/en/config_fw/pid_tuning_guide_fixedwing.md b/docs/en/config_fw/pid_tuning_guide_fixedwing.md index 0eb1005a49..df7db1ea00 100644 --- a/docs/en/config_fw/pid_tuning_guide_fixedwing.md +++ b/docs/en/config_fw/pid_tuning_guide_fixedwing.md @@ -17,6 +17,8 @@ Manual tuning is recommended for frames where autotuning does not work, or where - Excessive gains (and rapid servo motion) can violate the maximum forces of your airframe - increase gains carefully. - Roll and pitch tuning follow the same sequence. The only difference is that pitch is more sensitive to trim offsets, so [trimming](../config_fw/trimming_guide_fixedwing.md) has to be done carefully and integrator gains need more attention to compensate this. +- Disable automatic [gain compression](../features_fw/gain_compression.md) ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)) to avoid over-tuning. + Remember to re-enable it when tuning is done. ## Establishing the Airframe Baseline diff --git a/docs/en/config_fw/position_tuning_guide_fixedwing.md b/docs/en/config_fw/position_tuning_guide_fixedwing.md index b4061c0b00..d1be79cdd0 100644 --- a/docs/en/config_fw/position_tuning_guide_fixedwing.md +++ b/docs/en/config_fw/position_tuning_guide_fixedwing.md @@ -9,7 +9,7 @@ A pilot tuning the TECS gains should therefore be able to fly and land the plane ::: :::tip -All parameters are documented in the [Parameter Reference](../advanced_config/parameter_reference.md#fw-tecs). +All parameters are documented in the Parameter Reference [FW Performance](../advanced_config/parameter_reference.md#fw-performance) and [FW NPFG Control](../advanced_config/parameter_reference.md#fw-npfg-control) sections. The most important parameters are covered in this guide. ::: @@ -78,7 +78,7 @@ Furthermore, these two values define the height rate limits commanded by the use ### FW Path Control Tuning (Position) -All path control parameters are described [here](../advanced_config/parameter_reference.md#fw-path-control). +All path control parameters are described in [FW NPFG Control (Parameter Reference)](../advanced_config/parameter_reference.md#fw-npfg-control). - [NPFG_PERIOD](../advanced_config/parameter_reference.md#NPFG_PERIOD) - This is the previously called L1 distance and defines the tracking point ahead of the aircraft it's following. A value of 10-20 meters works for most aircraft. diff --git a/docs/en/config_heli/index.md b/docs/en/config_heli/index.md index 131f1c7e70..d74e4c8d79 100644 --- a/docs/en/config_heli/index.md +++ b/docs/en/config_heli/index.md @@ -42,14 +42,12 @@ To setup and configure a helicopter: ![Geometry: helicopter](../../assets/config/actuators/qgc_geometry_helicopter.png) 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` 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 diff --git a/docs/en/config_mc/filter_tuning.md b/docs/en/config_mc/filter_tuning.md index 1add3a8f02..868c350d9c 100644 --- a/docs/en/config_mc/filter_tuning.md +++ b/docs/en/config_mc/filter_tuning.md @@ -70,7 +70,7 @@ Airframes with more than two frequency noise spikes typically clean the first tw Dynamic notch filters use ESC RPM feedback and/or the onboard FFT analysis. The ESC RPM feedback is used to track the rotor blade pass frequency and its harmonics, while the FFT analysis can be used to track a frequency of another vibration source, such as a fuel engine. -ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/esc_motors.md#dshot) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). +ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/dshot.md) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). Before enabling, make sure that the ESC RPM is correct. You might have to adjust the [pole count of the motors](../advanced_config/parameter_reference.md#MOT_POLE_COUNT). @@ -92,10 +92,10 @@ To reduce the control latency, we want to increase the cutoff frequency for the The effect on latency of increasing `IMU_GYRO_CUTOFF` is approximated below. | Cutoff (Hz) | Delay approx. (ms) | -| ------------ | ------------------ | -| 30 | 8 | -| 60 | 3.8 | -| 120 | 1.9 | +| ----------- | ------------------ | +| 30 | 8 | +| 60 | 3.8 | +| 120 | 1.9 | However this is a trade-off as increasing `IMU_GYRO_CUTOFF` will also increase the noise of the signal that is fed to the motors. Noise on the motors has the following consequences: diff --git a/docs/en/config_mc/index.md b/docs/en/config_mc/index.md index 9d15f9924e..db4fd6809a 100644 --- a/docs/en/config_mc/index.md +++ b/docs/en/config_mc/index.md @@ -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) diff --git a/docs/en/config_mc/pid_tuning_guide_multicopter_basic.md b/docs/en/config_mc/pid_tuning_guide_multicopter_basic.md index 1faf538b8f..dcadf60b94 100644 --- a/docs/en/config_mc/pid_tuning_guide_multicopter_basic.md +++ b/docs/en/config_mc/pid_tuning_guide_multicopter_basic.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) diff --git a/docs/en/config_rover/basic_setup.md b/docs/en/config_rover/basic_setup.md index 328e04950c..e729fc6328 100644 --- a/docs/en/config_rover/basic_setup.md +++ b/docs/en/config_rover/basic_setup.md @@ -88,7 +88,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and One approach to determine an appropriate value is: 1. From a standstill, give the rover full throttle until it reaches the maximum speed. - 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md). + 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md). 3. Divide the maximum speed by the time it took to reach it and set this as the value for [RO_ACCEL_LIM](#RO_ACCEL_LIM). Some RC rovers have enough torque to lift up if the maximum acceleration is not limited. diff --git a/docs/en/config_rover/index.md b/docs/en/config_rover/index.md index 6c14cc41fb..366377c8ab 100644 --- a/docs/en/config_rover/index.md +++ b/docs/en/config_rover/index.md @@ -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). +::: diff --git a/docs/en/config_rover/position_tuning.md b/docs/en/config_rover/position_tuning.md index 933e528cbe..f5e7f6ae2e 100644 --- a/docs/en/config_rover/position_tuning.md +++ b/docs/en/config_rover/position_tuning.md @@ -19,7 +19,6 @@ To tune the position controller configure the [parameters](../advanced_config/pa $v*{max} = v*{full throttle} \cdot (1 - \theta\_{normalized} \cdot k) $ with - - $v_{max}:$ Maximum speed - $v_{full throttle}:$ Speed at maximum throttle [RO_MAX_THR_SPEED](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED). - $\theta_{normalized}:$ Course error (Course - bearing setpoint) normalized from $[0\degree, 180\degree]$ to $[0, 1]$ @@ -34,14 +33,13 @@ To tune the position controller configure the [parameters](../advanced_config/pa ::: tip Plan a mission for the rover to drive a square and observe how it slows down when approaching a waypoint: - - If the rover decelerates too quickly decrease the [RO_DECEL_LIM](../advanced_config/parameter_reference.md#RO_DECEL_LIM) parameter, if it starts slowing down too early increase the parameter. - If you observe a jerking motion as the rover slows down, decrease the [RO_JERK_LIM](../advanced_config/parameter_reference.md#RO_JERK_LIM) parameter otherwise increase it as much as possible as it can interfere with the tuning of [RO_DECEL_LIM](../advanced_config/parameter_reference.md#RO_DECEL_LIM). These two parameters have to be tuned as a pair, repeat until you are satisfied with the behaviour. ::: -3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. +3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. If the tracking of these setpoints is not satisfactory adjust the values for [RO_SPEED_P](../advanced_config/parameter_reference.md#RO_SPEED_P) and [RO_SPEED_I](../advanced_config/parameter_reference.md#RO_SPEED_I). ## Path Following @@ -57,7 +55,6 @@ The following parameters are used to tune the algorithm: Decreasing the parameter makes it more aggressive but can lead to oscillations. To tune this: - 1. Start with a value of 1 for [PP_LOOKAHD_GAIN](#PP_LOOKAHD_GAIN) 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and while driving a straight line at approximately half the maximum speed observe its behaviour. 3. If the rover does not drive in a straight line, reduce the value of the parameter, if it oscillates around the path increase the value. diff --git a/docs/en/config_rover/rate_tuning.md b/docs/en/config_rover/rate_tuning.md index 92d4ea5d98..fd327d34ef 100644 --- a/docs/en/config_rover/rate_tuning.md +++ b/docs/en/config_rover/rate_tuning.md @@ -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. diff --git a/docs/en/config_rover/velocity_tuning.md b/docs/en/config_rover/velocity_tuning.md index 04323e7413..bf0429d43f 100644 --- a/docs/en/config_rover/velocity_tuning.md +++ b/docs/en/config_rover/velocity_tuning.md @@ -23,11 +23,10 @@ To tune the velocity controller configure the following [parameters](../advanced ::: tip To further tune this parameter: - 1. Set [RO_SPEED_P](#RO_SPEED_P) and [RO_SPEED_I](#RO_SPEED_I) to zero. This way the speed is only controlled by the feed-forward term, which makes it easier to tune. 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and then move the left stick of your controller up and/or down and hold it at a few different levels for a couple of seconds each. - 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. + 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. 4. If the actual speed of the rover is higher than the speed setpoint, increase [RO_MAX_THR_SPEED](#RO_MAX_THR_SPEED). If it is the other way around decrease the parameter and repeat until you are satisfied with the setpoint tracking. @@ -64,7 +63,6 @@ These steps are only necessary if you are tuning/want to unlock the manual [Posi Decreasing the parameter makes it more aggressive but can lead to oscillations. To tune this: - 1. Start with a value of 1 for [PP_LOOKAHD_GAIN](#PP_LOOKAHD_GAIN) 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and while driving a straight line at approximately half the maximum speed observe its behaviour. 3. If the rover does not drive in a straight line, reduce the value of the parameter, if it oscillates around the path increase the value. diff --git a/docs/en/config_vtol/index.md b/docs/en/config_vtol/index.md index b819080b95..38ee15f2f9 100644 --- a/docs/en/config_vtol/index.md +++ b/docs/en/config_vtol/index.md @@ -9,3 +9,4 @@ Then perform VTOL-specific configuration and tuning: - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/en/config_vtol/vtol_ice_shedding.md b/docs/en/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..bf9ccc80af --- /dev/null +++ b/docs/en/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,21 @@ +# VTOL Ice Shedding feature + +## Overview + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::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 + ::: diff --git a/docs/en/config_vtol/vtol_without_airspeed_sensor.md b/docs/en/config_vtol/vtol_without_airspeed_sensor.md index 758543c354..dbcfc56ec2 100644 --- a/docs/en/config_vtol/vtol_without_airspeed_sensor.md +++ b/docs/en/config_vtol/vtol_without_airspeed_sensor.md @@ -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)). diff --git a/docs/en/contribute/code.md b/docs/en/contribute/code.md index 529aea3bde..0d51f2f120 100644 --- a/docs/en/contribute/code.md +++ b/docs/en/contribute/code.md @@ -34,7 +34,7 @@ If you update an existing file you are not required to make the whole file compl ### Line Length -- Maximum line length is 120 characters. +- Maximum line length is 140 characters. ### File Extensions diff --git a/docs/en/debug/asset_tracking.md b/docs/en/debug/asset_tracking.md new file mode 100644 index 0000000000..e933596944 --- /dev/null +++ b/docs/en/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +::: info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## Overview + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## Flight Log Analysis + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## See Also + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/en/debug/failure_injection.md b/docs/en/debug/failure_injection.md index c704982dc3..298e1aad50 100644 --- a/docs/en/debug/failure_injection.md +++ b/docs/en/debug/failure_injection.md @@ -9,7 +9,7 @@ Failure injection is disabled by default, and can be enabled using the [SYS_FAIL Failure injection still in development. At time of writing (PX4 v1.14): -- It can only be used in simulation (support for both failure injection in real flight is planned). +- Support may vary by failure type and between simulatiors and real vehicle. - It requires support in the simulator. It is supported in Gazebo Classic - Many failure types are not broadly implemented. @@ -19,7 +19,7 @@ At time of writing (PX4 v1.14): ## Failure System Command -Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 console/shell, specifying both the target and type of the failure. +Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 [console/shell](../debug/consoles.md) (such as the [QGC MAVLink Console](../debug/mavlink_shell.md#qgroundcontrol-mavlink-console) or SITL _pxh shell_), specifying both the target and type of the failure. ### Syntax @@ -33,40 +33,47 @@ where: - _component_: - Sensors: - - `gyro`: Gyro. - - `accel`: Accelerometer. + - `gyro`: Gyroscope + - `accel`: Accelerometer - `mag`: Magnetometer - `baro`: Barometer - - `gps`: GPS + - `gps`: Global navigation satellite system - `optical_flow`: Optical flow. - - `vio`: Visual inertial odometry. + - `vio`: Visual inertial odometry - `distance_sensor`: Distance sensor (rangefinder). - - `airspeed`: Airspeed sensor. + - `airspeed`: Airspeed sensor - Systems: - - `battery`: Battery. - - `motor`: Motor. - - `servo`: Servo. - - `avoidance`: Avoidance. - - `rc_signal`: RC Signal. - - `mavlink_signal`: MAVLink signal (data telemetry). + - `battery`: Battery + - `motor`: Motor + - `servo`: Servo + - `avoidance`: Avoidance + - `rc_signal`: RC Signal + - `mavlink_signal`: MAVLink data telemetry connection - _failure_type_: - - `ok`: Publish as normal (Disable failure injection). - - `off`: Stop publishing. - - `stuck`: Report same value every time (_could_ indicate a malfunctioning sensor). - - `garbage`: Publish random noise. This looks like reading uninitialized memory. - - `wrong`: Publish invalid values (that still look reasonable/aren't "garbage"). - - `slow`: Publish at a reduced rate. - - `delayed`: Publish valid data with a significant delay. - - `intermittent`: Publish intermittently. + - `ok`: Publish as normal (Disable failure injection) + - `off`: Stop publishing + - `stuck`: Constantly report the same value which _can_ happen on a malfunctioning sensor + - `garbage`: Publish random noise. This looks like reading uninitialized memory + - `wrong`: Publish invalid values that still look reasonable/aren't "garbage" + - `slow`: Publish at a reduced rate + - `delayed`: Publish valid data with a significant delay + - `intermittent`: Publish intermittently - _instance number_ (optional): Instance number of affected sensor. 0 (default) indicates all sensors of specified type. -### Example +## MAVSDK Failure Plugin + +The [MAVSDK failure plugin](https://mavsdk.mavlink.io/main/en/cpp/api_reference/classmavsdk_1_1_failure.html) can be used to programmatically inject failures. +It is used in [PX4 Integration Testing](../test_and_ci/integration_testing_mavsdk.md) to simulate failure cases (for example, see [PX4-Autopilot/test/mavsdk_tests/autopilot_tester.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/test/mavsdk_tests/autopilot_tester.cpp)). + +The plugin API is a direct mapping of the failure command shown above, with a few additional error signals related to the connection. + +## Example: RC signal To simulate losing RC signal without having to turn off your RC controller: -1. Enable the parameter [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN). -1. Enter the following commands on the MAVLink console or SITL _pxh shell_: +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enter the following commands on the MAVLink console or SITL _pxh shell_: ```sh # Fail RC (turn publishing off) @@ -76,9 +83,18 @@ To simulate losing RC signal without having to turn off your RC controller: failure rc_signal ok ``` -## MAVSDK Failure Plugin +## Example: Motor -The [MAVSDK failure plugin](https://mavsdk.mavlink.io/main/en/cpp/api_reference/classmavsdk_1_1_failure.html) can be used to programmatically inject failures. -It is used in [PX4 Integration Testing](../test_and_ci/integration_testing_mavsdk.md) to simulate failure cases (for example, see [PX4-Autopilot/test/mavsdk_tests/autopilot_tester.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/test/mavsdk_tests/autopilot_tester.cpp)). +To stop a motor mid-flight without the system anticipating it or excluding it from allocation effectiveness: -The plugin API is a direct mapping of the failure command shown above, with a few additional error signals related to the connection. +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enable [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) parameter to allow turning off motors. +3. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Turn off first motor + failure motor off -i 1 + + # Turn it back on + failure motor ok -i 1 + ``` diff --git a/docs/en/dev_airframes/adding_a_new_frame.md b/docs/en/dev_airframes/adding_a_new_frame.md index addec0b132..f34ec3ea30 100644 --- a/docs/en/dev_airframes/adding_a_new_frame.md +++ b/docs/en/dev_airframes/adding_a_new_frame.md @@ -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: diff --git a/docs/en/dev_log/logging.md b/docs/en/dev_log/logging.md index e2c91e56d5..daa0d6d9e7 100644 --- a/docs/en/dev_log/logging.md +++ b/docs/en/dev_log/logging.md @@ -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.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `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.
- bit `0`: SD card logging.
- 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".
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.
- bit `0`: SD card logging.
- 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".
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: @@ -161,7 +161,7 @@ There are different clients that support ulog streaming: - If log streaming does not start, make sure the `logger` is running (see above), and inspect the console output while starting. - If it still does not work, make sure that MAVLink 2 is used. - Enforce it by setting `MAV_PROTO_VER` to 2. + `MAV_PROTO_VER` needs to be set to 2. - Log streaming uses a maximum of 70% of the configured MAVLink rate (`-r` parameter). If more is needed, messages are dropped. The currently used percentage can be inspected with `mavlink status` (1.8% is used in this example): diff --git a/docs/en/dev_log/ulog_file_format.md b/docs/en/dev_log/ulog_file_format.md index 97d57412b2..18a065797f 100644 --- a/docs/en/dev_log/ulog_file_format.md +++ b/docs/en/dev_log/ulog_file_format.md @@ -215,7 +215,7 @@ Predefined information messages are: | `char[value_len] ver_sw_branch` | git branch | "master" | | `uint32_t ver_sw_release` | Software version (see below) | 0x010401ff | | `char[value_len] sys_os_name` | Operating System Name | "Linux" | -| `char[value_len] sys_os_ve`r | OS version (git tag) | "9f82919" | +| `char[value_len] sys_os_ver` | OS version (git tag) | "9f82919" | | `uint32_t ver_os_release` | OS version (see below) | 0x010401ff | | `char[value_len] sys_toolchain` | Toolchain Name | "GNU GCC" | | `char[value_len] sys_toolchain_ver` | Toolchain Version | "6.2.1" | @@ -486,6 +486,7 @@ A valid ULog parser must fulfill the following requirements: - [replay module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/replay) - [hardfault_log module](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hardfault_log): append hardfault crash data. - [pyulog](https://github.com/PX4/pyulog): python, ULog reader and writer library with CLI scripts. + The project also has tools to convert ULog to rosbag and other formats. - [ulog_cpp](https://github.com/PX4/ulog_cpp): C++, ULog reader and writer library. - [FlightPlot](https://github.com/PX4/FlightPlot): Java, log plotter. - [MAVLink](https://github.com/mavlink/mavlink): Messages for ULog streaming via MAVLink (note that appending data is not supported, at least not for cut off messages). @@ -496,6 +497,7 @@ A valid ULog parser must fulfill the following requirements: - [ulogreader](https://github.com/maxsun/ulogreader): Javascript, ULog reader and parser outputs log in JSON object format. - [Foxglove](https://foxglove.dev): an integrated visualization and diagnosis tool for robotics data that supports ULog files. - [TypeScript ULog parser](https://github.com/foxglove/ulog): TypeScript, ULog reader that outputs JS objects. +- [yule_log](https://crates.io/crates/yule_log): A streaming ULog parser written in Rust. ## File Format Version History diff --git a/docs/en/dev_setup/building_px4.md b/docs/en/dev_setup/building_px4.md index d9ac63b279..4d54522bb4 100644 --- a/docs/en/dev_setup/building_px4.md +++ b/docs/en/dev_setup/building_px4.md @@ -39,15 +39,6 @@ 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: - -```sh -make px4_sitl gazebo-classic -``` - -::: - This will bring up the PX4 console: ![PX4 Console](../../assets/toolchain/console_gazebo.png) @@ -88,6 +79,16 @@ cd PX4-Autopilot make px4_fmu-v5_default ``` +:::tip +You can also build using the [px4-dev Docker container](../test_and_ci/docker.md) without installing the toolchain locally. +From the PX4-Autopilot directory: + +```sh +./Tools/docker_run.sh 'make px4_fmu-v5_default' +``` + +::: + A successful run will end with similar output to: ```sh @@ -126,7 +127,8 @@ The following list shows the build commands for the [Pixhawk standard](../flight - [Pixhawk 1 (FMUv2)](../flight_controller/pixhawk.md): `make px4_fmu-v2_default` :::warning - You **must** use a supported version of GCC to build this board (e.g. the same as used by [CI/docker](../test_and_ci/docker.md)) or remove modules from the build. Building with an unsupported GCC may fail, as PX4 is close to the board's 1MB flash limit. + You **must** use a supported version of GCC to build this board (e.g. the `gcc-arm-none-eabi` package from the current Ubuntu LTS, which is the same toolchain used by CI) or remove modules from the build. + Building with an unsupported GCC may fail, as PX4 is close to the board's 1MB flash limit. ::: - Pixhawk 1 with 2 MB flash: `make px4_fmu-v3_default` @@ -191,7 +193,7 @@ The `region 'flash' overflowed by XXXX bytes` error indicates that the firmware This is common for `make px4_fmu-v2_default` builds, where the flash size is limited to 1MB. If you're building the _vanilla_ master branch, the most likely cause is using an unsupported version of GCC. -In this case, install the version specified in the [Developer Toolchain](../dev_setup/dev_env.md) instructions. +In this case, install the `gcc-arm-none-eabi` package from the current Ubuntu LTS as described in the [Developer Toolchain](../dev_setup/dev_env.md) instructions. If building your own branch, it is possible that you have increased the firmware size over the 1MB limit. In this case you will need to remove any drivers/modules that you don't need from the build. @@ -204,7 +206,7 @@ The PX4 build system opens a large number of files, so you may exceed this numbe The build toolchain will then report `Too many open files` for many files, as shown below: ```sh -/usr/local/Cellar/gcc-arm-none-eabi/20171218/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: cannot find NuttX/nuttx/fs/libfs.a: Too many open files +arm-none-eabi-ld: cannot find NuttX/nuttx/fs/libfs.a: Too many open files ``` The solution is to increase the maximum allowed number of open files (e.g. to 300). @@ -227,34 +229,9 @@ xcode-select --install sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/* /usr/local/include/ ``` -### Ubuntu 18.04: Compile errors involving arm_none_eabi_gcc - -Build issues related to `arm_none_eabi_gcc`may be due to a broken g++ toolchain installation. -You can verify that this is the case by checking for missing dependencies using: - -```sh -arm-none-eabi-gcc --version -arm-none-eabi-g++ --version -arm-none-eabi-gdb --version -arm-none-eabi-size --version -``` - -Example of bash output with missing dependencies: - -```sh -arm-none-eabi-gdb --version -arm-none-eabi-gdb: command not found -``` - -This can be resolved by removing and [reinstalling the compiler](https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa). - -### Ubuntu 18.04: Visual Studio Code is unable to watch for file changes in this large workspace - -See [Visual Studio Code IDE (VSCode) > Troubleshooting](../dev_setup/vscode.md#troubleshooting). - ### Failed to import Python packages -"Failed to import" errors when running the `make px4_sitl jmavsim` command indicates that some Python packages are not installed (where expected). +"Failed to import" errors when running the `make px4_sitl gz_x500` command indicates that some Python packages are not installed (where expected). ```sh Failed to import jinja2: No module named 'jinja2' @@ -262,12 +239,12 @@ You may need to install it using: pip3 install --user jinja2 ``` -If you have already installed these dependencies this may be because there is more than one Python version on the computer (e.g. Python 2.7.16 Python 3.8.3), and the module is not present in the version used by the build toolchain. +If you have already installed these dependencies this may be because there is more than one Python version on the computer (e.g. Python 2.7.16 and Python 3.8.3), and the module is not present in the version used by the build toolchain. -You should be able to fix this by explicitly installing the dependencies as shown: +You should be able to fix this by installing the dependencies from the repository's requirements file: ```sh -pip3 install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging +pip3 install --user -r Tools/setup/requirements.txt ``` ## PX4 Make Build Targets diff --git a/docs/en/dev_setup/config_initial.md b/docs/en/dev_setup/config_initial.md index 1e29ed30c6..b98f0bf24e 100644 --- a/docs/en/dev_setup/config_initial.md +++ b/docs/en/dev_setup/config_initial.md @@ -18,10 +18,9 @@ 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 + - Lenovo Thinkpad i5 with Ubuntu Linux 22.04 or later - **Ground control station** (computer or tablet): - iPad (may require Wifi telemetry adapter) @@ -40,9 +39,9 @@ Install the [QGroundControl Daily Build](../dev_setup/qgc_daily_build.md) for a To configure the vehicle: 1. [Install PX4 firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware) (including "custom" firmware with your own changes). -1. [Start with the airframe](../config/airframe.md) that best-matches your vehicle from the [airframe reference](../airframes/airframe_reference.md). -1. [Basic Configuration](../config/index.md) explains how to perform basic configuration. -1. [Parameter Configuration](../advanced_config/parameters.md) explains how you can find and modify individual parameters. +2. [Start with the airframe](../config/airframe.md) that best-matches your vehicle from the [airframe reference](../airframes/airframe_reference.md). +3. [Basic Configuration](../config/index.md) explains how to perform basic configuration. +4. [Parameter Configuration](../advanced_config/parameters.md) explains how you can find and modify individual parameters. ::: info diff --git a/docs/en/dev_setup/dev_env.md b/docs/en/dev_setup/dev_env.md index fddacba0cc..5d4810e00a 100644 --- a/docs/en/dev_setup/dev_env.md +++ b/docs/en/dev_setup/dev_env.md @@ -2,22 +2,22 @@ The _supported platforms_ for PX4 development are: -- [Ubuntu Linux (22.04/20.04/18.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended +- [Ubuntu Linux (24.04/22.04)](../dev_setup/dev_env_linux_ubuntu.md) - [Windows (10/11)](../dev_setup/dev_env_windows_wsl.md) — via WSL2 -- [Mac OS](../dev_setup/dev_env_mac.md) +- [macOS](../dev_setup/dev_env_mac.md) ## Supported Targets The table below shows what PX4 targets you can build on each OS. -| Target | Linux (Ubuntu) | Mac | 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 | ✓ | | ✓ | +| 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:** ROS 2 with Gazebo | ✓ | | ✓ | +| **Simulation:** [Gazebo Classic SITL](../sim_gazebo_classic/index.md) | | ✓ | ✓ | +| **Simulation:** [ROS with Gazebo Classic](../simulation/ros_interface.md) | | | ✓ | Experienced Docker users can also build with the containers used by our continuous integration system: [Docker Containers](../test_and_ci/docker.md) diff --git a/docs/en/dev_setup/dev_env_linux_centos.md b/docs/en/dev_setup/dev_env_linux_centos.md index e9b23dee5f..92398f30d8 100644 --- a/docs/en/dev_setup/dev_env_linux_centos.md +++ b/docs/en/dev_setup/dev_env_linux_centos.md @@ -39,8 +39,9 @@ You may want to also install `python-pip` and `screen`. Execute the script below to install GCC 7-2017-q4: :::warning -This version of GCC is out of date. -At time of writing the current version on Ubuntu is `9-2020-q2-update` (see [focal nuttx docker file](https://github.com/PX4/PX4-containers/blob/master/docker/Dockerfile_nuttx-focal#L28)) +This version of GCC is very outdated. +PX4 now uses the `gcc-arm-none-eabi` package from the current Ubuntu LTS (GCC 13.2.1 on Ubuntu 24.04). +This CentOS guide is community-maintained and may not produce working builds. ::: ```sh diff --git a/docs/en/dev_setup/dev_env_linux_ubuntu.md b/docs/en/dev_setup/dev_env_linux_ubuntu.md index 2c80b959ce..4edfd5793d 100644 --- a/docs/en/dev_setup/dev_env_linux_ubuntu.md +++ b/docs/en/dev_setup/dev_env_linux_ubuntu.md @@ -4,20 +4,14 @@ The following instructions use a bash script to set up the PX4 development envir The environment includes: -- [Gazebo Simulator](../sim_gazebo_gz/index.md) ("Harmonic") -- [Build toolchain for Pixhawk (and other NuttX-based hardware)](../dev_setup/building_px4.md#nuttx-pixhawk-based-boards). - -On Ubuntu 22.04: - -- [Gazebo Classic Simulator](../sim_gazebo_classic/index.md) can be used instead of Gazebo. - Gazebo is nearing feature-parity with Gazebo-Classic on PX4, and will soon replace it for all use cases. +- [Gazebo Simulator](../sim_gazebo_gz/index.md) (Gazebo Harmonic) +- [Build toolchain for Pixhawk (and other NuttX-based hardware)](../dev_setup/building_px4.md#nuttx-pixhawk-based-boards) using the `gcc-arm-none-eabi` compiler from the Ubuntu package manager. The build toolchain for other flight controllers, simulators, and working with ROS are discussed in the [Other Targets](#other-targets) section below. -::: details Can I use an older version of Ubuntu? -PX4 supports the current and last Ubuntu LTS release where possible. -Older releases are not supported (so you can't raise defects against them), but may still work. -For example, Gazebo Classic setup is included in our standard build instructions for macOS, Ubuntu 18.04 and 20.04, and Windows on WSL2 for the same hosts. +::: info +PX4 targets the **current Ubuntu LTS** (24.04) for CI and release builds, with the **previous LTS** (22.04) also supported. +Older Ubuntu versions are not supported and may not work. ::: ## Simulation and NuttX (Pixhawk) Targets @@ -50,19 +44,18 @@ To install the toolchain: - Acknowledge any prompts as the script progress. - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. -3. If you need Gazebo Classic (Ubuntu 22.04 only) then you can manually remove Gazebo and install it by following the instructions in [Gazebo Classic > Installation](../sim_gazebo_classic/index.md#installation). - -4. Restart the computer on completion. +3. Restart the computer on completion. :::details Additional notes These notes are provided "for information only": - This setup is supported by the PX4 Dev Team. The instructions may also work on other Debian Linux based systems. -- You can verify the NuttX installation by confirming the `gcc` version as shown: +- You can verify the NuttX installation by confirming `gcc` is available. + The version depends on your Ubuntu release (e.g. GCC 13.2.1 on Ubuntu 24.04): ```sh - $arm-none-eabi-gcc --version + $ arm-none-eabi-gcc --version arm-none-eabi-gcc (15:13.2.rel1-2) 13.2.1 20231009 Copyright (C) 2023 Free Software Foundation, Inc. diff --git a/docs/en/dev_setup/dev_env_mac.md b/docs/en/dev_setup/dev_env_mac.md index a77be14982..25757f8657 100644 --- a/docs/en/dev_setup/dev_env_mac.md +++ b/docs/en/dev_setup/dev_env_mac.md @@ -1,4 +1,4 @@ -# MacOS Development Environment +# macOS Development Environment The following instructions set up a PX4 development environment for macOS. This environment can be used to build PX4 for: @@ -21,8 +21,8 @@ The "base" macOS setup installs the tools needed for building firmware, and incl ### Environment Setup -:::details Apple Silicon Macbook users! -If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 by setting up an x86 terminal: +:::details Apple Silicon MacBook users! +If you have an Apple M1, M2 etc. MacBook, make sure to run the terminal as x86 by setting up an x86 terminal: 1. Locate the Terminal application within the Utilities folder (**Finder > Go menu > Utilities**) 2. Select _Terminal.app_ and right-click on it, then choose **Duplicate**. @@ -47,7 +47,7 @@ First set up the environment 1. Enforce Python 3 by appending the following lines to `~/.zshenv` ```sh - # Point pip3 to MacOS system python 3 pip + # Point pip3 to macOS system python 3 pip alias pip3=/usr/bin/pip3 ``` @@ -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: diff --git a/docs/en/dev_setup/dev_env_windows_wsl.md b/docs/en/dev_setup/dev_env_windows_wsl.md index a2efeed2e2..98e640124e 100644 --- a/docs/en/dev_setup/dev_env_windows_wsl.md +++ b/docs/en/dev_setup/dev_env_windows_wsl.md @@ -33,7 +33,7 @@ _QGroundControl for Windows_ is additionally required if you need to: Note that you can also use it to monitor a simulation, but you must manually [connect to the simulation running in WSL](#qgroundcontrol-on-windows). ::: info -Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. +Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. ::: ::: info @@ -58,20 +58,20 @@ To install WSL2 with Ubuntu on a new installation of Windows 10 or 11: wsl --install ``` - - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) - - ```sh - wsl --install -d Ubuntu-20.04 - ``` - - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) ```sh wsl --install -d Ubuntu-22.04 ``` + - Ubuntu 24.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) + + ```sh + wsl --install -d Ubuntu-24.04 + ``` + ::: info - You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: + You can also [Ubuntu 24.04](https://www.microsoft.com/store/productId/9nz3klhxdjp5) or [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from Microsoft Store, which allows you to delete the application using the normal Windows Add/Remove settings. ::: 1. WSL will prompt you for a user name and password for the Ubuntu installation. @@ -106,7 +106,7 @@ To open a WSL shell using a command prompt: ``` ```sh - wsl -d Ubuntu-20.04 + wsl -d Ubuntu-24.04 ``` If you only have one version of Ubuntu, you can just use `wsl`. @@ -325,3 +325,9 @@ sudo add-apt-repository ppa:kisak/kisak-mesa sudo apt update sudo apt upgrade ``` + +### QGroundControl not connecting to PX4 SITL + +- The connection between PX4 SITL on WSL2 and QGroundControl on Windows requires [broadcasting](../simulation/index.md#enable-udp-broadcasting) or [streaming to a specific address](../simulation/index.md#enable-streaming-to-specific-address) to be enabled. + Streaming to a specific address should be enabled by default, but is something to check if a connection can't be established. +- Network traffic might be blocked by firewall or antivirus on you system. diff --git a/docs/en/dev_setup/vscode.md b/docs/en/dev_setup/vscode.md index fb4d9e79e3..9a4b60a480 100644 --- a/docs/en/dev_setup/vscode.md +++ b/docs/en/dev_setup/vscode.md @@ -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**): ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) @@ -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). ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) @@ -127,10 +124,10 @@ Once that is done you don't need to do anything else; the toolchain will automat This section includes guidance on setup and build errors. -### Ubuntu 18.04: "Visual Studio Code is unable to watch for file changes in this large workspace" +### "Visual Studio Code is unable to watch for file changes in this large workspace" This error surfaces on startup. -On some systems, there is an upper-limit of 8192 file handles imposed on applications, which means that VSCode might not be able to detect file modifications in `/PX4-Autopilot`. +On some systems, there is an upper-limit on file handles imposed on applications, which means that VSCode might not be able to detect file modifications in `/PX4-Autopilot`. You can increase this limit to avoid the error, at the expense of memory consumption. Follow the [instructions here](https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc). diff --git a/docs/en/dronecan/ark_cannode.md b/docs/en/dronecan/ark_cannode.md index 9b3d78a085..fdb403f717 100644 --- a/docs/en/dronecan/ark_cannode.md +++ b/docs/en/dronecan/ark_cannode.md @@ -83,9 +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 | -| ----------------------------------------------------------------------------------------------- | ----------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED Meanings diff --git a/docs/en/dronecan/ark_dist.md b/docs/en/dronecan/ark_dist.md new file mode 100644 index 0000000000..b4629445ca --- /dev/null +++ b/docs/en/dronecan/ark_dist.md @@ -0,0 +1,98 @@ +# ARK DIST SR + +ARK DIST SR is a low range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). +It has an approximate range of between 8cm to 30m. + +![ARK DIST SR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-sr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- Sensors + - [Broadcom AFBR-S50LV85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lv85d) + - Typical distance range up to 30m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 84mA Average + - 86mA Max + +## Hardware Setup + +### Wiring + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST SR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 Configuration + +### DroneCAN + +#### 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `30`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## See Also + +- [ARK DIST SR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/en/dronecan/ark_dist_mr.md b/docs/en/dronecan/ark_dist_mr.md new file mode 100644 index 0000000000..054c27d769 --- /dev/null +++ b/docs/en/dronecan/ark_dist_mr.md @@ -0,0 +1,97 @@ +# ARK DIST MR + +ARK DIST MR is a mid range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). + +![ARK DIST MR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-mr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- Sensors + - [Broadcom AFBR-S50LX85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lx85d) + - Typical distance range up to 50m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 78mA Average + - 84mA Max + +## Hardware Setup + +### Wiring + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST MR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 Configuration + +### DroneCAN + +#### 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `50`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## See Also + +- [ARK DIST MR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/en/dronecan/ark_flow.md b/docs/en/dronecan/ark_flow.md index 1a107a4916..c3c7906c87 100644 --- a/docs/en/dronecan/ark_flow.md +++ b/docs/en/dronecan/ark_flow.md @@ -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)). @@ -95,6 +94,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -110,9 +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 | -| ----------------------------------------------------------------------------------------------- | ----------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED Meanings diff --git a/docs/en/dronecan/ark_flow_mr.md b/docs/en/dronecan/ark_flow_mr.md index 1262164b18..f6207cae73 100644 --- a/docs/en/dronecan/ark_flow_mr.md +++ b/docs/en/dronecan/ark_flow_mr.md @@ -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. ![ARK Flow MR](../../assets/hardware/sensors/optical_flow/ark_flow_mr.jpg) @@ -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)). @@ -92,6 +91,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -105,16 +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 | -| ----------------------------------------------------------------------------------------------- | ----------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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. diff --git a/docs/en/dronecan/ark_g5_rtk_gps.md b/docs/en/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..0a7a1d8f4d --- /dev/null +++ b/docs/en/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +::: info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Sensors + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- Buzzer +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- Dimensions + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Hardware Setup + +### Wiring + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +The steps are: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 Configuration + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## LED Meanings + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/en/dronecan/ark_g5_rtk_heading_gps.md b/docs/en/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..80505235ce --- /dev/null +++ b/docs/en/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +::: info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Sensors + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- Buzzer +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- Dimensions + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Hardware Setup + +### Wiring + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +The steps are: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 Configuration + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## LED Meanings + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/en/dronecan/ark_gps.md b/docs/en/dronecan/ark_gps.md index 1d83419d20..9b91601ca6 100644 --- a/docs/en/dronecan/ark_gps.md +++ b/docs/en/dronecan/ark_gps.md @@ -91,9 +91,17 @@ If the sensor is not centred within the vehicle you will also need to define sen - Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` if this is that last node on the CAN bus. - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK GPS from the vehicles centre of gravity. +### ARK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK GPS itself: + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 You will see green, blue and red LEDs on the ARK GPS when it is being flashed, and a blinking green LED if it is running properly. diff --git a/docs/en/dronecan/ark_rtk_gps.md b/docs/en/dronecan/ark_rtk_gps.md index b3f5637474..e3114685fa 100644 --- a/docs/en/dronecan/ark_rtk_gps.md +++ b/docs/en/dronecan/ark_rtk_gps.md @@ -20,6 +20,7 @@ Order this module from: - Multi-band RTK with fast convergence times and reliable performance - High update rate for highly dynamic applications - Centimetre accuracy in a small and energy efficient module + - Moving Base for Heading - Bosch BMM150 Magnetometer - Bosch BMP388 Barometer - Invensense ICM-42688-P 6-Axis IMU @@ -27,7 +28,7 @@ Order this module from: - Safety Button - Buzzer - Two Pixhawk Standard CAN Connectors (4 Pin JST GH) -- F9P “UART 2” Connector +- F9P `UART 2` Connector - 3 Pin JST GH - TX, RX, GND - Pixhawk Standard Debug Connector (6 Pin JST SH) @@ -85,7 +86,34 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if - Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS from the vehicles centre of gravity. -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` on the GPS if this it that last node on the CAN bus. + +### ARK RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS itself: + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +::: info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. ### Setting Up Moving Baseline & GPS Heading @@ -127,10 +155,11 @@ Setup via UART: - On the _Moving Base_, set the following: - [GPS_UBX_MODE](../advanced_config/parameter_reference.md#GPS_UBX_MODE) to `2`. +For more information see [Rover and Moving Base](../dronecan/index.md#rover-and-moving-base) in the DroneCAN guide. + ## LED Meanings - The GPS status lights are located to the right of the connectors - - Blinking green is GPS fix - Blinking blue is received corrections and RTK Float - Solid blue is RTK Fixed diff --git a/docs/en/dronecan/ark_rtk_gps_l1_l2.md b/docs/en/dronecan/ark_rtk_gps_l1_l2.md new file mode 100644 index 0000000000..4e2175a147 --- /dev/null +++ b/docs/en/dronecan/ark_rtk_gps_l1_l2.md @@ -0,0 +1,163 @@ +# ARK RTK GPS L1 L5 + +[ARK RTK GPS L1 L5](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox F9P](https://www.u-blox.com/en/product/zed-f9p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK RTK GPS L1 L5](../../assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-rtk-gps-l1-l5/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- Sensors + - Ublox F9P GPS + - Multi-band GNSS receiver delivers centimetre level accuracy in seconds + - Concurrent reception of GPS, GLONASS, Galileo and BeiDou + - Multi-band RTK with fast convergence times and reliable performance + - High update rate for highly dynamic applications + - Centimetre accuracy in a small and energy efficient module + - Does not Support Moving Base for Heading + - Bosch BMM150 Magnetometer + - Bosch BMP388 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412CEU6 MCU +- Safety Button +- Buzzer +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- F9P `UART 2` Connector + - 3 Pin JST GH + - TX, RX, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 170mA Average + - 180mA Max + +## Hardware Setup + +### Wiring + +The ARK RTK GPS L1 L5 is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK RTK GPS L1 L5 runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK RTK GPS L1 L5 boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK RTK GPS L1 L5, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +The steps are: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK RTK GPS L1 L5 CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 Configuration + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS L1 L5 from the vehicles centre of gravity. + +### ARK RTK GPS L1 L5 Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS L1 L5 itself: + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +::: info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED Meanings + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK RTK GPS L1 L5 has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +### Updating Ublox F9P Module + +ARK RTK GPS L1 L5 comes with the Ublox F9P module up to date with version 1.13 or newer. However, you can check the version and update the firmware if desired. + +The steps are: + +1. [Download u-center from u-blox.com](https://www.u-blox.com/en/product/u-center) and install on your PC (Windows only) +2. Open the [u-blox ZED-F9P website](https://www.u-blox.com/en/product/zed-f9p-module#tab-documentation-resources) +3. Scroll down and click on the "Show Legacy Documents" box +4. Scroll down again to Firmware Update and download your desired firmware (at least version 1.13 is needed) +5. While holding down the safety switch on the ARK RTK GPS L1 L5, connect it to power via one of its CAN ports and hold until all 3 LEDs blink rapidly +6. Connect the ARK RTK GPS L1 L5 to your PC via its debug port with a cable such as the Black Magic Probe or an FTDI +7. Open u-center, select the COM port for the ARK RTK GPS L1 L5 and connect + ![U-Center Connect](../../assets/hardware/gps/ark/ark_rtk_gps_ucenter_connect.png) +8. Check the current firmware version by selecting View, Messages View, UBX, MON, VER + ![Check Version](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_version.png) +9. To update the firmware: + 1. Select Tools, Firmware Update + 2. The Firmware image field should be the .bin file downloaded from the u-blox ZED-F9P website + 3. Check the "Use this baudrate for update" checkbox and select 115200 from the drop-down + 4. Ensure the other checkboxes are as shown below + 5. Push the green GO button on the bottom left + 6. "Firmware Update SUCCESS" should be displayed if it updated successfully + ![Firmware Update](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_f9p_firmware_update.png) + +## See Also + +- [ARK RTK GPS L1 L5 Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) (ARK Docs) diff --git a/docs/en/dronecan/ark_x20_rtk_gps.md b/docs/en/dronecan/ark_x20_rtk_gps.md new file mode 100644 index 0000000000..4afc299d5d --- /dev/null +++ b/docs/en/dronecan/ark_x20_rtk_gps.md @@ -0,0 +1,141 @@ +# ARK X20 RTK GPS + +[ARK X20 RTK GPS](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox ZED-X20P all-band high precision GNSS module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK X20 RTK GPS](../../assets/hardware/gps/ark/ark_x20_rtk_gps.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-x20-rtk-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- Sensors + - Ublox ZED-X20P + - All-band all constellation GNSS receiver + - Best position accuracy and availability in different environments + - RTK, PPP-RTK and PPP algorithms expanding the limits of performance + - Highest quality GNSS raw data + - u-blox end-to-end hardened security + - 25Hz update rate + - ST IIS2MDC Magnetometer + - Bosch BMP390 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412VGH6 MCU +- Safety Button +- Buzzer +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- X20 “UART 2” Connector + - 4 Pin JST GH + - TX, RX, PPS, GND +- I2C Expansion Connector + - 4 Pin JST-GH + - 5.0V, SCL, SDA, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 144mA Average + - 157mA Max + +## Hardware Setup + +### Wiring + +The ARK X20 RTK GPS is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK X20 RTK GPS runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK X20 RTK GPS boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK X20 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +The steps are: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK X20 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 Configuration + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK X20 RTK GPS from the vehicles centre of gravity. + +### ARK X20 RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK X20 RTK GPS itself: + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +::: info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED Meanings + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK X20 RTK GPS has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +## See Also + +- [ARK X20 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) (ARK Docs) diff --git a/docs/en/dronecan/escs.md b/docs/en/dronecan/escs.md index 9742e3739e..4b6eb3fafb 100644 --- a/docs/en/dronecan/escs.md +++ b/docs/en/dronecan/escs.md @@ -1,7 +1,14 @@ # DroneCAN ESCs PX4 supports DroneCAN compliant ESCs. -For more information, see the following articles for specific hardware/firmware: + +## Supported ESC + +:::info +[Supported ESCs](../peripherals/esc_motors#supported-esc) in _ESCs & Motors_ may include additional devices that are not listed below. +::: + +The following articles have specific hardware/firmware information: - [PX4 Sapog ESC Firmware](sapog.md) - [Holybro Kotleta 20](holybro_kotleta.md) @@ -9,3 +16,18 @@ For more information, see the following articles for specific hardware/firmware: - [Vertiq](../peripherals/vertiq.md) (larger modules) - [VESC Project](../peripherals/vesc.md) - [RaccoonLab Cyphal and DroneCAN PWM nodes](raccoonlab_nodes.md) + +## Hardware Configuration + +General DroneCAN hardware configuration is covered in [DroneCAN > Hardware Setup](../dronecan/index.md#hardware-setup). + +DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + +## PX4 Configuration + +DroneCAN peripherals are configured by following the procedure outlined in [DroneCAN](../dronecan/index.md). + +In addition to the general setup, such as setting `UAVCAN_ENABLE` to `3`: + +- Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +- Configure the [motor order and servo outputs](../config/actuators.md). diff --git a/docs/en/dronecan/holybro_h_rtk_zed_f9p_gps.md b/docs/en/dronecan/holybro_h_rtk_zed_f9p_gps.md index 12879ef265..de1de36510 100644 --- a/docs/en/dronecan/holybro_h_rtk_zed_f9p_gps.md +++ b/docs/en/dronecan/holybro_h_rtk_zed_f9p_gps.md @@ -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_` 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 diff --git a/docs/en/dronecan/index.md b/docs/en/dronecan/index.md index 75a211b927..00ba948cbc 100644 --- a/docs/en/dronecan/index.md +++ b/docs/en/dronecan/index.md @@ -27,6 +27,8 @@ Connecting peripherals over DroneCAN has many benefits: - Wiring is less complicated as you can have a single bus for connecting all your ESCs and other DroneCAN peripherals. - Setup is easier as you configure ESC numbering by manually spinning each motor. - It allows users to configure and update the firmware of all CAN-connected devices centrally through PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## Supported Hardware @@ -62,6 +64,8 @@ Supported hardware includes (this is not an exhaustive list): - [Holybro RM3100 Professional Grade Compass](https://holybro.com/products/dronecan-rm3100-compass) - [RaccoonLab RM3100 Magnetometer](https://docs.raccoonlab.co/guide/gps_mag_baro/mag_rm3100.html) - Distance sensors + - [ARK Dist](ark_dist.md) + - [Ark Dist MR](ark_dist_mr.md) - [ARK Flow](ark_flow.md) - [Ark Flow MR](ark_flow_mr.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface](../dronecan/avanon_laser_interface.md) @@ -96,6 +100,10 @@ If the DNA is still running and certain devices need to be manually configured, ::: info The PX4 node ID can be configured using the [UAVCAN_NODE_ID](../advanced_config/parameter_reference.md#UAVCAN_NODE_ID) parameter. The parameter is set to 1 by default. + +Devices running the [PX4 DroneCAN firmware](px4_cannode_fw.md) (such as [ARK CANnode](ark_cannode.md)) can use the +[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter to set a static node ID. +Set it to 0 (default) for dynamic allocation, or to a value between 1-127 to use a specific static node ID. ::: :::warning @@ -270,6 +278,22 @@ PX4 DroneCAN parameters: [DroneCAN ESCs and servos](../dronecan/escs.md) require the [motor order and servo outputs](../config/actuators.md) to be configured. +Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +Note that DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + +### Lights + +PX4 can control LEDs via DroneCAN [LightsCommand](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#lightscommand) messages. + +Configuration: + +1. Set [UAVCAN_LGT_NUM](../advanced_config/parameter_reference.md#UAVCAN_LGT_NUM) to the number of lights (0 disables). You might need to reopen the ground station to have parameters for new instances available. +2. For each light slot (0 to NUM-1), set: + - `UAVCAN_LGT_IDx`: The `light_id` matching your peripheral. + - `UAVCAN_LGT_FNx`: `Status` for system status colours, or `Anti-collision` for white beacon. +3. For anti-collision lights, [UAVCAN_LGT_ANTCL](../advanced_config/parameter_reference.md#UAVCAN_LGT_ANTCL) controls when they illuminate (off, armed, prearmed, always on). +4. Reboot for any changes to take effect. + ## QGC CANNODE Parameter Configuration QGroundControl can inspect and modify parameters belonging to CAN devices attached to the flight controller, provided the device are connected to the flight controller before QGC is started. @@ -279,6 +303,11 @@ For example, the screenshot below shows the parameters for a CAN GPS with node i ![QGC Parameter showing selected DroneCAN node](../../assets/can/dronecan/qgc_can_parameters.png) +Common CANNODE parameters that you can configure include: + +- [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID): Set a static node ID (1-127) or use 0 for dynamic allocation. See [PX4 DroneCAN Firmware > Static Node ID](px4_cannode_fw.md#static-node-id) for more information. +- [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM): Enable CAN bus termination on the last node in the bus. + ## Device Specific Setup Most DroneCAN nodes require no further setup, unless specifically noted in their device-specific documentation. @@ -307,7 +336,10 @@ If successful, the firmware binary will be removed from the root directory and t **Q**: The motors aren't spinning when armed. -**A**: Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +**A**: + +- Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +- Make sure `UAVCAN_ESC_IFACE` is set to enable the CAN interface(s) used for ESCs. --- diff --git a/docs/en/dronecan/px4_cannode_fw.md b/docs/en/dronecan/px4_cannode_fw.md index c165b74662..ad31e5e1be 100644 --- a/docs/en/dronecan/px4_cannode_fw.md +++ b/docs/en/dronecan/px4_cannode_fw.md @@ -20,6 +20,26 @@ make ark_can-flow_default This will create an output in **build/ark_can-flow_default** named **XX-X.X.XXXXXXXX.uavcan.bin**. Follow the instructions at [DroneCAN firmware update](index.md#firmware-update) to flash the firmware. +## Configuration + +### Static Node ID + +By default, DroneCAN devices use [Dynamic Node Allocation (DNA)](index.md#node-id-allocation) to automatically obtain a unique node ID from the flight controller. +However, you can configure a static node ID using the [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter. + +To configure a static node ID: + +1. Set [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) to a value between 1-127 using [QGroundControl](index.md#qgc-cannode-parameter-configuration) +2. Reboot the device + +To return to dynamic allocation, set `CANNODE_NODE_ID` back to 0. +Note that when switching back to dynamic allocation, the flight controller will typically continue to allocate the same node ID that was previously used (this is normal DNA behavior). + +:::warning +When using static node IDs, you must ensure that each device on the CAN bus has a unique node ID. +Configuring two devices with the same ID will cause communication conflicts. +::: + ## Developer Information This section has information that is relevant to developers who want to add support for new DroneCAN hardware to the PX4 Autopilot. diff --git a/docs/en/esc/ark_4in1_esc.md b/docs/en/esc/ark_4in1_esc.md new file mode 100644 index 0000000000..40fb8d607f --- /dev/null +++ b/docs/en/esc/ark_4in1_esc.md @@ -0,0 +1,56 @@ +# ARK 4IN1 ESC (with/without Connectors) + +4 in 1 Electronic Speed Controller (ESC) that is made in the USA, NDAA compliant, and DIU Blue Framework listed. + +The ESC comes in variants without connectors that you can solder in place, and a variant that has built-in motor and battery connectors (no soldering required). + +![ARK 4IN1 ESC without connectors ](../../assets/hardware/esc/ark/ark_4_in_1_esc.jpg)![ARK 4IN1 ESC with connectors](../../assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg) + +## Where to Buy + +Order this module from: + +- [4IN1 ESC (with connectors)](https://arkelectron.com/product/ark-4in1-esc/) (ARK Electronics - US) +- [ARK Electronics (without connectors)](https://arkelectron.com/product/ark-4in1-esc-cons/) (ARK Electronics US) + +## Hardware Specifications + +- Battery Voltage: 3-8s + - 6V Minimum + - 65V Absolute Maximum +- Current Rating: 50A Continuous, 75A Burst Per Motor +- [STM32F0](https://www.st.com/en/microcontrollers-microprocessors/stm32f0-series.html) +- [AM32 Firmware](https://github.com/am32-firmware/AM32/pull/27) +- Onboard Current Sensor, Serial Telemetry + - 100V/A +- Input Protocols + - DShot (300, 600) + - Bi-directional DShot + - KISS Serial Telemetry + - PWM +- 8 Pin JST-SH Input/Output +- 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 + +- Dimensions (without connectors) + - Size: 43.00mm x 40.50mm x 7.60mm + - Mounting Pattern: 30.5mm + - Weight: 14.5g + +Other + +- Made in the USA +- Open source AM32 firmware +- [DIU Blue Framework Listed](https://www.diu.mil/blue-uas/framework) + +## See Also + +- [ARK 4IN1 ESC CONS](https://docs.arkelectron.com/electronic-speed-controller/ark-4in1-esc) (ARK Docs) diff --git a/docs/en/esc/esc_protocols.md b/docs/en/esc/esc_protocols.md new file mode 100644 index 0000000000..930d436de6 --- /dev/null +++ b/docs/en/esc/esc_protocols.md @@ -0,0 +1,66 @@ +# ESC Protocols + +This topic lists the main [Electronic Speed Controller (ESC)](../peripherals/esc_motors.md) protocols supported by PX4. + +## DShot + +[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduced latency, in particular racing multicopters, VTOL vehicles, and so on. + +It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). +In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can reverse motor spin directions. + +PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). +Selecting a higher rate DShot ESC in the UI results in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. + +## DroneCAN + +[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. +The PX4 implementation is currently limited to update rates of 200 Hz. + +DroneCAN shares many similar benefits to [DShot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. + +[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). + +## PWM + +[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). + +PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired speed. +The pulse width typically ranges between 1000 μs for zero power and 2000 μs for full power. +The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50 Hz and 490 Hz (the theoretical maximum being 500 Hz for a very small "off" cycle). +A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. +For PWM servos 50 Hz is usually sufficient, and many don't support higher rates. + +![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) + +In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the pulse widths representing low and high values can vary significantly. +Unlike [DShot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) +- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) + +## OneShot 125 + +[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. +They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). +There are a number of variants of the OneShot protocol, which support different rates. +PX4 only supports OneShot 125. + +OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125 μs to 250 μs for zero to full power). +This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. +For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. +The actual supported rate depends on the ESC used. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) diff --git a/docs/en/features_fw/gain_compression.md b/docs/en/features_fw/gain_compression.md new file mode 100644 index 0000000000..25259fd05e --- /dev/null +++ b/docs/en/features_fw/gain_compression.md @@ -0,0 +1,24 @@ +# Gain compression + + + +Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. +It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. + +This approach is a safe adaptive mechanism for stable aircraft: the PID gains remain unchanged when no oscillations are present, they are never increased beyond their nominal values, and they are bounded by a minimum limit. + +Gain compression can help prevent actuator damage and even loss of the vehicle in cases such as airspeed-sensor failure (loss of airspeed scaling) or in-flight changes in dynamics (e.g.: CG shifts, inertia changes), or other failures that could cause the angular-rate loop to become oscillatory. + +![Gain compression diagram](../../assets/config/fw/gain_compression_diagram.png) + +## Usage + +Gain compression is enabled by default ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)). + +It should be disabled during fixed wing [manual tuning](../config_fw/pid_tuning_guide_fixedwing.md) to avoid over-tuning. +It does not need to be disabled when autotuning. + +## Parameters + +- [FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN) +- [FW_GC_GAIN_MIN](../advanced_config/parameter_reference.md#FW_GC_GAIN_MIN) diff --git a/docs/en/features_fw/index.md b/docs/en/features_fw/index.md new file mode 100644 index 0000000000..7eab8e9c6c --- /dev/null +++ b/docs/en/features_fw/index.md @@ -0,0 +1,5 @@ +# Fixedwing-Specific Features + +This section lists features that are specific to (or customised for) fixed-wings: + +- [Gain Compression](../features_fw/gain_compression.md) diff --git a/docs/en/flight_controller/accton-godwit_ga1.md b/docs/en/flight_controller/accton-godwit_ga1.md new file mode 100644 index 0000000000..e3671c20c6 --- /dev/null +++ b/docs/en/flight_controller/accton-godwit_ga1.md @@ -0,0 +1,153 @@ +# Accton Godwit G-A1 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://cubepilot.org/#/home) for hardware support or compliance issues. +::: + +The G-A1 is a state-of-the-art flight controller developed derived from the [Pixhawk Autopilot v6X Standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-012%20Pixhawk%20Autopilot%20v6X%20Standard.pdf). + +It includes an STM32H753 double-precision floating-point FMU processor and an STM32F103 IO coprocessor, multiple IMUs with 6-axis inertial sensors, two pressure/temperature sensors, and a geomagnetic sensor. +It also has independent buses and power supplies, and is designed for safety and rich expansion capabilities. + +With an integrated 10/100M Ethernet Physical Layer (PHY), the G-A1 can also communicate with a mission computer (airborne computer), high-end surveying and mapping cameras, and other UxV-mounted equipment for high-speed communications, meeting the needs of advanced UxV systems. + +:::tip +Visit [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) for more information. +::: + +![AccGodwitGA1](../../assets/flight_controller/accton-godwit/ga1/outlook.png "Accton Godwit G-A1") + +![AccGodwitGA1 Top View](../../assets/flight_controller/accton-godwit/ga1/orientation.png "Accton Godwit G-A1 Top View") + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## Specifications + +### Processor + +- STM32H753IIK (Arm® Cortex®-M7 480MHz) +- STM32F103 (Arm® Cortex®-M3, 72MHz) + +### Sensors + +- Bosch BMI088 (vibration isolated) +- TDK InvenSense ICM-42688-P x 2 (one vibration isolated) +- TDK Barometric Pressure and Temperature Sensor CP-20100 x 2 (one vibration isolated) +- PNI RM3100 Geomagnetic Sensor (vibration isolated) + +### Power + +- 4.6V to 5.7V + +### External ports + +- 2 CAN Buses (CAN1 and CAN2) +- 3 TELEM Ports (TELEM1, TELEM2 and TELEM3) +- 2 GPS Ports (GPS1 with safety switch, LED, buzzer, and GPS2) +- 1 PPM IN +- 1 SBUS OUT +- 2 USB Ports (1 TYPE-C and 1 JST GH1.25) +- 1 10/100Base-T Ethernet Port +- 1 DSM/SBUS RC +- 1 UART 4 +- 1 AD&IO Port +- 2 Debug Ports (1 IO Debug and 1 FMU Debug) +- 1 SPI6 Bus +- 4 Power Inputs (Power 1, Power 2, Power C1 and Power C2) +- 16 PWM Servo Outputs (A1-A8 from FMU and M1-M8 from IO) +- Micro SD Socket (supports SD 4.1 & SDIO 4.0 in two databus modes: 1 bit (default) and 4 bits) + +### Size and Dimensions + +- 92.2 (L) x 51.2 (W) x 28.3 (H) mm +- 77.6g (carrier board with IMU) + +## Where to Buy + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) + +## Pinout + +![G-A1 Pin definition](../../assets/flight_controller/accton-godwit/ga1/pin_definition.png "G-A1 Pin definition") + +## UART Mapping + +| Serial# | Protocol | Port | Notes | +| ------- | --------- | ------ | ---------- | +| SERIAL1 | Telem1 | UART7 | /dev/ttyS6 | +| SERIAL2 | Telem2 | UART5 | /dev/ttyS4 | +| SERIAL3 | GPS1 | USART1 | /dev/ttyS0 | +| SERIAL4 | GPS2 | UART8 | /dev/ttyS7 | +| SERIAL5 | Telem3 | USART2 | /dev/ttyS1 | +| SERIAL6 | UART4 | UART4 | /dev/ttyS3 | +| SERIAL7 | FMU Debug | USART3 | | +| SERIAL8 | OTG2 | USB | | + +## Wiring Diagram + +![G-A1 Wiring](../../assets/flight_controller/accton-godwit/ga1/wiring.png "G-A1 Wiring") + +## PWM Output + +PWM M1-M8 (IO Main PWM), A1-A8(FMU PWM). +All these 16 support normal PWM output formats. +FMU PWM A1-A6 can support DShot and B-Directional DShot. +A1-A8(FMU PWM) are grouped as: + +- Group 1: A1, A2, A3, A4 +- Group 2: A5, A6 +- Group 3: A7, A8 + +The motor and servo system should be connected to these ports according to the order outlined in the fuselage reference for your carrier. + +![G-A1 PWM Motor Servo](../../assets/flight_controller/accton-godwit/ga1/motor_servo.png "G-A1 PWM Motor Servo") + +## RC Input + +For DSM/SBUS receivers, connect them to the DSM/SBUS interface which provides dedicated 3.3V and 5V power pins respectively, and check above "Pinout" for detailed pin definition. +PPM receivers should be connected to the PPM interface. And other RC systems can be connected via other spare telemetry ports. + +![G-A1 Radio](../../assets/flight_controller/accton-godwit/ga1/radio.png "G-A1 Radio") + +## GPS/Compass + +The Godwit G-A1 has a built-in compass +Due to potential interference, the autopilot is usually used with an external I2C compass as part of a GPS/Compass combination. + +![G-A1 GPS](../../assets/flight_controller/accton-godwit/ga1/gps.png "G-A1 GPS") + +## Power Connection and Battery Monitor + +This universal controller features a CAN PMU module that supports 3 to 14s lithium batteries. +To ensure proper connection, attach the module's 6-pin connector to the flight control Power C1 and/or Power C2 interface. + +This universal controller does not provide power to the servos. +To power them, an external BEC must be connected to the positive and negative terminals of any A1–A8 or M1–M8 port. + +![G-A1 Power](../../assets/flight_controller/accton-godwit/ga1/power.png "G-A1 Power") + +## SD Card + +The SD card is NOT included in the package, you need to prepare the SD card and insert it into the slot. + +![G-A1 SD Card](../../assets/flight_controller/accton-godwit/ga1/sdcard.png "G-A1 SD Card") + +## Firmware + +The autopilot is compatible with PX4 firmware. And G-A1 can be detected by QGroundControl automatically. Users can also build it with target "accton-godwit_ga1" + +To [build PX4](../dev_setup/building_px4.md) for this target, open up the terminal and enter: + +```sh +make accton-godwit_ga1 +``` + +## More Information and Support + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) +- [support@accton-iot.com](mailto:support@accton-iot.com) diff --git a/docs/en/flight_controller/airlink.md b/docs/en/flight_controller/airlink.md index 0d4fb1ec2b..30218fc14c 100644 --- a/docs/en/flight_controller/airlink.md +++ b/docs/en/flight_controller/airlink.md @@ -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](../../assets/flight_controller/airlink/airlink-interfaces-left.jpg) - **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](../../assets/flight_controller/airlink/airlink-interfaces-right.jpg) - **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](../../assets/flight_controller/airlink/airlink-interfaces-front.jpg) - **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 ![Back side](../../assets/flight_controller/airlink/airlink-interfaces-back.jpg) - **Rear side interfaces:** - - SBUS input - 16 PWM output channels - 2x LTE antenna sockets (MIMO) diff --git a/docs/en/flight_controller/autopilot_manufacturer_supported.md b/docs/en/flight_controller/autopilot_manufacturer_supported.md index cb88202875..9cdb3492e4 100644 --- a/docs/en/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/en/flight_controller/autopilot_manufacturer_supported.md @@ -12,6 +12,7 @@ This category includes boards that are not fully compliant with the pixhawk stan The boards in this category are: +- [Accton Godwit GA1](../flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](../flight_controller/mindpx.md) - [AirMind MindRacer](../flight_controller/mindracer.md) - [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) (and [ARK Electronics Pixhawk Autopilot Bus Carrier](../flight_controller/ark_pab.md)) @@ -24,14 +25,19 @@ The boards in this category are: - [CubePilot Cube Orange+](../flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange](../flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow](../flight_controller/cubepilot_cube_yellow.md) +- [Gear Up AirBrainH743](../flight_controller/gearup_airbrainh743.md) - [Holybro Kakute H7v2](../flight_controller/kakuteh7v2.md) - [Holybro Kakute H7mini](../flight_controller/kakuteh7mini.md) - [Holybro Kakute H7](../flight_controller/kakuteh7.md) - [Holybro Durandal](../flight_controller/durandal.md) - [Holybro Pix32 v5](../flight_controller/holybro_pix32_v5.md) +- [MicoAir H743 Lite](../flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](../flight_controller/modalai_voxl_2.md) - [mRo Control Zero](../flight_controller/mro_control_zero_f7.md) +- [Radiolink PIX6](../flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](../flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](../flight_controller/spracingh7extreme.md) +- [Svehicle E2](../flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](../flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](../flight_controller/thepeach_r1.md) +- [X-MAV AP-H743-R1](../flight_controller/x-mav_ap-h743r1.md) diff --git a/docs/en/flight_controller/cuav_x25-evo.md b/docs/en/flight_controller/cuav_x25-evo.md index 2d53c32fbd..881290e9c8 100644 --- a/docs/en/flight_controller/cuav_x25-evo.md +++ b/docs/en/flight_controller/cuav_x25-evo.md @@ -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 diff --git a/docs/en/flight_controller/gearup_airbrainh743.md b/docs/en/flight_controller/gearup_airbrainh743.md new file mode 100644 index 0000000000..98c14710d7 --- /dev/null +++ b/docs/en/flight_controller/gearup_airbrainh743.md @@ -0,0 +1,96 @@ +# Gear Up AirBrainH743 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://takeyourgear.com/) for hardware support. +::: + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +Purchase from [takeyourgear.com](https://takeyourgear.com/pages/products/airbrain). + +For more information and pinout, check the [GitHub documentation](https://github.com/GearUp-Company/AirBrainH743). + +## Key Features + +- MCU: STM32H743 32-bit processor running at 480 MHz +- IMU: ICM42688P +- Barometer: DPS310 +- Magnetometer: LIS2MDL (internal) +- 128MB NAND Flash for logging (W25N) +- 7x UARTs +- I2C, SPI +- 9x PWM Outputs (8 Motor outputs, 1 LED strip) +- Battery input voltage: 3S-10S +- Battery voltage/current monitoring +- 5V@2A and 10V@2.5A BEC outputs +- USB Type-C (IP68) +- EMC and ESD protection + +## Connectors and Pins + +:::warning +The pin order is different from the Pixhawk standard (compatible to the Betaflight standard). +::: + +### UARTs + +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 | + +### Motor/Servo Outputs + +| Connector | Pin | Function | +| --------- | --- | ------------ | +| ESC | M1 | Motor 1 | +| ESC | M2 | Motor 2 | +| ESC | M3 | Motor 3 | +| ESC | M4 | Motor 4 | +| PWM | M5 | Motor 5 | +| PWM | M6 | Motor 6 | +| PWM | M7 | Motor 7 | +| PWM | M8 | Motor 8 | +| AUX | M9 | LED/PWM/etc. | + + + +## PX4 Bootloader Update + +Before PX4 firmware can be installed, the _PX4 bootloader_ must be flashed. +Download the [gearup_airbrainh743_bootloader.bin](https://github.com/PX4/PX4-Autopilot/blob/main/boards/gearup/airbrainh743/extras/gearup_airbrainh743_bootloader.bin) bootloader binary and read [this page](../advanced_config/bootloader_update_from_betaflight.md) for flashing instructions. + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target: + +``` +make gearup_airbrainh743_default +``` + +## Installing PX4 Firmware + +Firmware can be installed in any of the normal ways: + +- Build and upload the source: + + ``` + make gearup_airbrainh743_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + +### System Console + +UART1 (ttyS0) is configured for use as the [System Console](../debug/system_console.md). diff --git a/docs/en/flight_controller/kakuteh7-wing.md b/docs/en/flight_controller/kakuteh7-wing.md index 775eca078b..2546a5cc01 100644 --- a/docs/en/flight_controller/kakuteh7-wing.md +++ b/docs/en/flight_controller/kakuteh7-wing.md @@ -1,4 +1,4 @@ -# Holybro Kakute H743-Wing +# Holybro Kakute H743-Wing @@ -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 diff --git a/docs/en/flight_controller/micoair743-lite.md b/docs/en/flight_controller/micoair743-lite.md new file mode 100644 index 0000000000..7b3ed25128 --- /dev/null +++ b/docs/en/flight_controller/micoair743-lite.md @@ -0,0 +1,152 @@ +# MicoAir743-Lite + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://micoair.com/) for hardware support or compliance issues. +::: + +MicoAir743-Lite is an ultra-high performance H743 flight controller with an unbeatable price, featuring the ICM45686 IMU sensor and integrated Bluetooth telemetry. + +![MicoAir743-Lite Front View](../../assets/flight_controller/micoair743_lite/front_view.png) + +Equipped with a high-performance H7 processor, the MicoAir743-Lite features a compact form factor with SH1.0 connectors (which are more suitable than Pixhawk-standard GH1.25 for this board size). +When paired with with Bluetooth telemetry, the board can be debugged with a phone or PC. + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## MicoAir743-Lite (v1.1) + +![MicoAir743-Lite Back View](../../assets/flight_controller/micoair743_lite/back_view.png) + +## Quick Summary + +### Processors & Sensors + +- FMU Processor: STM32H743 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- On-board sensors + - Accel/Gyro: ICM-45686 (with BalancedGyro™ Technology) + - Barometer: SPA06 +- On-board Bluetooth Telemetry + - Connected to UART8 internally, baudrate 115200 + - Connecting to QGC (PC or Android phone) via Bluetooth +- Other Characteristics: + - Operating & storage temperature: -20 ~ 85°c + +### Interfaces + +- 8 UART (TELEM / GPS / RC) +- 14 PWM outputs (10 supports DShot) +- Support multiple RC inputs (SBUS / CRSF / DSM) +- 1 GPS port +- 1 I2C port +- 2 ADC port2 (VBAT, Current) +- 1 DJI O3/O4 VTX connector +- 1 MicroSD Card Slot +- 1 USB Type-C + +### Electrical data + +- VBAT Input: + - 2\~6S (6\~27V) +- USB Power Input: + - 4.75\~5.25V +- BEC Output: + - 5V 2A (for controller, receiver, GPS, optical flow or other devices) + - 9V 2A (for video transmitter, camera) + +### Mechanical data + +- Mounting: 30.5 x 30.5mm, Φ4mm +- Dimensions: 36 x 36 x 8 mm +- Weight: 10g + +![MicoAir743-Lite Size](../../assets/flight_controller/micoair743_lite/size.png) + +## Where to Buy + +Order from [MicoAir Tech Store](https://store.micoair.com/product/micoair743-lite/). + +## Pinouts + +Pinouts definition can be found in the [MicoAir743-Lite_pinout.xlsx](https://raw.githubusercontent.com/PX4/PX4-Autopilot/refs/heads/main/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx) file. + +## Serial Port Mapping + +| UART | Device | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | TELEM1 | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | GPS1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART5 | /dev/ttyS4 | TELEM3 | +| USART6 | /dev/ttyS5 | RC | +| UART7 | /dev/ttyS6 | URT6 | +| UART8 | /dev/ttyS7 | TELEM4 | + +## Interfaces Diagram + +::: note +All the connectors used on the board are SH1.0 +::: + +![MicoAir743-Lite Interface Diagram](../../assets/flight_controller/micoair743_lite/interfaces_diagram.png) + +## Sample Wiring Diagram + +![MicoAir743-Lite Wiring Diagram](../../assets/flight_controller/micoair743_lite/wiring_diagram.png) + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make micoair_h743-lite_default +``` + +## Installing PX4 Firmware + +The firmware can be installed in any of the normal ways: + +- Build and upload the source + + ```sh + make micoair_h743-lite_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + ::: + +## Radio Control + +A [Radio Control (RC) system](../getting_started/rc_transmitter_receiver.md) is required if you want to manually control your vehicle (PX4 does not require a radio system for autonomous flight modes). + +The RC port is connected to the FMU and you can attach a receiver that uses the protocols `DSM`, `SBUS`, `CSRF`, `GHST`, or other protocol listed in [Radio Control modules](../modules/modules_driver_radio_control.md). +You will need to enable the protocol by setting the corresponding parameter `RC_xxxx_PRT_CFG`, such as [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) for a [CRSF receiver](../telemetry/crsf_telemetry.md). + +## Supported Platforms / Airframes + +Any multicopter / airplane / rover or boat that can be controlled with normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be seen in the [Airframes Reference](../airframes/airframe_reference.md). + +## Peripherals + +- [MicoAir Telemetry Radio Modules](https://micoair.com/radio_telemetry/) +- [MicoAir Optical & Range Sensor](https://micoair.com/optical_range_sensor/) +- [MicoAir GPS](https://micoair.com/gps/) +- [MicoAir ESC Modules](https://micoair.com/esc/) + +## Further info + +- [MicoAir Tech.](https://micoair.com/) +- [Details about MicoAir743-Lite](https://micoair.com/flightcontroller_micoair743lite/) +- [QGroundControl Download and Install](https://docs.qgroundcontrol.com/Stable_V5.0/en/qgc-user-guide/getting_started/download_and_install.html) diff --git a/docs/en/flight_controller/modalai_voxl_2.md b/docs/en/flight_controller/modalai_voxl_2.md index 2e59ec3c41..7f4f9e2214 100644 --- a/docs/en/flight_controller/modalai_voxl_2.md +++ b/docs/en/flight_controller/modalai_voxl_2.md @@ -74,7 +74,6 @@ This board supported in QGroundControl 4.0 and later. ## Availability -- [PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit) - [Starling 2](https://www.modalai.com/products/starling-2) - [Starling 2 MAX](https://www.modalai.com/products/starling-2-max) - [Sentinel Development Drone powered by VOXL 2](https://www.modalai.com/pages/sentinel) diff --git a/docs/en/flight_controller/pixhawk_series.md b/docs/en/flight_controller/pixhawk_series.md index 3091a4afd8..cf1fd037d3 100644 --- a/docs/en/flight_controller/pixhawk_series.md +++ b/docs/en/flight_controller/pixhawk_series.md @@ -100,6 +100,24 @@ 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× | + ### Licensing and Trademarks Pixhawk project schematics and reference designs are licensed under [CC BY-SA 3](https://creativecommons.org/licenses/by-sa/3.0/legalcode). diff --git a/docs/en/flight_controller/radiolink_pix6.md b/docs/en/flight_controller/radiolink_pix6.md new file mode 100644 index 0000000000..1574314338 --- /dev/null +++ b/docs/en/flight_controller/radiolink_pix6.md @@ -0,0 +1,346 @@ +# RadiolinkPIX6 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://radiolink.com.cn/) for hardware support or compliance issues. +::: + +The autopilot is recommended for commercial systems integration, but is also suitable for academic research and any other use. + +![RadiolinkPIX6](http://www.radiolink.com.cn/firmware/wiki/RadiolinkPIX6/RadiolinkPIX6.png) + +The Radiolink PIX6 is a high-performance flight controller. +Featuring STM32F7 CPU, vibration isolation of IMUs, redundant IMUs, integrated OSD chip, IMU heating, and DShot. + +::: info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## Quick Summary + +- Processor + - 32-bit ARM Cortex M7 core with DPFPU - STM32F765VIT6 + - 216 MHz/512 KB RAM/2 MB Flash + - 32-bit IOMCU co-processor - STM32F100 + - 32KB FRAM - FM25V02A + - AT7456E OSD +- Sensors + - Bosh BMI088 IMU (accel, gyro) + - InvenSense ICM-42688 IMU (accel, gyro) + - SPA06 barometer + - IST8310 magnetometer +- Power + - SMBUS/I2C Power Module Inputs (I2C) + - voltage and current monitor inputs (Analog) +- Interfaces + - 16 PWM Outputs with independent power rail for external power source + - 5x UART serial ports, 2 with HW flow control + - Camera Input and Video Output + - PPM/SBUS input, DSM/SBUS input + - RSSI (PWM or voltage) input + - I2C, SPI, 2x CAN, USB + - 3.3V and 6.6V ADC inputs + - Buzzer and Safety Switch + - microSD card +- Weight and Dimensions: + - Weight 80g + - Size 94mm x 51.5mm x 14.5mm + +## Where to Buy + +[Radiolink Amazon](https://www.radiolink.com.cn/pix6_where_to_buy)(International users) + +[Radiolink Taobao](https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bNMdSqV&ft=t&id=815993357068&skuId=5515756705284)(China Mainland user) + +## Connector assignments + +### Top View + +![Pix6 top view](../../assets/flight_controller/radiolink_pix6/top_view.png) + +### Left View + +![Pix6 left view](../../assets/flight_controller/radiolink_pix6/left_view.png) + +### Right View + +![Pix6 right view](../../assets/flight_controller/radiolink_pix6/right_view.png) + +### Rear View + +![Pix6 rear view](../../assets/flight_controller/radiolink_pix6/rear_view.png) + +## Pinouts + +Unless noted otherwise all connectors are JST GH. + +### TELEM1, TELEM2 ports + +| Pin | Signal | Volt | +| --- | ------- | ----- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | CTS | +3.3V | +| 5 | RTS | +3.3V | +| 6 | GND | GND | + +### OSD + +| Pin | Signal | Volt | +| --- | ------ | ----- | +| 1 | GND | GND | +| 2 | VOUT | +3.3V | +| 3 | VCC | +5V | +| 4 | GND | GND | +| 5 | VCC | +5V | +| 6 | VIN | +3.3V | + +### I2C port + +| Pin | Signal | Volt | +| --- | ------ | --------------- | +| 1 | VCC | +5V | +| 2 | SCL | +3.3V (pullups) | +| 3 | SDA | +3.3V (pullups) | +| 4 | GND | GND | + +### CAN1, CAN2 ports + +| Pin | Signal | Volt | +| --- | ------ | ---- | +| 1 | VCC | +5V | +| 2 | CAN_H | +12V | +| 3 | CAN_L | +12V | +| 4 | GND | GND | + +### GPS1 port + +| Pin | Signal | Volt | +| --- | ------- | ----- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### GPS2 Port + +| Pin | Signal | Volt | +| --- | ------- | ----- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### SPI + +| Pin | Signal | Volt | +| --- | --------- | ----- | +| 1 | VCC | +5V | +| 2 | SPI_SCK | +3.3V | +| 3 | SPI_MISO | +3.3V | +| 4 | SPI_MOSI | +3.3V | +| 5 | !SPI_NSS1 | +3.3V | +| 6 | !SPI_NSS2 | +3.3V | +| 7 | DRDY | +3.3V | +| 8 | GND | GND | + +### POWER1 (HY2.0-6P) + +Port for analog power monitors. + +| Pin | Signal | Volt | +| --- | ------- | ----------- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | CURRENT | up to +3.3V | +| 4 | VOLTAGE | up to +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### POWER2 (HY2.0-6P) + +Port for digital (I2C) power monitor. + +| Pin | Signal | Volt | +| --- | ------ | ----- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | SCL | +3.3V | +| 4 | SDA | +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### ADC 3.3V + +| Pin | Signal | Volt | +| --- | ------- | ----------- | +| 1 | VCC | +5V | +| 2 | ADC IN1 | up to +3.3V | +| 3 | GND | GND | +| 4 | ADC IN2 | up to +3.3v | +| 5 | GND | GND | + +### ADC 6.6V + +| Pin | Signal | Volt | +| --- | ------ | ---------- | +| 1 | VCC | +5V | +| 2 | ADC IN | up to 6.6V | +| 3 | GND | GND | + +### USB remote port + +| Pin | Signal | Volt | +| --- | ------- | ----- | +| 1 | USB VDD | +5V | +| 2 | DM | +3.3V | +| 3 | DP | +3.3V | +| 4 | GND | GND | + +### SWITCH + +| Pin | Signal | Volt | +| --- | -------------- | ----- | +| 1 | VCC | +3.3V | +| 2 | !IO_LED_SAFETY | GND | +| 3 | SAFETY | GND | + +### Buzzer port + +| Pin | Signal | Volt | +| --- | ------- | ---- | +| 1 | VCC | +5V | +| 2 | BUZZER- | +5V | + +### Spektrum/DSM Port (PH1.25-3P) + +| Pin | Signal | Volt | +| --- | ------ | ----- | +| 1 | VCC | +3.3V | +| 2 | GND | GND | +| 3 | Signal | +3.3V | + +### Debug port (SH1.0-8P) + +| Pin | Signal | Volt | +| --- | --------- | ----- | +| 1 | VCC | +5V | +| 2 | FMU_SWCLK | +3.3V | +| 3 | FMU_SWDIO | +3.3V | +| 4 | TX(UART7) | +3.3V | +| 5 | RX(UART7) | +3.3V | +| 6 | IO_SWCLK | +3.3V | +| 7 | IO_SWDIO | +3.3V | +| 8 | GND | GND | + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make radiolink_PIX6_default +``` + +## Installing PX4 Firmware + +The firmware can be installed in any of the normal ways: + +- Build and upload the source + + ```sh + make radiolink_PIX6_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + ::: + +## PX4 Configuration + +In addition to the [basic configuration](../config/index.md), the following parameters are important: + +| Parameter | Setting | +| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG) | This should be disabled since the board does not have an internal mag. You can enable it if you attach an external mag. | + +### Powering the PIX6 + +The PIX6 has 2 dedicated power monitor ports, each with a 6 pin connector. +One is the Analog power monitor (`POWER1`), and the others is the I2C power monitor (`POWER2`). + +The power module that comes with the flight controller with a wide voltage input range of 2-12S (7.4-50.4V), a maximum detection current of 90A (single ESC maximum detection current is 22.5A), a BEC output voltage of 5.3±0.2V, and a BEC output current of 2A. + +![Radiolink power modules MODULES](../../assets/flight_controller/radiolink_pix6/radiolink_power_modules.png) + +The PIX6 also supports power modules from other manufacturers, such as [holybro_pm02d](../power_module/holybro_pm02d.md). + +## Recommended Accessories + +### GPS Modules + +Radiolink manufactures a variety of high-performance GPS,Dual Anti-interference Technology Worry-free of UAV High-power Image Transmission, High-Voltage Lines, or Other Strong Signal Interference. + +The PIX6 has 2 dedicated GPS ports, `GPS1` and `GPS2`, each with a 6 pin connector. + +Recommended modules include: + +- [Radiolink SE100](https://radiolink.com.cn/se100) +- [Radiolink TS100](https://radiolink.com.cn/ts100v2) +- [Radiolink RTK F9P](https://radiolink.com.cn/rtk_f9p) + +## Serial Port Mapping + +| UART | Device | Port | +| ------ | ---------- | --------------------- | +| UART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM1 (flow control) | +| USART3 | /dev/ttyS2 | TELEM2 (flow control) | +| UART4 | /dev/ttyS3 | GPS2 | +| UART7 | /dev/ttyS4 | Debug Console | +| UART8 | /dev/ttyS5 | PX4IO | + +## Analog inputs + +The Radiolink PIX6 has 3 analog inputs, one 6V tolerant and two 3.3V tolerant. + +- ADC Pin12 -> ADC 6.6V Sense +- ADC Pin4 -> ADC IN1 3.3V Sense +- ADC Pin13 -> ADC IN2 3.3V Sense + +## Radio Control + +A [Radio Control (RC)](../getting_started/rc_transmitter_receiver.md) 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](../getting_started/rc_transmitter_receiver.md) and then _bind_ them so that they communicate (read the instructions that come with your specific transmitter/receiver). + +- Spektrum/DSM receivers connect to the **DSM/SBUS RC** input. +- PPM or SBUS receivers connect to the **RC IN** input port. +- CRSF receiver must be wired to a spare port (UART) on the Flight Controller. + Then you can bind the transmitter and receiver together. + +#### CRSF Parameter Configuration + +[Find and set](../advanced_config/parameters.md) the following parameters: + +1. Set [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) to the port that is connected to the CRSF receiver (such as `TELEM1`). + + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + + There is no need to set the baud rate for the port, as this is configured by the driver. + +1. Enable [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) to activate Crossfire telemetry. + +For more information about selecting a radio system, receiver compatibility, and binding your transmitter/receiver pair, see: [Remote Control Transmitters & Receivers](../getting_started/rc_transmitter_receiver.md). diff --git a/docs/en/flight_controller/svehicle_e2.md b/docs/en/flight_controller/svehicle_e2.md new file mode 100644 index 0000000000..61629c8b6a --- /dev/null +++ b/docs/en/flight_controller/svehicle_e2.md @@ -0,0 +1,176 @@ +# S-Vehicle E2 + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The _E2_ is an advanced autopilot manufactured by S-Vehicle®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![SVehicle-E2](../../assets/flight_controller/svehicle_e2/main.png) + +::: info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H753IIK6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- On-board sensors + - Accel/Gyro: BMI088 + - Accel/Gyro: ICM-42688-P + - Accel/Gyro: ICM-20649 + - Mag: RM3100 + - Barometer: 2x ICP-20100 + +### Interfaces + +- 14x PWM Servo Outputs +- 1x Dedicated R/C Input for Spektrum / DSM and S.Bus +- 1x Analog/PWM RSSI Input +- 2x TELEM Ports (with full flow control) +- 1x UART4 Port +- 2x GPS Ports + - 1x Full GPS plus Safety Switch Port (GPS1) + - 1x Basic GPS Port (with I2C, GPS2) +- 1x USB Port (TYPE-C) +- 1x Ethernet Port + - Transformerless application + - 100Mbps +- 3x I2C Bus Ports +- 1x SPI Bus + - 1x Chip Select Line + - 1x Data Ready Line + - 1x SPI Reset Line +- 2x CAN Ports +- 3x Power Input Ports + - ADC Power Input + - I2C Power Input + - DroneCAN/UAVCAN Power Input +- 2x AD Ports + - Analog Input (3.3V) + - Analog Input (6.6V - not supported by PX4) +- 1x Dedicated Debug Port + - FMU Debug + +## Purchase Channels + +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). + +Spektrum/DSM receivers connect to the DSM/SBUS RC input. +PPM or SBUS receivers connect to the RC IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## Serial Port Mapping + +| UART | Device | Port | +| ------ | ---------- | ------------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | Debug Console | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | PX4IO/RC | +| UART7 | /dev/ttyS6 | TELEM1 | +| UART8 | /dev/ttyS7 | GPS2 | + +## PWM Output + +The E2-Plus flight controller supports up to 14 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 6 outputs (labelled 9 to 14) are the "auxiliary" outputs. +These are directly attached to the STM32H753 FMU controller . + +The 14 PWM outputs are: + +M1 - M8 are connected to the IOMCU +A1 - A6 are connected to the FMU + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 6 FMU PWM outputs are in 2 groups: + +A1 - A4 are in one group. +A5, A6 are in a 2nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.7V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V +- Current Ratings: + - TELEM1 and GPS2 combined output current limiter: 1.5A + - All other port combined output current limiter: 1.5A + +## Battery Monitoring + +The board has connectors for 3 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN +- POWER3 -- I2C + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor and I2C defaults configured which is enabled. + +The default PDB included with the E2+ is analog and must be connected to `POWER1`. + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make svehicle_e2_default +``` + +## Debug Port + +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 | + +For information about using this port see: + +- [SWD Debug Port](../debug/swd_debug.md) +- [PX4 System Console](../debug/system_console.md) (Note, the FMU console maps to USART3). +- All ports use GH1.25 ,power ports use ports on E2 uses the 6 circuit [2.00mm Pitch CLIK-Mate Wire-to-Board PCB Receptacle](https://www.molex.com/en-us/products/part-detail/5024430670). + +## Pinouts + +![SVehicle-E2 Top Down Photo](../../assets/flight_controller/svehicle_e2/top.png) + +![SVehicle-E2 Bottom Photo](../../assets/flight_controller/svehicle_e2/back.jpeg) + +![SVehicle-E2 left Photo](../../assets/flight_controller/svehicle_e2/left.png) + +![SVehicle-E2 right Photo](../../assets/flight_controller/svehicle_e2/right.png) + +## Supported Platforms / Airframes + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). diff --git a/docs/en/flight_controller/x-mav_ap-h743r1.md b/docs/en/flight_controller/x-mav_ap-h743r1.md new file mode 100644 index 0000000000..e6ccabed17 --- /dev/null +++ b/docs/en/flight_controller/x-mav_ap-h743r1.md @@ -0,0 +1,147 @@ +# AP-H743-R1 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The AP-H743-R1 is an advanced autopilot manufactured by X-MAV®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png) + +::: info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H743VIT6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- On-board sensors + - Accel/Gyro: ICM-42688-P\*2(Version1), BMI270\*2(Version2) + - Mag: QMC5883P + - Barometer: DPS310(Version1),SPL06(Version2) + +### Interfaces + +- 15x PWM Servo Outputs +- 1x Dedicated S.Bus Input +- 3x TELEM Ports +- 1x SERIAL4 Port +- 2x GPS Ports +- 1x USB Port (TYPE-C) +- 3x I2C Bus Ports +- 2x CAN Ports +- 2x Power Input Ports + - ADC Power Input + - DroneCAN/UAVCAN Power Input +- 2x Dedicated Debug Port + - FMU Debug + - IO Debug + +## Purchase Channels + +Order from [X-MAV](https://www.x-mav.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). + +SBUS receivers connect to the SBUS-IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## Serial Port Mapping + +| UART | Device | Port | +| ------ | ---------- | ------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | TELEM1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART7 | /dev/ttyS4 | TELEM3 | +| UART8 | /dev/ttyS5 | SERIAL4 | + +## PWM Output + +The AP-H743-R1 flight controller supports up to 15 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 7 outputs (labelled A1 to A7) are the "auxiliary" outputs. +These are directly attached to the STM32H743 FMU controller . + +The 15 PWM outputs are: + +M1 - M8 are connected to the IOMCU. +A1 - A7 are connected to the FMU. + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 7 FMU PWM outputs are in 3 groups: + +- A1 - A4 are in one group. +- A5, A6 are in a 2nd group. +- A7 is in a 3nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.4V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V + +## Battery Monitoring + +The board has connectors for 2 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor configured which is enabled. + +## Building Firmware + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make x-mav_ap-h743r1_default +``` + +## Pinouts and Size + +![AP-H743-R1 pinouts](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png) + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png) + +## Supported Platforms / Airframes + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). + +## Debug Port + +### SWD + +The [SWD interface](../debug/swd_debug.md) operate on the **FMU-DEBUG** port (`FMU-DEBUG`). + +The debug port (`FMU-DEBUG`) uses a [JST SM04B-GHS-TB](https://www.digikey.com/en/products/detail/jst-sales-america-inc/SM04B-GHS-TB/807788) connector and has the following pinout: + +| Pin | Signal | Volt | +| ------- | --------- | ----- | +| 1 (red) | 5V+ | +5V | +| 2 (blk) | FMU_SWDIO | +3.3V | +| 3 (blk) | FMU_SWCLK | +3.3V | +| 4 (blk) | GND | GND | diff --git a/docs/en/flight_modes/offboard.md b/docs/en/flight_modes/offboard.md index 6a8b74953b..353c9b75a0 100644 --- a/docs/en/flight_modes/offboard.md +++ b/docs/en/flight_modes/offboard.md @@ -44,7 +44,7 @@ The following ROS 2 messages and their particular fields and field values are al In addition to providing heartbeat functionality, `OffboardControlMode` has two other main purposes: 1. Controls the level of the [PX4 control architecture](../flight_stack/controller_diagrams.md) at which offboard setpoints must be injected, and disables the bypassed controllers. -1. Determines which valid estimates (position or velocity) are required, and also which setpoint messages should be used. +2. Determines which valid estimates (position or velocity) are required, and also which setpoint messages should be used. The `OffboardControlMode` message is defined as shown. @@ -62,6 +62,11 @@ bool thrust_and_torque bool direct_actuator ``` +::: warning +The following list shows the `OffboardControlMode` options for copter, fixed-wing, and VTOL. +For rovers see the [rover section](#rover). +::: + The fields are ordered in terms of priority such that `position` takes precedence over `velocity` and later fields, `velocity` takes precedence over `acceleration`, and so on. The first field that has a non-zero value (from top to bottom) defines what valid estimate is required in order to use offboard mode, and the setpoint message(s) that can be used. For example, if the `acceleration` field is the first non-zero value, then PX4 requires a valid `velocity estimate`, and the setpoint must be specified using the `TrajectorySetpoint` message. @@ -90,20 +95,93 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - Velocity setpoint (`velocity` different from `NaN` and `position` set to `NaN`). Non-`NaN` values acceleration are used as feedforward terms for the inner loop controllers. - Acceleration setpoint (`acceleration` different from `NaN` and `position` and `velocity` set to `NaN`) - - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are \[m\], \[m/s\] and \[m/s^2\] for position, velocity and acceleration, respectively. + - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are `[m]`, `[m/s]` and `[m/s^2]` for position, velocity and acceleration, respectively. - [px4_msgs::msg::VehicleAttitudeSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) - The following input combination is supported: - quaternion `q_d` + thrust setpoint `thrust_body`. - Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in \[rad/s\]. + Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in `[rad/s]`. - - The quaternion represents the rotation between the drone body FRD (front, right, down) frame and the NED frame. The thrust is in the drone body FRD frame and expressed in normalized \[-1, 1\] values. + - The quaternion represents the rotation between the drone body FRD (front, right, down) frame and the NED frame. + The thrust is in the drone body FRD frame and expressed in normalized \[-1, 1\] values. - [px4_msgs::msg::VehicleRatesSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) - The following input combination is supported: - `roll`, `pitch`, `yaw` and `thrust_body`. - - All the values are in the drone body FRD frame. The rates are in \[rad/s\] while thrust_body is normalized in \[-1, 1\]. + - All the values are in the drone body FRD frame. + The rates are in `[rad/s]` while thrust_body is normalized in `[-1, 1]`. + +### Rover + +Rover modules must set the control mode using `OffboardControlMode` and use the appropriate messages to configure the corresponding setpoints. +The approach is similar to other vehicle types, but the allowed control mode combinations and setpoints are different: + +| Category | Usage | Setpoints | +| ------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| (Recommended) [Rover Setpoints](#rover-setpoints) | General rover control | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md), [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md), [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md), [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md), [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md), [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| [Actuator Setpoints](#actuator-setpoints) | Direct actuator control | [ActuatorMotors](../msg_docs/ActuatorMotors.md), [ActuatorServos](../msg_docs/ActuatorServos.md) | +| (Deprecated) [Trajectory Setpoint](#deprecated-trajectory-setpoint) | General vehicle control | [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) | + +#### Rover Setpoints + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). + All combinations of "left" and "right" setpoints are valid. + +The following are all valid setpoint combinations and their respective control flags that must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md) (set all others to _false_). +Additionally, for some combinations we require certain setpoints to be published with `NAN` values so that the setpoints of interest are not overridden by the rover module (due to the hierarchy above). +✓ are the relevant setpoints we publish, and ✗ are the setpoint that need to be published with `NAN` values. + +| Setpoint Combination | Control Flag | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| -------------------- | ----------------- | ------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | +| Position | position | ✓ | | | | | | +| Speed + Attitude | velocity | | ✓ | | ✓ | | | +| Speed + Rate | velocity | | ✓ | | ✗ | ✓ | | +| Speed + Steering | velocity | | ✓ | | ✗ | ✗ | ✓ | +| Throttle + Attitude | attitude | | | ✓ | ✓ | | | +| Throttle + Rate | body_rate | | | ✓ | | ✓ | | +| Throttle + Steering | thrust_and_torque | | | ✓ | | | ✓ | + +::: info +If you intend to use the rover setpoints, we recommend using the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) instead since it simplifies the publishing of these setpoints. +::: + +#### Actuator Setpoints + +Instead of controlling the vehicle using position, speed, rate and other setpoints, you can directly control the motors and actuators using [ActuatorMotors](../msg_docs/ActuatorMotors.md) and [ActuatorServos](../msg_docs/ActuatorServos.md). +In [OffboardControlMode](../msg_docs/OffboardControlMode.md) set `direct_actuator` to _true_ and all other flags to _false_. + +::: info +This bypasses the rover modules including any limits on steering rates or accelerations and the inverse kinematics step. +We recommend using [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) and [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) instead for low level control (see [Rover Setpoints](#rover-setpoints)). +::: + +#### (Deprecated) Trajectory Setpoint + +::: warning +The [Rover Setpoints](#rover-setpoints) are a replacement for the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) and we highly recommend using those instead as they have a well defined behaviour and offer more flexibility. +::: + +The rover modules support the _position_, _velocity_ and _yaw_ fields of the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md). +However, only one of the fields is active at a time and is defined by the flags of [OffboardControlMode](../msg_docs/OffboardControlMode.md): + +| Control Mode Flag | Active Trajectory Setpoint Field | +| ----------------- | -------------------------------- | +| position | position | +| velocity | velocity | +| attitude | yaw | + +::: info +Ackermann rovers do not support the yaw setpoint. +::: ### Generic Vehicle @@ -116,8 +194,10 @@ The following offboard control modes bypass all internal PX4 control loops and s - [px4_msgs::msg::ActuatorMotors](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) + [px4_msgs::msg::ActuatorServos](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) - You directly control the motor outputs and/or servo outputs. - - Currently works at lower level than then `control_allocator` module. Do not publish these messages when not in offboard mode. - - All the values normalized in \[-1, 1\]. For outputs that do not support negative values, negative entries map to `NaN`. + - Currently works at lower level than then `control_allocator` module. + Do not publish these messages when not in offboard mode. + - All the values normalized in `[-1, 1]`. + For outputs that do not support negative values, negative entries map to `NaN`. - `NaN` maps to disarmed. ## MAVLink Messages @@ -148,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: @@ -191,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: @@ -200,38 +280,29 @@ The following MAVLink messages and their particular fields and field values are ### Rover +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) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `x`, `y`, `z`) - - Specify the _type_ of the setpoint in `type_mask`: - - ::: info - The _setpoint type_ values below are not part of the MAVLink standard for the `type_mask` field. - :: - - The values are: - - 12288: Loiter setpoint (vehicle stops when close enough to setpoint). - - - Velocity setpoint (only `vx`, `vy`, `vz`) - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) and [MAV_FRAME_BODY_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_BODY_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) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `lat_int`, `lon_int`, `alt`) - - Specify the _type_ of the setpoint in `type_mask` (not part of the MAVLink standard). - The values are: - - Following bits not set then normal behaviour. - - 12288: Loiter setpoint (vehicle stops when close enough to setpoint). - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL). + - 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) - - The following input combinations are supported: - - Attitude/orientation (`SET_ATTITUDE_TARGET.q`) with thrust setpoint (`SET_ATTITUDE_TARGET.thrust`). - ::: info - Only the yaw setting is actually used/extracted. - ::: + - Not supported for rover offboard control. ## Offboard Parameters diff --git a/docs/en/flight_modes_fw/hold.md b/docs/en/flight_modes_fw/hold.md index 3691bb3441..9265479c87 100644 --- a/docs/en/flight_modes_fw/hold.md +++ b/docs/en/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -It is usually activated with a pre-programmed switch. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ It is usually activated with a pre-programmed switch. ::: -## Technical Summary +## Loiter modes -The aircraft circles around the GPS hold position at the current altitude. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -RC stick movement is ignored. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### Parameters +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +::: info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## Parameters Hold mode behaviour can be configured using the parameters below. | Parameter | Description | | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Minimum height for loiter mode (vehicle will ascend to this altitude if mode is engaged at a lower altitude). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## See Also -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/en/flight_modes_fw/index.md b/docs/en/flight_modes_fw/index.md index 8bd9e4b062..74a7fe66f0 100644 --- a/docs/en/flight_modes_fw/index.md +++ b/docs/en/flight_modes_fw/index.md @@ -17,6 +17,8 @@ Manual-Easy: Airspeed is actively controlled if an airspeed sensor is installed. - [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). - [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. @@ -33,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. diff --git a/docs/en/flight_modes_fw/land.md b/docs/en/flight_modes_fw/land.md index 43d8ff9294..77a26d0666 100644 --- a/docs/en/flight_modes_fw/land.md +++ b/docs/en/flight_modes_fw/land.md @@ -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. + ::: ## 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 | -| ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The loiter radius that the controller tracks for the whole landing sequence. | -| [FW_LND_ANG](../advanced_config/parameter_reference.md#FW_LND_ANG) | The flight path angle setpoint. | -| [FW_LND_AIRSPD](../advanced_config/parameter_reference.md#FW_LND_AIRSPD) | The airspeed setpoint. | -| [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 | +| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The loiter radius that the controller tracks for the whole landing sequence. | +| [FW_LND_ANG](../advanced_config/parameter_reference.md#FW_LND_ANG) | The flight path angle setpoint. | +| [FW_LND_AIRSPD](../advanced_config/parameter_reference.md#FW_LND_AIRSPD) | The airspeed setpoint. | +| [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 diff --git a/docs/en/flight_modes_fw/mission.md b/docs/en/flight_modes_fw/mission.md index 10f147d326..f3ee6ee95f 100644 --- a/docs/en/flight_modes_fw/mission.md +++ b/docs/en/flight_modes_fw/mission.md @@ -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". @@ -162,6 +161,10 @@ Mission Items: - [MAV_CMD_OBLIQUE_SURVEY](https://mavlink.io/en/messages/common.html#MAV_CMD_OBLIQUE_SURVEY) - [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. GeoFence Definitions diff --git a/docs/en/flight_modes_fw/takeoff.md b/docs/en/flight_modes_fw/takeoff.md index 021a79df53..b95d0806e1 100644 --- a/docs/en/flight_modes_fw/takeoff.md +++ b/docs/en/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: @@ -85,6 +85,7 @@ The vehicle always respects normal FW max/min throttle settings during takeoff ( In _catapult/hand-launch mode_ the vehicle waits to detect launch (based on acceleration trigger). On launch it enables the motor(s) and climbs with the maximum climb rate [FW_T_CLMB_MAX](#FW_T_CLMB_MAX) while keeping the pitch setpoint above [FW_TKO_PITCH_MIN](#FW_TKO_PITCH_MIN). Once it reaches [MIS_TAKEOFF_ALT](#MIS_TAKEOFF_ALT) it will automatically switch to [Hold mode](../flight_modes_fw/hold.md) and loiter. +It is possible to delay the activation of the motors and control surfaces separately, see parameters [FW_LAUN_MOT_DEL](#FW_LAUN_MOT_DEL), [FW_LAUN_CS_LK_DY](#FW_LAUN_CS_LK_DY) and [CA_CS_LAUN_LK](#CA_CS_LAUN_LK). The later is also exposed in the actuator configuration page under the advanced view. All RC stick movement is ignored during the full takeoff sequence. @@ -105,6 +106,8 @@ The _launch detector_ is affected by the following parameters: | [FW_LAUN_AC_THLD](../advanced_config/parameter_reference.md#FW_LAUN_AC_THLD) | Acceleration threshold (acceleration in body-forward direction must be above this value) | | [FW_LAUN_AC_T](../advanced_config/parameter_reference.md#FW_LAUN_AC_T) | Trigger time (acceleration must be above threshold for this amount of seconds) | | [FW_LAUN_MOT_DEL](../advanced_config/parameter_reference.md#FW_LAUN_MOT_DEL) | Delay from launch detection to motor spin up | +| [FW_LAUN_CS_LK_DY](../advanced_config/parameter_reference.md#FW_LAUN_CS_LK_DY) | Delay from launch detection to unlocking the control surfaces | +| [CA_CS_LAUN_LK](../advanced_config/parameter_reference.md#CA_CS_LAUN_LK) | Bitmask to select which control surfaces are to be locked during launch | ## Runway Takeoff {#runway_launch} diff --git a/docs/en/flight_modes_mc/altitude.md b/docs/en/flight_modes_mc/altitude.md index 13d54b9148..b08688caa0 100644 --- a/docs/en/flight_modes_mc/altitude.md +++ b/docs/en/flight_modes_mc/altitude.md @@ -21,7 +21,7 @@ The diagram below shows the mode behaviour visually (for a [mode 2 transmitter]( RC/manual mode like [Stabilized mode](../flight_modes_mc/manual_stabilized.md) but with _altitude stabilization_ (centred sticks level vehicle and hold it to fixed altitude). The horizontal position of the vehicle can move due to wind (or pre-existing momentum). -- Centered sticks (inside deadband): +- Centered sticks: - RPY sticks levels vehicle. - Throttle (~50%) holds current altitude steady against wind. - Outside center: @@ -43,9 +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 | -| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. | -| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | -| `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 | +| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. | +| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. | +| `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. | diff --git a/docs/en/flight_modes_mc/altitude_cruise.md b/docs/en/flight_modes_mc/altitude_cruise.md new file mode 100644 index 0000000000..87728cc311 --- /dev/null +++ b/docs/en/flight_modes_mc/altitude_cruise.md @@ -0,0 +1,45 @@ +# Altitude Cruise Mode (Multicopter) + +   + +_Altitude Cruise mode_ is a _relatively_ easy-to-fly manual control mode in which roll and pitch sticks control vehicle movement in the left-right and forward-back directions (relative to the "front" of the vehicle), yaw stick controls rate of rotation over the horizontal plane, and throttle controls speed of ascent-descent. + +When the sticks are released/centered the vehicle will keep the current tilt and heading angle and maintain the current _altitude_. +If moving in the horizontal plane the vehicle will accelerate until the wind resistance equals the acceleration caused by the set tilt angle. +The vehicle will then continue to move with a constant velocity (unlike for Altitude mode, in which the vehicle will eventually slow down and stop). +If the wind blows the aircraft will drift in the direction of the wind even if flying perfectly level. + +:::tip +_Altitude Cruise mode_ is intended for long distance flights where the same tilt angle is kept for a long period of time. It is just like [Altitude](../flight_modes_mc/altitude.md) mode but does not go back to level tilt when the sticks are released. +::: + +The diagram below shows the mode behaviour visually (for a [mode 2 transmitter](../getting_started/rc_transmitter_receiver.md#transmitter_modes)). + +![Altitude Control MC - Mode2 RC Controller](../../assets/flight_modes/altitude_mc.png) + +## Technical Summary + +A manual mode that is similar to [Altitude mode](../flight_modes_mc/altitude.md) but with different interpretation of roll and pitch sticks. + +- Centered sticks: + - Roll/Pitch sticks: the current tilt is kept. + - Yaw: the current heading is kept. + - Throttle (~50%) holds current altitude. +- Outside center: + - Roll/Pitch sticks control the rate of change of the tilt angle, resulting in corresponding left-right and forward-back movement. A maximum stick deflection results in a tilting rate setpoint to go from level to max tilt within 0.5 seconds. + - Yaw stick deflection rotates the tilt angle either left or right, causing the vehicle to change course. It is _not_ causing a direct rotation around the body yaw axis like in [Acro mode](../flight_modes_mc/acro.md). + - Throttle stick controls up/down speed with a predetermined maximum rate (and movement speed in other axes). +- Takeoff: + - When landed, the vehicle will take off if the throttle stick is raised above 62.5% percent (of the full range from bottom). +- Manual control input is required (such as RC control, joystick) to enter this mode. Other than in all other manual modes, it's though possible to disable the manual control loss failsafe by setting the corresponding flag in [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT). In that case the current altitude, tilt and heading 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, and to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT). + +## Parameters + +Most of the relevant parameters are already covered in the corresponding section in the [Altitude mode](../flight_modes_mc/altitude.md). Here a list of parameters of particular importance for Altitude Cruise. + +| Parameter | Description | +| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | The manual control failsafe can be disabled for Altitude Cruise by setting the corresponding bit in this parameter. | +| [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Data link lost failsafe action. Recommended to set if the manual control failsafe is disabled to avoid fly-aways. | +| [MPC_MAN_TILT_MAX](../advanced_config/parameter_reference.md#MPC_MAN_TILT_MAX) | The maximum tilt angle the vehicle will go to. At max stick deflection, it will take 0.5 seconds from level flight to this tilt angle. | diff --git a/docs/en/flight_modes_mc/follow_me.md b/docs/en/flight_modes_mc/follow_me.md index 08ff63687d..33b02a896e 100644 --- a/docs/en/flight_modes_mc/follow_me.md +++ b/docs/en/flight_modes_mc/follow_me.md @@ -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: - 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 diff --git a/docs/en/flight_modes_mc/index.md b/docs/en/flight_modes_mc/index.md index c0fe5405f2..bbab81b23d 100644 --- a/docs/en/flight_modes_mc/index.md +++ b/docs/en/flight_modes_mc/index.md @@ -21,10 +21,12 @@ Manual-Easy: - [Stabilized mode](../flight_modes_mc/manual_stabilized.md) — Releasing the sticks levels and maintains the vehicle horizontal posture (but not altitude or position). The vehicle will continue to move with momentum, and both altitude and horizontal position may be affected by wind. This mode is also used if "Manual mode" is selected in a ground station. +- [Altitude Cruise mode](../flight_modes_mc/altitude_cruise.md) — Very similar to _Altitude mode_, with the difference that when the roll and pitch sticks are released the vehicle does not level out but keeps the tilt until further inputs are given. + Additionally it is possible to disable the manual control failsafe for this mode, having the vehicle continue on it's set path even if there are no new control inputs. Manual-Acrobatic -- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic maneuvers, such as rolls and loops. +- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic manoeuvrers, such as rolls and loops. Releasing the sticks stops the vehicle rotating in the roll, pitch, yaw axes, but does not otherwise stabilise the vehicle. Autonomous: diff --git a/docs/en/flight_modes_mc/manual_stabilized.md b/docs/en/flight_modes_mc/manual_stabilized.md index 9d3f29112d..36a9ae345f 100644 --- a/docs/en/flight_modes_mc/manual_stabilized.md +++ b/docs/en/flight_modes_mc/manual_stabilized.md @@ -31,7 +31,7 @@ Throttle is rescaled (see [below](#params)) and passed directly to control alloc The autopilot controls the attitude, meaning it regulates the roll and pitch angles to zero when the RC sticks are centered inside the controller deadzone (consequently leveling-out the attitude). The autopilot does not compensate for drift due to wind (or other sources). -- Centered sticks (inside deadband): +- Centered sticks: - Roll/Pitch sticks level vehicle. - Outside center: - Roll/Pitch sticks control tilt angle in those orientations, resulting in corresponding left-right and forward-back movement. diff --git a/docs/en/flight_modes_mc/mission.md b/docs/en/flight_modes_mc/mission.md index 0b5b9bced4..04e7ccf433 100644 --- a/docs/en/flight_modes_mc/mission.md +++ b/docs/en/flight_modes_mc/mission.md @@ -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". @@ -166,6 +165,9 @@ Mission Items: - [MAV_CMD_NAV_VTOL_TAKEOFF](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_VTOL_TAKEOFF) - `MAV_CMD_NAV_VTOL_TAKEOFF.param2` (transition heading) is ignored. Instead the heading to the next waypoint is used for the transition heading. +- [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) . GeoFence Definitions diff --git a/docs/en/flight_modes_mc/position.md b/docs/en/flight_modes_mc/position.md index cb85fc53ac..75fae4ab21 100644 --- a/docs/en/flight_modes_mc/position.md +++ b/docs/en/flight_modes_mc/position.md @@ -43,7 +43,7 @@ While very rare on a well calibrated vehicle, sometimes there may be problems wi RC mode where roll, pitch, throttle (RPT) sticks control movement in corresponding axes/directions. Centered sticks level vehicle and hold it to fixed altitude and position against wind. -- Centered roll, pitch, throttle sticks (within RC deadzone [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ)) hold x, y, z position steady against any disturbance like wind. +- Centered roll, pitch, throttle sticks (within RC deadzone [MAN_DEADZONE](#MAN_DEADZONE)) hold x, y, z position steady against any disturbance like wind. - Outside center: - Roll/Pitch sticks control horizontal acceleration over ground in the vehicle's left-right and forward-back directions (respectively). - Throttle stick controls speed of ascent-descent. @@ -51,28 +51,27 @@ Centered sticks level vehicle and hold it to fixed altitude and position against - Takeoff: - When landed, the vehicle will take off if the throttle stick is raised above 62.5% percent (of the full range from bottom). - Global position estimate is required. -- Manual control input is required (such as RC control, joystick). - - Roll, Pitch, Throttle: Assistance from autopilot to hold position against wind. - - Yaw: Assistance from autopilot to stabilize the attitude rate. - Position of RC stick maps to the rate of rotation of vehicle in that orientation. +- Manual control input is required (such as RC control, joystick). + - Roll, Pitch, Throttle: Assistance from autopilot to hold position against wind. + - Yaw: Assistance from autopilot to stabilize the attitude rate. + Position of RC stick maps to the rate of rotation of vehicle in that orientation. ### Parameters All the parameters in the [Multicopter Position Control](../advanced_config/parameter_reference.md#multicopter-position-control) group are relevant. A few parameters of particular note are listed below. -| Parameter | Description | -| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ) | Deadzone of sticks where position hold is enabled. Default: 0.1 (10% of full stick range). | -| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. | -| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. | -| [MPC_LAND_ALT1](../advanced_config/parameter_reference.md#MPC_LAND_ALT1) | Altitude for triggering first phase of slow landing. Below this altitude descending velocity gets limited to a value between [MPC_Z_VEL_MAX_DN](#MPC_Z_VEL_MAX_DN) (or `MPC_Z_V_AUTO_DN`) and [MPC_LAND_SPEED](#MPC_LAND_SPEED). Value needs to be higher than [MPC_LAND_ALT2](#MPC_LAND_ALT2). Default 10m. | -| [MPC_LAND_ALT2](../advanced_config/parameter_reference.md#MPC_LAND_ALT2) | Altitude for second phase of slow landing. Below this altitude descending velocity gets limited to [`MPC_LAND_SPEED`](#MPC_LAND_SPEED). Value needs to be lower than "MPC_LAND_ALT1". Default 5m. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | -| `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. | -| [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Stick input to movement translation strategy. From PX4 v1.12 the default (`Acceleration based`) is that stick position controls acceleration (in a similar way to a car accelerator pedal). Other options allow stick deflection to directly control speed over ground, with and without smoothing and acceleration limits. | -| [MPC_ACC_HOR_MAX](../advanced_config/parameter_reference.md#MPC_ACC_HOR_MAX) | Maximum horizontal acceleration. | -| [MPC_VEL_MANUAL](../advanced_config/parameter_reference.md#MPC_VEL_MANUAL) | Maximum horizontal velocity. | -| [MPC_LAND_SPEED](../advanced_config/parameter_reference.md#MPC_LAND_SPEED) | Landing descend rate. Default 0.7 m/s. | +| Parameter | Description | +| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MAN_DEADZONE](../advanced_config/parameter_reference.md#MAN_DEADZONE) | Deadzone of sticks where position hold is enabled. Default: 0.1 (10% of full stick range). | +| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. | +| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. | +| [MPC_LAND_ALT1](../advanced_config/parameter_reference.md#MPC_LAND_ALT1) | Altitude for triggering first phase of slow landing. Below this altitude descending velocity gets limited to a value between [MPC_Z_VEL_MAX_DN](#MPC_Z_VEL_MAX_DN) (or `MPC_Z_V_AUTO_DN`) and [MPC_LAND_SPEED](#MPC_LAND_SPEED). Value needs to be higher than [MPC_LAND_ALT2](#MPC_LAND_ALT2). Default 10m. | +| [MPC_LAND_ALT2](../advanced_config/parameter_reference.md#MPC_LAND_ALT2) | Altitude for second phase of slow landing. Below this altitude descending velocity gets limited to [`MPC_LAND_SPEED`](#MPC_LAND_SPEED). Value needs to be lower than "MPC_LAND_ALT1". Default 5m. | +| `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. | +| [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Stick input to movement translation strategy. From PX4 v1.12 the default (`Acceleration based`) is that stick position controls acceleration (in a similar way to a car accelerator pedal). Other options allow stick deflection to directly control speed over ground, with and without smoothing and acceleration limits. | +| [MPC_ACC_HOR_MAX](../advanced_config/parameter_reference.md#MPC_ACC_HOR_MAX) | Maximum horizontal acceleration. | +| [MPC_VEL_MANUAL](../advanced_config/parameter_reference.md#MPC_VEL_MANUAL) | Maximum horizontal velocity. | +| [MPC_LAND_SPEED](../advanced_config/parameter_reference.md#MPC_LAND_SPEED) | Landing descend rate. Default 0.7 m/s. | ## Additional Information diff --git a/docs/en/flight_modes_rover/api.md b/docs/en/flight_modes_rover/api.md new file mode 100644 index 0000000000..828aacf879 --- /dev/null +++ b/docs/en/flight_modes_rover/api.md @@ -0,0 +1,29 @@ +# Apps & API + +The rover modules have been tested and integrated with a subset of the available [Apps & API](../middleware/index.md) methods. +We specifically provide guides for using [ROS 2](../ros2/index.md) to interface a companion computer with PX4 via [uXRCE-DDS](../middleware/uxrce_dds.md). + +| Method | Description | +| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| [PX4 ROS 2 Interface](#px4-ros-2-interface) (Recommended) | Register a custom mode and publish [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). | +| [ROS 2 Offboard Control](#ros-2-offboard-control) | Use the PX4 internal [Offboard Mode](../flight_modes/offboard.md) and publish messages defined in [dds_topics.yaml](../middleware/dds_topics.md). | + +## PX4 ROS 2 Interface + +We recommend the use of the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) which allows you to register a custom drive mode and exposes [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). + +By using these setpoints (instead of the PX4 internal rover setpoints), you are guaranteed to send valid control inputs to your vehicle and the control flags for the setpoints you are using are automatically set for you. +Registering a custom drive mode instead of using [ROS 2 Offboard Control](#ros-2-offboard-control) additionally provides the advantages listed [here](../concept/flight_modes.md#internal-vs-external-modes). + +To get familiar with this method, read through the guide for the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) where we also provide an example app for rover. + +## ROS 2 Offboard Control + +[ROS 2 Offboard Control](../ros2/offboard_control.md) uses the PX4 internal [Offboard Mode](../flight_modes/offboard.md). + +While you can subscribe/publish to all topics specified in [dds_topics.yaml](../middleware/dds_topics.md), not all rover modules support all of these topics (see [Supported Setpoints](../flight_modes/offboard.md#rover)). +Unlike the [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints) exposed through the [PX4 ROS 2 Interface](#px4-ros-2-interface), there is no guarantee that the published setpoints lead to a valid control input. + +In addition, the correct control mode flags must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md). +This requires a deeper understanding of PX4 and the structure of the rover modules. +For general information on setting up offboard mode read through [Offboard Mode](../flight_modes/offboard.md) and then consult [Supported Setpoints](../flight_modes/offboard.md#rover). diff --git a/docs/en/flight_modes_vtol/return.md b/docs/en/flight_modes_vtol/return.md index cfcccf68ae..46ec8ec1e4 100644 --- a/docs/en/flight_modes_vtol/return.md +++ b/docs/en/flight_modes_vtol/return.md @@ -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). diff --git a/docs/en/flight_stack/controller_diagrams.md b/docs/en/flight_stack/controller_diagrams.md index b5465d5072..2a63e7e6d7 100644 --- a/docs/en/flight_stack/controller_diagrams.md +++ b/docs/en/flight_stack/controller_diagrams.md @@ -13,24 +13,24 @@ The diagrams use the standard [PX4 notation](../contribute/notation.md) (and eac ![MC Controller Diagram](../../assets/diagrams/mc_control_arch.jpg) -* 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 ![MC Rate Control Diagram](../../assets/diagrams/mc_angular_rate_diagram.jpg) -* 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*) ![IMU pipeline](../../assets/diagrams/px4_imu_pipeline.png) ::: @@ -41,51 +41,51 @@ The diagrams use the standard [PX4 notation](../contribute/notation.md) (and eac ![MC Angle Control Diagram](../../assets/diagrams/mc_angle_diagram.jpg) -* 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 ![MC Velocity Control Diagram](../../assets/diagrams/mc_velocity_diagram.png) -* 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 ![MC Position Control Diagram](../../assets/diagrams/mc_position_diagram.png) -* 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 ![MC Position Controller Diagram](../../assets/diagrams/px4_mc_position_controller_diagram.png) -* 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. + ## 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 ![Energy loop](../../assets/diagrams/TECS_throttle.png) @@ -130,7 +129,6 @@ We use thrust to regulate the specific total energy of the vehicle and pitch mai - 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 ![VTOL Attitude Controller Diagram](../../assets/diagrams/VTOL_controller_diagram.png) @@ -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. diff --git a/docs/en/flying/first_flight_guidelines.md b/docs/en/flying/first_flight_guidelines.md index 2aa3fd4bac..7facee2cb7 100644 --- a/docs/en/flying/first_flight_guidelines.md +++ b/docs/en/flying/first_flight_guidelines.md @@ -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 diff --git a/docs/en/flying/missions.md b/docs/en/flying/missions.md index 607ca605f7..7817fa9a2a 100644 --- a/docs/en/flying/missions.md +++ b/docs/en/flying/missions.md @@ -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 diff --git a/docs/en/flying/package_delivery_mission.md b/docs/en/flying/package_delivery_mission.md index 3ff6f87874..9ad16c403c 100644 --- a/docs/en/flying/package_delivery_mission.md +++ b/docs/en/flying/package_delivery_mission.md @@ -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. ![Gripper action setting](../../assets/flying/qgc_mission_plan_gripper_action_setting.png) - - Set it to "Release" in order to release the package. - The gripper ID does not need to be set for now. diff --git a/docs/en/flying/plan_safety_points.md b/docs/en/flying/plan_safety_points.md index dfca1f4087..311517c2c7 100644 --- a/docs/en/flying/plan_safety_points.md +++ b/docs/en/flying/plan_safety_points.md @@ -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_. ![Safety Points](../../assets/qgc/plan/rally_point/rally_points.jpg) ## 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). diff --git a/docs/en/flying/terrain_following_holding.md b/docs/en/flying/terrain_following_holding.md index fb4cc842f6..6ce0f46bdc 100644 --- a/docs/en/flying/terrain_following_holding.md +++ b/docs/en/flying/terrain_following_holding.md @@ -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). ::: ## 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`. - ## 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. ::: diff --git a/docs/en/frames_plane/index.md b/docs/en/frames_plane/index.md index ccbdc9547a..6108b190f3 100644 --- a/docs/en/frames_plane/index.md +++ b/docs/en/frames_plane/index.md @@ -22,7 +22,6 @@ The linked sections instructions for assembling and configuring fixed-wing frame ## Videos - --- diff --git a/docs/en/frames_rover/index.md b/docs/en/frames_rover/index.md index e805e1334b..f897cf6275 100644 --- a/docs/en/frames_rover/index.md +++ b/docs/en/frames_rover/index.md @@ -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). +::: + ![Rovers](../../assets/airframes/rover/rovers.png) - 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). @@ -57,15 +62,17 @@ Each wheel is driven by its own motor, and by controlling the speed and directio ## See Also -- [Drive Modes](../flight_modes_rover/index.md). +- [Drive Modes](../flight_modes_rover/index.md) - [Configuration/Tuning](../config_rover/index.md) +- [Apps & API](../flight_modes_rover/api.md) - [Complete Vehicles](../complete_vehicles_rover/index.md) ## Simulation -[Gazebo](../sim_gazebo_gz/index.md) provides simulations for ackermann and differential rovers: +PX4 provides synthetic simulation models for [Gazebo](../sim_gazebo_gz/index.md) of all three rover types to test the software and validate changes and new features: - [Ackermann rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) - [Differential rover](../sim_gazebo_gz/vehicles.md#differential-rover) +- [Mecanum rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) ![Rover gazebo simulation](../../assets/airframes/rover/rover_simulation.png) diff --git a/docs/en/frames_vtol/standardvtol.md b/docs/en/frames_vtol/standardvtol.md index f6fab32ad4..d244912c52 100644 --- a/docs/en/frames_vtol/standardvtol.md +++ b/docs/en/frames_vtol/standardvtol.md @@ -4,9 +4,7 @@ A **Standard VTOL** is a [VTOL](../frames_vtol/index.md) that has _completely se ![Vertical Technologies: Deltaquad QuadPlane VTOL](../../assets/airframes/vtol/vertical_technologies_deltaquad/hero_small.png) -*Vertical Technologies: Deltaquad QuadPlane VTOL* - - +_Vertical Technologies: Deltaquad QuadPlane VTOL_ ## Videos diff --git a/docs/en/frames_vtol/tailsitter.md b/docs/en/frames_vtol/tailsitter.md index 7a393f3720..cddc2bfb1e 100644 --- a/docs/en/frames_vtol/tailsitter.md +++ b/docs/en/frames_vtol/tailsitter.md @@ -86,7 +86,6 @@ This section contains videos that are specific to Tailsitter VTOL (videos that a - ## Gallery
diff --git a/docs/en/frames_vtol/tiltrotor.md b/docs/en/frames_vtol/tiltrotor.md index 320e23a598..c3ba16af08 100644 --- a/docs/en/frames_vtol/tiltrotor.md +++ b/docs/en/frames_vtol/tiltrotor.md @@ -4,7 +4,6 @@ A **Tiltrotor VTOL** is a [VTOL](../frames_vtol/index.md) vehicle that has rotor ![Horizon Hobby E-flite Convergence](../../assets/airframes/vtol/eflite_convergence_pixfalcon/hero.jpg) - ## Builds - [Convergence Tiltrotor](../frames_vtol/vtol_tiltrotor_eflite_convergence_pixfalcon.md) diff --git a/docs/en/frames_vtol/vtol_tiltrotor_eflite_convergence_pixfalcon.md b/docs/en/frames_vtol/vtol_tiltrotor_eflite_convergence_pixfalcon.md index 4d81aa8625..36ea66ad45 100644 --- a/docs/en/frames_vtol/vtol_tiltrotor_eflite_convergence_pixfalcon.md +++ b/docs/en/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. ::: - ## 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 - ### 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 ![Mount GPS](../../assets/airframes/vtol/eflite_convergence_pixfalcon/eflight_convergence_gps_mounting.jpg) - ## 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_. ![QGroundControl Vehicle Setting - Airframe selection E-Flight](../../assets/airframes/vtol/eflite_convergence_pixfalcon/qgc_setup_airframe.jpg) - [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. diff --git a/docs/en/getting_started/flight_controller_selection.md b/docs/en/getting_started/flight_controller_selection.md index 92c300957d..04a27a42f2 100644 --- a/docs/en/getting_started/flight_controller_selection.md +++ b/docs/en/getting_started/flight_controller_selection.md @@ -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). diff --git a/docs/en/getting_started/led_meanings.md b/docs/en/getting_started/led_meanings.md index cdc86d5cbb..2e6e57e5e4 100644 --- a/docs/en/getting_started/led_meanings.md +++ b/docs/en/getting_started/led_meanings.md @@ -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. ::: ![LED meanings](../../assets/flight_controller/pixhawk_led_meanings.gif) +- **[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. ## 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. ![Pixhawk 4](../../assets/flight_controller/pixhawk4/pixhawk4_status_leds.jpg) @@ -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 | diff --git a/docs/en/getting_started/tunes.md b/docs/en/getting_started/tunes.md index 15bc693b53..4615c101b1 100644 --- a/docs/en/getting_started/tunes.md +++ b/docs/en/getting_started/tunes.md @@ -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. - + #### Startup Tone + - microSD card successfully mounted (during boot). @@ -26,36 +26,37 @@ These tunes are played during the boot sequence. #### 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 + -- Formatting microSD card. +- Formatting microSD card. - Mounting failed (if formatting succeeds boot sequence will try to mount again). - No microSD card. - #### Format Failed + - Formatting microSD card failed (following previous attempt to mount card). - -#### Program PX4IO +#### Program PX4IO + - Starting to program PX4IO. @@ -63,6 +64,7 @@ These tunes are played during the boot sequence. #### Program PX4IO Success + - PX4IO programming succeeded. @@ -70,21 +72,23 @@ These tunes are played during the boot sequence. #### Program PX4IO Fail + - PX4IO programming failed. - PX4IO couldn't start. - AUX Mixer not found. - ## Operational These tones/tunes are emitted during normal operation. + #### Error Tune + - RC Loss @@ -92,6 +96,7 @@ These tones/tunes are emitted during normal operation. #### Notify Positive Tone + - Calibration succeeded. @@ -102,6 +107,7 @@ These tones/tunes are emitted during normal operation. #### Notify Neutral Tone + - Mission is valid and has no warnings. @@ -111,6 +117,7 @@ These tones/tunes are emitted during normal operation. #### Notify Negative Tone + - Calibration failed. @@ -123,6 +130,7 @@ These tones/tunes are emitted during normal operation. #### Arming Warning + - Vehicle is now armed. @@ -130,6 +138,7 @@ These tones/tunes are emitted during normal operation. #### Arming Failure Tune + - Arming failed @@ -137,6 +146,7 @@ These tones/tunes are emitted during normal operation. #### 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 + - Critical low battery warning ([failsafe](../config/safety.md#battery-level-failsafe)). - #### GPS Warning Slow + #### Parachute Release + - Parachute release triggered. - #### Single Beep + - Magnetometer/Compass calibration: Notify user to start rotating vehicle. @@ -172,6 +184,7 @@ These tones/tunes are emitted during normal operation. #### Home Set Tune + - Home position initialised (first time only). diff --git a/docs/en/getting_started/vehicle_status.md b/docs/en/getting_started/vehicle_status.md index 9fed271f74..b77083e876 100644 --- a/docs/en/getting_started/vehicle_status.md +++ b/docs/en/getting_started/vehicle_status.md @@ -7,6 +7,6 @@ In addition, PX4 provides more fine-grained information about readiness to fly i The LED, tune, and GCS notifications are linked below: -* [LED Meanings](../getting_started/led_meanings.md) -* [Tune/Sound Meanings](../getting_started/tunes.md) -* [QGroundControl Flight-Readiness Status](../flying/pre_flight_checks.md) +- [LED Meanings](../getting_started/led_meanings.md) +- [Tune/Sound Meanings](../getting_started/tunes.md) +- [QGroundControl Flight-Readiness Status](../flying/pre_flight_checks.md) diff --git a/docs/en/gps_compass/ark_dan_gps.md b/docs/en/gps_compass/ark_dan_gps.md new file mode 100644 index 0000000000..78cfd19a95 --- /dev/null +++ b/docs/en/gps_compass/ark_dan_gps.md @@ -0,0 +1,62 @@ +# ARK DAN GPS + +[ARK DAN GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox DAN-F10N GPS and industrial magnetometer. + +![ARK DAN GPS](../../assets/hardware/gps/ark/ark_dan_gps.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dan-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DAN_GPS) +- Sensors + - [u-blox DAN-F10N](https://www.u-blox.com/en/product/dan-f10n-module) + - L1/L5/E5a/B2a bands + - Consistently strong performance regardless of installation + - Integrated SAW-LNA-SAW for exceptional out-of-band jamming immunity + - u-blox F10 proprietary dual-band multipath mitigation technology + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 25mA Average + - 44mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## Hardware setup + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 Configuration + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## Pinout + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Voltage | +| ---------- | ----------- | ------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## See Also + +- [ARK DAN GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) (ARK Docs) diff --git a/docs/en/gps_compass/ark_sam_gps.md b/docs/en/gps_compass/ark_sam_gps.md index 8a6d11c21a..49a864458e 100644 --- a/docs/en/gps_compass/ark_sam_gps.md +++ b/docs/en/gps_compass/ark_sam_gps.md @@ -1,6 +1,6 @@ # ARK SAM GPS -[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps>) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. +[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. ![ARK SAM GPS](../../assets/hardware/gps/ark/ark_sam_gps.jpg) @@ -33,7 +33,7 @@ Order this module from: ## Hardware setup The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. -It should be mounted front facing, as far away from the flight controller and other electronics as possible. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). diff --git a/docs/en/gps_compass/ark_sam_gps_mini.md b/docs/en/gps_compass/ark_sam_gps_mini.md new file mode 100644 index 0000000000..3c124c07fe --- /dev/null +++ b/docs/en/gps_compass/ark_sam_gps_mini.md @@ -0,0 +1,61 @@ +# ARK SAM GPS MINI + +[ARK SAM GPS MINI](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. + +![ARK SAM GPS MINI](../../assets/hardware/gps/ark/ark_sam_gps_mini.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-sam-gps-mini/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_SAM_GPS/tree/main) +- Sensors + - [u-blox SAM-M10Q](https://www.u-blox.com/en/product/sam-m10q-module) + - Less than 38 mW power consumption without compromising GNSS performance + - Maximum position availability with 4 concurrent GNSS reception + - Advanced spoofing and jamming detection + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 15mA Average + - 20mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## Hardware setup + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 Configuration + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## Pinout + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Voltage | +| ---------- | ----------- | ------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## See Also + +- [ARK SAM GPS MINI Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) (ARK Docs) diff --git a/docs/en/gps_compass/index.md b/docs/en/gps_compass/index.md index dbd9514aec..60b22b9558 100644 --- a/docs/en/gps_compass/index.md +++ b/docs/en/gps_compass/index.md @@ -25,7 +25,9 @@ These have been tested by the PX4 dev team, or which are popular within the PX4 | Device | GPS | Compass | [CAN](../dronecan/index.md) | Buzzer / SafeSw / LED | Notes | | :----------------------------------------------------------- | :---------: | :-----------------------: | :-------------------------: | :-------------------: | :-------------------------- | | [ARK GPS](../dronecan/ark_gps.md) | M9N | BMM150 | ✓ | ✓ | + Baro, IMU | +| [ARK DAN GPS](../gps_compass/ark_dan_gps.md) | DAN-F10N | IIS2MDC | | ✓ | | | [ARK SAM GPS](../gps_compass/ark_sam_gps.md) | SAM-M10Q | IIS2MDC | | ✓ | | +| [ARK SAM GPS MINI ](../gps_compass/ark_sam_gps_mini.md) | SAM-M10Q | IIS2MDC | | ✓ | | | [ARK TESEO GPS](../dronecan/ark_teseo_gps.md) | Teseo-LIV4F | BMM150 | ✓ | ✓ | + Baro, IMU | | [Avionics Anonymous UAVCAN GNSS/Mag][avionics_anon_can_gnss] | SAM-M8Q | MMC5983MA | ✓ | ✘ | | | [CUAV NEO 3 GPS](../gps_compass/gps_cuav_neo_3.md) | M9N | IST8310 | | ✓ | | @@ -196,11 +198,21 @@ It is possible to have low DOP (good satellite geometry) but still have high EPH EPH/EPV values therefore provide a more immediate and practical estimate of the actual GPS accuracy you can expect under current conditions. +### GNSS Position Fusion + +GNSS position fusion will not begin until yaw alignment is established. +If a magnetometer is available, the EKF aligns yaw using the magnetic heading, allowing GPS position fusion to start soon after boot. +If no magnetometer is present, the system must rely on GPS yaw (from a dual-antenna setup) or movement-based yaw estimation. +Until one of these provides a valid heading, the EKF will not start GPS position fusion, and the vehicle will remain in a “no position” state even though attitude data is valid. +This behavior prevents large position errors that could occur when the yaw reference is uncertain. + ## Developer Information - GPS/RTK-GPS - [RTK-GPS](../advanced/rtk_gps.md) + - [PPS Time Synchronization](../advanced/pps_time_sync.md) - [GPS driver](../modules/modules_driver.md#gps) + - [PPS driver](../modules/modules_driver.md#pps-capture) - [DroneCAN Example](../dronecan/index.md) - Compass - [Driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/magnetometer) (Compasses) diff --git a/docs/en/gps_compass/magnetometer.md b/docs/en/gps_compass/magnetometer.md index 083985f9d3..2e6ce4f524 100644 --- a/docs/en/gps_compass/magnetometer.md +++ b/docs/en/gps_compass/magnetometer.md @@ -40,6 +40,7 @@ This list contains stand-alone magnetometer modules (without GNSS). | Device | Compass | DroneCan | | :--------------------------------------------------------------------------------------------------------------- | :-----: | :------: | +| [ARK MAG](https://arkelectron.com/product/ark-mag/) | RM3100 | ✓ | | [Avionics Anonymous UAVCAN Magnetometer](https://www.tindie.com/products/avionicsanonymous/uavcan-magnetometer/) | ? | | | [Holybro DroneCAN RM3100 Compass/Magnetometer](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | | [RaccoonLab DroneCAN/Cyphal Magnetometer RM3100](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | diff --git a/docs/en/gps_compass/rtk_gps.md b/docs/en/gps_compass/rtk_gps.md index fcaea1c01b..9b12190bdc 100644 --- a/docs/en/gps_compass/rtk_gps.md +++ b/docs/en/gps_compass/rtk_gps.md @@ -20,50 +20,59 @@ The RTK compatible devices below that are expected to work with PX4 (it omits di The table indicates devices that also output yaw, and that can provide yaw when two on-vehicle units are used. It also highlights devices that connect via the CAN bus, and those which support PPK (Post-Processing Kinematic). -| Device | GPS | Compass | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :-------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :------: | :------------------------------: | :-----------------------------------------------: | :-: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| Device | GPS | Compass | [DroneCAN] | [GPS Yaw] | PPK | +| :-------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :--------: | :---------------------------------: | :-: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK Notes: @@ -203,7 +212,7 @@ This should be enabled by default on recent builds. To ensure MAVLink2 is used: - Update the telemetry module firmware to the latest version (see [QGroundControl > Setup > Firmware](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/firmware.html)). -- Set [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) +- Ensure [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) is set to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) #### Tuning diff --git a/docs/en/index.md b/docs/en/index.md index 047ff55c45..f361486948 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,101 +1,63 @@ -
+ # PX4 Autopilot User Guide [![Releases](https://img.shields.io/badge/release-main-blue.svg)](https://github.com/PX4/PX4-Autopilot/releases) [![Discuss](https://img.shields.io/badge/discuss-px4-ff69b4.svg)](https://discuss.px4.io//) [![Discord](https://discordapp.com/api/guilds/1022170275984457759/widget.png?style=shield)](https://discord.gg/dronecode) -PX4 is the _Professional Autopilot_. -Developed by world-class developers from industry and academia, and supported by an active world wide community, it powers all kinds of vehicles from racing and cargo drones through to ground vehicles and submersibles. +PX4 is an open-source autopilot for drones and autonomous vehicles. It runs on multirotors, fixed-wing, VTOL, helicopters, rovers, and more. This guide covers everything from assembly and configuration to flight operations and development. -:::tip -This guide contains everything you need to assemble, configure, and safely fly a PX4-based vehicle. Interested in contributing? Check out the [Development](development/development.md) section. - -::: +
:::warning + This guide is for the _development_ version of PX4 (`main` branch). Use the **Version** selector to find the current _stable_ version. Documented changes since the stable release are captured in the evolving [release note](releases/main.md). ::: -## How Do I Get Started? +
-[Basic Concepts](getting_started/px4_basic_concepts.md) should be read by all users! -It provides an overview of PX4, including features provided by the flight stack (flight modes and safety features) and the supported hardware (flight controller, vehicle types, telemetry systems, RC control systems). +## For Developers -Depending on what you want to achieve, the following tips will help you navigate through this guide: +:::tip +Building on PX4 or extending the platform? Start here: [Development Guide](development/development.md). Set up your [dev environment](dev_setup/config_initial.md), [build from source](dev_setup/building_px4.md), run [SITL simulation](simulation/index.md), or integrate via [ROS 2](ros2/index.md) and [MAVSDK](https://mavsdk.mavlink.io/). +::: -### I want a vehicle that works with PX4 +## Getting Started -In the [Multicopter](frames_multicopter/index.md), [VTOL](frames_vtol/index.md), and [Plane (Fixed-Wing)](frames_plane/index.md) sections you'll find topics like the following (these links are for multicopter): +Start with [Basic Concepts](getting_started/px4_basic_concepts.md) for an overview of the flight stack, flight modes, safety features, and supported hardware. -- [Complete Vehicles](complete_vehicles_mc/index.md) list "Ready to Fly" (RTF) pre-built vehicles -- [Kits](frames_multicopter/kits.md) lists drones that you have to build yourself from a set of preselected parts -- [DIY Builds](frames_multicopter/diy_builds.md) shows some examples of drones that have been built using parts that were sourced individually +## Build a Vehicle -Both kits and complete vehicles usually include everything you need except for a battery and RC System. -Kits are usually not hard to build, provide a good introduction to how drones fit together, and are relatively inexpensive. -We provide generic instructions for assembly, such as [Assembling a Multicopter](assembly/assembly_mc.md), and most kits come with specific instructions too. +Pick your frame type: [Multicopter](frames_multicopter/index.md), [Fixed-Wing](frames_plane/index.md), [VTOL](frames_vtol/index.md), [Helicopter](frames_helicopter/index.md), or [Rover](frames_rover/index.md). Each section covers complete vehicles, kits, and DIY builds. For assembly instructions see [Assembling a Multicopter](assembly/assembly_mc.md) or the equivalent for your frame. -If the kits and complete drones aren't quite right for you then you can build a vehicle from scratch, but this requires more knowledge. -[Airframe Builds](airframes/index.md) lists the supported frame starting points to give you some idea of what is possible. +## Configure and Tune -Once you have a vehicle that supports PX4 you will need to configure it and calibrate the sensors. -Each vehicle type has its own configuration section that explains the main steps, such as [Multicopter Configuration/Tuning](config_mc/index.md). +Once assembled, follow the configuration guide for your vehicle type (e.g. [Multicopter Configuration](config_mc/index.md)). This covers sensor calibration, flight mode setup, and tuning. -### I want to add a payload/camera +## Hardware -The [Payloads](payloads/index.md) section describes how to add a camera and how to configure PX4 to enable you to deliver packages. +The [Hardware Selection & Setup](hardware/drone_parts.md) section covers flight controllers, sensors, telemetry, RC systems, and payloads. See [Payloads](payloads/index.md) for camera and delivery integrations. -### I am modifying a supported vehicle +## Fly -The [Hardware Selection & Setup](hardware/drone_parts.md) section provides both high level and product-specific information about hardware that you might use with PX4 and its configuration. -This is the first place you should look if you want to modify a drone and add new components. +Read [Operations](config/operations.md) to understand safety features and failsafe behavior before your first flight. Then see [Basic Flying (Multicopter)](flying/basic_flying_mc.md) or the equivalent for your frame type. -### I want to fly +## Support -Before you fly you should read [Operations](config/operations.md) to understand how to set up the safety features of your vehicle and the common behaviours of all frame types. -Once you've done that you're ready to fly. - -Basic instructions for flying each vehicle type are provided in the respective sections, such as [Basic Flying (Multicopter)](flying/basic_flying_mc.md). - -### I want to run PX4 on a new Flight Controller and extend the platform - -The [Development](development/development.md) section explains how to support new airframes and types of vehicles, modify flight algorithms, add new modes, integrate new hardware, communicate with PX4 from outside the flight controller, and contribute to PX4. - -## Getting Help - -The [Support](contribute/support.md) page explains how to get help from the core dev team and the wider community. - -Among other things it covers: - -- [Forums where you can get help](contribute/support.md#forums-and-chat) -- [Diagnosing issues](contribute/support.md#diagnosing-problems) -- [How to report bugs](contribute/support.md#issue-bug-reporting) -- [Weekly dev call](contribute/support.md#weekly-dev-call) - -## Reporting Bugs & Issues - -If you have any problems using PX4 first post them on the [support forums](contribute/support.md#forums-and-chat) (as they may be caused by vehicle configuration). - -If directed by the development team, code issues may be raised on [Github here](https://github.com/PX4/PX4-Autopilot/issues). -Where possible provide [flight logs](getting_started/flight_reporting.md) and other information requested in the issue template. +Get help on the [discussion forums](https://discuss.px4.io/) or [Discord](https://discord.gg/dronecode). See the [Support](contribute/support.md) page for diagnosing problems, reporting bugs, and joining the [weekly dev call](contribute/dev_call.md). ## Contributing -Information on how to contribute to code and documentation can be found in the [Contributing](contribute/index.md) section: - -- [Code](contribute/index.md) -- [Documentation](contribute/docs.md) -- [Translation](contribute/translation.md) +See the [Contributing](contribute/index.md) section for code, [documentation](contribute/docs.md), and [translation](contribute/translation.md) guidelines. ## Translations -There are several [translations](contribute/translation.md) of this guide. -You can access these from the Languages menu (top right): - -![Language Selector](../assets/vuepress/language_selector.png) +There are several [translations](contribute/translation.md) of this guide. Use the language selector in the top navigation. @@ -131,9 +93,9 @@ The following icons used in this library are licensed separately (as shown below ## Governance -The PX4 flight stack is hosted under the governance of the [Dronecode Project](https://dronecode.org/). +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](https://opensource.org/license/BSD-3-Clause) license, so you are free to use, modify, and distribute it in your own projects. -Dronecode Logo +Dronecode Logo Linux Foundation Logo
 
diff --git a/docs/en/log/flight_log_analysis.md b/docs/en/log/flight_log_analysis.md index 2abf0f4564..88073f60c2 100644 --- a/docs/en/log/flight_log_analysis.md +++ b/docs/en/log/flight_log_analysis.md @@ -41,6 +41,23 @@ Key features: See [Log Analysis using Flight Review](../log/flight_review.md) for an introduction. +### Foxglove + +[Foxglove](https://foxglove.dev/) is a purpose-built robotics observation platform that works natively with ULog. +It allows you to replay your flights and seek through the timeline to find data of interest. + +Key features: + +- Native support for ULog files — open files by dragging and dropping or using the file dialog. +- Multiple visualization panels, including Raw Messages, Plot, 3D, and Map panels. +- [PX4 Converter extension](https://github.com/foxglove/px4_converter) that translates selected uORB messages and creates Foxglove schemas for enhanced visualizations. +- Save and share custom layouts with panels and their settings. +- Cross-platform desktop application (Windows, macOS, Linux). + +See [Foxglove PX4 Docs](https://docs.foxglove.dev/docs/getting-started/frameworks/px4) for more detailed information and instructions. + +![Foxglove](../../assets/flight_log_analysis/foxglove/foxglove_px4.png) + ### PlotJuggler [PlotJuggler](https://github.com/facontidavide/PlotJuggler) is a desktop application that allows users to easily visualize and analyze data expressed in the form of time series. diff --git a/docs/en/log/flight_review.md b/docs/en/log/flight_review.md index a9e8ccd318..49d2d5c240 100644 --- a/docs/en/log/flight_review.md +++ b/docs/en/log/flight_review.md @@ -36,6 +36,7 @@ For the rate controller in particular, it is useful to enable the high-rate logg Vibration is one of the most common problems for multirotor vehicles. High vibration levels can lead to: + - less efficient flight and reduced flight time - the motors can heat up - increased material wearout @@ -45,7 +46,7 @@ High vibration levels can lead to: It is therefore important to keep an eye on the vibration levels and improve the setup if needed. -There is a point where vibration levels are clearly too high, and generally lower vibration levels are better. +There is a point where vibration levels are clearly too high, and generally lower vibration levels are better. However there is a broad range between 'everything is ok' and 'the levels are too high'. This range depends on a number of factors, including vehicle size - as larger vehicles have higher inertia, allowing for more software filtering (at the same time the vibrations on larger vehicles are of lower frequency). @@ -61,7 +62,7 @@ It is worth looking at multiple charts when analyzing vibration (different chart You need to enable the high-rate logging profile ([SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE)) to see this plot. ::: -This graph shows a frequency plot for the roll, pitch and yaw axis based on the actuator controls signal (the PID output from the rate controller). +This graph shows a frequency plot for the roll, pitch and yaw axis based on the actuator controls signal (the PID output from the rate controller). It helps to identify frequency peaks and configuring the software filters. There should only be a single peak at the lowest end (below around 20 Hz), the rest should be low and flat. @@ -96,7 +97,6 @@ This example shows a peak in frequency close to 50 Hz (in this case due to "loos ![Vibrations in landing gear - FFT plot](../../assets/flight_log_analysis/flight_review/vibrations_landing_gear_actuator_controls_fft.png) - ### Acceleration Power Spectral Density This is a 2D frequency plot showing the frequency response of the raw accelerometer data over time (it displays the sum for the x, y and z axis). @@ -104,12 +104,12 @@ The more yellow an area is, the higher the frequency response at that time and f Ideally only the lowest part up to a few Hz is yellow, and the rest is mostly green or blue. - #### Examples: Good Vibration [QAV-R 5" Racer](../frames_multicopter/qav_r_5_kiss_esc_racer.md) frame (excellent vibration). ![Low vibration QAV-R 5 Racer - spectral density plot](../../assets/flight_log_analysis/flight_review/vibrations_good_spectral.png) + DJI F450 frame (good vibration). @@ -122,7 +122,6 @@ Above you can see the blade passing frequency of the propellers at around 100 Hz S500 frame: ![Vibration S500 - spectral density plot](../../assets/flight_log_analysis/flight_review/vibrations_s500_spectral.png) - #### Examples: Bad Vibration The strong yellow lines at around 100Hz indicate a potential issue that requires further investigation (starting with a review of the other charts). @@ -138,7 +137,6 @@ With the default filter settings of 80 Hz vibrations at 50 Hz will not be filter ![Vibrations in landing gear - spectral density plot](../../assets/flight_log_analysis/flight_review/vibrations_landing_gear_spectral.png) - Extremely high (unsafe) vibration! Note that the graph is almost completely yellow. :::warning @@ -147,13 +145,12 @@ You should not fly with such high vibration levels. ![Exceedingly high vibration in spectral density plot](../../assets/flight_log_analysis/flight_review/vibrations_exceedingly_high_spectral.png) - ### Raw Acceleration -This graph shows the raw accelerometer measurements for the x, y and z axis. +This graph shows the raw accelerometer measurements for the x, y and z axis. Ideally each line is thin and clearly shows the vehicle's accelerations. -As a rule of thumb if the z-axis graph is touching the x/y-axis graph during hover or slow flight, the vibration levels are too high. +As a rule of thumb if the z-axis graph is touching the x/y-axis graph during hover or slow flight, the vibration levels are too high. :::tip The best way to use this graph is to zoom in a bit to a part where the vehicle is hovering. @@ -170,7 +167,6 @@ DJI F450 frame (good vibration). - #### Examples: Bad Vibration @@ -179,18 +175,15 @@ This is at the limit where it starts to negatively affect flight performance. ![Borderline vibration S500 x, y - raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_s500_accel.png) - Vibration too high. Note how the graph of the z-axis overlaps with the x/y-axis graph: ![Vibrations in landing gear - raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_landing_gear_accel.png) - Vibration levels are too high. Note how the graph of the z-axis overlaps with the x/y-axis graph: ![High vibration in raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_too_high_accel.png) - -Very high (unsafe) vibration levels. +Very high (unsafe) vibration levels. :::warning You should not fly with such high vibration levels. @@ -198,7 +191,6 @@ You should not fly with such high vibration levels. ![Exceedingly high vibration in raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_exceedingly_high_accel.png) - ### Raw High-rate IMU Data Plots @@ -207,16 +199,17 @@ For an in-depth analysis there is an option to log the raw IMU data at full rate This allows inspection of much higher frequencies than with normal logging, which can help when selecting vibration mounts or configuring low-pass and notch filters appropriately. To use it, some parameters need to be changed: + - Set [IMU_GYRO_RATEMAX](../advanced_config/parameter_reference.md#IMU_GYRO_RATEMAX) to 400. - This ensures that the raw sensor data is more efficiently packed when sent from the sensor to the rest of the system, and reduces the log size (without reducing useful data). + This ensures that the raw sensor data is more efficiently packed when sent from the sensor to the rest of the system, and reduces the log size (without reducing useful data). - Use a good SD card, as the IMU data requires a high logging bandwidth (Flight Review will show dropouts if the logging rate gets too high). - + :::tip See [Logging > SD Cards](../dev_log/logging.md#sd-cards) for a comparison of popular SD card. ::: - + - Enable either the gyro or accel high-rate FIFO profile in [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) and disable the rest of the entries. If you are using a really good SD card (seeing few/no dropouts), you can: - either enable both accel and gyro profiles @@ -244,17 +237,16 @@ Often a source of vibration (or combination of multiple sources) cannot be ident In this case the vehicle should be inspected. [Vibration Isolation](../assembly/vibration_isolation.md) explains some basic things you can check (and do) to reduce vibration levels. - - ## Actuator Outputs -The *Actuator Outputs* graph shows the signals that are sent to the individual actuators (motors/servos). +The _Actuator Outputs_ graph shows the signals that are sent to the individual actuators (motors/servos). Generally it is in the range between the minimum and maximum configured PWM values (e.g. from 1000 to 2000). This is an example for a quadrotor where everything is OK (all of the signals are within the range, approximately overlap each other, and are not too noisy): ![Good actuator outputs](../../assets/flight_log_analysis/flight_review/actuator_outputs_good.png) The plot can help to identify different problems: + - If one or more of the signals is at the maximum over a longer time, it means the controller runs into **saturation**. It is not necessarily a problem, for example when flying at full throttle this is expected. But if it happens for example during a mission, it's an indication that the vehicle is overweight for the amount of thrust that it can provide. @@ -270,20 +262,20 @@ The plot can help to identify different problems: This is an example from a hexarotor: motors 1, 3 and 6 run at higher thrust: ![Hexrotor imbalanced actuator outputs](../../assets/flight_log_analysis/flight_review/actuator_outputs_hex_imbalanced.png) + - If the signals look very **noisy** (with high amplitudes), it can have two causes: sensor noise or vibrations passing through the controller (this shows up in other plots as well, see previous section) or too high PID gains. This is an extreme example: ![Noisy actuator outputs - extreme case](../../assets/flight_log_analysis/flight_review/actuator_outputs_noisy.png) - ## GPS Uncertainty -The *GPS Uncertainty* plot shows information from the GPS device: +The _GPS Uncertainty_ plot shows information from the GPS device: + - Number of used satellites (should be around 12 or higher) - Horizontal position accuracy (should be below 1 meter) - Vertical position accuracy (should be below 2 meters) - GPS fix: this is 3 for a 3D GPS fix, 4 for GPS + Dead Reckoning, 5 for RTK float and 6 for RTK fixed type - ## GPS Noise & Jamming The GPS Noise & Jamming plot is useful to check for GPS signal interferences and jamming. @@ -301,21 +293,21 @@ This is an example without any interference: ![GPS jamming - good plot](../../assets/flight_log_analysis/flight_review/gps_jamming_good.png) - ## Thrust and Magnetic Field -The *Thrust and Magnetic Field* plot shows the thrust and the norm of the magnetic sensor measurement vector. +The _Thrust and Magnetic Field_ plot shows the thrust and the norm of the magnetic sensor measurement vector. The norm should be constant over the whole flight and uncorrelated with the thrust. This is a good example where the norm is very close to constant: ![Thrust and mag close to constant](../../assets/flight_log_analysis/flight_review/thrust_and_mag_good.png) -*If it is correlated*, it means that the current drawn by the motors (or other consumers) is influencing the magnetic field. +_If it is correlated_, it means that the current drawn by the motors (or other consumers) is influencing the magnetic field. This must be avoided as it leads to incorrect yaw estimation. The following plot shows a strong correlation between the thrust and the norm of the magnetometer: ![Correlated thrust and mag](../../assets/flight_log_analysis/flight_review/thrust_and_mag_correlated.png) Solutions to this are: + - Use an external magnetometer (avoid using the internal magnetometer) - If using an external magnetometer, move it further away from strong currents (i.e. by using a (longer) GPS mast). @@ -325,10 +317,9 @@ However it could also be due to external disturbances (for example when flying c This example shows that the norm is non-constant, but it does not correlate with the thrust: ![Uncorrelated thrust and mag](../../assets/flight_log_analysis/flight_review/thrust_and_mag_uncorrelated_problem.png) - ## Estimator Watchdog -The *Estimator Watchdog* plot shows the health report of the estimator. +The _Estimator Watchdog_ plot shows the health report of the estimator. It should be constant zero. This is what it should look like if there are no problems: @@ -337,12 +328,12 @@ This is what it should look like if there are no problems: If one of the flags is non-zero, the estimator detected a problem that needs to be further investigated. Most of the time it is an issue with a sensor, for example magnetometer interferences. It usually helps to look at the plots of the corresponding sensor. + Here is an example with magnetometer problems: ![Estimator watchdog with magnetometer problems](../../assets/flight_log_analysis/flight_review/estimator_watchdog_mag_problem.png) - ## Sampling Regularity of Sensor Data The sampling regularity plot provides insights into problems with the logging system and scheduling. @@ -373,14 +364,13 @@ The following example contains too many dropouts, the quality of the used SD car ## Logged Messages -This is a table with system error and warning messages. +This is a table with system error and warning messages. For example they show when a task becomes low on stack size. The messages need to be examined individually, and not all of them indicate a problem. For example the following shows a kill-switch test: ![Logged Messages](../../assets/flight_log_analysis/flight_review/logged_messages.png) - ## Flight/Frame Log Review Examples It is often worth looking at multiple charts for a particular flight when analyzing vehicle condition (different charts can better highlight some issues). @@ -391,9 +381,11 @@ The section below groups a few (previously presented) charts by flight/vehicle. ### QAV-R 5" Racer These charts are all from the same flight of a [QAV-R 5" Racer](../frames_multicopter/qav_r_5_kiss_esc_racer.md). + They show a vehicle that has very low vibration: + - Actuator Controls FFT shows only a single peak at the lowest end, with the rest low and flat. - Spectral density is mostly green, with only a little yellow at the low frequencies. - Raw Acceleration has z-axis trace well separated from the x/y-axis traces. @@ -404,14 +396,15 @@ They show a vehicle that has very low vibration: ![Low vibration QAV-R 5 Racer - raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_good_accel.png) - ### DJI F450 -These charts are all from the same flight of a *DJI F450*. +These charts are all from the same flight of a _DJI F450_. + They show a vehicle that has low vibration (but not as low as the QAV-R above!): -- Actuator Controls FFT shows a peak at the lowest end. + +- Actuator Controls FFT shows a peak at the lowest end. Most of the rest is flat, except for a bump at around 100Hz (this is the blade passing frequency of the propellers). - Spectral density is mostly green. The blade passing frequency is again visible. - Raw Acceleration has z-axis trace well separated from the x/y-axis traces. @@ -422,16 +415,16 @@ They show a vehicle that has low vibration (but not as low as the QAV-R above!): ![Low vibration DJI F450 - raw accel. plot](../../assets/flight_log_analysis/flight_review/vibrations_f450_accel.png) - ### S500 These charts are all from the same flight of an S500. They show a vehicle that has borderline-acceptable vibration: -- Actuator Controls FFT shows a peak at the lowest end. + +- Actuator Controls FFT shows a peak at the lowest end. Most of the rest is flat, except for a bump at around 100Hz. - Spectral density is mostly green, but more yellow than for the DJI F450 at 100Hz. -- Raw Acceleration has z-axis trace fairly close to the x/y-axis traces. +- Raw Acceleration has z-axis trace fairly close to the x/y-axis traces. This is at the limit where it starts to negatively affect flight performance. ![Low vibration S500 actuator controls - FFT plot](../../assets/flight_log_analysis/flight_review/vibrations_s500_actuator_controls_fft.png) diff --git a/docs/en/log/plotjuggler_log_analysis.md b/docs/en/log/plotjuggler_log_analysis.md index be9b0be76f..25cd7ce6eb 100644 --- a/docs/en/log/plotjuggler_log_analysis.md +++ b/docs/en/log/plotjuggler_log_analysis.md @@ -66,17 +66,17 @@ This shows the position / velocity relationship described above in detail. ::: info Try out the boat testing log analysis yourself by downloading the ULog and Layout file used above! + - [Boat testing ULog](https://github.com/PX4/PX4-Autopilot/raw/main/docs/assets/flight_log_analysis/plot_juggler/sample_log_boat_testing_2022-7-28-13-31-16.ulg) - [Boat testing Analysis Layout](https://raw.githubusercontent.com/PX4/PX4-user_guide/main/assets/flight_log_analysis/plot_juggler/sample_log_boat_testing_layout.xml) -::: + ::: ### Layout Templates There are a number of PlotJuggler layout files shared by PX4 Developers. Each can be used for a specific purpose (Multicopter tuning, VTOL tuning, Boat debugging, etc.): -* [Sample View layout](https://github.com/PX4/PX4-user_guide/blob/main/assets/flight_log_analysis/plot_juggler/plotjuggler_sample_view.xml) : Template used in the [Multi-panel example](#splitting-horizontally-vertically-multi-panel) above. - +- [Sample View layout](https://github.com/PX4/PX4-user_guide/blob/main/assets/flight_log_analysis/plot_juggler/plotjuggler_sample_view.xml) : Template used in the [Multi-panel example](#splitting-horizontally-vertically-multi-panel) above. ## Advanced Usage @@ -105,6 +105,7 @@ Here the custom series `Roll` is displayed along with other timeseries, includin ![Quaternion Roll plotted](../../assets/flight_log_analysis/plot_juggler/plotjuggler_quaternion_roll_plotted.png) The `quat_to_roll` function looks like this: + ```lua w = value x = v1 diff --git a/docs/en/mavlink/standard_modes.md b/docs/en/mavlink/standard_modes.md index eabfe8d15e..87d4cd2545 100644 --- a/docs/en/mavlink/standard_modes.md +++ b/docs/en/mavlink/standard_modes.md @@ -2,7 +2,7 @@ -PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.md) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). +PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.html) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). The protocol allows you to discover all flight modes available to the vehicle, including PX4 External modes created using the [PX4 ROS 2 Control Interface](../ros2/px4_ros2_control_interface.md), and get or set the current mode. diff --git a/docs/en/middleware/dds_topics.md b/docs/en/middleware/dds_topics.md index b174fe7638..226f0a801c 100644 --- a/docs/en/middleware/dds_topics.md +++ b/docs/en/middleware/dds_topics.md @@ -4,75 +4,84 @@ This document is [auto-generated](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/msg/generate_msg_docs.py) from the source code. ::: - The [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) file specifies which uORB message definitions are compiled into the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module when [PX4 is built](../middleware/uxrce_dds.md#code-generation), and hence which topics are available for ROS 2 applications to subscribe or publish (by default). This document shows a markdown-rendered version of [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml), listing the publications, subscriptions, and so on. ## Publications -Topic | Type| Rate Limit ---- | --- | --- -`/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | -`/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 -`/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 -`/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 -`/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 -`/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 -`/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 -`/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 -`/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | -`/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 -`/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | -`/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 -`/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 -`/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | -`/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 -`/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | -`/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 -`/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 -`/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 -`/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | -`/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 -`/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 -`/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | -`/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 +| Topic | Type | Rate Limit | +| ---------------------------------------- | -------------------------------------------------------------------------------------- | ---------- | +| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | +| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | +| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | +| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | +| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | +| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | +| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | +| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | +| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | +| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | +| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | +| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | +| `/fmu/out/transponder_report` | [px4_msgs::msg::TransponderReport](../msg_docs/TransponderReport.md) | +| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | +| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | 50.0 | +| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | +| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | +| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | +| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | +| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | +| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | 100.0 | +| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | +| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | +| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | +| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| `/fmu/out/wind` | [px4_msgs::msg::Wind](../msg_docs/Wind.md) | 1.0 | +| `/fmu/out/gimbal_device_attitude_status` | [px4_msgs::msg::GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) | 20.0 | ## Subscriptions -Topic | Type ---- | --- -/fmu/in/register_ext_component_request | [px4_msgs::msg::RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md) -/fmu/in/unregister_ext_component | [px4_msgs::msg::UnregisterExtComponent](../msg_docs/UnregisterExtComponent.md) -/fmu/in/config_overrides_request | [px4_msgs::msg::ConfigOverrides](../msg_docs/ConfigOverrides.md) -/fmu/in/arming_check_reply | [px4_msgs::msg::ArmingCheckReply](../msg_docs/ArmingCheckReply.md) -/fmu/in/message_format_request | [px4_msgs::msg::MessageFormatRequest](../msg_docs/MessageFormatRequest.md) -/fmu/in/mode_completed | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) -/fmu/in/config_control_setpoints | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) -/fmu/in/distance_sensor | [px4_msgs::msg::DistanceSensor](../msg_docs/DistanceSensor.md) -/fmu/in/manual_control_input | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) -/fmu/in/offboard_control_mode | [px4_msgs::msg::OffboardControlMode](../msg_docs/OffboardControlMode.md) -/fmu/in/onboard_computer_status | [px4_msgs::msg::OnboardComputerStatus](../msg_docs/OnboardComputerStatus.md) -/fmu/in/obstacle_distance | [px4_msgs::msg::ObstacleDistance](../msg_docs/ObstacleDistance.md) -/fmu/in/sensor_optical_flow | [px4_msgs::msg::SensorOpticalFlow](../msg_docs/SensorOpticalFlow.md) -/fmu/in/goto_setpoint | [px4_msgs::msg::GotoSetpoint](../msg_docs/GotoSetpoint.md) -/fmu/in/telemetry_status | [px4_msgs::msg::TelemetryStatus](../msg_docs/TelemetryStatus.md) -/fmu/in/trajectory_setpoint | [px4_msgs::msg::TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) -/fmu/in/vehicle_attitude_setpoint | [px4_msgs::msg::VehicleAttitudeSetpoint](../msg_docs/VehicleAttitudeSetpoint.md) -/fmu/in/vehicle_mocap_odometry | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) -/fmu/in/vehicle_rates_setpoint | [px4_msgs::msg::VehicleRatesSetpoint](../msg_docs/VehicleRatesSetpoint.md) -/fmu/in/vehicle_visual_odometry | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) -/fmu/in/vehicle_command | [px4_msgs::msg::VehicleCommand](../msg_docs/VehicleCommand.md) -/fmu/in/vehicle_command_mode_executor | [px4_msgs::msg::VehicleCommand](../msg_docs/VehicleCommand.md) -/fmu/in/vehicle_thrust_setpoint | [px4_msgs::msg::VehicleThrustSetpoint](../msg_docs/VehicleThrustSetpoint.md) -/fmu/in/vehicle_torque_setpoint | [px4_msgs::msg::VehicleTorqueSetpoint](../msg_docs/VehicleTorqueSetpoint.md) -/fmu/in/actuator_motors | [px4_msgs::msg::ActuatorMotors](../msg_docs/ActuatorMotors.md) -/fmu/in/actuator_servos | [px4_msgs::msg::ActuatorServos](../msg_docs/ActuatorServos.md) -/fmu/in/aux_global_position | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) -/fmu/in/fixed_wing_longitudinal_setpoint | [px4_msgs::msg::FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md) -/fmu/in/fixed_wing_lateral_setpoint | [px4_msgs::msg::FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) -/fmu/in/longitudinal_control_configuration | [px4_msgs::msg::LongitudinalControlConfiguration](../msg_docs/LongitudinalControlConfiguration.md) -/fmu/in/lateral_control_configuration | [px4_msgs::msg::LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) +| Topic | Type | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------- | +| /fmu/in/register_ext_component_request | [px4_msgs::msg::RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md) | +| /fmu/in/unregister_ext_component | [px4_msgs::msg::UnregisterExtComponent](../msg_docs/UnregisterExtComponent.md) | +| /fmu/in/config_overrides_request | [px4_msgs::msg::ConfigOverrides](../msg_docs/ConfigOverrides.md) | +| /fmu/in/arming_check_reply | [px4_msgs::msg::ArmingCheckReply](../msg_docs/ArmingCheckReply.md) | +| /fmu/in/message_format_request | [px4_msgs::msg::MessageFormatRequest](../msg_docs/MessageFormatRequest.md) | +| /fmu/in/mode_completed | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | +| /fmu/in/config_control_setpoints | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | +| /fmu/in/distance_sensor | [px4_msgs::msg::DistanceSensor](../msg_docs/DistanceSensor.md) | +| /fmu/in/manual_control_input | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | +| /fmu/in/offboard_control_mode | [px4_msgs::msg::OffboardControlMode](../msg_docs/OffboardControlMode.md) | +| /fmu/in/onboard_computer_status | [px4_msgs::msg::OnboardComputerStatus](../msg_docs/OnboardComputerStatus.md) | +| /fmu/in/obstacle_distance | [px4_msgs::msg::ObstacleDistance](../msg_docs/ObstacleDistance.md) | +| /fmu/in/sensor_optical_flow | [px4_msgs::msg::SensorOpticalFlow](../msg_docs/SensorOpticalFlow.md) | +| /fmu/in/goto_setpoint | [px4_msgs::msg::GotoSetpoint](../msg_docs/GotoSetpoint.md) | +| /fmu/in/telemetry_status | [px4_msgs::msg::TelemetryStatus](../msg_docs/TelemetryStatus.md) | +| /fmu/in/trajectory_setpoint | [px4_msgs::msg::TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) | +| /fmu/in/vehicle_attitude_setpoint | [px4_msgs::msg::VehicleAttitudeSetpoint](../msg_docs/VehicleAttitudeSetpoint.md) | +| /fmu/in/vehicle_mocap_odometry | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | +| /fmu/in/vehicle_rates_setpoint | [px4_msgs::msg::VehicleRatesSetpoint](../msg_docs/VehicleRatesSetpoint.md) | +| /fmu/in/vehicle_visual_odometry | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | +| /fmu/in/vehicle_command | [px4_msgs::msg::VehicleCommand](../msg_docs/VehicleCommand.md) | +| /fmu/in/vehicle_command_mode_executor | [px4_msgs::msg::VehicleCommand](../msg_docs/VehicleCommand.md) | +| /fmu/in/vehicle_thrust_setpoint | [px4_msgs::msg::VehicleThrustSetpoint](../msg_docs/VehicleThrustSetpoint.md) | +| /fmu/in/vehicle_torque_setpoint | [px4_msgs::msg::VehicleTorqueSetpoint](../msg_docs/VehicleTorqueSetpoint.md) | +| /fmu/in/actuator_motors | [px4_msgs::msg::ActuatorMotors](../msg_docs/ActuatorMotors.md) | +| /fmu/in/actuator_servos | [px4_msgs::msg::ActuatorServos](../msg_docs/ActuatorServos.md) | +| /fmu/in/aux_global_position | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | +| /fmu/in/fixed_wing_longitudinal_setpoint | [px4_msgs::msg::FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md) | +| /fmu/in/fixed_wing_lateral_setpoint | [px4_msgs::msg::FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) | +| /fmu/in/longitudinal_control_configuration | [px4_msgs::msg::LongitudinalControlConfiguration](../msg_docs/LongitudinalControlConfiguration.md) | +| /fmu/in/lateral_control_configuration | [px4_msgs::msg::LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) | +| /fmu/in/rover_position_setpoint | [px4_msgs::msg::RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | +| /fmu/in/rover_speed_setpoint | [px4_msgs::msg::RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | +| /fmu/in/rover_attitude_setpoint | [px4_msgs::msg::RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | +| /fmu/in/rover_rate_setpoint | [px4_msgs::msg::RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | +| /fmu/in/rover_throttle_setpoint | [px4_msgs::msg::RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | +| /fmu/in/rover_steering_setpoint | [px4_msgs::msg::RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| /fmu/in/landing_gear | [px4_msgs::msg::LandingGear](../msg_docs/LandingGear.md) | ## Subscriptions Multi @@ -85,192 +94,199 @@ They are not build into the module, and hence are neither published or subscribe ::: details See messages -- [SensorCorrection](../msg_docs/SensorCorrection.md) -- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) -- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) -- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) -- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) -- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) -- [Px4ioStatus](../msg_docs/Px4ioStatus.md) -- [SatelliteInfo](../msg_docs/SatelliteInfo.md) -- [GeofenceResult](../msg_docs/GeofenceResult.md) -- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) -- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) -- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) -- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) -- [EventV0](../msg_docs/EventV0.md) -- [QshellRetval](../msg_docs/QshellRetval.md) -- [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) -- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) -- [RcChannels](../msg_docs/RcChannels.md) -- [SensorAccel](../msg_docs/SensorAccel.md) -- [GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) -- [EscStatus](../msg_docs/EscStatus.md) -- [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) -- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) -- [AirspeedWind](../msg_docs/AirspeedWind.md) -- [InputRc](../msg_docs/InputRc.md) -- [GpioIn](../msg_docs/GpioIn.md) -- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) -- [VehicleImu](../msg_docs/VehicleImu.md) -- [Event](../msg_docs/Event.md) -- [SensorUwb](../msg_docs/SensorUwb.md) -- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) -- [DatamanResponse](../msg_docs/DatamanResponse.md) -- [OrbTest](../msg_docs/OrbTest.md) -- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) -- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) -- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) -- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) -- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) -- [TakeoffStatus](../msg_docs/TakeoffStatus.md) -- [UlogStreamAck](../msg_docs/UlogStreamAck.md) -- [OrbTestLarge](../msg_docs/OrbTestLarge.md) -- [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) -- [CameraCapture](../msg_docs/CameraCapture.md) -- [VehicleRoi](../msg_docs/VehicleRoi.md) -- [ActuatorArmed](../msg_docs/ActuatorArmed.md) -- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) -- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) -- [GeofenceStatus](../msg_docs/GeofenceStatus.md) -- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) -- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) -- [PowerMonitor](../msg_docs/PowerMonitor.md) -- [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) -- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) -- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) -- [TecsStatus](../msg_docs/TecsStatus.md) -- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) -- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) -- [Ping](../msg_docs/Ping.md) -- [LedControl](../msg_docs/LedControl.md) -- [Wind](../msg_docs/Wind.md) -- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) -- [ActuatorTest](../msg_docs/ActuatorTest.md) -- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) -- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) -- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) -- [Gripper](../msg_docs/Gripper.md) -- [SensorMag](../msg_docs/SensorMag.md) +- [BatteryInfo](../msg_docs/BatteryInfo.md) - [DebugValue](../msg_docs/DebugValue.md) -- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) -- [RcParameterMap](../msg_docs/RcParameterMap.md) -- [LandingGear](../msg_docs/LandingGear.md) -- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) -- [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md) -- [UlogStream](../msg_docs/UlogStream.md) -- [GimbalControls](../msg_docs/GimbalControls.md) -- [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) -- [LogMessage](../msg_docs/LogMessage.md) -- [RoverVelocitySetpoint](../msg_docs/RoverVelocitySetpoint.md) -- [GpioOut](../msg_docs/GpioOut.md) -- [TaskStackInfo](../msg_docs/TaskStackInfo.md) -- [VelocityLimits](../msg_docs/VelocityLimits.md) -- [MagWorkerData](../msg_docs/MagWorkerData.md) -- [ParameterUpdate](../msg_docs/ParameterUpdate.md) -- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) -- [SensorBaro](../msg_docs/SensorBaro.md) -- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) -- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) -- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) -- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) -- [Rpm](../msg_docs/Rpm.md) -- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) -- [MountOrientation](../msg_docs/MountOrientation.md) -- [ActionRequest](../msg_docs/ActionRequest.md) -- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) -- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) -- [LoggerStatus](../msg_docs/LoggerStatus.md) -- [GeneratorStatus](../msg_docs/GeneratorStatus.md) -- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) -- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) -- [LandingTargetPose](../msg_docs/LandingTargetPose.md) -- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) -- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) -- [OrbitStatus](../msg_docs/OrbitStatus.md) -- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) -- [EstimatorStatus](../msg_docs/EstimatorStatus.md) -- [DatamanRequest](../msg_docs/DatamanRequest.md) -- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) -- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) -- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) -- [Cpuload](../msg_docs/Cpuload.md) -- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) -- [RoverRateStatus](../msg_docs/RoverRateStatus.md) -- [EscReport](../msg_docs/EscReport.md) -- [DebugArray](../msg_docs/DebugArray.md) -- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) -- [SensorHygrometer](../msg_docs/SensorHygrometer.md) -- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) -- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) -- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) -- [QshellReq](../msg_docs/QshellReq.md) -- [CameraStatus](../msg_docs/CameraStatus.md) -- [GpsInjectData](../msg_docs/GpsInjectData.md) -- [FigureEightStatus](../msg_docs/FigureEightStatus.md) -- [TransponderReport](../msg_docs/TransponderReport.md) -- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) -- [MavlinkLog](../msg_docs/MavlinkLog.md) -- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) -- [FuelTankStatus](../msg_docs/FuelTankStatus.md) -- [Mission](../msg_docs/Mission.md) -- [PositionSetpoint](../msg_docs/PositionSetpoint.md) -- [MissionResult](../msg_docs/MissionResult.md) -- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) -- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) -- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) -- [DifferentialPressure](../msg_docs/DifferentialPressure.md) -- [CellularStatus](../msg_docs/CellularStatus.md) -- [GpsDump](../msg_docs/GpsDump.md) -- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) -- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) -- [NavigatorStatus](../msg_docs/NavigatorStatus.md) -- [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) -- [FollowTarget](../msg_docs/FollowTarget.md) -- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) -- [EstimatorStates](../msg_docs/EstimatorStates.md) -- [SensorGyro](../msg_docs/SensorGyro.md) -- [SensorAirflow](../msg_docs/SensorAirflow.md) -- [ButtonEvent](../msg_docs/ButtonEvent.md) -- [DebugKeyValue](../msg_docs/DebugKeyValue.md) -- [GpioConfig](../msg_docs/GpioConfig.md) -- [CameraTrigger](../msg_docs/CameraTrigger.md) - [LandingGearWheel](../msg_docs/LandingGearWheel.md) -- [VehicleConstraints](../msg_docs/VehicleConstraints.md) -- [HealthReport](../msg_docs/HealthReport.md) -- [PowerButtonState](../msg_docs/PowerButtonState.md) -- [RadioStatus](../msg_docs/RadioStatus.md) -- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) -- [EstimatorBias](../msg_docs/EstimatorBias.md) -- [DebugVect](../msg_docs/DebugVect.md) -- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) -- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) -- [PpsCapture](../msg_docs/PpsCapture.md) -- [SensorSelection](../msg_docs/SensorSelection.md) -- [SystemPower](../msg_docs/SystemPower.md) -- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) -- [SensorGyroFft](../msg_docs/SensorGyroFft.md) -- [VehicleAirData](../msg_docs/VehicleAirData.md) -- [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md) -- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) +- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) +- [ActionRequest](../msg_docs/ActionRequest.md) +- [GpsInjectData](../msg_docs/GpsInjectData.md) +- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) +- [LandingTargetPose](../msg_docs/LandingTargetPose.md) +- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) +- [FigureEightStatus](../msg_docs/FigureEightStatus.md) +- [DatamanRequest](../msg_docs/DatamanRequest.md) +- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md) +- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) +- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) - [GpioRequest](../msg_docs/GpioRequest.md) -- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) -- [RtlStatus](../msg_docs/RtlStatus.md) -- [Airspeed](../msg_docs/Airspeed.md) -- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) -- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) -- [IrlockReport](../msg_docs/IrlockReport.md) -- [HeaterStatus](../msg_docs/HeaterStatus.md) -- [AdcReport](../msg_docs/AdcReport.md) -- [PwmInput](../msg_docs/PwmInput.md) -- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) -- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) -- [OrbTestMedium](../msg_docs/OrbTestMedium.md) -- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) -- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) -- [TuneControl](../msg_docs/TuneControl.md) +- [EstimatorBias](../msg_docs/EstimatorBias.md) +- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) - [WheelEncoders](../msg_docs/WheelEncoders.md) -- [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md) -- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) +- [VehicleRoi](../msg_docs/VehicleRoi.md) +- [Airspeed](../msg_docs/Airspeed.md) +- [EstimatorStatus](../msg_docs/EstimatorStatus.md) +- [EventV0](../msg_docs/EventV0.md) +- [ActuatorTest](../msg_docs/ActuatorTest.md) +- [EscReport](../msg_docs/EscReport.md) +- [OrbTest](../msg_docs/OrbTest.md) +- [RoverRateStatus](../msg_docs/RoverRateStatus.md) +- [DebugKeyValue](../msg_docs/DebugKeyValue.md) +- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) +- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) +- [PowerMonitor](../msg_docs/PowerMonitor.md) +- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) +- [VehicleImu](../msg_docs/VehicleImu.md) +- [QshellRetval](../msg_docs/QshellRetval.md) +- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) +- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) +- [InputRc](../msg_docs/InputRc.md) +- [Ping](../msg_docs/Ping.md) +- [Px4ioStatus](../msg_docs/Px4ioStatus.md) +- [Event](../msg_docs/Event.md) +- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) +- [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md) +- [GpioIn](../msg_docs/GpioIn.md) +- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) +- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) +- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) +- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) +- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) +- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) +- [UlogStreamAck](../msg_docs/UlogStreamAck.md) +- [Rpm](../msg_docs/Rpm.md) - [SensorsStatus](../msg_docs/SensorsStatus.md) -::: +- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) +- [HealthReport](../msg_docs/HealthReport.md) +- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) +- [AirspeedWind](../msg_docs/AirspeedWind.md) +- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) +- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) +- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) +- [PositionSetpoint](../msg_docs/PositionSetpoint.md) +- [FollowTarget](../msg_docs/FollowTarget.md) +- [PwmInput](../msg_docs/PwmInput.md) +- [SensorUwb](../msg_docs/SensorUwb.md) +- [ConfigOverridesV0](../msg_docs/ConfigOverridesV0.md) +- [LedControl](../msg_docs/LedControl.md) +- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) +- [EstimatorStates](../msg_docs/EstimatorStates.md) +- [GeofenceResult](../msg_docs/GeofenceResult.md) +- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) +- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) +- [TakeoffStatus](../msg_docs/TakeoffStatus.md) +- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) +- [PowerButtonState](../msg_docs/PowerButtonState.md) +- [OrbTestLarge](../msg_docs/OrbTestLarge.md) +- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) +- [PpsCapture](../msg_docs/PpsCapture.md) +- [SensorHygrometer](../msg_docs/SensorHygrometer.md) +- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) +- [DeviceInformation](../msg_docs/DeviceInformation.md) +- [EscStatus](../msg_docs/EscStatus.md) +- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) +- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) +- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) +- [SensorTemp](../msg_docs/SensorTemp.md) +- [OrbitStatus](../msg_docs/OrbitStatus.md) +- [MountOrientation](../msg_docs/MountOrientation.md) +- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) +- [FuelTankStatus](../msg_docs/FuelTankStatus.md) +- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) +- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) +- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) +- [SatelliteInfo](../msg_docs/SatelliteInfo.md) +- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) +- [QshellReq](../msg_docs/QshellReq.md) +- [RcParameterMap](../msg_docs/RcParameterMap.md) +- [MavlinkLog](../msg_docs/MavlinkLog.md) +- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md) +- [LogMessage](../msg_docs/LogMessage.md) +- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) +- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) +- [ActuatorArmed](../msg_docs/ActuatorArmed.md) +- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) +- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) +- [UlogStream](../msg_docs/UlogStream.md) +- [SensorAirflow](../msg_docs/SensorAirflow.md) +- [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md) +- [Mission](../msg_docs/Mission.md) +- [HomePositionV0](../msg_docs/HomePositionV0.md) +- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) +- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) +- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) +- [GimbalControls](../msg_docs/GimbalControls.md) +- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) +- [SensorGyro](../msg_docs/SensorGyro.md) +- [MagWorkerData](../msg_docs/MagWorkerData.md) +- [RtlStatus](../msg_docs/RtlStatus.md) +- [VelocityLimits](../msg_docs/VelocityLimits.md) +- [SensorSelection](../msg_docs/SensorSelection.md) +- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) +- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) +- [ButtonEvent](../msg_docs/ButtonEvent.md) +- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) +- [ParameterUpdate](../msg_docs/ParameterUpdate.md) +- [MissionResult](../msg_docs/MissionResult.md) +- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) +- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) +- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) +- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) +- [AdcReport](../msg_docs/AdcReport.md) +- [TuneControl](../msg_docs/TuneControl.md) +- [CameraStatus](../msg_docs/CameraStatus.md) +- [GpioOut](../msg_docs/GpioOut.md) +- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) +- [HeaterStatus](../msg_docs/HeaterStatus.md) +- [OrbTestMedium](../msg_docs/OrbTestMedium.md) +- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) +- [GainCompression](../msg_docs/GainCompression.md) +- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) +- [SensorAccel](../msg_docs/SensorAccel.md) +- [NeuralControl](../msg_docs/NeuralControl.md) +- [Gripper](../msg_docs/Gripper.md) +- [SensorCorrection](../msg_docs/SensorCorrection.md) +- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md) +- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md) +- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md) +- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) +- [DebugVect](../msg_docs/DebugVect.md) +- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) +- [SensorGyroFft](../msg_docs/SensorGyroFft.md) +- [GeneratorStatus](../msg_docs/GeneratorStatus.md) +- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) +- [DatamanResponse](../msg_docs/DatamanResponse.md) +- [DebugArray](../msg_docs/DebugArray.md) +- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) +- [VehicleConstraints](../msg_docs/VehicleConstraints.md) +- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) +- [NavigatorStatus](../msg_docs/NavigatorStatus.md) +- [RaptorInput](../msg_docs/RaptorInput.md) +- [RcChannels](../msg_docs/RcChannels.md) +- [Vtx](../msg_docs/Vtx.md) +- [LoggerStatus](../msg_docs/LoggerStatus.md) +- [GpsDump](../msg_docs/GpsDump.md) +- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) +- [SensorBaro](../msg_docs/SensorBaro.md) +- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) +- [TecsStatus](../msg_docs/TecsStatus.md) +- [IrlockReport](../msg_docs/IrlockReport.md) +- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) +- [RadioStatus](../msg_docs/RadioStatus.md) +- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) +- [CameraCapture](../msg_docs/CameraCapture.md) +- [GeofenceStatus](../msg_docs/GeofenceStatus.md) +- [GpioConfig](../msg_docs/GpioConfig.md) +- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) +- [SensorMag](../msg_docs/SensorMag.md) +- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) +- [RaptorStatus](../msg_docs/RaptorStatus.md) +- [RegisterExtComponentRequestV0](../msg_docs/RegisterExtComponentRequestV0.md) +- [SystemPower](../msg_docs/SystemPower.md) +- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) +- [Cpuload](../msg_docs/Cpuload.md) +- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) +- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) +- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) +- [RegisterExtComponentReplyV0](../msg_docs/RegisterExtComponentReplyV0.md) +- [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md) +- [DifferentialPressure](../msg_docs/DifferentialPressure.md) +- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) +- [CellularStatus](../msg_docs/CellularStatus.md) +- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) +- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) + ::: diff --git a/docs/en/middleware/drivers.md b/docs/en/middleware/drivers.md index 6b29331d21..e64a3bfefb 100644 --- a/docs/en/middleware/drivers.md +++ b/docs/en/middleware/drivers.md @@ -1,27 +1,27 @@ # Driver Development -PX4 device drivers are based on the [Device](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/device) framework. +PX4 device drivers are based on the [Device](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/device) framework. ## Creating a Driver PX4 almost exclusively consumes data from [uORB](../middleware/uorb.md). Drivers for common peripheral types must publish the correct uORB messages (for example: gyro, accelerometer, pressure sensors, etc.). -The best approach for creating a new driver is to start with a similar driver as a template (see [src/drivers](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers)). +The best approach for creating a new driver is to start with a similar driver as a template (see [src/drivers](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers)). ::: info More detailed information about working with specific I/O buses and sensors may be available in [Sensor and Actuator Buses](../sensor_bus/index.md) section. ::: ::: info -Publishing the correct uORB topics is the only pattern that drivers *must* follow. +Publishing the correct uORB topics is the only pattern that drivers _must_ follow. ::: ## Core Architecture PX4 is a [reactive system](../concept/architecture.md) and uses [uORB](../middleware/uorb.md) publish/subscribe to transport messages. File handles are not required or used for the core operation of the system. Two main APIs are used: -* The publish / subscribe system which has a file, network or shared memory backend depending on the system PX4 runs on. -* The global device registry, which can be used to enumerate devices and get/set their configuration. This can be as simple as a linked list or map to the file system. +- The publish / subscribe system which has a file, network or shared memory backend depending on the system PX4 runs on. +- The global device registry, which can be used to enumerate devices and get/set their configuration. This can be as simple as a linked list or map to the file system. ## Device IDs @@ -33,7 +33,6 @@ The order of sensors (e.g. if there is a `/dev/mag0` and an alternate `/dev/mag1 For the example of three magnetometers on a system, use the flight log (.px4log) to dump the parameters. The three parameters encode the sensor IDs and `MAG_PRIME` identifies which magnetometer is selected as the primary sensor. Each MAGx_ID is a 24bit number and should be padded left with zeros for manual decoding. - ``` CAL_MAG0_ID = 73225.0 CAL_MAG1_ID = 66826.0 @@ -83,6 +82,7 @@ struct DeviceStructure { uint8_t devtype; // device class specific device type }; ``` + The `bus_type` is decoded according to: ```C @@ -126,17 +126,19 @@ Drivers (and other modules) output minimally verbose logs strings by default (e. Log verbosity is defined at build time using the `RELEASE_BUILD` (default), `DEBUG_BUILD` (verbose) or `TRACE_BUILD` (extremely verbose) macros. Change the logging level using `COMPILE_FLAGS` in the driver `px4_add_module` function (**CMakeLists.txt**). -The code fragment below shows the required change to enable DEBUG_BUILD level debugging for a single module or driver. +The code fragment below shows the required change to enable DEBUG_BUILD level debugging for a single module or driver. ``` px4_add_module( MODULE templates__module MAIN module ``` + ``` COMPILE_FLAGS -DDEBUG_BUILD ``` + ``` SRCS module.cpp diff --git a/docs/en/middleware/index.md b/docs/en/middleware/index.md index dc9d0464b7..3c35eeb96c 100644 --- a/docs/en/middleware/index.md +++ b/docs/en/middleware/index.md @@ -1,6 +1,6 @@ # Middleware -This section contains topics about PX4 middleware, including PX4 internal communication mechanisms ([uORB](../middleware/uorb.md)), and between PX4 and offboard systems like companion computers and GCS (e.g. [MAVLink](../middleware/mavlink.md), [uXRCE-DDS](../middleware/uxrce_dds.md)). +This section contains topics about PX4 middleware, including PX4 internal communication mechanisms ([uORB](../middleware/uorb.md)), and between PX4 and offboard systems like companion computers and GCS (e.g. [MAVLink](../middleware/mavlink.md), [uXRCE-DDS](../middleware/uxrce_dds.md)). :::tip For a detailed overview of the platform architecture see the [Architectural Overview](../concept/architecture.md). diff --git a/docs/en/middleware/uorb.md b/docs/en/middleware/uorb.md index ebd6a592df..401f3329b8 100644 --- a/docs/en/middleware/uorb.md +++ b/docs/en/middleware/uorb.md @@ -280,6 +280,8 @@ For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggl ## See Also +- [uORB Documentation Standard](../uorb/uorb_documentation.md) + - _PX4 uORB Explained_ Blog series - [Part 1](https://px4.io/px4-uorb-explained-part-1/) - [Part 2](https://px4.io/px4-uorb-explained-part-2/) diff --git a/docs/en/middleware/uorb_graph.md b/docs/en/middleware/uorb_graph.md index 7376e951b6..9dbdb57c2d 100644 --- a/docs/en/middleware/uorb_graph.md +++ b/docs/en/middleware/uorb_graph.md @@ -10,7 +10,6 @@ Usage instructions are provided [below](#graph-properties). import { withBase } from 'vitepress'; - ## Graph Properties The graph has the following properties: @@ -27,5 +26,5 @@ The graph has the following properties: - Double-clicking on a topic opens its message definition. - Make sure your browser window is wide enough to display the full graph (the sidebar menu can be hidden with the icon in the top-left corner). You can also zoom the image. -- The *Preset* selection list allows you to refine the list of modules that are shown. -- The *Search* box can be used to find particular modules/topics (topics that are not selected by the search are greyed-out). +- The _Preset_ selection list allows you to refine the list of modules that are shown. +- The _Search_ box can be used to find particular modules/topics (topics that are not selected by the search are greyed-out). diff --git a/docs/en/middleware/uxrce_dds.md b/docs/en/middleware/uxrce_dds.md index dcd9e3dbda..806fe0f479 100644 --- a/docs/en/middleware/uxrce_dds.md +++ b/docs/en/middleware/uxrce_dds.md @@ -65,7 +65,7 @@ PX4 Micro XRCE-DDS Client is based on version `v2.x` which is not compatible wit On Ubuntu you can build from source and install the Agent standalone using the following commands: ```sh -git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git +git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build @@ -106,12 +106,19 @@ The development version, fetched using `--edge` above, does work. ### Build/Run within ROS 2 Workspace -The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace. +The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace). You must already have installed ROS 2 following the instructions in: [ROS 2 User Guide > Install ROS 2](../ros2/user_guide.md#install-ros-2). ::: warning This approach will use the existing ROS 2 versions of the Agent dependencies, such as `fastcdr` and `fastdds`. -This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones. +This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones: + +| ROS 2 version | Micro-XRCE-DDS-Agent version | +| ------------- | ---------------------------- | +| Foxy | v2.4.2 | +| Humble | v2.4.2 | +| Jazzy | v2.4.3 | + ::: To build the agent within ROS: @@ -124,15 +131,50 @@ To build the agent within ROS: 1. Clone the source code for the eProsima [Micro-XRCE-DDS-Agent](https://github.com/eProsima/Micro-XRCE-DDS-Agent) to the `/src` directory (the `main` branch is cloned by default): + ::::tabs + + ::: tab jazzy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + ::: + + ::: tab humble + ```sh cd ~/px4_ros_uxrce_dds_ws/src git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git ``` + ::: + + ::: tab foxy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + ::: + + :::: + 1. Source the ROS 2 development environment, and compile the workspace using `colcon`: :::: tabs + ::: tab jazzy + + ```sh + source /opt/ros/jazzy/setup.bash + colcon build + ``` + + ::: + ::: tab humble ```sh @@ -161,6 +203,15 @@ To run the micro XRCE-DDS agent in the workspace: :::: tabs + ::: tab jazzy + + ```sh + source /opt/ros/jazzy/setup.bash + source install/local_setup.bash + ``` + + ::: + ::: tab humble ```sh @@ -230,7 +281,6 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_CFG](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG): Set the port to connect on, such as `TELEM2`, `Ethernet`, or `Wifi`. - If using an Ethernet connection: - - [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT): Use this to specify the agent UDP listening port. The default value is `8888`. @@ -240,7 +290,6 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi The default value is `2130706433` which corresponds to the _localhost_ `127.0.0.1`. You can use [Tools/convert_ip.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/convert_ip.py) to convert between the formats: - - To obtain the `int32` version of an IP in decimal dot notation the command is: ```sh @@ -254,14 +303,12 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi ``` - If using a serial connection: - - [SER_TEL2_BAUD](../advanced_config/parameter_reference.md#SER_TEL2_BAUD), [SER_URT6_BAUD](../advanced_config/parameter_reference.md#SER_URT6_BAUD) (and so on): Use the `_BAUD` parameter associated with the serial port to set the baud rate. For example, you'd set a value for `SER_TEL2_BAUD` if you are connecting to the companion using `TELEM2`. For more information see [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration). - Some setups might also need these parameters to be set: - - [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): The uXRCE-DDS key. If you're working in a multi-client, single agent configuration, each client should have a unique non-zero key. This is primarily important for multi-vehicle simulations, where all clients are connected in UDP to the same agent. @@ -274,6 +321,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge. This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. + Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. + See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. ::: info Many ports are already have a default configuration. @@ -347,7 +399,7 @@ Therefore, ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)) or at runtime (which is useful for multi vehicle operations): +Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)), at runtime, or through a parameter (which is useful for multi vehicle operations): - One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. This technique can be used both in simulation and real vehicles. @@ -376,6 +428,23 @@ will generate topics under the namespaces: ::: +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. + This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. + This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. + +::: info +PX4 parameters cannot carry rich text strings. +Therefore, you cannot use [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to automatically start a client with an arbitrary message namespace through PX4. +You can however specify a namespace when starting the client, using the `-n` argument: + +```sh +# In etc/extras.txt on the MicroSD card +uxrce_dds_client start -n fancy_uav +``` + +This can be included in `etc/extras.txt` as part of a custom [System Startup](../concept/system_startup.md). +::: + ## PX4 ROS 2 QoS Settings PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers. @@ -436,6 +505,11 @@ publications: - topic: /fmu/out/vehicle_trajectory_waypoint_desired type: px4_msgs::msg::VehicleTrajectoryWaypoint + - topic: /fmu/out/vehicle_imu + type: px4_msgs::msg::VehicleImu + rate_limit: 50. + instance: 1 # OPTIONAL + subscriptions: - topic: /fmu/in/offboard_control_mode @@ -468,6 +542,9 @@ Each (`topic`,`type`) pairs defines: 4. The message type (`VehicleOdometry`, `VehicleStatus`, `OffboardControlMode`, etc.) and the ROS 2 package (`px4_msgs`) that is expected to provide the message definition. 5. **(Optional)**: An additional `rate_limit` field (only for publication entries), which specifies the maximum rate (Hz) at which messages will be published on this topic by PX4 to ROS 2. If left unspecified, the maximum publication rate limit is set to 100 Hz. +6. **(Optional)**: An additional `instance` field (only for publication entries), which lets you select which instance of a [multi-instance topic](./uorb.md#multi-instance) you want to be published to ROS 2. + If provided, this option changes the ROS 2 topic name of the advertised uORB topic appending the instance number: `fmu/out/[uorb topic name][instance]` (plus eventual namespace and message version). + In the example above the final topic name would be `/fmu/out/vehicle_imu1`. `subscriptions` and `subscriptions_multi` allow us to choose the uORB topic instance that ROS 2 topics are routed to: either a shared instance that may also be getting updates from internal PX4 uORB publishers, or a separate instance that is reserved for ROS2 publications, respectively. Without this mechanism all ROS 2 messages would be routed to the _same_ uORB topic instance (because ROS 2 does not have the concept of [multiple topic instances](../middleware/uorb.md#multi-instance)), and it would not be possible for PX4 subscribers to differentiate between streams from ROS 2 or PX4 publishers. diff --git a/docs/en/middleware/zenoh.md b/docs/en/middleware/zenoh.md new file mode 100644 index 0000000000..bfee1e79f1 --- /dev/null +++ b/docs/en/middleware/zenoh.md @@ -0,0 +1,200 @@ +# Zenoh (PX4 ROS 2 rmw_zenoh) + + + +:::warning Experimental +At the time of writing, PX4 Zenoh-pico is experimental, and hence subject to change. +::: + +PX4 supports Zenoh as an alternative mechanism (to DDS) for bridging uORB topics to [ROS 2](../ros2/user_guide.md) (via the ROS 2 [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh) middleware). +This allows uORB messages to be published and subscribed on a companion computer as though they were ROS 2 topics. +It provides a fast and lightweight way to connect PX4 to ROS 2, making it easier for applications to access vehicle telemetry and send control commands. + +The following guide describes the architecture and various options for setting up the Zenoh client and router. +In particular, it covers the options that are most important to PX4 users exploring Zenoh as an alternative communication layer for ROS 2. + +## Architecture + +The Zenoh-based middleware consists of a client running on PX4 and a Zenoh router running on the companion computer, with bi-directional data exchange between them over a UART, TCP, UDP, or multicast-UDP link. +The router acts as a broker and discovery service, enabling PX4 to publish and subscribe to topics in the global Zenoh data space. +This allows seamless integration with ROS 2 nodes using [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh), and supports flexible deployment across distributed systems. + +![Architecture PX4 Zenoh-Pico with ROS 2](../../assets/middleware/zenoh/architecture-px4-zenoh.svg) + +The client is the _PX4 Zenoh-Pico Node_ referred to above, which is implemented in the [PX4 `zenoh` module](../modules/modules_driver.md#zenoh). +This is based on Zenoh-Pico, a minimalistic version of [Eclipse Zenoh](https://zenoh.io/) (a data-centric protocol designed for real-time, distributed, and resource-constrained environments). + +The router suggested above is [zenohd](https://github.com/eclipse-zenoh/zenoh/tree/main/zenohd). + +:::info +UART is supported by Zenoh but has not yet implemented in the PX4 Zenoh-Pico node. +::: + +## ROS 2 Zenoh Bring-up on Linux Companion + +In order for PX4 uORB topics to be shared with ROS 2 applications, you will need the PX4 Zenoh-Pico Node client running on your FMU, connected to a Zenoh router running on the companion computer (or elsewhere in the network). + +First select Zenoh as the ROS 2 transport by setting the `RMW_IMPLEMENTATION` environment variable as shown: + +```sh +export RMW_IMPLEMENTATION=rmw_zenoh_cpp +``` + +Then start the Zenoh router using the command: + +```sh +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +For more information about the Zenoh Router see the [rmw_zenoh](https://github.com/ros2/rmw_zenoh?tab=readme-ov-file#start-the-zenoh-router) documentation. + +## PX4 Zenoh-Pico Node Setup + +### PX4 Firmware + +Before setting up the Zenoh communication, first make sure that your firmware contains the driver that implements the [`zenoh` driver](../modules/modules_driver.md#zenoh), which provides the implementation of the _PX4 Zenoh-Pico Node_. + +You can check if the module is present on your board by searching for the key `CONFIG_MODULES_ZENOH=y` in your board's `default.px4board` KConfig file. +For example, you can see that the module is present in `px4_fmu-v6xrt` build targets from [/boards/px4/fmu-v6xrt/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#L91). + +If `CONFIG_MODULES_ZENOH=y` is not preset you can add this key to your board configuration and rebuild. +Note that due to flash constraints you may need to remove other components in order to include the module (such as the [`uxrce_dds_client` module](../modules/modules_system.md#uxrce-dds-client), which you will not need if you are using Zenoh). + +The table below shows some of the PX4 targets that include Zenoh by default. + +| PX4 Target | Notes | +| ---------------------- | ------------------------------------------------------------------------------------------- | +| `px4_fmu-v6xrt` | For [FMUv6X-RT](../flight_controller/nxp_mr_vmu_rt1176.md) (reference platform for testing) | +| `nxp_tropic-community` | | +| `nxp_mr-tropic` | | +| `nxp_mr-canhubk344` | | +| `px4_sitl_zenoh` | Zenoh-enabled simulation build | +| `px4_fmu-v6x_zenoh` | Zenoh-enabled firmware for FMUv6X | + +Zenoh is not included in the default `px4_fmu-` targets for any firmware other than `px4_fmu-v6xrt` (`px4_sitl_zenoh` and `px4_fmu-v6x_zenoh` [are build variants](../dev_setup/building_px4.md#px4-make-build-targets)). + +::: tip +You can check if Zenoh is present at runtime by using QGroundControl to [find the parameter](../advanced_config/parameters.md#finding-a-parameter) [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE). +If present, the module is installed. +::: + +### Enable Zenoh on PX4 Startup + +Set the [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE) parameter to `1` to enable Zenoh on PX4 startup. + +### Configure Zenoh Network + +Set up PX4 to connect to the companion computer running `zenohd`. + +PX4's default IP address of the Zenoh daemon host is `10.41.10.1`. +If you're using a different IP for the Zenoh daemon, run the following command (replacing the address) in a PX4 shell and then reboot: + +```sh +zenoh config net client tcp/10.41.10.1:7447#iface=eth0 +``` + +Note that for the simulation target with Zeroh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. + +:::warning +Any changes to the network configuration require a PX4 system reboot to take effect. +::: + +:::tip +See [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) for more information about Ethernet configuration. +::: + +### PX4 Zenoh-pico Node configuration + +The **default configuration** is auto-generated from the [dds_topics.yaml](../middleware/dds_topics.md) file in the PX4 repository. +This file specifies which uORB message definitions are to be published/subscribed by ROS 2 applications, and hence (indirectly) which topics are compiled into the zenoh module. + +To inspect the current Zenoh configuration: + +```sh +zenoh config +``` + +The PX4 Zenoh-pico node stores its configuration on the **SD card** under the `zenoh` folder. +This folder contains three key files: + +- **`net.txt`** – Defines the **Zenoh network configuration**. +- **`pub.csv`** – Maps **uORB topics to ROS2 topics** (used for publishing). +- **`sub.csv`** – Maps **ROS2 topics to uORB topics** (used for subscribing). + +### 4. Modifying Topic Mappings + +Zenoh topic mappings define how data flows between PX4's internal uORB topics and external ROS2 topics via Zenoh. +These mappings are stored in `pub.csv` and `sub.csv` on the SD card, and can be modified at runtime using the `zenoh config` CLI tool. + +:::warning +Any changes to the topic mappings require a PX4 system reboot to take effect. +::: + +There are two types of mappings you can modify: + +- **Publisher mappings**: Forward data from a uORB topic to a Zenoh topic. +- **Subscriber mappings**: Receive data from a Zenoh topic and publish it to a uORB topic. + +The main operations and their commands are: + +- Publish a uORB topic to a Zenoh topic: + + ```sh + zenoh config add publisher [uorb_instance] + ``` + +- Subscribe to a Zenoh topic and forward it to a uORB topic: + + ```sh + zenoh config add subscriber [uorb_instance] + ``` + +- Remove existing mappings: + + ```sh + zenoh config delete publisher + zenoh config delete subscriber + ``` + +After modifying the mappings, reboot PX4 to apply the changes. +The updated configuration will be loaded from the SD card during startup. + +## Communicating with PX4 from ROS 2 via Zenoh + +Once your PX4 FMU is publishing data into ROS 2, you can inspect the available topics and their contents using standard ROS 2 CLI tools: + +```sh +ros2 topic list +``` + +Check topic type and publishers/subscribers: + +```sh +ros2 topic info -v /fmu/out/vehicle_status +Type: px4_msgs/msg/VehicleStatus + +Publisher count: 1 + +Node name: px4_aabbcc00000000000000000000000000 +Node namespace: / +Topic type: px4_msgs/msg/VehicleStatus +Topic type hash: RIHS01_828bddbb7d4c2aa6ad93757955f6893be1ec5d8f11885ec7715bcdd76b5226c9 +Endpoint type: PUBLISHER +GID: 82.99.74.2c.b6.7d.93.44.91.4d.fe.14.93.58.40.16 +QoS profile: + Reliability: RELIABLE + History (Depth): KEEP_LAST (7) + Durability: VOLATILE + Lifespan: Infinite + Deadline: Infinite + Liveliness: AUTOMATIC + Liveliness lease duration: Infinite + +Subscription count: 0 +``` + +### PX4 ROS 2 Interface with Zenoh + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) works out of the box with Zenoh as a transport backend. +This means you can publish and subscribe to PX4 topics over Zenoh without changing your ROS 2 nodes or dealing with DDS configuration. +For setup details and supported message types, refer to the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). diff --git a/docs/en/modules/hello_sky.md b/docs/en/modules/hello_sky.md index ad1d9e5bc9..86aa6bd6e9 100644 --- a/docs/en/modules/hello_sky.md +++ b/docs/en/modules/hello_sky.md @@ -88,13 +88,17 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too ``` :::tip + The main function must be named `_main` and exported from the module as shown. + ::: :::tip + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 1. Create and open a new _cmake_ definition file named **CMakeLists.txt**. @@ -160,7 +164,7 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 1. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). Copy in the text below: - ``` + ```text menuconfig EXAMPLES_PX4_SIMPLE_APP bool "px4_simple_app" default n @@ -434,6 +438,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e */ #include +#include #include #include #include diff --git a/docs/en/modules/module_template.md b/docs/en/modules/module_template.md index 5d9fa26c6a..291c6ff0cf 100644 --- a/docs/en/modules/module_template.md +++ b/docs/en/modules/module_template.md @@ -1,6 +1,6 @@ # Module Template for Full Applications -An application can be written to run as either a *task* (a module with its own stack and process priority) or as a *work queue task* (a module that runs on a work queue thread, sharing the stack and thread priority with other tasks on the work queue). +An application can be written to run as either a _task_ (a module with its own stack and process priority) or as a _work queue task_ (a module that runs on a work queue thread, sharing the stack and thread priority with other tasks on the work queue). In most cases a work queue task can be used, as this minimizes resource usage. ::: info @@ -13,26 +13,28 @@ All the things learned in the [First Application Tutorial](../modules/hello_sky. ## Work Queue Task -PX4-Autopilot contains a template for writing a new application (module) that runs as a *work queue task*: +PX4-Autopilot contains a template for writing a new application (module) that runs as a _work queue task_: [src/examples/work_item](https://github.com/PX4/PX4-Autopilot/tree/main/src/examples/work_item). A work queue task application is just the same as an ordinary (task) application, except that it needs to specify that it is a work queue task, and schedule itself to run during initialisation. The example shows how. In summary: + 1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)): ``` ... DEPENDS px4_work_queue ``` -1. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp]( https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp)) +1. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp)) 1. Specify the queue to add the task to in the constructor initialisation. The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: + ```cpp WorkItemExample::WorkItemExample() : - ModuleParams(nullptr), - ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) { } ``` @@ -45,8 +47,6 @@ In summary: 1. Implement the `task_spawn` method, specifying that the task is a work queue (using the `task_id_is_work_queue` id. 1. Schedule the work queue task using one of the scheduling methods (in the example we use `ScheduleOnInterval` from within the `init` method). - - ## Tasks PX4/PX4-Autopilot contains a template for writing a new application (module) that runs as a task on its own stack: diff --git a/docs/en/modules/modules_autotune.md b/docs/en/modules/modules_autotune.md index 2292dd7494..f0570f8925 100644 --- a/docs/en/modules/modules_autotune.md +++ b/docs/en/modules/modules_autotune.md @@ -1,15 +1,11 @@ # Modules Reference: Autotune - - ## fw_autotune_attitude_control Source: [modules/fw_autotune_attitude_control](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/fw_autotune_attitude_control) - ### Description - ### Usage {#fw_autotune_attitude_control_usage} ``` @@ -27,10 +23,8 @@ fw_autotune_attitude_control [arguments...] Source: [modules/mc_autotune_attitude_control](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mc_autotune_attitude_control) - ### Description - ### Usage {#mc_autotune_attitude_control_usage} ``` diff --git a/docs/en/modules/modules_command.md b/docs/en/modules/modules_command.md index 4bba93f042..499d7f1fdb 100644 --- a/docs/en/modules/modules_command.md +++ b/docs/en/modules/modules_command.md @@ -1,12 +1,9 @@ # Modules Reference: Command - - ## actuator_test Source: [systemcmds/actuator_test](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/actuator_test) - Utility to test actuators. WARNING: remove all props before using this command. @@ -36,6 +33,7 @@ actuator_test [arguments...] Source: [systemcmds/bl_update](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/bl_update) Utility to flash the bootloader from a file + ### Usage {#bl_update_usage} ``` @@ -51,6 +49,7 @@ bl_update [arguments...] Source: [systemcmds/bsondump](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/bsondump) Utility to read BSON from a file and print or output document size. + ### Usage {#bsondump_usage} ``` @@ -63,6 +62,7 @@ bsondump [arguments...] Source: [systemcmds/dumpfile](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/dumpfile) Dump file utility. Prints file size and contents in binary mode (don't replace LF with CR LF) to stdout. + ### Usage {#dumpfile_usage} ``` @@ -74,16 +74,16 @@ dumpfile [arguments...] Source: [systemcmds/dyn](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/dyn) - ### Description + Load and run a dynamic PX4 module, which was not compiled into the PX4 binary. ### Example + ``` dyn ./hello.px4mod start ``` - ### Usage {#dyn_usage} ``` @@ -96,14 +96,16 @@ dyn [arguments...] Source: [systemcmds/failure](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/failure) - ### Description + Inject failures into system. ### Implementation + This system command sends a vehicle command over uORB to trigger failure. ### Examples + Test the GPS failsafe by stopping GPS: failure gps off @@ -125,32 +127,37 @@ failure [arguments...] Source: [systemcmds/gpio](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/gpio) - ### Description + This command is used to read and write GPIOs + ``` gpio read / [PULLDOWN|PULLUP] [--force] gpio write / [PUSHPULL|OPENDRAIN] [--force] ``` ### Examples + Read the value on port H pin 4 configured as pullup, and it is high + ``` gpio read H4 PULLUP ``` + 1 OK Set the output value on Port E pin 7 to high + ``` gpio write E7 1 --force ``` Set the output value on device /dev/gpio1 to high + ``` gpio write /dev/gpio1 1 ``` - ### Usage {#gpio_usage} ``` @@ -203,6 +210,7 @@ hardfault_log [arguments...] Source: [systemcmds/hist](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hist) Command-line tool to show the px4 message history. There are no arguments. + ### Usage {#hist_usage} ``` @@ -214,6 +222,7 @@ hist [arguments...] Source: [systemcmds/i2cdetect](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/i2cdetect) Utility to scan for I2C devices on a particular bus. + ### Usage {#i2cdetect_usage} ``` @@ -226,8 +235,8 @@ i2cdetect [arguments...] Source: [systemcmds/led_control](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/led_control) - ### Description + Command-line tool to control & test the (external) LED's. To use it make sure there's a driver running, which handles the led_control uorb topic. @@ -237,12 +246,13 @@ module can blink N times with high priority, and the LED's automatically return after the blinking. The `reset` command can also be used to return to a lower priority. ### Examples + Blink the first LED 5 times in blue: + ``` led_control blink -c blue -l 0 -n 5 ``` - ### Usage {#led_control_usage} ``` @@ -279,7 +289,6 @@ led_control [arguments...] Source: [systemcmds/topic_listener](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/topic_listener) - Utility to listen on uORB topics and print the data to the console. The listener can be exited any time by pressing Ctrl+C, Esc, or Q. @@ -303,6 +312,7 @@ listener [arguments...] Source: [systemcmds/mft](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/mft) Utility interact with the manifest + ### Usage {#mfd_usage} ``` @@ -316,6 +326,7 @@ mfd [arguments...] Source: [systemcmds/mft_cfg](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/mft_cfg) Tool to set and get manifest configuration + ### Usage {#mft_cfg_usage} ``` @@ -336,6 +347,7 @@ mft_cfg [arguments...] Source: [systemcmds/mtd](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/mtd) Utility to mount and test partitions (based on FRAM/EEPROM storage as defined by the board) + ### Usage {#mtd_usage} ``` @@ -378,8 +390,8 @@ nshterm [arguments...] Source: [systemcmds/param](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/param) - ### Description + Command to access and manipulate parameters via shell or script. This is used for example in the startup script to set airframe-specific parameters. @@ -396,7 +408,9 @@ Each parameter has a 'used' flag, which is set when it's read during boot. It is parameters to a ground control station. ### Examples + Change the airframe and make sure the airframe's default parameters are loaded: + ``` param set SYS_AUTOSTART 4001 param set SYS_AUTOCONFIG 1 @@ -476,12 +490,11 @@ param [arguments...] Source: [modules/payload_deliverer](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/payload_deliverer) - ### Description + Handles payload delivery with either Gripper or a Winch with an appropriate timeout / feedback sensor setting, and communicates back the delivery result as an acknowledgement internally - ### Usage {#payload_deliverer_usage} ``` @@ -505,6 +518,7 @@ payload_deliverer [arguments...] Source: [systemcmds/perf](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/perf) Tool to print performance counters + ### Usage {#perf_usage} ``` @@ -521,6 +535,7 @@ perf [arguments...] Source: [systemcmds/reboot](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/reboot) Reboot the system + ### Usage {#reboot_usage} ``` @@ -535,6 +550,7 @@ reboot [arguments...] Source: [systemcmds/sd_bench](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/sd_bench) Test the speed of an SD Card + ### Usage {#sd_bench_usage} ``` @@ -557,6 +573,7 @@ sd_bench [arguments...] Source: [systemcmds/sd_stress](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/sd_stress) Test operations on an SD Card + ### Usage {#sd_stress_usage} ``` @@ -592,7 +609,6 @@ serial_passthru [arguments...] Source: [systemcmds/system_time](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/system_time) - ### Description Command-line tool to set and get system time. @@ -600,6 +616,7 @@ Command-line tool to set and get system time. ### Examples Set the system time and read it back + ``` system_time set 1600775044 system_time get @@ -620,6 +637,7 @@ system_time [arguments...] Source: [systemcmds/top](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/top) Monitor running processes and their CPU, stack usage, priority and state + ### Usage {#top_usage} ``` @@ -633,6 +651,7 @@ Source: [systemcmds/usb_connected](https://github.com/PX4/PX4-Autopilot/tree/mai Utility to check if USB is connected. Was previously used in startup scripts. A return value of 0 means USB is connected, 1 otherwise. + ### Usage {#usb_connected_usage} ``` @@ -644,6 +663,7 @@ usb_connected [arguments...] Source: [systemcmds/ver](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/ver) Tool to print various version information + ### Usage {#ver_usage} ``` diff --git a/docs/en/modules/modules_driver.md b/docs/en/modules/modules_driver.md index 7801da4db3..349b98659d 100644 --- a/docs/en/modules/modules_driver.md +++ b/docs/en/modules/modules_driver.md @@ -2,6 +2,7 @@ Subcategories: +- [Adc](modules_driver_adc.md) - [Airspeed Sensor](modules_driver_airspeed_sensor.md) - [Baro](modules_driver_baro.md) - [Camera](modules_driver_camera.md) @@ -14,98 +15,6 @@ Subcategories: - [Rpm Sensor](modules_driver_rpm_sensor.md) - [Transponder](modules_driver_transponder.md) -## MCP23009 - -Source: [drivers/gpio/mcp23009](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/gpio/mcp23009) - -### Usage {#MCP23009_usage} - -``` -MCP23009 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 37 - [-D ] Direction - default: 0 - [-O ] Output - default: 0 - [-P ] Pullups - default: 0 - [-U ] Update Interval [ms] - default: 0 - - stop - - status print status info -``` - -## adc - -Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) - -### Description - -ADC driver. - -### Usage {#adc_usage} - -``` -adc [arguments...] - Commands: - start - - test - [-n] Do not publish ADC report, only system power - - stop - - status print status info -``` - -## ads1115 - -Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) - -### Description - -Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. - -The driver is included by default in firmware for boards that do not have an internal analog to digital converter, -such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) -(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). - -It is enabled/disabled using the -[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) -parameter, and is disabled by default. -If enabled, internal ADCs are not used. - -### Usage {#ads1115_usage} - -``` -ads1115 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 72 - - stop - - status print status info -``` - ## atxxxx Source: [drivers/osd/atxxxx](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/atxxxx) @@ -136,6 +45,26 @@ atxxxx [arguments...] status print status info ``` +## auterion_autostarter + +Source: [drivers/auterion_autostarter](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/auterion_autostarter) + +### Description + +Driver for starting and auto-detecting different power monitors. + +### Usage {#auterion_autostarter_usage} + +``` +auterion_autostarter [arguments...] + Commands: + start + + stop + + status print status info +``` + ## batmon Source: [drivers/smart_battery/batmon](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/smart_battery/batmon) @@ -808,6 +737,64 @@ lsm303agr [arguments...] status print status info ``` +## mcp230xx + +Source: [lib/drivers/mcp_common](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/mcp_common) + +### Usage {#mcp230xx_usage} + +``` +mcp230xx [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 39 + [-D ] Direction (1=Input, 0=Output) + default: 0 + [-O ] Output + default: 0 + [-P ] Pullups + default: 0 + [-U ] Update Interval [ms] + default: 0 + [-M ] First minor number + default: 0 + + stop + + status print status info +``` + +## mcp9808 + +Source: [drivers/temperature_sensor/mcp9808](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/temperature_sensor/mcp9808) + +### Usage {#mcp9808_usage} + +``` +mcp9808 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 24 + + stop + + status print status info +``` + ## msp_osd Source: [drivers/osd/msp_osd](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/msp_osd) @@ -958,26 +945,6 @@ pca9685_pwm_out [arguments...] status print status info ``` -## pm_selector_auterion - -Source: [drivers/power_monitor/pm_selector_auterion](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/power_monitor/pm_selector_auterion) - -### Description - -Driver for starting and auto-detecting different power monitors. - -### Usage {#pm_selector_auterion_usage} - -``` -pm_selector_auterion [arguments...] - Commands: - start - - stop - - status print status info -``` - ## pmw3901 Source: [drivers/optical_flow/pmw3901](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/optical_flow/pmw3901) @@ -1142,7 +1109,7 @@ px4io [arguments...] ## rgbled -Source: [drivers/lights/rgbled_ncp5623c](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/lights/rgbled_ncp5623c) +Source: [drivers/lights/rgbled](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/lights/rgbled) ### Usage {#rgbled_usage} @@ -1157,9 +1124,7 @@ rgbled [arguments...] [-f ] bus frequency in kHz [-q] quiet startup (no message if no device found) [-a ] I2C address - default: 57 - [-o ] RGB PWM Assignment - default: 123 + default: 85 stop @@ -1471,6 +1436,30 @@ tap_esc [arguments...] default: 4 ``` +## tmp102 + +Source: [drivers/temperature_sensor/tmp102](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/temperature_sensor/tmp102) + +### Usage {#tmp102_usage} + +``` +tmp102 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 72 + + stop + + status print status info +``` + ## tone_alarm Source: [drivers/tone_alarm](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/tone_alarm) @@ -1660,6 +1649,76 @@ voxlpm [arguments...] status print status info ``` +## vtx + +Source: [drivers/vtx](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/vtx) + +### Description + +This module communicates with a VTX camera via serial port. It can be used to +configure the camera settings and to control the camera's video transmission. +Supported protocols are: + +- SmartAudio v1, v2.0, v2.1 +- Tramp + +### Usage {#vtx_usage} + +``` +vtx [arguments...] + Commands: + start + -d VTX device + values: + + Sets an entry in the mapping table: + + + stop + + status print status info +``` + +## vtxtable + +Source: [drivers/vtxtable](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/vtxtable) + +### Description + +Manages the VTX frequency, power level and RC mapping table for VTX configuration. + +### Usage {#vtxtable_usage} + +``` +vtxtable [arguments...] + Commands: + status Shows the current VTX table configuration. + + name Sets the VTX table name: + + bands Sets the number of bands: + + band Sets the band frequencies: <1-index> + + + channels Sets the number of channels: + + powerlevels Sets number of power levels: + + powervalues Sets the power level values: + + powerlabels Sets the power level labels: <3 chars...> + + Sets an entry in the mapping table: <0-index> + + + clear Clears the VTX table configuration. + + save Saves the VTX config to a file: + + load Loads the VTX config from a file: +``` + ## zenoh Source: [modules/zenoh](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/zenoh) diff --git a/docs/en/modules/modules_driver_adc.md b/docs/en/modules/modules_driver_adc.md new file mode 100644 index 0000000000..cecdbff037 --- /dev/null +++ b/docs/en/modules/modules_driver_adc.md @@ -0,0 +1,107 @@ +# Modules Reference: Adc (Driver) + +## TLA2528 + +Source: [drivers/adc/tla2528](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/tla2528) + +### Usage {#TLA2528_usage} + +``` +TLA2528 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` + +## adc + +Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) + +### Description + +ADC driver. + +### Usage {#adc_usage} + +``` +adc [arguments...] + Commands: + start + + test + [-n] Do not publish ADC report, only system power + + stop + + status print status info +``` + +## ads1115 + +Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) + +### Description + +Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. + +The driver is included by default in firmware for boards that do not have an internal analog to digital converter, +such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) +(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). + +It is enabled/disabled using the +[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) +parameter, and is disabled by default. +If enabled, internal ADCs are not used. + +### Usage {#ads1115_usage} + +``` +ads1115 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 72 + + stop + + status print status info +``` + +## ads7953 + +Source: [drivers/adc/ads7953](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads7953) + +### Usage {#ads7953_usage} + +``` +ads7953 [arguments...] + Commands: + start + [-s] Internal SPI bus(es) + [-S] External SPI bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-c ] chip-select pin (for internal SPI) or index (for external SPI) + [-m ] SPI mode + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` diff --git a/docs/en/modules/modules_driver_airspeed_sensor.md b/docs/en/modules/modules_driver_airspeed_sensor.md index a1545bfe53..efab35a02a 100644 --- a/docs/en/modules/modules_driver_airspeed_sensor.md +++ b/docs/en/modules/modules_driver_airspeed_sensor.md @@ -4,8 +4,8 @@ Source: [drivers/differential_pressure/asp5033](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/differential_pressure/asp5033) - ### Description + Driver to enable an external [ASP5033] (https://www.qio-tek.com/index.php/product/qiotek-asp5033-dronecan-airspeed-and-compass-module/) TE connected via I2C. diff --git a/docs/en/modules/modules_driver_camera.md b/docs/en/modules/modules_driver_camera.md index 58f3cfb45d..c63df4619f 100644 --- a/docs/en/modules/modules_driver_camera.md +++ b/docs/en/modules/modules_driver_camera.md @@ -4,7 +4,6 @@ Source: [drivers/camera_trigger](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/camera_trigger) - ### Description Camera trigger driver. diff --git a/docs/en/modules/modules_driver_distance_sensor.md b/docs/en/modules/modules_driver_distance_sensor.md index af48d491a5..101ba55dd3 100644 --- a/docs/en/modules/modules_driver_distance_sensor.md +++ b/docs/en/modules/modules_driver_distance_sensor.md @@ -98,13 +98,56 @@ leddar_one [arguments...] stop Stop driver ``` +## lightware_grf_serial + +Source: [drivers/distance_sensor/lightware_grf_serial](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_grf_serial) + +### Description + +Serial bus driver for the Lightware GRF Laser rangefinder. + +### Configuration + +https://docs.px4.io/main/en/sensor/grf_lidar + +### Parameters + +https://docs.px4.io/main/en/advanced_config/parameter_reference#GRF_SENS_MODEL +https://docs.px4.io/main/en/advanced_config/parameter_reference#GRF_RATE_CFG +https://docs.px4.io/main/en/advanced_config/parameter_reference#SENS_EN_GRF_CFG + +### Examples + +Attempt to start driver on a specified serial device. + +``` +lightware_grf_serial start -d /dev/ttyS1 +``` + +Stop driver + +``` +lightware_grf_serial stop +``` + +### Usage {#lightware_grf_serial_usage} + +``` +lightware_grf_serial [arguments...] + Commands: + start Start driver + -d Serial device + + stop Stop driver +``` + ## lightware_laser_i2c Source: [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_laser_i2c) ### Description -I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20. +I2C bus driver for Lightware LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20, SF/LW30/d, GRF250, GRF500. Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html @@ -122,8 +165,6 @@ lightware_laser_i2c [arguments...] [-q] quiet startup (no message if no device found) [-a ] I2C address default: 102 - [-R ] Sensor rotation - downward facing by default - default: 25 stop diff --git a/docs/en/modules/modules_driver_ins.md b/docs/en/modules/modules_driver_ins.md index 408066a914..844aa645bb 100644 --- a/docs/en/modules/modules_driver_ins.md +++ b/docs/en/modules/modules_driver_ins.md @@ -45,6 +45,41 @@ MicroStrain [arguments...] status Driver status ``` +## eulernav_bahrs + +Source: [drivers/ins/eulernav_bahrs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/eulernav_bahrs) + +### Description + +Serial bus driver for the EULER-NAV Baro-Inertial AHRS. + +### Examples + +Attempt to start driver on a specified serial device. + +``` +eulernav_bahrs start -d /dev/ttyS1 +``` + +Stop driver + +``` +eulernav_bahrs stop +``` + +### Usage {#eulernav_bahrs_usage} + +``` +eulernav_bahrs [arguments...] + Commands: + start Start driver + -d Serial device + + status Print driver status + + stop Stop driver +``` + ## ilabs Source: [drivers/ins/ilabs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/ilabs) @@ -90,6 +125,31 @@ ilabs [arguments...] status Print driver status ``` +## sbgecom + +Source: [drivers/ins/sbgecom](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/sbgecom) + +Description du module + +### Usage {#sbgecom_usage} + +``` +sbgecom [arguments...] + Commands: + start Start driver + [-d ] Serial device + default: /dev/ttyS0 + [-b ] Baudrate device + default: 921600 + [-f ] Config JSON file path + default: /etc/extras/sbg_settings\.json + [-s ] Config JSON string + + status Driver status + + stop Stop driver +``` + ## vectornav Source: [drivers/ins/vectornav](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/vectornav) diff --git a/docs/en/modules/modules_driver_optical_flow.md b/docs/en/modules/modules_driver_optical_flow.md index 2c734b5c3f..d69b6d28cc 100644 --- a/docs/en/modules/modules_driver_optical_flow.md +++ b/docs/en/modules/modules_driver_optical_flow.md @@ -4,7 +4,6 @@ Source: [drivers/optical_flow/thoneflow](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/optical_flow/thoneflow) - ### Description Serial bus driver for the ThoneFlow-3901U optical flow sensor. @@ -16,10 +15,13 @@ Setup/usage information: https://docs.px4.io/main/en/sensor/pmw3901.html#thone-t ### Examples Attempt to start driver on a specified serial device. + ``` thoneflow start -d /dev/ttyS1 ``` + Stop driver + ``` thoneflow stop ``` diff --git a/docs/en/modules/modules_driver_radio_control.md b/docs/en/modules/modules_driver_radio_control.md index 98489438e5..1a2b5da0c0 100644 --- a/docs/en/modules/modules_driver_radio_control.md +++ b/docs/en/modules/modules_driver_radio_control.md @@ -4,10 +4,9 @@ Source: [drivers/rc/crsf_rc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/rc/crsf_rc) - ### Description -This module parses the CRSF RC uplink protocol and generates CRSF downlink telemetry data +This module parses the CRSF RC uplink protocol and generates CRSF downlink telemetry data ### Usage {#crsf_rc_usage} @@ -18,6 +17,8 @@ crsf_rc [arguments...] [-d ] RC device values: , default: /dev/ttyS3 + inject Inject frame data bytes (for testing) + stop status print status info @@ -27,10 +28,9 @@ crsf_rc [arguments...] Source: [drivers/rc/dsm_rc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/rc/dsm_rc) - ### Description -This module does Spektrum DSM RC input parsing. +This module does Spektrum DSM RC input parsing. ### Usage {#dsm_rc_usage} @@ -52,10 +52,9 @@ dsm_rc [arguments...] Source: [drivers/rc/ghst_rc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/rc/ghst_rc) - ### Description -This module does Ghost (GHST) RC input parsing. +This module does Ghost (GHST) RC input parsing. ### Usage {#ghst_rc_usage} @@ -75,9 +74,10 @@ ghst_rc [arguments...] Source: [drivers/rc_input](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/rc_input) - ### Description + This module does the RC input parsing and auto-selecting the method. Supported methods are: + - PPM - SBUS - DSM @@ -85,7 +85,6 @@ This module does the RC input parsing and auto-selecting the method. Supported m - ST24 - TBS Crossfire (CRSF) - ### Usage {#rc_input_usage} ``` @@ -106,10 +105,9 @@ rc_input [arguments...] Source: [drivers/rc/sbus_rc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/rc/sbus_rc) - ### Description -This module does SBUS RC input parsing. +This module does SBUS RC input parsing. ### Usage {#sbus_rc_usage} diff --git a/docs/en/modules/modules_driver_transponder.md b/docs/en/modules/modules_driver_transponder.md index 799f9a9179..dd9e4bdece 100644 --- a/docs/en/modules/modules_driver_transponder.md +++ b/docs/en/modules/modules_driver_transponder.md @@ -4,25 +4,24 @@ Source: [drivers/transponder/sagetech_mxs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/transponder/sagetech_mxs) + ### Description - ### Description + This driver integrates the Sagetech MXS Certified Transponder to send and receive ADSB messages and traffic. - This driver integrates the Sagetech MXS Certified Transponder to send and receive ADSB messages and traffic. + ### Examples - ### Examples + Attempt to start driver on a specified serial device. + $ sagetech_mxs start -d /dev/ttyS1 + Stop driver + $ sagetech_mxs stop + Set Flight ID (8 char max) + $ sagetech_mxs flight_id MXS12345 + Set MXS Operating Mode + $ sagetech_mxs opmode off/on/stby/alt + $ sagetech_mxs opmode 0/1/2/3 + Set the Squawk Code + $ sagetech_mxs squawk 1200 - Attempt to start driver on a specified serial device. - $ sagetech_mxs start -d /dev/ttyS1 - Stop driver - $ sagetech_mxs stop - Set Flight ID (8 char max) - $ sagetech_mxs flight_id MXS12345 - Set MXS Operating Mode - $ sagetech_mxs opmode off/on/stby/alt - $ sagetech_mxs opmode 0/1/2/3 - Set the Squawk Code - $ sagetech_mxs squawk 1200 - ### Usage {#sagetech_mxs_usage} ``` diff --git a/docs/en/modules/modules_estimator.md b/docs/en/modules/modules_estimator.md index 71041bcd50..8186889dd4 100644 --- a/docs/en/modules/modules_estimator.md +++ b/docs/en/modules/modules_estimator.md @@ -1,15 +1,12 @@ # Modules Reference: Estimator - - ## AttitudeEstimatorQ Source: [modules/attitude_estimator_q](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/attitude_estimator_q) - ### Description -Attitude estimator q. +Attitude estimator q. ### Usage {#AttitudeEstimatorQ_usage} @@ -27,8 +24,8 @@ AttitudeEstimatorQ [arguments...] Source: [modules/airspeed_selector](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/airspeed_selector) - ### Description + This module provides a single airspeed_validated topic, containing indicated (IAS), calibrated (CAS), true airspeed (TAS) and the information if the estimation currently is invalid and if based sensor readings or on groundspeed minus windspeed. @@ -37,7 +34,6 @@ to a valid sensor in case of failure detection. For failure detection as well as the estimation of a scale factor from IAS to CAS, it runs several wind estimators and also publishes those. - ### Usage {#airspeed_estimator_usage} ``` @@ -54,8 +50,8 @@ airspeed_estimator [arguments...] Source: [modules/ekf2](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2) - ### Description + Attitude and position estimator using an Extended Kalman Filter. It is used for Multirotors and Fixed-Wing. The documentation can be found on the [ECL/EKF Overview & Tuning](https://docs.px4.io/main/en/advanced_config/tuning_the_ecl_ekf.html) page. @@ -63,7 +59,6 @@ The documentation can be found on the [ECL/EKF Overview & Tuning](https://docs.p ekf2 can be started in replay mode (`-r`): in this mode, it does not access the system time, but only uses the timestamps from the sensor topics. - ### Usage {#ekf2_usage} ``` @@ -85,10 +80,9 @@ ekf2 [arguments...] Source: [modules/local_position_estimator](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/local_position_estimator) - ### Description -Attitude and position estimator using an Extended Kalman Filter. +Attitude and position estimator using an Extended Kalman Filter. ### Usage {#local_position_estimator_usage} @@ -106,10 +100,8 @@ local_position_estimator [arguments...] Source: [modules/mc_hover_thrust_estimator](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mc_hover_thrust_estimator) - ### Description - ### Usage {#mc_hover_thrust_estimator_usage} ``` diff --git a/docs/en/modules/modules_main.md b/docs/en/modules/modules_main.md index 34e325dcd2..4403a1ffa5 100644 --- a/docs/en/modules/modules_main.md +++ b/docs/en/modules/modules_main.md @@ -1,4 +1,3 @@ - # Modules & Commands Reference The following pages document the PX4 modules, drivers and commands. @@ -21,9 +20,11 @@ the root of the PX4-Autopilot directory: ``` make module_documentation ``` + The generated files will be written to the `modules` directory. ## Categories + - [Autotune](modules_autotune.md) - [Command](modules_command.md) - [Communication](modules_communication.md) diff --git a/docs/en/modules/modules_simulation.md b/docs/en/modules/modules_simulation.md index 18c267517b..f0a12f6604 100644 --- a/docs/en/modules/modules_simulation.md +++ b/docs/en/modules/modules_simulation.md @@ -1,13 +1,11 @@ # Modules Reference: Simulation - - ## simulator_sih Source: [modules/simulation/simulator_sih](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/simulator_sih) - ### Description + This module provides a simulator for quadrotors and fixed-wings running fully inside the hardware autopilot. @@ -18,13 +16,12 @@ This simulator publishes the sensors signals corrupted with realistic noise in order to incorporate the state estimator in the loop. ### Implementation + The simulator implements the equations of motion using matrix algebra. Quaternion representation is used for the attitude. Forward Euler is used for integration. Most of the variables are declared global in the .hpp file to avoid stack overflow. - - ### Usage {#simulator_sih_usage} ``` diff --git a/docs/en/modules/modules_system.md b/docs/en/modules/modules_system.md index c078d9202e..fe9b467cf6 100644 --- a/docs/en/modules/modules_system.md +++ b/docs/en/modules/modules_system.md @@ -127,6 +127,10 @@ commander [arguments...] check Run preflight checks + safety Change prearm safety state + on|off [on] to activate safety, [off] to deactivate safety and allow + control surface movements + arm [-f] Force arming (do not run preflight checks) @@ -140,9 +144,9 @@ commander [arguments...] transition VTOL transition mode Change flight mode - manual|acro|offboard|stabilized|altctl|posctl|position:slow|auto:mission|au - to:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1 - Flight mode + manual|acro|offboard|stabilized|altctl|posctl|altitude_cruise|position:slow + |auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto: + precland|ext1 Flight mode pair @@ -154,6 +158,9 @@ commander [arguments...] lat|lon|alt Origin latitude longitude altitude + set_heading Set current heading + heading degrees from True North [0 360] + poweroff Power off board (if supported) stop @@ -1062,7 +1069,9 @@ uxrce_dds_client [arguments...] values: [-p ] Agent listening port. If not provided, defaults to UXRCE_DDS_PRT - [-n ] Client DDS namespace + [-n ] Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is + between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will + be used stop diff --git a/docs/en/modules/modules_template.md b/docs/en/modules/modules_template.md index 523d9ff02b..10e0e16f05 100644 --- a/docs/en/modules/modules_template.md +++ b/docs/en/modules/modules_template.md @@ -1,27 +1,58 @@ # Modules Reference: Template +## mc_raptor +Source: [modules/mc_raptor](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mc_raptor) + +### Description + +RAPTOR Policy Flight Mode + +### Usage {#mc_raptor_usage} + +``` +mc_raptor [arguments...] + Commands: + start + + intref Modify internal reference + lissajous Set Lissajous trajectory parameters + Amplitude X [m] + Amplitude Y [m] + Amplitude Z [m] + Frequency a + Frequency b + Frequency c + Total duration [s] + Ramp duration [s] + + stop + + status print status info +``` ## module Source: [templates/template_module](https://github.com/PX4/PX4-Autopilot/tree/main/src/templates/template_module) - ### Description + Section that describes the provided module functionality. This is a template for a module running as a task in the background with start/stop/status functionality. ### Implementation + Section describing the high-level implementation of this module. ### Examples + CLI usage example: + ``` module start -f -p 42 ``` - ### Usage {#module_usage} ``` @@ -41,10 +72,9 @@ module [arguments...] Source: [examples/work_item](https://github.com/PX4/PX4-Autopilot/tree/main/src/examples/work_item) - ### Description -Example of a simple module running out of a work queue. +Example of a simple module running out of a work queue. ### Usage {#work_item_example_usage} diff --git a/docs/en/msg_docs/ActionRequest.md b/docs/en/msg_docs/ActionRequest.md index 3579870754..9d3bad8a5f 100644 --- a/docs/en/msg_docs/ActionRequest.md +++ b/docs/en/msg_docs/ActionRequest.md @@ -1,12 +1,56 @@ +--- +pageClass: is-wide-page +--- + # ActionRequest (UORB message) -Action request for the vehicle's main state +Action request for the vehicle's main state. Message represents actions requested by a PX4 internal component towards the main state machine such as a request to arm or switch mode. It allows mapping triggers from various external interfaces like RC channels or MAVLink to cause an action. Request are published by `manual_control` and subscribed by the `commander` and `vtol_att_control` modules. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActionRequest.msg) +**TOPICS:** action_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| action | `uint8` | | [ACTION](#ACTION) | Requested action | +| source | `uint8` | | [SOURCE](#SOURCE) | Request trigger type, such as a switch, button or gesture | +| mode | `uint8` | | | Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. | + +## Enums + +### ACTION {#ACTION} + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------------------- | ------- | ----- | --------------------------------------------------------------------- | +| ACTION_DISARM | `uint8` | 0 | Disarm vehicle | +| ACTION_ARM | `uint8` | 1 | Arm vehicle | +| ACTION_TOGGLE_ARMING | `uint8` | 2 | Toggle arming | +| ACTION_UNKILL | `uint8` | 3 | Revert a kill action | +| ACTION_KILL | `uint8` | 4 | Kill vehicle (instantly stop the motors) | +| ACTION_SWITCH_MODE | `uint8` | 5 | Switch mode. The target mode is set in the `mode` field. | +| ACTION_VTOL_TRANSITION_TO_MULTICOPTER | `uint8` | 6 | Transition to hover flight | +| ACTION_VTOL_TRANSITION_TO_FIXEDWING | `uint8` | 7 | Transition to fast forward flight | +| ACTION_TERMINATION | `uint8` | 8 | Irreversibly output failsafe values on all outputs, trigger parachute | + +### SOURCE {#SOURCE} + +| Name | Type | Value | Description | +| --------------------------------------------------------- | ------- | ----- | --------------------------------------------------------------- | +| SOURCE_STICK_GESTURE | `uint8` | 0 | Triggered by holding the sticks in a certain position | +| SOURCE_RC_SWITCH | `uint8` | 1 | Triggered by an RC switch moving into a certain position | +| SOURCE_RC_BUTTON | `uint8` | 2 | Triggered by a momentary button on the RC being pressed or held | +| SOURCE_RC_MODE_SLOT | `uint8` | 3 | Mode change through the RC mode selection mechanism | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActionRequest.msg) + +::: details Click here to see original file ```c # Action request for the vehicle's main state @@ -15,25 +59,26 @@ Request are published by `manual_control` and subscribed by the `commander` and # It allows mapping triggers from various external interfaces like RC channels or MAVLink to cause an action. # Request are published by `manual_control` and subscribed by the `commander` and `vtol_att_control` modules. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint8 action # [@enum ACTION] Requested action -uint8 ACTION_DISARM = 0 # Disarm vehicle -uint8 ACTION_ARM = 1 # Arm vehicle -uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming -uint8 ACTION_UNKILL = 3 # Revert a kill action -uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) -uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. -uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight -uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight -uint8 ACTION_TERMINATION = 8 # Irreversably output failsafe values on all outputs, trigger parachute +uint8 action # [@enum ACTION] Requested action +uint8 ACTION_DISARM = 0 # Disarm vehicle +uint8 ACTION_ARM = 1 # Arm vehicle +uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming +uint8 ACTION_UNKILL = 3 # Revert a kill action +uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) +uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. +uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight +uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight +uint8 ACTION_TERMINATION = 8 # Irreversibly output failsafe values on all outputs, trigger parachute -uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture -uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position -uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position -uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held -uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism - -uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. +uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture +uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position +uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position +uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held +uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism +uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. ``` + +::: diff --git a/docs/en/msg_docs/ActuatorArmed.md b/docs/en/msg_docs/ActuatorArmed.md index adee89cb21..e859fec479 100644 --- a/docs/en/msg_docs/ActuatorArmed.md +++ b/docs/en/msg_docs/ActuatorArmed.md @@ -1,6 +1,29 @@ +--- +pageClass: is-wide-page +--- + # ActuatorArmed (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorArmed.msg) +**TOPICS:** actuator_armed + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| armed | `bool` | | | Set to true if system is armed | +| prearmed | `bool` | | | Set to true if the actuator safety is disabled but motors are not armed | +| ready_to_arm | `bool` | | | Set to true if system is ready to be armed | +| lockdown | `bool` | | | Set to true if actuators are forced to being disabled (due to emergency or HIL) | +| kill | `bool` | | | Set to true if manual throttle kill switch is engaged | +| termination | `bool` | | | Send out failsafe (by default same as disarmed) output | +| in_esc_calibration_mode | `bool` | | | IO/FMU should ignore messages from the actuator controls topics | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorArmed.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +35,6 @@ bool lockdown # Set to true if actuators are forced to being disabled (due to e bool kill # Set to true if manual throttle kill switch is engaged bool termination # Send out failsafe (by default same as disarmed) output bool in_esc_calibration_mode # IO/FMU should ignore messages from the actuator controls topics - ``` + +::: diff --git a/docs/en/msg_docs/ActuatorControlsStatus.md b/docs/en/msg_docs/ActuatorControlsStatus.md index 2eb1d53f22..f15aff69ee 100644 --- a/docs/en/msg_docs/ActuatorControlsStatus.md +++ b/docs/en/msg_docs/ActuatorControlsStatus.md @@ -1,8 +1,23 @@ +--- +pageClass: is-wide-page +--- + # ActuatorControlsStatus (UORB message) +**TOPICS:** actuator_controls_status_0 actuator_controls_status_1 +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorControlsStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| control_power | `float32[3]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorControlsStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +25,6 @@ uint64 timestamp # time since system start (microseconds) float32[3] control_power # TOPICS actuator_controls_status_0 actuator_controls_status_1 - ``` + +::: diff --git a/docs/en/msg_docs/ActuatorMotors.md b/docs/en/msg_docs/ActuatorMotors.md index 06fbd1b908..e50477ebb2 100644 --- a/docs/en/msg_docs/ActuatorMotors.md +++ b/docs/en/msg_docs/ActuatorMotors.md @@ -1,11 +1,38 @@ +--- +pageClass: is-wide-page +--- + # ActuatorMotors (UORB message) -Motor control message +Motor control message. Normalised thrust setpoint for up to 12 motors. Published by the vehicle's allocation and consumed by the ESC protocol drivers e.g. PWM, DSHOT, UAVCAN. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) +**TOPICS:** actuator_motors + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Sampling timestamp of the data this control response is based on | +| reversible_flags | `uint16` | | | Bitset indicating which motors are configured to be reversible | +| control | `float32[12]` | | [-1 : 1] | Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| ACTUATOR_FUNCTION_MOTOR1 | `uint8` | 101 | +| NUM_CONTROLS | `uint8` | 12 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) + +::: details Click here to see original file ```c # Motor control message @@ -15,14 +42,15 @@ Published by the vehicle's allocation and consumed by the ESC protocol drivers e uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint16 reversible_flags # Bitset indicating which motors are configured to be reversible +uint16 reversible_flags # [-] Bitset indicating which motors are configured to be reversible -uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 - -uint8 NUM_CONTROLS = 12 -float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 # +uint8 NUM_CONTROLS = 12 # +float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) ``` + +::: diff --git a/docs/en/msg_docs/ActuatorOutputs.md b/docs/en/msg_docs/ActuatorOutputs.md index 3fc4a94c9d..fa8b313c4c 100644 --- a/docs/en/msg_docs/ActuatorOutputs.md +++ b/docs/en/msg_docs/ActuatorOutputs.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # ActuatorOutputs (UORB message) +**TOPICS:** actuator_outputs actuator_outputs_sim actuator_outputs_debug +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorOutputs.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| noutputs | `uint32` | | | valid outputs | +| output | `float32[16]` | | | output data, in natural output units | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------- | ------- | ----- | ------------------- | +| NUM_ACTUATOR_OUTPUTS | `uint8` | 16 | +| NUM_ACTUATOR_OUTPUT_GROUPS | `uint8` | 4 | for sanity checking | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorOutputs.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +36,6 @@ float32[16] output # output data, in natural output units # actuator_outputs_sim is used for SITL, HITL & SIH (with an output range of [-1, 1]) # TOPICS actuator_outputs actuator_outputs_sim actuator_outputs_debug - ``` + +::: diff --git a/docs/en/msg_docs/ActuatorServos.md b/docs/en/msg_docs/ActuatorServos.md index ffe01e2f49..de537fcca6 100644 --- a/docs/en/msg_docs/ActuatorServos.md +++ b/docs/en/msg_docs/ActuatorServos.md @@ -1,11 +1,36 @@ +--- +pageClass: is-wide-page +--- + # ActuatorServos (UORB message) -Servo control message +Servo control message. Normalised output setpoint for up to 8 servos. Published by the vehicle's allocation and consumed by the actuator output drivers. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) +**TOPICS:** actuator_servos + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Sampling timestamp of the data this control response is based on | +| control | `float32[8]` | | [-1 : 1] | Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| NUM_CONTROLS | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) + +::: details Click here to see original file ```c # Servo control message @@ -15,10 +40,11 @@ Published by the vehicle's allocation and consumed by the actuator output driver uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on - -uint8 NUM_CONTROLS = 8 -float32[8] control # [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint8 NUM_CONTROLS = 8 # +float32[8] control # [-] [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. ``` + +::: diff --git a/docs/en/msg_docs/ActuatorServosTrim.md b/docs/en/msg_docs/ActuatorServosTrim.md index 07f42a43ce..380f53832b 100644 --- a/docs/en/msg_docs/ActuatorServosTrim.md +++ b/docs/en/msg_docs/ActuatorServosTrim.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # ActuatorServosTrim (UORB message) -Servo trims, added as offset to servo outputs +Servo trims, added as offset to servo outputs. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorServosTrim.msg) +**TOPICS:** actuator_servostrim + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| trim | `float32[8]` | | | range: [-1, 1] | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------- | ------- | ----- | ----------- | +| NUM_CONTROLS | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorServosTrim.msg) + +::: details Click here to see original file ```c # Servo trims, added as offset to servo outputs @@ -10,5 +33,6 @@ uint64 timestamp # time since system start (microseconds) uint8 NUM_CONTROLS = 8 float32[8] trim # range: [-1, 1] - ``` + +::: diff --git a/docs/en/msg_docs/ActuatorTest.md b/docs/en/msg_docs/ActuatorTest.md index 923d829774..820c6214fa 100644 --- a/docs/en/msg_docs/ActuatorTest.md +++ b/docs/en/msg_docs/ActuatorTest.md @@ -1,8 +1,38 @@ +--- +pageClass: is-wide-page +--- + # ActuatorTest (UORB message) +**TOPICS:** actuator_test +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorTest.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------- | --------- | ------------ | ---------- | ------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| action | `uint8` | | | one of ACTION\_\* | +| function | `uint16` | | | actuator output function | +| value | `float32` | | | range: [-1, 1], where 1 means maximum positive output, | +| timeout_ms | `uint32` | | | timeout in ms after which to exit test mode (if 0, do not time out) | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------- | ------- | ----- | ---------------------------------------------------- | +| ACTION_RELEASE_CONTROL | `uint8` | 0 | exit test mode for the given function | +| ACTION_DO_CONTROL | `uint8` | 1 | enable actuator test mode | +| FUNCTION_MOTOR1 | `uint8` | 101 | +| MAX_NUM_MOTORS | `uint8` | 12 | +| FUNCTION_SERVO1 | `uint8` | 201 | +| MAX_NUM_SERVOS | `uint8` | 8 | +| ORB_QUEUE_LENGTH | `uint8` | 16 | >= MAX_NUM_MOTORS to support code in esc_calibration | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ActuatorTest.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -26,5 +56,6 @@ float32 value # range: [-1, 1], where 1 means maximum positive output, uint32 timeout_ms # timeout in ms after which to exit test mode (if 0, do not time out) uint8 ORB_QUEUE_LENGTH = 16 # >= MAX_NUM_MOTORS to support code in esc_calibration - ``` + +::: diff --git a/docs/en/msg_docs/AdcReport.md b/docs/en/msg_docs/AdcReport.md index 53ab9a2f07..9cb57dc674 100644 --- a/docs/en/msg_docs/AdcReport.md +++ b/docs/en/msg_docs/AdcReport.md @@ -1,15 +1,43 @@ +--- +pageClass: is-wide-page +--- + # AdcReport (UORB message) +ADC raw data. +Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AdcReport.msg) +**TOPICS:** adc_report + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------- | ----------- | ------------ | ---------- | ------------------------------------------------------------------------------------ | +| timestamp | `uint64` | us | | Time since system start | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| channel_id | `int16[16]` | | | ADC channel IDs, negative for non-existent, TODO: should be kept same as array index | +| raw_data | `int32[16]` | | | ADC channel raw value, accept negative value, valid if channel ID is positive | +| resolution | `uint32` | | | ADC channel resolution | +| v_ref | `float32` | V | | ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AdcReport.msg) + +::: details Click here to see original file ```c -uint64 timestamp # time since system start (microseconds) -uint32 device_id # unique device ID for the sensor that does not change between power cycles -int16[12] channel_id # ADC channel IDs, negative for non-existent, TODO: should be kept same as array index -int32[12] raw_data # ADC channel raw value, accept negative value, valid if channel ID is positive -uint32 resolution # ADC channel resolution -float32 v_ref # ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) +# ADC raw data. +# +# Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. +uint64 timestamp # [us] Time since system start +uint32 device_id # [-] unique device ID for the sensor that does not change between power cycles +int16[16] channel_id # [-] ADC channel IDs, negative for non-existent, TODO: should be kept same as array index +int32[16] raw_data # [-] ADC channel raw value, accept negative value, valid if channel ID is positive +uint32 resolution # [-] ADC channel resolution +float32 v_ref # [V] ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) ``` + +::: diff --git a/docs/en/msg_docs/Airspeed.md b/docs/en/msg_docs/Airspeed.md index 7309747f66..d769925620 100644 --- a/docs/en/msg_docs/Airspeed.md +++ b/docs/en/msg_docs/Airspeed.md @@ -1,11 +1,31 @@ +--- +pageClass: is-wide-page +--- + # Airspeed (UORB message) -Airspeed data from sensors +Airspeed data from sensors. This is published by airspeed sensor drivers, CAN airspeed sensors, simulators. It is subscribed by the airspeed selector module, which validates the data from multiple sensors and passes on a single estimation to the EKF, controllers and telemetry providers. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Airspeed.msg) +**TOPICS:** airspeed + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | -------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Timestamp of the raw data | +| indicated_airspeed_m_s | `float32` | m/s | | Indicated airspeed | +| true_airspeed_m_s | `float32` | m/s | | True airspeed | +| confidence | `float32` | | [0 : 1] | Confidence value for this sensor | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Airspeed.msg) + +::: details Click here to see original file ```c # Airspeed data from sensors @@ -13,10 +33,11 @@ It is subscribed by the airspeed selector module, which validates the data from # This is published by airspeed sensor drivers, CAN airspeed sensors, simulators. # It is subscribed by the airspeed selector module, which validates the data from multiple sensors and passes on a single estimation to the EKF, controllers and telemetry providers. -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Timestamp of the raw data -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed -float32 true_airspeed_m_s # [m/s] True airspeed -float32 confidence # [@range 0,1] Confidence value for this sensor - +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +float32 indicated_airspeed_m_s # [m/s] Indicated airspeed +float32 true_airspeed_m_s # [m/s] True airspeed +float32 confidence # [@range 0,1] Confidence value for this sensor ``` + +::: diff --git a/docs/en/msg_docs/AirspeedValidated.md b/docs/en/msg_docs/AirspeedValidated.md index b5fe9191a5..92b2f35f1d 100644 --- a/docs/en/msg_docs/AirspeedValidated.md +++ b/docs/en/msg_docs/AirspeedValidated.md @@ -1,31 +1,84 @@ +--- +pageClass: is-wide-page +--- + # AirspeedValidated (UORB message) +Validated airspeed. +Provides information about airspeed (indicated, true, calibrated) and the source of the data. +Used by controllers, estimators and for airspeed reporting to operator. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/AirspeedValidated.msg) +**TOPICS:** airspeed_validated + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------------- | --------- | ------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| indicated_airspeed_m_s | `float32` | m/s | | Indicated airspeed (IAS) (Invalid: NaN) | +| calibrated_airspeed_m_s | `float32` | m/s | | Calibrated airspeed (CAS) (Invalid: NaN) | +| true_airspeed_m_s | `float32` | m/s | | True airspeed (TAS) (Invalid: NaN) | +| airspeed_source | `int8` | | [SOURCE](#SOURCE) | Source of currently published airspeed values | +| calibrated_ground_minus_wind_m_s | `float32` | m/s | | CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption (Invalid: NaN) | +| calibraded_airspeed_synth_m_s | `float32` | m/s | | Synthetic airspeed (Invalid: NaN) | +| airspeed_derivative_filtered | `float32` | m/s^2 | | Filtered indicated airspeed derivative | +| throttle_filtered | `float32` | | | Filtered fixed-wing throttle | +| pitch_filtered | `float32` | rad | | Filtered pitch | + +## Enums + +### SOURCE {#SOURCE} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------- | ------ | ----- | ----------------------- | +| SOURCE_DISABLED | `int8` | -1 | Disabled | +| SOURCE_GROUND_MINUS_WIND | `int8` | 0 | Ground speed minus wind | +| SOURCE_SENSOR_1 | `int8` | 1 | Sensor 1 | +| SOURCE_SENSOR_2 | `int8` | 2 | Sensor 2 | +| SOURCE_SENSOR_3 | `int8` | 3 | Sensor 3 | +| SOURCE_SYNTHETIC | `int8` | 4 | Synthetic airspeed | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/AirspeedValidated.msg) + +::: details Click here to see original file ```c +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + + uint32 MESSAGE_VERSION = 1 -uint64 timestamp # time since system start (microseconds) +uint64 timestamp # [us] Time since system start -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed (IAS), set to NAN if invalid -float32 calibrated_airspeed_m_s # [m/s] Calibrated airspeed (CAS), set to NAN if invalid -float32 true_airspeed_m_s # [m/s] True airspeed (TAS), set to NAN if invalid +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) -int8 airspeed_source # Source of currently published airspeed values -int8 DISABLED = -1 -int8 GROUND_MINUS_WIND = 0 -int8 SENSOR_1 = 1 -int8 SENSOR_2 = 2 -int8 SENSOR_3 = 3 -int8 SYNTHETIC = 4 - -# debug states -float32 calibrated_ground_minus_wind_m_s # CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid -float32 calibraded_airspeed_synth_m_s # synthetic airspeed in m/s, set to NAN if invalid -float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] -float32 throttle_filtered # filtered fixed-wing throttle [-] -float32 pitch_filtered # filtered pitch [rad] +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch ``` + +::: diff --git a/docs/en/msg_docs/AirspeedValidatedV0.md b/docs/en/msg_docs/AirspeedValidatedV0.md index 9cd392a955..8650ee3116 100644 --- a/docs/en/msg_docs/AirspeedValidatedV0.md +++ b/docs/en/msg_docs/AirspeedValidatedV0.md @@ -1,8 +1,38 @@ +--- +pageClass: is-wide-page +--- + # AirspeedValidatedV0 (UORB message) +**TOPICS:** airspeed_validatedv0 +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/AirspeedValidatedV0.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| indicated_airspeed_m_s | `float32` | | | indicated airspeed in m/s (IAS), set to NAN if invalid | +| calibrated_airspeed_m_s | `float32` | | | calibrated airspeed in m/s (CAS, accounts for instrumentation errors), set to NAN if invalid | +| true_airspeed_m_s | `float32` | | | true filtered airspeed in m/s (TAS), set to NAN if invalid | +| calibrated_ground_minus_wind_m_s | `float32` | | | CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid | +| true_ground_minus_wind_m_s | `float32` | | | TAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid | +| airspeed_sensor_measurement_valid | `bool` | | | True if data from at least one airspeed sensor is declared valid. | +| selected_airspeed_index | `int8` | | | 1-3: airspeed sensor index, 0: groundspeed-windspeed, -1: airspeed invalid | +| airspeed_derivative_filtered | `float32` | | | filtered indicated airspeed derivative [m/s/s] | +| throttle_filtered | `float32` | | | filtered fixed-wing throttle [-] | +| pitch_filtered | `float32` | | | filtered pitch [rad] | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/AirspeedValidatedV0.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -23,5 +53,6 @@ int8 selected_airspeed_index # 1-3: airspeed sensor index, 0: groundspeed-win float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] float32 throttle_filtered # filtered fixed-wing throttle [-] float32 pitch_filtered # filtered pitch [rad] - ``` + +::: diff --git a/docs/en/msg_docs/AirspeedWind.md b/docs/en/msg_docs/AirspeedWind.md index 23e91399b0..3be13ac999 100644 --- a/docs/en/msg_docs/AirspeedWind.md +++ b/docs/en/msg_docs/AirspeedWind.md @@ -1,6 +1,10 @@ +--- +pageClass: is-wide-page +--- + # AirspeedWind (UORB message) -Wind estimate (from airspeed_selector) +Wind estimate (from airspeed_selector). Contains wind estimation and airspeed innovation information estimated by the WindEstimator in the airspeed selector module. @@ -8,7 +12,41 @@ in the airspeed selector module. This message is published by the airspeed selector for debugging purposes, and is not subscribed to by any other modules. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AirspeedWind.msg) +**TOPICS:** airspeed_wind + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | --------- | ------------ | ---------- | --------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Timestamp of the raw data | +| windspeed_north | `float32` | m/s | | Wind component in north / X direction | +| windspeed_east | `float32` | m/s | | Wind component in east / Y direction | +| variance_north | `float32` | (m/s)^2 | | Wind estimate error variance in north / X direction (Invalid: 0 if not estimated) | +| variance_east | `float32` | (m/s)^2 | | Wind estimate error variance in east / Y direction (Invalid: 0 if not estimated) | +| tas_innov | `float32` | m/s | | True airspeed innovation | +| tas_innov_var | `float32` | m/s | | True airspeed innovation variance | +| tas_scale_raw | `float32` | | | Estimated true airspeed scale factor (not validated) | +| tas_scale_raw_var | `float32` | | | True airspeed scale factor variance | +| tas_scale_validated | `float32` | | | Estimated true airspeed scale factor after validation | +| beta_innov | `float32` | rad | | Sideslip measurement innovation | +| beta_innov_var | `float32` | rad^2 | | Sideslip measurement innovation variance | +| source | `uint8` | | | source of wind estimate | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ---------------------------------------------------------------------------------- | +| SOURCE_AS_BETA_ONLY | `uint8` | 0 | Wind estimate only based on synthetic sideslip fusion | +| SOURCE_AS_SENSOR_1 | `uint8` | 1 | Combined synthetic sideslip and airspeed fusion (data from first airspeed sensor) | +| SOURCE_AS_SENSOR_2 | `uint8` | 2 | Combined synthetic sideslip and airspeed fusion (data from second airspeed sensor) | +| SOURCE_AS_SENSOR_3 | `uint8` | 3 | Combined synthetic sideslip and airspeed fusion (data from third airspeed sensor) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AirspeedWind.msg) + +::: details Click here to see original file ```c # Wind estimate (from airspeed_selector) @@ -45,5 +83,6 @@ uint8 SOURCE_AS_BETA_ONLY = 0 # Wind estimate only based on synthetic sideslip f uint8 SOURCE_AS_SENSOR_1 = 1 # Combined synthetic sideslip and airspeed fusion (data from first airspeed sensor) uint8 SOURCE_AS_SENSOR_2 = 2 # Combined synthetic sideslip and airspeed fusion (data from second airspeed sensor) uint8 SOURCE_AS_SENSOR_3 = 3 # Combined synthetic sideslip and airspeed fusion (data from third airspeed sensor) - ``` + +::: diff --git a/docs/en/msg_docs/ArmingCheckReply.md b/docs/en/msg_docs/ArmingCheckReply.md index d5e3322506..b6119357d7 100644 --- a/docs/en/msg_docs/ArmingCheckReply.md +++ b/docs/en/msg_docs/ArmingCheckReply.md @@ -1,3 +1,7 @@ +--- +pageClass: is-wide-page +--- + # ArmingCheckReply (UORB message) Arming check reply. @@ -9,10 +13,57 @@ The request is sent regularly to all registered ROS modes, even while armed, so Note that the external component is identified by its registration_id, which is allocated to the component during registration (arming_check_id in RegisterExtComponentReply). The message is not used by internal/FMU components, as their mode requirements are known at compile time. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckReply.msg) +**TOPICS:** arming_checkreply + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------------- | ---------- | ------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start. | +| request_id | `uint8` | | | Id of ArmingCheckRequest for which this is a response | +| registration_id | `uint8` | | | Id of external component emitting this response | +| health_component_index | `uint8` | | [HEALTH_COMPONENT_INDEX](#HEALTH_COMPONENT_INDEX) | +| health_component_is_present | `bool` | | | Unused. Intended for use with health events interface (health_component_t in events.json) | +| health_component_warning | `bool` | | | Unused. Intended for use with health events interface (health_component_t in events.json) | +| health_component_error | `bool` | | | Unused. Intended for use with health events interface (health_component_t in events.json) | +| can_arm_and_run | `bool` | | | True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed | +| num_events | `uint8` | | | Number of queued failure messages (Event) in the events field | +| events | `Event[5]` | | | Arming failure reasons (Queue of events to report to GCS) | +| mode_req_angular_velocity | `bool` | | | Requires angular velocity estimate (e.g. from gyroscope) | +| mode_req_attitude | `bool` | | | Requires an attitude estimate | +| mode_req_local_alt | `bool` | | | Requires a local altitude estimate | +| mode_req_local_position | `bool` | | | Requires a local position estimate | +| mode_req_local_position_relaxed | `bool` | | | Requires a more relaxed global position estimate | +| mode_req_global_position | `bool` | | | Requires a global position estimate | +| mode_req_global_position_relaxed | `bool` | | | Requires a relaxed global position estimate | +| mode_req_mission | `bool` | | | Requires an uploaded mission | +| mode_req_home_position | `bool` | | | Requires a home position (such as RTL/Return mode) | +| mode_req_prevent_arming | `bool` | | | Prevent arming (such as in Land mode) | +| mode_req_manual_control | `bool` | | | Requires a manual controller | + +## Enums + +### HEALTH_COMPONENT_INDEX {#HEALTH_COMPONENT_INDEX} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | ------- | ----- | --------------------------------------------------------- | +| HEALTH_COMPONENT_INDEX_NONE | `uint8` | 0 | Index of health component for which this response applies | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckReply.msg) + +::: details Click here to see original file ```c -# Arming check reply. +# Arming check reply # # This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. # The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -21,39 +72,40 @@ The message is not used by internal/FMU components, as their mode requirements a # Note that the external component is identified by its registration_id, which is allocated to the component during registration (arming_check_id in RegisterExtComponentReply). # The message is not used by internal/FMU components, as their mode requirements are known at compile time. -uint32 MESSAGE_VERSION = 1 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # [us] Time since system start. -uint8 request_id # Id of ArmingCheckRequest for which this is a response. -uint8 registration_id # Id of external component emitting this response. +uint8 request_id # [-] Id of ArmingCheckRequest for which this is a response +uint8 registration_id # [-] Id of external component emitting this response -uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies. +uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies -uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] -bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json). +uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] +bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json) -bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed. +bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed -uint8 num_events # Number of queued failure messages (Event) in the events field. +uint8 num_events # Number of queued failure messages (Event) in the events field -Event[5] events # Arming failure reasons (Queue of events to report to GCS). +Event[5] events # Arming failure reasons (Queue of events to report to GCS) # Mode requirements -bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope). -bool mode_req_attitude # Requires an attitude estimate. -bool mode_req_local_alt # Requires a local altitude estimate. -bool mode_req_local_position # Requires a local position estimate. -bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate. -bool mode_req_global_position # Requires a global position estimate. -bool mode_req_global_position_relaxed # Requires a relaxed global position estimate. -bool mode_req_mission # Requires an uploaded mission. -bool mode_req_home_position # Requires a home position (such as RTL/Return mode). -bool mode_req_prevent_arming # Prevent arming (such as in Land mode). -bool mode_req_manual_control # Requires a manual controller - -uint8 ORB_QUEUE_LENGTH = 4 # +bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope) +bool mode_req_attitude # Requires an attitude estimate +bool mode_req_local_alt # Requires a local altitude estimate +bool mode_req_local_position # Requires a local position estimate +bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate +bool mode_req_global_position # Requires a global position estimate +bool mode_req_global_position_relaxed # Requires a relaxed global position estimate +bool mode_req_mission # Requires an uploaded mission +bool mode_req_home_position # Requires a home position (such as RTL/Return mode) +bool mode_req_prevent_arming # Prevent arming (such as in Land mode) +bool mode_req_manual_control # Requires a manual controller +uint8 ORB_QUEUE_LENGTH = 4 ``` + +::: diff --git a/docs/en/msg_docs/ArmingCheckReplyV0.md b/docs/en/msg_docs/ArmingCheckReplyV0.md index 48917da802..d93dd9a1b6 100644 --- a/docs/en/msg_docs/ArmingCheckReplyV0.md +++ b/docs/en/msg_docs/ArmingCheckReplyV0.md @@ -1,6 +1,49 @@ +--- +pageClass: is-wide-page +--- + # ArmingCheckReplyV0 (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckReplyV0.msg) +**TOPICS:** arming_checkreplyv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_id | `uint8` | | | +| registration_id | `uint8` | | | +| health_component_index | `uint8` | | | HEALTH*COMPONENT_INDEX*\* | +| health_component_is_present | `bool` | | | +| health_component_warning | `bool` | | | +| health_component_error | `bool` | | | +| can_arm_and_run | `bool` | | | whether arming is possible, and if it's a navigation mode, if it can run | +| num_events | `uint8` | | | +| events | `EventV0[5]` | | | +| mode_req_angular_velocity | `bool` | | | +| mode_req_attitude | `bool` | | | +| mode_req_local_alt | `bool` | | | +| mode_req_local_position | `bool` | | | +| mode_req_local_position_relaxed | `bool` | | | +| mode_req_global_position | `bool` | | | +| mode_req_mission | `bool` | | | +| mode_req_home_position | `bool` | | | +| mode_req_prevent_arming | `bool` | | | +| mode_req_manual_control | `bool` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| HEALTH_COMPONENT_INDEX_NONE | `uint8` | 0 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckReplyV0.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -37,5 +80,6 @@ bool mode_req_manual_control uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/ArmingCheckRequest.md b/docs/en/msg_docs/ArmingCheckRequest.md index cfa4b52c23..083c8743e1 100644 --- a/docs/en/msg_docs/ArmingCheckRequest.md +++ b/docs/en/msg_docs/ArmingCheckRequest.md @@ -1,3 +1,7 @@ +--- +pageClass: is-wide-page +--- + # ArmingCheckRequest (UORB message) Arming check request. @@ -9,10 +13,30 @@ The request is sent regularly, even while armed, so that the FMU always knows th The reply will include the published request_id, allowing correlation of all arming check information for a particular request. The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckRequest.msg) +**TOPICS:** arming_checkrequest + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------ | -------- | ------------ | ---------- | --------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| request_id | `uint8` | | | Id of this request. Allows correlation with associated ArmingCheckReply messages. | +| valid_registrations_mask | `uint32` | | | Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckRequest.msg) + +::: details Click here to see original file ```c -# Arming check request. +# Arming check request # # Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. # All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -21,10 +45,13 @@ The reply will also include the registration_id for each external component, pro # The reply will include the published request_id, allowing correlation of all arming check information for a particular request. # The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 -uint64 timestamp # [us] Time since system start. +uint64 timestamp # [us] Time since system start -uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint8 request_id # [-] Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint32 valid_registrations_mask # [-] Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) ``` + +::: diff --git a/docs/en/msg_docs/ArmingCheckRequestV0.md b/docs/en/msg_docs/ArmingCheckRequestV0.md new file mode 100644 index 0000000000..986bb893b3 --- /dev/null +++ b/docs/en/msg_docs/ArmingCheckRequestV0.md @@ -0,0 +1,54 @@ +--- +pageClass: is-wide-page +--- + +# ArmingCheckRequestV0 (UORB message) + +Arming check request. + +Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. + +The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +**TOPICS:** arming_checkrequestv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start. | +| request_id | `uint8` | | | Id of this request. Allows correlation with associated ArmingCheckReply messages. | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckRequestV0.msg) + +::: details Click here to see original file + +```c +# Arming check request. +# +# Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +# All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +# The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. +# +# The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +# The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start. + +uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +``` + +::: diff --git a/docs/en/msg_docs/AutotuneAttitudeControlStatus.md b/docs/en/msg_docs/AutotuneAttitudeControlStatus.md index b8d7517950..e4bbd32fa9 100644 --- a/docs/en/msg_docs/AutotuneAttitudeControlStatus.md +++ b/docs/en/msg_docs/AutotuneAttitudeControlStatus.md @@ -1,44 +1,114 @@ +--- +pageClass: is-wide-page +--- + # AutotuneAttitudeControlStatus (UORB message) +Autotune attitude control status. +This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +and is subscribed to by the respective attitude controllers to command rate setpoints. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AutotuneAttitudeControlStatus.msg) +The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. + +**TOPICS:** autotune_attitudecontrol_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------ | ------------ | --------------- | --------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| coeff | `float32[5]` | | | Coefficients of the identified discrete-time model | +| coeff_var | `float32[5]` | | | Coefficients' variance of the identified discrete-time model | +| fitness | `float32` | | | Fitness of the parameter estimate | +| innov | `float32` | rad/s | | Innovation (residual error between model and measured output) | +| dt_model | `float32` | s | | Model sample time used for identification | +| kc | `float32` | | | Proportional rate-loop gain (ideal form) | +| ki | `float32` | | | Integral rate-loop gain (ideal form) | +| kd | `float32` | | | Derivative rate-loop gain (ideal form) | +| kff | `float32` | | | Feedforward rate-loop gain | +| att_p | `float32` | | | Proportional attitude gain | +| rate_sp | `float32[3]` | rad/s | | Rate setpoint commanded to the attitude controller. | +| u_filt | `float32` | | | Filtered input signal (normalized torque setpoint) used in system identification. | +| y_filt | `float32` | rad/s | | Filtered output signal (angular velocity) used in system identification. | +| state | `uint8` | | [STATE](#STATE) | Current state of the autotune procedure. | + +## Enums + +### STATE {#STATE} + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | ------- | ----- | -------------------------------------------------------- | +| STATE_IDLE | `uint8` | 0 | Idle (not running) | +| STATE_INIT | `uint8` | 1 | Initialize filters and setup | +| STATE_ROLL_AMPLITUDE_DETECTION | `uint8` | 2 | FW only: determine required excitation amplitude (roll) | +| STATE_ROLL | `uint8` | 3 | Roll-axis excitation and model identification | +| STATE_ROLL_PAUSE | `uint8` | 4 | Pause to return to level flight | +| STATE_PITCH_AMPLITUDE_DETECTION | `uint8` | 5 | FW only: determine required excitation amplitude (pitch) | +| STATE_PITCH | `uint8` | 6 | Pitch-axis excitation and model identification | +| STATE_PITCH_PAUSE | `uint8` | 7 | Pause to return to level flight | +| STATE_YAW_AMPLITUDE_DETECTION | `uint8` | 8 | FW only: determine required excitation amplitude (yaw) | +| STATE_YAW | `uint8` | 9 | Yaw-axis excitation and model identification | +| STATE_YAW_PAUSE | `uint8` | 10 | Pause to return to level flight | +| STATE_VERIFICATION | `uint8` | 11 | Verify model and candidate gains | +| STATE_APPLY | `uint8` | 12 | Apply gains | +| STATE_TEST | `uint8` | 13 | Test gains in closed-loop | +| STATE_COMPLETE | `uint8` | 14 | Tuning completed successfully | +| STATE_FAIL | `uint8` | 15 | Tuning failed (model invalid or controller unstable) | +| STATE_WAIT_FOR_DISARM | `uint8` | 16 | Waiting for disarm before finalizing | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AutotuneAttitudeControlStatus.msg) + +::: details Click here to see original file ```c -uint64 timestamp # time since system start (microseconds) +# Autotune attitude control status +# +# This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +# and is subscribed to by the respective attitude controllers to command rate setpoints. +# +# The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. -float32[5] coeff # coefficients of the identified discrete-time model -float32[5] coeff_var # coefficients' variance of the identified discrete-time model -float32 fitness # fitness of the parameter estimate -float32 innov -float32 dt_model +uint64 timestamp # [us] Time since system start -float32 kc -float32 ki -float32 kd -float32 kff -float32 att_p +float32[5] coeff # [-] Coefficients of the identified discrete-time model +float32[5] coeff_var # [-] Coefficients' variance of the identified discrete-time model +float32 fitness # [-] Fitness of the parameter estimate +float32 innov # [rad/s] Innovation (residual error between model and measured output) +float32 dt_model # [s] Model sample time used for identification -float32[3] rate_sp -float32 u_filt -float32 y_filt +float32 kc # [-] Proportional rate-loop gain (ideal form) +float32 ki # [-] Integral rate-loop gain (ideal form) +float32 kd # [-] Derivative rate-loop gain (ideal form) +float32 kff # [-] Feedforward rate-loop gain +float32 att_p # [-] Proportional attitude gain -uint8 STATE_IDLE = 0 -uint8 STATE_INIT = 1 -uint8 STATE_ROLL = 2 -uint8 STATE_ROLL_PAUSE = 3 -uint8 STATE_PITCH = 4 -uint8 STATE_PITCH_PAUSE = 5 -uint8 STATE_YAW = 6 -uint8 STATE_YAW_PAUSE = 7 -uint8 STATE_VERIFICATION = 8 -uint8 STATE_APPLY = 9 -uint8 STATE_TEST = 10 -uint8 STATE_COMPLETE = 11 -uint8 STATE_FAIL = 12 -uint8 STATE_WAIT_FOR_DISARM = 13 +float32[3] rate_sp # [rad/s] Rate setpoint commanded to the attitude controller. -uint8 state +float32 u_filt # [-] Filtered input signal (normalized torque setpoint) used in system identification. +float32 y_filt # [rad/s] Filtered output signal (angular velocity) used in system identification. +uint8 state # [@enum STATE] Current state of the autotune procedure. +uint8 STATE_IDLE = 0 # Idle (not running) +uint8 STATE_INIT = 1 # Initialize filters and setup +uint8 STATE_ROLL_AMPLITUDE_DETECTION = 2 # FW only: determine required excitation amplitude (roll) +uint8 STATE_ROLL = 3 # Roll-axis excitation and model identification +uint8 STATE_ROLL_PAUSE = 4 # Pause to return to level flight +uint8 STATE_PITCH_AMPLITUDE_DETECTION = 5 # FW only: determine required excitation amplitude (pitch) +uint8 STATE_PITCH = 6 # Pitch-axis excitation and model identification +uint8 STATE_PITCH_PAUSE = 7 # Pause to return to level flight +uint8 STATE_YAW_AMPLITUDE_DETECTION = 8 # FW only: determine required excitation amplitude (yaw) +uint8 STATE_YAW = 9 # Yaw-axis excitation and model identification +uint8 STATE_YAW_PAUSE = 10 # Pause to return to level flight +uint8 STATE_VERIFICATION = 11 # Verify model and candidate gains +uint8 STATE_APPLY = 12 # Apply gains +uint8 STATE_TEST = 13 # Test gains in closed-loop +uint8 STATE_COMPLETE = 14 # Tuning completed successfully +uint8 STATE_FAIL = 15 # Tuning failed (model invalid or controller unstable) +uint8 STATE_WAIT_FOR_DISARM = 16 # Waiting for disarm before finalizing ``` + +::: diff --git a/docs/en/msg_docs/BatteryInfo.md b/docs/en/msg_docs/BatteryInfo.md index 4b0c2823ce..ca105f0d26 100644 --- a/docs/en/msg_docs/BatteryInfo.md +++ b/docs/en/msg_docs/BatteryInfo.md @@ -1,11 +1,29 @@ +--- +pageClass: is-wide-page +--- + # BatteryInfo (UORB message) -Battery information +Battery information. Static or near-invariant battery information. Should be streamed at low rate. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/BatteryInfo.msg) +**TOPICS:** battery_info + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | ---------- | ------------ | ---------- | ------------------------------------------------------------------------------------------ | +| timestamp | `uint64` | us | | Time since system start | +| id | `uint8` | | | Must match the id in the battery_status message for the same battery | +| serial_number | `char[32]` | | | Serial number of the battery pack in ASCII characters, 0 terminated (Invalid: 0 All bytes) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/BatteryInfo.msg) + +::: details Click here to see original file ```c # Battery information @@ -17,5 +35,6 @@ uint64 timestamp # [us] Time since system start uint8 id # Must match the id in the battery_status message for the same battery char[32] serial_number # [@invalid 0 All bytes] Serial number of the battery pack in ASCII characters, 0 terminated - ``` + +::: diff --git a/docs/en/msg_docs/BatteryStatus.md b/docs/en/msg_docs/BatteryStatus.md index 7204a2a12f..b9ba00d63a 100644 --- a/docs/en/msg_docs/BatteryStatus.md +++ b/docs/en/msg_docs/BatteryStatus.md @@ -1,91 +1,197 @@ +--- +pageClass: is-wide-page +--- + # BatteryStatus (UORB message) -Battery status +Battery status. -Battery status information for up to 4 battery instances. +Battery status information for up to 3 battery instances. These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. Battery instance information is also logged and streamed in MAVLink telemetry. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/BatteryStatus.msg) +**TOPICS:** battery_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | ------------- | ------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| connected | `bool` | | | Whether or not a battery is connected. For power modules this is based on a voltage threshold. | +| voltage_v | `float32` | V | | Battery voltage (Invalid: 0) | +| current_a | `float32` | A | | Battery current (Invalid: -1) | +| current_average_a | `float32` | A | | Battery current average (for FW average in level flight) (Invalid: -1) | +| discharged_mah | `float32` | mAh | | Discharged amount (Invalid: -1) | +| remaining | `float32` | | [0 : 1] | Remaining capacity (Invalid: -1) | +| scale | `float32` | | [1 : -] | Scaling factor to compensate for lower actuation power caused by voltage sag (Invalid: -1) | +| time_remaining_s | `float32` | s | | Predicted time remaining until battery is empty under previous averaged load (Invalid: NaN) | +| temperature | `float32` | °C | | Temperature of the battery (Invalid: NaN) | +| cell_count | `uint8` | | | Number of cells (Invalid: 0) | +| source | `uint8` | | [SOURCE](#SOURCE) | Battery source | +| priority | `uint8` | | | Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 | +| capacity | `uint16` | mAh | | Capacity of the battery when fully charged | +| cycle_count | `uint16` | | | Number of discharge cycles the battery has experienced | +| average_time_to_empty | `uint16` | minutes | | Predicted remaining battery capacity based on the average rate of discharge | +| manufacture_date | `uint16` | | | Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 | +| state_of_health | `uint16` | % | [0 : 100] | State of health. FullChargeCapacity/DesignCapacity | +| max_error | `uint16` | % | [1 : 100] | Max error, expected margin of error in the state-of-charge calculation | +| id | `uint8` | | | ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed | +| interface_error | `uint16` | | | Interface error counter | +| voltage_cell_v | `float32[14]` | V | | Battery individual cell voltages (Invalid: 0) | +| max_cell_voltage_delta | `float32` | V | | Max difference between individual cell voltages | +| is_powering_off | `bool` | | | Power off event imminent indication, false if unknown | +| is_required | `bool` | | | Set if the battery is explicitly required before arming | +| warning | `uint8` | | [WARNING](#WARNING)[STATE](#STATE) | Current battery warning | +| faults | `uint16` | | [FAULT](#FAULT) | Smart battery supply status/fault flags (bitmask) for health indication | +| full_charge_capacity_wh | `float32` | Wh | | Compensated battery capacity | +| remaining_capacity_wh | `float32` | Wh | | Compensated battery capacity remaining | +| over_discharge_count | `uint16` | | | Number of battery overdischarge | +| nominal_voltage | `float32` | V | | Nominal voltage of the battery pack | +| internal_resistance_estimate | `float32` | Ohm | | Internal resistance per cell estimate | +| ocv_estimate | `float32` | V | | Open circuit voltage estimate | +| ocv_estimate_filtered | `float32` | V | | Filtered open circuit voltage estimate | +| volt_based_soc_estimate | `float32` | | [0 : 1] | Normalized volt based state of charge estimate | +| voltage_prediction | `float32` | V | | Predicted voltage | +| prediction_error | `float32` | V | | Prediction error | +| estimation_covariance_norm | `float32` | | | Norm of the covariance matrix | + +## Enums + +### SOURCE {#SOURCE} + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ---------------------------------------------- | +| SOURCE_POWER_MODULE | `uint8` | 0 | Power module (analog ADC or I2C power monitor) | +| SOURCE_EXTERNAL | `uint8` | 1 | External (MAVLink, CAN, or external driver) | +| SOURCE_ESCS | `uint8` | 2 | ESCs (via ESC telemetry) | + +### WARNING {#WARNING} + +| Name | Type | Value | Description | +| --------------------------------------------------- | ------- | ----- | -------------------------------------------- | +| WARNING_NONE | `uint8` | 0 | No battery low voltage warning active | +| WARNING_LOW | `uint8` | 1 | Low voltage warning | +| WARNING_CRITICAL | `uint8` | 2 | Critical voltage, return / abort immediately | +| WARNING_EMERGENCY | `uint8` | 3 | Immediate landing required | +| WARNING_FAILED | `uint8` | 4 | Battery has failed completely | + +### STATE {#STATE} + +| Name | Type | Value | Description | +| ----------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| STATE_UNHEALTHY | `uint8` | 6 | Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field | +| STATE_CHARGING | `uint8` | 7 | Battery is charging | + +### FAULT {#FAULT} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | ------- | ----- | -------------------------------------------------------------------------------------------------------------- | +| FAULT_DEEP_DISCHARGE | `uint8` | 0 | Battery has deep discharged | +| FAULT_SPIKES | `uint8` | 1 | Voltage spikes | +| FAULT_CELL_FAIL | `uint8` | 2 | One or more cells have failed | +| FAULT_OVER_CURRENT | `uint8` | 3 | Over-current | +| FAULT_OVER_TEMPERATURE | `uint8` | 4 | Over-temperature | +| FAULT_UNDER_TEMPERATURE | `uint8` | 5 | Under-temperature fault | +| FAULT_INCOMPATIBLE_VOLTAGE | `uint8` | 6 | Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) | +| FAULT_INCOMPATIBLE_FIRMWARE | `uint8` | 7 | Battery firmware is not compatible with current autopilot firmware | +| FAULT_INCOMPATIBLE_MODEL | `uint8` | 8 | Battery model is not supported by the system | +| FAULT_HARDWARE_FAILURE | `uint8` | 9 | Hardware problem | +| FAULT_FAILED_TO_ARM | `uint8` | 10 | Battery had a problem while arming | +| FAULT_COUNT | `uint8` | 11 | Counter. Keep this as last element | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | +| MAX_INSTANCES | `uint8` | 3 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/BatteryStatus.msg) + +::: details Click here to see original file ```c # Battery status # -# Battery status information for up to 4 battery instances. +# Battery status information for up to 3 battery instances. # These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. # Battery instance information is also logged and streamed in MAVLink telemetry. uint32 MESSAGE_VERSION = 1 -uint8 MAX_INSTANCES = 4 +uint8 MAX_INSTANCES = 3 -uint64 timestamp # [us] Time since system start -bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. -float32 voltage_v # [V] [@invalid 0] Battery voltage -float32 current_a # [A] [@invalid -1] Battery current -float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) -float32 discharged_mah # [mAh] [@invalid -1] Discharged amount -float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity -float32 scale # [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag -float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load -float32 temperature # [°C] [@invalid NaN] Temperature of the battery -uint8 cell_count # [@invalid 0] Number of cells +uint64 timestamp # [us] Time since system start + +bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. +float32 voltage_v # [V] [@invalid 0] Battery voltage +float32 current_a # [A] [@invalid -1] Battery current +float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) +float32 discharged_mah # [mAh] [@invalid -1] Discharged amount +float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity +float32 scale # [-] [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag +float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load +float32 temperature # [°C] [@invalid NaN] Temperature of the battery +uint8 cell_count # [-] [@invalid 0] Number of cells -uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 source # [@enum SOURCE] Battery source +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) -uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 -uint16 capacity # [mAh] Capacity of the battery when fully charged -uint16 cycle_count # Number of discharge cycles the battery has experienced -uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge -uint16 manufacture_date # Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 -uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity -uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation -uint8 id # ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed -uint16 interface_error # Interface error counter +uint8 priority # [-] Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 +uint16 capacity # [mAh] Capacity of the battery when fully charged +uint16 cycle_count # [-] Number of discharge cycles the battery has experienced +uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge +uint16 manufacture_date # [-] Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 +uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity +uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation +uint8 id # [-] ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed +uint16 interface_error # [-] Interface error counter -float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages -float32 max_cell_voltage_delta # Max difference between individual cell voltages +float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages +float32 max_cell_voltage_delta # [V] Max difference between individual cell voltages -bool is_powering_off # Power off event imminent indication, false if unknown -bool is_required # Set if the battery is explicitly required before arming +bool is_powering_off # Power off event imminent indication, false if unknown +bool is_required # Set if the battery is explicitly required before arming -uint8 warning # [@enum WARNING STATE] Current battery warning -uint8 WARNING_NONE = 0 # No battery low voltage warning active -uint8 WARNING_LOW = 1 # Low voltage warning -uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately -uint8 WARNING_EMERGENCY = 3 # Immediate landing required -uint8 WARNING_FAILED = 4 # Battery has failed completely -uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field -uint8 STATE_CHARGING = 7 # Battery is charging +uint8 warning # [@enum WARNING STATE] Current battery warning +uint8 WARNING_NONE = 0 # No battery low voltage warning active +uint8 WARNING_LOW = 1 # Low voltage warning +uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately +uint8 WARNING_EMERGENCY = 3 # Immediate landing required +uint8 WARNING_FAILED = 4 # Battery has failed completely +uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field +uint8 STATE_CHARGING = 7 # Battery is charging -uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication -uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged -uint8 FAULT_SPIKES = 1 # Voltage spikes -uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed -uint8 FAULT_OVER_CURRENT = 3 # Over-current -uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature -uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault -uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) -uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware -uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system -uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem -uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming -uint8 FAULT_COUNT = 11 # Counter. Keep this as last element +uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication +uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged +uint8 FAULT_SPIKES = 1 # Voltage spikes +uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed +uint8 FAULT_OVER_CURRENT = 3 # Over-current +uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature +uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault +uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) +uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware +uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system +uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem +uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming +uint8 FAULT_COUNT = 11 # Counter. Keep this as last element -float32 full_charge_capacity_wh # [Wh] Compensated battery capacity -float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining -uint16 over_discharge_count # Number of battery overdischarge -float32 nominal_voltage # [V] Nominal voltage of the battery pack - -float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate -float32 ocv_estimate # [V] Open circuit voltage estimate -float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate -float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of charge estimate -float32 voltage_prediction # [V] Predicted voltage -float32 prediction_error # [V] Prediction error -float32 estimation_covariance_norm # Norm of the covariance matrix +float32 full_charge_capacity_wh # [Wh] Compensated battery capacity +float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining +uint16 over_discharge_count # [-] Number of battery overdischarge +float32 nominal_voltage # [V] Nominal voltage of the battery pack +float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate +float32 ocv_estimate # [V] Open circuit voltage estimate +float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate +float32 volt_based_soc_estimate # [-] [@range 0, 1] Normalized volt based state of charge estimate +float32 voltage_prediction # [V] Predicted voltage +float32 prediction_error # [V] Prediction error +float32 estimation_covariance_norm # [-] Norm of the covariance matrix ``` + +::: diff --git a/docs/en/msg_docs/BatteryStatusV0.md b/docs/en/msg_docs/BatteryStatusV0.md index 86500d17a6..4dfdd4e530 100644 --- a/docs/en/msg_docs/BatteryStatusV0.md +++ b/docs/en/msg_docs/BatteryStatusV0.md @@ -1,12 +1,117 @@ +--- +pageClass: is-wide-page +--- + # BatteryStatusV0 (UORB message) -Battery status +Battery status. Battery status information for up to 4 battery instances. These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. Battery instance information is also logged and streamed in MAVLink telemetry. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/BatteryStatusV0.msg) +**TOPICS:** battery_statusv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | ------------- | ------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| connected | `bool` | | | Whether or not a battery is connected. For power modules this is based on a voltage threshold. | +| voltage_v | `float32` | V | | Battery voltage (Invalid: 0) | +| current_a | `float32` | A | | Battery current (Invalid: -1) | +| current_average_a | `float32` | A | | Battery current average (for FW average in level flight) (Invalid: -1) | +| discharged_mah | `float32` | mAh | | Discharged amount (Invalid: -1) | +| remaining | `float32` | | [0 : 1] | Remaining capacity (Invalid: -1) | +| scale | `float32` | | [1 : -] | Scaling factor to compensate for lower actuation power caused by voltage sag (Invalid: -1) | +| time_remaining_s | `float32` | s | | Predicted time remaining until battery is empty under previous averaged load (Invalid: NaN) | +| temperature | `float32` | °C | | Temperature of the battery (Invalid: NaN) | +| cell_count | `uint8` | | | Number of cells (Invalid: 0) | +| source | `uint8` | | [SOURCE](#SOURCE) | Battery source | +| priority | `uint8` | | | Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 | +| capacity | `uint16` | mAh | | Capacity of the battery when fully charged | +| cycle_count | `uint16` | | | Number of discharge cycles the battery has experienced | +| average_time_to_empty | `uint16` | minutes | | Predicted remaining battery capacity based on the average rate of discharge | +| serial_number | `uint16` | | | Serial number of the battery pack | +| manufacture_date | `uint16` | | | Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 | +| state_of_health | `uint16` | % | [0 : 100] | State of health. FullChargeCapacity/DesignCapacity | +| max_error | `uint16` | % | [1 : 100] | Max error, expected margin of error in the state-of-charge calculation | +| id | `uint8` | | | ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed | +| interface_error | `uint16` | | | Interface error counter | +| voltage_cell_v | `float32[14]` | V | | Battery individual cell voltages (Invalid: 0) | +| max_cell_voltage_delta | `float32` | | | Max difference between individual cell voltages | +| is_powering_off | `bool` | | | Power off event imminent indication, false if unknown | +| is_required | `bool` | | | Set if the battery is explicitly required before arming | +| warning | `uint8` | | [WARNING](#WARNING)[STATE](#STATE) | Current battery warning | +| faults | `uint16` | | [FAULT](#FAULT) | Smart battery supply status/fault flags (bitmask) for health indication | +| full_charge_capacity_wh | `float32` | Wh | | Compensated battery capacity | +| remaining_capacity_wh | `float32` | Wh | | Compensated battery capacity remaining | +| over_discharge_count | `uint16` | | | Number of battery overdischarge | +| nominal_voltage | `float32` | V | | Nominal voltage of the battery pack | +| internal_resistance_estimate | `float32` | Ohm | | Internal resistance per cell estimate | +| ocv_estimate | `float32` | V | | Open circuit voltage estimate | +| ocv_estimate_filtered | `float32` | V | | Filtered open circuit voltage estimate | +| volt_based_soc_estimate | `float32` | | [0 : 1] | Normalized volt based state of charge estimate | +| voltage_prediction | `float32` | V | | Predicted voltage | +| prediction_error | `float32` | V | | Prediction error | +| estimation_covariance_norm | `float32` | | | Norm of the covariance matrix | + +## Enums + +### SOURCE {#SOURCE} + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ---------------------------------------------- | +| SOURCE_POWER_MODULE | `uint8` | 0 | Power module (analog ADC or I2C power monitor) | +| SOURCE_EXTERNAL | `uint8` | 1 | External (MAVLink, CAN, or external driver) | +| SOURCE_ESCS | `uint8` | 2 | ESCs (via ESC telemetry) | + +### WARNING {#WARNING} + +| Name | Type | Value | Description | +| --------------------------------------------------- | ------- | ----- | -------------------------------------------- | +| WARNING_NONE | `uint8` | 0 | No battery low voltage warning active | +| WARNING_LOW | `uint8` | 1 | Low voltage warning | +| WARNING_CRITICAL | `uint8` | 2 | Critical voltage, return / abort immediately | +| WARNING_EMERGENCY | `uint8` | 3 | Immediate landing required | +| WARNING_FAILED | `uint8` | 4 | Battery has failed completely | + +### STATE {#STATE} + +| Name | Type | Value | Description | +| ----------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| STATE_UNHEALTHY | `uint8` | 6 | Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field | +| STATE_CHARGING | `uint8` | 7 | Battery is charging | + +### FAULT {#FAULT} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | ------- | ----- | -------------------------------------------------------------------------------------------------------------- | +| FAULT_DEEP_DISCHARGE | `uint8` | 0 | Battery has deep discharged | +| FAULT_SPIKES | `uint8` | 1 | Voltage spikes | +| FAULT_CELL_FAIL | `uint8` | 2 | One or more cells have failed | +| FAULT_OVER_CURRENT | `uint8` | 3 | Over-current | +| FAULT_OVER_TEMPERATURE | `uint8` | 4 | Over-temperature | +| FAULT_UNDER_TEMPERATURE | `uint8` | 5 | Under-temperature fault | +| FAULT_INCOMPATIBLE_VOLTAGE | `uint8` | 6 | Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) | +| FAULT_INCOMPATIBLE_FIRMWARE | `uint8` | 7 | Battery firmware is not compatible with current autopilot firmware | +| FAULT_INCOMPATIBLE_MODEL | `uint8` | 8 | Battery model is not supported by the system | +| FAULT_HARDWARE_FAILURE | `uint8` | 9 | Hardware problem | +| FAULT_FAILED_TO_ARM | `uint8` | 10 | Battery had a problem while arming | +| FAULT_COUNT | `uint8` | 11 | Counter. Keep this as last element | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| MAX_INSTANCES | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/BatteryStatusV0.msg) + +::: details Click here to see original file ```c # Battery status @@ -32,9 +137,9 @@ uint8 cell_count # [@invalid 0] Number of cells uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 uint16 capacity # [mAh] Capacity of the battery when fully charged @@ -88,5 +193,6 @@ float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of c float32 voltage_prediction # [V] Predicted voltage float32 prediction_error # [V] Prediction error float32 estimation_covariance_norm # Norm of the covariance matrix - ``` + +::: diff --git a/docs/en/msg_docs/ButtonEvent.md b/docs/en/msg_docs/ButtonEvent.md index 967f694fa6..34cf6e40e4 100644 --- a/docs/en/msg_docs/ButtonEvent.md +++ b/docs/en/msg_docs/ButtonEvent.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # ButtonEvent (UORB message) +**TOPICS:** button_event safety_button +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ButtonEvent.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| triggered | `bool` | | | Set to true if the event is triggered | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ButtonEvent.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,5 +32,6 @@ bool triggered # Set to true if the event is triggered # TOPICS button_event safety_button uint8 ORB_QUEUE_LENGTH = 2 - ``` + +::: diff --git a/docs/en/msg_docs/CameraCapture.md b/docs/en/msg_docs/CameraCapture.md index fb73e30458..cc5fa015d5 100644 --- a/docs/en/msg_docs/CameraCapture.md +++ b/docs/en/msg_docs/CameraCapture.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # CameraCapture (UORB message) +**TOPICS:** camera_capture +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraCapture.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_utc | `uint64` | | | Capture time in UTC / GPS time | +| seq | `uint32` | | | Image sequence number | +| lat | `float64` | | | Latitude in degrees (WGS84) | +| lon | `float64` | | | Longitude in degrees (WGS84) | +| alt | `float32` | | | Altitude (AMSL) | +| ground_distance | `float32` | | | Altitude above ground (meters) | +| q | `float32[4]` | | | Attitude of the camera relative to NED earth-fixed frame when using a gimbal, otherwise vehicle attitude | +| result | `int8` | | | 1 for success, 0 for failure, -1 if camera does not provide feedback | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraCapture.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -14,5 +36,6 @@ float32 alt # Altitude (AMSL) float32 ground_distance # Altitude above ground (meters) float32[4] q # Attitude of the camera relative to NED earth-fixed frame when using a gimbal, otherwise vehicle attitude int8 result # 1 for success, 0 for failure, -1 if camera does not provide feedback - ``` + +::: diff --git a/docs/en/msg_docs/CameraStatus.md b/docs/en/msg_docs/CameraStatus.md index 1bf6d3b33c..47b724a6bd 100644 --- a/docs/en/msg_docs/CameraStatus.md +++ b/docs/en/msg_docs/CameraStatus.md @@ -1,13 +1,30 @@ +--- +pageClass: is-wide-page +--- + # CameraStatus (UORB message) +**TOPICS:** camera_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | -------- | ------------ | ---------- | ------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| active_sys_id | `uint8` | | | mavlink system id of the currently active camera | +| active_comp_id | `uint8` | | | mavlink component id of currently active camera | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) uint8 active_sys_id # mavlink system id of the currently active camera uint8 active_comp_id # mavlink component id of currently active camera - ``` + +::: diff --git a/docs/en/msg_docs/CameraTrigger.md b/docs/en/msg_docs/CameraTrigger.md index a1949a7569..fee6698518 100644 --- a/docs/en/msg_docs/CameraTrigger.md +++ b/docs/en/msg_docs/CameraTrigger.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # CameraTrigger (UORB message) +**TOPICS:** camera_trigger +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraTrigger.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_utc | `uint64` | | | UTC timestamp | +| seq | `uint32` | | | Image sequence number | +| feedback | `bool` | | | Trigger feedback from camera | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint32` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CameraTrigger.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +35,6 @@ uint32 seq # Image sequence number bool feedback # Trigger feedback from camera uint32 ORB_QUEUE_LENGTH = 2 - ``` + +::: diff --git a/docs/en/msg_docs/CanInterfaceStatus.md b/docs/en/msg_docs/CanInterfaceStatus.md index 234ade997d..0d063764e1 100644 --- a/docs/en/msg_docs/CanInterfaceStatus.md +++ b/docs/en/msg_docs/CanInterfaceStatus.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # CanInterfaceStatus (UORB message) +**TOPICS:** can_interfacestatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CanInterfaceStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| interface | `uint8` | | | +| io_errors | `uint64` | | | +| frames_tx | `uint64` | | | +| frames_rx | `uint64` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CanInterfaceStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,5 +29,6 @@ uint8 interface uint64 io_errors uint64 frames_tx uint64 frames_rx - ``` + +::: diff --git a/docs/en/msg_docs/CellularStatus.md b/docs/en/msg_docs/CellularStatus.md index 6579d3fe85..10214361e7 100644 --- a/docs/en/msg_docs/CellularStatus.md +++ b/docs/en/msg_docs/CellularStatus.md @@ -1,49 +1,112 @@ +--- +pageClass: is-wide-page +--- + # CellularStatus (UORB message) -Cellular status +Cellular status. This is currently used only for logging cell status from MAVLink. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CellularStatus.msg) +**TOPICS:** cellular_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | -------- | ------------ | ----------------------------------------------------------- | ------------------------------------------ | +| timestamp | `uint64` | us | | Time since system start | +| status | `uint16` | | [STATUS_FLAG](#STATUS_FLAG) | Status bitmap | +| failure_reason | `uint8` | | [FAILURE_REASON](#FAILURE_REASON) | Failure reason | +| type | `uint8` | | [CELLULAR_NETWORK_RADIO_TYPE](#CELLULAR_NETWORK_RADIO_TYPE) | Cellular network radio type | +| quality | `uint8` | dBm | | Cellular network RSSI/RSRP, absolute value | +| mcc | `uint16` | | | Mobile country code (Invalid: UINT16_MAX) | +| mnc | `uint16` | | | Mobile network code (Invalid: UINT16_MAX) | +| lac | `uint16` | | | Location area code (Invalid: 0) | + +## Enums + +### STATUS_FLAG {#STATUS_FLAG} + +| Name | Type | Value | Description | +| ------------------------------------------------------------------- | -------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| STATUS_FLAG_UNKNOWN | `uint16` | 1 | State unknown or not reportable | +| STATUS_FLAG_FAILED | `uint16` | 2 | Modem is unusable | +| STATUS_FLAG_INITIALIZING | `uint16` | 4 | Modem is being initialized | +| STATUS_FLAG_LOCKED | `uint16` | 8 | Modem is locked | +| STATUS_FLAG_DISABLED | `uint16` | 16 | Modem is not enabled and is powered down | +| STATUS_FLAG_DISABLING | `uint16` | 32 | Modem is currently transitioning to the STATUS_FLAG_DISABLED state | +| STATUS_FLAG_ENABLING | `uint16` | 64 | Modem is currently transitioning to the STATUS_FLAG_ENABLED state | +| STATUS_FLAG_ENABLED | `uint16` | 128 | Modem is enabled and powered on but not registered with a network provider and not available for data connections | +| STATUS_FLAG_SEARCHING | `uint16` | 256 | Modem is searching for a network provider to register | +| STATUS_FLAG_REGISTERED | `uint16` | 512 | Modem is registered with a network provider, and data connections and messaging may be available for use | +| STATUS_FLAG_DISCONNECTING | `uint16` | 1024 | Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated | +| STATUS_FLAG_CONNECTING | `uint16` | 2048 | Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered | +| STATUS_FLAG_CONNECTED | `uint16` | 4096 | One or more packet data bearers is active and connected | + +### FAILURE_REASON {#FAILURE_REASON} + +| Name | Type | Value | Description | +| --------------------------------------------------------------------- | ------- | ----- | ----------------------------------------------- | +| FAILURE_REASON_NONE | `uint8` | 0 | No error | +| FAILURE_REASON_UNKNOWN | `uint8` | 1 | Error state is unknown | +| FAILURE_REASON_SIM_MISSING | `uint8` | 2 | SIM is required for the modem but missing | +| FAILURE_REASON_SIM_ERROR | `uint8` | 3 | SIM is available, but not usable for connection | + +### CELLULAR_NETWORK_RADIO_TYPE {#CELLULAR_NETWORK_RADIO_TYPE} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------- | ------- | ----- | ----------- | +| CELLULAR_NETWORK_RADIO_TYPE_NONE | `uint8` | 0 | None | +| CELLULAR_NETWORK_RADIO_TYPE_GSM | `uint8` | 1 | GSM | +| CELLULAR_NETWORK_RADIO_TYPE_CDMA | `uint8` | 2 | CDMA | +| CELLULAR_NETWORK_RADIO_TYPE_WCDMA | `uint8` | 3 | WCDMA | +| CELLULAR_NETWORK_RADIO_TYPE_LTE | `uint8` | 4 | LTE | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CellularStatus.msg) + +::: details Click here to see original file ```c # Cellular status # # This is currently used only for logging cell status from MAVLink. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint16 status # [@enum STATUS_FLAG] Status bitmap -uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable -uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable -uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized -uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked -uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down -uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state -uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state -uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections -uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register -uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use -uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated -uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered -uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected +uint16 status # [@enum STATUS_FLAG] Status bitmap +uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable +uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable +uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized +uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked +uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down +uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state +uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state +uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections +uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register +uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use +uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated +uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered +uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected -uint8 failure_reason # [@enum FAILURE_REASON] Failure reason -uint8 FAILURE_REASON_NONE = 0 # No error -uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown -uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing -uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection +uint8 failure_reason # [@enum FAILURE_REASON] Failure reason +uint8 FAILURE_REASON_NONE = 0 # No error +uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown +uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing +uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection -uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type -uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None -uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM -uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE - -uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value -uint16 mcc # [@invalid UINT16_MAX] Mobile country code -uint16 mnc # [@invalid UINT16_MAX] Mobile network code -uint16 lac # [@invalid 0] Location area code +uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type +uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None +uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM +uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE +uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value +uint16 mcc # [@invalid UINT16_MAX] Mobile country code +uint16 mnc # [@invalid UINT16_MAX] Mobile network code +uint16 lac # [@invalid 0] Location area code ``` + +::: diff --git a/docs/en/msg_docs/CollisionConstraints.md b/docs/en/msg_docs/CollisionConstraints.md index fd0f562886..cca3930fdf 100644 --- a/docs/en/msg_docs/CollisionConstraints.md +++ b/docs/en/msg_docs/CollisionConstraints.md @@ -1,9 +1,26 @@ +--- +pageClass: is-wide-page +--- + # CollisionConstraints (UORB message) -Local setpoint constraints in NED frame -setting something to NaN means that no limit is provided +Local setpoint constraints in NED frame. setting something to NaN means that no limit is provided. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CollisionConstraints.msg) +**TOPICS:** collision_constraints + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| original_setpoint | `float32[2]` | | | velocities demanded | +| adapted_setpoint | `float32[2]` | | | velocities allowed | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/CollisionConstraints.msg) + +::: details Click here to see original file ```c # Local setpoint constraints in NED frame @@ -13,5 +30,6 @@ uint64 timestamp # time since system start (microseconds) float32[2] original_setpoint # velocities demanded float32[2] adapted_setpoint # velocities allowed - ``` + +::: diff --git a/docs/en/msg_docs/ConfigOverrides.md b/docs/en/msg_docs/ConfigOverrides.md index 37f88d4923..62f79f7498 100644 --- a/docs/en/msg_docs/ConfigOverrides.md +++ b/docs/en/msg_docs/ConfigOverrides.md @@ -1,13 +1,44 @@ +--- +pageClass: is-wide-page +--- + # ConfigOverrides (UORB message) -Configurable overrides by (external) modes or mode executors +Configurable overrides by (external) modes or mode executors. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ConfigOverrides.msg) +**TOPICS:** config_overrides config_overrides_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | -------- | ------------ | ---------- | -------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| disable_auto_disarm | `bool` | | | Prevent the drone from automatically disarming after landing (if configured) | +| defer_failsafes | `bool` | | | Defer all failsafes that can be deferred (until the flag is cleared) | +| defer_failsafes_timeout_s | `int16` | | | Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout | +| disable_auto_set_home | `bool` | | | Prevent the drone from automatically setting the home position on arm or takeoff | +| source_type | `int8` | | | +| source_id | `uint8` | | | ID depending on source_type | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | +| SOURCE_TYPE_MODE | `int8` | 0 | +| SOURCE_TYPE_MODE_EXECUTOR | `int8` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ConfigOverrides.msg) + +::: details Click here to see original file ```c # Configurable overrides by (external) modes or mode executors -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -15,7 +46,7 @@ bool disable_auto_disarm # Prevent the drone from automatically disarmin bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout - +bool disable_auto_set_home # Prevent the drone from automatically setting the home position on arm or takeoff int8 SOURCE_TYPE_MODE = 0 int8 SOURCE_TYPE_MODE_EXECUTOR = 1 @@ -26,5 +57,6 @@ uint8 source_id # ID depending on source_type uint8 ORB_QUEUE_LENGTH = 4 # TOPICS config_overrides config_overrides_request - ``` + +::: diff --git a/docs/en/msg_docs/ConfigOverridesV0.md b/docs/en/msg_docs/ConfigOverridesV0.md new file mode 100644 index 0000000000..1b882bb4b8 --- /dev/null +++ b/docs/en/msg_docs/ConfigOverridesV0.md @@ -0,0 +1,61 @@ +--- +pageClass: is-wide-page +--- + +# ConfigOverridesV0 (UORB message) + +Configurable overrides by (external) modes or mode executors. + +**TOPICS:** config_overrides config_overrides_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | -------- | ------------ | ---------- | ---------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| disable_auto_disarm | `bool` | | | Prevent the drone from automatically disarming after landing (if configured) | +| defer_failsafes | `bool` | | | Defer all failsafes that can be deferred (until the flag is cleared) | +| defer_failsafes_timeout_s | `int16` | | | Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout | +| source_type | `int8` | | | +| source_id | `uint8` | | | ID depending on source_type | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| SOURCE_TYPE_MODE | `int8` | 0 | +| SOURCE_TYPE_MODE_EXECUTOR | `int8` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ConfigOverridesV0.msg) + +::: details Click here to see original file + +```c +# Configurable overrides by (external) modes or mode executors + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +bool disable_auto_disarm # Prevent the drone from automatically disarming after landing (if configured) + +bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) +int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout + + +int8 SOURCE_TYPE_MODE = 0 +int8 SOURCE_TYPE_MODE_EXECUTOR = 1 +int8 source_type + +uint8 source_id # ID depending on source_type + +uint8 ORB_QUEUE_LENGTH = 4 + +# TOPICS config_overrides config_overrides_request +``` + +::: diff --git a/docs/en/msg_docs/ControlAllocatorStatus.md b/docs/en/msg_docs/ControlAllocatorStatus.md index 0ac1b24b55..2bc894471c 100644 --- a/docs/en/msg_docs/ControlAllocatorStatus.md +++ b/docs/en/msg_docs/ControlAllocatorStatus.md @@ -1,8 +1,39 @@ +--- +pageClass: is-wide-page +--- + # ControlAllocatorStatus (UORB message) +**TOPICS:** control_allocatorstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ControlAllocatorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| torque_setpoint_achieved | `bool` | | | Boolean indicating whether the 3D torque setpoint was correctly allocated to actuators. 0 if not achieved, 1 if achieved. | +| unallocated_torque | `float32[3]` | | | Unallocated torque. Equal to 0 if the setpoint was achieved. | +| thrust_setpoint_achieved | `bool` | | | Boolean indicating whether the 3D thrust setpoint was correctly allocated to actuators. 0 if not achieved, 1 if achieved. | +| unallocated_thrust | `float32[3]` | | | Unallocated thrust. Equal to 0 if the setpoint was achieved. | +| actuator_saturation | `int8[16]` | | | Indicates actuator saturation status. | +| handled_motor_failure_mask | `uint16` | | | Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector | +| motor_stop_mask | `uint16` | | | Bitmaks of motors stopped by failure injection | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------- | ------ | ----- | --------------------------------------------------------------------------------------------------------- | +| ACTUATOR_SATURATION_OK | `int8` | 0 | The actuator is not saturated | +| ACTUATOR_SATURATION_UPPER_DYN | `int8` | 1 | The actuator is saturated (with a value <= the desired value) because it cannot increase its value faster | +| ACTUATOR_SATURATION_UPPER | `int8` | 2 | The actuator is saturated (with a value <= the desired value) because it has reached its maximum value | +| ACTUATOR_SATURATION_LOWER_DYN | `int8` | -1 | The actuator is saturated (with a value >= the desired value) because it cannot decrease its value faster | +| ACTUATOR_SATURATION_LOWER | `int8` | -2 | The actuator is saturated (with a value >= the desired value) because it has reached its minimum value | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ControlAllocatorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -26,5 +57,7 @@ int8[16] actuator_saturation # Indicates actuator saturation status. # Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value. uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector - +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` + +::: diff --git a/docs/en/msg_docs/Cpuload.md b/docs/en/msg_docs/Cpuload.md index 84f8447c39..850bc582ce 100644 --- a/docs/en/msg_docs/Cpuload.md +++ b/docs/en/msg_docs/Cpuload.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # Cpuload (UORB message) +**TOPICS:** cpuload +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Cpuload.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| load | `float32` | | | processor load from 0 to 1 | +| ram_usage | `float32` | | | RAM usage from 0 to 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Cpuload.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) float32 load # processor load from 0 to 1 float32 ram_usage # RAM usage from 0 to 1 - ``` + +::: diff --git a/docs/en/msg_docs/DatamanRequest.md b/docs/en/msg_docs/DatamanRequest.md index 06d1c5d8b7..cb9692ba34 100644 --- a/docs/en/msg_docs/DatamanRequest.md +++ b/docs/en/msg_docs/DatamanRequest.md @@ -1,8 +1,28 @@ +--- +pageClass: is-wide-page +--- + # DatamanRequest (UORB message) +**TOPICS:** dataman_request +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DatamanRequest.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ----------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| client_id | `uint8` | | | +| request_type | `uint8` | | | id/read/write/clear | +| item | `uint8` | | | dm_item_t | +| index | `uint32` | | | +| data | `uint8[56]` | | | +| data_length | `uint32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DatamanRequest.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +33,6 @@ uint8 item # dm_item_t uint32 index uint8[56] data uint32 data_length - ``` + +::: diff --git a/docs/en/msg_docs/DatamanResponse.md b/docs/en/msg_docs/DatamanResponse.md index 3857d85c69..62ea93d6d5 100644 --- a/docs/en/msg_docs/DatamanResponse.md +++ b/docs/en/msg_docs/DatamanResponse.md @@ -1,8 +1,39 @@ +--- +pageClass: is-wide-page +--- + # DatamanResponse (UORB message) +**TOPICS:** dataman_response +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DatamanResponse.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ----------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| client_id | `uint8` | | | +| request_type | `uint8` | | | id/read/write/clear | +| item | `uint8` | | | dm_item_t | +| index | `uint32` | | | +| data | `uint8[56]` | | | +| status | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | ------- | ----- | ----------- | +| STATUS_SUCCESS | `uint8` | 0 | +| STATUS_FAILURE_ID_ERR | `uint8` | 1 | +| STATUS_FAILURE_NO_DATA | `uint8` | 2 | +| STATUS_FAILURE_READ_FAILED | `uint8` | 3 | +| STATUS_FAILURE_WRITE_FAILED | `uint8` | 4 | +| STATUS_FAILURE_CLEAR_FAILED | `uint8` | 5 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DatamanResponse.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -20,5 +51,6 @@ uint8 STATUS_FAILURE_READ_FAILED = 3 uint8 STATUS_FAILURE_WRITE_FAILED = 4 uint8 STATUS_FAILURE_CLEAR_FAILED = 5 uint8 status - ``` + +::: diff --git a/docs/en/msg_docs/DebugArray.md b/docs/en/msg_docs/DebugArray.md index 7dc20d00e3..b7fd0c81f9 100644 --- a/docs/en/msg_docs/DebugArray.md +++ b/docs/en/msg_docs/DebugArray.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # DebugArray (UORB message) +**TOPICS:** debug_array +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugArray.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------- | ------------ | ---------- | ------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| id | `uint16` | | | unique ID of debug array, used to discriminate between arrays | +| name | `char[10]` | | | name of the debug array (max. 10 characters) | +| data | `float32[58]` | | | data | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------- | ------- | ----- | ----------- | +| ARRAY_SIZE | `uint8` | 58 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugArray.msg) + +::: details Click here to see original file ```c uint8 ARRAY_SIZE = 58 @@ -10,5 +33,6 @@ uint64 timestamp # time since system start (microseconds) uint16 id # unique ID of debug array, used to discriminate between arrays char[10] name # name of the debug array (max. 10 characters) float32[58] data # data - ``` + +::: diff --git a/docs/en/msg_docs/DebugKeyValue.md b/docs/en/msg_docs/DebugKeyValue.md index ea5709c88e..31883af75f 100644 --- a/docs/en/msg_docs/DebugKeyValue.md +++ b/docs/en/msg_docs/DebugKeyValue.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # DebugKeyValue (UORB message) +**TOPICS:** debug_keyvalue +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugKeyValue.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ---------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| key | `char[10]` | | | max. 10 characters as key / name | +| value | `float32` | | | the value to send as debug output | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugKeyValue.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) char[10] key # max. 10 characters as key / name float32 value # the value to send as debug output - ``` + +::: diff --git a/docs/en/msg_docs/DebugValue.md b/docs/en/msg_docs/DebugValue.md index 8c86a763a4..9739f056be 100644 --- a/docs/en/msg_docs/DebugValue.md +++ b/docs/en/msg_docs/DebugValue.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # DebugValue (UORB message) +**TOPICS:** debug_value +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugValue.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| ind | `int8` | | | index of debug variable | +| value | `float32` | | | the value to send as debug output | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugValue.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) int8 ind # index of debug variable float32 value # the value to send as debug output - ``` + +::: diff --git a/docs/en/msg_docs/DebugVect.md b/docs/en/msg_docs/DebugVect.md index 31e1c8d044..941c894409 100644 --- a/docs/en/msg_docs/DebugVect.md +++ b/docs/en/msg_docs/DebugVect.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # DebugVect (UORB message) +**TOPICS:** debug_vect +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugVect.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ---------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| name | `char[10]` | | | max. 10 characters as key / name | +| x | `float32` | | | x value | +| y | `float32` | | | y value | +| z | `float32` | | | z value | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DebugVect.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +28,6 @@ char[10] name # max. 10 characters as key / name float32 x # x value float32 y # y value float32 z # z value - ``` + +::: diff --git a/docs/en/msg_docs/DeviceInformation.md b/docs/en/msg_docs/DeviceInformation.md new file mode 100644 index 0000000000..0f68dc8d80 --- /dev/null +++ b/docs/en/msg_docs/DeviceInformation.md @@ -0,0 +1,92 @@ +--- +pageClass: is-wide-page +--- + +# DeviceInformation (UORB message) + +Device information. + +Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +as well as tracking of the used firmware versions on the devices. + +**TOPICS:** device_information + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_type | `uint8` | | [DEVICE_TYPE](#DEVICE_TYPE) | Type of the device. Matches MAVLink DEVICE_TYPE enum | +| vendor_name | `char[32]` | | | Name of the device vendor | +| model_name | `char[32]` | | | Name of the device model | +| `uint32` | | | Unique device ID for the sensor. Does not change between power cycles. (Invalid: 0 if not available) | +| firmware_version | `char[24]` | | | Firmware version. (Invalid: empty if not available) | +| hardware_version | `char[24]` | | | Hardware version. (Invalid: empty if not available) | +| serial_number | `char[33]` | | | Device serial number or unique identifier. (Invalid: empty if not available) | + +## Enums + +### DEVICE_TYPE {#DEVICE_TYPE} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------- | ------- | ----- | ---------------------- | +| DEVICE_TYPE_GENERIC | `uint8` | 0 | Generic/unknown sensor | +| DEVICE_TYPE_AIRSPEED | `uint8` | 1 | Airspeed sensor | +| DEVICE_TYPE_ESC | `uint8` | 2 | ESC | +| DEVICE_TYPE_SERVO | `uint8` | 3 | Servo | +| DEVICE_TYPE_GPS | `uint8` | 4 | GPS | +| DEVICE_TYPE_MAGNETOMETER | `uint8` | 5 | Magnetometer | +| DEVICE_TYPE_PARACHUTE | `uint8` | 6 | Parachute | +| DEVICE_TYPE_RANGEFINDER | `uint8` | 7 | Rangefinder | +| DEVICE_TYPE_WINCH | `uint8` | 8 | Winch | +| DEVICE_TYPE_BAROMETER | `uint8` | 9 | Barometer | +| DEVICE_TYPE_OPTICAL_FLOW | `uint8` | 10 | Optical flow | +| DEVICE_TYPE_ACCELEROMETER | `uint8` | 11 | Accelerometer | +| DEVICE_TYPE_GYROSCOPE | `uint8` | 12 | Gyroscope | +| DEVICE_TYPE_DIFFERENTIAL_PRESSURE | `uint8` | 13 | Differential pressure | +| DEVICE_TYPE_BATTERY | `uint8` | 14 | Battery | +| DEVICE_TYPE_HYGROMETER | `uint8` | 15 | Hygrometer | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DeviceInformation.msg) + +::: details Click here to see original file + +```c +# Device information +# +# Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +# as well as tracking of the used firmware versions on the devices. + +uint64 timestamp # time since system start (microseconds) + +uint8 device_type # [@enum DEVICE_TYPE] Type of the device. Matches MAVLink DEVICE_TYPE enum + +uint8 DEVICE_TYPE_GENERIC = 0 # Generic/unknown sensor +uint8 DEVICE_TYPE_AIRSPEED = 1 # Airspeed sensor +uint8 DEVICE_TYPE_ESC = 2 # ESC +uint8 DEVICE_TYPE_SERVO = 3 # Servo +uint8 DEVICE_TYPE_GPS = 4 # GPS +uint8 DEVICE_TYPE_MAGNETOMETER = 5 # Magnetometer +uint8 DEVICE_TYPE_PARACHUTE = 6 # Parachute +uint8 DEVICE_TYPE_RANGEFINDER = 7 # Rangefinder +uint8 DEVICE_TYPE_WINCH = 8 # Winch +uint8 DEVICE_TYPE_BAROMETER = 9 # Barometer +uint8 DEVICE_TYPE_OPTICAL_FLOW = 10 # Optical flow +uint8 DEVICE_TYPE_ACCELEROMETER = 11 # Accelerometer +uint8 DEVICE_TYPE_GYROSCOPE = 12 # Gyroscope +uint8 DEVICE_TYPE_DIFFERENTIAL_PRESSURE = 13 # Differential pressure +uint8 DEVICE_TYPE_BATTERY = 14 # Battery +uint8 DEVICE_TYPE_HYGROMETER = 15 # Hygrometer + +char[32] vendor_name # Name of the device vendor +char[32] model_name # Name of the device model + +uint32 device_id # [-] [@invalid 0 if not available] Unique device ID for the sensor. Does not change between power cycles. +char[24] firmware_version # [-] [@invalid empty if not available] Firmware version. +char[24] hardware_version # [-] [@invalid empty if not available] Hardware version. +char[33] serial_number # [-] [@invalid empty if not available] Device serial number or unique identifier. +``` + +::: diff --git a/docs/en/msg_docs/DifferentialPressure.md b/docs/en/msg_docs/DifferentialPressure.md index a6f10625c6..e9c7410ce7 100644 --- a/docs/en/msg_docs/DifferentialPressure.md +++ b/docs/en/msg_docs/DifferentialPressure.md @@ -1,19 +1,46 @@ +--- +pageClass: is-wide-page +--- + # DifferentialPressure (UORB message) +Differential-pressure (airspeed) sensor. +This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DifferentialPressure.msg) +**TOPICS:** differential_pressure + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------ | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time of publication (since system start) | +| timestamp_sample | `uint64` | us | | Time of raw data capture | +| device_id | `uint32` | | | Unique device ID for the sensor that does not change between power cycles | +| differential_pressure_pa | `float32` | Pa | | Differential pressure reading (may be negative) | +| temperature | `float32` | degC | | Temperature (Invalid: NaN if unknown) | +| error_count | `uint32` | | | Number of errors detected by driver | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DifferentialPressure.msg) + +::: details Click here to see original file ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Differential-pressure (airspeed) sensor +# +# This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles - -float32 differential_pressure_pa # differential pressure reading in Pascals (may be negative) - -float32 temperature # Temperature provided by sensor in degrees Celsius, NAN if unknown - -uint32 error_count # Number of errors detected by driver +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 differential_pressure_pa # [Pa] Differential pressure reading (may be negative) +float32 temperature # [degC] [@invalid NaN if unknown] Temperature +uint32 error_count # [-] Number of errors detected by driver ``` + +::: diff --git a/docs/en/msg_docs/DistanceSensor.md b/docs/en/msg_docs/DistanceSensor.md index c4d5bbc2c0..6bf1ea75b6 100644 --- a/docs/en/msg_docs/DistanceSensor.md +++ b/docs/en/msg_docs/DistanceSensor.md @@ -1,8 +1,63 @@ +--- +pageClass: is-wide-page +--- + # DistanceSensor (UORB message) -DISTANCE_SENSOR message data +DISTANCE_SENSOR message data. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DistanceSensor.msg) +**TOPICS:** distance_sensor + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| min_distance | `float32` | | | Minimum distance the sensor can measure (in m) | +| max_distance | `float32` | | | Maximum distance the sensor can measure (in m) | +| current_distance | `float32` | | | Current distance reading (in m) | +| variance | `float32` | | | Measurement variance (in m^2), 0 for unknown / invalid readings | +| signal_quality | `int8` | | | Signal quality in percent (0...100%), where 0 = invalid signal, 100 = perfect signal, and -1 = unknown signal quality. | +| type | `uint8` | | | Type from MAV_DISTANCE_SENSOR enum | +| h_fov | `float32` | | | Sensor horizontal field of view (rad) | +| v_fov | `float32` | | | Sensor vertical field of view (rad) | +| q | `float32[4]` | | | Quaterion sensor orientation with respect to the vehicle body frame to specify the orientation ROTATION_CUSTOM | +| orientation | `uint8` | | | Direction the sensor faces from MAV_SENSOR_ORIENTATION enum | +| mode | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------- | ------- | ----- | ----------------------------- | +| MAV_DISTANCE_SENSOR_LASER | `uint8` | 0 | +| MAV_DISTANCE_SENSOR_ULTRASOUND | `uint8` | 1 | +| MAV_DISTANCE_SENSOR_INFRARED | `uint8` | 2 | +| MAV_DISTANCE_SENSOR_RADAR | `uint8` | 3 | +| ROTATION_YAW_0 | `uint8` | 0 | MAV_SENSOR_ROTATION_NONE | +| ROTATION_YAW_45 | `uint8` | 1 | MAV_SENSOR_ROTATION_YAW_45 | +| ROTATION_YAW_90 | `uint8` | 2 | MAV_SENSOR_ROTATION_YAW_90 | +| ROTATION_YAW_135 | `uint8` | 3 | MAV_SENSOR_ROTATION_YAW_135 | +| ROTATION_YAW_180 | `uint8` | 4 | MAV_SENSOR_ROTATION_YAW_180 | +| ROTATION_YAW_225 | `uint8` | 5 | MAV_SENSOR_ROTATION_YAW_225 | +| ROTATION_YAW_270 | `uint8` | 6 | MAV_SENSOR_ROTATION_YAW_270 | +| ROTATION_YAW_315 | `uint8` | 7 | MAV_SENSOR_ROTATION_YAW_315 | +| ROTATION_FORWARD_FACING | `uint8` | 0 | MAV_SENSOR_ROTATION_NONE | +| ROTATION_RIGHT_FACING | `uint8` | 2 | MAV_SENSOR_ROTATION_YAW_90 | +| ROTATION_BACKWARD_FACING | `uint8` | 4 | MAV_SENSOR_ROTATION_YAW_180 | +| ROTATION_LEFT_FACING | `uint8` | 6 | MAV_SENSOR_ROTATION_YAW_270 | +| ROTATION_UPWARD_FACING | `uint8` | 24 | MAV_SENSOR_ROTATION_PITCH_90 | +| ROTATION_DOWNWARD_FACING | `uint8` | 25 | MAV_SENSOR_ROTATION_PITCH_270 | +| ROTATION_CUSTOM | `uint8` | 100 | MAV_SENSOR_ROTATION_CUSTOM | +| MODE_UNKNOWN | `uint8` | 0 | +| MODE_ENABLED | `uint8` | 1 | +| MODE_DISABLED | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DistanceSensor.msg) + +::: details Click here to see original file ```c # DISTANCE_SENSOR message data @@ -52,5 +107,6 @@ uint8 mode uint8 MODE_UNKNOWN = 0 uint8 MODE_ENABLED = 1 uint8 MODE_DISABLED = 2 - ``` + +::: diff --git a/docs/en/msg_docs/DistanceSensorModeChangeRequest.md b/docs/en/msg_docs/DistanceSensorModeChangeRequest.md index 56ed7e1bba..1c4f596106 100644 --- a/docs/en/msg_docs/DistanceSensorModeChangeRequest.md +++ b/docs/en/msg_docs/DistanceSensorModeChangeRequest.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # DistanceSensorModeChangeRequest (UORB message) +**TOPICS:** distance_sensormode_changerequest +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DistanceSensorModeChangeRequest.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | -------- | ------------ | ---------- | --------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_on_off | `uint8` | | | request to disable/enable the distance sensor | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------- | ------- | ----- | ----------- | +| REQUEST_OFF | `uint8` | 0 | +| REQUEST_ON | `uint8` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DistanceSensorModeChangeRequest.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +32,6 @@ uint64 timestamp # time since system start (microseconds) uint8 request_on_off # request to disable/enable the distance sensor uint8 REQUEST_OFF = 0 uint8 REQUEST_ON = 1 - ``` + +::: diff --git a/docs/en/msg_docs/DronecanNodeStatus.md b/docs/en/msg_docs/DronecanNodeStatus.md index 5c8a8d7862..e25f221092 100644 --- a/docs/en/msg_docs/DronecanNodeStatus.md +++ b/docs/en/msg_docs/DronecanNodeStatus.md @@ -1,6 +1,42 @@ +--- +pageClass: is-wide-page +--- + # DronecanNodeStatus (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DronecanNodeStatus.msg) +**TOPICS:** dronecan_nodestatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| node_id | `uint16` | | | The node ID which this data comes from | +| uptime_sec | `uint32` | | | Node uptime | +| health | `uint8` | | | +| mode | `uint8` | | | +| sub_mode | `uint8` | | | +| vendor_specific_status_code | `uint16` | | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------- | +| HEALTH_OK | `uint8` | 0 | The node is functioning properly. | +| HEALTH_WARNING | `uint8` | 1 | A critical parameter went out of range or the node encountered a minor failure. | +| HEALTH_ERROR | `uint8` | 2 | The node encountered a major failure. | +| HEALTH_CRITICAL | `uint8` | 3 | The node suffered a fatal malfunction. | +| MODE_OPERATIONAL | `uint8` | 0 | Normal operating mode. | +| MODE_INITIALIZATION | `uint8` | 1 | Initialization is in progress; this mode is entered immediately after startup. | +| MODE_MAINTENANCE | `uint8` | 2 | E.g. calibration, the bootloader is running, etc. | +| MODE_SOFTWARE_UPDATE | `uint8` | 3 | New software/firmware is being loaded. | +| MODE_OFFLINE | `uint8` | 7 | The node is no longer available. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DronecanNodeStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -44,5 +80,6 @@ uint8 sub_mode # Optional, vendor-specific node status code, e.g. a fault code or a status bitmask. # uint16 vendor_specific_status_code - ``` + +::: diff --git a/docs/en/msg_docs/Ekf2Timestamps.md b/docs/en/msg_docs/Ekf2Timestamps.md index 8de695f523..970bd52edf 100644 --- a/docs/en/msg_docs/Ekf2Timestamps.md +++ b/docs/en/msg_docs/Ekf2Timestamps.md @@ -1,12 +1,37 @@ +--- +pageClass: is-wide-page +--- + # Ekf2Timestamps (UORB message) -this message contains the (relative) timestamps of the sensor inputs used by EKF2. -It can be used for reproducible replay. +this message contains the (relative) timestamps of the sensor inputs used by EKF2. It can be used for reproducible replay. -the timestamp field is the ekf2 reference time and matches the timestamp of -the sensor_combined topic. +**TOPICS:** ekf2_timestamps -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Ekf2Timestamps.msg) +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| airspeed_timestamp_rel | `int16` | | | +| airspeed_validated_timestamp_rel | `int16` | | | +| distance_sensor_timestamp_rel | `int16` | | | +| optical_flow_timestamp_rel | `int16` | | | +| vehicle_air_data_timestamp_rel | `int16` | | | +| vehicle_magnetometer_timestamp_rel | `int16` | | | +| visual_odometry_timestamp_rel | `int16` | | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------- | ------- | ----- | ------------------------------------------ | +| RELATIVE_TIMESTAMP_INVALID | `int16` | 32767 | (0x7fff) If one of the relative timestamps | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Ekf2Timestamps.msg) + +::: details Click here to see original file ```c # this message contains the (relative) timestamps of the sensor inputs used by EKF2. @@ -33,5 +58,6 @@ int16 vehicle_magnetometer_timestamp_rel int16 visual_odometry_timestamp_rel # Note: this is a high-rate logged topic, so it needs to be as small as possible - ``` + +::: diff --git a/docs/en/msg_docs/EscReport.md b/docs/en/msg_docs/EscReport.md index 4a75bee418..2887d96454 100644 --- a/docs/en/msg_docs/EscReport.md +++ b/docs/en/msg_docs/EscReport.md @@ -1,8 +1,61 @@ +--- +pageClass: is-wide-page +--- + # EscReport (UORB message) +**TOPICS:** esc_report +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EscReport.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| esc_errorcount | `uint32` | | | Number of reported errors by ESC - if supported | +| esc_rpm | `int32` | | | Motor RPM, negative for reverse rotation [RPM] - if supported | +| esc_voltage | `float32` | | | Voltage measured from current ESC [V] - if supported | +| esc_current | `float32` | | | Current measured from current ESC [A] - if supported | +| esc_temperature | `float32` | | | Temperature measured from current ESC [degC] - if supported | +| esc_address | `uint8` | | | Address of current ESC (in most cases 1-8 / must be set by driver) | +| esc_cmdcount | `uint8` | | | Counter of number of commands | +| esc_state | `uint8` | | | State of ESC - depend on Vendor | +| actuator_function | `uint8` | | | actuator output function (one of Motor1...MotorN) | +| failures | `uint16` | | | Bitmask to indicate the internal ESC faults | +| esc_power | `int8` | | | Applied power 0-100 in % (negative values reserved) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------- | ------- | ----- | ---------------------------------------------------------------------------- | +| ACTUATOR_FUNCTION_MOTOR1 | `uint8` | 101 | +| ACTUATOR_FUNCTION_MOTOR2 | `uint8` | 102 | +| ACTUATOR_FUNCTION_MOTOR3 | `uint8` | 103 | +| ACTUATOR_FUNCTION_MOTOR4 | `uint8` | 104 | +| ACTUATOR_FUNCTION_MOTOR5 | `uint8` | 105 | +| ACTUATOR_FUNCTION_MOTOR6 | `uint8` | 106 | +| ACTUATOR_FUNCTION_MOTOR7 | `uint8` | 107 | +| ACTUATOR_FUNCTION_MOTOR8 | `uint8` | 108 | +| ACTUATOR_FUNCTION_MOTOR9 | `uint8` | 109 | +| ACTUATOR_FUNCTION_MOTOR10 | `uint8` | 110 | +| ACTUATOR_FUNCTION_MOTOR11 | `uint8` | 111 | +| ACTUATOR_FUNCTION_MOTOR12 | `uint8` | 112 | +| FAILURE_OVER_CURRENT | `uint8` | 0 | (1 << 0) | +| FAILURE_OVER_VOLTAGE | `uint8` | 1 | (1 << 1) | +| FAILURE_MOTOR_OVER_TEMPERATURE | `uint8` | 2 | (1 << 2) | +| FAILURE_OVER_RPM | `uint8` | 3 | (1 << 3) | +| FAILURE_INCONSISTENT_CMD | `uint8` | 4 | (1 << 4) Set if ESC received an inconsistent command (i.e out of boundaries) | +| FAILURE_MOTOR_STUCK | `uint8` | 5 | (1 << 5) | +| FAILURE_GENERIC | `uint8` | 6 | (1 << 6) | +| FAILURE_MOTOR_WARN_TEMPERATURE | `uint8` | 7 | (1 << 7) | +| FAILURE_WARN_ESC_TEMPERATURE | `uint8` | 8 | (1 << 8) | +| FAILURE_OVER_ESC_TEMPERATURE | `uint8` | 9 | (1 << 9) | +| ESC_FAILURE_COUNT | `uint8` | 10 | Counter - keep it as last element! | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EscReport.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -18,6 +71,19 @@ uint8 esc_state # State of ESC - depend on Vendor uint8 actuator_function # actuator output function (one of Motor1...MotorN) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR2 = 102 +uint8 ACTUATOR_FUNCTION_MOTOR3 = 103 +uint8 ACTUATOR_FUNCTION_MOTOR4 = 104 +uint8 ACTUATOR_FUNCTION_MOTOR5 = 105 +uint8 ACTUATOR_FUNCTION_MOTOR6 = 106 +uint8 ACTUATOR_FUNCTION_MOTOR7 = 107 +uint8 ACTUATOR_FUNCTION_MOTOR8 = 108 +uint8 ACTUATOR_FUNCTION_MOTOR9 = 109 +uint8 ACTUATOR_FUNCTION_MOTOR10 = 110 +uint8 ACTUATOR_FUNCTION_MOTOR11 = 111 +uint8 ACTUATOR_FUNCTION_MOTOR12 = 112 + uint16 failures # Bitmask to indicate the internal ESC faults int8 esc_power # Applied power 0-100 in % (negative values reserved) @@ -32,5 +98,6 @@ uint8 FAILURE_MOTOR_WARN_TEMPERATURE = 7 # (1 << 7) uint8 FAILURE_WARN_ESC_TEMPERATURE = 8 # (1 << 8) uint8 FAILURE_OVER_ESC_TEMPERATURE = 9 # (1 << 9) uint8 ESC_FAILURE_COUNT = 10 # Counter - keep it as last element! - ``` + +::: diff --git a/docs/en/msg_docs/EscStatus.md b/docs/en/msg_docs/EscStatus.md index 07bd468cee..9f8b0a409a 100644 --- a/docs/en/msg_docs/EscStatus.md +++ b/docs/en/msg_docs/EscStatus.md @@ -1,8 +1,40 @@ +--- +pageClass: is-wide-page +--- + # EscStatus (UORB message) +**TOPICS:** esc_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EscStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | -------------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| counter | `uint16` | | | incremented by the writing thread everytime new data is stored | +| esc_count | `uint8` | | | number of connected ESCs | +| esc_connectiontype | `uint8` | | | how ESCs connected to the system | +| esc_online_flags | `uint8` | | | Bitmask indicating which ESC is online/offline | +| esc_armed_flags | `uint8` | | | Bitmask indicating which ESC is armed. For ESC's where the arming state is not known (returned by the ESC), the arming bits should always be set. | +| esc | `EscReport[8]` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | ------- | ----- | ----------------------------------------------------------------- | +| CONNECTED_ESC_MAX | `uint8` | 8 | The number of ESCs supported. Current (Q2/2013) we support 8 ESCs | +| ESC_CONNECTION_TYPE_PPM | `uint8` | 0 | Traditional PPM ESC | +| ESC_CONNECTION_TYPE_SERIAL | `uint8` | 1 | Serial Bus connected ESC | +| ESC_CONNECTION_TYPE_ONESHOT | `uint8` | 2 | One Shot PPM | +| ESC_CONNECTION_TYPE_I2C | `uint8` | 3 | I2C | +| ESC_CONNECTION_TYPE_CAN | `uint8` | 4 | CAN-Bus | +| ESC_CONNECTION_TYPE_DSHOT | `uint8` | 5 | DShot | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EscStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -33,5 +65,6 @@ uint8 esc_online_flags # Bitmask indicating which ESC is online/offline uint8 esc_armed_flags # Bitmask indicating which ESC is armed. For ESC's where the arming state is not known (returned by the ESC), the arming bits should always be set. EscReport[8] esc - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorAidSource1d.md b/docs/en/msg_docs/EstimatorAidSource1d.md index 45d0659de2..908495b407 100644 --- a/docs/en/msg_docs/EstimatorAidSource1d.md +++ b/docs/en/msg_docs/EstimatorAidSource1d.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # EstimatorAidSource1d (UORB message) +**TOPICS:** estimator_aid_src_baro_hgt estimator_aid_src_ev_hgt estimator_aid_src_gnss_hgt estimator_aid_src_rng_hgt estimator_aid_src_airspeed estimator_aid_src_sideslip estimator_aid_src_fake_hgt estimator_aid_src_gnss_yaw estimator_aid_src_ev_yaw +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource1d.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | --------- | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| estimator_instance | `uint8` | | | +| device_id | `uint32` | | | +| time_last_fuse | `uint64` | | | +| observation | `float32` | | | +| observation_variance | `float32` | | | +| innovation | `float32` | | | +| innovation_filtered | `float32` | | | +| innovation_variance | `float32` | | | +| test_ratio | `float32` | | | normalized innovation squared | +| test_ratio_filtered | `float32` | | | signed filtered test ratio | +| innovation_rejected | `bool` | | | true if the observation has been rejected | +| fused | `bool` | | | true if the sample was successfully fused | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource1d.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -32,5 +59,6 @@ bool fused # true if the sample was successfully fused # TOPICS estimator_aid_src_airspeed estimator_aid_src_sideslip # TOPICS estimator_aid_src_fake_hgt # TOPICS estimator_aid_src_gnss_yaw estimator_aid_src_ev_yaw - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorAidSource2d.md b/docs/en/msg_docs/EstimatorAidSource2d.md index 70cc2948e5..cb21f508cb 100644 --- a/docs/en/msg_docs/EstimatorAidSource2d.md +++ b/docs/en/msg_docs/EstimatorAidSource2d.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # EstimatorAidSource2d (UORB message) +**TOPICS:** estimator_aid_src_ev_pos estimator_aid_src_fake_pos estimator_aid_src_gnss_pos estimator_aid_src_aux_global_position estimator_aid_src_aux_vel estimator_aid_src_optical_flow estimator_aid_src_drag +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource2d.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| estimator_instance | `uint8` | | | +| device_id | `uint32` | | | +| time_last_fuse | `uint64` | | | +| observation | `float64[2]` | | | +| observation_variance | `float32[2]` | | | +| innovation | `float32[2]` | | | +| innovation_filtered | `float32[2]` | | | +| innovation_variance | `float32[2]` | | | +| test_ratio | `float32[2]` | | | normalized innovation squared | +| test_ratio_filtered | `float32[2]` | | | signed filtered test ratio | +| innovation_rejected | `bool` | | | true if the observation has been rejected | +| fused | `bool` | | | true if the sample was successfully fused | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource2d.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -31,5 +58,6 @@ bool fused # true if the sample was successfully fused # TOPICS estimator_aid_src_ev_pos estimator_aid_src_fake_pos estimator_aid_src_gnss_pos estimator_aid_src_aux_global_position # TOPICS estimator_aid_src_aux_vel estimator_aid_src_optical_flow # TOPICS estimator_aid_src_drag - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorAidSource3d.md b/docs/en/msg_docs/EstimatorAidSource3d.md index 457deec9c9..38ed296214 100644 --- a/docs/en/msg_docs/EstimatorAidSource3d.md +++ b/docs/en/msg_docs/EstimatorAidSource3d.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # EstimatorAidSource3d (UORB message) +**TOPICS:** estimator_aid_src_ev_vel estimator_aid_src_gnss_vel estimator_aid_src_gravity estimator_aid_src_mag +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource3d.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| estimator_instance | `uint8` | | | +| device_id | `uint32` | | | +| time_last_fuse | `uint64` | | | +| observation | `float32[3]` | | | +| observation_variance | `float32[3]` | | | +| innovation | `float32[3]` | | | +| innovation_filtered | `float32[3]` | | | +| innovation_variance | `float32[3]` | | | +| test_ratio | `float32[3]` | | | normalized innovation squared | +| test_ratio_filtered | `float32[3]` | | | signed filtered test ratio | +| innovation_rejected | `bool` | | | true if the observation has been rejected | +| fused | `bool` | | | true if the sample was successfully fused | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorAidSource3d.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -29,5 +56,6 @@ bool innovation_rejected # true if the observation has been rejected bool fused # true if the sample was successfully fused # TOPICS estimator_aid_src_ev_vel estimator_aid_src_gnss_vel estimator_aid_src_gravity estimator_aid_src_mag - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorBias.md b/docs/en/msg_docs/EstimatorBias.md index 3b7408be15..4e19c7590b 100644 --- a/docs/en/msg_docs/EstimatorBias.md +++ b/docs/en/msg_docs/EstimatorBias.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # EstimatorBias (UORB message) +**TOPICS:** estimator_baro_bias estimator_gnss_hgt_bias +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorBias.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| bias | `float32` | | | estimated barometric altitude bias (m) | +| bias_var | `float32` | | | estimated barometric altitude bias variance (m^2) | +| innov | `float32` | | | innovation of the last measurement fusion (m) | +| innov_var | `float32` | | | innovation variance of the last measurement fusion (m^2) | +| innov_test_ratio | `float32` | | | normalized innovation squared test ratio | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorBias.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -17,5 +38,6 @@ float32 innov_var # innovation variance of the last measurement fusion (m^2) float32 innov_test_ratio # normalized innovation squared test ratio # TOPICS estimator_baro_bias estimator_gnss_hgt_bias - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorBias3d.md b/docs/en/msg_docs/EstimatorBias3d.md index af89bab69f..42b7c0ac7e 100644 --- a/docs/en/msg_docs/EstimatorBias3d.md +++ b/docs/en/msg_docs/EstimatorBias3d.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # EstimatorBias3d (UORB message) +**TOPICS:** estimator_bias3d estimator_ev_pos_bias +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorBias3d.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| bias | `float32[3]` | | | estimated barometric altitude bias (m) | +| bias_var | `float32[3]` | | | estimated barometric altitude bias variance (m^2) | +| innov | `float32[3]` | | | innovation of the last measurement fusion (m) | +| innov_var | `float32[3]` | | | innovation variance of the last measurement fusion (m^2) | +| innov_test_ratio | `float32[3]` | | | normalized innovation squared test ratio | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorBias3d.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -19,5 +40,6 @@ float32[3] innov_test_ratio # normalized innovation squared test ratio # TOPICS estimator_bias3d # TOPICS estimator_ev_pos_bias - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorEventFlags.md b/docs/en/msg_docs/EstimatorEventFlags.md index c56f29a842..639c3b6db0 100644 --- a/docs/en/msg_docs/EstimatorEventFlags.md +++ b/docs/en/msg_docs/EstimatorEventFlags.md @@ -1,8 +1,41 @@ +--- +pageClass: is-wide-page +--- + # EstimatorEventFlags (UORB message) +**TOPICS:** estimator_eventflags +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorEventFlags.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| information_event_changes | `uint32` | | | number of information event changes | +| gps_checks_passed | `bool` | | | 0 - true when gps quality checks are passing passed | +| reset_vel_to_gps | `bool` | | | 1 - true when the velocity states are reset to the gps measurement | +| reset_vel_to_flow | `bool` | | | 2 - true when the velocity states are reset using the optical flow measurement | +| reset_vel_to_vision | `bool` | | | 3 - true when the velocity states are reset to the vision system measurement | +| reset_vel_to_zero | `bool` | | | 4 - true when the velocity states are reset to zero | +| reset_pos_to_last_known | `bool` | | | 5 - true when the position states are reset to the last known position | +| reset_pos_to_gps | `bool` | | | 6 - true when the position states are reset to the gps measurement | +| reset_pos_to_vision | `bool` | | | 7 - true when the position states are reset to the vision system measurement | +| starting_gps_fusion | `bool` | | | 8 - true when the filter starts using gps measurements to correct the state estimates | +| starting_vision_pos_fusion | `bool` | | | 9 - true when the filter starts using vision system position measurements to correct the state estimates | +| starting_vision_vel_fusion | `bool` | | | 10 - true when the filter starts using vision system velocity measurements to correct the state estimates | +| starting_vision_yaw_fusion | `bool` | | | 11 - true when the filter starts using vision system yaw measurements to correct the state estimates | +| yaw_aligned_to_imu_gps | `bool` | | | 12 - true when the filter resets the yaw to an estimate derived from IMU and GPS data | +| reset_hgt_to_baro | `bool` | | | 13 - true when the vertical position state is reset to the baro measurement | +| reset_hgt_to_gps | `bool` | | | 14 - true when the vertical position state is reset to the gps measurement | +| reset_hgt_to_rng | `bool` | | | 15 - true when the vertical position state is reset to the rng measurement | +| reset_hgt_to_ev | `bool` | | | 16 - true when the vertical position state is reset to the ev measurement | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorEventFlags.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -27,5 +60,6 @@ bool reset_hgt_to_baro # 13 - true when the vertical position s bool reset_hgt_to_gps # 14 - true when the vertical position state is reset to the gps measurement bool reset_hgt_to_rng # 15 - true when the vertical position state is reset to the rng measurement bool reset_hgt_to_ev # 16 - true when the vertical position state is reset to the ev measurement - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorGpsStatus.md b/docs/en/msg_docs/EstimatorGpsStatus.md index e25be3e558..a7c5927b41 100644 --- a/docs/en/msg_docs/EstimatorGpsStatus.md +++ b/docs/en/msg_docs/EstimatorGpsStatus.md @@ -1,8 +1,38 @@ +--- +pageClass: is-wide-page +--- + # EstimatorGpsStatus (UORB message) +**TOPICS:** estimator_gpsstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorGpsStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------------- | --------- | ------------ | ---------- | -------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| checks_passed | `bool` | | | +| check_fail_gps_fix | `bool` | | | 0 : insufficient fix type (no 3D solution) | +| check_fail_min_sat_count | `bool` | | | 1 : minimum required sat count fail | +| check_fail_max_pdop | `bool` | | | 2 : maximum allowed PDOP fail | +| check_fail_max_horz_err | `bool` | | | 3 : maximum allowed horizontal position error fail | +| check_fail_max_vert_err | `bool` | | | 4 : maximum allowed vertical position error fail | +| check_fail_max_spd_err | `bool` | | | 5 : maximum allowed speed error fail | +| check_fail_max_horz_drift | `bool` | | | 6 : maximum allowed horizontal position drift fail - requires stationary vehicle | +| check_fail_max_vert_drift | `bool` | | | 7 : maximum allowed vertical position drift fail - requires stationary vehicle | +| check_fail_max_horz_spd_err | `bool` | | | 8 : maximum allowed horizontal speed fail - requires stationary vehicle | +| check_fail_max_vert_spd_err | `bool` | | | 9 : maximum allowed vertical velocity discrepancy fail | +| check_fail_spoofed_gps | `bool` | | | 10 : GPS signal is spoofed | +| position_drift_rate_horizontal_m_s | `float32` | | | Horizontal position rate magnitude (m/s) | +| position_drift_rate_vertical_m_s | `float32` | | | Vertical position rate magnitude (m/s) | +| filtered_horizontal_speed_m_s | `float32` | | | Filtered horizontal velocity magnitude (m/s) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorGpsStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -25,5 +55,6 @@ bool check_fail_spoofed_gps # 10 : GPS signal is spoofed float32 position_drift_rate_horizontal_m_s # Horizontal position rate magnitude (m/s) float32 position_drift_rate_vertical_m_s # Vertical position rate magnitude (m/s) float32 filtered_horizontal_speed_m_s # Filtered horizontal velocity magnitude (m/s) - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorInnovations.md b/docs/en/msg_docs/EstimatorInnovations.md index 478fe79831..87b559ecf8 100644 --- a/docs/en/msg_docs/EstimatorInnovations.md +++ b/docs/en/msg_docs/EstimatorInnovations.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # EstimatorInnovations (UORB message) +**TOPICS:** estimator_innovations estimator_innovation_variances estimator_innovation_test_ratios +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| gps_hvel | `float32[2]` | | | horizontal GPS velocity innovation (m/sec) and innovation variance ((m/sec)\*\*2) | +| `float32` | | | vertical GPS velocity innovation (m/sec) and innovation variance ((m/sec)\*\*2) | +| gps_hpos | `float32[2]` | | | horizontal GPS position innovation (m) and innovation variance (m\*\*2) | +| `float32` | | | vertical GPS position innovation (m) and innovation variance (m\*\*2) | +| ev_hvel | `float32[2]` | | | horizontal external vision velocity innovation (m/sec) and innovation variance ((m/sec)\*\*2) | +| `float32` | | | vertical external vision velocity innovation (m/sec) and innovation variance ((m/sec)\*\*2) | +| ev_hpos | `float32[2]` | | | horizontal external vision position innovation (m) and innovation variance (m\*\*2) | +| `float32` | | | vertical external vision position innovation (m) and innovation variance (m\*\*2) | +| rng_vpos | `float32` | | | range sensor height innovation (m) and innovation variance (m\*\*2) | +| baro_vpos | `float32` | | | barometer height innovation (m) and innovation variance (m\*\*2) | +| aux_hvel | `float32[2]` | | | horizontal auxiliary velocity innovation from landing target measurement (m/sec) and innovation variance ((m/sec)\*\*2) | +| flow | `float32[2]` | | | flow innvoation (rad/sec) and innovation variance ((rad/sec)\*\*2) | +| heading | `float32` | | | heading innovation (rad) and innovation variance (rad\*\*2) | +| mag_field | `float32[3]` | | | earth magnetic field innovation (Gauss) and innovation variance (Gauss\*\*2) | +| gravity | `float32[3]` | | | gravity innovation from accelerometerr vector (m/s\*\*2) | +| drag | `float32[2]` | | | drag specific force innovation (m/sec**2) and innovation variance ((m/sec)**2) | +| airspeed | `float32` | | | airspeed innovation (m/sec) and innovation variance ((m/sec)\*\*2) | +| beta | `float32` | | | synthetic sideslip innovation (rad) and innovation variance (rad\*\*2) | +| hagl | `float32` | | | height of ground innovation (m) and innovation variance (m\*\*2) | +| hagl_rate | `float32` | | | height of ground rate innovation (m/s) and innovation variance ((m/s)\*\*2) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -44,5 +79,6 @@ float32 hagl_rate # height of ground rate innovation (m/s) and innovation varian # the test ratio will be put in the first component of the vector. # TOPICS estimator_innovations estimator_innovation_variances estimator_innovation_test_ratios - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorSelectorStatus.md b/docs/en/msg_docs/EstimatorSelectorStatus.md index 3e64205a8f..71ed593ee3 100644 --- a/docs/en/msg_docs/EstimatorSelectorStatus.md +++ b/docs/en/msg_docs/EstimatorSelectorStatus.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # EstimatorSelectorStatus (UORB message) +**TOPICS:** estimator_selectorstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorSelectorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| primary_instance | `uint8` | | | +| instances_available | `uint8` | | | +| instance_changed_count | `uint32` | | | +| last_instance_change | `uint64` | | | +| accel_device_id | `uint32` | | | +| baro_device_id | `uint32` | | | +| gyro_device_id | `uint32` | | | +| mag_device_id | `uint32` | | | +| combined_test_ratio | `float32[9]` | | | +| relative_test_ratio | `float32[9]` | | | +| healthy | `bool[9]` | | | +| accumulated_gyro_error | `float32[4]` | | | +| accumulated_accel_error | `float32[4]` | | | +| gyro_fault_detected | `bool` | | | +| accel_fault_detected | `bool` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorSelectorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -27,5 +56,6 @@ float32[4] accumulated_gyro_error float32[4] accumulated_accel_error bool gyro_fault_detected bool accel_fault_detected - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorSensorBias.md b/docs/en/msg_docs/EstimatorSensorBias.md index 9b4a1d66c2..b41736370c 100644 --- a/docs/en/msg_docs/EstimatorSensorBias.md +++ b/docs/en/msg_docs/EstimatorSensorBias.md @@ -1,9 +1,43 @@ +--- +pageClass: is-wide-page +--- + # EstimatorSensorBias (UORB message) -Sensor readings and in-run biases in SI-unit form. Sensor readings are compensated for static offsets, -scale errors, in-run bias and thermal drift (if thermal compensation is enabled and available). +Sensor readings and in-run biases in SI-unit form. Sensor readings are compensated for static offsets,. scale errors, in-run bias and thermal drift (if thermal compensation is enabled and available). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorSensorBias.msg) +**TOPICS:** estimator_sensorbias + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| gyro_device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| gyro_bias | `float32[3]` | | | gyroscope in-run bias in body frame (rad/s) | +| gyro_bias_limit | `float32` | | | magnitude of maximum gyroscope in-run bias in body frame (rad/s) | +| gyro_bias_variance | `float32[3]` | | | +| gyro_bias_valid | `bool` | | | +| gyro_bias_stable | `bool` | | | true when the gyro bias estimate is stable enough to use for calibration | +| accel_device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| accel_bias | `float32[3]` | | | accelerometer in-run bias in body frame (m/s^2) | +| accel_bias_limit | `float32` | | | magnitude of maximum accelerometer in-run bias in body frame (m/s^2) | +| accel_bias_variance | `float32[3]` | | | +| accel_bias_valid | `bool` | | | +| accel_bias_stable | `bool` | | | true when the accel bias estimate is stable enough to use for calibration | +| mag_device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| mag_bias | `float32[3]` | | | magnetometer in-run bias in body frame (Gauss) | +| mag_bias_limit | `float32` | | | magnitude of maximum magnetometer in-run bias in body frame (Gauss) | +| mag_bias_variance | `float32[3]` | | | +| mag_bias_valid | `bool` | | | +| mag_bias_stable | `bool` | | | true when the mag bias estimate is stable enough to use for calibration | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorSensorBias.msg) + +::: details Click here to see original file ```c # @@ -36,5 +70,6 @@ float32 mag_bias_limit # magnitude of maximum magnetometer in-run bias float32[3] mag_bias_variance bool mag_bias_valid bool mag_bias_stable # true when the mag bias estimate is stable enough to use for calibration - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorStates.md b/docs/en/msg_docs/EstimatorStates.md index b3a343217b..f4f5f2f149 100644 --- a/docs/en/msg_docs/EstimatorStates.md +++ b/docs/en/msg_docs/EstimatorStates.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # EstimatorStates (UORB message) +**TOPICS:** estimator_states +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------- | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| states | `float32[25]` | | | Internal filter states | +| n_states | `uint8` | | | Number of states effectively used | +| covariances | `float32[24]` | | | Diagonal Elements of Covariance Matrix | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +30,6 @@ float32[25] states # Internal filter states uint8 n_states # Number of states effectively used float32[24] covariances # Diagonal Elements of Covariance Matrix - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorStatus.md b/docs/en/msg_docs/EstimatorStatus.md index 96254b1d1c..b07b023f3e 100644 --- a/docs/en/msg_docs/EstimatorStatus.md +++ b/docs/en/msg_docs/EstimatorStatus.md @@ -1,8 +1,108 @@ +--- +pageClass: is-wide-page +--- + # EstimatorStatus (UORB message) +**TOPICS:** estimator_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| output_tracking_error | `float32[3]` | | | return a vector containing the output predictor angular, velocity and position tracking error magnitudes (rad), (m/s), (m) | +| gps_check_fail_flags | `uint16` | | | Bitmask to indicate status of GPS checks - see definition below | +| control_mode_flags | `uint64` | | | Bitmask to indicate EKF logic state | +| filter_fault_flags | `uint32` | | | Bitmask to indicate EKF internal faults | +| pos_horiz_accuracy | `float32` | | | 1-Sigma estimated horizontal position accuracy relative to the estimators origin (m) | +| pos_vert_accuracy | `float32` | | | 1-Sigma estimated vertical position accuracy relative to the estimators origin (m) | +| hdg_test_ratio | `float32` | | | low-pass filtered ratio of the largest heading innovation component to the innovation test limit | +| vel_test_ratio | `float32` | | | low-pass filtered ratio of the largest velocity innovation component to the innovation test limit | +| pos_test_ratio | `float32` | | | low-pass filtered ratio of the largest horizontal position innovation component to the innovation test limit | +| hgt_test_ratio | `float32` | | | low-pass filtered ratio of the vertical position innovation to the innovation test limit | +| tas_test_ratio | `float32` | | | low-pass filtered ratio of the true airspeed innovation to the innovation test limit | +| hagl_test_ratio | `float32` | | | low-pass filtered ratio of the height above ground innovation to the innovation test limit | +| beta_test_ratio | `float32` | | | low-pass filtered ratio of the synthetic sideslip innovation to the innovation test limit | +| solution_status_flags | `uint16` | | | Bitmask indicating which filter kinematic state outputs are valid for flight control use. | +| reset_count_vel_ne | `uint8` | | | number of horizontal position reset events (allow to wrap if count exceeds 255) | +| reset_count_vel_d | `uint8` | | | number of vertical velocity reset events (allow to wrap if count exceeds 255) | +| reset_count_pos_ne | `uint8` | | | number of horizontal position reset events (allow to wrap if count exceeds 255) | +| reset_count_pod_d | `uint8` | | | number of vertical position reset events (allow to wrap if count exceeds 255) | +| reset_count_quat | `uint8` | | | number of quaternion reset events (allow to wrap if count exceeds 255) | +| time_slip | `float32` | | | cumulative amount of time in seconds that the EKF inertial calculation has slipped relative to system time | +| pre_flt_fail_innov_heading | `bool` | | | +| pre_flt_fail_innov_height | `bool` | | | +| pre_flt_fail_innov_pos_horiz | `bool` | | | +| pre_flt_fail_innov_vel_horiz | `bool` | | | +| pre_flt_fail_innov_vel_vert | `bool` | | | +| pre_flt_fail_mag_field_disturbed | `bool` | | | +| accel_device_id | `uint32` | | | +| gyro_device_id | `uint32` | | | +| baro_device_id | `uint32` | | | +| mag_device_id | `uint32` | | | +| health_flags | `uint8` | | | Bitmask to indicate sensor health states (vel, pos, hgt) | +| timeout_flags | `uint8` | | | Bitmask to indicate timeout flags (vel, pos, hgt) | +| mag_inclination_deg | `float32` | | | +| mag_inclination_ref_deg | `float32` | | | +| mag_strength_gs | `float32` | | | +| mag_strength_ref_gs | `float32` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | ------- | ----- | --------------------------------------------------------------------------------------------- | +| GPS_CHECK_FAIL_GPS_FIX | `uint8` | 0 | 0 : insufficient fix type (no 3D solution) | +| GPS_CHECK_FAIL_MIN_SAT_COUNT | `uint8` | 1 | 1 : minimum required sat count fail | +| GPS_CHECK_FAIL_MAX_PDOP | `uint8` | 2 | 2 : maximum allowed PDOP fail | +| GPS_CHECK_FAIL_MAX_HORZ_ERR | `uint8` | 3 | 3 : maximum allowed horizontal position error fail | +| GPS_CHECK_FAIL_MAX_VERT_ERR | `uint8` | 4 | 4 : maximum allowed vertical position error fail | +| GPS_CHECK_FAIL_MAX_SPD_ERR | `uint8` | 5 | 5 : maximum allowed speed error fail | +| GPS_CHECK_FAIL_MAX_HORZ_DRIFT | `uint8` | 6 | 6 : maximum allowed horizontal position drift fail - requires stationary vehicle | +| GPS_CHECK_FAIL_MAX_VERT_DRIFT | `uint8` | 7 | 7 : maximum allowed vertical position drift fail - requires stationary vehicle | +| GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR | `uint8` | 8 | 8 : maximum allowed horizontal speed fail - requires stationary vehicle | +| GPS_CHECK_FAIL_MAX_VERT_SPD_ERR | `uint8` | 9 | 9 : maximum allowed vertical velocity discrepancy fail | +| GPS_CHECK_FAIL_SPOOFED | `uint8` | 10 | 10 : GPS signal is spoofed | +| GPS_CHECK_FAIL_JAMMED | `uint8` | 11 | 11 : GPS signal is jammed | +| CS_TILT_ALIGN | `uint8` | 0 | 0 - true if the filter tilt alignment is complete | +| CS_YAW_ALIGN | `uint8` | 1 | 1 - true if the filter yaw alignment is complete | +| CS_GNSS_POS | `uint8` | 2 | 2 - true if GNSS position measurements are being fused | +| CS_OPT_FLOW | `uint8` | 3 | 3 - true if optical flow measurements are being fused | +| CS_MAG_HDG | `uint8` | 4 | 4 - true if a simple magnetic yaw heading is being fused | +| CS_MAG_3D | `uint8` | 5 | 5 - true if 3-axis magnetometer measurement are being fused | +| CS_MAG_DEC | `uint8` | 6 | 6 - true if synthetic magnetic declination measurements are being fused | +| CS_IN_AIR | `uint8` | 7 | 7 - true when thought to be airborne | +| CS_WIND | `uint8` | 8 | 8 - true when wind velocity is being estimated | +| CS_BARO_HGT | `uint8` | 9 | 9 - true when baro data is being fused | +| CS_RNG_HGT | `uint8` | 10 | 10 - true when range finder data is being fused for height aiding | +| CS_GPS_HGT | `uint8` | 11 | 11 - true when GPS altitude is being fused | +| CS_EV_POS | `uint8` | 12 | 12 - true when local position data from external vision is being fused | +| CS_EV_YAW | `uint8` | 13 | 13 - true when yaw data from external vision measurements is being fused | +| CS_EV_HGT | `uint8` | 14 | 14 - true when height data from external vision measurements is being fused | +| CS_BETA | `uint8` | 15 | 15 - true when synthetic sideslip measurements are being fused | +| CS_MAG_FIELD | `uint8` | 16 | 16 - true when only the magnetic field states are updated by the magnetometer | +| CS_FIXED_WING | `uint8` | 17 | 17 - true when thought to be operating as a fixed wing vehicle with constrained sideslip | +| CS_MAG_FAULT | `uint8` | 18 | 18 - true when the magnetometer has been declared faulty and is no longer being used | +| CS_ASPD | `uint8` | 19 | 19 - true when airspeed measurements are being fused | +| CS_GND_EFFECT | `uint8` | 20 | 20 - true when when protection from ground effect induced static pressure rise is active | +| CS_RNG_STUCK | `uint8` | 21 | 21 - true when a stuck range finder sensor has been detected | +| CS_GPS_YAW | `uint8` | 22 | 22 - true when yaw (not ground course) data from a GPS receiver is being fused | +| CS_MAG_ALIGNED | `uint8` | 23 | 23 - true when the in-flight mag field alignment has been completed | +| CS_EV_VEL | `uint8` | 24 | 24 - true when local frame velocity data fusion from external vision measurements is intended | +| CS_SYNTHETIC_MAG_Z | `uint8` | 25 | 25 - true when we are using a synthesized measurement for the magnetometer Z component | +| CS_VEHICLE_AT_REST | `uint8` | 26 | 26 - true when the vehicle is at rest | +| CS_GPS_YAW_FAULT | `uint8` | 27 | 27 - true when the GNSS heading has been declared faulty and is no longer being used | +| CS_RNG_FAULT | `uint8` | 28 | 28 - true when the range finder has been declared faulty and is no longer being used | +| CS_GNSS_VEL | `uint8` | 44 | 44 - true if GNSS velocity measurement fusion is intended | +| CS_GNSS_FAULT | `uint8` | 45 | 45 - true if GNSS measurements have been declared faulty and are no longer used | +| CS_YAW_MANUAL | `uint8` | 46 | 46 - true if yaw has been set manually | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -23,6 +123,7 @@ uint8 GPS_CHECK_FAIL_MAX_VERT_DRIFT = 7 # 7 : maximum allowed vertical position uint8 GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR = 8 # 8 : maximum allowed horizontal speed fail - requires stationary vehicle uint8 GPS_CHECK_FAIL_MAX_VERT_SPD_ERR = 9 # 9 : maximum allowed vertical velocity discrepancy fail uint8 GPS_CHECK_FAIL_SPOOFED = 10 # 10 : GPS signal is spoofed +uint8 GPS_CHECK_FAIL_JAMMED = 11 # 11 : GPS signal is jammed uint64 control_mode_flags # Bitmask to indicate EKF logic state uint8 CS_TILT_ALIGN = 0 # 0 - true if the filter tilt alignment is complete @@ -54,7 +155,9 @@ uint8 CS_SYNTHETIC_MAG_Z = 25 # 25 - true when we are using a synthesized measur uint8 CS_VEHICLE_AT_REST = 26 # 26 - true when the vehicle is at rest uint8 CS_GPS_YAW_FAULT = 27 # 27 - true when the GNSS heading has been declared faulty and is no longer being used uint8 CS_RNG_FAULT = 28 # 28 - true when the range finder has been declared faulty and is no longer being used -uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurements are being fused +uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurement fusion is intended +uint8 CS_GNSS_FAULT = 45 # 45 - true if GNSS measurements have been declared faulty and are no longer used +uint8 CS_YAW_MANUAL = 46 # 46 - true if yaw has been set manually uint32 filter_fault_flags # Bitmask to indicate EKF internal faults # 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error @@ -129,5 +232,6 @@ float32 mag_inclination_deg float32 mag_inclination_ref_deg float32 mag_strength_gs float32 mag_strength_ref_gs - ``` + +::: diff --git a/docs/en/msg_docs/EstimatorStatusFlags.md b/docs/en/msg_docs/EstimatorStatusFlags.md index eede0693db..f5cd630a8c 100644 --- a/docs/en/msg_docs/EstimatorStatusFlags.md +++ b/docs/en/msg_docs/EstimatorStatusFlags.md @@ -1,8 +1,84 @@ +--- +pageClass: is-wide-page +--- + # EstimatorStatusFlags (UORB message) +**TOPICS:** estimator_statusflags +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatusFlags.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| control_status_changes | `uint32` | | | number of filter control status (cs) changes | +| cs_tilt_align | `bool` | | | 0 - true if the filter tilt alignment is complete | +| cs_yaw_align | `bool` | | | 1 - true if the filter yaw alignment is complete | +| cs_gnss_pos | `bool` | | | 2 - true if GNSS position measurement fusion is intended | +| cs_opt_flow | `bool` | | | 3 - true if optical flow measurements fusion is intended | +| cs_mag_hdg | `bool` | | | 4 - true if a simple magnetic yaw heading fusion is intended | +| cs_mag_3d | `bool` | | | 5 - true if 3-axis magnetometer measurement fusion is intended | +| cs_mag_dec | `bool` | | | 6 - true if synthetic magnetic declination measurements fusion is intended | +| cs_in_air | `bool` | | | 7 - true when the vehicle is airborne | +| cs_wind | `bool` | | | 8 - true when wind velocity is being estimated | +| cs_baro_hgt | `bool` | | | 9 - true when baro data is being fused | +| cs_rng_hgt | `bool` | | | 10 - true when range finder data is being fused for height aiding | +| cs_gps_hgt | `bool` | | | 11 - true when GPS altitude is being fused | +| cs_ev_pos | `bool` | | | 12 - true when local position data fusion from external vision is intended | +| cs_ev_yaw | `bool` | | | 13 - true when yaw data from external vision measurements fusion is intended | +| cs_ev_hgt | `bool` | | | 14 - true when height data from external vision measurements is being fused | +| cs_fuse_beta | `bool` | | | 15 - true when synthetic sideslip measurements are being fused | +| cs_mag_field_disturbed | `bool` | | | 16 - true when the mag field does not match the expected strength | +| cs_fixed_wing | `bool` | | | 17 - true when the vehicle is operating as a fixed wing vehicle | +| cs_mag_fault | `bool` | | | 18 - true when the magnetometer has been declared faulty and is no longer being used | +| cs_fuse_aspd | `bool` | | | 19 - true when airspeed measurements are being fused | +| cs_gnd_effect | `bool` | | | 20 - true when protection from ground effect induced static pressure rise is active | +| cs_rng_stuck | `bool` | | | 21 - true when rng data wasn't ready for more than 10s and new rng values haven't changed enough | +| cs_gnss_yaw | `bool` | | | 22 - true when yaw (not ground course) data fusion from a GPS receiver is intended | +| cs_mag_aligned_in_flight | `bool` | | | 23 - true when the in-flight mag field alignment has been completed | +| cs_ev_vel | `bool` | | | 24 - true when local frame velocity data fusion from external vision measurements is intended | +| cs_synthetic_mag_z | `bool` | | | 25 - true when we are using a synthesized measurement for the magnetometer Z component | +| cs_vehicle_at_rest | `bool` | | | 26 - true when the vehicle is at rest | +| cs_gnss_yaw_fault | `bool` | | | 27 - true when the GNSS heading has been declared faulty and is no longer being used | +| cs_rng_fault | `bool` | | | 28 - true when the range finder has been declared faulty and is no longer being used | +| cs_inertial_dead_reckoning | `bool` | | | 29 - true if we are no longer fusing measurements that constrain horizontal velocity drift | +| cs_wind_dead_reckoning | `bool` | | | 30 - true if we are navigationg reliant on wind relative measurements | +| cs_rng_kin_consistent | `bool` | | | 31 - true when the range finder kinematic consistency check is passing | +| cs_fake_pos | `bool` | | | 32 - true when fake position measurements are being fused | +| cs_fake_hgt | `bool` | | | 33 - true when fake height measurements are being fused | +| cs_gravity_vector | `bool` | | | 34 - true when gravity vector measurements are being fused | +| cs_mag | `bool` | | | 35 - true if 3-axis magnetometer measurement fusion (mag states only) is intended | +| cs_ev_yaw_fault | `bool` | | | 36 - true when the EV heading has been declared faulty and is no longer being used | +| cs_mag_heading_consistent | `bool` | | | 37 - true when the heading obtained from mag data is declared consistent with the filter | +| cs_aux_gpos | `bool` | | | 38 - true if auxiliary global position measurement fusion is intended | +| cs_rng_terrain | `bool` | | | 39 - true if we are fusing range finder data for terrain | +| cs_opt_flow_terrain | `bool` | | | 40 - true if we are fusing flow data for terrain | +| cs_valid_fake_pos | `bool` | | | 41 - true if a valid constant position is being fused | +| cs_constant_pos | `bool` | | | 42 - true if the vehicle is at a constant position | +| cs_baro_fault | `bool` | | | 43 - true when the current baro has been declared faulty and is no longer being used | +| cs_gnss_vel | `bool` | | | 44 - true if GNSS velocity measurement fusion is intended | +| cs_gnss_fault | `bool` | | | 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty | +| cs_yaw_manual | `bool` | | | 46 - true if yaw has been set manually | +| cs_gnss_hgt_fault | `bool` | | | 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty | +| fault_status_changes | `uint32` | | | number of filter fault status (fs) changes | +| fs_bad_mag_x | `bool` | | | 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error | +| fs_bad_mag_y | `bool` | | | 1 - true if the fusion of the magnetometer Y-axis has encountered a numerical error | +| fs_bad_mag_z | `bool` | | | 2 - true if the fusion of the magnetometer Z-axis has encountered a numerical error | +| fs_bad_hdg | `bool` | | | 3 - true if the fusion of the heading angle has encountered a numerical error | +| fs_bad_mag_decl | `bool` | | | 4 - true if the fusion of the magnetic declination has encountered a numerical error | +| fs_bad_airspeed | `bool` | | | 5 - true if fusion of the airspeed has encountered a numerical error | +| fs_bad_sideslip | `bool` | | | 6 - true if fusion of the synthetic sideslip constraint has encountered a numerical error | +| fs_bad_optflow_x | `bool` | | | 7 - true if fusion of the optical flow X axis has encountered a numerical error | +| fs_bad_optflow_y | `bool` | | | 8 - true if fusion of the optical flow Y axis has encountered a numerical error | +| fs_bad_acc_vertical | `bool` | | | 10 - true if bad vertical accelerometer data has been detected | +| fs_bad_acc_clipping | `bool` | | | 11 - true if delta velocity data contains clipping (asymmetric railing) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatusFlags.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -56,6 +132,9 @@ bool cs_valid_fake_pos # 41 - true if a valid constant position is bein bool cs_constant_pos # 42 - true if the vehicle is at a constant position bool cs_baro_fault # 43 - true when the current baro has been declared faulty and is no longer being used bool cs_gnss_vel # 44 - true if GNSS velocity measurement fusion is intended +bool cs_gnss_fault # 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty +bool cs_yaw_manual # 46 - true if yaw has been set manually +bool cs_gnss_hgt_fault # 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty # fault status uint32 fault_status_changes # number of filter fault status (fs) changes @@ -70,19 +149,6 @@ bool fs_bad_optflow_x # 7 - true if fusion of the optical flow X axis h bool fs_bad_optflow_y # 8 - true if fusion of the optical flow Y axis has encountered a numerical error bool fs_bad_acc_vertical # 10 - true if bad vertical accelerometer data has been detected bool fs_bad_acc_clipping # 11 - true if delta velocity data contains clipping (asymmetric railing) - - -# innovation test failures -uint32 innovation_fault_status_changes # number of innovation fault status (reject) changes -bool reject_hor_vel # 0 - true if horizontal velocity observations have been rejected -bool reject_ver_vel # 1 - true if vertical velocity observations have been rejected -bool reject_hor_pos # 2 - true if horizontal position observations have been rejected -bool reject_ver_pos # 3 - true if vertical position observations have been rejected -bool reject_yaw # 7 - true if the yaw observation has been rejected -bool reject_airspeed # 8 - true if the airspeed observation has been rejected -bool reject_sideslip # 9 - true if the synthetic sideslip observation has been rejected -bool reject_hagl # 10 - true if the height above ground observation has been rejected -bool reject_optflow_x # 11 - true if the X optical flow observation has been rejected -bool reject_optflow_y # 12 - true if the Y optical flow observation has been rejected - ``` + +::: diff --git a/docs/en/msg_docs/Event.md b/docs/en/msg_docs/Event.md index 5d22f337f5..b32143749d 100644 --- a/docs/en/msg_docs/Event.md +++ b/docs/en/msg_docs/Event.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # Event (UORB message) -Events interface +Events interface. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/Event.msg) +**TOPICS:** event + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | ----------- | ------------ | ---------- | ------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| id | `uint32` | | | Event ID | +| event_sequence | `uint16` | | | Event sequence number | +| arguments | `uint8[25]` | | | (optional) arguments, depend on event id | +| log_levels | `uint8` | | | Log levels: 4 bits MSB: internal, 4 bits LSB: external | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/Event.msg) + +::: details Click here to see original file ```c # Events interface @@ -17,5 +44,6 @@ uint8[25] arguments # (optional) arguments, depend on event id uint8 log_levels # Log levels: 4 bits MSB: internal, 4 bits LSB: external uint8 ORB_QUEUE_LENGTH = 16 - ``` + +::: diff --git a/docs/en/msg_docs/EventV0.md b/docs/en/msg_docs/EventV0.md index 19cfa7b70c..e0d8cf8619 100644 --- a/docs/en/msg_docs/EventV0.md +++ b/docs/en/msg_docs/EventV0.md @@ -1,9 +1,35 @@ +--- +pageClass: is-wide-page +--- + # EventV0 (UORB message) -this message is required here in the msg_old folder because other msg are depending on it -Events interface +this message is required here in the msg_old folder because other msg are depending on it. Events interface. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/EventV0.msg) +**TOPICS:** eventv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | ----------- | ------------ | ---------- | ------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| id | `uint32` | | | Event ID | +| event_sequence | `uint16` | | | Event sequence number | +| arguments | `uint8[25]` | | | (optional) arguments, depend on event id | +| log_levels | `uint8` | | | Log levels: 4 bits MSB: internal, 4 bits LSB: external | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| ORB_QUEUE_LENGTH | `uint8` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/EventV0.msg) + +::: details Click here to see original file ```c # this message is required here in the msg_old folder because other msg are depending on it @@ -20,5 +46,6 @@ uint8[25] arguments # (optional) arguments, depend on event id uint8 log_levels # Log levels: 4 bits MSB: internal, 4 bits LSB: external uint8 ORB_QUEUE_LENGTH = 16 - ``` + +::: diff --git a/docs/en/msg_docs/FailsafeFlags.md b/docs/en/msg_docs/FailsafeFlags.md index a9e0079ae8..4d55acf155 100644 --- a/docs/en/msg_docs/FailsafeFlags.md +++ b/docs/en/msg_docs/FailsafeFlags.md @@ -1,3 +1,7 @@ +--- +pageClass: is-wide-page +--- + # FailsafeFlags (UORB message) Input flags for the failsafe state machine set by the arming & health checks. @@ -5,7 +9,60 @@ Input flags for the failsafe state machine set by the arming & health checks. Flags must be named such that false == no failure (e.g. \_invalid, \_unhealthy, \_lost) The flag comments are used as label for the failsafe state machine simulation -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FailsafeFlags.msg) +**TOPICS:** failsafe_flags + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------------------- | -------- | ------------ | ---------- | ----------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| mode_req_angular_velocity | `uint32` | | | +| mode_req_attitude | `uint32` | | | +| mode_req_local_alt | `uint32` | | | +| mode_req_local_position | `uint32` | | | +| mode_req_local_position_relaxed | `uint32` | | | +| mode_req_global_position | `uint32` | | | +| mode_req_global_position_relaxed | `uint32` | | | +| mode_req_mission | `uint32` | | | +| mode_req_offboard_signal | `uint32` | | | +| mode_req_home_position | `uint32` | | | +| mode_req_wind_and_flight_time_compliance | `uint32` | | | if set, mode cannot be entered if wind or flight time limit exceeded | +| mode_req_prevent_arming | `uint32` | | | if set, cannot arm while in this mode | +| mode_req_manual_control | `uint32` | | | +| mode_req_other | `uint32` | | | other requirements, not covered above (for external modes) | +| angular_velocity_invalid | `bool` | | | Angular velocity invalid | +| attitude_invalid | `bool` | | | Attitude invalid | +| local_altitude_invalid | `bool` | | | Local altitude invalid | +| local_position_invalid | `bool` | | | Local position estimate invalid | +| local_position_invalid_relaxed | `bool` | | | Local position with reduced accuracy requirements invalid (e.g. flying with optical flow) | +| local_velocity_invalid | `bool` | | | Local velocity estimate invalid | +| global_position_invalid | `bool` | | | Global position estimate invalid | +| global_position_invalid_relaxed | `bool` | | | Global position estimate invalid with relaxed accuracy requirements | +| auto_mission_missing | `bool` | | | No mission available | +| offboard_control_signal_lost | `bool` | | | Offboard signal lost | +| home_position_invalid | `bool` | | | No home position available | +| manual_control_signal_lost | `bool` | | | Manual control (RC) signal lost | +| gcs_connection_lost | `bool` | | | GCS connection lost | +| battery_warning | `uint8` | | | Battery warning level (see BatteryStatus.msg) | +| battery_low_remaining_time | `bool` | | | Low battery based on remaining flight time | +| battery_unhealthy | `bool` | | | Battery unhealthy | +| geofence_breached | `bool` | | | Geofence breached (one or multiple) | +| mission_failure | `bool` | | | Mission failure | +| vtol_fixed_wing_system_failure | `bool` | | | vehicle in fixed-wing system failure failsafe mode (after quad-chute) | +| wind_limit_exceeded | `bool` | | | Wind limit exceeded | +| flight_time_limit_exceeded | `bool` | | | Maximum flight time exceeded | +| position_accuracy_low | `bool` | | | Position estimate has dropped below threshold, but is currently still declared valid | +| navigator_failure | `bool` | | | Navigator failed to execute a mode | +| fd_critical_failure | `bool` | | | Critical failure (attitude/altitude limit exceeded, or external ATS) | +| fd_esc_arming_failure | `bool` | | | ESC failed to arm | +| fd_imbalanced_prop | `bool` | | | Imbalanced propeller detected | +| fd_motor_failure | `bool` | | | Motor failure | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FailsafeFlags.msg) + +::: details Click here to see original file ```c # Input flags for the failsafe state machine set by the arming & health checks. @@ -68,5 +125,6 @@ bool fd_critical_failure # Critical failure (attitude/altitude limi bool fd_esc_arming_failure # ESC failed to arm bool fd_imbalanced_prop # Imbalanced propeller detected bool fd_motor_failure # Motor failure - ``` + +::: diff --git a/docs/en/msg_docs/FailureDetectorStatus.md b/docs/en/msg_docs/FailureDetectorStatus.md index 369a176b24..66474a28c0 100644 --- a/docs/en/msg_docs/FailureDetectorStatus.md +++ b/docs/en/msg_docs/FailureDetectorStatus.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # FailureDetectorStatus (UORB message) +**TOPICS:** failure_detectorstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FailureDetectorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | --------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| fd_roll | `bool` | | | +| fd_pitch | `bool` | | | +| fd_alt | `bool` | | | +| fd_ext | `bool` | | | +| fd_arm_escs | `bool` | | | +| fd_battery | `bool` | | | +| fd_imbalanced_prop | `bool` | | | +| fd_motor | `bool` | | | +| imbalanced_prop_metric | `float32` | | | Metric of the imbalanced propeller check (low-passed) | +| motor_failure_mask | `uint16` | | | Bit-mask with motor indices, indicating critical motor failures | +| motor_stop_mask | `uint16` | | | Bitmaks of motors stopped by failure injection | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FailureDetectorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -19,5 +44,7 @@ bool fd_motor float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed) uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures - +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` + +::: diff --git a/docs/en/msg_docs/FigureEightStatus.md b/docs/en/msg_docs/FigureEightStatus.md index 5487490804..2f1e197a89 100644 --- a/docs/en/msg_docs/FigureEightStatus.md +++ b/docs/en/msg_docs/FigureEightStatus.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # FigureEightStatus (UORB message) +**TOPICS:** figure_eightstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FigureEightStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| major_radius | `float32` | | | Major axis radius of the figure eight [m]. Positive values orbit clockwise, negative values orbit counter-clockwise. | +| minor_radius | `float32` | | | Minor axis radius of the figure eight [m]. | +| orientation | `float32` | | | Orientation of the major axis of the figure eight [rad]. | +| frame | `uint8` | | | The coordinate system of the fields: x, y, z. | +| x | `int32` | | | X coordinate of center point. Coordinate system depends on frame field: local = x position in meters _ 1e4, global = latitude in degrees _ 1e7. | +| y | `int32` | | | Y coordinate of center point. Coordinate system depends on frame field: local = y position in meters _ 1e4, global = latitude in degrees _ 1e7. | +| z | `float32` | | | Altitude of center point. Coordinate system depends on frame field. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FigureEightStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +34,6 @@ uint8 frame # The coordinate system of the fields: x, y, z. int32 x # X coordinate of center point. Coordinate system depends on frame field: local = x position in meters * 1e4, global = latitude in degrees * 1e7. int32 y # Y coordinate of center point. Coordinate system depends on frame field: local = y position in meters * 1e4, global = latitude in degrees * 1e7. float32 z # Altitude of center point. Coordinate system depends on frame field. - ``` + +::: diff --git a/docs/en/msg_docs/FixedWingLateralGuidanceStatus.md b/docs/en/msg_docs/FixedWingLateralGuidanceStatus.md index 02dc50b410..648e02d748 100644 --- a/docs/en/msg_docs/FixedWingLateralGuidanceStatus.md +++ b/docs/en/msg_docs/FixedWingLateralGuidanceStatus.md @@ -1,9 +1,32 @@ +--- +pageClass: is-wide-page +--- + # FixedWingLateralGuidanceStatus (UORB message) -Fixed Wing Lateral Guidance Status message -Published by fw_pos_control module to report the resultant lateral setpoints and NPFG debug outputs +Fixed Wing Lateral Guidance Status message. Published by fw_pos_control module to report the resultant lateral setpoints and NPFG debug outputs. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingLateralGuidanceStatus.msg) +**TOPICS:** fixed_winglateral_guidancestatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| course_setpoint | `float32` | rad | [-pi : pi] | Desired direction of travel over ground w.r.t (true) North. Set by guidance law | +| lateral_acceleration_ff | `float32` | FRD | | lateral acceleration demand only for maintaining curvature | +| bearing_feas | `float32` | | [0 : 1] | bearing feasibility | +| bearing_feas_on_track | `float32` | | [0 : 1] | on-track bearing feasibility | +| signed_track_error | `float32` | m | | signed track error | +| track_error_bound | `float32` | m | | track error bound | +| adapted_period | `float32` | s | | adapted period (if auto-tuning enabled) | +| wind_est_valid | `uint8` | boolean | | true = wind estimate is valid and/or being used by controller (also indicates if wind estimate usage is disabled despite being valid) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingLateralGuidanceStatus.msg) + +::: details Click here to see original file ```c # Fixed Wing Lateral Guidance Status message @@ -19,5 +42,6 @@ float32 signed_track_error # [m] signed track error float32 track_error_bound # [m] track error bound float32 adapted_period # [s] adapted period (if auto-tuning enabled) uint8 wind_est_valid # [boolean] true = wind estimate is valid and/or being used by controller (also indicates if wind estimate usage is disabled despite being valid) - ``` + +::: diff --git a/docs/en/msg_docs/FixedWingLateralSetpoint.md b/docs/en/msg_docs/FixedWingLateralSetpoint.md index 153167bb62..3b1cc74836 100644 --- a/docs/en/msg_docs/FixedWingLateralSetpoint.md +++ b/docs/en/msg_docs/FixedWingLateralSetpoint.md @@ -1,10 +1,33 @@ +--- +pageClass: is-wide-page +--- + # FixedWingLateralSetpoint (UORB message) -Fixed Wing Lateral Setpoint message -Used by the fw_lateral_longitudinal_control module -At least one of course, airspeed_direction, or lateral_acceleration must be finite. +Fixed Wing Lateral Setpoint message. Used by the fw_lateral_longitudinal_control module. At least one of course, airspeed_direction, or lateral_acceleration must be finite. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/FixedWingLateralSetpoint.msg) +**TOPICS:** fixed_winglateral_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | --------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| course | `float32` | rad | [-pi : pi] | Desired direction of travel over ground w.r.t (true) North. NAN if not controlled directly. | +| airspeed_direction | `float32` | rad | [-pi : pi] | Desired horizontal angle of airspeed vector w.r.t. (true) North. Same as vehicle heading if in the absence of sideslip. NAN if not controlled directly, takes precedence over course if finite. | +| lateral_acceleration | `float32` | FRD | | Lateral acceleration setpoint. NAN if not controlled directly, used as feedforward if either course setpoint or airspeed_direction is finite. | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/FixedWingLateralSetpoint.msg) + +::: details Click here to see original file ```c # Fixed Wing Lateral Setpoint message @@ -18,5 +41,6 @@ uint64 timestamp # time since system start (microseconds) float32 course # [rad] [@range -pi, pi] Desired direction of travel over ground w.r.t (true) North. NAN if not controlled directly. float32 airspeed_direction # [rad] [@range -pi, pi] Desired horizontal angle of airspeed vector w.r.t. (true) North. Same as vehicle heading if in the absence of sideslip. NAN if not controlled directly, takes precedence over course if finite. float32 lateral_acceleration # [m/s^2] [FRD] Lateral acceleration setpoint. NAN if not controlled directly, used as feedforward if either course setpoint or airspeed_direction is finite. - ``` + +::: diff --git a/docs/en/msg_docs/FixedWingLateralStatus.md b/docs/en/msg_docs/FixedWingLateralStatus.md index 9214d1e9e0..5956a00dfb 100644 --- a/docs/en/msg_docs/FixedWingLateralStatus.md +++ b/docs/en/msg_docs/FixedWingLateralStatus.md @@ -1,9 +1,26 @@ +--- +pageClass: is-wide-page +--- + # FixedWingLateralStatus (UORB message) -Fixed Wing Lateral Status message -Published by the fw_lateral_longitudinal_control module to report the resultant lateral setpoint +Fixed Wing Lateral Status message. Published by the fw_lateral_longitudinal_control module to report the resultant lateral setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingLateralStatus.msg) +**TOPICS:** fixed_winglateral_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------------- | --------- | ------------ | ---------- | ---------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| lateral_acceleration_setpoint | `float32` | FRD | | resultant lateral acceleration setpoint | +| can_run_factor | `float32` | norm | [0 : 1] | estimate of certainty of the correct functionality of the npfg roll setpoint | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingLateralStatus.msg) + +::: details Click here to see original file ```c # Fixed Wing Lateral Status message @@ -13,5 +30,6 @@ uint64 timestamp # time since system start (microseconds float32 lateral_acceleration_setpoint # [m/s^2] [FRD] resultant lateral acceleration setpoint float32 can_run_factor # [norm] [@range 0, 1] estimate of certainty of the correct functionality of the npfg roll setpoint - ``` + +::: diff --git a/docs/en/msg_docs/FixedWingLongitudinalSetpoint.md b/docs/en/msg_docs/FixedWingLongitudinalSetpoint.md index 6b8fb29e5b..f58d892f8f 100644 --- a/docs/en/msg_docs/FixedWingLongitudinalSetpoint.md +++ b/docs/en/msg_docs/FixedWingLongitudinalSetpoint.md @@ -1,11 +1,35 @@ +--- +pageClass: is-wide-page +--- + # FixedWingLongitudinalSetpoint (UORB message) -Fixed Wing Longitudinal Setpoint message -Used by the fw_lateral_longitudinal_control module -If pitch_direct and throttle_direct are not both finite, then the controller relies on altitude/height_rate and equivalent_airspeed to control vertical motion. -If both altitude and height_rate are NAN, the controller maintains the current altitude. +Fixed Wing Longitudinal Setpoint message. Used by the fw_lateral_longitudinal_control module. If pitch_direct and throttle_direct are not both finite, then the controller relies on altitude/height_rate and equivalent_airspeed to control vertical motion. If both altitude and height_rate are NAN, the controller maintains the current altitude. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/FixedWingLongitudinalSetpoint.msg) +**TOPICS:** fixed_winglongitudinal_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | --------- | ------------ | ---------- | ---------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| altitude | `float32` | m | | Altitude setpoint AMSL, not controlled directly if NAN or if height_rate is finite | +| height_rate | `float32` | ENU | | Scalar height rate setpoint. NAN if not controlled directly | +| equivalent_airspeed | `float32` | m/s | [0 : inf] | Scalar equivalent airspeed setpoint. NAN if system default should be used | +| pitch_direct | `float32` | FRD | [-pi : pi] | NAN if not controlled, overrides total energy controller | +| throttle_direct | `float32` | norm | [0 : 1] | NAN if not controlled, overrides total energy controller | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/FixedWingLongitudinalSetpoint.msg) + +::: details Click here to see original file ```c # Fixed Wing Longitudinal Setpoint message @@ -22,5 +46,6 @@ float32 height_rate # [m/s] [ENU] Scalar height rate setpoint. NAN if not con float32 equivalent_airspeed # [m/s] [@range 0, inf] Scalar equivalent airspeed setpoint. NAN if system default should be used float32 pitch_direct # [rad] [@range -pi, pi] [FRD] NAN if not controlled, overrides total energy controller float32 throttle_direct # [norm] [@range 0,1] NAN if not controlled, overrides total energy controller - ``` + +::: diff --git a/docs/en/msg_docs/FixedWingRunwayControl.md b/docs/en/msg_docs/FixedWingRunwayControl.md index 9e9f5ff428..a51a543a72 100644 --- a/docs/en/msg_docs/FixedWingRunwayControl.md +++ b/docs/en/msg_docs/FixedWingRunwayControl.md @@ -1,19 +1,53 @@ +--- +pageClass: is-wide-page +--- + # FixedWingRunwayControl (UORB message) -Auxiliary control fields for fixed-wing runway takeoff/landing +Auxiliary control fields for fixed-wing runway takeoff/landing. -Passes information from the FixedWingModeManager to the FixedWingAttitudeController +**TOPICS:** fixed_wingrunway_control -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingRunwayControl.msg) +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | --------- | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | time since system start | +| runway_takeoff_state | `uint8` | | | Current state of runway takeoff state machine | +| wheel_steering_enabled | `bool` | | | Flag that enables the wheel steering. | +| wheel_steering_nudging_rate | `float32` | FRD | [-1 : 1] | Manual wheel nudging, added to controller output. NAN is interpreted as 0. | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | ------------------------------------------------------------- | +| STATE_THROTTLE_RAMP | `uint8` | 0 | ramping up throttle | +| STATE_CLAMPED_TO_RUNWAY | `uint8` | 1 | clamped to runway, controlling yaw directly (wheel or rudder) | +| STATE_CLIMBOUT | `uint8` | 2 | climbout to safe height before navigation | +| STATE_FLYING | `uint8` | 3 | navigate freely | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FixedWingRunwayControl.msg) + +::: details Click here to see original file ```c # Auxiliary control fields for fixed-wing runway takeoff/landing -# Passes information from the FixedWingModeManager to the FixedWingAttitudeController +# Passes information from the FixedWingModeManager to the FixedWingAttitudeController (wheel control) and FixedWingLandDetector (takeoff state) uint64 timestamp # [us] time since system start +uint8 STATE_THROTTLE_RAMP = 0 # ramping up throttle +uint8 STATE_CLAMPED_TO_RUNWAY = 1 # clamped to runway, controlling yaw directly (wheel or rudder) +uint8 STATE_CLIMBOUT = 2 # climbout to safe height before navigation +uint8 STATE_FLYING = 3 # navigate freely + +uint8 runway_takeoff_state # Current state of runway takeoff state machine + bool wheel_steering_enabled # Flag that enables the wheel steering. float32 wheel_steering_nudging_rate # [norm] [@range -1, 1] [FRD] Manual wheel nudging, added to controller output. NAN is interpreted as 0. - ``` + +::: diff --git a/docs/en/msg_docs/FlightPhaseEstimation.md b/docs/en/msg_docs/FlightPhaseEstimation.md index b3d9147e28..de23fd4f1b 100644 --- a/docs/en/msg_docs/FlightPhaseEstimation.md +++ b/docs/en/msg_docs/FlightPhaseEstimation.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # FlightPhaseEstimation (UORB message) +**TOPICS:** flight_phaseestimation +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FlightPhaseEstimation.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| flight_phase | `uint8` | | | Estimate of current flight phase | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------- | ------- | ----- | ------------------------------- | +| FLIGHT_PHASE_UNKNOWN | `uint8` | 0 | vehicle flight phase is unknown | +| FLIGHT_PHASE_LEVEL | `uint8` | 1 | Vehicle is in level flight | +| FLIGHT_PHASE_DESCEND | `uint8` | 2 | vehicle is in descend | +| FLIGHT_PHASE_CLIMB | `uint8` | 3 | vehicle is climbing | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FlightPhaseEstimation.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +37,6 @@ uint8 FLIGHT_PHASE_UNKNOWN = 0 # vehicle flight phase is unknown uint8 FLIGHT_PHASE_LEVEL = 1 # Vehicle is in level flight uint8 FLIGHT_PHASE_DESCEND = 2 # vehicle is in descend uint8 FLIGHT_PHASE_CLIMB = 3 # vehicle is climbing - ``` + +::: diff --git a/docs/en/msg_docs/FollowTarget.md b/docs/en/msg_docs/FollowTarget.md index e9086f27d6..1aab86e642 100644 --- a/docs/en/msg_docs/FollowTarget.md +++ b/docs/en/msg_docs/FollowTarget.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # FollowTarget (UORB message) +**TOPICS:** follow_target +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTarget.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| lat | `float64` | | | target position (deg \* 1e7) | +| lon | `float64` | | | target position (deg \* 1e7) | +| alt | `float32` | | | target position | +| vy | `float32` | | | target vel in y | +| vx | `float32` | | | target vel in x | +| vz | `float32` | | | target vel in z | +| est_cap | `uint8` | | | target reporting capabilities | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTarget.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,5 +37,6 @@ float32 vx # target vel in x float32 vz # target vel in z uint8 est_cap # target reporting capabilities - ``` + +::: diff --git a/docs/en/msg_docs/FollowTargetEstimator.md b/docs/en/msg_docs/FollowTargetEstimator.md index e118475f41..a9a18b8796 100644 --- a/docs/en/msg_docs/FollowTargetEstimator.md +++ b/docs/en/msg_docs/FollowTargetEstimator.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # FollowTargetEstimator (UORB message) +**TOPICS:** follow_targetestimator +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTargetEstimator.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | ------------ | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| last_filter_reset_timestamp | `uint64` | | | time of last filter reset (microseconds) | +| valid | `bool` | | | True if estimator states are okay to be used | +| stale | `bool` | | | True if estimator stopped receiving follow_target messages for some time. The estimate can still be valid, though it might be inaccurate. | +| lat_est | `float64` | | | Estimated target latitude | +| lon_est | `float64` | | | Estimated target longitude | +| alt_est | `float32` | | | Estimated target altitude | +| pos_est | `float32[3]` | | | Estimated target NED position (m) | +| vel_est | `float32[3]` | | | Estimated target NED velocity (m/s) | +| acc_est | `float32[3]` | | | Estimated target NED acceleration (m^2/s) | +| prediction_count | `uint64` | | | +| fusion_count | `uint64` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTargetEstimator.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -21,5 +46,6 @@ float32[3] acc_est # Estimated target NED acceleration (m^2/s) uint64 prediction_count uint64 fusion_count - ``` + +::: diff --git a/docs/en/msg_docs/FollowTargetStatus.md b/docs/en/msg_docs/FollowTargetStatus.md index 7f24cc1dd5..a40cc3c215 100644 --- a/docs/en/msg_docs/FollowTargetStatus.md +++ b/docs/en/msg_docs/FollowTargetStatus.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # FollowTargetStatus (UORB message) +**TOPICS:** follow_targetstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTargetStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------- | +| timestamp | `uint64` | microseconds | | time since system start | +| tracked_target_course | `float32` | rad | | Tracked target course in NED local frame (North is course zero) | +| follow_angle | `float32` | rad | | Current follow angle setting | +| orbit_angle_setpoint | `float32` | rad | | Current orbit angle setpoint from the smooth trajectory generator | +| angular_rate_setpoint | `float32` | rad/s | | Angular rate commanded from Jerk-limited Orbit Angle trajectory for Orbit Angle | +| desired_position_raw | `float32[3]` | m | | Raw 'idealistic' desired drone position if a drone could teleport from place to places | +| in_emergency_ascent | `bool` | bool | | True when doing emergency ascent (when distance to ground is below safety altitude) | +| gimbal_pitch | `float32` | rad | | Gimbal pitch commanded to track target in the center of the frame | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FollowTargetStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # [microseconds] time since system start @@ -17,5 +38,6 @@ float32[3] desired_position_raw # [m] Raw 'idealistic' desired drone position bool in_emergency_ascent # [bool] True when doing emergency ascent (when distance to ground is below safety altitude) float32 gimbal_pitch # [rad] Gimbal pitch commanded to track target in the center of the frame - ``` + +::: diff --git a/docs/en/msg_docs/FuelTankStatus.md b/docs/en/msg_docs/FuelTankStatus.md index 608999e84c..762ad98bfe 100644 --- a/docs/en/msg_docs/FuelTankStatus.md +++ b/docs/en/msg_docs/FuelTankStatus.md @@ -1,8 +1,38 @@ +--- +pageClass: is-wide-page +--- + # FuelTankStatus (UORB message) +**TOPICS:** fuel_tankstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FuelTankStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| maximum_fuel_capacity | `float32` | | | maximum fuel capacity. Must always be provided, either from the driver or a parameter | +| consumed_fuel | `float32` | | | consumed fuel, NaN if not measured. Should not be inferred from the max fuel capacity | +| fuel_consumption_rate | `float32` | | | fuel consumption rate, NaN if not measured | +| percent_remaining | `uint8` | | | percentage of remaining fuel, UINT8_MAX if not provided | +| remaining_fuel | `float32` | | | remaining fuel, NaN if not measured. Should not be inferred from the max fuel capacity | +| fuel_tank_id | `uint8` | | | identifier for the fuel tank. Must match ID of other messages for same fuel system. 0 by default when only a single tank exists | +| fuel_type | `uint32` | | | type of fuel based on MAV_FUEL_TYPE enum. Set to MAV_FUEL_TYPE_UNKNOWN if unknown or it does not fit the provided types | +| temperature | `float32` | | | fuel temperature in Kelvin, NaN if not measured | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------- | ------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| MAV_FUEL_TYPE_UNKNOWN | `uint8` | 0 | fuel type not specified. Fuel levels are normalized (i.e., maximum is 1, and other levels are relative to 1). | +| MAV_FUEL_TYPE_LIQUID | `uint8` | 1 | represents generic liquid fuels, such as gasoline or diesel. Fuel levels are measured in millilitres (ml), and flow rates in millilitres per second (ml/s). | +| MAV_FUEL_TYPE_GAS | `uint8` | 2 | represents a gas fuel, such as hydrogen, methane, or propane. Fuel levels are in kilo-Pascal (kPa), and flow rates are in milliliters per second (ml/s). | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/FuelTankStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -22,5 +52,6 @@ uint8 MAV_FUEL_TYPE_LIQUID = 1 # represents generic liquid fuels, such as gasol uint8 MAV_FUEL_TYPE_GAS = 2 # represents a gas fuel, such as hydrogen, methane, or propane. Fuel levels are in kilo-Pascal (kPa), and flow rates are in milliliters per second (ml/s). float32 temperature # fuel temperature in Kelvin, NaN if not measured - ``` + +::: diff --git a/docs/en/msg_docs/GainCompression.md b/docs/en/msg_docs/GainCompression.md new file mode 100644 index 0000000000..c19a34c34b --- /dev/null +++ b/docs/en/msg_docs/GainCompression.md @@ -0,0 +1,32 @@ +--- +pageClass: is-wide-page +--- + +# GainCompression (UORB message) + +**TOPICS:** gain_compression + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------- | +| timestamp | `uint64` | | | Time since system start (microseconds) | +| compression_gains | `float32[3]` | [FRD] | [0 : 1] | Multiplicative gain to modify the output of the controller per axis | +| spectral_damper_hpf | `float32[3]` | [FRD] | | Squared output of spectral damper high-pass filter | +| spectral_damper_out | `float32[3]` | [FRD] | | Spectral damper output squared | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GainCompression.msg) + +::: details Click here to see original file + +```c +uint64 timestamp # Time since system start (microseconds) + +float32[3] compression_gains # [-] [@frame FRD] [@range 0, 1] Multiplicative gain to modify the output of the controller per axis +float32[3] spectral_damper_hpf # [-] [@frame FRD] Squared output of spectral damper high-pass filter +float32[3] spectral_damper_out # [-] [@frame FRD] Spectral damper output squared +``` + +::: diff --git a/docs/en/msg_docs/GeneratorStatus.md b/docs/en/msg_docs/GeneratorStatus.md index 159221547f..41092269e5 100644 --- a/docs/en/msg_docs/GeneratorStatus.md +++ b/docs/en/msg_docs/GeneratorStatus.md @@ -1,8 +1,61 @@ +--- +pageClass: is-wide-page +--- + # GeneratorStatus (UORB message) +**TOPICS:** generator_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeneratorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| status | `uint64` | | | Status flags | +| battery_current | `float32` | A | | Current into/out of battery. Positive for out. Negative for in. NaN: field not provided. | +| load_current | `float32` | A | | Current going to the UAV. If battery current not available this is the DC current from the generator. Positive for out. Negative for in. NaN: field not provided | +| power_generated | `float32` | W | | The power being generated. NaN: field not provided | +| bus_voltage | `float32` | V | | Voltage of the bus seen at the generator, or battery bus if battery bus is controlled by generator and at a different voltage to main bus. | +| bat_current_setpoint | `float32` | A | | The target battery current. Positive for out. Negative for in. NaN: field not provided | +| runtime | `uint32` | s | | Seconds this generator has run since it was rebooted. UINT32_MAX: field not provided. | +| time_until_maintenance | `int32` | s | | Seconds until this generator requires maintenance. A negative value indicates maintenance is past-due. INT32_MAX: field not provided. | +| generator_speed | `uint16` | rpm | | Speed of electrical generator or alternator. UINT16_MAX: field not provided. | +| rectifier_temperature | `int16` | degC | | The temperature of the rectifier or power converter. INT16_MAX: field not provided. | +| generator_temperature | `int16` | degC | | The temperature of the mechanical motor, fuel cell core or generator. INT16_MAX: field not provided. | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| STATUS_FLAG_OFF | `uint64` | 1 | Generator is off. | +| STATUS_FLAG_READY | `uint64` | 2 | Generator is ready to start generating power. | +| STATUS_FLAG_GENERATING | `uint64` | 4 | Generator is generating power. | +| STATUS_FLAG_CHARGING | `uint64` | 8 | Generator is charging the batteries (generating enough power to charge and provide the load). | +| STATUS_FLAG_REDUCED_POWER | `uint64` | 16 | Generator is operating at a reduced maximum power. | +| STATUS_FLAG_MAXPOWER | `uint64` | 32 | Generator is providing the maximum output. | +| STATUS_FLAG_OVERTEMP_WARNING | `uint64` | 64 | Generator is near the maximum operating temperature, cooling is insufficient. | +| STATUS_FLAG_OVERTEMP_FAULT | `uint64` | 128 | Generator hit the maximum operating temperature and shutdown. | +| STATUS_FLAG_ELECTRONICS_OVERTEMP_WARNING | `uint64` | 256 | Power electronics are near the maximum operating temperature, cooling is insufficient. | +| STATUS_FLAG_ELECTRONICS_OVERTEMP_FAULT | `uint64` | 512 | Power electronics hit the maximum operating temperature and shutdown. | +| STATUS_FLAG_ELECTRONICS_FAULT | `uint64` | 1024 | Power electronics experienced a fault and shutdown. | +| STATUS_FLAG_POWERSOURCE_FAULT | `uint64` | 2048 | The power source supplying the generator failed e.g. mechanical generator stopped, tether is no longer providing power, solar cell is in shade, hydrogen reaction no longer happening. | +| STATUS_FLAG_COMMUNICATION_WARNING | `uint64` | 4096 | Generator controller having communication problems. | +| STATUS_FLAG_COOLING_WARNING | `uint64` | 8192 | Power electronic or generator cooling system error. | +| STATUS_FLAG_POWER_RAIL_FAULT | `uint64` | 16384 | Generator controller power rail experienced a fault. | +| STATUS_FLAG_OVERCURRENT_FAULT | `uint64` | 32768 | Generator controller exceeded the overcurrent threshold and shutdown to prevent damage. | +| STATUS_FLAG_BATTERY_OVERCHARGE_CURRENT_FAULT | `uint64` | 65536 | Generator controller detected a high current going into the batteries and shutdown to prevent battery damage. | +| STATUS_FLAG_OVERVOLTAGE_FAULT | `uint64` | 131072 | Generator controller exceeded it's overvoltage threshold and shutdown to prevent it exceeding the voltage rating. | +| STATUS_FLAG_BATTERY_UNDERVOLT_FAULT | `uint64` | 262144 | Batteries are under voltage (generator will not start). | +| STATUS_FLAG_START_INHIBITED | `uint64` | 524288 | Generator start is inhibited by e.g. a safety switch. | +| STATUS_FLAG_MAINTENANCE_REQUIRED | `uint64` | 1048576 | Generator requires maintenance. | +| STATUS_FLAG_WARMING_UP | `uint64` | 2097152 | Generator is not ready to generate yet. | +| STATUS_FLAG_IDLE | `uint64` | 4194304 | Generator is idle. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeneratorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -49,5 +102,6 @@ uint16 generator_speed # [rpm] Speed of electrical generator or alte int16 rectifier_temperature # [degC] The temperature of the rectifier or power converter. INT16_MAX: field not provided. int16 generator_temperature # [degC] The temperature of the mechanical motor, fuel cell core or generator. INT16_MAX: field not provided. - ``` + +::: diff --git a/docs/en/msg_docs/GeofenceResult.md b/docs/en/msg_docs/GeofenceResult.md index f54a2f9942..66fb6f97bd 100644 --- a/docs/en/msg_docs/GeofenceResult.md +++ b/docs/en/msg_docs/GeofenceResult.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # GeofenceResult (UORB message) +**TOPICS:** geofence_result +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeofenceResult.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------- | -------- | ------------ | ---------- | ---------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| geofence_max_dist_triggered | `bool` | | | true the check for max distance from Home is triggered | +| geofence_max_alt_triggered | `bool` | | | true the check for max altitude above Home is triggered | +| geofence_custom_fence_triggered | `bool` | | | true the check for custom inclusion/exclusion geofence(s) is triggered | +| geofence_action | `uint8` | | | action to take when the geofence is breached | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ------------------------------- | ------ | +| GF_ACTION_NONE | `uint8` | 0 | no action on geofence violation | +| GF_ACTION_WARN | `uint8` | 1 | critical mavlink message | +| GF_ACTION_LOITER | `uint8` | 2 | switch to AUTO | LOITER | +| GF_ACTION_RTL | `uint8` | 3 | switch to AUTO | RTL | +| GF_ACTION_TERMINATE | `uint8` | 4 | flight termination | +| GF_ACTION_LAND | `uint8` | 5 | switch to AUTO | LAND | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeofenceResult.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -18,5 +47,6 @@ bool geofence_max_alt_triggered # true the check for max altitude above Home is bool geofence_custom_fence_triggered # true the check for custom inclusion/exclusion geofence(s) is triggered uint8 geofence_action # action to take when the geofence is breached - ``` + +::: diff --git a/docs/en/msg_docs/GeofenceStatus.md b/docs/en/msg_docs/GeofenceStatus.md index 298fd31ba6..6bde8a6566 100644 --- a/docs/en/msg_docs/GeofenceStatus.md +++ b/docs/en/msg_docs/GeofenceStatus.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # GeofenceStatus (UORB message) +**TOPICS:** geofence_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeofenceStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| geofence_id | `uint32` | | | loaded geofence id | +| status | `uint8` | | | Current geofence status | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------- | ------- | ----- | ----------- | +| GF_STATUS_LOADING | `uint8` | 0 | +| GF_STATUS_READY | `uint8` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GeofenceStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +35,6 @@ uint8 status # Current geofence status uint8 GF_STATUS_LOADING = 0 uint8 GF_STATUS_READY = 1 - ``` + +::: diff --git a/docs/en/msg_docs/GimbalControls.md b/docs/en/msg_docs/GimbalControls.md index cde183d443..0f7c46bdc6 100644 --- a/docs/en/msg_docs/GimbalControls.md +++ b/docs/en/msg_docs/GimbalControls.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # GimbalControls (UORB message) +**TOPICS:** gimbal_controls +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalControls.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp the data this control response is based on was sampled | +| control | `float32[3]` | | | Normalized output. 1 means maximum positive position. -1 maximum negative position. 0 means no deflection. NaN maps to disarmed. | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------- | ------- | ----- | ----------- | +| INDEX_ROLL | `uint8` | 0 | +| INDEX_PITCH | `uint8` | 1 | +| INDEX_YAW | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalControls.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,6 +35,7 @@ uint8 INDEX_PITCH = 1 uint8 INDEX_YAW = 2 uint64 timestamp_sample # the timestamp the data this control response is based on was sampled -float32[3] control - +float32[3] control # Normalized output. 1 means maximum positive position. -1 maximum negative position. 0 means no deflection. NaN maps to disarmed. ``` + +::: diff --git a/docs/en/msg_docs/GimbalDeviceAttitudeStatus.md b/docs/en/msg_docs/GimbalDeviceAttitudeStatus.md index cb14c570d5..8d155b1cdd 100644 --- a/docs/en/msg_docs/GimbalDeviceAttitudeStatus.md +++ b/docs/en/msg_docs/GimbalDeviceAttitudeStatus.md @@ -1,8 +1,46 @@ +--- +pageClass: is-wide-page +--- + # GimbalDeviceAttitudeStatus (UORB message) +**TOPICS:** gimbal_deviceattitude_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceAttitudeStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| target_system | `uint8` | | | +| target_component | `uint8` | | | +| device_flags | `uint16` | | | +| q | `float32[4]` | | | +| angular_velocity_x | `float32` | | | +| angular_velocity_y | `float32` | | | +| angular_velocity_z | `float32` | | | +| failure_flags | `uint32` | | | +| delta_yaw | `float32` | | | +| delta_yaw_velocity | `float32` | | | +| gimbal_device_id | `uint8` | | | +| received_from_mavlink | `bool` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| DEVICE_FLAGS_RETRACT | `uint16` | 1 | +| DEVICE_FLAGS_NEUTRAL | `uint16` | 2 | +| DEVICE_FLAGS_ROLL_LOCK | `uint16` | 4 | +| DEVICE_FLAGS_PITCH_LOCK | `uint16` | 8 | +| DEVICE_FLAGS_YAW_LOCK | `uint16` | 16 | +| DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME | `uint16` | 32 | +| DEVICE_FLAGS_YAW_IN_EARTH_FRAME | `uint16` | 64 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceAttitudeStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,6 +54,9 @@ uint16 DEVICE_FLAGS_NEUTRAL = 2 uint16 DEVICE_FLAGS_ROLL_LOCK = 4 uint16 DEVICE_FLAGS_PITCH_LOCK = 8 uint16 DEVICE_FLAGS_YAW_LOCK = 16 +uint16 DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32 +uint16 DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64 + float32[4] q float32 angular_velocity_x @@ -28,5 +69,6 @@ float32 delta_yaw_velocity uint8 gimbal_device_id bool received_from_mavlink - ``` + +::: diff --git a/docs/en/msg_docs/GimbalDeviceInformation.md b/docs/en/msg_docs/GimbalDeviceInformation.md index fd727f4b86..e886ad892a 100644 --- a/docs/en/msg_docs/GimbalDeviceInformation.md +++ b/docs/en/msg_docs/GimbalDeviceInformation.md @@ -1,8 +1,54 @@ +--- +pageClass: is-wide-page +--- + # GimbalDeviceInformation (UORB message) +**TOPICS:** gimbal_deviceinformation +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceInformation.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| vendor_name | `uint8[32]` | | | +| model_name | `uint8[32]` | | | +| custom_name | `uint8[32]` | | | +| firmware_version | `uint32` | | | +| hardware_version | `uint32` | | | +| uid | `uint64` | | | +| cap_flags | `uint16` | | | +| custom_cap_flags | `uint16` | | | +| roll_min | `float32` | rad | | +| roll_max | `float32` | rad | | +| pitch_min | `float32` | rad | | +| pitch_max | `float32` | rad | | +| yaw_min | `float32` | rad | | +| yaw_max | `float32` | rad | | +| gimbal_device_id | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_RETRACT | `uint32` | 1 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_NEUTRAL | `uint32` | 2 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_ROLL_AXIS | `uint32` | 4 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_ROLL_FOLLOW | `uint32` | 8 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_ROLL_LOCK | `uint32` | 16 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_PITCH_AXIS | `uint32` | 32 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_PITCH_FOLLOW | `uint32` | 64 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_PITCH_LOCK | `uint32` | 128 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_YAW_AXIS | `uint32` | 256 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_YAW_FOLLOW | `uint32` | 512 | +| GIMBAL_DEVICE_CAP_FLAGS_HAS_YAW_LOCK | `uint32` | 1024 | +| GIMBAL_DEVICE_CAP_FLAGS_SUPPORTS_INFINITE_YAW | `uint32` | 2048 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceInformation.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -41,5 +87,6 @@ float32 yaw_min # [rad] float32 yaw_max # [rad] uint8 gimbal_device_id - ``` + +::: diff --git a/docs/en/msg_docs/GimbalDeviceSetAttitude.md b/docs/en/msg_docs/GimbalDeviceSetAttitude.md index 9921536084..9b7ee4b8e5 100644 --- a/docs/en/msg_docs/GimbalDeviceSetAttitude.md +++ b/docs/en/msg_docs/GimbalDeviceSetAttitude.md @@ -1,8 +1,39 @@ +--- +pageClass: is-wide-page +--- + # GimbalDeviceSetAttitude (UORB message) +**TOPICS:** gimbal_deviceset_attitude +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceSetAttitude.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| target_system | `uint8` | | | +| target_component | `uint8` | | | +| flags | `uint16` | | | +| q | `float32[4]` | | | +| angular_velocity_x | `float32` | | | +| angular_velocity_y | `float32` | | | +| angular_velocity_z | `float32` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------- | -------- | ----- | ----------- | +| GIMBAL_DEVICE_FLAGS_RETRACT | `uint32` | 1 | +| GIMBAL_DEVICE_FLAGS_NEUTRAL | `uint32` | 2 | +| GIMBAL_DEVICE_FLAGS_ROLL_LOCK | `uint32` | 4 | +| GIMBAL_DEVICE_FLAGS_PITCH_LOCK | `uint32` | 8 | +| GIMBAL_DEVICE_FLAGS_YAW_LOCK | `uint32` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalDeviceSetAttitude.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -22,5 +53,6 @@ float32[4] q float32 angular_velocity_x float32 angular_velocity_y float32 angular_velocity_z - ``` + +::: diff --git a/docs/en/msg_docs/GimbalManagerInformation.md b/docs/en/msg_docs/GimbalManagerInformation.md index ce60d2c5e0..6f0dafc790 100644 --- a/docs/en/msg_docs/GimbalManagerInformation.md +++ b/docs/en/msg_docs/GimbalManagerInformation.md @@ -1,8 +1,49 @@ +--- +pageClass: is-wide-page +--- + # GimbalManagerInformation (UORB message) +**TOPICS:** gimbal_managerinformation +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerInformation.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| cap_flags | `uint32` | | | +| gimbal_device_id | `uint8` | | | +| roll_min | `float32` | rad | | +| roll_max | `float32` | rad | | +| pitch_min | `float32` | rad | | +| pitch_max | `float32` | rad | | +| yaw_min | `float32` | rad | | +| yaw_max | `float32` | rad | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------------------------------------- | -------- | ------ | ----------- | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_RETRACT | `uint32` | 1 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_NEUTRAL | `uint32` | 2 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_AXIS | `uint32` | 4 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_FOLLOW | `uint32` | 8 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_LOCK | `uint32` | 16 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_AXIS | `uint32` | 32 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_FOLLOW | `uint32` | 64 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_LOCK | `uint32` | 128 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_AXIS | `uint32` | 256 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_FOLLOW | `uint32` | 512 | +| GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_LOCK | `uint32` | 1024 | +| GIMBAL_MANAGER_CAP_FLAGS_SUPPORTS_INFINITE_YAW | `uint32` | 2048 | +| GIMBAL_MANAGER_CAP_FLAGS_CAN_POINT_LOCATION_LOCAL | `uint32` | 65536 | +| GIMBAL_MANAGER_CAP_FLAGS_CAN_POINT_LOCATION_GLOBAL | `uint32` | 131072 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerInformation.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -34,5 +75,6 @@ float32 pitch_max # [rad] float32 yaw_min # [rad] float32 yaw_max # [rad] - ``` + +::: diff --git a/docs/en/msg_docs/GimbalManagerSetAttitude.md b/docs/en/msg_docs/GimbalManagerSetAttitude.md index 22c97eb74e..90690c07ee 100644 --- a/docs/en/msg_docs/GimbalManagerSetAttitude.md +++ b/docs/en/msg_docs/GimbalManagerSetAttitude.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # GimbalManagerSetAttitude (UORB message) +**TOPICS:** gimbal_managerset_attitude +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerSetAttitude.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| origin_sysid | `uint8` | | | +| origin_compid | `uint8` | | | +| target_system | `uint8` | | | +| target_component | `uint8` | | | +| flags | `uint32` | | | +| gimbal_device_id | `uint8` | | | +| q | `float32[4]` | | | +| angular_velocity_x | `float32` | | | +| angular_velocity_y | `float32` | | | +| angular_velocity_z | `float32` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| GIMBAL_MANAGER_FLAGS_RETRACT | `uint32` | 1 | +| GIMBAL_MANAGER_FLAGS_NEUTRAL | `uint32` | 2 | +| GIMBAL_MANAGER_FLAGS_ROLL_LOCK | `uint32` | 4 | +| GIMBAL_MANAGER_FLAGS_PITCH_LOCK | `uint32` | 8 | +| GIMBAL_MANAGER_FLAGS_YAW_LOCK | `uint32` | 16 | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerSetAttitude.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -29,5 +64,6 @@ float32 angular_velocity_y float32 angular_velocity_z uint8 ORB_QUEUE_LENGTH = 2 - ``` + +::: diff --git a/docs/en/msg_docs/GimbalManagerSetManualControl.md b/docs/en/msg_docs/GimbalManagerSetManualControl.md index c419917ba6..23efa6c4f4 100644 --- a/docs/en/msg_docs/GimbalManagerSetManualControl.md +++ b/docs/en/msg_docs/GimbalManagerSetManualControl.md @@ -1,8 +1,42 @@ +--- +pageClass: is-wide-page +--- + # GimbalManagerSetManualControl (UORB message) +**TOPICS:** gimbal_managerset_manualcontrol +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerSetManualControl.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| origin_sysid | `uint8` | | | +| origin_compid | `uint8` | | | +| target_system | `uint8` | | | +| target_component | `uint8` | | | +| flags | `uint32` | | | +| gimbal_device_id | `uint8` | | | +| pitch | `float32` | | | unitless -1..1, can be NAN | +| yaw | `float32` | | | unitless -1..1, can be NAN | +| pitch_rate | `float32` | | | unitless -1..1, can be NAN | +| yaw_rate | `float32` | | | unitless -1..1, can be NAN | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| GIMBAL_MANAGER_FLAGS_RETRACT | `uint32` | 1 | +| GIMBAL_MANAGER_FLAGS_NEUTRAL | `uint32` | 2 | +| GIMBAL_MANAGER_FLAGS_ROLL_LOCK | `uint32` | 4 | +| GIMBAL_MANAGER_FLAGS_PITCH_LOCK | `uint32` | 8 | +| GIMBAL_MANAGER_FLAGS_YAW_LOCK | `uint32` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerSetManualControl.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -26,5 +60,6 @@ float32 pitch # unitless -1..1, can be NAN float32 yaw # unitless -1..1, can be NAN float32 pitch_rate # unitless -1..1, can be NAN float32 yaw_rate # unitless -1..1, can be NAN - ``` + +::: diff --git a/docs/en/msg_docs/GimbalManagerStatus.md b/docs/en/msg_docs/GimbalManagerStatus.md index d0f741ad39..4773e15b50 100644 --- a/docs/en/msg_docs/GimbalManagerStatus.md +++ b/docs/en/msg_docs/GimbalManagerStatus.md @@ -1,8 +1,28 @@ +--- +pageClass: is-wide-page +--- + # GimbalManagerStatus (UORB message) +**TOPICS:** gimbal_managerstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------ | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| flags | `uint32` | | | +| gimbal_device_id | `uint8` | | | +| primary_control_sysid | `uint8` | | | +| primary_control_compid | `uint8` | | | +| secondary_control_sysid | `uint8` | | | +| secondary_control_compid | `uint8` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GimbalManagerStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +33,6 @@ uint8 primary_control_sysid uint8 primary_control_compid uint8 secondary_control_sysid uint8 secondary_control_compid - ``` + +::: diff --git a/docs/en/msg_docs/GotoSetpoint.md b/docs/en/msg_docs/GotoSetpoint.md index 746d15eb00..a656ab2dfc 100644 --- a/docs/en/msg_docs/GotoSetpoint.md +++ b/docs/en/msg_docs/GotoSetpoint.md @@ -1,13 +1,39 @@ +--- +pageClass: is-wide-page +--- + # GotoSetpoint (UORB message) -Position and (optional) heading setpoints with corresponding speed constraints -Setpoints are intended as inputs to position and heading smoothers, respectively -Setpoints do not need to be kinematically consistent -Optional heading setpoints may be specified as controlled by the respective flag -Unset optional setpoints are not controlled -Unset optional constraints default to vehicle specifications +Position and (optional) heading setpoints with corresponding speed constraints. Setpoints are intended as inputs to position and heading smoothers, respectively. Setpoints do not need to be kinematically consistent. Optional heading setpoints may be specified as controlled by the respective flag. Unset optional setpoints are not controlled. Unset optional constraints default to vehicle specifications. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/GotoSetpoint.msg) +**TOPICS:** goto_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| position | `float32[3]` | m | | NED local world frame | +| flag_control_heading | `bool` | | | true if heading is to be controlled | +| heading | `float32` | | | (optional) [rad] [-pi,pi] from North | +| flag_set_max_horizontal_speed | `bool` | | | true if setting a non-default horizontal speed limit | +| max_horizontal_speed | `float32` | | | (optional) [m/s] maximum speed (absolute) in the NE-plane | +| flag_set_max_vertical_speed | `bool` | | | true if setting a non-default vertical speed limit | +| max_vertical_speed | `float32` | | | (optional) [m/s] maximum speed (absolute) in the D-axis | +| flag_set_max_heading_rate | `bool` | | | true if setting a non-default heading rate limit | +| max_heading_rate | `float32` | | | (optional) [rad/s] maximum heading rate (absolute) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/GotoSetpoint.msg) + +::: details Click here to see original file ```c # Position and (optional) heading setpoints with corresponding speed constraints @@ -36,5 +62,6 @@ float32 max_vertical_speed # (optional) [m/s] maximum speed (absolute) in the D- bool flag_set_max_heading_rate # true if setting a non-default heading rate limit float32 max_heading_rate # (optional) [rad/s] maximum heading rate (absolute) - ``` + +::: diff --git a/docs/en/msg_docs/GpioConfig.md b/docs/en/msg_docs/GpioConfig.md index 0d21b3ce66..f8b54041c1 100644 --- a/docs/en/msg_docs/GpioConfig.md +++ b/docs/en/msg_docs/GpioConfig.md @@ -1,8 +1,44 @@ +--- +pageClass: is-wide-page +--- + # GpioConfig (UORB message) -GPIO configuration +GPIO configuration. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioConfig.msg) +**TOPICS:** gpio_config + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | Device id | +| mask | `uint32` | | | Pin mask | +| state | `uint32` | | | Initial pin output state | +| config | `uint32` | | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | -------- | ----- | ----------- | +| INPUT | `uint32` | 0 | 0x0000 | +| OUTPUT | `uint32` | 1 | 0x0001 | +| PULLUP | `uint32` | 16 | 0x0010 | +| PULLDOWN | `uint32` | 32 | 0x0020 | +| OPENDRAIN | `uint32` | 256 | 0x0100 | +| INPUT_FLOATING | `uint32` | 0 | 0x0000 | +| INPUT_PULLUP | `uint32` | 16 | 0x0010 | +| INPUT_PULLDOWN | `uint32` | 32 | 0x0020 | +| OUTPUT_PUSHPULL | `uint32` | 0 | 0x0000 | +| OUTPUT_OPENDRAIN | `uint32` | 256 | 0x0100 | +| OUTPUT_OPENDRAIN_PULLUP | `uint32` | 272 | 0x0110 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioConfig.msg) + +::: details Click here to see original file ```c # GPIO configuration @@ -33,5 +69,6 @@ uint32 OUTPUT_OPENDRAIN = 256 # 0x0100 uint32 OUTPUT_OPENDRAIN_PULLUP = 272 # 0x0110 uint32 config - ``` + +::: diff --git a/docs/en/msg_docs/GpioIn.md b/docs/en/msg_docs/GpioIn.md index 039ed02851..f3af80cd4e 100644 --- a/docs/en/msg_docs/GpioIn.md +++ b/docs/en/msg_docs/GpioIn.md @@ -1,15 +1,41 @@ +--- +pageClass: is-wide-page +--- + # GpioIn (UORB message) -GPIO mask and state +GPIO mask and state. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioIn.msg) +**TOPICS:** gpio_in + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | Device id | +| state | `uint32` | | | pin state mask | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------- | ------- | ----- | ----------- | +| MAX_INSTANCES | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioIn.msg) + +::: details Click here to see original file ```c # GPIO mask and state +uint8 MAX_INSTANCES = 8 uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id uint32 state # pin state mask - ``` + +::: diff --git a/docs/en/msg_docs/GpioOut.md b/docs/en/msg_docs/GpioOut.md index fd77f0be3b..fa554844be 100644 --- a/docs/en/msg_docs/GpioOut.md +++ b/docs/en/msg_docs/GpioOut.md @@ -1,8 +1,27 @@ +--- +pageClass: is-wide-page +--- + # GpioOut (UORB message) -GPIO mask and state +GPIO mask and state. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioOut.msg) +**TOPICS:** gpio_out + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | Device id | +| mask | `uint32` | | | pin mask | +| state | `uint32` | | | pin state mask | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioOut.msg) + +::: details Click here to see original file ```c # GPIO mask and state @@ -12,5 +31,6 @@ uint32 device_id # Device id uint32 mask # pin mask uint32 state # pin state mask - ``` + +::: diff --git a/docs/en/msg_docs/GpioRequest.md b/docs/en/msg_docs/GpioRequest.md index 027b84c685..676b46f79e 100644 --- a/docs/en/msg_docs/GpioRequest.md +++ b/docs/en/msg_docs/GpioRequest.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # GpioRequest (UORB message) -Request GPIO mask to be read +Request GPIO mask to be read. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioRequest.msg) +**TOPICS:** gpio_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | Device id | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpioRequest.msg) + +::: details Click here to see original file ```c # Request GPIO mask to be read uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id - ``` + +::: diff --git a/docs/en/msg_docs/GpsDump.md b/docs/en/msg_docs/GpsDump.md index 1f96901671..888a0a825f 100644 --- a/docs/en/msg_docs/GpsDump.md +++ b/docs/en/msg_docs/GpsDump.md @@ -1,19 +1,52 @@ +--- +pageClass: is-wide-page +--- + # GpsDump (UORB message) This message is used to dump the raw gps communication to the log. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpsDump.msg) +**TOPICS:** gps_dump + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ----------- | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| instance | `uint8` | | | Instance of GNSS receiver | +| device_id | `uint32` | | | +| len | `uint8` | | | length of data, MSB bit set = message to the gps device, | +| data | `uint8[79]` | | | data to write to the log | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------- | ------- | ----- | ----------- | +| INSTANCE_MAIN | `uint8` | 0 | +| INSTANCE_SECONDARY | `uint8` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpsDump.msg) + +::: details Click here to see original file ```c # This message is used to dump the raw gps communication to the log. uint64 timestamp # time since system start (microseconds) +uint8 INSTANCE_MAIN = 0 +uint8 INSTANCE_SECONDARY = 1 + uint8 instance # Instance of GNSS receiver +uint32 device_id uint8 len # length of data, MSB bit set = message to the gps device, # clear = message from the device uint8[79] data # data to write to the log -uint8 ORB_QUEUE_LENGTH = 8 - +uint8 ORB_QUEUE_LENGTH = 16 ``` + +::: diff --git a/docs/en/msg_docs/GpsInjectData.md b/docs/en/msg_docs/GpsInjectData.md index 0eefd1da40..62d3d356d0 100644 --- a/docs/en/msg_docs/GpsInjectData.md +++ b/docs/en/msg_docs/GpsInjectData.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # GpsInjectData (UORB message) +**TOPICS:** gps_injectdata +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpsInjectData.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| len | `uint16` | | | length of data | +| flags | `uint8` | | | LSB: 1=fragmented | +| data | `uint8[300]` | | | data to write to GPS device (RTCM message) | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 8 | +| MAX_INSTANCES | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GpsInjectData.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,5 +41,6 @@ uint8[300] data # data to write to GPS device (RTCM message) uint8 ORB_QUEUE_LENGTH = 8 uint8 MAX_INSTANCES = 2 - ``` + +::: diff --git a/docs/en/msg_docs/Gripper.md b/docs/en/msg_docs/Gripper.md index eb888e2017..8fcda0cacc 100644 --- a/docs/en/msg_docs/Gripper.md +++ b/docs/en/msg_docs/Gripper.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # Gripper (UORB message) -# Used to command an actuation in the gripper, which is mapped to a specific output in the control allocation module +# Used to command an actuation in the gripper, which is mapped to a specific output in the control allocation module. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Gripper.msg) +**TOPICS:** gripper + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | ------------------------------- | +| timestamp | `uint64` | | | +| command | `int8` | | | Commanded state for the gripper | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | ------ | ----- | ----------- | +| COMMAND_GRAB | `int8` | 0 | +| COMMAND_RELEASE | `int8` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Gripper.msg) + +::: details Click here to see original file ```c ## Used to command an actuation in the gripper, which is mapped to a specific output in the control allocation module @@ -12,5 +36,6 @@ uint64 timestamp int8 command # Commanded state for the gripper int8 COMMAND_GRAB = 0 int8 COMMAND_RELEASE = 1 - ``` + +::: diff --git a/docs/en/msg_docs/HealthReport.md b/docs/en/msg_docs/HealthReport.md index 447d9da621..608fbecfc1 100644 --- a/docs/en/msg_docs/HealthReport.md +++ b/docs/en/msg_docs/HealthReport.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # HealthReport (UORB message) +**TOPICS:** health_report +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HealthReport.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| can_arm_mode_flags | `uint64` | | | bitfield for each flight mode (NAVIGATION*STATE*\*) if arming is possible | +| can_run_mode_flags | `uint64` | | | bitfield for each flight mode if it can run | +| health_is_present_flags | `uint64` | | | flags for each health_component_t | +| health_warning_flags | `uint64` | | | +| health_error_flags | `uint64` | | | +| arming_check_warning_flags | `uint64` | | | +| arming_check_error_flags | `uint64` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HealthReport.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -17,5 +38,6 @@ uint64 health_error_flags uint64 arming_check_warning_flags uint64 arming_check_error_flags - ``` + +::: diff --git a/docs/en/msg_docs/HeaterStatus.md b/docs/en/msg_docs/HeaterStatus.md index 3917f02428..431b621226 100644 --- a/docs/en/msg_docs/HeaterStatus.md +++ b/docs/en/msg_docs/HeaterStatus.md @@ -1,8 +1,40 @@ +--- +pageClass: is-wide-page +--- + # HeaterStatus (UORB message) +**TOPICS:** heater_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HeaterStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | +| heater_on | `bool` | | | +| temperature_target_met | `bool` | | | +| temperature_sensor | `float32` | | | +| temperature_target | `float32` | | | +| controller_period_usec | `uint32` | | | +| controller_time_on_usec | `uint32` | | | +| proportional_value | `float32` | | | +| integrator_value | `float32` | | | +| feed_forward_value | `float32` | | | +| mode | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------- | ------- | ----- | ----------- | +| MODE_GPIO | `uint8` | 1 | +| MODE_PX4IO | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HeaterStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -25,5 +57,6 @@ float32 feed_forward_value uint8 MODE_GPIO = 1 uint8 MODE_PX4IO = 2 uint8 mode - ``` + +::: diff --git a/docs/en/msg_docs/HomePosition.md b/docs/en/msg_docs/HomePosition.md index b48528de7e..ed5b43dc3c 100644 --- a/docs/en/msg_docs/HomePosition.md +++ b/docs/en/msg_docs/HomePosition.md @@ -1,8 +1,44 @@ +--- +pageClass: is-wide-page +--- + # HomePosition (UORB message) GPS home position in WGS84 coordinates. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/HomePosition.msg) +**TOPICS:** home_position + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | -------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| lat | `float64` | | | Latitude in degrees | +| lon | `float64` | | | Longitude in degrees | +| alt | `float32` | | | Altitude in meters (AMSL) | +| x | `float32` | | | X coordinate in meters | +| y | `float32` | | | Y coordinate in meters | +| z | `float32` | | | Z coordinate in meters | +| roll | `float32` | | | Pitch angle in radians | +| pitch | `float32` | | | Roll angle in radians | +| yaw | `float32` | | | Yaw angle in radians | +| valid_alt | `bool` | | | true when the altitude has been set | +| valid_hpos | `bool` | | | true when the latitude and longitude have been set | +| valid_lpos | `bool` | | | true when the local position (xyz) has been set | +| manual_home | `bool` | | | true when home position was set manually | +| update_count | `uint32` | | | update counter of the home position | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/HomePosition.msg) + +::: details Click here to see original file ```c # GPS home position in WGS84 coordinates. @@ -30,5 +66,6 @@ bool valid_lpos # true when the local position (xyz) has been set bool manual_home # true when home position was set manually uint32 update_count # update counter of the home position - ``` + +::: diff --git a/docs/en/msg_docs/HomePositionV0.md b/docs/en/msg_docs/HomePositionV0.md index 270d752337..c95ba3d44a 100644 --- a/docs/en/msg_docs/HomePositionV0.md +++ b/docs/en/msg_docs/HomePositionV0.md @@ -1,8 +1,42 @@ +--- +pageClass: is-wide-page +--- + # HomePositionV0 (UORB message) GPS home position in WGS84 coordinates. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/HomePositionV0.msg) +**TOPICS:** home_positionv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | -------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| lat | `float64` | | | Latitude in degrees | +| lon | `float64` | | | Longitude in degrees | +| alt | `float32` | | | Altitude in meters (AMSL) | +| x | `float32` | | | X coordinate in meters | +| y | `float32` | | | Y coordinate in meters | +| z | `float32` | | | Z coordinate in meters | +| yaw | `float32` | | | Yaw angle in radians | +| valid_alt | `bool` | | | true when the altitude has been set | +| valid_hpos | `bool` | | | true when the latitude and longitude have been set | +| valid_lpos | `bool` | | | true when the local position (xyz) has been set | +| manual_home | `bool` | | | true when home position was set manually | +| update_count | `uint32` | | | update counter of the home position | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/HomePositionV0.msg) + +::: details Click here to see original file ```c # GPS home position in WGS84 coordinates. @@ -28,5 +62,6 @@ bool valid_lpos # true when the local position (xyz) has been set bool manual_home # true when home position was set manually uint32 update_count # update counter of the home position - ``` + +::: diff --git a/docs/en/msg_docs/HoverThrustEstimate.md b/docs/en/msg_docs/HoverThrustEstimate.md index 8c0aa1eb83..c892718d22 100644 --- a/docs/en/msg_docs/HoverThrustEstimate.md +++ b/docs/en/msg_docs/HoverThrustEstimate.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # HoverThrustEstimate (UORB message) +**TOPICS:** hover_thrustestimate +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HoverThrustEstimate.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | ----------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | time of corresponding sensor data last used for this estimate | +| hover_thrust | `float32` | | | estimated hover thrust [0.1, 0.9] | +| hover_thrust_var | `float32` | | | estimated hover thrust variance | +| accel_innov | `float32` | | | innovation of the last acceleration fusion | +| accel_innov_var | `float32` | | | innovation variance of the last acceleration fusion | +| accel_innov_test_ratio | `float32` | | | normalized innovation squared test ratio | +| accel_noise_var | `float32` | | | vertical acceleration noise variance estimated form innovation residual | +| valid | `bool` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/HoverThrustEstimate.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -18,5 +40,6 @@ float32 accel_innov_test_ratio # normalized innovation squared test ratio float32 accel_noise_var # vertical acceleration noise variance estimated form innovation residual bool valid - ``` + +::: diff --git a/docs/en/msg_docs/InputRc.md b/docs/en/msg_docs/InputRc.md index 3f8bdb3da3..9ad672ebc8 100644 --- a/docs/en/msg_docs/InputRc.md +++ b/docs/en/msg_docs/InputRc.md @@ -1,8 +1,59 @@ +--- +pageClass: is-wide-page +--- + # InputRc (UORB message) +**TOPICS:** input_rc +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InputRc.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_last_signal | `uint64` | | | last valid reception time | +| channel_count | `uint8` | | | number of channels actually being seen | +| rssi | `int32` | | | receive signal strength indicator (RSSI): < 0: Undefined, 0: no signal, 100: full reception | +| rc_failsafe | `bool` | | | explicit failsafe flag: true on TX failure or TX out of range , false otherwise. Only the true state is reliable, as there are some (PPM) receivers on the market going into failsafe without telling us explicitly. | +| rc_lost | `bool` | | | RC receiver connection status: True,if no frame has arrived in the expected time, false otherwise. True usually means that the receiver has been disconnected, but can also indicate a radio link loss on "stupid" systems. Will remain false, if a RX with failsafe option continues to transmit frames after a link loss. | +| rc_lost_frame_count | `uint16` | | | Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. | +| rc_total_frame_count | `uint16` | | | Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. | +| rc_ppm_frame_length | `uint16` | | | Length of a single PPM frame. Zero for non-PPM systems | +| rc_frame_rate | `uint16` | | | RC frame rate in msg/second. 0 = invalid | +| input_source | `uint8` | | | Input source | +| values | `uint16[18]` | | | measured pulse widths for each of the supported channels | +| link_quality | `int8` | | | link quality. Percentage 0-100%. -1 = invalid | +| rssi_dbm | `float32` | | | Actual rssi in units of dBm. NaN = invalid | +| link_snr | `int8` | | | link signal to noise ratio in units of dB. -1 = invalid | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | ------- | ----- | -------------------------------------------------------------------------------- | +| RC_INPUT_SOURCE_UNKNOWN | `uint8` | 0 | +| RC_INPUT_SOURCE_PX4FMU_PPM | `uint8` | 1 | +| RC_INPUT_SOURCE_PX4IO_PPM | `uint8` | 2 | +| RC_INPUT_SOURCE_PX4IO_SPEKTRUM | `uint8` | 3 | +| RC_INPUT_SOURCE_PX4IO_SBUS | `uint8` | 4 | +| RC_INPUT_SOURCE_PX4IO_ST24 | `uint8` | 5 | +| RC_INPUT_SOURCE_MAVLINK | `uint8` | 6 | +| RC_INPUT_SOURCE_QURT | `uint8` | 7 | +| RC_INPUT_SOURCE_PX4FMU_SPEKTRUM | `uint8` | 8 | +| RC_INPUT_SOURCE_PX4FMU_SBUS | `uint8` | 9 | +| RC_INPUT_SOURCE_PX4FMU_ST24 | `uint8` | 10 | +| RC_INPUT_SOURCE_PX4FMU_SUMD | `uint8` | 11 | +| RC_INPUT_SOURCE_PX4FMU_DSM | `uint8` | 12 | +| RC_INPUT_SOURCE_PX4IO_SUMD | `uint8` | 13 | +| RC_INPUT_SOURCE_PX4FMU_CRSF | `uint8` | 14 | +| RC_INPUT_SOURCE_PX4FMU_GHST | `uint8` | 15 | +| RC_INPUT_MAX_CHANNELS | `uint8` | 18 | Maximum number of R/C input channels in the system. S.Bus has up to 18 channels. | +| RSSI_MAX | `int8` | 100 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InputRc.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -39,11 +90,14 @@ bool rc_lost # RC receiver connection status: True,if no frame has arrived in uint16 rc_lost_frame_count # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_total_frame_count # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_ppm_frame_length # Length of a single PPM frame. Zero for non-PPM systems +uint16 rc_frame_rate # RC frame rate in msg/second. 0 = invalid uint8 input_source # Input source uint16[18] values # measured pulse widths for each of the supported channels int8 link_quality # link quality. Percentage 0-100%. -1 = invalid float32 rssi_dbm # Actual rssi in units of dBm. NaN = invalid - +int8 link_snr # link signal to noise ratio in units of dB. -1 = invalid ``` + +::: diff --git a/docs/en/msg_docs/InternalCombustionEngineControl.md b/docs/en/msg_docs/InternalCombustionEngineControl.md index aacacd8973..02af18d879 100644 --- a/docs/en/msg_docs/InternalCombustionEngineControl.md +++ b/docs/en/msg_docs/InternalCombustionEngineControl.md @@ -1,6 +1,27 @@ +--- +pageClass: is-wide-page +--- + # InternalCombustionEngineControl (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InternalCombustionEngineControl.msg) +**TOPICS:** internal_combustionengine_control + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| ignition_on | `bool` | | | activate/deactivate ignition (spark plug) | +| throttle_control | `float32` | | | setpoint for throttle actuator, with slew rate if enabled, idles with 0 [norm] [@range 0,1] [@uncontrolled NAN to stop motor] | +| choke_control | `float32` | | | setpoint for choke actuator, 1: fully closed [norm] [@range 0,1] | +| starter_engine_control | `float32` | | | setpoint for (electric) starter motor [norm] [@range 0,1] | +| user_request | `uint8` | | | user intent for the ICE being on/off | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InternalCombustionEngineControl.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,5 +32,6 @@ float32 choke_control # setpoint for choke actuator, 1: fully closed [norm] [@ float32 starter_engine_control # setpoint for (electric) starter motor [norm] [@range 0,1] uint8 user_request # user intent for the ICE being on/off - ``` + +::: diff --git a/docs/en/msg_docs/InternalCombustionEngineStatus.md b/docs/en/msg_docs/InternalCombustionEngineStatus.md index 32642ea23e..33f25cfb7a 100644 --- a/docs/en/msg_docs/InternalCombustionEngineStatus.md +++ b/docs/en/msg_docs/InternalCombustionEngineStatus.md @@ -1,8 +1,77 @@ +--- +pageClass: is-wide-page +--- + # InternalCombustionEngineStatus (UORB message) +**TOPICS:** internal_combustionengine_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InternalCombustionEngineStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| state | `uint8` | | | +| flags | `uint32` | | | +| engine_load_percent | `uint8` | | | Engine load estimate, percent, [0, 127] | +| engine_speed_rpm | `uint32` | | | Engine speed, revolutions per minute | +| spark_dwell_time_ms | `float32` | | | Spark dwell time, millisecond | +| atmospheric_pressure_kpa | `float32` | | | Atmospheric (barometric) pressure, kilopascal | +| intake_manifold_pressure_kpa | `float32` | | | Engine intake manifold pressure, kilopascal | +| intake_manifold_temperature | `float32` | | | Engine intake manifold temperature, kelvin | +| coolant_temperature | `float32` | | | Engine coolant temperature, kelvin | +| oil_pressure | `float32` | | | Oil pressure, kilopascal | +| oil_temperature | `float32` | | | Oil temperature, kelvin | +| fuel_pressure | `float32` | | | Fuel pressure, kilopascal | +| fuel_consumption_rate_cm3pm | `float32` | | | Instant fuel consumption estimate, (centimeter^3)/minute | +| estimated_consumed_fuel_volume_cm3 | `float32` | | | Estimate of the consumed fuel since the start of the engine, centimeter^3 | +| throttle_position_percent | `uint8` | | | Throttle position, percent | +| ecu_index | `uint8` | | | The index of the publishing ECU | +| spark_plug_usage | `uint8` | | | Spark plug activity report. | +| ignition_timing_deg | `float32` | | | Cylinder ignition timing, angular degrees of the crankshaft | +| injection_time_ms | `float32` | | | Fuel injection time, millisecond | +| cylinder_head_temperature | `float32` | | | Cylinder head temperature (CHT), kelvin | +| exhaust_gas_temperature | `float32` | | | Exhaust gas temperature (EGT), kelvin | +| lambda_coefficient | `float32` | | | Estimated lambda coefficient, dimensionless ratio | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------------- | -------- | ------ | ------------------------------------------------------ | +| STATE_STOPPED | `uint8` | 0 | The engine is not running. This is the default state. | +| STATE_STARTING | `uint8` | 1 | The engine is starting. This is a transient state. | +| STATE_RUNNING | `uint8` | 2 | The engine is running normally. | +| STATE_FAULT | `uint8` | 3 | The engine can no longer function. | +| FLAG_GENERAL_ERROR | `uint32` | 1 | General error. | +| FLAG_CRANKSHAFT_SENSOR_ERROR_SUPPORTED | `uint32` | 2 | Error of the crankshaft sensor. This flag is optional. | +| FLAG_CRANKSHAFT_SENSOR_ERROR | `uint32` | 4 | +| FLAG_TEMPERATURE_SUPPORTED | `uint32` | 8 | Temperature levels. These flags are optional | +| FLAG_TEMPERATURE_BELOW_NOMINAL | `uint32` | 16 | Under-temperature warning | +| FLAG_TEMPERATURE_ABOVE_NOMINAL | `uint32` | 32 | Over-temperature warning | +| FLAG_TEMPERATURE_OVERHEATING | `uint32` | 64 | Critical overheating | +| FLAG_TEMPERATURE_EGT_ABOVE_NOMINAL | `uint32` | 128 | Exhaust gas over-temperature warning | +| FLAG_FUEL_PRESSURE_SUPPORTED | `uint32` | 256 | Fuel pressure. These flags are optional | +| FLAG_FUEL_PRESSURE_BELOW_NOMINAL | `uint32` | 512 | Under-pressure warning | +| FLAG_FUEL_PRESSURE_ABOVE_NOMINAL | `uint32` | 1024 | Over-pressure warning | +| FLAG_DETONATION_SUPPORTED | `uint32` | 2048 | Detonation warning. This flag is optional. | +| FLAG_DETONATION_OBSERVED | `uint32` | 4096 | Detonation condition observed warning | +| FLAG_MISFIRE_SUPPORTED | `uint32` | 8192 | Misfire warning. This flag is optional. | +| FLAG_MISFIRE_OBSERVED | `uint32` | 16384 | Misfire condition observed warning | +| FLAG_OIL_PRESSURE_SUPPORTED | `uint32` | 32768 | Oil pressure. These flags are optional | +| FLAG_OIL_PRESSURE_BELOW_NOMINAL | `uint32` | 65536 | Under-pressure warning | +| FLAG_OIL_PRESSURE_ABOVE_NOMINAL | `uint32` | 131072 | Over-pressure warning | +| FLAG_DEBRIS_SUPPORTED | `uint32` | 262144 | Debris warning. This flag is optional | +| FLAG_DEBRIS_DETECTED | `uint32` | 524288 | Detection of debris warning | +| SPARK_PLUG_SINGLE | `uint8` | 0 | +| SPARK_PLUG_FIRST_ACTIVE | `uint8` | 1 | +| SPARK_PLUG_SECOND_ACTIVE | `uint8` | 2 | +| SPARK_PLUG_BOTH_ACTIVE | `uint8` | 3 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/InternalCombustionEngineStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -69,5 +138,6 @@ float32 injection_time_ms # Fuel injection time, millisecond float32 cylinder_head_temperature # Cylinder head temperature (CHT), kelvin float32 exhaust_gas_temperature # Exhaust gas temperature (EGT), kelvin float32 lambda_coefficient # Estimated lambda coefficient, dimensionless ratio - ``` + +::: diff --git a/docs/en/msg_docs/IridiumsbdStatus.md b/docs/en/msg_docs/IridiumsbdStatus.md index f2b76adc24..02263b6922 100644 --- a/docs/en/msg_docs/IridiumsbdStatus.md +++ b/docs/en/msg_docs/IridiumsbdStatus.md @@ -1,8 +1,36 @@ +--- +pageClass: is-wide-page +--- + # IridiumsbdStatus (UORB message) +**TOPICS:** iridiumsbd_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/IridiumsbdStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| last_at_ok_timestamp | `uint64` | | | timestamp of the last "OK" received after the "AT" command | +| tx_buf_write_index | `uint16` | | | current size of the tx buffer | +| rx_buf_read_index | `uint16` | | | the rx buffer is parsed up to that index | +| rx_buf_end_index | `uint16` | | | current size of the rx buffer | +| failed_sbd_sessions | `uint16` | | | number of failed sbd sessions | +| successful_sbd_sessions | `uint16` | | | number of successful sbd sessions | +| num_tx_buf_reset | `uint16` | | | number of times the tx buffer was reset | +| signal_quality | `uint8` | | | current signal quality, 0 is no signal, 5 the best | +| state | `uint8` | | | current state of the driver, see the satcom_state of IridiumSBD.h for the definition | +| ring_pending | `bool` | | | indicates if a ring call is pending | +| tx_buf_write_pending | `bool` | | | indicates if a tx buffer write is pending | +| tx_session_pending | `bool` | | | indicates if a tx session is pending | +| rx_read_pending | `bool` | | | indicates if a rx read is pending | +| rx_session_pending | `bool` | | | indicates if a rx session is pending | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/IridiumsbdStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -20,5 +48,6 @@ bool tx_buf_write_pending # indicates if a tx buffer write is pending bool tx_session_pending # indicates if a tx session is pending bool rx_read_pending # indicates if a rx read is pending bool rx_session_pending # indicates if a rx session is pending - ``` + +::: diff --git a/docs/en/msg_docs/IrlockReport.md b/docs/en/msg_docs/IrlockReport.md index d850a0bb1e..fbe26d9649 100644 --- a/docs/en/msg_docs/IrlockReport.md +++ b/docs/en/msg_docs/IrlockReport.md @@ -1,8 +1,29 @@ +--- +pageClass: is-wide-page +--- + # IrlockReport (UORB message) -IRLOCK_REPORT message data +IRLOCK_REPORT message data. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/IrlockReport.msg) +**TOPICS:** irlock_report + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| signature | `uint16` | | | +| pos_x | `float32` | | | tan(theta), where theta is the angle between the target and the camera center of projection in camera x-axis | +| pos_y | `float32` | | | tan(theta), where theta is the angle between the target and the camera center of projection in camera y-axis | +| size_x | `float32` | | | /** size of target along camera x-axis in units of tan(theta) **/ | +| size_y | `float32` | | | /** size of target along camera y-axis in units of tan(theta) **/ | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/IrlockReport.msg) + +::: details Click here to see original file ```c # IRLOCK_REPORT message data @@ -16,5 +37,6 @@ float32 pos_x # tan(theta), where theta is the angle between the target and the float32 pos_y # tan(theta), where theta is the angle between the target and the camera center of projection in camera y-axis float32 size_x #/** size of target along camera x-axis in units of tan(theta) **/ float32 size_y #/** size of target along camera y-axis in units of tan(theta) **/ - ``` + +::: diff --git a/docs/en/msg_docs/LandingGear.md b/docs/en/msg_docs/LandingGear.md index 89b79a8b2c..0abcc5b2b2 100644 --- a/docs/en/msg_docs/LandingGear.md +++ b/docs/en/msg_docs/LandingGear.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # LandingGear (UORB message) +**TOPICS:** landing_gear +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingGear.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| landing_gear | `int8` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------- | ------ | ----- | ---------------------- | +| GEAR_UP | `int8` | 1 | landing gear up | +| GEAR_DOWN | `int8` | -1 | landing gear down | +| GEAR_KEEP | `int8` | 0 | keep the current state | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingGear.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +35,6 @@ int8 GEAR_DOWN = -1 # landing gear down int8 GEAR_KEEP = 0 # keep the current state int8 landing_gear - ``` + +::: diff --git a/docs/en/msg_docs/LandingGearWheel.md b/docs/en/msg_docs/LandingGearWheel.md index 1c04a448bd..d220ba4101 100644 --- a/docs/en/msg_docs/LandingGearWheel.md +++ b/docs/en/msg_docs/LandingGearWheel.md @@ -1,12 +1,28 @@ +--- +pageClass: is-wide-page +--- + # LandingGearWheel (UORB message) +**TOPICS:** landing_gearwheel +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingGearWheel.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | --------- | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| normalized_wheel_setpoint | `float32` | | | negative is turning left, positive turning right [-1, 1] | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingGearWheel.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) float32 normalized_wheel_setpoint # negative is turning left, positive turning right [-1, 1] - ``` + +::: diff --git a/docs/en/msg_docs/LandingTargetInnovations.md b/docs/en/msg_docs/LandingTargetInnovations.md index 29bc06bbc2..0bf0dc7bc4 100644 --- a/docs/en/msg_docs/LandingTargetInnovations.md +++ b/docs/en/msg_docs/LandingTargetInnovations.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # LandingTargetInnovations (UORB message) +**TOPICS:** landing_targetinnovations +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingTargetInnovations.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| innov_x | `float32` | | | +| innov_y | `float32` | | | +| innov_cov_x | `float32` | | | +| innov_cov_y | `float32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingTargetInnovations.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +31,6 @@ float32 innov_y # Innovation covariance of landing target position estimator float32 innov_cov_x float32 innov_cov_y - ``` + +::: diff --git a/docs/en/msg_docs/LandingTargetPose.md b/docs/en/msg_docs/LandingTargetPose.md index b4a76aeda7..e06e7157a3 100644 --- a/docs/en/msg_docs/LandingTargetPose.md +++ b/docs/en/msg_docs/LandingTargetPose.md @@ -1,8 +1,40 @@ +--- +pageClass: is-wide-page +--- + # LandingTargetPose (UORB message) -Relative position of precision land target in navigation (body fixed, north aligned, NED) and inertial (world fixed, north aligned, NED) frames +Relative position of precision land target in navigation (body fixed, north aligned, NED) and inertial (world fixed, north aligned, NED) frames. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingTargetPose.msg) +**TOPICS:** landing_targetpose + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | --------- | ------------ | ---------- | ----------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| is_static | `bool` | | | Flag indicating whether the landing target is static or moving with respect to the ground | +| rel_pos_valid | `bool` | | | Flag showing whether relative position is valid | +| rel_vel_valid | `bool` | | | Flag showing whether relative velocity is valid | +| x_rel | `float32` | | | X/north position of target, relative to vehicle (navigation frame) [meters] | +| y_rel | `float32` | | | Y/east position of target, relative to vehicle (navigation frame) [meters] | +| z_rel | `float32` | | | Z/down position of target, relative to vehicle (navigation frame) [meters] | +| vx_rel | `float32` | | | X/north velocity of target, relative to vehicle (navigation frame) [meters/second] | +| vy_rel | `float32` | | | Y/east velocity of target, relative to vehicle (navigation frame) [meters/second] | +| cov_x_rel | `float32` | | | X/north position variance [meters^2] | +| cov_y_rel | `float32` | | | Y/east position variance [meters^2] | +| cov_vx_rel | `float32` | | | X/north velocity variance [(meters/second)^2] | +| cov_vy_rel | `float32` | | | Y/east velocity variance [(meters/second)^2] | +| abs_pos_valid | `bool` | | | Flag showing whether absolute position is valid | +| x_abs | `float32` | | | X/north position of target, relative to origin (navigation frame) [meters] | +| y_abs | `float32` | | | Y/east position of target, relative to origin (navigation frame) [meters] | +| z_abs | `float32` | | | Z/down position of target, relative to origin (navigation frame) [meters] | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LandingTargetPose.msg) + +::: details Click here to see original file ```c # Relative position of precision land target in navigation (body fixed, north aligned, NED) and inertial (world fixed, north aligned, NED) frames @@ -31,5 +63,6 @@ bool abs_pos_valid # Flag showing whether absolute position is valid float32 x_abs # X/north position of target, relative to origin (navigation frame) [meters] float32 y_abs # Y/east position of target, relative to origin (navigation frame) [meters] float32 z_abs # Z/down position of target, relative to origin (navigation frame) [meters] - ``` + +::: diff --git a/docs/en/msg_docs/LateralControlConfiguration.md b/docs/en/msg_docs/LateralControlConfiguration.md index b0a03a6378..36f7724a09 100644 --- a/docs/en/msg_docs/LateralControlConfiguration.md +++ b/docs/en/msg_docs/LateralControlConfiguration.md @@ -1,9 +1,31 @@ +--- +pageClass: is-wide-page +--- + # LateralControlConfiguration (UORB message) -Fixed Wing Lateral Control Configuration message -Used by the fw_lateral_longitudinal_control module to constrain FixedWingLateralSetpoint messages. +Fixed Wing Lateral Control Configuration message. Used by the fw_lateral_longitudinal_control module to constrain FixedWingLateralSetpoint messages. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/LateralControlConfiguration.msg) +**TOPICS:** lateral_controlconfiguration + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | --------- | ------------ | ---------- | ---------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| lateral_accel_max | `float32` | m/s^2 | | currently maps to a maximum roll angle, accel_max = tan(roll_max) \* GRAVITY | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/LateralControlConfiguration.msg) + +::: details Click here to see original file ```c # Fixed Wing Lateral Control Configuration message @@ -14,5 +36,6 @@ uint32 MESSAGE_VERSION = 0 uint64 timestamp # time since system start (microseconds) float32 lateral_accel_max # [m/s^2] currently maps to a maximum roll angle, accel_max = tan(roll_max) * GRAVITY - ``` + +::: diff --git a/docs/en/msg_docs/LaunchDetectionStatus.md b/docs/en/msg_docs/LaunchDetectionStatus.md index a85c63e4e8..4f18e03700 100644 --- a/docs/en/msg_docs/LaunchDetectionStatus.md +++ b/docs/en/msg_docs/LaunchDetectionStatus.md @@ -1,8 +1,34 @@ +--- +pageClass: is-wide-page +--- + # LaunchDetectionStatus (UORB message) -Status of the launch detection state machine (fixed-wing only) +Status of the launch detection state machine (fixed-wing only). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LaunchDetectionStatus.msg) +**TOPICS:** launch_detectionstatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| launch_detection_state | `uint8` | | | +| selected_control_surface_disarmed | `bool` | | | flag indicating whether selected actuators should kept disarmed (have to be configured in control allocation) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------- | +| STATE_WAITING_FOR_LAUNCH | `uint8` | 0 | waiting for launch | +| STATE_LAUNCH_DETECTED_DISABLED_MOTOR | `uint8` | 1 | launch detected, but keep motor(s) disabled (e.g. because it can't spin freely while on catapult) | +| STATE_FLYING | `uint8` | 2 | launch detected, use normal takeoff/flying configuration | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LaunchDetectionStatus.msg) + +::: details Click here to see original file ```c # Status of the launch detection state machine (fixed-wing only) @@ -15,4 +41,7 @@ uint8 STATE_FLYING = 2 # launch detected, use normal takeoff/flying configur uint8 launch_detection_state +bool selected_control_surface_disarmed # [-] flag indicating whether selected actuators should kept disarmed (have to be configured in control allocation) ``` + +::: diff --git a/docs/en/msg_docs/LedControl.md b/docs/en/msg_docs/LedControl.md index 69590eb8a5..0b066b2b90 100644 --- a/docs/en/msg_docs/LedControl.md +++ b/docs/en/msg_docs/LedControl.md @@ -1,9 +1,53 @@ +--- +pageClass: is-wide-page +--- + # LedControl (UORB message) -LED control: control a single or multiple LED's. -These are the externally visible LED's, not the board LED's +LED control: control a single or multiple LED's. These are the externally visible LED's, not the board LED's. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LedControl.msg) +**TOPICS:** led_control + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| led_mask | `uint8` | | | bitmask which LED(s) to control, set to 0xff for all | +| color | `uint8` | | | see COLOR\_\* | +| mode | `uint8` | | | see MODE\_\* | +| num_blinks | `uint8` | | | how many times to blink (number of on-off cycles if mode is one of MODE*BLINK*\*) . Set to 0 for infinite | +| priority | `uint8` | | | priority: higher priority events will override current lower priority events (see MAX_PRIORITY) | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------- | ------- | ----- | --------------------------------------------------------------------------------------- | +| COLOR_OFF | `uint8` | 0 | this is only used in the drivers | +| COLOR_RED | `uint8` | 1 | +| COLOR_GREEN | `uint8` | 2 | +| COLOR_BLUE | `uint8` | 3 | +| COLOR_YELLOW | `uint8` | 4 | +| COLOR_PURPLE | `uint8` | 5 | +| COLOR_AMBER | `uint8` | 6 | +| COLOR_CYAN | `uint8` | 7 | +| COLOR_WHITE | `uint8` | 8 | +| MODE_OFF | `uint8` | 0 | turn LED off | +| MODE_ON | `uint8` | 1 | turn LED on | +| MODE_DISABLED | `uint8` | 2 | disable this priority (switch to lower priority setting) | +| MODE_BLINK_SLOW | `uint8` | 3 | +| MODE_BLINK_NORMAL | `uint8` | 4 | +| MODE_BLINK_FAST | `uint8` | 5 | +| MODE_BREATHE | `uint8` | 6 | continuously increase & decrease brightness (solid color if driver does not support it) | +| MODE_FLASH | `uint8` | 7 | two fast blinks (on/off) with timing as in MODE_BLINK_FAST and then off for a while | +| MAX_PRIORITY | `uint8` | 2 | maximum priority (minimum is 0) | +| ORB_QUEUE_LENGTH | `uint8` | 8 | needs to match BOARD_MAX_LEDS | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LedControl.msg) + +::: details Click here to see original file ```c # LED control: control a single or multiple LED's. @@ -43,5 +87,6 @@ uint8 num_blinks # how many times to blink (number of on-off cycles if mode is o uint8 priority # priority: higher priority events will override current lower priority events (see MAX_PRIORITY) uint8 ORB_QUEUE_LENGTH = 8 # needs to match BOARD_MAX_LEDS - ``` + +::: diff --git a/docs/en/msg_docs/LogMessage.md b/docs/en/msg_docs/LogMessage.md index 5f640bae18..c9cd50cdb3 100644 --- a/docs/en/msg_docs/LogMessage.md +++ b/docs/en/msg_docs/LogMessage.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # LogMessage (UORB message) -A logging message, output with PX4_WARN, PX4_ERR, PX4_INFO +A logging message, output with PX4_WARN, PX4_ERR, PX4_INFO. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LogMessage.msg) +**TOPICS:** log_message + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ----------- | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| severity | `uint8` | | | log level (same as in the linux kernel, starting with 0) | +| text | `char[127]` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LogMessage.msg) + +::: details Click here to see original file ```c # A logging message, output with PX4_WARN, PX4_ERR, PX4_INFO @@ -13,5 +37,6 @@ uint8 severity # log level (same as in the linux kernel, starting with 0) char[127] text uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/LoggerStatus.md b/docs/en/msg_docs/LoggerStatus.md index 63ca114851..48d3a54b2e 100644 --- a/docs/en/msg_docs/LoggerStatus.md +++ b/docs/en/msg_docs/LoggerStatus.md @@ -1,8 +1,42 @@ +--- +pageClass: is-wide-page +--- + # LoggerStatus (UORB message) +**TOPICS:** logger_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LoggerStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | --------- | ------------ | ---------- | ----------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| type | `uint8` | | | +| backend | `uint8` | | | +| is_logging | `bool` | | | +| total_written_kb | `float32` | | | total written to log in kiloBytes | +| write_rate_kb_s | `float32` | | | write rate in kiloBytes/s | +| dropouts | `uint32` | | | number of failed buffer writes due to buffer overflow | +| message_gaps | `uint32` | | | messages misssed | +| buffer_used_bytes | `uint32` | | | current buffer fill in Bytes | +| buffer_size_bytes | `uint32` | | | total buffer size in Bytes | +| num_messages | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ----------------------------------------- | +| LOGGER_TYPE_FULL | `uint8` | 0 | Normal, full size log | +| LOGGER_TYPE_MISSION | `uint8` | 1 | reduced mission log (e.g. for geotagging) | +| BACKEND_FILE | `uint8` | 1 | +| BACKEND_MAVLINK | `uint8` | 2 | +| BACKEND_ALL | `uint8` | 3 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/LoggerStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -28,5 +62,6 @@ uint32 buffer_used_bytes # current buffer fill in Bytes uint32 buffer_size_bytes # total buffer size in Bytes uint8 num_messages - ``` + +::: diff --git a/docs/en/msg_docs/LongitudinalControlConfiguration.md b/docs/en/msg_docs/LongitudinalControlConfiguration.md index 901d5c23bc..92d81b624c 100644 --- a/docs/en/msg_docs/LongitudinalControlConfiguration.md +++ b/docs/en/msg_docs/LongitudinalControlConfiguration.md @@ -1,10 +1,39 @@ +--- +pageClass: is-wide-page +--- + # LongitudinalControlConfiguration (UORB message) -Fixed Wing Longitudinal Control Configuration message -Used by the fw_lateral_longitudinal_control module and TECS to constrain FixedWingLongitudinalSetpoint messages -and configure the resultant setpoints. +Fixed Wing Longitudinal Control Configuration message. Used by the fw_lateral_longitudinal_control module and TECS to constrain FixedWingLongitudinalSetpoint messages. and configure the resultant setpoints. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/LongitudinalControlConfiguration.msg) +**TOPICS:** longitudinal_controlconfiguration + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| pitch_min | `float32` | rad | [-pi : pi] | defaults to FW_P_LIM_MIN if NAN. | +| pitch_max | `float32` | rad | [-pi : pi] | defaults to FW_P_LIM_MAX if NAN. | +| throttle_min | `float32` | norm | [0 : 1] | deaults to FW_THR_MIN if NAN. | +| throttle_max | `float32` | norm | [0 : 1] | defaults to FW_THR_MAX if NAN. | +| climb_rate_target | `float32` | m/s | | target climbrate to change altitude. Defaults to FW_T_CLIMB_MAX if NAN. Not used if height_rate is directly set in FixedWingLongitudinalSetpoint. | +| sink_rate_target | `float32` | m/s | | target sinkrate to change altitude. Defaults to FW_T_SINK_MAX if NAN. Not used if height_rate is directly set in FixedWingLongitudinalSetpoint. | +| speed_weight | `float32` | | [0 : 2] | , 0=pitch controls altitude only, 2=pitch controls airspeed only | +| enforce_low_height_condition | `bool` | boolean | | if true, the altitude controller is configured with an alternative timeconstant for tighter altitude tracking | +| disable_underspeed_protection | `bool` | boolean | | if true, underspeed handling is disabled in the altitude controller | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/LongitudinalControlConfiguration.msg) + +::: details Click here to see original file ```c # Fixed Wing Longitudinal Control Configuration message @@ -24,5 +53,6 @@ float32 sink_rate_target # [m/s] target sinkrate to change altitude. Defaults float32 speed_weight # [@range 0,2], 0=pitch controls altitude only, 2=pitch controls airspeed only bool enforce_low_height_condition # [boolean] if true, the altitude controller is configured with an alternative timeconstant for tighter altitude tracking bool disable_underspeed_protection # [boolean] if true, underspeed handling is disabled in the altitude controller - ``` + +::: diff --git a/docs/en/msg_docs/MagWorkerData.md b/docs/en/msg_docs/MagWorkerData.md index cb7103aaea..cd6d8964d9 100644 --- a/docs/en/msg_docs/MagWorkerData.md +++ b/docs/en/msg_docs/MagWorkerData.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # MagWorkerData (UORB message) +**TOPICS:** mag_workerdata +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MagWorkerData.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| done_count | `uint32` | | | +| calibration_points_perside | `uint32` | | | +| calibration_interval_perside_us | `uint64` | | | +| calibration_counter_total | `uint32[4]` | | | +| side_data_collected | `bool[4]` | | | +| x | `float32[4]` | | | +| y | `float32[4]` | | | +| z | `float32[4]` | | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------- | ------- | ----- | ----------- | +| MAX_MAGS | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MagWorkerData.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -18,5 +47,6 @@ bool[4] side_data_collected float32[4] x float32[4] y float32[4] z - ``` + +::: diff --git a/docs/en/msg_docs/MagnetometerBiasEstimate.md b/docs/en/msg_docs/MagnetometerBiasEstimate.md index 08f4011497..fafb6dc4df 100644 --- a/docs/en/msg_docs/MagnetometerBiasEstimate.md +++ b/docs/en/msg_docs/MagnetometerBiasEstimate.md @@ -1,8 +1,27 @@ +--- +pageClass: is-wide-page +--- + # MagnetometerBiasEstimate (UORB message) +**TOPICS:** magnetometer_biasestimate +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MagnetometerBiasEstimate.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| bias_x | `float32[4]` | | | estimated X-bias of all the sensors | +| bias_y | `float32[4]` | | | estimated Y-bias of all the sensors | +| bias_z | `float32[4]` | | | estimated Z-bias of all the sensors | +| valid | `bool[4]` | | | true if the estimator has converged | +| stable | `bool[4]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MagnetometerBiasEstimate.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +32,6 @@ float32[4] bias_z # estimated Z-bias of all the sensors bool[4] valid # true if the estimator has converged bool[4] stable - ``` + +::: diff --git a/docs/en/msg_docs/ManualControlSetpoint.md b/docs/en/msg_docs/ManualControlSetpoint.md index a4f70d6738..5d85d3d27f 100644 --- a/docs/en/msg_docs/ManualControlSetpoint.md +++ b/docs/en/msg_docs/ManualControlSetpoint.md @@ -1,8 +1,52 @@ +--- +pageClass: is-wide-page +--- + # ManualControlSetpoint (UORB message) +**TOPICS:** manual_control_setpoint manual_control_input +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ManualControlSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| valid | `bool` | | | +| data_source | `uint8` | | | +| roll | `float32` | | | move right, positive roll rotation, right side down | +| pitch | `float32` | | | move forward, negative pitch rotation, nose down | +| yaw | `float32` | | | positive yaw rotation, clockwise when seen top down | +| throttle | `float32` | | | move up, positive thrust, -1 is minimum available 0% or -100% +1 is 100% thrust | +| flaps | `float32` | | | position of flaps switch/knob/lever [-1, 1] | +| aux1 | `float32` | | | +| aux2 | `float32` | | | +| aux3 | `float32` | | | +| aux4 | `float32` | | | +| aux5 | `float32` | | | +| aux6 | `float32` | | | +| sticks_moving | `bool` | | | +| buttons | `uint16` | | | From uint16 buttons field of Mavlink manual_control message | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ------------------------ | +| MESSAGE_VERSION | `uint32` | 0 | +| SOURCE_UNKNOWN | `uint8` | 0 | +| SOURCE_RC | `uint8` | 1 | radio control (input_rc) | +| SOURCE_MAVLINK_0 | `uint8` | 2 | mavlink instance 0 | +| SOURCE_MAVLINK_1 | `uint8` | 3 | mavlink instance 1 | +| SOURCE_MAVLINK_2 | `uint8` | 4 | mavlink instance 2 | +| SOURCE_MAVLINK_3 | `uint8` | 5 | mavlink instance 3 | +| SOURCE_MAVLINK_4 | `uint8` | 6 | mavlink instance 4 | +| SOURCE_MAVLINK_5 | `uint8` | 7 | mavlink instance 5 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ManualControlSetpoint.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -53,5 +97,6 @@ uint16 buttons # From uint16 buttons field of Mavlink manual_control message # DEPRECATED: float32 y # DEPRECATED: float32 z # DEPRECATED: float32 r - ``` + +::: diff --git a/docs/en/msg_docs/ManualControlSwitches.md b/docs/en/msg_docs/ManualControlSwitches.md index 189682730f..9d2b661535 100644 --- a/docs/en/msg_docs/ManualControlSwitches.md +++ b/docs/en/msg_docs/ManualControlSwitches.md @@ -1,6 +1,54 @@ +--- +pageClass: is-wide-page +--- + # ManualControlSwitches (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ManualControlSwitches.msg) +**TOPICS:** manual_controlswitches + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------ | -------- | ------------ | ---------- | ------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| mode_slot | `uint8` | | | the slot a specific model selector is in | +| arm_switch | `uint8` | | | arm/disarm switch: _DISARMED_, ARMED | +| return_switch | `uint8` | | | return to launch 2 position switch (mandatory): _NORMAL_, RTL | +| loiter_switch | `uint8` | | | loiter 2 position switch (optional): _MISSION_, LOITER | +| offboard_switch | `uint8` | | | offboard 2 position switch (optional): _NORMAL_, OFFBOARD | +| kill_switch | `uint8` | | | throttle kill: _NORMAL_, KILL | +| termination_switch | `uint8` | | | trigger termination which cannot be undone | +| gear_switch | `uint8` | | | landing gear switch: _DOWN_, UP | +| transition_switch | `uint8` | | | VTOL transition switch: \_HOVER, FORWARD_FLIGHT | +| photo_switch | `uint8` | | | Photo trigger switch | +| video_switch | `uint8` | | | Photo trigger switch | +| engage_main_motor_switch | `uint8` | | | Engage the main motor (for helicopters) | +| payload_power_switch | `uint8` | | | Payload power switch | +| switch_changes | `uint32` | | | number of switch changes | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------- | ------- | ----- | --------------------------------- | +| SWITCH_POS_NONE | `uint8` | 0 | switch is not mapped | +| SWITCH_POS_ON | `uint8` | 1 | switch activated (value = 1) | +| SWITCH_POS_MIDDLE | `uint8` | 2 | middle position (value = 0) | +| SWITCH_POS_OFF | `uint8` | 3 | switch not activated (value = -1) | +| MODE_SLOT_NONE | `uint8` | 0 | no mode slot assigned | +| MODE_SLOT_1 | `uint8` | 1 | mode slot 1 selected | +| MODE_SLOT_2 | `uint8` | 2 | mode slot 2 selected | +| MODE_SLOT_3 | `uint8` | 3 | mode slot 3 selected | +| MODE_SLOT_4 | `uint8` | 4 | mode slot 4 selected | +| MODE_SLOT_5 | `uint8` | 5 | mode slot 5 selected | +| MODE_SLOT_6 | `uint8` | 6 | mode slot 6 selected | +| MODE_SLOT_NUM | `uint8` | 6 | number of slots | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ManualControlSwitches.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -40,5 +88,6 @@ uint8 engage_main_motor_switch # Engage the main motor (for helicopters) uint8 payload_power_switch # Payload power switch uint32 switch_changes # number of switch changes - ``` + +::: diff --git a/docs/en/msg_docs/MavlinkLog.md b/docs/en/msg_docs/MavlinkLog.md index 91900aea1b..b95bdc65ff 100644 --- a/docs/en/msg_docs/MavlinkLog.md +++ b/docs/en/msg_docs/MavlinkLog.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # MavlinkLog (UORB message) +**TOPICS:** mavlink_log +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MavlinkLog.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ----------- | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| text | `char[127]` | | | +| severity | `uint8` | | | log level (same as in the linux kernel, starting with 0) | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MavlinkLog.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,5 +33,6 @@ char[127] text uint8 severity # log level (same as in the linux kernel, starting with 0) uint8 ORB_QUEUE_LENGTH = 8 - ``` + +::: diff --git a/docs/en/msg_docs/MavlinkTunnel.md b/docs/en/msg_docs/MavlinkTunnel.md index 8775e82ae4..ca6556b13b 100644 --- a/docs/en/msg_docs/MavlinkTunnel.md +++ b/docs/en/msg_docs/MavlinkTunnel.md @@ -1,8 +1,45 @@ +--- +pageClass: is-wide-page +--- + # MavlinkTunnel (UORB message) -MAV_TUNNEL_PAYLOAD_TYPE enum +MAV_TUNNEL_PAYLOAD_TYPE enum. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MavlinkTunnel.msg) +**TOPICS:** mavlink_tunnel esc_serial_passthru io_serial_passthru + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | Time since system start (microseconds) | +| payload_type | `uint16` | | | A code that identifies the content of the payload (0 for unknown, which is the default). If this code is less than 32768, it is a 'registered' payload type and the corresponding code should be added to the MAV_TUNNEL_PAYLOAD_TYPE enum. Software creators can register blocks of types as needed. Codes greater than 32767 are considered local experiments and should not be checked in to any widely distributed codebase. | +| target_system | `uint8` | | | System ID (can be 0 for broadcast, but this is discouraged) | +| target_component | `uint8` | | | Component ID (can be 0 for broadcast, but this is discouraged) | +| payload_length | `uint8` | | | Length of the data transported in payload | +| payload | `uint8[128]` | | | Data itself | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------------------- | ------- | ----- | ---------------------------------------- | +| MAV_TUNNEL_PAYLOAD_TYPE_UNKNOWN | `uint8` | 0 | Encoding of payload unknown | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED0 | `uint8` | 200 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED1 | `uint8` | 201 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED2 | `uint8` | 202 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED3 | `uint8` | 203 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED4 | `uint8` | 204 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED5 | `uint8` | 205 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED6 | `uint8` | 206 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED7 | `uint8` | 207 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED8 | `uint8` | 208 | Registered for STorM32 gimbal controller | +| MAV_TUNNEL_PAYLOAD_TYPE_STORM32_RESERVED9 | `uint8` | 209 | Registered for STorM32 gimbal controller | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MavlinkTunnel.msg) + +::: details Click here to see original file ```c # MAV_TUNNEL_PAYLOAD_TYPE enum @@ -27,6 +64,7 @@ uint8 payload_length # Length of the data transported in payload uint8[128] payload # Data itself # Topic aliases for known payload types -# TOPICS mavlink_tunnel esc_serial_passthru - +# TOPICS mavlink_tunnel esc_serial_passthru io_serial_passthru ``` + +::: diff --git a/docs/en/msg_docs/MessageFormatRequest.md b/docs/en/msg_docs/MessageFormatRequest.md index 7c4675e3f6..0f6acac371 100644 --- a/docs/en/msg_docs/MessageFormatRequest.md +++ b/docs/en/msg_docs/MessageFormatRequest.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # MessageFormatRequest (UORB message) +**TOPICS:** message_formatrequest +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MessageFormatRequest.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| protocol_version | `uint16` | | | Must be set to LATEST_PROTOCOL_VERSION. Do not change this field, it must be the first field after the timestamp | +| topic_name | `char[50]` | | | E.g. /fmu/in/vehicle_command | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | -------- | ----- | ------------------------------------------------------------------------------------------------------------------- | +| LATEST_PROTOCOL_VERSION | `uint16` | 1 | Current version of this protocol. Increase this whenever the MessageFormatRequest or MessageFormatResponse changes. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MessageFormatRequest.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -14,5 +36,6 @@ uint16 LATEST_PROTOCOL_VERSION = 1 # Current version of this protocol. Increase uint16 protocol_version # Must be set to LATEST_PROTOCOL_VERSION. Do not change this field, it must be the first field after the timestamp char[50] topic_name # E.g. /fmu/in/vehicle_command - ``` + +::: diff --git a/docs/en/msg_docs/MessageFormatResponse.md b/docs/en/msg_docs/MessageFormatResponse.md index 3a537289a0..5e11481d34 100644 --- a/docs/en/msg_docs/MessageFormatResponse.md +++ b/docs/en/msg_docs/MessageFormatResponse.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # MessageFormatResponse (UORB message) +**TOPICS:** message_formatresponse +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MessageFormatResponse.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| protocol_version | `uint16` | | | Must be set to LATEST_PROTOCOL_VERSION. Do not change this field, it must be the first field after the timestamp | +| topic_name | `char[50]` | | | E.g. /fmu/in/vehicle_command | +| success | `bool` | | | +| message_hash | `uint32` | | | hash over all message fields | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MessageFormatResponse.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -15,5 +33,6 @@ char[50] topic_name # E.g. /fmu/in/vehicle_command bool success uint32 message_hash # hash over all message fields - ``` + +::: diff --git a/docs/en/msg_docs/Mission.md b/docs/en/msg_docs/Mission.md index 139b2e8914..69771d01c0 100644 --- a/docs/en/msg_docs/Mission.md +++ b/docs/en/msg_docs/Mission.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # Mission (UORB message) +**TOPICS:** mission +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Mission.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | -------- | ------------ | ---------- | ----------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| mission_dataman_id | `uint8` | | | default 0, there are two offboard storage places in the dataman: 0 or 1 | +| fence_dataman_id | `uint8` | | | default 0, there are two offboard storage places in the dataman: 0 or 1 | +| safepoint_dataman_id | `uint8` | | | default 0, there are two offboard storage places in the dataman: 0 or 1 | +| count | `uint16` | | | count of the missions stored in the dataman | +| current_seq | `int32` | | | default -1, start at the one changed latest | +| land_start_index | `int32` | | | Index of the land start marker, if unavailable index of the land item, -1 otherwise | +| land_index | `int32` | | | Index of the land item, -1 otherwise | +| mission_id | `uint32` | | | indicates updates to the mission, reload from dataman if changed | +| geofence_id | `uint32` | | | indicates updates to the geofence, reload from dataman if changed | +| safe_points_id | `uint32` | | | indicates updates to the safe points, reload from dataman if changed | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Mission.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -19,5 +43,6 @@ int32 land_index # Index of the land item, -1 otherwise uint32 mission_id # indicates updates to the mission, reload from dataman if changed uint32 geofence_id # indicates updates to the geofence, reload from dataman if changed uint32 safe_points_id # indicates updates to the safe points, reload from dataman if changed - ``` + +::: diff --git a/docs/en/msg_docs/MissionResult.md b/docs/en/msg_docs/MissionResult.md index 325dc0e438..05be6aea8a 100644 --- a/docs/en/msg_docs/MissionResult.md +++ b/docs/en/msg_docs/MissionResult.md @@ -1,8 +1,36 @@ +--- +pageClass: is-wide-page +--- + # MissionResult (UORB message) +**TOPICS:** mission_result +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MissionResult.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| mission_id | `uint32` | | | Id for the mission for which the result was generated | +| geofence_id | `uint32` | | | Id for the corresponding geofence for which the result was generated (used for mission feasibility) | +| home_position_counter | `uint32` | | | Counter of the home position for which the result was generated (used for mission feasibility) | +| seq_reached | `int32` | | | Sequence of the mission item which has been reached, default -1 | +| seq_current | `uint16` | | | Sequence of the current mission item | +| seq_total | `uint16` | | | Total number of mission items | +| valid | `bool` | | | true if mission is valid | +| warning | `bool` | | | true if mission is valid, but has potentially problematic items leading to safety warnings | +| finished | `bool` | | | true if mission has been completed | +| failure | `bool` | | | true if the mission cannot continue or be completed for some reason | +| item_do_jump_changed | `bool` | | | true if the number of do jumps remaining has changed | +| item_changed_index | `uint16` | | | indicate which item has changed | +| item_do_jump_remaining | `uint16` | | | set to the number of do jumps remaining for that item | +| execution_mode | `uint8` | | | indicates the mode in which the mission is executed | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MissionResult.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -25,5 +53,6 @@ uint16 item_changed_index # indicate which item has changed uint16 item_do_jump_remaining # set to the number of do jumps remaining for that item uint8 execution_mode # indicates the mode in which the mission is executed - ``` + +::: diff --git a/docs/en/msg_docs/ModeCompleted.md b/docs/en/msg_docs/ModeCompleted.md index 76c0c297e6..2b223136fc 100644 --- a/docs/en/msg_docs/ModeCompleted.md +++ b/docs/en/msg_docs/ModeCompleted.md @@ -1,11 +1,34 @@ +--- +pageClass: is-wide-page +--- + # ModeCompleted (UORB message) -Mode completion result, published by an active mode. -The possible values of nav_state are defined in the VehicleStatus msg. -Note that this is not always published (e.g. when a user switches modes or on -failsafe activation) +Mode completion result, published by an active mode. The possible values of nav_state are defined in the VehicleStatus msg. Note that this is not always published (e.g. when a user switches modes or on. failsafe activation). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ModeCompleted.msg) +**TOPICS:** mode_completed + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| result | `uint8` | | | One of RESULT\_\* | +| nav_state | `uint8` | | | Source mode (values in VehicleStatus) | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------- | -------- | ----- | --------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| RESULT_SUCCESS | `uint8` | 0 | +| RESULT_FAILURE_OTHER | `uint8` | 100 | Mode failed (generic error) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ModeCompleted.msg) + +::: details Click here to see original file ```c # Mode completion result, published by an active mode. @@ -25,5 +48,6 @@ uint8 RESULT_FAILURE_OTHER = 100 # Mode failed (generic error) uint8 result # One of RESULT_* uint8 nav_state # Source mode (values in VehicleStatus) - ``` + +::: diff --git a/docs/en/msg_docs/MountOrientation.md b/docs/en/msg_docs/MountOrientation.md index dc676cb94b..1928e141cc 100644 --- a/docs/en/msg_docs/MountOrientation.md +++ b/docs/en/msg_docs/MountOrientation.md @@ -1,11 +1,27 @@ +--- +pageClass: is-wide-page +--- + # MountOrientation (UORB message) +**TOPICS:** mount_orientation +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MountOrientation.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| attitude_euler_angle | `float32[3]` | | | Attitude/direction of the mount as euler angles in rad | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/MountOrientation.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) float32[3] attitude_euler_angle # Attitude/direction of the mount as euler angles in rad - ``` + +::: diff --git a/docs/en/msg_docs/NavigatorMissionItem.md b/docs/en/msg_docs/NavigatorMissionItem.md index 3c3bc3f58c..92fab1ba15 100644 --- a/docs/en/msg_docs/NavigatorMissionItem.md +++ b/docs/en/msg_docs/NavigatorMissionItem.md @@ -1,8 +1,38 @@ +--- +pageClass: is-wide-page +--- + # NavigatorMissionItem (UORB message) +**TOPICS:** navigator_missionitem +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NavigatorMissionItem.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| sequence_current | `uint16` | | | Sequence of the current mission item | +| nav_cmd | `uint16` | | | +| latitude | `float32` | | | +| longitude | `float32` | | | +| time_inside | `float32` | | | time that the MAV should stay inside the radius before advancing in seconds | +| acceptance_radius | `float32` | | | default radius in which the mission is accepted as reached in meters | +| loiter_radius | `float32` | | | loiter radius in meters, 0 for a VTOL to hover, negative for counter-clockwise | +| yaw | `float32` | | | in radians NED -PI..+PI, NAN means don't change yaw | +| altitude | `float32` | | | altitude in meters (AMSL) | +| frame | `uint8` | | | mission frame | +| origin | `uint8` | | | mission item origin (onboard or mavlink) | +| loiter_exit_xtrack | `bool` | | | exit xtrack location: 0 for center of loiter wp, 1 for exit location | +| force_heading | `bool` | | | heading needs to be reached | +| altitude_is_relative | `bool` | | | true if altitude is relative from start point | +| autocontinue | `bool` | | | true if next waypoint should follow after this one | +| vtol_back_transition | `bool` | | | part of the vtol back transition sequence | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NavigatorMissionItem.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -28,5 +58,6 @@ bool force_heading # heading needs to be reached bool altitude_is_relative # true if altitude is relative from start point bool autocontinue # true if next waypoint should follow after this one bool vtol_back_transition # part of the vtol back transition sequence - ``` + +::: diff --git a/docs/en/msg_docs/NavigatorStatus.md b/docs/en/msg_docs/NavigatorStatus.md index 4eb53a56c8..18fe9235d4 100644 --- a/docs/en/msg_docs/NavigatorStatus.md +++ b/docs/en/msg_docs/NavigatorStatus.md @@ -1,9 +1,33 @@ +--- +pageClass: is-wide-page +--- + # NavigatorStatus (UORB message) -Current status of a Navigator mode -The possible values of nav_state are defined in the VehicleStatus msg. +Current status of a Navigator mode. The possible values of nav_state are defined in the VehicleStatus msg. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NavigatorStatus.msg) +**TOPICS:** navigator_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| nav_state | `uint8` | | | Source mode (values in VehicleStatus) | +| failure | `uint8` | | | Navigator failure enum | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------- | ------- | ----- | --------------------------------------------------- | +| FAILURE_NONE | `uint8` | 0 | +| FAILURE_HAGL | `uint8` | 1 | Target altitude exceeds maximum height above ground | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NavigatorStatus.msg) + +::: details Click here to see original file ```c # Current status of a Navigator mode @@ -15,5 +39,6 @@ uint8 failure # Navigator failure enum uint8 FAILURE_NONE = 0 uint8 FAILURE_HAGL = 1 # Target altitude exceeds maximum height above ground - ``` + +::: diff --git a/docs/en/msg_docs/NeuralControl.md b/docs/en/msg_docs/NeuralControl.md index 3e99004fbc..bb62fdb33b 100644 --- a/docs/en/msg_docs/NeuralControl.md +++ b/docs/en/msg_docs/NeuralControl.md @@ -1,12 +1,32 @@ +--- +pageClass: is-wide-page +--- + # NeuralControl (UORB message) -Neural control +Neural control. Debugging topic for the Neural controller, logs the inputs and output vectors of the neural network, and the time it takes to run Publisher: mc_nn_control Subscriber: logger -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NeuralControl.msg) +**TOPICS:** neural_control + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | ------------- | ------------ | ---------- | ---------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| observation | `float32[15]` | | | Observation vector (pos error (3), att (6d), lin vel (3), ang vel (3)) | +| network_output | `float32[4]` | | | Output from neural network | +| controller_time | `int32` | us | | Time spent from input to output | +| inference_time | `int32` | us | | Time spent for NN inference | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NeuralControl.msg) + +::: details Click here to see original file ```c # Neural control @@ -22,5 +42,6 @@ float32[4] network_output # Output from neural network int32 controller_time # [us] Time spent from input to output int32 inference_time # [us] Time spent for NN inference - ``` + +::: diff --git a/docs/en/msg_docs/NormalizedUnsignedSetpoint.md b/docs/en/msg_docs/NormalizedUnsignedSetpoint.md index 025a5fae76..521881a0a9 100644 --- a/docs/en/msg_docs/NormalizedUnsignedSetpoint.md +++ b/docs/en/msg_docs/NormalizedUnsignedSetpoint.md @@ -1,8 +1,23 @@ +--- +pageClass: is-wide-page +--- + # NormalizedUnsignedSetpoint (UORB message) +**TOPICS:** flaps_setpoint spoilers_setpoint +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NormalizedUnsignedSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| normalized_setpoint | `float32` | 0, 1 | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/NormalizedUnsignedSetpoint.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +25,6 @@ uint64 timestamp # time since system start (microseconds) float32 normalized_setpoint # [0, 1] # TOPICS flaps_setpoint spoilers_setpoint - ``` + +::: diff --git a/docs/en/msg_docs/ObstacleDistance.md b/docs/en/msg_docs/ObstacleDistance.md index 622ba0a2ba..59b6eef1e6 100644 --- a/docs/en/msg_docs/ObstacleDistance.md +++ b/docs/en/msg_docs/ObstacleDistance.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # ObstacleDistance (UORB message) Obstacle distances in front of the sensor. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ObstacleDistance.msg) +**TOPICS:** obstacle_distance obstacle_distance_fused + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ------------ | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| frame | `uint8` | | | Coordinate frame of reference for the yaw rotation and offset of the sensor data. Defaults to MAV_FRAME_GLOBAL, which is North aligned. For body-mounted sensors use MAV_FRAME_BODY_FRD, which is vehicle front aligned. | +| sensor_type | `uint8` | | | Type from MAV_DISTANCE_SENSOR enum. | +| distances | `uint16[72]` | | | Distance of obstacles around the UAV with index 0 corresponding to local North. A value of 0 means that the obstacle is right in front of the sensor. A value of max_distance +1 means no obstacle is present. A value of UINT16_MAX for unknown/not used. In a array element, one unit corresponds to 1cm. | +| increment | `float32` | | | Angular width in degrees of each array element. | +| min_distance | `uint16` | | | Minimum distance the sensor can measure in centimeters. | +| max_distance | `uint16` | | | Maximum distance the sensor can measure in centimeters. | +| angle_offset | `float32` | | | Relative angle offset of the 0-index element in the distances array. Value of 0 corresponds to forward. Positive is clockwise direction, negative is counter-clockwise. | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------- | ------- | ----- | ----------- | +| MAV_FRAME_GLOBAL | `uint8` | 0 | +| MAV_FRAME_LOCAL_NED | `uint8` | 1 | +| MAV_FRAME_BODY_FRD | `uint8` | 12 | +| MAV_DISTANCE_SENSOR_LASER | `uint8` | 0 | +| MAV_DISTANCE_SENSOR_ULTRASOUND | `uint8` | 1 | +| MAV_DISTANCE_SENSOR_INFRARED | `uint8` | 2 | +| MAV_DISTANCE_SENSOR_RADAR | `uint8` | 3 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ObstacleDistance.msg) + +::: details Click here to see original file ```c # Obstacle distances in front of the sensor. @@ -29,5 +64,6 @@ uint16 max_distance # Maximum distance the sensor can measure in centimeters. float32 angle_offset # Relative angle offset of the 0-index element in the distances array. Value of 0 corresponds to forward. Positive is clockwise direction, negative is counter-clockwise. # TOPICS obstacle_distance obstacle_distance_fused - ``` + +::: diff --git a/docs/en/msg_docs/OffboardControlMode.md b/docs/en/msg_docs/OffboardControlMode.md index 4499912d95..16bcb63ebf 100644 --- a/docs/en/msg_docs/OffboardControlMode.md +++ b/docs/en/msg_docs/OffboardControlMode.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # OffboardControlMode (UORB message) -Off-board control mode +Off-board control mode. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OffboardControlMode.msg) +**TOPICS:** offboard_controlmode + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| position | `bool` | | | +| velocity | `bool` | | | +| acceleration | `bool` | | | +| attitude | `bool` | | | +| body_rate | `bool` | | | +| thrust_and_torque | `bool` | | | +| direct_actuator | `bool` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OffboardControlMode.msg) + +::: details Click here to see original file ```c # Off-board control mode @@ -16,5 +39,6 @@ bool attitude bool body_rate bool thrust_and_torque bool direct_actuator - ``` + +::: diff --git a/docs/en/msg_docs/OnboardComputerStatus.md b/docs/en/msg_docs/OnboardComputerStatus.md index fc60e6f789..73aa9f30cf 100644 --- a/docs/en/msg_docs/OnboardComputerStatus.md +++ b/docs/en/msg_docs/OnboardComputerStatus.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # OnboardComputerStatus (UORB message) -ONBOARD_COMPUTER_STATUS message data +ONBOARD_COMPUTER_STATUS message data. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OnboardComputerStatus.msg) +**TOPICS:** onboard_computerstatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | ----------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | time since system start (microseconds) | +| uptime | `uint32` | ms | | time since system boot of the companion (milliseconds) | +| type | `uint8` | | | type of onboard computer 0: Mission computer primary, 1: Mission computer backup 1, 2: Mission computer backup 2, 3: Compute node, 4-5: Compute spares, 6-9: Payload computers. | +| cpu_cores | `uint8[8]` | | | CPU usage on the component in percent | +| cpu_combined | `uint8[10]` | | | Combined CPU usage as the last 10 slices of 100 MS | +| gpu_cores | `uint8[4]` | | | GPU usage on the component in percent | +| gpu_combined | `uint8[10]` | | | Combined GPU usage as the last 10 slices of 100 MS | +| temperature_board | `int8` | degC | | Temperature of the board | +| temperature_core | `int8[8]` | degC | | Temperature of the CPU core | +| fan_speed | `int16[4]` | rpm | | Fan speeds | +| ram_usage | `uint32` | MB | | Amount of used RAM on the component system | +| ram_total | `uint32` | MB | | Total amount of RAM on the component system | +| storage_type | `uint32[4]` | | | Storage type: 0: HDD, 1: SSD, 2: EMMC, 3: SD card (non-removable), 4: SD card (removable) | +| storage_usage | `uint32[4]` | MB | | Amount of used storage space on the component system | +| storage_total | `uint32[4]` | MB | | Total amount of storage space on the component system | +| link_type | `uint32[6]` | Kb/s | | Link type: 0-9: UART, 10-19: Wired network, 20-29: Wifi, 30-39: Point-to-point proprietary, 40-49: Mesh proprietary | +| link_tx_rate | `uint32[6]` | Kb/s | | Network traffic from the component system | +| link_rx_rate | `uint32[6]` | Kb/s | | Network traffic to the component system | +| link_tx_max | `uint32[6]` | Kb/s | | Network capacity from the component system | +| link_rx_max | `uint32[6]` | Kb/s | | Network capacity to the component system | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OnboardComputerStatus.msg) + +::: details Click here to see original file ```c # ONBOARD_COMPUTER_STATUS message data @@ -28,5 +63,6 @@ uint32[6] link_tx_rate # [Kb/s] Network traffic from the component system uint32[6] link_rx_rate # [Kb/s] Network traffic to the component system uint32[6] link_tx_max # [Kb/s] Network capacity from the component system uint32[6] link_rx_max # [Kb/s] Network capacity to the component system - ``` + +::: diff --git a/docs/en/msg_docs/OpenDroneIdArmStatus.md b/docs/en/msg_docs/OpenDroneIdArmStatus.md index 78c7992a11..ba5fceb5b6 100644 --- a/docs/en/msg_docs/OpenDroneIdArmStatus.md +++ b/docs/en/msg_docs/OpenDroneIdArmStatus.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # OpenDroneIdArmStatus (UORB message) +**TOPICS:** open_droneid_armstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdArmStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ---------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| status | `uint8` | | | +| error | `char[50]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdArmStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp uint8 status char[50] error - ``` + +::: diff --git a/docs/en/msg_docs/OpenDroneIdOperatorId.md b/docs/en/msg_docs/OpenDroneIdOperatorId.md index e30192ea97..2e3b5fb3e1 100644 --- a/docs/en/msg_docs/OpenDroneIdOperatorId.md +++ b/docs/en/msg_docs/OpenDroneIdOperatorId.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # OpenDroneIdOperatorId (UORB message) +**TOPICS:** open_droneid_operatorid +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdOperatorId.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| id_or_mac | `uint8[20]` | | | +| operator_id_type | `uint8` | | | +| operator_id | `char[20]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdOperatorId.msg) + +::: details Click here to see original file ```c uint64 timestamp uint8[20] id_or_mac uint8 operator_id_type char[20] operator_id - ``` + +::: diff --git a/docs/en/msg_docs/OpenDroneIdSelfId.md b/docs/en/msg_docs/OpenDroneIdSelfId.md index e14e7746f4..d6fa45edce 100644 --- a/docs/en/msg_docs/OpenDroneIdSelfId.md +++ b/docs/en/msg_docs/OpenDroneIdSelfId.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # OpenDroneIdSelfId (UORB message) +**TOPICS:** open_droneid_selfid +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdSelfId.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| id_or_mac | `uint8[20]` | | | +| description_type | `uint8` | | | +| description | `char[23]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdSelfId.msg) + +::: details Click here to see original file ```c uint64 timestamp uint8[20] id_or_mac uint8 description_type char[23] description - ``` + +::: diff --git a/docs/en/msg_docs/OpenDroneIdSystem.md b/docs/en/msg_docs/OpenDroneIdSystem.md index 2fb1943c79..702221d403 100644 --- a/docs/en/msg_docs/OpenDroneIdSystem.md +++ b/docs/en/msg_docs/OpenDroneIdSystem.md @@ -1,8 +1,34 @@ +--- +pageClass: is-wide-page +--- + # OpenDroneIdSystem (UORB message) +**TOPICS:** open_droneid_system +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdSystem.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | ----------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| id_or_mac | `uint8[20]` | | | +| operator_location_type | `uint8` | | | +| classification_type | `uint8` | | | +| operator_latitude | `int32` | | | +| operator_longitude | `int32` | | | +| area_count | `uint16` | | | +| area_radius | `uint16` | | | +| area_ceiling | `float32` | | | +| area_floor | `float32` | | | +| category_eu | `uint8` | | | +| class_eu | `uint8` | | | +| operator_altitude_geo | `float32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OpenDroneIdSystem.msg) + +::: details Click here to see original file ```c uint64 timestamp @@ -18,5 +44,6 @@ float32 area_floor uint8 category_eu uint8 class_eu float32 operator_altitude_geo - ``` + +::: diff --git a/docs/en/msg_docs/OrbTest.md b/docs/en/msg_docs/OrbTest.md index d833eb9ba3..5e6ea41cc9 100644 --- a/docs/en/msg_docs/OrbTest.md +++ b/docs/en/msg_docs/OrbTest.md @@ -1,8 +1,23 @@ +--- +pageClass: is-wide-page +--- + # OrbTest (UORB message) +**TOPICS:** orb_test orb_multitest +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTest.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| val | `int32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTest.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +25,6 @@ uint64 timestamp # time since system start (microseconds) int32 val # TOPICS orb_test orb_multitest - ``` + +::: diff --git a/docs/en/msg_docs/OrbTestLarge.md b/docs/en/msg_docs/OrbTestLarge.md index 8fb96f757f..b78f964662 100644 --- a/docs/en/msg_docs/OrbTestLarge.md +++ b/docs/en/msg_docs/OrbTestLarge.md @@ -1,8 +1,24 @@ +--- +pageClass: is-wide-page +--- + # OrbTestLarge (UORB message) +**TOPICS:** orb_testlarge +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTestLarge.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| val | `int32` | | | +| junk | `uint8[512]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTestLarge.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +26,6 @@ uint64 timestamp # time since system start (microseconds) int32 val uint8[512] junk - ``` + +::: diff --git a/docs/en/msg_docs/OrbTestMedium.md b/docs/en/msg_docs/OrbTestMedium.md index a5484401c7..52d8736a09 100644 --- a/docs/en/msg_docs/OrbTestMedium.md +++ b/docs/en/msg_docs/OrbTestMedium.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # OrbTestMedium (UORB message) +**TOPICS:** orb_test_medium orb_test_medium_multi orb_test_medium_wrap_around orb_test_medium_queue orb_test_medium_queue_poll +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTestMedium.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ----------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| val | `int32` | | | +| junk | `uint8[64]` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbTestMedium.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -14,5 +36,6 @@ uint8[64] junk uint8 ORB_QUEUE_LENGTH = 16 # TOPICS orb_test_medium orb_test_medium_multi orb_test_medium_wrap_around orb_test_medium_queue orb_test_medium_queue_poll - ``` + +::: diff --git a/docs/en/msg_docs/OrbitStatus.md b/docs/en/msg_docs/OrbitStatus.md index 2cbeeec36b..79f8cdd6f4 100644 --- a/docs/en/msg_docs/OrbitStatus.md +++ b/docs/en/msg_docs/OrbitStatus.md @@ -1,8 +1,41 @@ +--- +pageClass: is-wide-page +--- + # OrbitStatus (UORB message) -ORBIT_YAW_BEHAVIOUR +ORBIT_YAW_BEHAVIOUR. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbitStatus.msg) +**TOPICS:** orbit_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | --------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| radius | `float32` | | | Radius of the orbit circle. Positive values orbit clockwise, negative values orbit counter-clockwise. [m] | +| frame | `uint8` | | | The coordinate system of the fields: x, y, z. | +| x | `float64` | | | X coordinate of center point. Coordinate system depends on frame field: local = x position in meters _ 1e4, global = latitude in degrees _ 1e7. | +| y | `float64` | | | Y coordinate of center point. Coordinate system depends on frame field: local = y position in meters _ 1e4, global = latitude in degrees _ 1e7. | +| z | `float32` | | | Altitude of center point. Coordinate system depends on frame field. | +| yaw_behaviour | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------------------------- | ------- | ----- | ----------- | +| ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TO_CIRCLE_CENTER | `uint8` | 0 | +| ORBIT_YAW_BEHAVIOUR_HOLD_INITIAL_HEADING | `uint8` | 1 | +| ORBIT_YAW_BEHAVIOUR_UNCONTROLLED | `uint8` | 2 | +| ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TANGENT_TO_CIRCLE | `uint8` | 3 | +| ORBIT_YAW_BEHAVIOUR_RC_CONTROLLED | `uint8` | 4 | +| ORBIT_YAW_BEHAVIOUR_UNCHANGED | `uint8` | 5 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/OrbitStatus.msg) + +::: details Click here to see original file ```c # ORBIT_YAW_BEHAVIOUR @@ -20,5 +53,6 @@ float64 x # X coordinate of center point. Coordinate system depends on fr float64 y # Y coordinate of center point. Coordinate system depends on frame field: local = y position in meters * 1e4, global = latitude in degrees * 1e7. float32 z # Altitude of center point. Coordinate system depends on frame field. uint8 yaw_behaviour - ``` + +::: diff --git a/docs/en/msg_docs/ParameterResetRequest.md b/docs/en/msg_docs/ParameterResetRequest.md index 3c776a0faf..b0c92c37db 100644 --- a/docs/en/msg_docs/ParameterResetRequest.md +++ b/docs/en/msg_docs/ParameterResetRequest.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # ParameterResetRequest (UORB message) -ParameterResetRequest : Used by the primary to reset one or all parameter value(s) on the remote +ParameterResetRequest : Used by the primary to reset one or all parameter value(s) on the remote. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterResetRequest.msg) +**TOPICS:** parameter_resetrequest + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | -------- | ------------ | ---------- | ------------------------------------------- | +| timestamp | `uint64` | | | +| parameter_index | `uint16` | | | +| reset_all | `bool` | | | If this is true then ignore parameter_index | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterResetRequest.msg) + +::: details Click here to see original file ```c # ParameterResetRequest : Used by the primary to reset one or all parameter value(s) on the remote @@ -13,5 +37,6 @@ uint16 parameter_index bool reset_all # If this is true then ignore parameter_index uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/ParameterSetUsedRequest.md b/docs/en/msg_docs/ParameterSetUsedRequest.md index 14684c0eed..c2afd68aa0 100644 --- a/docs/en/msg_docs/ParameterSetUsedRequest.md +++ b/docs/en/msg_docs/ParameterSetUsedRequest.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # ParameterSetUsedRequest (UORB message) -ParameterSetUsedRequest : Used by a remote to update the used flag for a parameter on the primary +ParameterSetUsedRequest : Used by a remote to update the used flag for a parameter on the primary. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetUsedRequest.msg) +**TOPICS:** parameter_setused_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | -------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| parameter_index | `uint16` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 64 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetUsedRequest.msg) + +::: details Click here to see original file ```c # ParameterSetUsedRequest : Used by a remote to update the used flag for a parameter on the primary @@ -11,5 +34,6 @@ uint64 timestamp uint16 parameter_index uint8 ORB_QUEUE_LENGTH = 64 - ``` + +::: diff --git a/docs/en/msg_docs/ParameterSetValueRequest.md b/docs/en/msg_docs/ParameterSetValueRequest.md index b8322a952e..f229c6076e 100644 --- a/docs/en/msg_docs/ParameterSetValueRequest.md +++ b/docs/en/msg_docs/ParameterSetValueRequest.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # ParameterSetValueRequest (UORB message) -ParameterSetValueRequest : Used by a remote or primary to update the value for a parameter at the other end +ParameterSetValueRequest : Used by a remote or primary to update the value for a parameter at the other end. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetValueRequest.msg) +**TOPICS:** parameter_set_value_request parameter_remote_set_value_request parameter_primary_set_value_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | --------- | ------------ | ---------- | --------------------------------------- | +| timestamp | `uint64` | | | +| parameter_index | `uint16` | | | +| int_value | `int32` | | | Optional value for an integer parameter | +| float_value | `float32` | | | Optional value for a float parameter | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 32 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetValueRequest.msg) + +::: details Click here to see original file ```c # ParameterSetValueRequest : Used by a remote or primary to update the value for a parameter at the other end @@ -16,5 +41,6 @@ float32 float_value # Optional value for a float parameter uint8 ORB_QUEUE_LENGTH = 32 # TOPICS parameter_set_value_request parameter_remote_set_value_request parameter_primary_set_value_request - ``` + +::: diff --git a/docs/en/msg_docs/ParameterSetValueResponse.md b/docs/en/msg_docs/ParameterSetValueResponse.md index dbb44d46ea..f0a0bf4051 100644 --- a/docs/en/msg_docs/ParameterSetValueResponse.md +++ b/docs/en/msg_docs/ParameterSetValueResponse.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # ParameterSetValueResponse (UORB message) -ParameterSetValueResponse : Response to a set value request by either primary or secondary +ParameterSetValueResponse : Response to a set value request by either primary or secondary. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetValueResponse.msg) +**TOPICS:** parameter_set_value_response parameter_remote_set_value_response parameter_primary_set_value_response + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | -------- | ------------ | ---------- | ----------- | +| timestamp | `uint64` | | | +| request_timestamp | `uint64` | | | +| parameter_index | `uint16` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterSetValueResponse.msg) + +::: details Click here to see original file ```c # ParameterSetValueResponse : Response to a set value request by either primary or secondary @@ -14,5 +38,6 @@ uint16 parameter_index uint8 ORB_QUEUE_LENGTH = 4 # TOPICS parameter_set_value_response parameter_remote_set_value_response parameter_primary_set_value_response - ``` + +::: diff --git a/docs/en/msg_docs/ParameterUpdate.md b/docs/en/msg_docs/ParameterUpdate.md index 29148e2b5b..47df977aa4 100644 --- a/docs/en/msg_docs/ParameterUpdate.md +++ b/docs/en/msg_docs/ParameterUpdate.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # ParameterUpdate (UORB message) -This message is used to notify the system about one or more parameter changes +This message is used to notify the system about one or more parameter changes. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterUpdate.msg) +**TOPICS:** parameter_update + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | -------- | ------------ | ---------- | ---------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| instance | `uint32` | | | Instance count - constantly incrementing | +| get_count | `uint32` | | | +| set_count | `uint32` | | | +| find_count | `uint32` | | | +| export_count | `uint32` | | | +| active | `uint16` | | | +| changed | `uint16` | | | +| custom_default | `uint16` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/ParameterUpdate.msg) + +::: details Click here to see original file ```c # This message is used to notify the system about one or more parameter changes @@ -19,5 +43,6 @@ uint32 export_count uint16 active uint16 changed uint16 custom_default - ``` + +::: diff --git a/docs/en/msg_docs/Ping.md b/docs/en/msg_docs/Ping.md index 1d68cebad1..c27bfbac41 100644 --- a/docs/en/msg_docs/Ping.md +++ b/docs/en/msg_docs/Ping.md @@ -1,8 +1,28 @@ +--- +pageClass: is-wide-page +--- + # Ping (UORB message) +**TOPICS:** ping +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Ping.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| ping_time | `uint64` | | | Timestamp of the ping packet | +| ping_sequence | `uint32` | | | Sequence number of the ping packet | +| dropped_packets | `uint32` | | | Number of dropped ping packets | +| rtt_ms | `float32` | | | Round trip time (in ms) | +| system_id | `uint8` | | | System ID of the remote system | +| component_id | `uint8` | | | Component ID of the remote system | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Ping.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -12,5 +32,6 @@ uint32 dropped_packets # Number of dropped ping packets float32 rtt_ms # Round trip time (in ms) uint8 system_id # System ID of the remote system uint8 component_id # Component ID of the remote system - ``` + +::: diff --git a/docs/en/msg_docs/PositionControllerLandingStatus.md b/docs/en/msg_docs/PositionControllerLandingStatus.md index 0e7ce90a2e..a2265e80ae 100644 --- a/docs/en/msg_docs/PositionControllerLandingStatus.md +++ b/docs/en/msg_docs/PositionControllerLandingStatus.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # PositionControllerLandingStatus (UORB message) +**TOPICS:** position_controllerlanding_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionControllerLandingStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------ | --------- | ------------ | ---------- | ------------------------------------------------------------------- | +| timestamp | `uint64` | us | | time since system start | +| lateral_touchdown_offset | `float32` | m | | lateral touchdown position offset manually commanded during landing | +| flaring | `bool` | | | true if the aircraft is flaring | +| abort_status | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | --------------------- | +| NOT_ABORTED | `uint8` | 0 | +| ABORTED_BY_OPERATOR | `uint8` | 1 | +| TERRAIN_NOT_FOUND | `uint8` | 2 | FW_LND_ABORT (1 << 0) | +| TERRAIN_TIMEOUT | `uint8` | 3 | FW_LND_ABORT (1 << 1) | +| UNKNOWN_ABORT_CRITERION | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionControllerLandingStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # [us] time since system start @@ -21,5 +48,6 @@ uint8 ABORTED_BY_OPERATOR = 1 uint8 TERRAIN_NOT_FOUND = 2 # FW_LND_ABORT (1 << 0) uint8 TERRAIN_TIMEOUT = 3 # FW_LND_ABORT (1 << 1) uint8 UNKNOWN_ABORT_CRITERION = 4 - ``` + +::: diff --git a/docs/en/msg_docs/PositionControllerStatus.md b/docs/en/msg_docs/PositionControllerStatus.md index 95f0ec0926..40b2d40a82 100644 --- a/docs/en/msg_docs/PositionControllerStatus.md +++ b/docs/en/msg_docs/PositionControllerStatus.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # PositionControllerStatus (UORB message) +**TOPICS:** position_controllerstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionControllerStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| nav_roll | `float32` | | | Roll setpoint [rad] | +| nav_pitch | `float32` | | | Pitch setpoint [rad] | +| nav_bearing | `float32` | | | Bearing angle[rad] | +| target_bearing | `float32` | | | Bearing angle from aircraft to current target [rad] | +| xtrack_error | `float32` | | | Signed track error [m] | +| wp_dist | `float32` | | | Distance to active (next) waypoint [m] | +| acceptance_radius | `float32` | | | Current horizontal acceptance radius [m] | +| type | `uint8` | | | Current (applied) position setpoint type (see PositionSetpoint.msg) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionControllerStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -15,5 +37,6 @@ float32 xtrack_error # Signed track error [m] float32 wp_dist # Distance to active (next) waypoint [m] float32 acceptance_radius # Current horizontal acceptance radius [m] uint8 type # Current (applied) position setpoint type (see PositionSetpoint.msg) - ``` + +::: diff --git a/docs/en/msg_docs/PositionSetpoint.md b/docs/en/msg_docs/PositionSetpoint.md index b4e16681b7..2ed4747470 100644 --- a/docs/en/msg_docs/PositionSetpoint.md +++ b/docs/en/msg_docs/PositionSetpoint.md @@ -1,8 +1,56 @@ +--- +pageClass: is-wide-page +--- + # PositionSetpoint (UORB message) -this file is only used in the position_setpoint triple as a dependency +this file is only used in the position_setpoint triple as a dependency. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionSetpoint.msg) +**TOPICS:** position_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| valid | `bool` | | | true if setpoint is valid | +| type | `uint8` | | | setpoint type to adjust behavior of position controller | +| vx | `float32` | | | local velocity setpoint in m/s in NED | +| vy | `float32` | | | local velocity setpoint in m/s in NED | +| vz | `float32` | | | local velocity setpoint in m/s in NED | +| lat | `float64` | | | latitude, in deg | +| lon | `float64` | | | longitude, in deg | +| alt | `float32` | | | altitude AMSL, in m | +| yaw | `float32` | | | yaw (only in hover), in rad [-PI..PI), NaN = leave to flight task | +| loiter_radius | `float32` | m | [0 : INF] | loiter major axis radius | +| loiter_minor_radius | `float32` | m | [0 : INF] | loiter minor axis radius (used for non-circular loiter shapes) | +| loiter_direction_counter_clockwise | `bool` | | | loiter direction is clockwise by default and can be changed using this field | +| loiter_orientation | `float32` | rad | [-pi : pi] | orientation of the major axis with respect to true north | +| loiter_pattern | `uint8` | | | loitern pattern to follow | +| acceptance_radius | `float32` | | | horizontal acceptance_radius (meters) | +| alt_acceptance_radius | `float32` | | | vertical acceptance radius, only used for fixed wing guidance, NAN = let guidance choose (meters) | +| cruising_speed | `float32` | | | the generally desired cruising speed (not a hard constraint) | +| gliding_enabled | `bool` | | | commands the vehicle to glide if the capability is available (fixed wing only) | +| cruising_throttle | `float32` | | | the generally desired cruising throttle (not a hard constraint), only has an effect for rover | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | -------------------------------------------------------------- | +| SETPOINT_TYPE_POSITION | `uint8` | 0 | position setpoint | +| SETPOINT_TYPE_VELOCITY | `uint8` | 1 | velocity setpoint | +| SETPOINT_TYPE_LOITER | `uint8` | 2 | loiter setpoint | +| SETPOINT_TYPE_TAKEOFF | `uint8` | 3 | takeoff setpoint | +| SETPOINT_TYPE_LAND | `uint8` | 4 | land setpoint, altitude must be ignored, descend until landing | +| SETPOINT_TYPE_IDLE | `uint8` | 5 | do nothing, switch off motors or keep at idle speed (MC) | +| LOITER_TYPE_ORBIT | `uint8` | 0 | Circular pattern | +| LOITER_TYPE_FIGUREEIGHT | `uint8` | 1 | Pattern resembling an 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionSetpoint.msg) + +::: details Click here to see original file ```c # this file is only used in the position_setpoint triple as a dependency @@ -43,5 +91,6 @@ float32 alt_acceptance_radius # vertical acceptance radius, only used for fixed float32 cruising_speed # the generally desired cruising speed (not a hard constraint) bool gliding_enabled # commands the vehicle to glide if the capability is available (fixed wing only) float32 cruising_throttle # the generally desired cruising throttle (not a hard constraint), only has an effect for rover - ``` + +::: diff --git a/docs/en/msg_docs/PositionSetpointTriplet.md b/docs/en/msg_docs/PositionSetpointTriplet.md index d4de724bdd..4aea2917fe 100644 --- a/docs/en/msg_docs/PositionSetpointTriplet.md +++ b/docs/en/msg_docs/PositionSetpointTriplet.md @@ -1,9 +1,27 @@ +--- +pageClass: is-wide-page +--- + # PositionSetpointTriplet (UORB message) -Global position setpoint triplet in WGS84 coordinates. -This are the three next waypoints (or just the next two or one). +Global position setpoint triplet in WGS84 coordinates. This are the three next waypoints (or just the next two or one). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionSetpointTriplet.msg) +**TOPICS:** position_setpointtriplet + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ------------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| previous | `PositionSetpoint` | | | +| current | `PositionSetpoint` | | | +| next | `PositionSetpoint` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PositionSetpointTriplet.msg) + +::: details Click here to see original file ```c # Global position setpoint triplet in WGS84 coordinates. @@ -14,5 +32,6 @@ uint64 timestamp # time since system start (microseconds) PositionSetpoint previous PositionSetpoint current PositionSetpoint next - ``` + +::: diff --git a/docs/en/msg_docs/PowerButtonState.md b/docs/en/msg_docs/PowerButtonState.md index 8d6f38461e..f43ec7dce6 100644 --- a/docs/en/msg_docs/PowerButtonState.md +++ b/docs/en/msg_docs/PowerButtonState.md @@ -1,8 +1,34 @@ +--- +pageClass: is-wide-page +--- + # PowerButtonState (UORB message) -power button state notification message +power button state notification message. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PowerButtonState.msg) +**TOPICS:** power_buttonstate + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| event | `uint8` | | | one of PWR*BUTTON_STATE*\* | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------- | ------- | ----- | ----------------------------------------------------------------------- | +| PWR_BUTTON_STATE_IDEL | `uint8` | 0 | Button went up without meeting shutdown button down time (delete event) | +| PWR_BUTTON_STATE_DOWN | `uint8` | 1 | Button went Down | +| PWR_BUTTON_STATE_UP | `uint8` | 2 | Button went Up | +| PWR_BUTTON_STATE_REQUEST_SHUTDOWN | `uint8` | 3 | Button went Up after meeting shutdown button down time | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PowerButtonState.msg) + +::: details Click here to see original file ```c # power button state notification message @@ -15,5 +41,6 @@ uint8 PWR_BUTTON_STATE_UP = 2 # Button went Up uint8 PWR_BUTTON_STATE_REQUEST_SHUTDOWN = 3 # Button went Up after meeting shutdown button down time uint8 event # one of PWR_BUTTON_STATE_* - ``` + +::: diff --git a/docs/en/msg_docs/PowerMonitor.md b/docs/en/msg_docs/PowerMonitor.md index 5f38bb3d56..082a23b3d8 100644 --- a/docs/en/msg_docs/PowerMonitor.md +++ b/docs/en/msg_docs/PowerMonitor.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # PowerMonitor (UORB message) -power monitor message +power monitor message. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PowerMonitor.msg) +**TOPICS:** power_monitor + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | Time since system start (microseconds) | +| voltage_v | `float32` | | | Voltage in volts, 0 if unknown | +| current_a | `float32` | | | Current in amperes, -1 if unknown | +| power_w | `float32` | | | power in watts, -1 if unknown | +| rconf | `int16` | | | +| rsv | `int16` | | | +| rbv | `int16` | | | +| rp | `int16` | | | +| rc | `int16` | | | +| rcal | `int16` | | | +| me | `int16` | | | +| al | `int16` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PowerMonitor.msg) + +::: details Click here to see original file ```c # power monitor message @@ -20,5 +47,6 @@ int16 rc int16 rcal int16 me int16 al - ``` + +::: diff --git a/docs/en/msg_docs/PpsCapture.md b/docs/en/msg_docs/PpsCapture.md index ffe87fd2dc..5d1a14348d 100644 --- a/docs/en/msg_docs/PpsCapture.md +++ b/docs/en/msg_docs/PpsCapture.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # PpsCapture (UORB message) +**TOPICS:** pps_capture +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PpsCapture.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | -------- | ------------ | ----------------------------- | ----------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) at PPS capture event | +| rtc_timestamp | `uint64` | | | Corrected GPS UTC timestamp at PPS capture event | +| `uint8` | | | Increments when PPS dt < 50ms | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PpsCapture.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) at PPS capture event uint64 rtc_timestamp # Corrected GPS UTC timestamp at PPS capture event uint8 pps_rate_exceeded_counter # Increments when PPS dt < 50ms - ``` + +::: diff --git a/docs/en/msg_docs/PurePursuitStatus.md b/docs/en/msg_docs/PurePursuitStatus.md index 96577a0220..fa442729b1 100644 --- a/docs/en/msg_docs/PurePursuitStatus.md +++ b/docs/en/msg_docs/PurePursuitStatus.md @@ -1,17 +1,39 @@ +--- +pageClass: is-wide-page +--- + # PurePursuitStatus (UORB message) -Pure pursuit status +Pure pursuit status. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PurePursuitStatus.msg) +**TOPICS:** pure_pursuitstatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | --------- | ------------ | --------------------------------------------------- | -------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| lookahead_distance | `float32` | m | [0 : inf] | Lookahead distance of pure the pursuit controller | +| target_bearing | `float32` | rad [NED] | [-pi : pi] | Target bearing calculated by the pure pursuit controller | +| crosstrack_error | `float32` | m | [-inf (Left of the path) : inf (Right of the path)] | Shortest distance from the vehicle to the path | +| distance_to_waypoint | `float32` | m | [-inf : inf] | Distance from the vehicle to the current waypoint | +| bearing_to_waypoint | `float32` | rad [NED] | [-pi : pi] | Bearing towards current waypoint | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PurePursuitStatus.msg) + +::: details Click here to see original file ```c # Pure pursuit status -uint64 timestamp # [us] Time since system start -float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller -float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller -float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path -float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint -float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint - +uint64 timestamp # [us] Time since system start +float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller +float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller +float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path +float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint +float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint ``` + +::: diff --git a/docs/en/msg_docs/PwmInput.md b/docs/en/msg_docs/PwmInput.md index dbf078955b..ca4d9ed41f 100644 --- a/docs/en/msg_docs/PwmInput.md +++ b/docs/en/msg_docs/PwmInput.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # PwmInput (UORB message) +**TOPICS:** pwm_input +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PwmInput.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | -------- | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | Time since system start (microseconds) | +| error_count | `uint64` | | | Timer overcapture error flag (AUX5 or MAIN5) | +| pulse_width | `uint32` | | | Pulse width, timer counts (microseconds) | +| period | `uint32` | | | Period, timer counts (microseconds) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/PwmInput.msg) + +::: details Click here to see original file ```c uint64 timestamp # Time since system start (microseconds) uint64 error_count # Timer overcapture error flag (AUX5 or MAIN5) uint32 pulse_width # Pulse width, timer counts (microseconds) uint32 period # Period, timer counts (microseconds) - ``` + +::: diff --git a/docs/en/msg_docs/Px4ioStatus.md b/docs/en/msg_docs/Px4ioStatus.md index 4b1fbb1314..cbc5e0f339 100644 --- a/docs/en/msg_docs/Px4ioStatus.md +++ b/docs/en/msg_docs/Px4ioStatus.md @@ -1,6 +1,53 @@ +--- +pageClass: is-wide-page +--- + # Px4ioStatus (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Px4ioStatus.msg) +**TOPICS:** px4io_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | ------------ | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| free_memory_bytes | `uint16` | | | +| voltage_v | `float32` | | | Servo rail voltage in volts | +| rssi_v | `float32` | | | RSSI pin voltage in volts | +| status_arm_sync | `bool` | | | +| status_failsafe | `bool` | | | +| status_fmu_initialized | `bool` | | | +| status_fmu_ok | `bool` | | | +| status_init_ok | `bool` | | | +| status_outputs_armed | `bool` | | | +| status_raw_pwm | `bool` | | | +| status_rc_ok | `bool` | | | +| status_rc_dsm | `bool` | | | +| status_rc_ppm | `bool` | | | +| status_rc_sbus | `bool` | | | +| status_rc_st24 | `bool` | | | +| status_rc_sumd | `bool` | | | +| status_safety_button_event | `bool` | | | px4io safety button was pressed for longer than 1 second | +| alarm_pwm_error | `bool` | | | +| alarm_rc_lost | `bool` | | | +| arming_failsafe_custom | `bool` | | | +| arming_fmu_armed | `bool` | | | +| arming_fmu_prearmed | `bool` | | | +| arming_termination | `bool` | | | +| arming_io_arm_ok | `bool` | | | +| arming_lockdown | `bool` | | | +| arming_termination_failsafe | `bool` | | | +| pwm | `uint16[8]` | | | +| pwm_disarmed | `uint16[8]` | | | +| pwm_failsafe | `uint16[8]` | | | +| pwm_rate_hz | `uint16[8]` | | | +| raw_inputs | `uint16[18]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Px4ioStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -46,5 +93,6 @@ uint16[8] pwm_failsafe uint16[8] pwm_rate_hz uint16[18] raw_inputs - ``` + +::: diff --git a/docs/en/msg_docs/QshellReq.md b/docs/en/msg_docs/QshellReq.md index 99cb82472b..346717a999 100644 --- a/docs/en/msg_docs/QshellReq.md +++ b/docs/en/msg_docs/QshellReq.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # QshellReq (UORB message) +**TOPICS:** qshell_req +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/QshellReq.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| cmd | `char[100]` | | | +| strlen | `uint32` | | | +| request_sequence | `uint32` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------- | -------- | ----- | ----------- | +| MAX_STRLEN | `uint32` | 100 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/QshellReq.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +33,6 @@ char[100] cmd uint32 MAX_STRLEN = 100 uint32 strlen uint32 request_sequence - ``` + +::: diff --git a/docs/en/msg_docs/QshellRetval.md b/docs/en/msg_docs/QshellRetval.md index 53cf5063f9..c37afd652e 100644 --- a/docs/en/msg_docs/QshellRetval.md +++ b/docs/en/msg_docs/QshellRetval.md @@ -1,12 +1,29 @@ +--- +pageClass: is-wide-page +--- + # QshellRetval (UORB message) +**TOPICS:** qshell_retval +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/QshellRetval.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| return_value | `int32` | | | +| return_sequence | `uint32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/QshellRetval.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) int32 return_value uint32 return_sequence - ``` + +::: diff --git a/docs/en/msg_docs/RadioStatus.md b/docs/en/msg_docs/RadioStatus.md index 64e69beba4..2712fdea13 100644 --- a/docs/en/msg_docs/RadioStatus.md +++ b/docs/en/msg_docs/RadioStatus.md @@ -1,11 +1,31 @@ +--- +pageClass: is-wide-page +--- + # RadioStatus (UORB message) +**TOPICS:** radio_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RadioStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | -------- | ------------ | ---------- | ----------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| rssi | `uint8` | | | local signal strength | +| remote_rssi | `uint8` | | | remote signal strength | +| txbuf | `uint8` | | | how full the tx buffer is as a percentage | +| noise | `uint8` | | | background noise level | +| remote_noise | `uint8` | | | remote background noise level | +| rxerrors | `uint16` | | | receive errors | +| fix | `uint16` | | | count of error corrected packets | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RadioStatus.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint8 rssi # local signal strength @@ -18,5 +38,6 @@ uint8 remote_noise # remote background noise level uint16 rxerrors # receive errors uint16 fix # count of error corrected packets - ``` + +::: diff --git a/docs/en/msg_docs/RaptorInput.md b/docs/en/msg_docs/RaptorInput.md new file mode 100644 index 0000000000..e18b7531ef --- /dev/null +++ b/docs/en/msg_docs/RaptorInput.md @@ -0,0 +1,58 @@ +--- +pageClass: is-wide-page +--- + +# RaptorInput (UORB message) + +Raptor Input. + +**TOPICS:** raptor_input + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Sampling timestamp of the data this control response is based on | +| active | `bool` | | | Signals if the policy is active (aka publishing actuator_motors) | +| position | `float32[3]` | m [FLU] | | Position of the vehicle_local_position frame | +| orientation | `float32[4]` | | | Orientation in the vehicle_attitude frame but using the FLU convention as a unit quaternion (w, x, y, z) | +| linear_velocity | `float32[3]` | m/s [FLU] | | Linear velocity in the vehicle_local_position frame | +| angular_velocity | `float32[3]` | rad/s [FLU] | | Angular velocity in the body frame | +| previous_action | `float32[4]` | | [-1 : 1] | Previous action. Motor commands normalized to [-1, 1] | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | --------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| ACTION_DIM | `uint8` | 4 | Policy output dimensionality (for quadrotors) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RaptorInput.msg) + +::: details Click here to see original file + +```c +# Raptor Input + +# The exact inputs to the Raptor foundation policy. +# Having access to the exact inputs helps with debugging and post-hoc analysis. + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +bool active # Signals if the policy is active (aka publishing actuator_motors) +float32[3] position # [m] [@frame FLU] Position of the vehicle_local_position frame +float32[4] orientation # [-] Orientation in the vehicle_attitude frame but using the FLU convention as a unit quaternion (w, x, y, z) +float32[3] linear_velocity # [m/s] [@frame FLU] Linear velocity in the vehicle_local_position frame +float32[3] angular_velocity # [rad/s] [@frame FLU] Angular velocity in the body frame +uint8 ACTION_DIM = 4 # Policy output dimensionality (for quadrotors) +float32[4] previous_action # [@range -1, 1] Previous action. Motor commands normalized to [-1, 1] + +# TOPICS raptor_input +``` + +::: diff --git a/docs/en/msg_docs/RaptorStatus.md b/docs/en/msg_docs/RaptorStatus.md new file mode 100644 index 0000000000..945dbd521b --- /dev/null +++ b/docs/en/msg_docs/RaptorStatus.md @@ -0,0 +1,108 @@ +--- +pageClass: is-wide-page +--- + +# RaptorStatus (UORB message) + +Raptor Status. + +**TOPICS:** raptor_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Sampling timestamp of the data this control response is based on | +| subscription_update_angular_velocity | `bool` | bool | | Flag signalling if the vehicle_angular_velocity was updated | +| subscription_update_local_position | `bool` | bool | | Flag signalling if the vehicle_local_position was updated | +| subscription_update_attitude | `bool` | bool | | Flag signalling if the vehicle_attitude was updated | +| subscription_update_trajectory_setpoint | `bool` | bool | | Flag signalling if the trajectory_setpoint was updated | +| subscription_update_vehicle_status | `bool` | bool | | Flag signalling if the vehicle_status was updated | +| exit_reason | `uint8` | enum | | Exit reason identifier. Representing conditions that lead to the Raptor policy not being executed | +| timestamp_last_vehicle_angular_velocity | `uint32` | us | | Timestamp of the last received vehicle_angular_velocity message | +| timestamp_last_vehicle_local_position | `uint32` | us | | Timestamp of the last received vehicle_local_position message | +| timestamp_last_vehicle_attitude | `uint32` | us | | Timestamp of the last received vehicle_attitude message | +| timestamp_last_trajectory_setpoint | `uint32` | us | | Timestamp of the last received trajectory_setpoint message | +| vehicle_angular_velocity_stale | `bool` | bool | | True if vehicle_angular_velocity data is considered stale (exceeded timeout) | +| vehicle_local_position_stale | `bool` | bool | | True if vehicle_local_position data is considered stale (exceeded timeout) | +| vehicle_attitude_stale | `bool` | bool | | True if vehicle_attitude data is considered stale (exceeded timeout) | +| trajectory_setpoint_stale | `bool` | bool | | True if trajectory_setpoint data is considered stale (exceeded timeout) | +| active | `bool` | bool | | True if the Raptor policy is currently active (publishing actuator_motors) | +| substep | `uint8` | | | The policy is trained at a fixed frequency (e.g. 100 Hz) but we might want to use it for control at higher frequencies (e.g. 400 Hz), which leads to a number of intermediate steps before the actual policy state is advanced (in this case 4 = 400 Hz / 100 Hz). This field provides the current substep (e.g. 0-3). | +| control_interval | `float32` | s | | Time interval between control updates | +| trajectory_setpoint_dt_mean | `float32` | us | | The average trajectory setpoint arrival time interval (since Raptor mode activation within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) | +| trajectory_setpoint_dt_max | `float32` | us | | The max trajectory setpoint arrival time interval (since Raptor mode activation and within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) | +| trajectory_setpoint_dt_max_since_activation | `float32` | us | | The max trajectory setpoint arrival time interval (since Raptor mode activation) | +| internal_reference_position | `float32[3]` | m [FLU] | | Internal reference position | +| internal_reference_linear_velocity | `float32[3]` | m/s [FLU] | | Internal reference linear velocity | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| EXIT_REASON_NONE | `uint8` | 0 | No exit reason => Raptor control step was executed (actuator_motors should have been published) | +| EXIT_REASON_NO_ANGULAR_VELOCITY_UPDATE | `uint8` | 1 | We synchronize the control onto the input observation with the highest update frequency, which is vehicle_angular_velocity. If there was no update, we do not need to execute the policy again | +| EXIT_REASON_NOT_ALL_OBSERVATIONS_SET | `uint8` | 2 | We can not execute the policy if not all observations are available | +| EXIT_REASON_ANGULAR_VELOCITY_STALE | `uint8` | 3 | If OBSERVATION_TIMEOUT_ANGULAR_VELOCITY is exceeded, we treat the vehicle_angular_velocity as stale and can not run the policy | +| EXIT_REASON_LOCAL_POSITION_STALE | `uint8` | 4 | If OBSERVATION_TIMEOUT_LOCAL_POSITION is exceeded, we treat the vehicle_local_position as stale and can not run the policy | +| EXIT_REASON_ATTITUDE_STALE | `uint8` | 5 | If OBSERVATION_TIMEOUT_ATTITUDE is exceeded, we treat the vehicle_attitude as stale and can not run the policy | +| EXIT_REASON_EXECUTOR_STATUS_SOURCE_NOT_CONTROL | `uint8` | 6 | The executor that runs the policy can run in oversampling mode, where it decides if the policy should be ran based on the timestamp and not based on fixed synchronization onto the vehicle_angular_velocity. In this case the executor can decide to skip running the policy if the interval is too small, in which case this flag is set. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RaptorStatus.msg) + +::: details Click here to see original file + +```c +# Raptor Status + +# Diagnostic messages for the Raptor foundation policy. +# This diagnostic data is useful for debugging (e.g. identifying missing input information). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +bool subscription_update_angular_velocity # [bool] Flag signalling if the vehicle_angular_velocity was updated +bool subscription_update_local_position # [bool] Flag signalling if the vehicle_local_position was updated +bool subscription_update_attitude # [bool] Flag signalling if the vehicle_attitude was updated +bool subscription_update_trajectory_setpoint # [bool] Flag signalling if the trajectory_setpoint was updated +bool subscription_update_vehicle_status # [bool] Flag signalling if the vehicle_status was updated + +uint8 exit_reason # [enum] Exit reason identifier. Representing conditions that lead to the Raptor policy not being executed +uint8 EXIT_REASON_NONE = 0 # No exit reason => Raptor control step was executed (actuator_motors should have been published) +uint8 EXIT_REASON_NO_ANGULAR_VELOCITY_UPDATE = 1 # We synchronize the control onto the input observation with the highest update frequency, which is vehicle_angular_velocity. If there was no update, we do not need to execute the policy again +uint8 EXIT_REASON_NOT_ALL_OBSERVATIONS_SET = 2 # We can not execute the policy if not all observations are available +uint8 EXIT_REASON_ANGULAR_VELOCITY_STALE = 3 # If OBSERVATION_TIMEOUT_ANGULAR_VELOCITY is exceeded, we treat the vehicle_angular_velocity as stale and can not run the policy +uint8 EXIT_REASON_LOCAL_POSITION_STALE = 4 # If OBSERVATION_TIMEOUT_LOCAL_POSITION is exceeded, we treat the vehicle_local_position as stale and can not run the policy +uint8 EXIT_REASON_ATTITUDE_STALE = 5 # If OBSERVATION_TIMEOUT_ATTITUDE is exceeded, we treat the vehicle_attitude as stale and can not run the policy +uint8 EXIT_REASON_EXECUTOR_STATUS_SOURCE_NOT_CONTROL = 6 # The executor that runs the policy can run in oversampling mode, where it decides if the policy should be ran based on the timestamp and not based on fixed synchronization onto the vehicle_angular_velocity. In this case the executor can decide to skip running the policy if the interval is too small, in which case this flag is set. + +uint32 timestamp_last_vehicle_angular_velocity # [us] Timestamp of the last received vehicle_angular_velocity message +uint32 timestamp_last_vehicle_local_position # [us] Timestamp of the last received vehicle_local_position message +uint32 timestamp_last_vehicle_attitude # [us] Timestamp of the last received vehicle_attitude message +uint32 timestamp_last_trajectory_setpoint # [us] Timestamp of the last received trajectory_setpoint message + +bool vehicle_angular_velocity_stale # [bool] True if vehicle_angular_velocity data is considered stale (exceeded timeout) +bool vehicle_local_position_stale # [bool] True if vehicle_local_position data is considered stale (exceeded timeout) +bool vehicle_attitude_stale # [bool] True if vehicle_attitude data is considered stale (exceeded timeout) +bool trajectory_setpoint_stale # [bool] True if trajectory_setpoint data is considered stale (exceeded timeout) + +bool active # [bool] True if the Raptor policy is currently active (publishing actuator_motors) +uint8 substep # [-] The policy is trained at a fixed frequency (e.g. 100 Hz) but we might want to use it for control at higher frequencies (e.g. 400 Hz), which leads to a number of intermediate steps before the actual policy state is advanced (in this case 4 = 400 Hz / 100 Hz). This field provides the current substep (e.g. 0-3). +float32 control_interval # [s] Time interval between control updates + +float32 trajectory_setpoint_dt_mean # [us] The average trajectory setpoint arrival time interval (since Raptor mode activation within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) +float32 trajectory_setpoint_dt_max # [us] The max trajectory setpoint arrival time interval (since Raptor mode activation and within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) +float32 trajectory_setpoint_dt_max_since_activation # [us] The max trajectory setpoint arrival time interval (since Raptor mode activation) + +float32[3] internal_reference_position # [m] [@frame FLU] Internal reference position +float32[3] internal_reference_linear_velocity # [m/s] [@frame FLU] Internal reference linear velocity + +# TOPICS raptor_status +``` + +::: diff --git a/docs/en/msg_docs/RateCtrlStatus.md b/docs/en/msg_docs/RateCtrlStatus.md index 28adaafbbd..e6caf8764a 100644 --- a/docs/en/msg_docs/RateCtrlStatus.md +++ b/docs/en/msg_docs/RateCtrlStatus.md @@ -1,8 +1,25 @@ +--- +pageClass: is-wide-page +--- + # RateCtrlStatus (UORB message) +**TOPICS:** rate_ctrlstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RateCtrlStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| rollspeed_integ | `float32` | | | +| pitchspeed_integ | `float32` | | | +| yawspeed_integ | `float32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RateCtrlStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -11,5 +28,6 @@ uint64 timestamp # time since system start (microseconds) float32 rollspeed_integ float32 pitchspeed_integ float32 yawspeed_integ - ``` + +::: diff --git a/docs/en/msg_docs/RcChannels.md b/docs/en/msg_docs/RcChannels.md index 7abb87c0bc..04894fd4c3 100644 --- a/docs/en/msg_docs/RcChannels.md +++ b/docs/en/msg_docs/RcChannels.md @@ -1,6 +1,65 @@ +--- +pageClass: is-wide-page +--- + # RcChannels (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RcChannels.msg) +**TOPICS:** rc_channels + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------- | ------------ | ---------- | ------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_last_valid | `uint64` | | | Timestamp of last valid RC signal | +| channels | `float32[18]` | | | Scaled to -1..1 (throttle: 0..1) | +| channel_count | `uint8` | | | Number of valid channels | +| function | `int8[30]` | | | Functions mapping | +| rssi | `uint8` | | | Receive signal strength index | +| signal_lost | `bool` | | | Control signal lost, should be checked together with topic timeout | +| frame_drop_count | `uint32` | | | Number of dropped frames | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------- | ------- | ----- | ----------- | +| FUNCTION_THROTTLE | `uint8` | 0 | +| FUNCTION_ROLL | `uint8` | 1 | +| FUNCTION_PITCH | `uint8` | 2 | +| FUNCTION_YAW | `uint8` | 3 | +| FUNCTION_RETURN | `uint8` | 4 | +| FUNCTION_LOITER | `uint8` | 5 | +| FUNCTION_OFFBOARD | `uint8` | 6 | +| FUNCTION_FLAPS | `uint8` | 7 | +| FUNCTION_AUX_1 | `uint8` | 8 | +| FUNCTION_AUX_2 | `uint8` | 9 | +| FUNCTION_AUX_3 | `uint8` | 10 | +| FUNCTION_AUX_4 | `uint8` | 11 | +| FUNCTION_AUX_5 | `uint8` | 12 | +| FUNCTION_AUX_6 | `uint8` | 13 | +| FUNCTION_PARAM_1 | `uint8` | 14 | +| FUNCTION_PARAM_2 | `uint8` | 15 | +| FUNCTION_PARAM_3_5 | `uint8` | 16 | +| FUNCTION_KILLSWITCH | `uint8` | 17 | +| FUNCTION_TRANSITION | `uint8` | 18 | +| FUNCTION_GEAR | `uint8` | 19 | +| FUNCTION_ARMSWITCH | `uint8` | 20 | +| FUNCTION_FLTBTN_SLOT_1 | `uint8` | 21 | +| FUNCTION_FLTBTN_SLOT_2 | `uint8` | 22 | +| FUNCTION_FLTBTN_SLOT_3 | `uint8` | 23 | +| FUNCTION_FLTBTN_SLOT_4 | `uint8` | 24 | +| FUNCTION_FLTBTN_SLOT_5 | `uint8` | 25 | +| FUNCTION_FLTBTN_SLOT_6 | `uint8` | 26 | +| FUNCTION_ENGAGE_MAIN_MOTOR | `uint8` | 27 | +| FUNCTION_PAYLOAD_POWER | `uint8` | 28 | +| FUNCTION_TERMINATION | `uint8` | 29 | +| FUNCTION_FLTBTN_SLOT_COUNT | `uint8` | 6 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RcChannels.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -45,5 +104,6 @@ int8[30] function # Functions mapping uint8 rssi # Receive signal strength index bool signal_lost # Control signal lost, should be checked together with topic timeout uint32 frame_drop_count # Number of dropped frames - ``` + +::: diff --git a/docs/en/msg_docs/RcParameterMap.md b/docs/en/msg_docs/RcParameterMap.md index a371149b15..6aff36b48e 100644 --- a/docs/en/msg_docs/RcParameterMap.md +++ b/docs/en/msg_docs/RcParameterMap.md @@ -1,8 +1,36 @@ +--- +pageClass: is-wide-page +--- + # RcParameterMap (UORB message) +**TOPICS:** rc_parametermap +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RcParameterMap.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| valid | `bool[3]` | | | true for RC-Param channels which are mapped to a param | +| param_index | `int32[3]` | | | corresponding param index, this field is ignored if set to -1, in this case param_id will be used | +| param_id | `char[51]` | | | MAP_NCHAN \* (ID_LEN + 1) chars, corresponding param id, null terminated | +| scale | `float32[3]` | | | scale to map the RC input [-1, 1] to a parameter value | +| value0 | `float32[3]` | | | initial value around which the parameter value is changed | +| value_min | `float32[3]` | | | minimal parameter value | +| value_max | `float32[3]` | | | minimal parameter value | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------ | +| RC_PARAM_MAP_NCHAN | `uint8` | 3 | This limit is also hardcoded in the enum RC_CHANNELS_FUNCTION in rc_channels.h | +| PARAM_ID_LEN | `uint8` | 16 | corresponds to MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RcParameterMap.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,5 +44,6 @@ float32[3] scale # scale to map the RC input [-1, 1] to a parameter value float32[3] value0 # initial value around which the parameter value is changed float32[3] value_min # minimal parameter value float32[3] value_max # minimal parameter value - ``` + +::: diff --git a/docs/en/msg_docs/RegisterExtComponentReply.md b/docs/en/msg_docs/RegisterExtComponentReply.md index 31b1b8b00d..09fc14ab9e 100644 --- a/docs/en/msg_docs/RegisterExtComponentReply.md +++ b/docs/en/msg_docs/RegisterExtComponentReply.md @@ -1,11 +1,40 @@ +--- +pageClass: is-wide-page +--- + # RegisterExtComponentReply (UORB message) +**TOPICS:** register_extcomponent_reply +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentReply.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ---------- | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_id | `uint64` | | | ID from the request | +| name | `char[25]` | | | name from the request | +| px4_ros2_api_version | `uint16` | | | +| success | `bool` | | | +| arming_check_id | `int8` | | | arming check registration ID (-1 if invalid) | +| mode_id | `int8` | | | assigned mode ID (-1 if invalid) | +| mode_executor_id | `int8` | | | assigned mode executor ID (-1 if invalid) | +| not_user_selectable | `bool` | | | mode cannot be selected by the user | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentReply.msg) + +::: details Click here to see original file ```c -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -19,6 +48,9 @@ int8 arming_check_id # arming check registration ID (-1 if invalid) int8 mode_id # assigned mode ID (-1 if invalid) int8 mode_executor_id # assigned mode executor ID (-1 if invalid) -uint8 ORB_QUEUE_LENGTH = 2 +bool not_user_selectable # mode cannot be selected by the user +uint8 ORB_QUEUE_LENGTH = 2 ``` + +::: diff --git a/docs/en/msg_docs/RegisterExtComponentReplyV0.md b/docs/en/msg_docs/RegisterExtComponentReplyV0.md new file mode 100644 index 0000000000..c1b28811df --- /dev/null +++ b/docs/en/msg_docs/RegisterExtComponentReplyV0.md @@ -0,0 +1,53 @@ +--- +pageClass: is-wide-page +--- + +# RegisterExtComponentReplyV0 (UORB message) + +**TOPICS:** register_extcomponent_replyv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ---------- | ------------ | ---------- | -------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_id | `uint64` | | | ID from the request | +| name | `char[25]` | | | name from the request | +| px4_ros2_api_version | `uint16` | | | +| success | `bool` | | | +| arming_check_id | `int8` | | | arming check registration ID (-1 if invalid) | +| mode_id | `int8` | | | assigned mode ID (-1 if invalid) | +| mode_executor_id | `int8` | | | assigned mode executor ID (-1 if invalid) | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg) + +::: details Click here to see original file + +```c +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID from the request +char[25] name # name from the request + +uint16 px4_ros2_api_version + +bool success +int8 arming_check_id # arming check registration ID (-1 if invalid) +int8 mode_id # assigned mode ID (-1 if invalid) +int8 mode_executor_id # assigned mode executor ID (-1 if invalid) + +uint8 ORB_QUEUE_LENGTH = 2 +``` + +::: diff --git a/docs/en/msg_docs/RegisterExtComponentRequest.md b/docs/en/msg_docs/RegisterExtComponentRequest.md index 545737c64a..4ac2f32e57 100644 --- a/docs/en/msg_docs/RegisterExtComponentRequest.md +++ b/docs/en/msg_docs/RegisterExtComponentRequest.md @@ -1,13 +1,47 @@ +--- +pageClass: is-wide-page +--- + # RegisterExtComponentRequest (UORB message) -Request to register an external component +Request to register an external component. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentRequest.msg) +**TOPICS:** register_extcomponent_request + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | ---------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_id | `uint64` | | | ID, set this to a random value | +| name | `char[25]` | | | either the requested mode name, or component name | +| px4_ros2_api_version | `uint16` | | | Set to LATEST_PX4_ROS2_API_VERSION | +| register_arming_check | `bool` | | | +| register_mode | `bool` | | | registering a mode also requires arming_check to be set | +| register_mode_executor | `bool` | | | registering an executor also requires a mode to be registered (which is the owned mode by the executor) | +| enable_replace_internal_mode | `bool` | | | set to true if an internal mode should be replaced | +| replace_internal_mode | `uint8` | | | vehicle*status::NAVIGATION_STATE*\* | +| activate_mode_immediately | `bool` | | | switch to the registered mode (can only be set in combination with an executor) | +| not_user_selectable | `bool` | | | mode cannot be selected by the user | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | -------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 1 | +| LATEST_PX4_ROS2_API_VERSION | `uint16` | 1 | API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentRequest.msg) + +::: details Click here to see original file ```c # Request to register an external component -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -26,8 +60,9 @@ bool register_mode_executor # registering an executor also requires a mod bool enable_replace_internal_mode # set to true if an internal mode should be replaced uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) - +bool not_user_selectable # mode cannot be selected by the user uint8 ORB_QUEUE_LENGTH = 2 - ``` + +::: diff --git a/docs/en/msg_docs/RegisterExtComponentRequestV0.md b/docs/en/msg_docs/RegisterExtComponentRequestV0.md new file mode 100644 index 0000000000..469bfdd70b --- /dev/null +++ b/docs/en/msg_docs/RegisterExtComponentRequestV0.md @@ -0,0 +1,67 @@ +--- +pageClass: is-wide-page +--- + +# RegisterExtComponentRequestV0 (UORB message) + +Request to register an external component. + +**TOPICS:** register_extcomponent_requestv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | ---------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| request_id | `uint64` | | | ID, set this to a random value | +| name | `char[25]` | | | either the requested mode name, or component name | +| px4_ros2_api_version | `uint16` | | | Set to LATEST_PX4_ROS2_API_VERSION | +| register_arming_check | `bool` | | | +| register_mode | `bool` | | | registering a mode also requires arming_check to be set | +| register_mode_executor | `bool` | | | registering an executor also requires a mode to be registered (which is the owned mode by the executor) | +| enable_replace_internal_mode | `bool` | | | set to true if an internal mode should be replaced | +| replace_internal_mode | `uint8` | | | vehicle*status::NAVIGATION_STATE*\* | +| activate_mode_immediately | `bool` | | | switch to the registered mode (can only be set in combination with an executor) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------- | -------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| LATEST_PX4_ROS2_API_VERSION | `uint16` | 1 | API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg) + +::: details Click here to see original file + +```c +# Request to register an external component + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID, set this to a random value +char[25] name # either the requested mode name, or component name + +uint16 LATEST_PX4_ROS2_API_VERSION = 1 # API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. + +uint16 px4_ros2_api_version # Set to LATEST_PX4_ROS2_API_VERSION + +# Components to be registered +bool register_arming_check +bool register_mode # registering a mode also requires arming_check to be set +bool register_mode_executor # registering an executor also requires a mode to be registered (which is the owned mode by the executor) + +bool enable_replace_internal_mode # set to true if an internal mode should be replaced +uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* +bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) + + +uint8 ORB_QUEUE_LENGTH = 2 +``` + +::: diff --git a/docs/en/msg_docs/RoverAttitudeSetpoint.md b/docs/en/msg_docs/RoverAttitudeSetpoint.md index bd436278ca..8049e8bfe3 100644 --- a/docs/en/msg_docs/RoverAttitudeSetpoint.md +++ b/docs/en/msg_docs/RoverAttitudeSetpoint.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # RoverAttitudeSetpoint (UORB message) -Rover Attitude Setpoint +Rover Attitude Setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverAttitudeSetpoint.msg) +**TOPICS:** rover_attitudesetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ------------ | ----------------------- | +| timestamp | `uint64` | us | | Time since system start | +| yaw_setpoint | `float32` | rad [NED] | [-inf : inf] | Yaw setpoint | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverAttitudeSetpoint.msg) + +::: details Click here to see original file ```c # Rover Attitude Setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint - +uint64 timestamp # [us] Time since system start +float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint ``` + +::: diff --git a/docs/en/msg_docs/RoverAttitudeStatus.md b/docs/en/msg_docs/RoverAttitudeStatus.md index e6df929abd..a012cd2e17 100644 --- a/docs/en/msg_docs/RoverAttitudeStatus.md +++ b/docs/en/msg_docs/RoverAttitudeStatus.md @@ -1,14 +1,33 @@ +--- +pageClass: is-wide-page +--- + # RoverAttitudeStatus (UORB message) -Rover Attitude Status +Rover Attitude Status. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverAttitudeStatus.msg) +**TOPICS:** rover_attitudestatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | --------- | ------------ | ---------- | ------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| measured_yaw | `float32` | rad [NED] | [-pi : pi] | Measured yaw | +| adjusted_yaw_setpoint | `float32` | rad [NED] | [-pi : pi] | Yaw setpoint that is being tracked (Applied slew rates) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverAttitudeStatus.msg) + +::: details Click here to see original file ```c # Rover Attitude Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw -float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) - +uint64 timestamp # [us] Time since system start +float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw +float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) ``` + +::: diff --git a/docs/en/msg_docs/RoverPositionSetpoint.md b/docs/en/msg_docs/RoverPositionSetpoint.md index b45aa0515f..2a3835c984 100644 --- a/docs/en/msg_docs/RoverPositionSetpoint.md +++ b/docs/en/msg_docs/RoverPositionSetpoint.md @@ -1,17 +1,39 @@ +--- +pageClass: is-wide-page +--- + # RoverPositionSetpoint (UORB message) -Rover Position Setpoint +Rover Position Setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverPositionSetpoint.msg) +**TOPICS:** rover_positionsetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | ------------ | ------------ | ------------ | -------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| position_ned | `float32[2]` | m [NED] | [-inf : inf] | Target position | +| start_ned | `float32[2]` | m [NED] | [-inf : inf] | Start position which specifies a line for the rover to track (Invalid: NaN Defaults to vehicle position) | +| cruising_speed | `float32` | m/s | [0 : inf] | Cruising speed (Invalid: NaN Defaults to maximum speed) | +| arrival_speed | `float32` | m/s | [0 : inf] | Speed the rover should arrive at the target with (Invalid: NaN Defaults to 0) | +| yaw | `float32` | rad [NED] | [-pi : pi] | Mecanum only: Specify vehicle yaw during travel (Invalid: NaN Defaults to vehicle yaw) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverPositionSetpoint.msg) + +::: details Click here to see original file ```c # Rover Position Setpoint -uint64 timestamp # [us] Time since system start -float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position -float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track -float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed -float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with -float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel - +uint64 timestamp # [us] Time since system start +float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position +float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track +float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed +float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with +float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel ``` + +::: diff --git a/docs/en/msg_docs/RoverRateSetpoint.md b/docs/en/msg_docs/RoverRateSetpoint.md index 9bffa41b80..79a2746bcc 100644 --- a/docs/en/msg_docs/RoverRateSetpoint.md +++ b/docs/en/msg_docs/RoverRateSetpoint.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # RoverRateSetpoint (UORB message) -Rover Rate setpoint +Rover Rate setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverRateSetpoint.msg) +**TOPICS:** rover_ratesetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | --------- | ------------ | ------------ | ----------------------- | +| timestamp | `uint64` | us | | Time since system start | +| yaw_rate_setpoint | `float32` | rad/s [NED] | [-inf : inf] | Yaw rate setpoint | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverRateSetpoint.msg) + +::: details Click here to see original file ```c # Rover Rate setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint - +uint64 timestamp # [us] Time since system start +float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint ``` + +::: diff --git a/docs/en/msg_docs/RoverRateStatus.md b/docs/en/msg_docs/RoverRateStatus.md index 684e4c458a..27cb672a32 100644 --- a/docs/en/msg_docs/RoverRateStatus.md +++ b/docs/en/msg_docs/RoverRateStatus.md @@ -1,15 +1,35 @@ +--- +pageClass: is-wide-page +--- + # RoverRateStatus (UORB message) -Rover Rate Status +Rover Rate Status. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverRateStatus.msg) +**TOPICS:** rover_ratestatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------- | --------- | ------------ | ------------ | ------------------------------------------------------------ | +| timestamp | `uint64` | us | | Time since system start | +| measured_yaw_rate | `float32` | rad/s [NED] | [-inf : inf] | Measured yaw rate | +| adjusted_yaw_rate_setpoint | `float32` | rad/s [NED] | [-inf : inf] | Yaw rate setpoint that is being tracked (Applied slew rates) | +| pid_yaw_rate_integral | `float32` | | [-1 : 1] | Integral of the PID for the closed loop yaw rate controller | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverRateStatus.msg) + +::: details Click here to see original file ```c # Rover Rate Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate -float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) -float32 pid_yaw_rate_integral # [] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller - +uint64 timestamp # [us] Time since system start +float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate +float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) +float32 pid_yaw_rate_integral # [-] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller ``` + +::: diff --git a/docs/en/msg_docs/RoverSpeedSetpoint.md b/docs/en/msg_docs/RoverSpeedSetpoint.md new file mode 100644 index 0000000000..63c9e6aeba --- /dev/null +++ b/docs/en/msg_docs/RoverSpeedSetpoint.md @@ -0,0 +1,33 @@ +--- +pageClass: is-wide-page +--- + +# RoverSpeedSetpoint (UORB message) + +Rover Speed Setpoint. + +**TOPICS:** rover_speedsetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ----------------------------------- | ------------------------------------------------------------------------------ | +| timestamp | `uint64` | us | | Time since system start | +| speed_body_x | `float32` | m/s [Body] | [-inf (Backwards) : inf (Forwards)] | Speed setpoint in body x direction | +| speed_body_y | `float32` | m/s [Body] | [-inf (Left) : inf (Right)] | Mecanum only: Speed setpoint in body y direction (Invalid: NaN If not mecanum) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedSetpoint.msg) + +::: details Click here to see original file + +```c +# Rover Speed Setpoint + +uint64 timestamp # [us] Time since system start +float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction +float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction +``` + +::: diff --git a/docs/en/msg_docs/RoverSpeedStatus.md b/docs/en/msg_docs/RoverSpeedStatus.md new file mode 100644 index 0000000000..c0790eb03d --- /dev/null +++ b/docs/en/msg_docs/RoverSpeedStatus.md @@ -0,0 +1,41 @@ +--- +pageClass: is-wide-page +--- + +# RoverSpeedStatus (UORB message) + +Rover Velocity Status. + +**TOPICS:** rover_speedstatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------ | --------- | ------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| measured_speed_body_x | `float32` | m/s [Body] | [-inf (Backwards) : inf (Forwards)] | Measured speed in body x direction | +| adjusted_speed_body_x_setpoint | `float32` | m/s [Body] | [-inf (Backwards) : inf (Forwards)] | Speed setpoint in body x direction that is being tracked (Applied slew rates) | +| pid_throttle_body_x_integral | `float32` | | [-1 : 1] | Integral of the PID for the closed loop controller of the speed in body x direction | +| measured_speed_body_y | `float32` | m/s [Body] | [-inf (Left) : inf (Right)] | Mecanum only: Measured speed in body y direction (Invalid: NaN If not mecanum) | +| adjusted_speed_body_y_setpoint | `float32` | m/s [Body] | [-inf (Left) : inf (Right)] | Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) (Invalid: NaN If not mecanum) | +| pid_throttle_body_y_integral | `float32` | | [-1 : 1] | Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction (Invalid: NaN If not mecanum) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedStatus.msg) + +::: details Click here to see original file + +```c +# Rover Velocity Status + +uint64 timestamp # [us] Time since system start +float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction +float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_x_integral # [-] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction +float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction +float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_y_integral # [-] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction +``` + +::: diff --git a/docs/en/msg_docs/RoverSteeringSetpoint.md b/docs/en/msg_docs/RoverSteeringSetpoint.md index 3e40a3986b..b87ea4c311 100644 --- a/docs/en/msg_docs/RoverSteeringSetpoint.md +++ b/docs/en/msg_docs/RoverSteeringSetpoint.md @@ -1,13 +1,31 @@ +--- +pageClass: is-wide-page +--- + # RoverSteeringSetpoint (UORB message) -Rover Steering setpoint +Rover Steering setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSteeringSetpoint.msg) +**TOPICS:** rover_steeringsetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | --------- | ------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| normalized_steering_setpoint | `float32` | [Body] | [-1 (Left) : 1 (Right)] | Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSteeringSetpoint.msg) + +::: details Click here to see original file ```c # Rover Steering setpoint -uint64 timestamp # [us] Time since system start -float32 normalized_steering_setpoint # [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels - +uint64 timestamp # [us] Time since system start +float32 normalized_steering_setpoint # [-] [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels ``` + +::: diff --git a/docs/en/msg_docs/RoverThrottleSetpoint.md b/docs/en/msg_docs/RoverThrottleSetpoint.md index f1c4f7f653..22a459eb82 100644 --- a/docs/en/msg_docs/RoverThrottleSetpoint.md +++ b/docs/en/msg_docs/RoverThrottleSetpoint.md @@ -1,14 +1,33 @@ +--- +pageClass: is-wide-page +--- + # RoverThrottleSetpoint (UORB message) -Rover Throttle setpoint +Rover Throttle setpoint. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverThrottleSetpoint.msg) +**TOPICS:** rover_throttlesetpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | --------- | ------------ | ------------------------------- | ------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| throttle_body_x | `float32` | [Body] | [-1 (Backwards) : 1 (Forwards)] | Throttle setpoint along body X axis | +| throttle_body_y | `float32` | [Body] | [-1 (Left) : 1 (Right)] | Mecanum only: Throttle setpoint along body Y axis (Invalid: NaN If not mecanum) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverThrottleSetpoint.msg) + +::: details Click here to see original file ```c # Rover Throttle setpoint -uint64 timestamp # [us] Time since system start -float32 throttle_body_x # [] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis -float32 throttle_body_y # [] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis - +uint64 timestamp # [us] Time since system start +float32 throttle_body_x # [-] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis +float32 throttle_body_y # [-] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis ``` + +::: diff --git a/docs/en/msg_docs/RoverVelocitySetpoint.md b/docs/en/msg_docs/RoverVelocitySetpoint.md deleted file mode 100644 index 65103082b8..0000000000 --- a/docs/en/msg_docs/RoverVelocitySetpoint.md +++ /dev/null @@ -1,15 +0,0 @@ -# RoverVelocitySetpoint (UORB message) - -Rover Velocity Setpoint - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocitySetpoint.msg) - -```c -# Rover Velocity Setpoint - -uint64 timestamp # [us] Time since system start -float32 speed # [m/s] [@range -inf (Backwards), inf (Forwards)] Speed setpoint -float32 bearing # [rad] [@range -pi,pi] [@frame NED] [@invalid: NaN, speed is defined in body x direction] Bearing setpoint -float32 yaw # [rad] [@range -pi, pi] [@frame NED] [@invalid NaN, Defaults to vehicle yaw] Mecanum only: Yaw setpoint - -``` diff --git a/docs/en/msg_docs/RoverVelocityStatus.md b/docs/en/msg_docs/RoverVelocityStatus.md deleted file mode 100644 index dfd7756afa..0000000000 --- a/docs/en/msg_docs/RoverVelocityStatus.md +++ /dev/null @@ -1,18 +0,0 @@ -# RoverVelocityStatus (UORB message) - -Rover Velocity Status - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocityStatus.msg) - -```c -# Rover Velocity Status - -uint64 timestamp # [us] Time since system start -float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction -float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_x_integral # [] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction -float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction -float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_y_integral # [] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction - -``` diff --git a/docs/en/msg_docs/Rpm.md b/docs/en/msg_docs/Rpm.md index edf6c37e19..a2ad43c153 100644 --- a/docs/en/msg_docs/Rpm.md +++ b/docs/en/msg_docs/Rpm.md @@ -1,8 +1,24 @@ +--- +pageClass: is-wide-page +--- + # Rpm (UORB message) +**TOPICS:** rpm +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Rpm.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| rpm_estimate | `float32` | | | filtered revolutions per minute | +| rpm_raw | `float32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Rpm.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +26,6 @@ uint64 timestamp # time since system start (microseconds) # rpm values of 0.0 mean within a timeout there is no movement measured float32 rpm_estimate # filtered revolutions per minute float32 rpm_raw - ``` + +::: diff --git a/docs/en/msg_docs/RtlStatus.md b/docs/en/msg_docs/RtlStatus.md index 299b6f4b16..ea1da9648c 100644 --- a/docs/en/msg_docs/RtlStatus.md +++ b/docs/en/msg_docs/RtlStatus.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # RtlStatus (UORB message) +**TOPICS:** rtl_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RtlStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | -------- | ------------ | ---------- | -------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| safe_points_id | `uint32` | | | unique ID of active set of safe_point_items | +| is_evaluation_pending | `bool` | | | flag if the RTL point needs reevaluation (e.g. new safe points available, but need loading). | +| has_vtol_approach | `bool` | | | flag if approaches are defined for current RTL_TYPE parameter setting | +| rtl_type | `uint8` | | | Type of RTL chosen | +| safe_point_index | `uint8` | | | index of the chosen safe point, if in RTL_STATUS_TYPE_DIRECT_SAFE_POINT mode | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------------- | ------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RTL_STATUS_TYPE_NONE | `uint8` | 0 | pending if evaluation can't pe performed currently e.g. when it is still loading the safe points | +| RTL_STATUS_TYPE_DIRECT_SAFE_POINT | `uint8` | 1 | chosen to directly go to a safe point or home position | +| RTL_STATUS_TYPE_DIRECT_MISSION_LAND | `uint8` | 2 | going straight to the beginning of the mission landing | +| RTL_STATUS_TYPE_FOLLOW_MISSION | `uint8` | 3 | Following the mission from start index to mission landing. Start index is current WP if in Mission mode, and closest WP otherwise. | +| RTL_STATUS_TYPE_FOLLOW_MISSION_REVERSE | `uint8` | 4 | Following the mission in reverse from start index to the beginning of the mission. Start index is previous WP if in Mission mode, and closest WP otherwise. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RtlStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -20,5 +49,6 @@ uint8 RTL_STATUS_TYPE_DIRECT_SAFE_POINT=1 # chosen to directly go to a safe poi uint8 RTL_STATUS_TYPE_DIRECT_MISSION_LAND=2 # going straight to the beginning of the mission landing uint8 RTL_STATUS_TYPE_FOLLOW_MISSION=3 # Following the mission from start index to mission landing. Start index is current WP if in Mission mode, and closest WP otherwise. uint8 RTL_STATUS_TYPE_FOLLOW_MISSION_REVERSE=4 # Following the mission in reverse from start index to the beginning of the mission. Start index is previous WP if in Mission mode, and closest WP otherwise. - ``` + +::: diff --git a/docs/en/msg_docs/RtlTimeEstimate.md b/docs/en/msg_docs/RtlTimeEstimate.md index 14dbe31594..894fe4589c 100644 --- a/docs/en/msg_docs/RtlTimeEstimate.md +++ b/docs/en/msg_docs/RtlTimeEstimate.md @@ -1,8 +1,25 @@ +--- +pageClass: is-wide-page +--- + # RtlTimeEstimate (UORB message) +**TOPICS:** rtl_timeestimate +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RtlTimeEstimate.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | --------- | ------------ | ---------- | --------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| valid | `bool` | | | Flag indicating whether the time estiamtes are valid | +| time_estimate | `float32` | s | | Estimated time for RTL | +| safe_time_estimate | `float32` | s | | Same as time_estimate, but with safety factor and safety margin included (factor\*t + margin) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RtlTimeEstimate.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +27,6 @@ uint64 timestamp # time since system start (microseconds) bool valid # Flag indicating whether the time estiamtes are valid float32 time_estimate # [s] Estimated time for RTL float32 safe_time_estimate # [s] Same as time_estimate, but with safety factor and safety margin included (factor*t + margin) - ``` + +::: diff --git a/docs/en/msg_docs/SatelliteInfo.md b/docs/en/msg_docs/SatelliteInfo.md index c040856148..af1587d7a6 100644 --- a/docs/en/msg_docs/SatelliteInfo.md +++ b/docs/en/msg_docs/SatelliteInfo.md @@ -1,6 +1,35 @@ +--- +pageClass: is-wide-page +--- + # SatelliteInfo (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SatelliteInfo.msg) +**TOPICS:** satellite_info + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | ----------- | ------------ | ---------- | -------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| count | `uint8` | | | Number of satellites visible to the receiver | +| svid | `uint8[40]` | | | Space vehicle ID [1..255], see scheme below | +| used | `uint8[40]` | | | 0: Satellite not used, 1: used for navigation | +| elevation | `uint8[40]` | | | Elevation (0: right on top of receiver, 90: on the horizon) of satellite | +| azimuth | `uint8[40]` | | | Direction of satellite, 0: 0 deg, 255: 360 deg. | +| snr | `uint8[40]` | | | dBHz, Signal to noise ratio of satellite C/N0, range 0..99, zero when not tracking this satellite. | +| prn | `uint8[40]` | | | Satellite PRN code assignment, (psuedorandom number SBAS, valid codes are 120-144) | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | ----------- | +| SAT_INFO_MAX_SATELLITES | `uint8` | 40 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SatelliteInfo.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +42,6 @@ uint8[40] elevation # Elevation (0: right on top of receiver, 90: on the horizo uint8[40] azimuth # Direction of satellite, 0: 0 deg, 255: 360 deg. uint8[40] snr # dBHz, Signal to noise ratio of satellite C/N0, range 0..99, zero when not tracking this satellite. uint8[40] prn # Satellite PRN code assignment, (psuedorandom number SBAS, valid codes are 120-144) - ``` + +::: diff --git a/docs/en/msg_docs/SensorAccel.md b/docs/en/msg_docs/SensorAccel.md index 50e0c9f240..5c34986404 100644 --- a/docs/en/msg_docs/SensorAccel.md +++ b/docs/en/msg_docs/SensorAccel.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # SensorAccel (UORB message) +**TOPICS:** sensor_accel +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAccel.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| x | `float32` | | | acceleration in the FRD board frame X-axis in m/s^2 | +| y | `float32` | | | acceleration in the FRD board frame Y-axis in m/s^2 | +| z | `float32` | | | acceleration in the FRD board frame Z-axis in m/s^2 | +| temperature | `float32` | | | temperature in degrees Celsius | +| error_count | `uint32` | | | +| clip_counter | `uint8[3]` | | | clip count per axis in the sample period | +| samples | `uint8` | | | number of raw samples that went into this message | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAccel.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -23,5 +52,6 @@ uint8[3] clip_counter # clip count per axis in the sample period uint8 samples # number of raw samples that went into this message uint8 ORB_QUEUE_LENGTH = 8 - ``` + +::: diff --git a/docs/en/msg_docs/SensorAccelFifo.md b/docs/en/msg_docs/SensorAccelFifo.md index b624951f07..beebee2315 100644 --- a/docs/en/msg_docs/SensorAccelFifo.md +++ b/docs/en/msg_docs/SensorAccelFifo.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # SensorAccelFifo (UORB message) +**TOPICS:** sensor_accelfifo +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAccelFifo.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| dt | `float32` | | | delta time between samples (microseconds) | +| scale | `float32` | | | +| samples | `uint8` | | | number of valid samples | +| x | `int16[32]` | | | acceleration in the FRD board frame X-axis in m/s^2 | +| y | `int16[32]` | | | acceleration in the FRD board frame Y-axis in m/s^2 | +| z | `int16[32]` | | | acceleration in the FRD board frame Z-axis in m/s^2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAccelFifo.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -18,5 +40,6 @@ uint8 samples # number of valid samples int16[32] x # acceleration in the FRD board frame X-axis in m/s^2 int16[32] y # acceleration in the FRD board frame Y-axis in m/s^2 int16[32] z # acceleration in the FRD board frame Z-axis in m/s^2 - ``` + +::: diff --git a/docs/en/msg_docs/SensorAirflow.md b/docs/en/msg_docs/SensorAirflow.md index 72bdd43e2c..05b066c70e 100644 --- a/docs/en/msg_docs/SensorAirflow.md +++ b/docs/en/msg_docs/SensorAirflow.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # SensorAirflow (UORB message) +**TOPICS:** sensor_airflow +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAirflow.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| speed | `float32` | | | the speed being reported by the wind / airflow sensor | +| direction | `float32` | | | the direction being reported by the wind / airflow sensor | +| status | `uint8` | | | Status code from the sensor | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorAirflow.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +28,6 @@ uint32 device_id # unique device ID for the sensor that does not float32 speed # the speed being reported by the wind / airflow sensor float32 direction # the direction being reported by the wind / airflow sensor uint8 status # Status code from the sensor - ``` + +::: diff --git a/docs/en/msg_docs/SensorBaro.md b/docs/en/msg_docs/SensorBaro.md index 8a3c364f60..22038554af 100644 --- a/docs/en/msg_docs/SensorBaro.md +++ b/docs/en/msg_docs/SensorBaro.md @@ -1,21 +1,54 @@ +--- +pageClass: is-wide-page +--- + # SensorBaro (UORB message) +Barometer sensor. +This is populated by barometer drivers and used by the EKF2 estimator. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorBaro.msg) +**TOPICS:** sensor_baro + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time of publication (since system start) | +| timestamp_sample | `uint64` | us | | Time of raw data capture | +| device_id | `uint32` | | | Unique device ID for the sensor that does not change between power cycles | +| pressure | `float32` | Pa | | Static pressure measurement | +| temperature | `float32` | degC | | Temperature. | +| error_count | `uint32` | | | Number of errors detected by driver. | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorBaro.msg) + +::: details Click here to see original file ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Barometer sensor +# +# This is populated by barometer drivers and used by the EKF2 estimator. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 pressure # static pressure measurement in Pascals - -float32 temperature # temperature in degrees Celsius - -uint32 error_count +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 pressure # [Pa] Static pressure measurement +float32 temperature # [degC] Temperature. +uint32 error_count # [-] Number of errors detected by driver. uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/SensorCombined.md b/docs/en/msg_docs/SensorCombined.md index 29a22b6326..e04c3fcab4 100644 --- a/docs/en/msg_docs/SensorCombined.md +++ b/docs/en/msg_docs/SensorCombined.md @@ -1,10 +1,42 @@ +--- +pageClass: is-wide-page +--- + # SensorCombined (UORB message) -Sensor readings in SI-unit form. -These fields are scaled and offset-compensated where possible and do not -change with board revisions and sensor updates. +Sensor readings in SI-unit form. These fields are scaled and offset-compensated where possible and do not. change with board revisions and sensor updates. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorCombined.msg) +**TOPICS:** sensor_combined + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------------- | ------------ | ------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| gyro_rad | `float32[3]` | | | average angular rate measured in the FRD body frame XYZ-axis in rad/s over the last gyro sampling period | +| gyro_integral_dt | `uint32` | | | gyro measurement sampling period in microseconds | +| accelerometer_timestamp_relative | `int32` | | | timestamp + accelerometer_timestamp_relative = Accelerometer timestamp | +| accelerometer_m_s2 | `float32[3]` | | | average value acceleration measured in the FRD body frame XYZ-axis in m/s^2 over the last accelerometer sampling period | +| accelerometer_integral_dt | `uint32` | | | accelerometer measurement sampling period in microseconds | +| accelerometer_clipping | `uint8` | | | bitfield indicating if there was any accelerometer clipping (per axis) during the integration time frame | +| gyro_clipping | `uint8` | | | bitfield indicating if there was any gyro clipping (per axis) during the integration time frame | +| accel_calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever accelermeter calibration changes. | +| gyro_calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever rate gyro calibration changes. | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------- | ------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| RELATIVE_TIMESTAMP_INVALID | `int32` | 2147483647 | (0x7fffffff) If one of the relative timestamps is set to this value, it means the associated sensor values are invalid | +| CLIPPING_X | `uint8` | 1 | +| CLIPPING_Y | `uint8` | 2 | +| CLIPPING_Z | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorCombined.msg) + +::: details Click here to see original file ```c # Sensor readings in SI-unit form. @@ -32,5 +64,6 @@ uint8 gyro_clipping # bitfield indicating if there was any gyro clip uint8 accel_calibration_count # Calibration changed counter. Monotonically increases whenever accelermeter calibration changes. uint8 gyro_calibration_count # Calibration changed counter. Monotonically increases whenever rate gyro calibration changes. - ``` + +::: diff --git a/docs/en/msg_docs/SensorCorrection.md b/docs/en/msg_docs/SensorCorrection.md index 8c9cfbb9d2..649fbf5714 100644 --- a/docs/en/msg_docs/SensorCorrection.md +++ b/docs/en/msg_docs/SensorCorrection.md @@ -1,8 +1,48 @@ +--- +pageClass: is-wide-page +--- + # SensorCorrection (UORB message) -Sensor corrections in SI-unit form for the voted sensor +Sensor corrections in SI-unit form for the voted sensor. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorCorrection.msg) +**TOPICS:** sensor_correction + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| accel_device_ids | `uint32[4]` | | | +| accel_temperature | `float32[4]` | | | +| accel_offset_0 | `float32[3]` | | | accelerometer 0 offsets in the FRD board frame XYZ-axis in m/s^s | +| accel_offset_1 | `float32[3]` | | | accelerometer 1 offsets in the FRD board frame XYZ-axis in m/s^s | +| accel_offset_2 | `float32[3]` | | | accelerometer 2 offsets in the FRD board frame XYZ-axis in m/s^s | +| accel_offset_3 | `float32[3]` | | | accelerometer 3 offsets in the FRD board frame XYZ-axis in m/s^s | +| gyro_device_ids | `uint32[4]` | | | +| gyro_temperature | `float32[4]` | | | +| gyro_offset_0 | `float32[3]` | | | gyro 0 XYZ offsets in the sensor frame in rad/s | +| gyro_offset_1 | `float32[3]` | | | gyro 1 XYZ offsets in the sensor frame in rad/s | +| gyro_offset_2 | `float32[3]` | | | gyro 2 XYZ offsets in the sensor frame in rad/s | +| gyro_offset_3 | `float32[3]` | | | gyro 3 XYZ offsets in the sensor frame in rad/s | +| mag_device_ids | `uint32[4]` | | | +| mag_temperature | `float32[4]` | | | +| mag_offset_0 | `float32[3]` | | | magnetometer 0 offsets in the FRD board frame XYZ-axis in m/s^s | +| mag_offset_1 | `float32[3]` | | | magnetometer 1 offsets in the FRD board frame XYZ-axis in m/s^s | +| mag_offset_2 | `float32[3]` | | | magnetometer 2 offsets in the FRD board frame XYZ-axis in m/s^s | +| mag_offset_3 | `float32[3]` | | | magnetometer 3 offsets in the FRD board frame XYZ-axis in m/s^s | +| baro_device_ids | `uint32[4]` | | | +| baro_temperature | `float32[4]` | | | +| baro_offset_0 | `float32` | | | barometric pressure 0 offsets in the sensor frame in Pascals | +| baro_offset_1 | `float32` | | | barometric pressure 1 offsets in the sensor frame in Pascals | +| baro_offset_2 | `float32` | | | barometric pressure 2 offsets in the sensor frame in Pascals | +| baro_offset_3 | `float32` | | | barometric pressure 3 offsets in the sensor frame in Pascals | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorCorrection.msg) + +::: details Click here to see original file ```c # @@ -46,5 +86,6 @@ float32 baro_offset_0 # barometric pressure 0 offsets in the sensor frame in Pa float32 baro_offset_1 # barometric pressure 1 offsets in the sensor frame in Pascals float32 baro_offset_2 # barometric pressure 2 offsets in the sensor frame in Pascals float32 baro_offset_3 # barometric pressure 3 offsets in the sensor frame in Pascals - ``` + +::: diff --git a/docs/en/msg_docs/SensorGnssRelative.md b/docs/en/msg_docs/SensorGnssRelative.md index 639e7897f5..e00e872113 100644 --- a/docs/en/msg_docs/SensorGnssRelative.md +++ b/docs/en/msg_docs/SensorGnssRelative.md @@ -1,8 +1,44 @@ +--- +pageClass: is-wide-page +--- + # SensorGnssRelative (UORB message) GNSS relative positioning information in NED frame. The NED frame is defined as the local topological system at the reference station. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssRelative.msg) +**TOPICS:** sensor_gnssrelative + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| time_utc_usec | `uint64` | | | Timestamp (microseconds, UTC), this is the timestamp which comes from the gps module. It might be unavailable right after cold start, indicated by a value of 0 | +| reference_station_id | `uint16` | | | Reference Station ID | +| position | `float32[3]` | | | GPS NED relative position vector (m) | +| position_accuracy | `float32[3]` | | | Accuracy of relative position (m) | +| heading | `float32` | | | Heading of the relative position vector (radians) | +| heading_accuracy | `float32` | | | Accuracy of heading of the relative position vector (radians) | +| position_length | `float32` | | | Length of the position vector (m) | +| accuracy_length | `float32` | | | Accuracy of the position length (m) | +| gnss_fix_ok | `bool` | | | GNSS valid fix (i.e within DOP & accuracy masks) | +| differential_solution | `bool` | | | differential corrections were applied | +| relative_position_valid | `bool` | | | +| carrier_solution_floating | `bool` | | | carrier phase range solution with floating ambiguities | +| carrier_solution_fixed | `bool` | | | carrier phase range solution with fixed ambiguities | +| moving_base_mode | `bool` | | | if the receiver is operating in moving base mode | +| reference_position_miss | `bool` | | | extrapolated reference position was used to compute moving base solution this epoch | +| reference_observations_miss | `bool` | | | extrapolated reference observations were used to compute moving base solution this epoch | +| heading_valid | `bool` | | | +| relative_position_normalized | `bool` | | | the components of the relative position vector (including the high-precision parts) are normalized | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssRelative.msg) + +::: details Click here to see original file ```c # GNSS relative positioning information in NED frame. The NED frame is defined as the local topological system at the reference station. @@ -35,5 +71,6 @@ bool reference_position_miss # extrapolated reference position was used to bool reference_observations_miss # extrapolated reference observations were used to compute moving base solution this epoch bool heading_valid bool relative_position_normalized # the components of the relative position vector (including the high-precision parts) are normalized - ``` + +::: diff --git a/docs/en/msg_docs/SensorGnssStatus.md b/docs/en/msg_docs/SensorGnssStatus.md new file mode 100644 index 0000000000..e4e40b948d --- /dev/null +++ b/docs/en/msg_docs/SensorGnssStatus.md @@ -0,0 +1,42 @@ +--- +pageClass: is-wide-page +--- + +# SensorGnssStatus (UORB message) + +Gnss quality indicators. + +**TOPICS:** sensor_gnssstatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | -------- | ------------ | ----------------------------------------------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| `bool` | | | Set to true if quality indicators are available | +| quality_corrections | `uint8` | | | Corrections quality from 0 to 10, or 255 if not available | +| quality_receiver | `uint8` | | | Overall receiver operating status from 0 to 10, or 255 if not available | +| quality_gnss_signals | `uint8` | | | Quality of GNSS signals from 0 to 10, or 255 if not available | +| quality_post_processing | `uint8` | | | Expected post processing quality from 0 to 10, or 255 if not available | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssStatus.msg) + +::: details Click here to see original file + +```c +# Gnss quality indicators + +uint64 timestamp # time since system start (microseconds) +uint32 device_id # unique device ID for the sensor that does not change between power cycles + +bool quality_available # Set to true if quality indicators are available +uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available +uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available +uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available +uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available +``` + +::: diff --git a/docs/en/msg_docs/SensorGps.md b/docs/en/msg_docs/SensorGps.md index c8d09e9472..4c8b3c58ab 100644 --- a/docs/en/msg_docs/SensorGps.md +++ b/docs/en/msg_docs/SensorGps.md @@ -1,9 +1,96 @@ +--- +pageClass: is-wide-page +--- + # SensorGps (UORB message) -GPS position in WGS84 coordinates. -the field 'timestamp' is for the position & velocity (microseconds) +GPS position in WGS84 coordinates. the field 'timestamp' is for the position & velocity (microseconds). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGps.msg) +**TOPICS:** sensor_gps vehicle_gps_position + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | --------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| latitude_deg | `float64` | | | Latitude in degrees, allows centimeter level RTK precision | +| longitude_deg | `float64` | | | Longitude in degrees, allows centimeter level RTK precision | +| altitude_msl_m | `float64` | | | Altitude above MSL, meters | +| altitude_ellipsoid_m | `float64` | | | Altitude above Ellipsoid, meters | +| s_variance_m_s | `float32` | | | GPS speed accuracy estimate, (metres/sec) | +| c_variance_rad | `float32` | | | GPS course accuracy estimate, (radians) | +| fix_type | `uint8` | | | Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. | +| eph | `float32` | | | GPS horizontal position accuracy (metres) | +| epv | `float32` | | | GPS vertical position accuracy (metres) | +| hdop | `float32` | | | Horizontal dilution of precision | +| vdop | `float32` | | | Vertical dilution of precision | +| noise_per_ms | `int32` | | | GPS noise per millisecond | +| automatic_gain_control | `uint16` | | | Automatic gain control monitor | +| jamming_state | `uint8` | | | indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected | +| jamming_indicator | `int32` | | | indicates jamming is occurring | +| spoofing_state | `uint8` | | | indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected | +| authentication_state | `uint8` | | | GPS signal authentication state | +| vel_m_s | `float32` | | | GPS ground speed, (metres/sec) | +| vel_n_m_s | `float32` | | | GPS North velocity, (metres/sec) | +| vel_e_m_s | `float32` | | | GPS East velocity, (metres/sec) | +| vel_d_m_s | `float32` | | | GPS Down velocity, (metres/sec) | +| cog_rad | `float32` | | | Course over ground (NOT heading, but direction of movement), -PI..PI, (radians) | +| vel_ned_valid | `bool` | | | True if NED velocity is valid | +| timestamp_time_relative | `int32` | | | timestamp + timestamp_time_relative = Time of the UTC timestamp since system start, (microseconds) | +| time_utc_usec | `uint64` | | | Timestamp (microseconds, UTC), this is the timestamp which comes from the gps module. It might be unavailable right after cold start, indicated by a value of 0 | +| satellites_used | `uint8` | | | Number of satellites used | +| system_error | `uint32` | | | General errors with the connected GPS receiver | +| heading | `float32` | | | heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) | +| heading_offset | `float32` | | | heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) | +| heading_accuracy | `float32` | | | heading accuracy (rad, [0, 2PI]) | +| rtcm_injection_rate | `float32` | | | RTCM message injection rate Hz | +| selected_rtcm_instance | `uint8` | | | uorb instance that is being used for RTCM corrections | +| rtcm_crc_failed | `bool` | | | RTCM message CRC failure detected | +| rtcm_msg_used | `uint8` | | | Indicates if the RTCM message was used successfully by the receiver | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------ | +| FIX_TYPE_NONE | `uint8` | 1 | Value 0 is also valid to represent no fix. | +| FIX_TYPE_2D | `uint8` | 2 | +| FIX_TYPE_3D | `uint8` | 3 | +| FIX_TYPE_RTCM_CODE_DIFFERENTIAL | `uint8` | 4 | +| FIX_TYPE_RTK_FLOAT | `uint8` | 5 | +| FIX_TYPE_RTK_FIXED | `uint8` | 6 | +| FIX_TYPE_EXTRAPOLATED | `uint8` | 8 | +| JAMMING_STATE_UNKNOWN | `uint8` | 0 | default | +| JAMMING_STATE_OK | `uint8` | 1 | +| JAMMING_STATE_MITIGATED | `uint8` | 2 | +| JAMMING_STATE_DETECTED | `uint8` | 3 | +| SPOOFING_STATE_UNKNOWN | `uint8` | 0 | default | +| SPOOFING_STATE_OK | `uint8` | 1 | +| SPOOFING_STATE_MITIGATED | `uint8` | 2 | +| SPOOFING_STATE_DETECTED | `uint8` | 3 | +| AUTHENTICATION_STATE_UNKNOWN | `uint8` | 0 | default | +| AUTHENTICATION_STATE_INITIALIZING | `uint8` | 1 | +| AUTHENTICATION_STATE_ERROR | `uint8` | 2 | +| AUTHENTICATION_STATE_OK | `uint8` | 3 | +| AUTHENTICATION_STATE_DISABLED | `uint8` | 4 | +| SYSTEM_ERROR_OK | `uint32` | 0 | default | +| SYSTEM_ERROR_INCOMING_CORRECTIONS | `uint32` | 1 | +| SYSTEM_ERROR_CONFIGURATION | `uint32` | 2 | +| SYSTEM_ERROR_SOFTWARE | `uint32` | 4 | +| SYSTEM_ERROR_ANTENNA | `uint32` | 8 | +| SYSTEM_ERROR_EVENT_CONGESTION | `uint32` | 16 | +| SYSTEM_ERROR_CPU_OVERLOAD | `uint32` | 32 | +| SYSTEM_ERROR_OUTPUT_CONGESTION | `uint32` | 64 | +| RTCM_MSG_USED_UNKNOWN | `uint8` | 0 | +| RTCM_MSG_USED_NOT_USED | `uint8` | 1 | +| RTCM_MSG_USED_USED | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGps.msg) + +::: details Click here to see original file ```c # GPS position in WGS84 coordinates. @@ -38,18 +125,26 @@ float32 vdop # Vertical dilution of precision int32 noise_per_ms # GPS noise per millisecond uint16 automatic_gain_control # Automatic gain control monitor -uint8 JAMMING_STATE_UNKNOWN = 0 -uint8 JAMMING_STATE_OK = 1 -uint8 JAMMING_STATE_WARNING = 2 -uint8 JAMMING_STATE_CRITICAL = 3 -uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical -int32 jamming_indicator # indicates jamming is occurring +uint8 JAMMING_STATE_UNKNOWN = 0 #default +uint8 JAMMING_STATE_OK = 1 +uint8 JAMMING_STATE_MITIGATED = 2 +uint8 JAMMING_STATE_DETECTED = 3 +uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected +int32 jamming_indicator # indicates jamming is occurring -uint8 SPOOFING_STATE_UNKNOWN = 0 -uint8 SPOOFING_STATE_NONE = 1 -uint8 SPOOFING_STATE_INDICATED = 2 -uint8 SPOOFING_STATE_MULTIPLE = 3 -uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical +uint8 SPOOFING_STATE_UNKNOWN = 0 #default +uint8 SPOOFING_STATE_OK = 1 +uint8 SPOOFING_STATE_MITIGATED = 2 +uint8 SPOOFING_STATE_DETECTED = 3 +uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected + +# Combined authentication state (e.g. Galileo OSNMA) +uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default +uint8 AUTHENTICATION_STATE_INITIALIZING = 1 +uint8 AUTHENTICATION_STATE_ERROR = 2 +uint8 AUTHENTICATION_STATE_OK = 3 +uint8 AUTHENTICATION_STATE_DISABLED = 4 +uint8 authentication_state # GPS signal authentication state float32 vel_m_s # GPS ground speed, (metres/sec) float32 vel_n_m_s # GPS North velocity, (metres/sec) @@ -63,6 +158,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi uint8 satellites_used # Number of satellites used +uint32 SYSTEM_ERROR_OK = 0 #default +uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1 +uint32 SYSTEM_ERROR_CONFIGURATION = 2 +uint32 SYSTEM_ERROR_SOFTWARE = 4 +uint32 SYSTEM_ERROR_ANTENNA = 8 +uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16 +uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32 +uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64 +uint32 system_error # General errors with the connected GPS receiver + float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) float32 heading_accuracy # heading accuracy (rad, [0, 2PI]) @@ -78,5 +183,6 @@ uint8 RTCM_MSG_USED_USED = 2 uint8 rtcm_msg_used # Indicates if the RTCM message was used successfully by the receiver # TOPICS sensor_gps vehicle_gps_position - ``` + +::: diff --git a/docs/en/msg_docs/SensorGyro.md b/docs/en/msg_docs/SensorGyro.md index d55d2f44c2..aea82546dd 100644 --- a/docs/en/msg_docs/SensorGyro.md +++ b/docs/en/msg_docs/SensorGyro.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # SensorGyro (UORB message) +**TOPICS:** sensor_gyro +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyro.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| x | `float32` | | | angular velocity in the FRD board frame X-axis in rad/s | +| y | `float32` | | | angular velocity in the FRD board frame Y-axis in rad/s | +| z | `float32` | | | angular velocity in the FRD board frame Z-axis in rad/s | +| temperature | `float32` | | | temperature in degrees Celsius | +| error_count | `uint32` | | | +| clip_counter | `uint8[3]` | | | clip count per axis in the sample period | +| samples | `uint8` | | | number of raw samples that went into this message | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyro.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -23,5 +52,6 @@ uint8[3] clip_counter # clip count per axis in the sample period uint8 samples # number of raw samples that went into this message uint8 ORB_QUEUE_LENGTH = 8 - ``` + +::: diff --git a/docs/en/msg_docs/SensorGyroFft.md b/docs/en/msg_docs/SensorGyroFft.md index 279c2428ae..b3edd2e04c 100644 --- a/docs/en/msg_docs/SensorGyroFft.md +++ b/docs/en/msg_docs/SensorGyroFft.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # SensorGyroFft (UORB message) +**TOPICS:** sensor_gyrofft +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyroFft.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| sensor_sample_rate_hz | `float32` | | | +| resolution_hz | `float32` | | | +| peak_frequencies_x | `float32[3]` | | | x axis peak frequencies | +| peak_frequencies_y | `float32[3]` | | | y axis peak frequencies | +| peak_frequencies_z | `float32[3]` | | | z axis peak frequencies | +| peak_snr_x | `float32[3]` | | | x axis peak SNR | +| peak_snr_y | `float32[3]` | | | y axis peak SNR | +| peak_snr_z | `float32[3]` | | | z axis peak SNR | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyroFft.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -20,5 +44,6 @@ float32[3] peak_frequencies_z # z axis peak frequencies float32[3] peak_snr_x # x axis peak SNR float32[3] peak_snr_y # y axis peak SNR float32[3] peak_snr_z # z axis peak SNR - ``` + +::: diff --git a/docs/en/msg_docs/SensorGyroFifo.md b/docs/en/msg_docs/SensorGyroFifo.md index 3de5eff4d8..34bf270e90 100644 --- a/docs/en/msg_docs/SensorGyroFifo.md +++ b/docs/en/msg_docs/SensorGyroFifo.md @@ -1,8 +1,36 @@ +--- +pageClass: is-wide-page +--- + # SensorGyroFifo (UORB message) +**TOPICS:** sensor_gyrofifo +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyroFifo.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ----------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| dt | `float32` | | | delta time between samples (microseconds) | +| scale | `float32` | | | +| samples | `uint8` | | | number of valid samples | +| x | `int16[32]` | | | angular velocity in the FRD board frame X-axis in rad/s | +| y | `int16[32]` | | | angular velocity in the FRD board frame Y-axis in rad/s | +| z | `int16[32]` | | | angular velocity in the FRD board frame Z-axis in rad/s | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGyroFifo.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -20,5 +48,6 @@ int16[32] y # angular velocity in the FRD board frame Y-axis in ra int16[32] z # angular velocity in the FRD board frame Z-axis in rad/s uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/SensorHygrometer.md b/docs/en/msg_docs/SensorHygrometer.md index 34bedf9ae9..0d86c2d9ba 100644 --- a/docs/en/msg_docs/SensorHygrometer.md +++ b/docs/en/msg_docs/SensorHygrometer.md @@ -1,8 +1,26 @@ +--- +pageClass: is-wide-page +--- + # SensorHygrometer (UORB message) +**TOPICS:** sensor_hygrometer +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorHygrometer.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------------------------------------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| `float32` | | | Temperature provided by sensor (Celsius) | +| humidity | `float32` | | | Humidity provided by sensor | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorHygrometer.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -13,5 +31,6 @@ uint32 device_id # unique device ID for the sensor that does not change float32 temperature # Temperature provided by sensor (Celsius) float32 humidity # Humidity provided by sensor - ``` + +::: diff --git a/docs/en/msg_docs/SensorMag.md b/docs/en/msg_docs/SensorMag.md index d574b95e1f..06f95d0fab 100644 --- a/docs/en/msg_docs/SensorMag.md +++ b/docs/en/msg_docs/SensorMag.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # SensorMag (UORB message) +**TOPICS:** sensor_mag +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorMag.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| x | `float32` | | | magnetic field in the FRD board frame X-axis in Gauss | +| y | `float32` | | | magnetic field in the FRD board frame Y-axis in Gauss | +| z | `float32` | | | magnetic field in the FRD board frame Z-axis in Gauss | +| temperature | `float32` | | | temperature in degrees Celsius | +| error_count | `uint32` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorMag.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -19,5 +46,6 @@ float32 temperature # temperature in degrees Celsius uint32 error_count uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/SensorOpticalFlow.md b/docs/en/msg_docs/SensorOpticalFlow.md index d4ea32da34..bc0b36ddc4 100644 --- a/docs/en/msg_docs/SensorOpticalFlow.md +++ b/docs/en/msg_docs/SensorOpticalFlow.md @@ -1,8 +1,45 @@ +--- +pageClass: is-wide-page +--- + # SensorOpticalFlow (UORB message) +**TOPICS:** sensor_opticalflow +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorOpticalFlow.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| pixel_flow | `float32[2]` | | | (radians) optical flow in radians where a positive value is produced by a RH rotation of the sensor about the body axis | +| delta_angle | `float32[3]` | | | (radians) accumulated gyro radians where a positive value is produced by a RH rotation about the body axis. Set to NaN if flow sensor does not have 3-axis gyro data. | +| delta_angle_available | `bool` | | | +| distance_m | `float32` | | | (meters) Distance to the center of the flow field | +| distance_available | `bool` | | | +| integration_timespan_us | `uint32` | | | (microseconds) accumulation timespan in microseconds | +| quality | `uint8` | | | quality, 0: bad quality, 255: maximum quality | +| error_count | `uint32` | | | +| max_flow_rate | `float32` | | | (radians/s) Magnitude of maximum angular which the optical flow sensor can measure reliably | +| min_ground_distance | `float32` | | | (meters) Minimum distance from ground at which the optical flow sensor operates reliably | +| max_ground_distance | `float32` | | | (meters) Maximum distance from ground at which the optical flow sensor operates reliably | +| mode | `uint8` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ----------- | +| MODE_UNKNOWN | `uint8` | 0 | +| MODE_BRIGHT | `uint8` | 1 | +| MODE_LOWLIGHT | `uint8` | 2 | +| MODE_SUPER_LOWLIGHT | `uint8` | 3 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorOpticalFlow.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -35,5 +72,6 @@ uint8 MODE_LOWLIGHT = 2 uint8 MODE_SUPER_LOWLIGHT = 3 uint8 mode - ``` + +::: diff --git a/docs/en/msg_docs/SensorPreflightMag.md b/docs/en/msg_docs/SensorPreflightMag.md index 7d5a933bc7..a5eba92824 100644 --- a/docs/en/msg_docs/SensorPreflightMag.md +++ b/docs/en/msg_docs/SensorPreflightMag.md @@ -1,9 +1,25 @@ +--- +pageClass: is-wide-page +--- + # SensorPreflightMag (UORB message) -Pre-flight sensor check metrics. -The topic will not be updated when the vehicle is armed +Pre-flight sensor check metrics. The topic will not be updated when the vehicle is armed. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorPreflightMag.msg) +**TOPICS:** sensor_preflightmag + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | --------- | ------------ | ---------- | --------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| mag_inconsistency_angle | `float32` | | | maximum angle between magnetometer instance field vectors in radians. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorPreflightMag.msg) + +::: details Click here to see original file ```c # @@ -13,5 +29,6 @@ The topic will not be updated when the vehicle is armed uint64 timestamp # time since system start (microseconds) float32 mag_inconsistency_angle # maximum angle between magnetometer instance field vectors in radians. - ``` + +::: diff --git a/docs/en/msg_docs/SensorSelection.md b/docs/en/msg_docs/SensorSelection.md index 58fb6be289..d2f0ee5546 100644 --- a/docs/en/msg_docs/SensorSelection.md +++ b/docs/en/msg_docs/SensorSelection.md @@ -1,9 +1,26 @@ +--- +pageClass: is-wide-page +--- + # SensorSelection (UORB message) -Sensor ID's for the voted sensors output on the sensor_combined topic. -Will be updated on startup of the sensor module and when sensor selection changes +Sensor ID's for the voted sensors output on the sensor_combined topic. Will be updated on startup of the sensor module and when sensor selection changes. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorSelection.msg) +**TOPICS:** sensor_selection + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------- | -------- | ------------ | ---------- | ------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| accel_device_id | `uint32` | | | unique device ID for the selected accelerometers | +| gyro_device_id | `uint32` | | | unique device ID for the selected rate gyros | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorSelection.msg) + +::: details Click here to see original file ```c # @@ -13,5 +30,6 @@ Will be updated on startup of the sensor module and when sensor selection change uint64 timestamp # time since system start (microseconds) uint32 accel_device_id # unique device ID for the selected accelerometers uint32 gyro_device_id # unique device ID for the selected rate gyros - ``` + +::: diff --git a/docs/en/msg_docs/SensorTemp.md b/docs/en/msg_docs/SensorTemp.md new file mode 100644 index 0000000000..8c68e73dd9 --- /dev/null +++ b/docs/en/msg_docs/SensorTemp.md @@ -0,0 +1,30 @@ +--- +pageClass: is-wide-page +--- + +# SensorTemp (UORB message) + +**TOPICS:** sensor_temp + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------- | -------- | ------------ | ---------------------------------------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| `float32` | | | Temperature provided by sensor (Celsius) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorTemp.msg) + +::: details Click here to see original file + +```c +uint64 timestamp # time since system start (microseconds) + +uint32 device_id # unique device ID for the sensor that does not change between power cycles +float32 temperature # Temperature provided by sensor (Celsius) +``` + +::: diff --git a/docs/en/msg_docs/SensorUwb.md b/docs/en/msg_docs/SensorUwb.md index 544bc60e7a..afd888517a 100644 --- a/docs/en/msg_docs/SensorUwb.md +++ b/docs/en/msg_docs/SensorUwb.md @@ -1,9 +1,44 @@ +--- +pageClass: is-wide-page +--- + # SensorUwb (UORB message) -UWB distance contains the distance information measured by an ultra-wideband positioning system, -such as Pozyx or NXP Rddrone. +UWB distance contains the distance information measured by an ultra-wideband positioning system,. such as Pozyx or NXP Rddrone. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorUwb.msg) +**TOPICS:** sensor_uwb + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------- | --------- | ------------ | ---------- | ----------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| sessionid | `uint32` | | | UWB SessionID | +| time_offset | `uint32` | | | Time between Ranging Rounds in ms | +| counter | `uint32` | | | Number of Ranges since last Start of Ranging | +| mac | `uint16` | | | MAC adress of Initiator (controller) | +| mac_dest | `uint16` | | | MAC adress of Responder (Controlee) | +| status | `uint16` | | | status feedback # | +| nlos | `uint8` | | | None line of site condition y/n | +| distance | `float32` | | | distance in m to the UWB receiver | +| aoa_azimuth_dev | `float32` | | | Angle of arrival of first incomming RX msg | +| aoa_elevation_dev | `float32` | | | Angle of arrival of first incomming RX msg | +| aoa_azimuth_resp | `float32` | | | Angle of arrival of first incomming RX msg at the responder | +| aoa_elevation_resp | `float32` | | | Angle of arrival of first incomming RX msg at the responder | +| aoa_azimuth_fom | `uint8` | | | AOA Azimuth FOM | +| aoa_elevation_fom | `uint8` | | | AOA Elevation FOM | +| aoa_dest_azimuth_fom | `uint8` | | | AOA Azimuth FOM | +| aoa_dest_elevation_fom | `uint8` | | | AOA Elevation FOM | +| orientation | `uint8` | | | Direction the sensor faces from MAV_SENSOR_ORIENTATION enum | +| offset_x | `float32` | | | UWB initiator offset in X axis (NED drone frame) | +| offset_y | `float32` | | | UWB initiator offset in Y axis (NED drone frame) | +| offset_z | `float32` | | | UWB initiator offset in Z axis (NED drone frame) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorUwb.msg) + +::: details Click here to see original file ```c # UWB distance contains the distance information measured by an ultra-wideband positioning system, @@ -40,5 +75,6 @@ uint8 orientation # Direction the sensor faces from MAV_SENSOR_ORIENTATION enum float32 offset_x # UWB initiator offset in X axis (NED drone frame) float32 offset_y # UWB initiator offset in Y axis (NED drone frame) float32 offset_z # UWB initiator offset in Z axis (NED drone frame) - ``` + +::: diff --git a/docs/en/msg_docs/SensorsStatus.md b/docs/en/msg_docs/SensorsStatus.md index 996d7107fb..cdac839723 100644 --- a/docs/en/msg_docs/SensorsStatus.md +++ b/docs/en/msg_docs/SensorsStatus.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # SensorsStatus (UORB message) Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorsStatus.msg) +**TOPICS:** sensors_status_baro sensors_status_mag + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | ------------ | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| device_id_primary | `uint32` | | | current primary device id for reference | +| device_ids | `uint32[4]` | | | +| inconsistency | `float32[4]` | | | magnitude of difference between sensor instance and mean | +| healthy | `bool[4]` | | | sensor healthy | +| priority | `uint8[4]` | | | +| enabled | `bool[4]` | | | +| external | `bool[4]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorsStatus.msg) + +::: details Click here to see original file ```c # @@ -20,5 +43,6 @@ bool[4] enabled bool[4] external # TOPICS sensors_status_baro sensors_status_mag - ``` + +::: diff --git a/docs/en/msg_docs/SensorsStatusImu.md b/docs/en/msg_docs/SensorsStatusImu.md index a25b5d1c01..13b2b2420b 100644 --- a/docs/en/msg_docs/SensorsStatusImu.md +++ b/docs/en/msg_docs/SensorsStatusImu.md @@ -1,8 +1,34 @@ +--- +pageClass: is-wide-page +--- + # SensorsStatusImu (UORB message) Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorsStatusImu.msg) +**TOPICS:** sensors_statusimu + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| accel_device_id_primary | `uint32` | | | current primary accel device id for reference | +| accel_device_ids | `uint32[4]` | | | +| accel_inconsistency_m_s_s | `float32[4]` | | | magnitude of acceleration difference between IMU instance and mean in m/s^2. | +| accel_healthy | `bool[4]` | | | +| accel_priority | `uint8[4]` | | | +| gyro_device_id_primary | `uint32` | | | current primary gyro device id for reference | +| gyro_device_ids | `uint32[4]` | | | +| gyro_inconsistency_rad_s | `float32[4]` | | | magnitude of angular rate difference between IMU instance and mean in (rad/s). | +| gyro_healthy | `bool[4]` | | | +| gyro_priority | `uint8[4]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorsStatusImu.msg) + +::: details Click here to see original file ```c # @@ -23,5 +49,6 @@ uint32[4] gyro_device_ids float32[4] gyro_inconsistency_rad_s # magnitude of angular rate difference between IMU instance and mean in (rad/s). bool[4] gyro_healthy uint8[4] gyro_priority - ``` + +::: diff --git a/docs/en/msg_docs/SystemPower.md b/docs/en/msg_docs/SystemPower.md index c33cffca77..2fe83124d2 100644 --- a/docs/en/msg_docs/SystemPower.md +++ b/docs/en/msg_docs/SystemPower.md @@ -1,8 +1,48 @@ +--- +pageClass: is-wide-page +--- + # SystemPower (UORB message) +**TOPICS:** system_power +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SystemPower.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | ------------ | ------------ | ---------- | --------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| voltage5v_v | `float32` | | | peripheral 5V rail voltage | +| voltage_payload_v | `float32` | | | payload rail voltage | +| sensors3v3 | `float32[4]` | | | Sensors 3V3 rail voltage | +| sensors3v3_valid | `uint8` | | | Sensors 3V3 rail voltage was read (bitfield). | +| usb_connected | `uint8` | | | USB is connected when 1 | +| brick_valid | `uint8` | | | brick bits power is good when bit 1 | +| usb_valid | `uint8` | | | USB is valid when 1 | +| servo_valid | `uint8` | | | servo power is good when 1 | +| periph_5v_oc | `uint8` | | | peripheral overcurrent when 1 | +| hipower_5v_oc | `uint8` | | | high power peripheral overcurrent when 1 | +| comp_5v_valid | `uint8` | | | 5V to companion valid | +| can1_gps1_5v_valid | `uint8` | | | 5V for CAN1/GPS1 valid | +| payload_v_valid | `uint8` | | | payload rail voltage is valid | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------- | ------- | ----- | ----------- | +| BRICK1_VALID_SHIFTS | `uint8` | 0 | +| BRICK1_VALID_MASK | `uint8` | 1 | +| BRICK2_VALID_SHIFTS | `uint8` | 1 | +| BRICK2_VALID_MASK | `uint8` | 2 | +| BRICK3_VALID_SHIFTS | `uint8` | 2 | +| BRICK3_VALID_MASK | `uint8` | 4 | +| BRICK4_VALID_SHIFTS | `uint8` | 3 | +| BRICK4_VALID_MASK | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SystemPower.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -28,5 +68,6 @@ uint8 BRICK3_VALID_SHIFTS=2 uint8 BRICK3_VALID_MASK=4 uint8 BRICK4_VALID_SHIFTS=3 uint8 BRICK4_VALID_MASK=8 - ``` + +::: diff --git a/docs/en/msg_docs/TakeoffStatus.md b/docs/en/msg_docs/TakeoffStatus.md index 45540a74b4..8567effe40 100644 --- a/docs/en/msg_docs/TakeoffStatus.md +++ b/docs/en/msg_docs/TakeoffStatus.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # TakeoffStatus (UORB message) -Status of the takeoff state machine currently just available for multicopters +Status of the takeoff state machine currently just available for multicopters. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TakeoffStatus.msg) +**TOPICS:** takeoff_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| takeoff_state | `uint8` | | | +| tilt_limit | `float32` | | | limited tilt feasibility during takeoff, contains maximum tilt otherwise | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | ------- | ----- | ----------- | +| TAKEOFF_STATE_UNINITIALIZED | `uint8` | 0 | +| TAKEOFF_STATE_DISARMED | `uint8` | 1 | +| TAKEOFF_STATE_SPOOLUP | `uint8` | 2 | +| TAKEOFF_STATE_READY_FOR_TAKEOFF | `uint8` | 3 | +| TAKEOFF_STATE_RAMPUP | `uint8` | 4 | +| TAKEOFF_STATE_FLIGHT | `uint8` | 5 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TakeoffStatus.msg) + +::: details Click here to see original file ```c # Status of the takeoff state machine currently just available for multicopters @@ -19,5 +48,6 @@ uint8 TAKEOFF_STATE_FLIGHT = 5 uint8 takeoff_state float32 tilt_limit # limited tilt feasibility during takeoff, contains maximum tilt otherwise - ``` + +::: diff --git a/docs/en/msg_docs/TaskStackInfo.md b/docs/en/msg_docs/TaskStackInfo.md index fde6ed7585..3ffa39b3bb 100644 --- a/docs/en/msg_docs/TaskStackInfo.md +++ b/docs/en/msg_docs/TaskStackInfo.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # TaskStackInfo (UORB message) -stack information for a single running process +stack information for a single running process. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TaskStackInfo.msg) +**TOPICS:** task_stackinfo + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------- | ---------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| stack_free | `uint16` | | | +| task_name | `char[24]` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | ----------- | +| ORB_QUEUE_LENGTH | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TaskStackInfo.msg) + +::: details Click here to see original file ```c # stack information for a single running process @@ -13,5 +37,6 @@ uint16 stack_free char[24] task_name uint8 ORB_QUEUE_LENGTH = 2 - ``` + +::: diff --git a/docs/en/msg_docs/TecsStatus.md b/docs/en/msg_docs/TecsStatus.md index 96643b3d44..a225729f52 100644 --- a/docs/en/msg_docs/TecsStatus.md +++ b/docs/en/msg_docs/TecsStatus.md @@ -1,8 +1,46 @@ +--- +pageClass: is-wide-page +--- + # TecsStatus (UORB message) +**TOPICS:** tecs_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TecsStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | --------- | ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| altitude_sp | `float32` | | | Altitude setpoint AMSL [m] | +| altitude_reference | `float32` | | | Altitude setpoint reference AMSL [m] | +| altitude_time_constant | `float32` | | | Time constant of the altitude tracker [s] | +| height_rate_reference | `float32` | | | Height rate setpoint reference [m/s] | +| height_rate_direct | `float32` | | | Direct height rate setpoint from velocity reference generator [m/s] | +| height_rate_setpoint | `float32` | | | Height rate setpoint [m/s] | +| height_rate | `float32` | | | Height rate [m/s] | +| equivalent_airspeed_sp | `float32` | | | Equivalent airspeed setpoint [m/s] | +| true_airspeed_sp | `float32` | | | True airspeed setpoint [m/s] | +| true_airspeed_filtered | `float32` | | | True airspeed filtered [m/s] | +| true_airspeed_derivative_sp | `float32` | | | True airspeed derivative setpoint [m/s^2] | +| true_airspeed_derivative | `float32` | | | True airspeed derivative [m/s^2] | +| true_airspeed_derivative_raw | `float32` | | | True airspeed derivative raw [m/s^2] | +| total_energy_rate_sp | `float32` | | | Total energy rate setpoint [m^2/s^3] | +| total_energy_rate | `float32` | | | Total energy rate estimate [m^2/s^3] | +| total_energy_balance_rate_sp | `float32` | | | Energy balance rate setpoint [m^2/s^3] | +| total_energy_balance_rate | `float32` | | | Energy balance rate estimate [m^2/s^3] | +| throttle_integ | `float32` | | | Throttle integrator value [-] | +| pitch_integ | `float32` | | | Pitch integrator value [rad] | +| throttle_sp | `float32` | | | Current throttle setpoint [-] | +| pitch_sp_rad | `float32` | | | Current pitch setpoint [rad] | +| throttle_trim | `float32` | | | estimated throttle value [0,1] required to fly level at equivalent_airspeed_sp in the current atmospheric conditions | +| underspeed_ratio | `float32` | | | 0: no underspeed, 1: maximal underspeed. Controller takes measures to avoid stall proportional to ratio if >0. | +| fast_descend_ratio | `float32` | | | value indicating if fast descend mode is enabled with ramp up and ramp down [0-1] | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TecsStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -36,5 +74,6 @@ float32 throttle_trim # estimated throttle value [0,1] required to fly level a float32 underspeed_ratio # 0: no underspeed, 1: maximal underspeed. Controller takes measures to avoid stall proportional to ratio if >0. float32 fast_descend_ratio # value indicating if fast descend mode is enabled with ramp up and ramp down [0-1] - ``` + +::: diff --git a/docs/en/msg_docs/TelemetryStatus.md b/docs/en/msg_docs/TelemetryStatus.md index 87ca267be6..011293bf23 100644 --- a/docs/en/msg_docs/TelemetryStatus.md +++ b/docs/en/msg_docs/TelemetryStatus.md @@ -1,8 +1,70 @@ +--- +pageClass: is-wide-page +--- + # TelemetryStatus (UORB message) +**TOPICS:** telemetry_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TelemetryStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------------------- | --------- | ------------ | ---------- | ----------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| type | `uint8` | | | type of the radio hardware (LINK*TYPE*\*) | +| mode | `uint8` | | | +| flow_control | `bool` | | | +| forwarding | `bool` | | | +| mavlink_v2 | `bool` | | | +| ftp | `bool` | | | +| streams | `uint8` | | | +| data_rate | `float32` | | | configured maximum data rate (Bytes/s) | +| rate_multiplier | `float32` | | | +| tx_rate_avg | `float32` | | | transmit rate average (Bytes/s) | +| tx_error_rate_avg | `float32` | | | transmit error rate average (Bytes/s) | +| tx_message_count | `uint32` | | | total message sent count | +| tx_buffer_overruns | `uint32` | | | number of TX buffer overruns | +| rx_rate_avg | `float32` | | | transmit rate average (Bytes/s) | +| rx_message_count | `uint32` | | | count of total messages received | +| rx_message_lost_count | `uint32` | | | +| rx_buffer_overruns | `uint32` | | | number of RX buffer overruns | +| rx_parse_errors | `uint32` | | | number of parse errors | +| rx_packet_drop_count | `uint32` | | | number of packet drops | +| rx_message_lost_rate | `float32` | | | +| heartbeat_type_antenna_tracker | `bool` | | | MAV_TYPE_ANTENNA_TRACKER | +| heartbeat_type_gcs | `bool` | | | MAV_TYPE_GCS | +| heartbeat_type_onboard_controller | `bool` | | | MAV_TYPE_ONBOARD_CONTROLLER | +| heartbeat_type_gimbal | `bool` | | | MAV_TYPE_GIMBAL | +| heartbeat_type_adsb | `bool` | | | MAV_TYPE_ADSB | +| heartbeat_type_camera | `bool` | | | MAV_TYPE_CAMERA | +| heartbeat_type_parachute | `bool` | | | MAV_TYPE_PARACHUTE | +| heartbeat_type_open_drone_id | `bool` | | | MAV_TYPE_ODID | +| heartbeat_component_telemetry_radio | `bool` | | | MAV_COMP_ID_TELEMETRY_RADIO | +| heartbeat_component_log | `bool` | | | MAV_COMP_ID_LOG | +| heartbeat_component_osd | `bool` | | | MAV_COMP_ID_OSD | +| heartbeat_component_vio | `bool` | | | MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY | +| heartbeat_component_pairing_manager | `bool` | | | MAV_COMP_ID_PAIRING_MANAGER | +| heartbeat_component_udp_bridge | `bool` | | | MAV_COMP_ID_UDP_BRIDGE | +| heartbeat_component_uart_bridge | `bool` | | | MAV_COMP_ID_UART_BRIDGE | +| open_drone_id_system_healthy | `bool` | | | +| parachute_system_healthy | `bool` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------- | -------- | ------- | ----------------------------------------------- | +| LINK_TYPE_GENERIC | `uint8` | 0 | +| LINK_TYPE_UBIQUITY_BULLET | `uint8` | 1 | +| LINK_TYPE_WIRE | `uint8` | 2 | +| LINK_TYPE_USB | `uint8` | 3 | +| LINK_TYPE_IRIDIUM | `uint8` | 4 | +| HEARTBEAT_TIMEOUT_US | `uint64` | 2500000 | Heartbeat timeout (tolerate missing 1 + jitter) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TelemetryStatus.msg) + +::: details Click here to see original file ```c uint8 LINK_TYPE_GENERIC = 0 @@ -66,5 +128,6 @@ bool heartbeat_component_uart_bridge # MAV_COMP_ID_UART_BRIDGE # Misc component health bool open_drone_id_system_healthy bool parachute_system_healthy - ``` + +::: diff --git a/docs/en/msg_docs/TiltrotorExtraControls.md b/docs/en/msg_docs/TiltrotorExtraControls.md index 80a1bd7ac1..d5be191d3c 100644 --- a/docs/en/msg_docs/TiltrotorExtraControls.md +++ b/docs/en/msg_docs/TiltrotorExtraControls.md @@ -1,13 +1,30 @@ +--- +pageClass: is-wide-page +--- + # TiltrotorExtraControls (UORB message) +**TOPICS:** tiltrotor_extracontrols +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TiltrotorExtraControls.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| collective_tilt_normalized_setpoint | `float32` | | | Collective tilt angle of motors of tiltrotor, 0: vertical, 1: horizontal [0, 1] | +| collective_thrust_normalized_setpoint | `float32` | | | Collective thrust setpoint [0, 1] | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TiltrotorExtraControls.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) float32 collective_tilt_normalized_setpoint # Collective tilt angle of motors of tiltrotor, 0: vertical, 1: horizontal [0, 1] float32 collective_thrust_normalized_setpoint # Collective thrust setpoint [0, 1] - ``` + +::: diff --git a/docs/en/msg_docs/TimesyncStatus.md b/docs/en/msg_docs/TimesyncStatus.md index 2488b8c577..7344f7c5b8 100644 --- a/docs/en/msg_docs/TimesyncStatus.md +++ b/docs/en/msg_docs/TimesyncStatus.md @@ -1,8 +1,35 @@ +--- +pageClass: is-wide-page +--- + # TimesyncStatus (UORB message) +**TOPICS:** timesync_status +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TimesyncStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | -------- | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| source_protocol | `uint8` | | | timesync source | +| remote_timestamp | `uint64` | | | remote system timestamp (microseconds) | +| observed_offset | `int64` | | | raw time offset directly observed from this timesync packet (microseconds) | +| estimated_offset | `int64` | | | smoothed time offset between companion system and PX4 (microseconds) | +| round_trip_time | `uint32` | | | round trip time of this timesync packet (microseconds) | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | ----------- | +| SOURCE_PROTOCOL_UNKNOWN | `uint8` | 0 | +| SOURCE_PROTOCOL_MAVLINK | `uint8` | 1 | +| SOURCE_PROTOCOL_DDS | `uint8` | 2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TimesyncStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,5 +43,6 @@ uint64 remote_timestamp # remote system timestamp (microseconds) int64 observed_offset # raw time offset directly observed from this timesync packet (microseconds) int64 estimated_offset # smoothed time offset between companion system and PX4 (microseconds) uint32 round_trip_time # round trip time of this timesync packet (microseconds) - ``` + +::: diff --git a/docs/en/msg_docs/TrajectorySetpoint.md b/docs/en/msg_docs/TrajectorySetpoint.md index 06e44bcf11..a778ddcf0b 100644 --- a/docs/en/msg_docs/TrajectorySetpoint.md +++ b/docs/en/msg_docs/TrajectorySetpoint.md @@ -1,11 +1,36 @@ +--- +pageClass: is-wide-page +--- + # TrajectorySetpoint (UORB message) -Trajectory setpoint in NED frame -Input to PID position controller. -Needs to be kinematically consistent and feasible for smooth flight. -setting a value to NaN means the state should not be controlled +Trajectory setpoint in NED frame. Input to PID position controller. Needs to be kinematically consistent and feasible for smooth flight. setting a value to NaN means the state should not be controlled. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/TrajectorySetpoint.msg) +**TOPICS:** trajectory_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ------------ | ------------ | ---------- | ---------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| position | `float32[3]` | | | in meters | +| velocity | `float32[3]` | | | in meters/second | +| acceleration | `float32[3]` | | | in meters/second^2 | +| jerk | `float32[3]` | | | in meters/second^3 (for logging only) | +| yaw | `float32` | | | euler angle of desired attitude in radians -PI..+PI | +| yawspeed | `float32` | | | angular velocity around NED frame z-axis in radians/second | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/TrajectorySetpoint.msg) + +::: details Click here to see original file ```c # Trajectory setpoint in NED frame @@ -25,5 +50,6 @@ float32[3] jerk # in meters/second^3 (for logging only) float32 yaw # euler angle of desired attitude in radians -PI..+PI float32 yawspeed # angular velocity around NED frame z-axis in radians/second - ``` + +::: diff --git a/docs/en/msg_docs/TrajectorySetpoint6dof.md b/docs/en/msg_docs/TrajectorySetpoint6dof.md index f2629e19c4..4b6b4e820c 100644 --- a/docs/en/msg_docs/TrajectorySetpoint6dof.md +++ b/docs/en/msg_docs/TrajectorySetpoint6dof.md @@ -1,9 +1,30 @@ +--- +pageClass: is-wide-page +--- + # TrajectorySetpoint6dof (UORB message) -Trajectory setpoint in NED frame -Input to position controller. +Trajectory setpoint in NED frame. Input to position controller. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TrajectorySetpoint6dof.msg) +**TOPICS:** trajectory_setpoint6dof + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| position | `float32[3]` | | | in meters | +| velocity | `float32[3]` | | | in meters/second | +| acceleration | `float32[3]` | | | in meters/second^2 | +| jerk | `float32[3]` | | | in meters/second^3 (for logging only) | +| quaternion | `float32[4]` | | | unit quaternion | +| angular_velocity | `float32[3]` | | | angular velocity in radians/second | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TrajectorySetpoint6dof.msg) + +::: details Click here to see original file ```c # Trajectory setpoint in NED frame @@ -19,5 +40,6 @@ float32[3] jerk # in meters/second^3 (for logging only) float32[4] quaternion # unit quaternion float32[3] angular_velocity # angular velocity in radians/second - ``` + +::: diff --git a/docs/en/msg_docs/TransponderReport.md b/docs/en/msg_docs/TransponderReport.md index 9bab882b02..6d1aba922f 100644 --- a/docs/en/msg_docs/TransponderReport.md +++ b/docs/en/msg_docs/TransponderReport.md @@ -1,6 +1,70 @@ +--- +pageClass: is-wide-page +--- + # TransponderReport (UORB message) -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TransponderReport.msg) +**TOPICS:** transponder_report + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | ----------- | ------------ | ---------- | -------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| icao_address | `uint32` | | | ICAO address | +| lat | `float64` | | | Latitude, expressed as degrees | +| lon | `float64` | | | Longitude, expressed as degrees | +| altitude_type | `uint8` | | | Type from ADSB_ALTITUDE_TYPE enum | +| altitude | `float32` | | | Altitude(ASL) in meters | +| heading | `float32` | | | Course over ground in radians, 0 to 2pi, 0 is north | +| hor_velocity | `float32` | | | The horizontal velocity in m/s | +| ver_velocity | `float32` | | | The vertical velocity in m/s, positive is up | +| callsign | `char[9]` | | | The callsign, 8+null | +| emitter_type | `uint8` | | | Type from ADSB_EMITTER_TYPE enum | +| tslc | `uint8` | | | Time since last communication in seconds | +| flags | `uint16` | | | Flags to indicate various statuses including valid data fields | +| squawk | `uint16` | | | Squawk code | +| uas_id | `uint8[18]` | | | Unique UAS ID | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| PX4_ADSB_FLAGS_VALID_COORDS | `uint16` | 1 | +| PX4_ADSB_FLAGS_VALID_ALTITUDE | `uint16` | 2 | +| PX4_ADSB_FLAGS_VALID_HEADING | `uint16` | 4 | +| PX4_ADSB_FLAGS_VALID_VELOCITY | `uint16` | 8 | +| PX4_ADSB_FLAGS_VALID_CALLSIGN | `uint16` | 16 | +| PX4_ADSB_FLAGS_VALID_SQUAWK | `uint16` | 32 | +| PX4_ADSB_FLAGS_RETRANSLATE | `uint16` | 256 | +| ADSB_EMITTER_TYPE_NO_INFO | `uint16` | 0 | +| ADSB_EMITTER_TYPE_LIGHT | `uint16` | 1 | +| ADSB_EMITTER_TYPE_SMALL | `uint16` | 2 | +| ADSB_EMITTER_TYPE_LARGE | `uint16` | 3 | +| ADSB_EMITTER_TYPE_HIGH_VORTEX_LARGE | `uint16` | 4 | +| ADSB_EMITTER_TYPE_HEAVY | `uint16` | 5 | +| ADSB_EMITTER_TYPE_HIGHLY_MANUV | `uint16` | 6 | +| ADSB_EMITTER_TYPE_ROTOCRAFT | `uint16` | 7 | +| ADSB_EMITTER_TYPE_UNASSIGNED | `uint16` | 8 | +| ADSB_EMITTER_TYPE_GLIDER | `uint16` | 9 | +| ADSB_EMITTER_TYPE_LIGHTER_AIR | `uint16` | 10 | +| ADSB_EMITTER_TYPE_PARACHUTE | `uint16` | 11 | +| ADSB_EMITTER_TYPE_ULTRA_LIGHT | `uint16` | 12 | +| ADSB_EMITTER_TYPE_UNASSIGNED2 | `uint16` | 13 | +| ADSB_EMITTER_TYPE_UAV | `uint16` | 14 | +| ADSB_EMITTER_TYPE_SPACE | `uint16` | 15 | +| ADSB_EMITTER_TYPE_UNASSGINED3 | `uint16` | 16 | +| ADSB_EMITTER_TYPE_EMERGENCY_SURFACE | `uint16` | 17 | +| ADSB_EMITTER_TYPE_SERVICE_SURFACE | `uint16` | 18 | +| ADSB_EMITTER_TYPE_POINT_OBSTACLE | `uint16` | 19 | +| ADSB_EMITTER_TYPE_ENUM_END | `uint16` | 20 | +| ORB_QUEUE_LENGTH | `uint8` | 16 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TransponderReport.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -53,5 +117,6 @@ uint16 ADSB_EMITTER_TYPE_POINT_OBSTACLE=19 uint16 ADSB_EMITTER_TYPE_ENUM_END=20 uint8 ORB_QUEUE_LENGTH = 16 - ``` + +::: diff --git a/docs/en/msg_docs/TuneControl.md b/docs/en/msg_docs/TuneControl.md index b6e96771ad..25a79645d4 100644 --- a/docs/en/msg_docs/TuneControl.md +++ b/docs/en/msg_docs/TuneControl.md @@ -1,9 +1,60 @@ +--- +pageClass: is-wide-page +--- + # TuneControl (UORB message) -This message is used to control the tunes, when the tune_id is set to CUSTOM -then the frequency, duration are used otherwise those values are ignored. +This message is used to control the tunes, when the tune_id is set to CUSTOM. then the frequency, duration are used otherwise those values are ignored. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TuneControl.msg) +**TOPICS:** tune_control + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| tune_id | `uint8` | | | tune_id corresponding to TuneID::\* from the tune_defaults.h in the tunes library | +| tune_override | `bool` | | | if true the tune which is playing will be stopped and the new started | +| frequency | `uint16` | | | in Hz | +| duration | `uint32` | | | in us | +| silence | `uint32` | | | in us | +| volume | `uint8` | | | value between 0-100 if supported by backend | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------- | ------- | ----- | ----------- | +| TUNE_ID_STOP | `uint8` | 0 | +| TUNE_ID_STARTUP | `uint8` | 1 | +| TUNE_ID_ERROR | `uint8` | 2 | +| TUNE_ID_NOTIFY_POSITIVE | `uint8` | 3 | +| TUNE_ID_NOTIFY_NEUTRAL | `uint8` | 4 | +| TUNE_ID_NOTIFY_NEGATIVE | `uint8` | 5 | +| TUNE_ID_ARMING_WARNING | `uint8` | 6 | +| TUNE_ID_BATTERY_WARNING_SLOW | `uint8` | 7 | +| TUNE_ID_BATTERY_WARNING_FAST | `uint8` | 8 | +| TUNE_ID_GPS_WARNING | `uint8` | 9 | +| TUNE_ID_ARMING_FAILURE | `uint8` | 10 | +| TUNE_ID_PARACHUTE_RELEASE | `uint8` | 11 | +| TUNE_ID_SINGLE_BEEP | `uint8` | 12 | +| TUNE_ID_HOME_SET | `uint8` | 13 | +| TUNE_ID_SD_INIT | `uint8` | 14 | +| TUNE_ID_SD_ERROR | `uint8` | 15 | +| TUNE_ID_PROG_PX4IO | `uint8` | 16 | +| TUNE_ID_PROG_PX4IO_OK | `uint8` | 17 | +| TUNE_ID_PROG_PX4IO_ERR | `uint8` | 18 | +| TUNE_ID_POWER_OFF | `uint8` | 19 | +| NUMBER_OF_TUNES | `uint8` | 20 | +| VOLUME_LEVEL_MIN | `uint8` | 0 | +| VOLUME_LEVEL_DEFAULT | `uint8` | 20 | +| VOLUME_LEVEL_MAX | `uint8` | 100 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/TuneControl.msg) + +::: details Click here to see original file ```c # This message is used to control the tunes, when the tune_id is set to CUSTOM @@ -45,5 +96,6 @@ uint8 VOLUME_LEVEL_DEFAULT = 20 uint8 VOLUME_LEVEL_MAX = 100 uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/UavcanParameterRequest.md b/docs/en/msg_docs/UavcanParameterRequest.md index 681c8aa8c9..1abc63360e 100644 --- a/docs/en/msg_docs/UavcanParameterRequest.md +++ b/docs/en/msg_docs/UavcanParameterRequest.md @@ -1,8 +1,44 @@ +--- +pageClass: is-wide-page +--- + # UavcanParameterRequest (UORB message) -UAVCAN-MAVLink parameter bridge request type +UAVCAN-MAVLink parameter bridge request type. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UavcanParameterRequest.msg) +**TOPICS:** uavcan_parameterrequest + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ---------- | ------------ | ---------- | ----------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| message_type | `uint8` | | | MAVLink message type: PARAM_REQUEST_READ, PARAM_REQUEST_LIST, PARAM_SET | +| node_id | `uint8` | | | UAVCAN node ID mapped from MAVLink component ID | +| param_id | `char[17]` | | | MAVLink/UAVCAN parameter name | +| param_index | `int16` | | | -1 if the param_id field should be used as identifier | +| param_type | `uint8` | | | MAVLink parameter type | +| int_value | `int64` | | | current value if param_type is int-like | +| real_value | `float32` | | | current value if param_type is float-like | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------------------- | ------- | ----- | --------------------------------- | +| MESSAGE_TYPE_PARAM_REQUEST_READ | `uint8` | 20 | MAVLINK_MSG_ID_PARAM_REQUEST_READ | +| MESSAGE_TYPE_PARAM_REQUEST_LIST | `uint8` | 21 | MAVLINK_MSG_ID_PARAM_REQUEST_LIST | +| MESSAGE_TYPE_PARAM_SET | `uint8` | 23 | MAVLINK_MSG_ID_PARAM_SET | +| NODE_ID_ALL | `uint8` | 0 | MAV_COMP_ID_ALL | +| PARAM_TYPE_UINT8 | `uint8` | 1 | MAV_PARAM_TYPE_UINT8 | +| PARAM_TYPE_INT64 | `uint8` | 8 | MAV_PARAM_TYPE_INT64 | +| PARAM_TYPE_REAL32 | `uint8` | 9 | MAV_PARAM_TYPE_REAL32 | +| ORB_QUEUE_LENGTH | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UavcanParameterRequest.msg) + +::: details Click here to see original file ```c # UAVCAN-MAVLink parameter bridge request type @@ -28,5 +64,6 @@ int64 int_value # current value if param_type is int-like float32 real_value # current value if param_type is float-like uint8 ORB_QUEUE_LENGTH = 4 - ``` + +::: diff --git a/docs/en/msg_docs/UavcanParameterValue.md b/docs/en/msg_docs/UavcanParameterValue.md index f77444727a..fec16df590 100644 --- a/docs/en/msg_docs/UavcanParameterValue.md +++ b/docs/en/msg_docs/UavcanParameterValue.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # UavcanParameterValue (UORB message) -UAVCAN-MAVLink parameter bridge response type +UAVCAN-MAVLink parameter bridge response type. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UavcanParameterValue.msg) +**TOPICS:** uavcan_parametervalue + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | ---------- | ------------ | ---------- | ----------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| node_id | `uint8` | | | UAVCAN node ID mapped from MAVLink component ID | +| param_id | `char[17]` | | | MAVLink/UAVCAN parameter name | +| param_index | `int16` | | | parameter index, if known | +| param_count | `uint16` | | | number of parameters exposed by the node | +| param_type | `uint8` | | | MAVLink parameter type | +| int_value | `int64` | | | current value if param_type is int-like | +| real_value | `float32` | | | current value if param_type is float-like | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UavcanParameterValue.msg) + +::: details Click here to see original file ```c # UAVCAN-MAVLink parameter bridge response type @@ -14,5 +37,6 @@ uint16 param_count # number of parameters exposed by the node uint8 param_type # MAVLink parameter type int64 int_value # current value if param_type is int-like float32 real_value # current value if param_type is float-like - ``` + +::: diff --git a/docs/en/msg_docs/UlogStream.md b/docs/en/msg_docs/UlogStream.md index 8aba8063c8..f52c44da41 100644 --- a/docs/en/msg_docs/UlogStream.md +++ b/docs/en/msg_docs/UlogStream.md @@ -1,9 +1,36 @@ +--- +pageClass: is-wide-page +--- + # UlogStream (UORB message) -Message to stream ULog data from the logger. Corresponds to the LOGGING_DATA -mavlink message +Message to stream ULog data from the logger. Corresponds to the LOGGING_DATA. mavlink message. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UlogStream.msg) +**TOPICS:** ulog_stream + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | ------------ | ---------- | ------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| length | `uint8` | | | length of data | +| first_message_offset | `uint8` | | | offset into data where first message starts. This | +| msg_sequence | `uint16` | | | allows determine drops | +| flags | `uint8` | | | see FLAGS\_\* | +| data | `uint8[249]` | | | ulog data | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------- | ------- | ----- | -------------------------------------------------------------------- | +| FLAGS_NEED_ACK | `uint8` | 1 | if set, this message requires to be acked. | +| ORB_QUEUE_LENGTH | `uint8` | 16 | TODO: we might be able to reduce this if mavlink polled on the topic | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UlogStream.msg) + +::: details Click here to see original file ```c # Message to stream ULog data from the logger. Corresponds to the LOGGING_DATA @@ -25,5 +52,6 @@ uint8 flags # see FLAGS_* uint8[249] data # ulog data uint8 ORB_QUEUE_LENGTH = 16 # TODO: we might be able to reduce this if mavlink polled on the topic - ``` + +::: diff --git a/docs/en/msg_docs/UlogStreamAck.md b/docs/en/msg_docs/UlogStreamAck.md index 4bef62c4f5..ea874882fd 100644 --- a/docs/en/msg_docs/UlogStreamAck.md +++ b/docs/en/msg_docs/UlogStreamAck.md @@ -1,9 +1,32 @@ +--- +pageClass: is-wide-page +--- + # UlogStreamAck (UORB message) -Ack a previously sent ulog_stream message that had -the NEED_ACK flag set +Ack a previously sent ulog_stream message that had. the NEED_ACK flag set. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UlogStreamAck.msg) +**TOPICS:** ulog_streamack + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | -------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| msg_sequence | `uint16` | | | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------- | ------- | ----- | -------------------------------------------------------------------------------- | +| ACK_TIMEOUT | `int32` | 50 | timeout waiting for an ack until we retry to send the message [ms] | +| ACK_MAX_TRIES | `int32` | 50 | maximum amount of tries to (re-)send a message, each time waiting ACK_TIMEOUT ms | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/UlogStreamAck.msg) + +::: details Click here to see original file ```c # Ack a previously sent ulog_stream message that had @@ -14,5 +37,6 @@ int32 ACK_TIMEOUT = 50 # timeout waiting for an ack until we retry to send the int32 ACK_MAX_TRIES = 50 # maximum amount of tries to (re-)send a message, each time waiting ACK_TIMEOUT ms uint16 msg_sequence - ``` + +::: diff --git a/docs/en/msg_docs/UnregisterExtComponent.md b/docs/en/msg_docs/UnregisterExtComponent.md index 5a36c85613..a3e7a4d6da 100644 --- a/docs/en/msg_docs/UnregisterExtComponent.md +++ b/docs/en/msg_docs/UnregisterExtComponent.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # UnregisterExtComponent (UORB message) +**TOPICS:** unregister_extcomponent +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/UnregisterExtComponent.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ---------- | ------------ | ---------- | --------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| name | `char[25]` | | | either the mode name, or component name | +| arming_check_id | `int8` | | | arming check registration ID (-1 if not registered) | +| mode_id | `int8` | | | assigned mode ID (-1 if not registered) | +| mode_executor_id | `int8` | | | assigned mode executor ID (-1 if not registered) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/UnregisterExtComponent.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -14,5 +38,6 @@ char[25] name # either the mode name, or component name int8 arming_check_id # arming check registration ID (-1 if not registered) int8 mode_id # assigned mode ID (-1 if not registered) int8 mode_executor_id # assigned mode executor ID (-1 if not registered) - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAcceleration.md b/docs/en/msg_docs/VehicleAcceleration.md index 1fb3d0880c..e463dedd18 100644 --- a/docs/en/msg_docs/VehicleAcceleration.md +++ b/docs/en/msg_docs/VehicleAcceleration.md @@ -1,15 +1,31 @@ +--- +pageClass: is-wide-page +--- + # VehicleAcceleration (UORB message) +**TOPICS:** vehicle_acceleration +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAcceleration.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| xyz | `float32[3]` | | | Bias corrected acceleration (including gravity) in the FRD body frame XYZ-axis in m/s^2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAcceleration.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint64 timestamp_sample # the timestamp of the raw data (microseconds) float32[3] xyz # Bias corrected acceleration (including gravity) in the FRD body frame XYZ-axis in m/s^2 - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAirData.md b/docs/en/msg_docs/VehicleAirData.md index 86cf87e44c..020b706c27 100644 --- a/docs/en/msg_docs/VehicleAirData.md +++ b/docs/en/msg_docs/VehicleAirData.md @@ -1,24 +1,51 @@ +--- +pageClass: is-wide-page +--- + # VehicleAirData (UORB message) +Vehicle air data. +Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +Includes calculated data such as barometric altitude and air density. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAirData.msg) +**TOPICS:** vehicle_airdata + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | --------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Timestamp of the raw data | +| baro_device_id | `uint32` | | | Unique device ID for the selected barometer | +| baro_alt_meter | `float32` | m [MSL] | | Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH | +| baro_pressure_pa | `float32` | Pa | | Absolute pressure | +| ambient_temperature | `float32` | degC | | Ambient temperature | +| temperature_source | `uint8` | | | Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed | +| rho | `float32` | kg/m^3 | | Air density | +| calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever calibration changes. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAirData.msg) + +::: details Click here to see original file ```c +# Vehicle air data +# +# Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +# Includes calculated data such as barometric altitude and air density. -uint64 timestamp # time since system start (microseconds) - -uint64 timestamp_sample # the timestamp of the raw data (microseconds) - -uint32 baro_device_id # unique device ID for the selected barometer - -float32 baro_alt_meter # Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH. -float32 baro_pressure_pa # Absolute pressure in Pascals -float32 ambient_temperature # Abient temperature in degrees Celsius -uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed - -float32 rho # air density - -uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. - +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +uint32 baro_device_id # Unique device ID for the selected barometer +float32 baro_alt_meter # [m] [@frame MSL] Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH +float32 baro_pressure_pa # [Pa] Absolute pressure +float32 ambient_temperature # [degC] Ambient temperature +uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed +float32 rho # [kg/m^3] Air density +uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. ``` + +::: diff --git a/docs/en/msg_docs/VehicleAngularAccelerationSetpoint.md b/docs/en/msg_docs/VehicleAngularAccelerationSetpoint.md index d10cabdb55..f098855945 100644 --- a/docs/en/msg_docs/VehicleAngularAccelerationSetpoint.md +++ b/docs/en/msg_docs/VehicleAngularAccelerationSetpoint.md @@ -1,14 +1,30 @@ +--- +pageClass: is-wide-page +--- + # VehicleAngularAccelerationSetpoint (UORB message) +**TOPICS:** vehicle_angularacceleration_setpoint +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAngularAccelerationSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | timestamp of the data sample on which this message is based (microseconds) | +| xyz | `float32[3]` | | | angular acceleration about X, Y, Z body axis in rad/s^2 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAngularAccelerationSetpoint.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint64 timestamp_sample # timestamp of the data sample on which this message is based (microseconds) float32[3] xyz # angular acceleration about X, Y, Z body axis in rad/s^2 - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAngularVelocity.md b/docs/en/msg_docs/VehicleAngularVelocity.md index 2c94cb706a..81fa680129 100644 --- a/docs/en/msg_docs/VehicleAngularVelocity.md +++ b/docs/en/msg_docs/VehicleAngularVelocity.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # VehicleAngularVelocity (UORB message) +**TOPICS:** vehicle_angular_velocity vehicle_angular_velocity_groundtruth +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAngularVelocity.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | timestamp of the data sample on which this message is based (microseconds) | +| xyz | `float32[3]` | | | Bias corrected angular velocity about the FRD body frame XYZ-axis in rad/s | +| xyz_derivative | `float32[3]` | | | angular acceleration about the FRD body frame XYZ-axis in rad/s^2 | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAngularVelocity.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -15,5 +38,6 @@ float32[3] xyz # Bias corrected angular velocity about the FRD body frame XYZ float32[3] xyz_derivative # angular acceleration about the FRD body frame XYZ-axis in rad/s^2 # TOPICS vehicle_angular_velocity vehicle_angular_velocity_groundtruth - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAttitude.md b/docs/en/msg_docs/VehicleAttitude.md index 856fe6d5a6..526e299db5 100644 --- a/docs/en/msg_docs/VehicleAttitude.md +++ b/docs/en/msg_docs/VehicleAttitude.md @@ -1,9 +1,34 @@ +--- +pageClass: is-wide-page +--- + # VehicleAttitude (UORB message) -This is similar to the mavlink message ATTITUDE_QUATERNION, but for onboard use -The quaternion uses the Hamilton convention, and the order is q(w, x, y, z) +This is similar to the mavlink message ATTITUDE_QUATERNION, but for onboard use. The quaternion uses the Hamilton convention, and the order is q(w, x, y, z). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitude.msg) +**TOPICS:** vehicle_attitude vehicle_attitude_groundtruth external_ins_attitude estimator_attitude + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------ | ------------ | ------------ | ---------- | ------------------------------------------------------------------ | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| q | `float32[4]` | | | Quaternion rotation from the FRD body frame to the NED earth frame | +| delta_q_reset | `float32[4]` | | | Amount by which quaternion has changed during last reset | +| quat_reset_counter | `uint8` | | | Quaternion reset counter | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitude.msg) + +::: details Click here to see original file ```c # This is similar to the mavlink message ATTITUDE_QUATERNION, but for onboard use @@ -21,5 +46,6 @@ uint8 quat_reset_counter # Quaternion reset counter # TOPICS vehicle_attitude vehicle_attitude_groundtruth external_ins_attitude # TOPICS estimator_attitude - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAttitudeSetpoint.md b/docs/en/msg_docs/VehicleAttitudeSetpoint.md index 69552e23ef..7bc0940ba3 100644 --- a/docs/en/msg_docs/VehicleAttitudeSetpoint.md +++ b/docs/en/msg_docs/VehicleAttitudeSetpoint.md @@ -1,8 +1,31 @@ +--- +pageClass: is-wide-page +--- + # VehicleAttitudeSetpoint (UORB message) +**TOPICS:** vehicle_attitude_setpoint mc_virtual_attitude_setpoint fw_virtual_attitude_setpoint +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| yaw_sp_move_rate | `float32` | | | rad/s (commanded by user) | +| q_d | `float32[4]` | | | Desired quaternion for quaternion control | +| thrust_body | `float32[3]` | | | Normalized thrust command in body FRD frame [-1,1] | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 1 @@ -19,5 +42,6 @@ float32[4] q_d # Desired quaternion for quaternion control float32[3] thrust_body # Normalized thrust command in body FRD frame [-1,1] # TOPICS vehicle_attitude_setpoint mc_virtual_attitude_setpoint fw_virtual_attitude_setpoint - ``` + +::: diff --git a/docs/en/msg_docs/VehicleAttitudeSetpointV0.md b/docs/en/msg_docs/VehicleAttitudeSetpointV0.md index 9b3a8c655e..9a53c593f9 100644 --- a/docs/en/msg_docs/VehicleAttitudeSetpointV0.md +++ b/docs/en/msg_docs/VehicleAttitudeSetpointV0.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # VehicleAttitudeSetpointV0 (UORB message) +**TOPICS:** vehicle_attitude_setpoint mc_virtual_attitude_setpoint fw_virtual_attitude_setpoint +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleAttitudeSetpointV0.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| yaw_sp_move_rate | `float32` | | | rad/s (commanded by user) | +| q_d | `float32[4]` | | | Desired quaternion for quaternion control | +| thrust_body | `float32[3]` | | | Normalized thrust command in body FRD frame [-1,1] | +| reset_integral | `bool` | | | Reset roll/pitch/yaw integrals (navigation logic change) | +| fw_control_yaw_wheel | `bool` | | | control heading with steering wheel (used for auto takeoff on runway) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleAttitudeSetpointV0.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -23,5 +48,6 @@ bool reset_integral # Reset roll/pitch/yaw integrals (navigation logic change) bool fw_control_yaw_wheel # control heading with steering wheel (used for auto takeoff on runway) # TOPICS vehicle_attitude_setpoint mc_virtual_attitude_setpoint fw_virtual_attitude_setpoint - ``` + +::: diff --git a/docs/en/msg_docs/VehicleCommand.md b/docs/en/msg_docs/VehicleCommand.md index 19557cf496..32b719e7b7 100644 --- a/docs/en/msg_docs/VehicleCommand.md +++ b/docs/en/msg_docs/VehicleCommand.md @@ -1,9 +1,1581 @@ +--- +pageClass: is-wide-page +--- + # VehicleCommand (UORB message) -Vehicle Command uORB message. Used for commanding a mission / action / etc. -Follows the MAVLink COMMAND_INT / COMMAND_LONG definition +Vehicle Command uORB message. Used for commanding a mission / action / etc. Follows the MAVLink COMMAND_INT / COMMAND_LONG definition. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleCommand.msg) +**TOPICS:** vehicle_command gimbal_v1_command vehicle_command_mode_executor + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | ------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start. | +| param1 | `float32` | | | Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param2 | `float32` | | | Parameter 2, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param3 | `float32` | | | Parameter 3, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param4 | `float32` | | | Parameter 4, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param5 | `float64` | | | Parameter 5, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param6 | `float64` | | | Parameter 6, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| param7 | `float32` | | | Parameter 7, as defined by MAVLink uint16 VEHICLE_CMD enum. | +| command | `uint32` | | | Command ID. | +| target_system | `uint8` | | | System which should execute the command. | +| target_component | `uint8` | | | Component which should execute the command, 0 for all components. | +| source_system | `uint8` | | | System sending the command. | +| source_component | `uint16` | | | Component / mode executor sending the command. | +| confirmation | `uint8` | | | 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command). | +| from_external | `bool` | | | + +## Commands + +### VEHICLE_CMD_CUSTOM_0 (0) + +Test command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_CUSTOM_1 (1) + +Test command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_CUSTOM_2 (2) + +Test command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_NAV_WAYPOINT (16) + +Navigate to MISSION. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | s | | (decimal) Hold time. (ignored by fixed wing, time to stay at MISSION for rotary wing) | +| 2 | m | | Acceptance radius (if the sphere with this radius is hit, the MISSION counts as reached) | +| 3 | | | 0 to pass through the WP, if > 0 radius [m] to pass by WP. Positive value for clockwise orbit, negative value for counter-clockwise orbit. Allows trajectory control. | +| 4 | | | Desired yaw angle at MISSION (rotary wing) | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_LOITER_UNLIM (17) + +Loiter around this MISSION an unlimited amount of time. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------------------------------------------------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | m | | Radius around MISSION. If positive loiter clockwise, else counter-clockwise | +| 4 | | | Desired yaw angle. | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_LOITER_TURNS (18) + +Loiter around this MISSION for X turns. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------------- | +| 1 | | | Turns | +| 2 | | | Unused | +| 3 | | | Radius around MISSION [m]. If positive loiter clockwise, else counter-clockwise | +| 4 | | | Desired yaw angle. | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_LOITER_TIME (19) + +Loiter around this MISSION for time. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------------- | +| 1 | s | | Seconds (decimal) | +| 2 | | | Unused | +| 3 | | | Radius around MISSION [m]. If positive loiter clockwise, else counter-clockwise | +| 4 | | | Desired yaw angle. | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_RETURN_TO_LAUNCH (20) + +Return to launch location. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_NAV_LAND (21) + +Land at location. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------ | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Desired yaw angle. | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_TAKEOFF (22) + +Takeoff from ground / hand. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------------------------------------------------- | +| 1 | | | Unused (FW pitch from FW_TKO_PITCH_MIN) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | deg | [0 : 360] | Yaw angle in NED if yaw source available, ignored otherwise | +| 5 | | | Latitude (WGS-84) | +| 6 | | | Longitude (WGS-84) | +| 7 | m | | Altitude AMSL | + +### VEHICLE_CMD_NAV_PRECLAND (23) + +Attempt a precision landing. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_ORBIT (34) + +Start orbiting on the circumference of a circle defined by the parameters. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ------------------------------------------- | ------------- | +| 1 | m | | Radius | +| 2 | m/s | | Velocity | +| 3 | | [ORBIT_YAW_BEHAVIOUR](#ORBIT_YAW_BEHAVIOUR) | Yaw behaviour | +| 4 | | | Unused | +| 5 | | | Latitude/X | +| 6 | | | Longitude/Y | +| 7 | | | Altitude/Z | + +### VEHICLE_CMD_DO_FIGUREEIGHT (35) + +Start flying on the outline of a figure eight defined by the parameters. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------ | +| 1 | m | | Major radius | +| 2 | m | | Minor radius | +| 3 | m/s | | Velocity | +| 4 | | | Orientation | +| 5 | | | Latitude/X | +| 6 | | | Longitude/Y | +| 7 | | | Altitude/Z | + +### VEHICLE_CMD_NAV_ROI (80) + +Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | --------------------------- | ----------------------------------------------------- | +| 1 | | [VEHICLE_ROI](#VEHICLE_ROI) | Region of interest mode. | +| 2 | | | MISSION index/ target ID. | +| 3 | | | ROI index (allows a vehicle to manage multiple ROI's) | +| 4 | | | Unused | +| 5 | | | x the location of the fixed ROI (see MAV_FRAME) | +| 6 | | | y | +| 7 | | | z | + +### VEHICLE_CMD_NAV_PATHPLANNING (81) + +Control autonomous path planning on the MAV. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | | | 0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning | +| 2 | | | 0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid | +| 3 | | | Unused | +| 4 | deg | [0 : 360] | Yaw angle at goal, in compass degrees | +| 5 | | | Latitude/X of goal | +| 6 | | | Longitude/Y of goal | +| 7 | | | Altitude/Z of goal | + +### VEHICLE_CMD_NAV_VTOL_TAKEOFF (84) + +Takeoff from ground / hand and transition to fixed wing. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------ | +| 1 | | | Minimum pitch (if airspeed sensor present), desired pitch without sensor | +| 2 | | | Transition heading, 0: Default, 3: Use specified transition heading | +| 3 | | | Unused | +| 4 | | | Yaw angle (if magnetometer present), ignored without magnetometer | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_VTOL_LAND (85) + +Transition to MC and land at location. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------ | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Desired yaw angle. | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_NAV_GUIDED_LIMITS (90) + +Set limits for external control. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | s | | Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout | +| 2 | m | | Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit | +| 3 | m | | Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit | +| 4 | m | | Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_NAV_GUIDED_MASTER (91) + +Set id of master controller. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------ | +| 1 | | | System ID | +| 2 | | | Component ID | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_NAV_DELAY (93) + +Delay the next navigation command a number of seconds or until a specified time. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------ | +| 1 | s | | Delay (decimal, -1 to enable time-of-day fields) | +| 2 | h | | hour (24h format, UTC, -1 to ignore) | +| 3 | | | minute (24h format, UTC, -1 to ignore) | +| 4 | | | second (24h format, UTC) | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_NAV_LAST (95) + +NOP - This command is only used to mark the upper limit of the NAV/ACTION commands in the enumeration. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_CONDITION_DELAY (112) + +Delay mission state machine. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------------- | +| 1 | s | | Delay (decimal seconds) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_CONDITION_CHANGE_ALT (113) + +Ascend/descend at rate. Delay mission state machine until desired altitude reached. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------- | +| 1 | | | Descent / Ascend rate (m/s) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Finish Altitude | + +### VEHICLE_CMD_CONDITION_DISTANCE (114) + +Delay mission state machine until within desired distance of next NAV point. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------ | +| 1 | | | Distance [m] | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_CONDITION_YAW (115) + +Reach a certain target angle. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------------------------------------------------- | +| 1 | deg | [0 : 360] | Target angle. 0 is north | +| 2 | deg/s | | Speed during yaw change | +| 3 | | [-1 : 1] | Direction: negative: counter clockwise, positive: clockwise | +| 4 | 1,0 | | Relative offset or absolute angle | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_CONDITION_LAST (159) + +NOP - This command is only used to mark the upper limit of the CONDITION commands in the enumeration. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_CONDITION_GATE (4501) + +Wait until passing a threshold. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------------------- | +| 1 | | | 2D coord mode: 0: Orthogonal to planned route | +| 2 | | | Altitude mode: 0: Ignore altitude | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Lat | +| 6 | | | Lon | +| 7 | | | Alt | + +### VEHICLE_CMD_DO_SET_MODE (176) + +Set system mode. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------- | +| 1 | | | Mode, as defined by ENUM MAV_MODE | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_JUMP (177) + +Jump to the desired command in the mission list. Repeat this action only the specified number of times. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------- | +| 1 | | | Sequence number | +| 2 | | | Repeat count | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_CHANGE_SPEED (178) + +Change speed and/or throttle set points. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ------------------------- | ------------------------------------------- | +| 1 | | [SPEED_TYPE](#SPEED_TYPE) | Speed type (0=Airspeed, 1=Ground Speed) | +| 2 | | | Speed (m/s, -1 indicates no change) | +| 3 | % | | Throttle ( Percent, -1 indicates no change) | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_HOME (179) + +Changes the home location either to the current location or a specified location. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | -------------------------------------------------------------- | +| 1 | | | Use current (1=use current location, 0=use specified location) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_DO_SET_PARAMETER (180) + +Set a system parameter. Caution! Use of this command requires knowledge of the numeric enumeration value of the parameter. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------- | +| 1 | | | Parameter number | +| 2 | | | Parameter value | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_RELAY (181) + +Set a relay to a condition. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------- | +| 1 | | | Relay number | +| 2 | | | Setting (1=on, 0=off, others possible depending on system hardware) | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_REPEAT_RELAY (182) + +Cycle a relay on and off for a desired number of cycles with a desired period. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------------------- | +| 1 | | | Relay number | +| 2 | | | Cycle count | +| 3 | s | | Cycle time (decimal seconds) | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_REPEAT_SERVO (184) + +Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------- | +| 1 | | | Servo number | +| 2 | us | | PWM rate (1000 to 2000 typical) | +| 3 | | | Cycle count | +| 4 | s | | Cycle time | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_FLIGHTTERMINATION (185) + +Terminate flight immediately. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------- | +| 1 | | | Flight termination activated if > 0.5 | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_CHANGE_ALTITUDE (186) + +Set the vehicle to Loiter mode and change the altitude to specified value. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------- | +| 1 | | | Altitude | +| 2 | | | Frame of new altitude | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_ACTUATOR (187) + +Sets actuators (e.g. servos) to a desired value. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Actuator 1 | +| 2 | | | Actuator 2 | +| 3 | | | Actuator 3 | +| 4 | | | Actuator 4 | +| 5 | | | Actuator 5 | +| 6 | | | Actuator 6 | +| 7 | | | Index | + +### VEHICLE_CMD_DO_LAND_START (189) + +Mission command to perform a landing. This is used as a marker in a mission to tell the autopilot where a sequence of mission items that represents a landing starts. It may also be sent via a COMMAND_LONG to trigger a landing, in which case the nearest (geographically) landing sequence in the mission will be used. The Latitude/Longitude is optional, and may be set to 0/0 if not needed. If specified then it will be used to help find the closest landing sequence. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_GO_AROUND (191) + +Mission command to safely abort an autonomous landing. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | m | | Altitude | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_REPOSITION (192) + +Reposition to specific WGS84 GPS position. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------ | +| 1 | m/s | | Ground speed | +| 2 | | | Bitmask | +| 3 | m | | Loiter radius for planes | +| 4 | deg | | Yaw | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_DO_PAUSE_CONTINUE (193) + +None + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_SET_ROI_LOCATION (195) + +Sets the region of interest (ROI) to a location. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Latitude | +| 6 | | | Longitude | +| 7 | | | Altitude | + +### VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET (196) + +Sets the region of interest (ROI) to be toward next waypoint, with optional pitch/roll/yaw offset. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Pitch offset from next waypoint | +| 6 | | | Roll offset from next waypoint | +| 7 | | | Yaw offset from next waypoint | + +### VEHICLE_CMD_DO_SET_ROI_NONE (197) + +Cancels any previous ROI command returning the vehicle/sensors to default flight characteristics. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_CONTROL_VIDEO (200) + +Control onboard camera system. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------------------------------------------------------------- | +| 1 | | | Camera ID (-1 for all) | +| 2 | | | Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw | +| 3 | | | Transmission mode: 0: video stream, >0: single images every n seconds (decimal seconds) | +| 4 | | | Recording: 0: disabled, 1: enabled compressed, 2: enabled raw | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_ROI (201) + +Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | --------------------------- | ----------------------------------------------------- | +| 1 | | [VEHICLE_ROI](#VEHICLE_ROI) | Region of interest mode. | +| 2 | | | MISSION index/ target ID. | +| 3 | | | ROI index (allows a vehicle to manage multiple ROI's) | +| 4 | | | Unused | +| 5 | | | x the location of the fixed ROI (see MAV_FRAME) | +| 6 | | | y | +| 7 | | | z | + +### VEHICLE_CMD_DO_DIGICAM_CONTROL (203) + +None + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_MOUNT_CONFIGURE (204) + +Mission command to configure a camera or antenna mount. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | --------------------------------- | ---------------------------------- | +| 1 | | [MAV_MOUNT_MODE](#MAV_MOUNT_MODE) | Mount operation mode | +| 2 | | | Stabilize roll? (1 = yes, 0 = no) | +| 3 | | | Stabilize pitch? (1 = yes, 0 = no) | +| 4 | | | stabilize yaw? (1 = yes, 0 = no) | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_MOUNT_CONTROL (205) + +Mission command to control a camera or antenna mount. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | --------------------------------- | --------------------------------------- | +| 1 | deg | | Pitch or lat, depending on mount mode. | +| 2 | deg | | Roll or lon depending on mount mode | +| 3 | deg | | /[m] Yaw or alt depending on mount mode | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | [MAV_MOUNT_MODE](#MAV_MOUNT_MODE) | + +### VEHICLE_CMD_DO_SET_CAM_TRIGG_DIST (206) + +Mission command to set TRIG_DIST for this flight. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------ | +| 1 | m | | Camera trigger distance | +| 2 | ms | | Shutter integration time | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_FENCE_ENABLE (207) + +Mission command to enable the geofence. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------------------- | +| 1 | | | enable? (0=disable, 1=enable) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_PARACHUTE (208) + +Mission command to trigger a parachute. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | | | action [@enum PARACHUTE_ACTION] (0=disable, 1=enable, 2=release, for some systems see [@enum PARACHUTE_ACTION], not in general message set.) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_MOTOR_TEST (209) + +Motor test command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------- | +| 1 | | | Instance (@range 1, ) | +| 2 | | | throttle type | +| 3 | | | throttle | +| 4 | | | timeout [s] | +| 5 | | | Motor count | +| 6 | | | Test order | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_INVERTED_FLIGHT (210) + +Change to/from inverted flight. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------- | +| 1 | | | inverted (0=normal, 1=inverted) | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_GRIPPER (211) + +Command to operate a gripper. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_AUTOTUNE_ENABLE (212) + +Enable autotune module. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | 1 to enable | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL (214) + +Mission command to set TRIG_INTERVAL for this flight. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------------------- | +| 1 | m | | Camera trigger distance | +| 2 | | | Shutter integration time (ms) | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT (220) + +Mission command to control a camera or antenna mount, using a quaternion as reference. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------ | +| 1 | | | q1 - quaternion param #1, w (1 in null-rotation) | +| 2 | | | q2 - quaternion param #2, x (0 in null-rotation) | +| 3 | | | q3 - quaternion param #3, y (0 in null-rotation) | +| 4 | | | q4 - quaternion param #4, z (0 in null-rotation) | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_GUIDED_MASTER (221) + +Set id of master controller. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------ | +| 1 | | | System ID | +| 2 | | | Component ID | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_GUIDED_LIMITS (222) + +Set limits for external control. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | s | | Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout | +| 2 | m | | Absolute altitude min(AMSL) - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit | +| 3 | m | | Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit | +| 4 | m | | Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_LAST (240) + +NOP - This command is only used to mark the upper limit of the DO commands in the enumeration. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_PREFLIGHT_CALIBRATION (241) + +Trigger calibration. This command will be only accepted if in pre-flight mode. See MAVLink spec MAV_CMD_PREFLIGHT_CALIBRATION. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_PREFLIGHT_SET_SENSOR_OFFSETS (242) + +Set sensor offsets. This command will be only accepted if in pre-flight mode. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------------------------------------------ | +| 1 | | | Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow | +| 2 | | | X axis offset (or generic dimension 1), in the sensor's raw units | +| 3 | | | Y axis offset (or generic dimension 2), in the sensor's raw units | +| 4 | | | Z axis offset (or generic dimension 3), in the sensor's raw units | +| 5 | | | Generic dimension 4, in the sensor's raw units | +| 6 | | | Generic dimension 5, in the sensor's raw units | +| 7 | | | Generic dimension 6, in the sensor's raw units | + +### VEHICLE_CMD_PREFLIGHT_UAVCAN (243) + +UAVCAN configuration. If param 1 == 1 actuator mapping and direction assignment should be started. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_PREFLIGHT_STORAGE (245) + +Request storage of different parameter values and logs. This command will be only accepted if in pre-flight mode. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------------------------------------ | +| 1 | | | Parameter storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM | +| 2 | | | Mission storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_PREFLIGHT_REBOOT_SHUTDOWN (246) + +Request the reboot or shutdown of system components. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------------------------------------------------------------------------------------- | +| 1 | | | 0: Do nothing for autopilot, 1: Reboot autopilot, 2: Shutdown autopilot. | +| 2 | | | 0: Do nothing for onboard computer, 1: Reboot onboard computer, 2: Shutdown onboard computer. | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_OBLIQUE_SURVEY (260) + +Mission command to set a Camera Auto Mount Pivoting Oblique Survey for this flight. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------- | +| 1 | m | | Camera trigger distance | +| 2 | ms | | Shutter integration time | +| 3 | | | Camera minimum trigger interval | +| 4 | | | Number of positions | +| 5 | | | Roll | +| 6 | | | Pitch | +| 7 | | | Unused | + +### VEHICLE_CMD_DO_SET_STANDARD_MODE (262) + +Enable the specified standard MAVLink mode. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------------- | +| 1 | | | MAV_STANDARD_MODE | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_GIMBAL_DEVICE_INFORMATION (283) + +Command to ask information about a low level gimbal. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_MISSION_START (300) + +Start running a mission. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------------------------------------------------------------------------- | +| 1 | | | first_item: the first mission item to run | +| 2 | | | last_item: the last mission item to run (after this item is run, the mission ends) | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_ACTUATOR_TEST (310) + +Actuator testing command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------- | +| 1 | | [-1 : 1] | value | +| 2 | s | | timeout | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | output function | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_CONFIGURE_ACTUATOR (311) + +Actuator configuration command. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | --------------- | +| 1 | | | configuration | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | output function | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_COMPONENT_ARM_DISARM (400) + +Arms / Disarms a component. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ---------------------- | +| 1 | | | 1 to arm, 0 to disarm. | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_RUN_PREARM_CHECKS (401) + +Instructs a target system to run pre-arm checks. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_INJECT_FAILURE (420) + +Inject artificial failure for testing purposes. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_START_RX_PAIR (500) + +Starts receiver pairing. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | -------------------------------- | +| 1 | | | 0:Spektrum | +| 2 | | | 0:Spektrum DSM2, 1:Spektrum DSMX | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_REQUEST_MESSAGE (512) + +Request to send a single instance of the specified message. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_REQUEST_CAMERA_INFORMATION (521) + +Request camera information (CAMERA_INFORMATION). + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------- | +| 1 | | | 0: No action 1: Request camera capabilities | +| 2 | | | Reserved (all remaining params) | +| 3 | | | Reserved (default:0) | +| 4 | | | Reserved (default:0) | +| 5 | | | Reserved (default:0) | +| 6 | | | Reserved (default:0) | +| 7 | | | Reserved (default:0) | + +### VEHICLE_CMD_SET_CAMERA_MODE (530) + +Set camera capture mode (photo, video, etc.). + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_SET_CAMERA_ZOOM (531) + +Set camera zoom. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_SET_CAMERA_FOCUS (532) + +None + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE (620) + +Set an external estimate of vehicle attitude in degrees. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW (1000) + +Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE (1001) + +Gimbal configuration to set which sysid/compid is in primary and secondary control. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_IMAGE_START_CAPTURE (2000) + +Start image capture sequence. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_TRIGGER_CONTROL (2003) + +Enable or disable on-board camera triggering system. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_VIDEO_START_CAPTURE (2500) + +Start a video capture. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_VIDEO_STOP_CAPTURE (2501) + +Stop the current video capture. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_LOGGING_START (2510) + +Start streaming ULog data. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_LOGGING_STOP (2511) + +Stop streaming ULog data. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_CONTROL_HIGH_LATENCY (2600) + +Control starting/stopping transmitting data over the high latency link. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_VTOL_TRANSITION (3000) + +Command VTOL transition. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE (5300) + +Command safety on/off. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | -------------------------------------------------------------------------------- | +| 1 | | | 1 to activate safety, 0 to deactivate safety and allow control surface movements | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +### VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST (3001) + +Request arm authorization. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY (30001) + +Prepare a payload deployment in the flight plan. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY (30002) + +Control a pre-programmed payload deployment. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_FIXED_MAG_CAL_YAW (42006) + +Magnetometer calibration based on provided known yaw. This allows for fast calibration using WMM field tables in the vehicle, given only the known yaw of the vehicle. If Latitude and longitude are both zero then use the current vehicle location. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_DO_WINCH (42600) + +Command to operate winch. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_EXTERNAL_POSITION_ESTIMATE (43003) + +External reset of estimator global position when dead reckoning. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_EXTERNAL_WIND_ESTIMATE (43004) + +None + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_PX4_INTERNAL_START (65537) + +Start of PX4 internal only vehicle commands (> UINT16_MAX). + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | ? | +| 2 | | | ? | +| 3 | | | ? | +| 4 | | | ? | +| 5 | | | ? | +| 6 | | | ? | +| 7 | | | ? | + +### VEHICLE_CMD_SET_GPS_GLOBAL_ORIGIN (100000) + +Sets the GPS coordinates of the vehicle local origin (0,0,0) position. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ------------------------------------------------ | +| 1 | | | Unused | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Latitude (WGS-84) | +| 6 | | | Longitude (WGS-84) | +| 7 | m | | Altitude (AMSL from GNSS, positive above ground) | + +### VEHICLE_CMD_SET_NAV_STATE (100001) + +Change mode by specifying nav_state directly. + +| Param | Units | Range/Enum | Description | +| ----- | ----- | ---------- | ----------- | +| 1 | | | nav_state | +| 2 | | | Unused | +| 3 | | | Unused | +| 4 | | | Unused | +| 5 | | | Unused | +| 6 | | | Unused | +| 7 | | | Unused | + +## Enums + +### ORBIT_YAW_BEHAVIOUR {#ORBIT_YAW_BEHAVIOUR} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------------------------- | ------- | ----- | ----------- | +| ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TO_CIRCLE_CENTER | `uint8` | 0 | +| ORBIT_YAW_BEHAVIOUR_HOLD_INITIAL_HEADING | `uint8` | 1 | +| ORBIT_YAW_BEHAVIOUR_UNCONTROLLED | `uint8` | 2 | +| ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TANGENT_TO_CIRCLE | `uint8` | 3 | +| ORBIT_YAW_BEHAVIOUR_RC_CONTROLLED | `uint8` | 4 | +| ORBIT_YAW_BEHAVIOUR_UNCHANGED | `uint8` | 5 | + +### VEHICLE_ROI {#VEHICLE_ROI} + +| Name | Type | Value | Description | +| --------------------------------------------------------- | ------- | ----- | ---------------------------- | +| VEHICLE_ROI_NONE | `uint8` | 0 | No region of interest. | +| VEHICLE_ROI_WPNEXT | `uint8` | 1 | Point toward next MISSION. | +| VEHICLE_ROI_WPINDEX | `uint8` | 2 | Point toward given MISSION. | +| VEHICLE_ROI_LOCATION | `uint8` | 3 | Point toward fixed location. | +| VEHICLE_ROI_TARGET | `uint8` | 4 | Point toward target. | +| VEHICLE_ROI_ENUM_END | `uint8` | 5 | + +### SPEED_TYPE {#SPEED_TYPE} + +| Name | Type | Value | Description | +| ----------------------------------------------------------------- | ------- | ----- | ----------- | +| SPEED_TYPE_AIRSPEED | `uint8` | 0 | +| SPEED_TYPE_GROUNDSPEED | `uint8` | 1 | +| SPEED_TYPE_CLIMB_SPEED | `uint8` | 2 | +| SPEED_TYPE_DESCEND_SPEED | `uint8` | 3 | + +### MAV_MOUNT_MODE {#MAV_MOUNT_MODE} + +| Name | Type | Value | Description | +| ---- | ---- | ----- | ----------- | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------------------------------------------------------ | +| MESSAGE_VERSION | `uint32` | 0 | +| PREFLIGHT_CALIBRATION_TEMPERATURE_CALIBRATION | `uint16` | 3 | Param value for VEHICLE_CMD_PREFLIGHT_CALIBRATION to start temperature calibration. | +| VEHICLE_MOUNT_MODE_RETRACT | `uint8` | 0 | Load and keep safe position (Roll,Pitch,Yaw) from permanent memory and stop stabilization. | +| VEHICLE_MOUNT_MODE_NEUTRAL | `uint8` | 1 | Load and keep neutral position (Roll,Pitch,Yaw) from permanent memory. | +| VEHICLE_MOUNT_MODE_MAVLINK_TARGETING | `uint8` | 2 | Load neutral position and start MAVLink Roll,Pitch,Yaw control with stabilization. | +| VEHICLE_MOUNT_MODE_RC_TARGETING | `uint8` | 3 | Load neutral position and start RC Roll,Pitch,Yaw control with stabilization. | +| VEHICLE_MOUNT_MODE_GPS_POINT | `uint8` | 4 | Load neutral position and start to point to Lat,Lon,Alt. | +| VEHICLE_MOUNT_MODE_ENUM_END | `uint8` | 5 | +| PARACHUTE_ACTION_DISABLE | `uint8` | 0 | +| PARACHUTE_ACTION_ENABLE | `uint8` | 1 | +| PARACHUTE_ACTION_RELEASE | `uint8` | 2 | +| FAILURE_UNIT_SENSOR_GYRO | `uint8` | 0 | +| FAILURE_UNIT_SENSOR_ACCEL | `uint8` | 1 | +| FAILURE_UNIT_SENSOR_MAG | `uint8` | 2 | +| FAILURE_UNIT_SENSOR_BARO | `uint8` | 3 | +| FAILURE_UNIT_SENSOR_GPS | `uint8` | 4 | +| FAILURE_UNIT_SENSOR_OPTICAL_FLOW | `uint8` | 5 | +| FAILURE_UNIT_SENSOR_VIO | `uint8` | 6 | +| FAILURE_UNIT_SENSOR_DISTANCE_SENSOR | `uint8` | 7 | +| FAILURE_UNIT_SENSOR_AIRSPEED | `uint8` | 8 | +| FAILURE_UNIT_SYSTEM_BATTERY | `uint8` | 100 | +| FAILURE_UNIT_SYSTEM_MOTOR | `uint8` | 101 | +| FAILURE_UNIT_SYSTEM_SERVO | `uint8` | 102 | +| FAILURE_UNIT_SYSTEM_AVOIDANCE | `uint8` | 103 | +| FAILURE_UNIT_SYSTEM_RC_SIGNAL | `uint8` | 104 | +| FAILURE_UNIT_SYSTEM_MAVLINK_SIGNAL | `uint8` | 105 | +| FAILURE_TYPE_OK | `uint8` | 0 | +| FAILURE_TYPE_OFF | `uint8` | 1 | +| FAILURE_TYPE_STUCK | `uint8` | 2 | +| FAILURE_TYPE_GARBAGE | `uint8` | 3 | +| FAILURE_TYPE_WRONG | `uint8` | 4 | +| FAILURE_TYPE_SLOW | `uint8` | 5 | +| FAILURE_TYPE_DELAYED | `uint8` | 6 | +| FAILURE_TYPE_INTERMITTENT | `uint8` | 7 | +| ARMING_ACTION_DISARM | `int8` | 0 | +| ARMING_ACTION_ARM | `int8` | 1 | +| GRIPPER_ACTION_RELEASE | `uint8` | 0 | +| GRIPPER_ACTION_GRAB | `uint8` | 1 | +| SAFETY_OFF | `uint8` | 0 | +| SAFETY_ON | `uint8` | 1 | +| ORB_QUEUE_LENGTH | `uint8` | 8 | +| COMPONENT_MODE_EXECUTOR_START | `uint16` | 1000 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleCommand.msg) + +::: details Click here to see original file ```c # Vehicle Command uORB message. Used for commanding a mission / action / etc. @@ -28,7 +1600,7 @@ uint16 VEHICLE_CMD_DO_ORBIT = 34 # Start orbiting on the circumference of a circ uint16 VEHICLE_CMD_DO_FIGUREEIGHT = 35 # Start flying on the outline of a figure eight defined by the parameters. |[m] Major radius|[m] Minor radius|[m/s] Velocity|Orientation|Latitude/X|Longitude/Y|Altitude/Z| uint16 VEHICLE_CMD_NAV_ROI = 80 # Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |[@enum VEHICLE_ROI] Region of interest mode.|MISSION index/ target ID.|ROI index (allows a vehicle to manage multiple ROI's)|Unused|x the location of the fixed ROI (see MAV_FRAME)|y|z| uint16 VEHICLE_CMD_NAV_PATHPLANNING = 81 # Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning|0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid|Unused|[deg] [@range 0, 360] Yaw angle at goal, in compass degrees|Latitude/X of goal|Longitude/Y of goal|Altitude/Z of goal| -uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Unused|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| +uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Transition heading, 0: Default, 3: Use specified transition heading|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_VTOL_LAND = 85 # Transition to MC and land at location. |Unused|Unused|Unused|Desired yaw angle.|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_GUIDED_LIMITS = 90 # Set limits for external control. |[s] Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout|[m] Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit|[m] Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit|[m] Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit|Unused|Unused|Unused| uint16 VEHICLE_CMD_NAV_GUIDED_MASTER = 91 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -69,6 +1641,7 @@ uint16 VEHICLE_CMD_DO_PARACHUTE=208 # Mission command to trigger a parachute. |a uint16 VEHICLE_CMD_DO_MOTOR_TEST=209 # Motor test command. |Instance (@range 1, )|throttle type|throttle|timeout [s]|Motor count|Test order|Unused| uint16 VEHICLE_CMD_DO_INVERTED_FLIGHT=210 # Change to/from inverted flight. |inverted (0=normal, 1=inverted)|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GRIPPER = 211 # Command to operate a gripper. +uint16 VEHICLE_CMD_DO_AUTOTUNE_ENABLE = 212 # Enable autotune module. |1 to enable|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL=214 # Mission command to set TRIG_INTERVAL for this flight. |[m] Camera trigger distance|Shutter integration time (ms)|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT=220 # Mission command to control a camera or antenna mount, using a quaternion as reference. |q1 - quaternion param #1, w (1 in null-rotation)|q2 - quaternion param #2, x (0 in null-rotation)|q3 - quaternion param #3, y (0 in null-rotation)|q4 - quaternion param #4, z (0 in null-rotation)|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GUIDED_MASTER=221 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -96,6 +1669,7 @@ uint16 VEHICLE_CMD_REQUEST_CAMERA_INFORMATION = 521 # Request camera information uint16 VEHICLE_CMD_SET_CAMERA_MODE = 530 # Set camera capture mode (photo, video, etc.). uint16 VEHICLE_CMD_SET_CAMERA_ZOOM = 531 # Set camera zoom. uint16 VEHICLE_CMD_SET_CAMERA_FOCUS = 532 +uint16 VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE = 620 # Set an external estimate of vehicle attitude in degrees. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000 # Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE = 1001 # Gimbal configuration to set which sysid/compid is in primary and secondary control. uint16 VEHICLE_CMD_IMAGE_START_CAPTURE = 2000 # Start image capture sequence. @@ -106,6 +1680,7 @@ uint16 VEHICLE_CMD_LOGGING_START = 2510 # Start streaming ULog data. uint16 VEHICLE_CMD_LOGGING_STOP = 2511 # Stop streaming ULog data. uint16 VEHICLE_CMD_CONTROL_HIGH_LATENCY = 2600 # Control starting/stopping transmitting data over the high latency link. uint16 VEHICLE_CMD_DO_VTOL_TRANSITION = 3000 # Command VTOL transition. +uint16 VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE = 5300 # Command safety on/off. |1 to activate safety, 0 to deactivate safety and allow control surface movements|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST = 3001 # Request arm authorization. uint16 VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY = 30001 # Prepare a payload deployment in the flight plan. uint16 VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY = 30002 # Control a pre-programmed payload deployment. @@ -185,6 +1760,10 @@ int8 ARMING_ACTION_ARM = 1 uint8 GRIPPER_ACTION_RELEASE = 0 uint8 GRIPPER_ACTION_GRAB = 1 +# Used as param1 in DO_SET_SAFETY_SWITCH_STATE command. +uint8 SAFETY_OFF = 0 +uint8 SAFETY_ON = 1 + uint8 ORB_QUEUE_LENGTH = 8 float32 param1 # Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. @@ -205,5 +1784,6 @@ bool from_external uint16 COMPONENT_MODE_EXECUTOR_START = 1000 # TOPICS vehicle_command gimbal_v1_command vehicle_command_mode_executor - ``` + +::: diff --git a/docs/en/msg_docs/VehicleCommandAck.md b/docs/en/msg_docs/VehicleCommandAck.md index e40b7bc87c..a06d896283 100644 --- a/docs/en/msg_docs/VehicleCommandAck.md +++ b/docs/en/msg_docs/VehicleCommandAck.md @@ -1,10 +1,51 @@ +--- +pageClass: is-wide-page +--- + # VehicleCommandAck (UORB message) -Vehicle Command Ackonwledgement uORB message. -Used for acknowledging the vehicle command being received. -Follows the MAVLink COMMAND_ACK message definition +Vehicle Command Ackonwledgement uORB message. Used for acknowledging the vehicle command being received. Follows the MAVLink COMMAND_ACK message definition. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleCommandAck.msg) +**TOPICS:** vehicle_commandack + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | -------- | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| command | `uint32` | | | Command that is being acknowledged | +| result | `uint8` | | | Command result | +| result_param1 | `uint8` | | | Also used as progress[%], it can be set with the reason why the command was denied, or the progress percentage when result is MAV_RESULT_IN_PROGRESS | +| result_param2 | `int32` | | | Additional parameter of the result, example: which parameter of MAV_CMD_NAV_WAYPOINT caused it to be denied. | +| target_system | `uint8` | | | +| target_component | `uint16` | | | Target component / mode executor | +| from_external | `bool` | | | Indicates if the command came from an external source | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------- | -------- | ----- | --------------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| VEHICLE_CMD_RESULT_ACCEPTED | `uint8` | 0 | Command ACCEPTED and EXECUTED | +| VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED | `uint8` | 1 | Command TEMPORARY REJECTED/DENIED | +| VEHICLE_CMD_RESULT_DENIED | `uint8` | 2 | Command PERMANENTLY DENIED | +| VEHICLE_CMD_RESULT_UNSUPPORTED | `uint8` | 3 | Command UNKNOWN/UNSUPPORTED | +| VEHICLE_CMD_RESULT_FAILED | `uint8` | 4 | Command executed, but failed | +| VEHICLE_CMD_RESULT_IN_PROGRESS | `uint8` | 5 | Command being executed | +| VEHICLE_CMD_RESULT_CANCELLED | `uint8` | 6 | Command Canceled | +| ARM_AUTH_DENIED_REASON_GENERIC | `uint16` | 0 | +| ARM_AUTH_DENIED_REASON_NONE | `uint16` | 1 | +| ARM_AUTH_DENIED_REASON_INVALID_WAYPOINT | `uint16` | 2 | +| ARM_AUTH_DENIED_REASON_TIMEOUT | `uint16` | 3 | +| ARM_AUTH_DENIED_REASON_AIRSPACE_IN_USE | `uint16` | 4 | +| ARM_AUTH_DENIED_REASON_BAD_WEATHER | `uint16` | 5 | +| ORB_QUEUE_LENGTH | `uint8` | 8 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleCommandAck.msg) + +::: details Click here to see original file ```c # Vehicle Command Ackonwledgement uORB message. @@ -32,7 +73,7 @@ uint16 ARM_AUTH_DENIED_REASON_TIMEOUT = 3 uint16 ARM_AUTH_DENIED_REASON_AIRSPACE_IN_USE = 4 uint16 ARM_AUTH_DENIED_REASON_BAD_WEATHER = 5 -uint8 ORB_QUEUE_LENGTH = 4 +uint8 ORB_QUEUE_LENGTH = 8 uint32 command # Command that is being acknowledged uint8 result # Command result @@ -42,5 +83,6 @@ uint8 target_system uint16 target_component # Target component / mode executor bool from_external # Indicates if the command came from an external source - ``` + +::: diff --git a/docs/en/msg_docs/VehicleConstraints.md b/docs/en/msg_docs/VehicleConstraints.md index 266ac8911f..ecca9d3576 100644 --- a/docs/en/msg_docs/VehicleConstraints.md +++ b/docs/en/msg_docs/VehicleConstraints.md @@ -1,9 +1,27 @@ +--- +pageClass: is-wide-page +--- + # VehicleConstraints (UORB message) -Local setpoint constraints in NED frame -setting something to NaN means that no limit is provided +Local setpoint constraints in NED frame. setting something to NaN means that no limit is provided. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleConstraints.msg) +**TOPICS:** vehicle_constraints + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | --------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| speed_up | `float32` | | | in meters/sec | +| speed_down | `float32` | | | in meters/sec | +| want_takeoff | `bool` | | | tell the controller to initiate takeoff when idling (ignored during flight) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleConstraints.msg) + +::: details Click here to see original file ```c # Local setpoint constraints in NED frame @@ -15,5 +33,6 @@ float32 speed_up # in meters/sec float32 speed_down # in meters/sec bool want_takeoff # tell the controller to initiate takeoff when idling (ignored during flight) - ``` + +::: diff --git a/docs/en/msg_docs/VehicleControlMode.md b/docs/en/msg_docs/VehicleControlMode.md index 0c6d062938..e122049c8c 100644 --- a/docs/en/msg_docs/VehicleControlMode.md +++ b/docs/en/msg_docs/VehicleControlMode.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # VehicleControlMode (UORB message) +**TOPICS:** vehicle_control_mode config_control_setpoints +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleControlMode.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------------------------- | -------- | ------------ | ---------- | ------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| flag_armed | `bool` | | | synonym for actuator_armed.armed | +| flag_multicopter_position_control_enabled | `bool` | | | +| flag_control_manual_enabled | `bool` | | | true if manual input is mixed in | +| flag_control_auto_enabled | `bool` | | | true if onboard autopilot should act | +| flag_control_offboard_enabled | `bool` | | | true if offboard control should be used | +| flag_control_position_enabled | `bool` | | | true if position is controlled | +| flag_control_velocity_enabled | `bool` | | | true if horizontal velocity (implies direction) is controlled | +| flag_control_altitude_enabled | `bool` | | | true if altitude is controlled | +| flag_control_climb_rate_enabled | `bool` | | | true if climb rate is controlled | +| flag_control_acceleration_enabled | `bool` | | | true if acceleration is controlled | +| flag_control_attitude_enabled | `bool` | | | true if attitude stabilization is mixed in | +| flag_control_rates_enabled | `bool` | | | true if rates are stabilized | +| flag_control_allocation_enabled | `bool` | | | true if control allocation is enabled | +| flag_control_termination_enabled | `bool` | | | true if flighttermination is enabled | +| source_id | `uint8` | | | Mode ID (nav_state) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleControlMode.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -29,5 +64,6 @@ bool flag_control_termination_enabled # true if flighttermination is enabled uint8 source_id # Mode ID (nav_state) # TOPICS vehicle_control_mode config_control_setpoints - ``` + +::: diff --git a/docs/en/msg_docs/VehicleGlobalPosition.md b/docs/en/msg_docs/VehicleGlobalPosition.md index c3e4147201..67ed199cd2 100644 --- a/docs/en/msg_docs/VehicleGlobalPosition.md +++ b/docs/en/msg_docs/VehicleGlobalPosition.md @@ -1,12 +1,47 @@ +--- +pageClass: is-wide-page +--- + # VehicleGlobalPosition (UORB message) -Fused global position in WGS84. -This struct contains global position estimation. It is not the raw GPS -measurement (@see vehicle_gps_position). This topic is usually published by the position -estimator, which will take more sources of information into account than just GPS, -e.g. control inputs of the vehicle in a Kalman-filter implementation. +Fused global position in WGS84. This struct contains global position estimation. It is not the raw GPS. measurement (@see vehicle_gps_position). This topic is usually published by the position. estimator, which will take more sources of information into account than just GPS,. e.g. control inputs of the vehicle in a Kalman-filter implementation. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleGlobalPosition.msg) +**TOPICS:** vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position estimator_global_position aux_global_position + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------- | --------- | ------------ | ---------- | ----------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| lat | `float64` | | | Latitude, (degrees) | +| lon | `float64` | | | Longitude, (degrees) | +| alt | `float32` | | | Altitude AMSL, (meters) | +| alt_ellipsoid | `float32` | | | Altitude above ellipsoid, (meters) | +| lat_lon_valid | `bool` | | | +| alt_valid | `bool` | | | +| delta_alt | `float32` | | | Reset delta for altitude | +| delta_terrain | `float32` | | | Reset delta for terrain | +| lat_lon_reset_counter | `uint8` | | | Counter for reset events on horizontal position coordinates | +| alt_reset_counter | `uint8` | | | Counter for reset events on altitude | +| terrain_reset_counter | `uint8` | | | Counter for reset events on terrain | +| eph | `float32` | | | Standard deviation of horizontal position error, (metres) | +| epv | `float32` | | | Standard deviation of vertical position error, (metres) | +| terrain_alt | `float32` | | | Terrain altitude WGS84, (metres) | +| terrain_alt_valid | `bool` | | | Terrain altitude estimate is valid | +| dead_reckoning | `bool` | | | True if this position is estimated through dead-reckoning | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleGlobalPosition.msg) + +::: details Click here to see original file ```c # Fused global position in WGS84. @@ -46,5 +81,6 @@ bool dead_reckoning # True if this position is estimated through dead-reckoning # TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position # TOPICS estimator_global_position # TOPICS aux_global_position - ``` + +::: diff --git a/docs/en/msg_docs/VehicleImu.md b/docs/en/msg_docs/VehicleImu.md index 5c3856f190..005cf34ae6 100644 --- a/docs/en/msg_docs/VehicleImu.md +++ b/docs/en/msg_docs/VehicleImu.md @@ -1,8 +1,43 @@ +--- +pageClass: is-wide-page +--- + # VehicleImu (UORB message) IMU readings in SI-unit form. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleImu.msg) +**TOPICS:** vehicle_imu + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| accel_device_id | `uint32` | | | Accelerometer unique device ID for the sensor that does not change between power cycles | +| gyro_device_id | `uint32` | | | Gyroscope unique device ID for the sensor that does not change between power cycles | +| delta_angle | `float32[3]` | | | delta angle about the FRD body frame XYZ-axis in rad over the integration time frame (delta_angle_dt) | +| delta_velocity | `float32[3]` | | | delta velocity in the FRD body frame XYZ-axis in m/s over the integration time frame (delta_velocity_dt) | +| delta_angle_dt | `uint32` | | | integration period in microseconds | +| delta_velocity_dt | `uint32` | | | integration period in microseconds | +| delta_angle_clipping | `uint8` | | | bitfield indicating if there was any gyro clipping (per axis) during the integration time frame | +| delta_velocity_clipping | `uint8` | | | bitfield indicating if there was any accelerometer clipping (per axis) during the integration time frame | +| accel_calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever accelermeter calibration changes. | +| gyro_calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever rate gyro calibration changes. | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------- | ------- | ----- | ----------- | +| CLIPPING_X | `uint8` | 1 | +| CLIPPING_Y | `uint8` | 2 | +| CLIPPING_Z | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleImu.msg) + +::: details Click here to see original file ```c # IMU readings in SI-unit form. @@ -28,5 +63,6 @@ uint8 delta_velocity_clipping # bitfield indicating if there was any accelerom uint8 accel_calibration_count # Calibration changed counter. Monotonically increases whenever accelermeter calibration changes. uint8 gyro_calibration_count # Calibration changed counter. Monotonically increases whenever rate gyro calibration changes. - ``` + +::: diff --git a/docs/en/msg_docs/VehicleImuStatus.md b/docs/en/msg_docs/VehicleImuStatus.md index 1d26a7af36..bd7f1c89ec 100644 --- a/docs/en/msg_docs/VehicleImuStatus.md +++ b/docs/en/msg_docs/VehicleImuStatus.md @@ -1,8 +1,41 @@ +--- +pageClass: is-wide-page +--- + # VehicleImuStatus (UORB message) +**TOPICS:** vehicle_imustatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleImuStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | ------------ | ------------ | ---------- | ------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| accel_device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| gyro_device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| accel_clipping | `uint32[3]` | | | total clipping per axis | +| gyro_clipping | `uint32[3]` | | | total clipping per axis | +| accel_error_count | `uint32` | | | +| gyro_error_count | `uint32` | | | +| accel_rate_hz | `float32` | | | +| gyro_rate_hz | `float32` | | | +| accel_raw_rate_hz | `float32` | | | full raw sensor sample rate (Hz) | +| gyro_raw_rate_hz | `float32` | | | full raw sensor sample rate (Hz) | +| accel_vibration_metric | `float32` | | | high frequency vibration level in the accelerometer data (m/s/s) | +| gyro_vibration_metric | `float32` | | | high frequency vibration level in the gyro data (rad/s) | +| delta_angle_coning_metric | `float32` | | | average IMU delta angle coning correction (rad^2) | +| mean_accel | `float32[3]` | | | average accelerometer readings since last publication | +| mean_gyro | `float32[3]` | | | average gyroscope readings since last publication | +| var_accel | `float32[3]` | | | accelerometer variance since last publication | +| var_gyro | `float32[3]` | | | gyroscope variance since last publication | +| temperature_accel | `float32` | | | +| temperature_gyro | `float32` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleImuStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -33,5 +66,6 @@ float32[3] var_gyro # gyroscope variance since last publication float32 temperature_accel float32 temperature_gyro - ``` + +::: diff --git a/docs/en/msg_docs/VehicleLandDetected.md b/docs/en/msg_docs/VehicleLandDetected.md index bd53ce680f..1756a382f1 100644 --- a/docs/en/msg_docs/VehicleLandDetected.md +++ b/docs/en/msg_docs/VehicleLandDetected.md @@ -1,8 +1,40 @@ +--- +pageClass: is-wide-page +--- + # VehicleLandDetected (UORB message) +**TOPICS:** vehicle_landdetected +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLandDetected.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------------------- | -------- | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| freefall | `bool` | | | true if vehicle is currently in free-fall | +| ground_contact | `bool` | | | true if vehicle has ground contact but is not landed (1. stage) | +| maybe_landed | `bool` | | | true if the vehicle might have landed (2. stage) | +| landed | `bool` | | | true if vehicle is currently landed on the ground (3. stage) | +| in_ground_effect | `bool` | | | indicates if from the perspective of the landing detector the vehicle might be in ground effect (baro). This flag will become true if the vehicle is not moving horizontally and is descending (crude assumption that user is landing). | +| in_descend | `bool` | | | +| has_low_throttle | `bool` | | | +| vertical_movement | `bool` | | | +| horizontal_movement | `bool` | | | +| rotational_movement | `bool` | | | +| close_to_ground_or_skipped_check | `bool` | | | +| at_rest | `bool` | | | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLandDetected.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -26,5 +58,6 @@ bool rotational_movement bool close_to_ground_or_skipped_check bool at_rest - ``` + +::: diff --git a/docs/en/msg_docs/VehicleLocalPosition.md b/docs/en/msg_docs/VehicleLocalPosition.md index af84dc1ddb..855cb89910 100644 --- a/docs/en/msg_docs/VehicleLocalPosition.md +++ b/docs/en/msg_docs/VehicleLocalPosition.md @@ -1,9 +1,85 @@ +--- +pageClass: is-wide-page +--- + # VehicleLocalPosition (UORB message) -Fused local position in NED. -The coordinate system origin is the vehicle position at the time when the EKF2-module was started. +Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLocalPosition.msg) +**TOPICS:** vehicle_local_position vehicle_local_position_groundtruth external_ins_local_position estimator_local_position + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | ------------ | ------------ | ---------- | ----------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| xy_valid | `bool` | | | true if x and y are valid | +| z_valid | `bool` | | | true if z is valid | +| v_xy_valid | `bool` | | | true if vx and vy are valid | +| v_z_valid | `bool` | | | true if vz is valid | +| x | `float32` | | | North position in NED earth-fixed frame, (metres) | +| y | `float32` | | | East position in NED earth-fixed frame, (metres) | +| z | `float32` | | | Down position (negative altitude) in NED earth-fixed frame, (metres) | +| delta_xy | `float32[2]` | | | Amount of lateral shift of position estimate in latest reset (in x and y) [m] | +| xy_reset_counter | `uint8` | | | Index of latest lateral position estimate reset | +| delta_z | `float32` | | | Amount of vertical shift of position estimate in latest reset [m] | +| z_reset_counter | `uint8` | | | Index of latest vertical position estimate reset | +| vx | `float32` | | | North velocity in NED earth-fixed frame, (metres/sec) | +| vy | `float32` | | | East velocity in NED earth-fixed frame, (metres/sec) | +| vz | `float32` | | | Down velocity in NED earth-fixed frame, (metres/sec) | +| z_deriv | `float32` | | | Down position time derivative in NED earth-fixed frame, (metres/sec) | +| delta_vxy | `float32[2]` | | | Amount of lateral shift of velocity estimate in latest reset (in x and y) [m/s] | +| vxy_reset_counter | `uint8` | | | Index of latest vertical velocity estimate reset | +| delta_vz | `float32` | | | Amount of vertical shift of velocity estimate in latest reset [m/s] | +| vz_reset_counter | `uint8` | | | Index of latest vertical velocity estimate reset | +| ax | `float32` | | | North velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| ay | `float32` | | | East velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| az | `float32` | | | Down velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| heading | `float32` | | | Euler yaw angle transforming the tangent plane relative to NED earth-fixed frame, -PI..+PI, (radians) | +| heading_var | `float32` | | | +| unaided_heading | `float32` | | | Same as heading but generated by integrating corrected gyro data only | +| delta_heading | `float32` | | | Heading delta caused by latest heading reset [rad] | +| heading_reset_counter | `uint8` | | | Index of latest heading reset | +| heading_good_for_control | `bool` | | | +| tilt_var | `float32` | | | +| xy_global | `bool` | | | true if position (x, y) has a valid global reference (ref_lat, ref_lon) | +| z_global | `bool` | | | true if z has a valid global reference (ref_alt) | +| ref_timestamp | `uint64` | | | Time when reference position was set since system start, (microseconds) | +| ref_lat | `float64` | | | Reference point latitude, (degrees) | +| ref_lon | `float64` | | | Reference point longitude, (degrees) | +| ref_alt | `float32` | | | Reference altitude AMSL, (metres) | +| dist_bottom_valid | `bool` | | | true if distance to bottom surface is valid | +| dist_bottom | `float32` | | | Distance from from bottom surface to ground, (metres) | +| dist_bottom_var | `float32` | | | terrain estimate variance (m^2) | +| delta_dist_bottom | `float32` | | | Amount of vertical shift of dist bottom estimate in latest reset [m] | +| dist_bottom_reset_counter | `uint8` | | | Index of latest dist bottom estimate reset | +| dist_bottom_sensor_bitfield | `uint8` | | | bitfield indicating what type of sensor is used to estimate dist_bottom | +| eph | `float32` | | | Standard deviation of horizontal position error, (metres) | +| epv | `float32` | | | Standard deviation of vertical position error, (metres) | +| evh | `float32` | | | Standard deviation of horizontal velocity error, (metres/sec) | +| evv | `float32` | | | Standard deviation of vertical velocity error, (metres/sec) | +| dead_reckoning | `bool` | | | True if this position is estimated through dead-reckoning | +| vxy_max | `float32` | | | maximum horizontal speed (meters/sec) | +| vz_max | `float32` | | | maximum vertical speed (meters/sec) | +| hagl_min | `float32` | | | minimum height above ground level (meters) | +| hagl_max_z | `float32` | | | maximum height above ground level for z-control (meters) | +| hagl_max_xy | `float32` | | | maximum height above ground level for xy-control (meters) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------- | -------- | ----- | ----------------------------------------------------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 1 | +| DIST_BOTTOM_SENSOR_NONE | `uint8` | 0 | +| DIST_BOTTOM_SENSOR_RANGE | `uint8` | 1 | (1 << 0) a range sensor is used to estimate dist_bottom field | +| DIST_BOTTOM_SENSOR_FLOW | `uint8` | 2 | (1 << 1) a flow sensor is used to estimate dist_bottom field (mostly fixed-wing use case) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLocalPosition.msg) + +::: details Click here to see original file ```c # Fused local position in NED. @@ -94,5 +170,6 @@ float32 hagl_max_xy # maximum height above ground level for xy-control (meters # TOPICS vehicle_local_position vehicle_local_position_groundtruth external_ins_local_position # TOPICS estimator_local_position - ``` + +::: diff --git a/docs/en/msg_docs/VehicleLocalPositionSetpoint.md b/docs/en/msg_docs/VehicleLocalPositionSetpoint.md index 15f66292b3..e4fa76c086 100644 --- a/docs/en/msg_docs/VehicleLocalPositionSetpoint.md +++ b/docs/en/msg_docs/VehicleLocalPositionSetpoint.md @@ -1,10 +1,34 @@ +--- +pageClass: is-wide-page +--- + # VehicleLocalPositionSetpoint (UORB message) -Local position setpoint in NED frame -Telemetry of PID position controller to monitor tracking. -NaN means the state was not controlled +Local position setpoint in NED frame. Telemetry of PID position controller to monitor tracking. NaN means the state was not controlled. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleLocalPositionSetpoint.msg) +**TOPICS:** vehicle_localposition_setpoint + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| x | `float32` | | | in meters NED | +| y | `float32` | | | in meters NED | +| z | `float32` | | | in meters NED | +| vx | `float32` | | | in meters/sec | +| vy | `float32` | | | in meters/sec | +| vz | `float32` | | | in meters/sec | +| acceleration | `float32[3]` | | | in meters/sec^2 | +| thrust | `float32[3]` | | | normalized thrust vector in NED | +| yaw | `float32` | | | in radians NED -PI..+PI | +| yawspeed | `float32` | | | in radians/sec | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleLocalPositionSetpoint.msg) + +::: details Click here to see original file ```c # Local position setpoint in NED frame @@ -26,5 +50,6 @@ float32[3] thrust # normalized thrust vector in NED float32 yaw # in radians NED -PI..+PI float32 yawspeed # in radians/sec - ``` + +::: diff --git a/docs/en/msg_docs/VehicleLocalPositionV0.md b/docs/en/msg_docs/VehicleLocalPositionV0.md index 05d9361dc1..1596c85b1b 100644 --- a/docs/en/msg_docs/VehicleLocalPositionV0.md +++ b/docs/en/msg_docs/VehicleLocalPositionV0.md @@ -1,9 +1,84 @@ +--- +pageClass: is-wide-page +--- + # VehicleLocalPositionV0 (UORB message) -Fused local position in NED. -The coordinate system origin is the vehicle position at the time when the EKF2-module was started. +Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleLocalPositionV0.msg) +**TOPICS:** vehicle_local_position vehicle_local_position_groundtruth external_ins_local_position estimator_local_position + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| --------------------------- | ------------ | ------------ | ---------- | ----------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| xy_valid | `bool` | | | true if x and y are valid | +| z_valid | `bool` | | | true if z is valid | +| v_xy_valid | `bool` | | | true if vx and vy are valid | +| v_z_valid | `bool` | | | true if vz is valid | +| x | `float32` | | | North position in NED earth-fixed frame, (metres) | +| y | `float32` | | | East position in NED earth-fixed frame, (metres) | +| z | `float32` | | | Down position (negative altitude) in NED earth-fixed frame, (metres) | +| delta_xy | `float32[2]` | | | Amount of lateral shift of position estimate in latest reset (in x and y) [m] | +| xy_reset_counter | `uint8` | | | Index of latest lateral position estimate reset | +| delta_z | `float32` | | | Amount of vertical shift of position estimate in latest reset [m] | +| z_reset_counter | `uint8` | | | Index of latest vertical position estimate reset | +| vx | `float32` | | | North velocity in NED earth-fixed frame, (metres/sec) | +| vy | `float32` | | | East velocity in NED earth-fixed frame, (metres/sec) | +| vz | `float32` | | | Down velocity in NED earth-fixed frame, (metres/sec) | +| z_deriv | `float32` | | | Down position time derivative in NED earth-fixed frame, (metres/sec) | +| delta_vxy | `float32[2]` | | | Amount of lateral shift of velocity estimate in latest reset (in x and y) [m/s] | +| vxy_reset_counter | `uint8` | | | Index of latest vertical velocity estimate reset | +| delta_vz | `float32` | | | Amount of vertical shift of velocity estimate in latest reset [m/s] | +| vz_reset_counter | `uint8` | | | Index of latest vertical velocity estimate reset | +| ax | `float32` | | | North velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| ay | `float32` | | | East velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| az | `float32` | | | Down velocity derivative in NED earth-fixed frame, (metres/sec^2) | +| heading | `float32` | | | Euler yaw angle transforming the tangent plane relative to NED earth-fixed frame, -PI..+PI, (radians) | +| heading_var | `float32` | | | +| unaided_heading | `float32` | | | Same as heading but generated by integrating corrected gyro data only | +| delta_heading | `float32` | | | Heading delta caused by latest heading reset [rad] | +| heading_reset_counter | `uint8` | | | Index of latest heading reset | +| heading_good_for_control | `bool` | | | +| tilt_var | `float32` | | | +| xy_global | `bool` | | | true if position (x, y) has a valid global reference (ref_lat, ref_lon) | +| z_global | `bool` | | | true if z has a valid global reference (ref_alt) | +| ref_timestamp | `uint64` | | | Time when reference position was set since system start, (microseconds) | +| ref_lat | `float64` | | | Reference point latitude, (degrees) | +| ref_lon | `float64` | | | Reference point longitude, (degrees) | +| ref_alt | `float32` | | | Reference altitude AMSL, (metres) | +| dist_bottom_valid | `bool` | | | true if distance to bottom surface is valid | +| dist_bottom | `float32` | | | Distance from from bottom surface to ground, (metres) | +| dist_bottom_var | `float32` | | | terrain estimate variance (m^2) | +| delta_dist_bottom | `float32` | | | Amount of vertical shift of dist bottom estimate in latest reset [m] | +| dist_bottom_reset_counter | `uint8` | | | Index of latest dist bottom estimate reset | +| dist_bottom_sensor_bitfield | `uint8` | | | bitfield indicating what type of sensor is used to estimate dist_bottom | +| eph | `float32` | | | Standard deviation of horizontal position error, (metres) | +| epv | `float32` | | | Standard deviation of vertical position error, (metres) | +| evh | `float32` | | | Standard deviation of horizontal velocity error, (metres/sec) | +| evv | `float32` | | | Standard deviation of vertical velocity error, (metres/sec) | +| dead_reckoning | `bool` | | | True if this position is estimated through dead-reckoning | +| vxy_max | `float32` | | | maximum horizontal speed - set to 0 when limiting not required (meters/sec) | +| vz_max | `float32` | | | maximum vertical speed - set to 0 when limiting not required (meters/sec) | +| hagl_min | `float32` | | | minimum height above ground level - set to 0 when limiting not required (meters) | +| hagl_max | `float32` | | | maximum height above ground level - set to 0 when limiting not required (meters) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------- | -------- | ----- | ----------------------------------------------------------------------------------------- | +| MESSAGE_VERSION | `uint32` | 0 | +| DIST_BOTTOM_SENSOR_NONE | `uint8` | 0 | +| DIST_BOTTOM_SENSOR_RANGE | `uint8` | 1 | (1 << 0) a range sensor is used to estimate dist_bottom field | +| DIST_BOTTOM_SENSOR_FLOW | `uint8` | 2 | (1 << 1) a flow sensor is used to estimate dist_bottom field (mostly fixed-wing use case) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleLocalPositionV0.msg) + +::: details Click here to see original file ```c # Fused local position in NED. @@ -92,5 +167,6 @@ float32 hagl_max # maximum height above ground level - set to 0 when limiting # TOPICS vehicle_local_position vehicle_local_position_groundtruth external_ins_local_position # TOPICS estimator_local_position - ``` + +::: diff --git a/docs/en/msg_docs/VehicleMagnetometer.md b/docs/en/msg_docs/VehicleMagnetometer.md index 3d8f504fd4..23be7d6896 100644 --- a/docs/en/msg_docs/VehicleMagnetometer.md +++ b/docs/en/msg_docs/VehicleMagnetometer.md @@ -1,11 +1,28 @@ +--- +pageClass: is-wide-page +--- + # VehicleMagnetometer (UORB message) +**TOPICS:** vehicle_magnetometer +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleMagnetometer.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| device_id | `uint32` | | | unique device ID for the selected magnetometer | +| magnetometer_ga | `float32[3]` | | | Magnetic field in the FRD body frame XYZ-axis in Gauss | +| calibration_count | `uint8` | | | Calibration changed counter. Monotonically increases whenever calibration changes. | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleMagnetometer.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint64 timestamp_sample # the timestamp of the raw data (microseconds) @@ -15,5 +32,6 @@ uint32 device_id # unique device ID for the selected magnetometer float32[3] magnetometer_ga # Magnetic field in the FRD body frame XYZ-axis in Gauss uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. - ``` + +::: diff --git a/docs/en/msg_docs/VehicleOdometry.md b/docs/en/msg_docs/VehicleOdometry.md index d559ded6c7..a89f94d675 100644 --- a/docs/en/msg_docs/VehicleOdometry.md +++ b/docs/en/msg_docs/VehicleOdometry.md @@ -1,43 +1,100 @@ +--- +pageClass: is-wide-page +--- + # VehicleOdometry (UORB message) -Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +Vehicle odometry data. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleOdometry.msg) +Fits ROS REP 147 for aerial vehicles + +**TOPICS:** vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry estimator_odometry + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------------- | ------------ | -------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Timestamp sample | +| pose_frame | `uint8` | | [POSE_FRAME](#POSE_FRAME) | Position and orientation frame of reference | +| position | `float32[3]` | m [local frame] | | Position. Origin is position of GC at startup. (Invalid: NaN If invalid/unknown) | +| q | `float32[4]` | | | Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) (Invalid: NaN First value if invalid/unknown) | +| velocity_frame | `uint8` | | [VELOCITY_FRAME](#VELOCITY_FRAME) | Reference frame of the velocity data | +| velocity | `float32[3]` | m/s [@velocity_frame] | | Velocity. (Invalid: NaN If invalid/unknown) | +| angular_velocity | `float32[3]` | rad/s [@VELOCITY_FRAME_BODY_FRD] | | Angular velocity in body-fixed frame (Invalid: NaN If invalid/unknown) | +| position_variance | `float32[3]` | m^2 | | Variance of position error | +| orientation_variance | `float32[3]` | rad^2 | | Variance of orientation/attitude error (expressed in body frame) | +| velocity_variance | `float32[3]` | m^2/s^2 | | Variance of velocity error | +| reset_counter | `uint8` | | | Reset counter. Counts reset events on attitude, velocity and position. | +| quality | `int8` | | | Quality. Unused. (Invalid: 0) | + +## Enums + +### POSE_FRAME {#POSE_FRAME} + +| Name | Type | Value | Description | +| ----------------------------------------------------- | ------- | ----- | --------------------------------------------------------------------------------------------- | +| POSE_FRAME_UNKNOWN | `uint8` | 0 | Unknown frame | +| POSE_FRAME_NED | `uint8` | 1 | North-East-Down (NED) navigation frame. Aligned with True North. | +| POSE_FRAME_FRD | `uint8` | 2 | Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. | + +### VELOCITY_FRAME {#VELOCITY_FRAME} + +| Name | Type | Value | Description | +| --------------------------------------------------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------- | +| VELOCITY_FRAME_UNKNOWN | `uint8` | 0 | Unknown frame | +| VELOCITY_FRAME_NED | `uint8` | 1 | NED navigation frame at current position. | +| VELOCITY_FRAME_FRD | `uint8` | 2 | FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. | +| VELOCITY_FRAME_BODY_FRD | `uint8` | 3 | FRD body-fixed frame | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleOdometry.msg) + +::: details Click here to see original file ```c -# Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +# Vehicle odometry data +# +# Fits ROS REP 147 for aerial vehicles uint32 MESSAGE_VERSION = 0 -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp sample -uint8 POSE_FRAME_UNKNOWN = 0 -uint8 POSE_FRAME_NED = 1 # NED earth-fixed frame -uint8 POSE_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 pose_frame # Position and orientation frame of reference +uint8 pose_frame # [@enum POSE_FRAME] Position and orientation frame of reference +uint8 POSE_FRAME_UNKNOWN = 0 # Unknown frame +uint8 POSE_FRAME_NED = 1 # North-East-Down (NED) navigation frame. Aligned with True North. +uint8 POSE_FRAME_FRD = 2 # Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. -float32[3] position # Position in meters. Frame of reference defined by local_frame. NaN if invalid/unknown -float32[4] q # Quaternion rotation from FRD body frame to reference frame. First value NaN if invalid/unknown +float32[3] position # [m] [@frame local frame] [@invalid NaN If invalid/unknown] Position. Origin is position of GC at startup. +float32[4] q # [-] [@invalid NaN First value if invalid/unknown] Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) -uint8 VELOCITY_FRAME_UNKNOWN = 0 -uint8 VELOCITY_FRAME_NED = 1 # NED earth-fixed frame -uint8 VELOCITY_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -uint8 velocity_frame # Reference frame of the velocity data +uint8 velocity_frame # [@enum VELOCITY_FRAME] Reference frame of the velocity data +uint8 VELOCITY_FRAME_UNKNOWN = 0 # Unknown frame +uint8 VELOCITY_FRAME_NED = 1 # NED navigation frame at current position. +uint8 VELOCITY_FRAME_FRD = 2 # FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. +uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -float32[3] velocity # Velocity in meters/sec. Frame of reference defined by velocity_frame variable. NaN if invalid/unknown +float32[3] velocity # [m/s] [@frame @velocity_frame] [@invalid NaN If invalid/unknown] Velocity. +float32[3] angular_velocity # [rad/s] [@frame @VELOCITY_FRAME_BODY_FRD] [@invalid NaN If invalid/unknown] Angular velocity in body-fixed frame -float32[3] angular_velocity # Angular velocity in body-fixed frame (rad/s). NaN if invalid/unknown +float32[3] position_variance # [m^2] Variance of position error +float32[3] orientation_variance # [rad^2] Variance of orientation/attitude error (expressed in body frame) +float32[3] velocity_variance # [m^2/s^2] Variance of velocity error -float32[3] position_variance -float32[3] orientation_variance -float32[3] velocity_variance - -uint8 reset_counter -int8 quality +uint8 reset_counter # [-] Reset counter. Counts reset events on attitude, velocity and position. +int8 quality # [-] [@invalid 0] Quality. Unused. # TOPICS vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry # TOPICS estimator_odometry - ``` + +::: diff --git a/docs/en/msg_docs/VehicleOpticalFlow.md b/docs/en/msg_docs/VehicleOpticalFlow.md index 21bd5ab438..298502f826 100644 --- a/docs/en/msg_docs/VehicleOpticalFlow.md +++ b/docs/en/msg_docs/VehicleOpticalFlow.md @@ -1,8 +1,34 @@ +--- +pageClass: is-wide-page +--- + # VehicleOpticalFlow (UORB message) Optical flow in XYZ body frame in SI units. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleOpticalFlow.msg) +**TOPICS:** vehicle_opticalflow + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | ------------ | ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | +| device_id | `uint32` | | | unique device ID for the sensor that does not change between power cycles | +| pixel_flow | `float32[2]` | | | (radians) accumulated optical flow in radians where a positive value is produced by a RH rotation about the body axis | +| delta_angle | `float32[3]` | | | (radians) accumulated gyro radians where a positive value is produced by a RH rotation of the sensor about the body axis. (NAN if unavailable) | +| distance_m | `float32` | | | (meters) Distance to the center of the flow field (NAN if unavailable) | +| integration_timespan_us | `uint32` | | | (microseconds) accumulation timespan in microseconds | +| quality | `uint8` | | | Average of quality of accumulated frames, 0: bad quality, 255: maximum quality | +| max_flow_rate | `float32` | | | (radians/s) Magnitude of maximum angular which the optical flow sensor can measure reliably | +| min_ground_distance | `float32` | | | (meters) Minimum distance from ground at which the optical flow sensor operates reliably | +| max_ground_distance | `float32` | | | (meters) Maximum distance from ground at which the optical flow sensor operates reliably | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleOpticalFlow.msg) + +::: details Click here to see original file ```c # Optical flow in XYZ body frame in SI units. @@ -26,5 +52,6 @@ float32 max_flow_rate # (radians/s) Magnitude of maximum angular which float32 min_ground_distance # (meters) Minimum distance from ground at which the optical flow sensor operates reliably float32 max_ground_distance # (meters) Maximum distance from ground at which the optical flow sensor operates reliably - ``` + +::: diff --git a/docs/en/msg_docs/VehicleOpticalFlowVel.md b/docs/en/msg_docs/VehicleOpticalFlowVel.md index eec61e9ba9..7431dafc15 100644 --- a/docs/en/msg_docs/VehicleOpticalFlowVel.md +++ b/docs/en/msg_docs/VehicleOpticalFlowVel.md @@ -1,8 +1,32 @@ +--- +pageClass: is-wide-page +--- + # VehicleOpticalFlowVel (UORB message) +**TOPICS:** estimator_optical_flow_vel vehicle_optical_flow_vel +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleOpticalFlowVel.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------------------- | ------------ | ------------ | ---------- | --------------------------------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| vel_body | `float32[2]` | | | velocity obtained from gyro-compensated and distance-scaled optical flow raw measurements in body frame(m/s) | +| vel_ne | `float32[2]` | | | same as vel_body but in local frame (m/s) | +| vel_body_filtered | `float32[2]` | | | filtered velocity obtained from gyro-compensated and distance-scaled optical flow raw measurements in body frame(m/s) | +| vel_ne_filtered | `float32[2]` | | | filtered same as vel_body_filtered but in local frame (m/s) | +| flow_rate_uncompensated | `float32[2]` | | | integrated optical flow measurement (rad/s) | +| flow_rate_compensated | `float32[2]` | | | integrated optical flow measurement compensated for angular motion (rad/s) | +| gyro_rate | `float32[3]` | | | gyro measurement synchronized with flow measurements (rad/s) | +| gyro_bias | `float32[3]` | | | +| ref_gyro | `float32[3]` | | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleOpticalFlowVel.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -23,5 +47,6 @@ float32[3] gyro_bias float32[3] ref_gyro # TOPICS estimator_optical_flow_vel vehicle_optical_flow_vel - ``` + +::: diff --git a/docs/en/msg_docs/VehicleRatesSetpoint.md b/docs/en/msg_docs/VehicleRatesSetpoint.md index ebc5827d68..89184ec42d 100644 --- a/docs/en/msg_docs/VehicleRatesSetpoint.md +++ b/docs/en/msg_docs/VehicleRatesSetpoint.md @@ -1,8 +1,33 @@ +--- +pageClass: is-wide-page +--- + # VehicleRatesSetpoint (UORB message) +**TOPICS:** vehicle_ratessetpoint +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| -------------- | ------------ | ------------ | ---------- | -------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| roll | `float32` | rad/s | | roll rate setpoint | +| pitch | `float32` | rad/s | | pitch rate setpoint | +| yaw | `float32` | rad/s | | yaw rate setpoint | +| thrust_body | `float32[3]` | | | Normalized thrust command in body NED frame [-1,1] | +| reset_integral | `bool` | | | Reset roll/pitch/yaw integrals (navigation logic change) | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) + +::: details Click here to see original file ```c uint32 MESSAGE_VERSION = 0 @@ -19,5 +44,6 @@ float32 yaw # [rad/s] yaw rate setpoint float32[3] thrust_body # Normalized thrust command in body NED frame [-1,1] bool reset_integral # Reset roll/pitch/yaw integrals (navigation logic change) - ``` + +::: diff --git a/docs/en/msg_docs/VehicleRoi.md b/docs/en/msg_docs/VehicleRoi.md index 9f3533e29f..3ddf7ad10b 100644 --- a/docs/en/msg_docs/VehicleRoi.md +++ b/docs/en/msg_docs/VehicleRoi.md @@ -1,8 +1,42 @@ +--- +pageClass: is-wide-page +--- + # VehicleRoi (UORB message) -Vehicle Region Of Interest (ROI) +Vehicle Region Of Interest (ROI). -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleRoi.msg) +**TOPICS:** vehicle_roi + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------ | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| mode | `uint8` | | | ROI mode (see above) | +| lat | `float64` | | | Latitude to point to | +| lon | `float64` | | | Longitude to point to | +| alt | `float32` | | | Altitude to point to | +| roll_offset | `float32` | | | angle offset in rad | +| pitch_offset | `float32` | | | angle offset in rad | +| yaw_offset | `float32` | | | angle offset in rad | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------- | ------- | ----- | ---------------------------------------------- | +| ROI_NONE | `uint8` | 0 | No region of interest | +| ROI_WPNEXT | `uint8` | 1 | Point toward next MISSION with optional offset | +| ROI_WPINDEX | `uint8` | 2 | Point toward given MISSION | +| ROI_LOCATION | `uint8` | 3 | Point toward fixed location | +| ROI_TARGET | `uint8` | 4 | Point toward target | +| ROI_ENUM_END | `uint8` | 5 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleRoi.msg) + +::: details Click here to see original file ```c # Vehicle Region Of Interest (ROI) @@ -26,5 +60,6 @@ float32 alt # Altitude to point to float32 roll_offset # angle offset in rad float32 pitch_offset # angle offset in rad float32 yaw_offset # angle offset in rad - ``` + +::: diff --git a/docs/en/msg_docs/VehicleStatus.md b/docs/en/msg_docs/VehicleStatus.md index d1deeb0500..e9ea5416ff 100644 --- a/docs/en/msg_docs/VehicleStatus.md +++ b/docs/en/msg_docs/VehicleStatus.md @@ -1,8 +1,130 @@ +--- +pageClass: is-wide-page +--- + # VehicleStatus (UORB message) -Encodes the system state of the vehicle published by commander +Encodes the system state of the vehicle published by commander. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleStatus.msg) +**TOPICS:** vehicle_status + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | -------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| armed_time | `uint64` | | | Arming timestamp (microseconds) | +| takeoff_time | `uint64` | | | Takeoff timestamp (microseconds) | +| arming_state | `uint8` | | | +| latest_arming_reason | `uint8` | | | +| latest_disarming_reason | `uint8` | | | +| nav_state_timestamp | `uint64` | | | time when current nav_state activated | +| nav_state_user_intention | `uint8` | | | Mode that the user selected (might be different from nav_state in a failsafe situation) | +| nav_state | `uint8` | | | Currently active mode | +| executor_in_charge | `uint8` | | | Current mode executor in charge (0=Autopilot) | +| valid_nav_states_mask | `uint32` | | | Bitmask for all valid nav_state values | +| can_set_nav_states_mask | `uint32` | | | Bitmask for all modes that a user can select | +| failure_detector_status | `uint16` | | | +| hil_state | `uint8` | | | +| vehicle_type | `uint8` | | | +| failsafe | `bool` | | | true if system is in failsafe state (e.g.:RTL, Hover, Terminate, ...) | +| failsafe_and_user_took_over | `bool` | | | true if system is in failsafe state but the user took over control | +| failsafe_defer_state | `uint8` | | | one of FAILSAFE*DEFER_STATE*\* | +| gcs_connection_lost | `bool` | | | datalink to GCS lost | +| gcs_connection_lost_counter | `uint8` | | | counts unique GCS connection lost events | +| high_latency_data_link_lost | `bool` | | | Set to true if the high latency data link (eg. RockBlock Iridium 9603 telemetry module) is lost | +| is_vtol | `bool` | | | True if the system is VTOL capable | +| is_vtol_tailsitter | `bool` | | | True if the system performs a 90° pitch down rotation during transition from MC to FW | +| in_transition_mode | `bool` | | | True if VTOL is doing a transition | +| in_transition_to_fw | `bool` | | | True if VTOL is doing a transition from MC to FW | +| system_type | `uint8` | | | system type, contains mavlink MAV_TYPE | +| system_id | `uint8` | | | system id, contains MAVLink's system ID field | +| component_id | `uint8` | | | subsystem / component id, contains MAVLink's component ID field | +| safety_button_available | `bool` | | | Set to true if a safety button is connected | +| safety_off | `bool` | | | Set to true if safety is off | +| power_input_valid | `bool` | | | set if input power is valid | +| usb_connected | `bool` | | | set to true (never cleared) once telemetry received from usb link | +| open_drone_id_system_present | `bool` | | | +| open_drone_id_system_healthy | `bool` | | | +| parachute_system_present | `bool` | | | +| parachute_system_healthy | `bool` | | | +| rc_calibration_in_progress | `bool` | | | +| calibration_enabled | `bool` | | | +| pre_flight_checks_pass | `bool` | | | true if all checks necessary to arm pass | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------------ | +| MESSAGE_VERSION | `uint32` | 1 | +| ARMING_STATE_DISARMED | `uint8` | 1 | +| ARMING_STATE_ARMED | `uint8` | 2 | +| ARM_DISARM_REASON_STICK_GESTURE | `uint8` | 1 | +| ARM_DISARM_REASON_RC_SWITCH | `uint8` | 2 | +| ARM_DISARM_REASON_COMMAND_INTERNAL | `uint8` | 3 | +| ARM_DISARM_REASON_COMMAND_EXTERNAL | `uint8` | 4 | +| ARM_DISARM_REASON_MISSION_START | `uint8` | 5 | +| ARM_DISARM_REASON_LANDING | `uint8` | 6 | +| ARM_DISARM_REASON_PREFLIGHT_INACTION | `uint8` | 7 | +| ARM_DISARM_REASON_KILL_SWITCH | `uint8` | 8 | +| ARM_DISARM_REASON_RC_BUTTON | `uint8` | 13 | +| ARM_DISARM_REASON_FAILSAFE | `uint8` | 14 | +| NAVIGATION_STATE_MANUAL | `uint8` | 0 | Manual mode | +| NAVIGATION_STATE_ALTCTL | `uint8` | 1 | Altitude control mode | +| NAVIGATION_STATE_POSCTL | `uint8` | 2 | Position control mode | +| NAVIGATION_STATE_AUTO_MISSION | `uint8` | 3 | Auto mission mode | +| NAVIGATION_STATE_AUTO_LOITER | `uint8` | 4 | Auto loiter mode | +| NAVIGATION_STATE_AUTO_RTL | `uint8` | 5 | Auto return to launch mode | +| NAVIGATION_STATE_POSITION_SLOW | `uint8` | 6 | +| NAVIGATION_STATE_FREE5 | `uint8` | 7 | +| NAVIGATION_STATE_ALTITUDE_CRUISE | `uint8` | 8 | Altitude with Cruise mode | +| NAVIGATION_STATE_FREE3 | `uint8` | 9 | +| NAVIGATION_STATE_ACRO | `uint8` | 10 | Acro mode | +| NAVIGATION_STATE_FREE2 | `uint8` | 11 | +| NAVIGATION_STATE_DESCEND | `uint8` | 12 | Descend mode (no position control) | +| NAVIGATION_STATE_TERMINATION | `uint8` | 13 | Termination mode | +| NAVIGATION_STATE_OFFBOARD | `uint8` | 14 | +| NAVIGATION_STATE_STAB | `uint8` | 15 | Stabilized mode | +| NAVIGATION_STATE_FREE1 | `uint8` | 16 | +| NAVIGATION_STATE_AUTO_TAKEOFF | `uint8` | 17 | Takeoff | +| NAVIGATION_STATE_AUTO_LAND | `uint8` | 18 | Land | +| NAVIGATION_STATE_AUTO_FOLLOW_TARGET | `uint8` | 19 | Auto Follow | +| NAVIGATION_STATE_AUTO_PRECLAND | `uint8` | 20 | Precision land with landing target | +| NAVIGATION_STATE_ORBIT | `uint8` | 21 | Orbit in a circle | +| NAVIGATION_STATE_AUTO_VTOL_TAKEOFF | `uint8` | 22 | Takeoff, transition, establish loiter | +| NAVIGATION_STATE_EXTERNAL1 | `uint8` | 23 | +| NAVIGATION_STATE_EXTERNAL2 | `uint8` | 24 | +| NAVIGATION_STATE_EXTERNAL3 | `uint8` | 25 | +| NAVIGATION_STATE_EXTERNAL4 | `uint8` | 26 | +| NAVIGATION_STATE_EXTERNAL5 | `uint8` | 27 | +| NAVIGATION_STATE_EXTERNAL6 | `uint8` | 28 | +| NAVIGATION_STATE_EXTERNAL7 | `uint8` | 29 | +| NAVIGATION_STATE_EXTERNAL8 | `uint8` | 30 | +| NAVIGATION_STATE_MAX | `uint8` | 31 | +| FAILURE_NONE | `uint16` | 0 | +| FAILURE_ROLL | `uint16` | 1 | (1 << 0) | +| FAILURE_PITCH | `uint16` | 2 | (1 << 1) | +| FAILURE_ALT | `uint16` | 4 | (1 << 2) | +| FAILURE_EXT | `uint16` | 8 | (1 << 3) | +| FAILURE_ARM_ESC | `uint16` | 16 | (1 << 4) | +| FAILURE_BATTERY | `uint16` | 32 | (1 << 5) | +| FAILURE_IMBALANCED_PROP | `uint16` | 64 | (1 << 6) | +| FAILURE_MOTOR | `uint16` | 128 | (1 << 7) | +| HIL_STATE_OFF | `uint8` | 0 | +| HIL_STATE_ON | `uint8` | 1 | +| VEHICLE_TYPE_UNSPECIFIED | `uint8` | 0 | +| VEHICLE_TYPE_ROTARY_WING | `uint8` | 1 | +| VEHICLE_TYPE_FIXED_WING | `uint8` | 2 | +| VEHICLE_TYPE_ROVER | `uint8` | 3 | +| FAILSAFE_DEFER_STATE_DISABLED | `uint8` | 0 | +| FAILSAFE_DEFER_STATE_ENABLED | `uint8` | 1 | +| FAILSAFE_DEFER_STATE_WOULD_FAILSAFE | `uint8` | 2 | Failsafes deferred, but would trigger a failsafe | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleStatus.msg) + +::: details Click here to see original file ```c # Encodes the system state of the vehicle published by commander @@ -20,20 +142,16 @@ uint8 ARMING_STATE_ARMED = 2 uint8 latest_arming_reason uint8 latest_disarming_reason -uint8 ARM_DISARM_REASON_TRANSITION_TO_STANDBY = 0 uint8 ARM_DISARM_REASON_STICK_GESTURE = 1 uint8 ARM_DISARM_REASON_RC_SWITCH = 2 uint8 ARM_DISARM_REASON_COMMAND_INTERNAL = 3 uint8 ARM_DISARM_REASON_COMMAND_EXTERNAL = 4 uint8 ARM_DISARM_REASON_MISSION_START = 5 -uint8 ARM_DISARM_REASON_SAFETY_BUTTON = 6 -uint8 ARM_DISARM_REASON_AUTO_DISARM_LAND = 7 -uint8 ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT = 8 -uint8 ARM_DISARM_REASON_KILL_SWITCH = 9 -uint8 ARM_DISARM_REASON_LOCKDOWN = 10 -uint8 ARM_DISARM_REASON_FAILURE_DETECTOR = 11 -uint8 ARM_DISARM_REASON_SHUTDOWN = 12 -uint8 ARM_DISARM_REASON_UNIT_TEST = 13 +uint8 ARM_DISARM_REASON_LANDING = 6 +uint8 ARM_DISARM_REASON_PREFLIGHT_INACTION = 7 +uint8 ARM_DISARM_REASON_KILL_SWITCH = 8 +uint8 ARM_DISARM_REASON_RC_BUTTON = 13 +uint8 ARM_DISARM_REASON_FAILSAFE = 14 uint64 nav_state_timestamp # time when current nav_state activated @@ -48,7 +166,7 @@ uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode uint8 NAVIGATION_STATE_POSITION_SLOW = 6 uint8 NAVIGATION_STATE_FREE5 = 7 -uint8 NAVIGATION_STATE_FREE4 = 8 +uint8 NAVIGATION_STATE_ALTITUDE_CRUISE = 8 # Altitude with Cruise mode uint8 NAVIGATION_STATE_FREE3 = 9 uint8 NAVIGATION_STATE_ACRO = 10 # Acro mode uint8 NAVIGATION_STATE_FREE2 = 11 @@ -141,5 +259,6 @@ bool rc_calibration_in_progress bool calibration_enabled bool pre_flight_checks_pass # true if all checks necessary to arm pass - ``` + +::: diff --git a/docs/en/msg_docs/VehicleStatusV0.md b/docs/en/msg_docs/VehicleStatusV0.md index 9a91186524..5c9b8c0ae5 100644 --- a/docs/en/msg_docs/VehicleStatusV0.md +++ b/docs/en/msg_docs/VehicleStatusV0.md @@ -1,8 +1,137 @@ +--- +pageClass: is-wide-page +--- + # VehicleStatusV0 (UORB message) -Encodes the system state of the vehicle published by commander +Encodes the system state of the vehicle published by commander. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleStatusV0.msg) +**TOPICS:** vehicle_statusv0 + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------------------- | -------- | ------------ | ---------- | ----------------------------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| armed_time | `uint64` | | | Arming timestamp (microseconds) | +| takeoff_time | `uint64` | | | Takeoff timestamp (microseconds) | +| arming_state | `uint8` | | | +| latest_arming_reason | `uint8` | | | +| latest_disarming_reason | `uint8` | | | +| nav_state_timestamp | `uint64` | | | time when current nav_state activated | +| nav_state_user_intention | `uint8` | | | Mode that the user selected (might be different from nav_state in a failsafe situation) | +| nav_state | `uint8` | | | Currently active mode | +| executor_in_charge | `uint8` | | | Current mode executor in charge (0=Autopilot) | +| valid_nav_states_mask | `uint32` | | | Bitmask for all valid nav_state values | +| can_set_nav_states_mask | `uint32` | | | Bitmask for all modes that a user can select | +| failure_detector_status | `uint16` | | | +| hil_state | `uint8` | | | +| vehicle_type | `uint8` | | | +| failsafe | `bool` | | | true if system is in failsafe state (e.g.:RTL, Hover, Terminate, ...) | +| failsafe_and_user_took_over | `bool` | | | true if system is in failsafe state but the user took over control | +| failsafe_defer_state | `uint8` | | | one of FAILSAFE*DEFER_STATE*\* | +| gcs_connection_lost | `bool` | | | datalink to GCS lost | +| gcs_connection_lost_counter | `uint8` | | | counts unique GCS connection lost events | +| high_latency_data_link_lost | `bool` | | | Set to true if the high latency data link (eg. RockBlock Iridium 9603 telemetry module) is lost | +| is_vtol | `bool` | | | True if the system is VTOL capable | +| is_vtol_tailsitter | `bool` | | | True if the system performs a 90° pitch down rotation during transition from MC to FW | +| in_transition_mode | `bool` | | | True if VTOL is doing a transition | +| in_transition_to_fw | `bool` | | | True if VTOL is doing a transition from MC to FW | +| system_type | `uint8` | | | system type, contains mavlink MAV_TYPE | +| system_id | `uint8` | | | system id, contains MAVLink's system ID field | +| component_id | `uint8` | | | subsystem / component id, contains MAVLink's component ID field | +| safety_button_available | `bool` | | | Set to true if a safety button is connected | +| safety_off | `bool` | | | Set to true if safety is off | +| power_input_valid | `bool` | | | set if input power is valid | +| usb_connected | `bool` | | | set to true (never cleared) once telemetry received from usb link | +| open_drone_id_system_present | `bool` | | | +| open_drone_id_system_healthy | `bool` | | | +| parachute_system_present | `bool` | | | +| parachute_system_healthy | `bool` | | | +| avoidance_system_required | `bool` | | | Set to true if avoidance system is enabled via COM_OBS_AVOID parameter | +| avoidance_system_valid | `bool` | | | Status of the obstacle avoidance system | +| rc_calibration_in_progress | `bool` | | | +| calibration_enabled | `bool` | | | +| pre_flight_checks_pass | `bool` | | | true if all checks necessary to arm pass | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------------------------------------------------------- | -------- | ----- | ------------------------------------------------ | +| MESSAGE_VERSION | `uint32` | 0 | +| ARMING_STATE_DISARMED | `uint8` | 1 | +| ARMING_STATE_ARMED | `uint8` | 2 | +| ARM_DISARM_REASON_TRANSITION_TO_STANDBY | `uint8` | 0 | +| ARM_DISARM_REASON_STICK_GESTURE | `uint8` | 1 | +| ARM_DISARM_REASON_RC_SWITCH | `uint8` | 2 | +| ARM_DISARM_REASON_COMMAND_INTERNAL | `uint8` | 3 | +| ARM_DISARM_REASON_COMMAND_EXTERNAL | `uint8` | 4 | +| ARM_DISARM_REASON_MISSION_START | `uint8` | 5 | +| ARM_DISARM_REASON_SAFETY_BUTTON | `uint8` | 6 | +| ARM_DISARM_REASON_AUTO_DISARM_LAND | `uint8` | 7 | +| ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT | `uint8` | 8 | +| ARM_DISARM_REASON_KILL_SWITCH | `uint8` | 9 | +| ARM_DISARM_REASON_LOCKDOWN | `uint8` | 10 | +| ARM_DISARM_REASON_FAILURE_DETECTOR | `uint8` | 11 | +| ARM_DISARM_REASON_SHUTDOWN | `uint8` | 12 | +| ARM_DISARM_REASON_UNIT_TEST | `uint8` | 13 | +| NAVIGATION_STATE_MANUAL | `uint8` | 0 | Manual mode | +| NAVIGATION_STATE_ALTCTL | `uint8` | 1 | Altitude control mode | +| NAVIGATION_STATE_POSCTL | `uint8` | 2 | Position control mode | +| NAVIGATION_STATE_AUTO_MISSION | `uint8` | 3 | Auto mission mode | +| NAVIGATION_STATE_AUTO_LOITER | `uint8` | 4 | Auto loiter mode | +| NAVIGATION_STATE_AUTO_RTL | `uint8` | 5 | Auto return to launch mode | +| NAVIGATION_STATE_POSITION_SLOW | `uint8` | 6 | +| NAVIGATION_STATE_FREE5 | `uint8` | 7 | +| NAVIGATION_STATE_FREE4 | `uint8` | 8 | +| NAVIGATION_STATE_FREE3 | `uint8` | 9 | +| NAVIGATION_STATE_ACRO | `uint8` | 10 | Acro mode | +| NAVIGATION_STATE_FREE2 | `uint8` | 11 | +| NAVIGATION_STATE_DESCEND | `uint8` | 12 | Descend mode (no position control) | +| NAVIGATION_STATE_TERMINATION | `uint8` | 13 | Termination mode | +| NAVIGATION_STATE_OFFBOARD | `uint8` | 14 | +| NAVIGATION_STATE_STAB | `uint8` | 15 | Stabilized mode | +| NAVIGATION_STATE_FREE1 | `uint8` | 16 | +| NAVIGATION_STATE_AUTO_TAKEOFF | `uint8` | 17 | Takeoff | +| NAVIGATION_STATE_AUTO_LAND | `uint8` | 18 | Land | +| NAVIGATION_STATE_AUTO_FOLLOW_TARGET | `uint8` | 19 | Auto Follow | +| NAVIGATION_STATE_AUTO_PRECLAND | `uint8` | 20 | Precision land with landing target | +| NAVIGATION_STATE_ORBIT | `uint8` | 21 | Orbit in a circle | +| NAVIGATION_STATE_AUTO_VTOL_TAKEOFF | `uint8` | 22 | Takeoff, transition, establish loiter | +| NAVIGATION_STATE_EXTERNAL1 | `uint8` | 23 | +| NAVIGATION_STATE_EXTERNAL2 | `uint8` | 24 | +| NAVIGATION_STATE_EXTERNAL3 | `uint8` | 25 | +| NAVIGATION_STATE_EXTERNAL4 | `uint8` | 26 | +| NAVIGATION_STATE_EXTERNAL5 | `uint8` | 27 | +| NAVIGATION_STATE_EXTERNAL6 | `uint8` | 28 | +| NAVIGATION_STATE_EXTERNAL7 | `uint8` | 29 | +| NAVIGATION_STATE_EXTERNAL8 | `uint8` | 30 | +| NAVIGATION_STATE_MAX | `uint8` | 31 | +| FAILURE_NONE | `uint16` | 0 | +| FAILURE_ROLL | `uint16` | 1 | (1 << 0) | +| FAILURE_PITCH | `uint16` | 2 | (1 << 1) | +| FAILURE_ALT | `uint16` | 4 | (1 << 2) | +| FAILURE_EXT | `uint16` | 8 | (1 << 3) | +| FAILURE_ARM_ESC | `uint16` | 16 | (1 << 4) | +| FAILURE_BATTERY | `uint16` | 32 | (1 << 5) | +| FAILURE_IMBALANCED_PROP | `uint16` | 64 | (1 << 6) | +| FAILURE_MOTOR | `uint16` | 128 | (1 << 7) | +| HIL_STATE_OFF | `uint8` | 0 | +| HIL_STATE_ON | `uint8` | 1 | +| VEHICLE_TYPE_UNKNOWN | `uint8` | 0 | +| VEHICLE_TYPE_ROTARY_WING | `uint8` | 1 | +| VEHICLE_TYPE_FIXED_WING | `uint8` | 2 | +| VEHICLE_TYPE_ROVER | `uint8` | 3 | +| VEHICLE_TYPE_AIRSHIP | `uint8` | 4 | +| FAILSAFE_DEFER_STATE_DISABLED | `uint8` | 0 | +| FAILSAFE_DEFER_STATE_ENABLED | `uint8` | 1 | +| FAILSAFE_DEFER_STATE_WOULD_FAILSAFE | `uint8` | 2 | Failsafes deferred, but would trigger a failsafe | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/VehicleStatusV0.msg) + +::: details Click here to see original file ```c # Encodes the system state of the vehicle published by commander @@ -145,5 +274,6 @@ bool rc_calibration_in_progress bool calibration_enabled bool pre_flight_checks_pass # true if all checks necessary to arm pass - ``` + +::: diff --git a/docs/en/msg_docs/VehicleThrustSetpoint.md b/docs/en/msg_docs/VehicleThrustSetpoint.md index 6bcf6e9d13..2b5324b098 100644 --- a/docs/en/msg_docs/VehicleThrustSetpoint.md +++ b/docs/en/msg_docs/VehicleThrustSetpoint.md @@ -1,11 +1,26 @@ +--- +pageClass: is-wide-page +--- + # VehicleThrustSetpoint (UORB message) +**TOPICS:** vehicle_thrust_setpoint vehicle_thrust_setpoint_virtual_fw vehicle_thrust_setpoint_virtual_mc +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleThrustSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | timestamp of the data sample on which this message is based (microseconds) | +| xyz | `float32[3]` | | | thrust setpoint along X, Y, Z body axis [-1, 1] | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleThrustSetpoint.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint64 timestamp_sample # timestamp of the data sample on which this message is based (microseconds) @@ -13,5 +28,6 @@ float32[3] xyz # thrust setpoint along X, Y, Z body axis [-1, 1] # TOPICS vehicle_thrust_setpoint # TOPICS vehicle_thrust_setpoint_virtual_fw vehicle_thrust_setpoint_virtual_mc - ``` + +::: diff --git a/docs/en/msg_docs/VehicleTorqueSetpoint.md b/docs/en/msg_docs/VehicleTorqueSetpoint.md index d67e37b3a3..a0449a4711 100644 --- a/docs/en/msg_docs/VehicleTorqueSetpoint.md +++ b/docs/en/msg_docs/VehicleTorqueSetpoint.md @@ -1,11 +1,26 @@ +--- +pageClass: is-wide-page +--- + # VehicleTorqueSetpoint (UORB message) +**TOPICS:** vehicle_torque_setpoint vehicle_torque_setpoint_virtual_fw vehicle_torque_setpoint_virtual_mc +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleTorqueSetpoint.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | ------------ | ------------ | ---------- | -------------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | timestamp of the data sample on which this message is based (microseconds) | +| xyz | `float32[3]` | | | torque setpoint about X, Y, Z body axis (normalized) | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleTorqueSetpoint.msg) + +::: details Click here to see original file ```c - uint64 timestamp # time since system start (microseconds) uint64 timestamp_sample # timestamp of the data sample on which this message is based (microseconds) @@ -13,5 +28,6 @@ float32[3] xyz # torque setpoint about X, Y, Z body axis (normalized) # TOPICS vehicle_torque_setpoint # TOPICS vehicle_torque_setpoint_virtual_fw vehicle_torque_setpoint_virtual_mc - ``` + +::: diff --git a/docs/en/msg_docs/VelocityLimits.md b/docs/en/msg_docs/VelocityLimits.md index 6a86fdc977..007088412a 100644 --- a/docs/en/msg_docs/VelocityLimits.md +++ b/docs/en/msg_docs/VelocityLimits.md @@ -1,8 +1,27 @@ +--- +pageClass: is-wide-page +--- + # VelocityLimits (UORB message) -Velocity and yaw rate limits for a multicopter position slow mode only +Velocity and yaw rate limits for a multicopter position slow mode only. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VelocityLimits.msg) +**TOPICS:** velocity_limits + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | --------- | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| horizontal_velocity | `float32` | m/s | | +| vertical_velocity | `float32` | m/s | | +| yaw_rate | `float32` | rad/s | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VelocityLimits.msg) + +::: details Click here to see original file ```c # Velocity and yaw rate limits for a multicopter position slow mode only @@ -13,5 +32,6 @@ uint64 timestamp # time since system start (microseconds) float32 horizontal_velocity # [m/s] float32 vertical_velocity # [m/s] float32 yaw_rate # [rad/s] - ``` + +::: diff --git a/docs/en/msg_docs/VtolVehicleStatus.md b/docs/en/msg_docs/VtolVehicleStatus.md index a271005673..0e6a351aac 100644 --- a/docs/en/msg_docs/VtolVehicleStatus.md +++ b/docs/en/msg_docs/VtolVehicleStatus.md @@ -1,8 +1,37 @@ +--- +pageClass: is-wide-page +--- + # VtolVehicleStatus (UORB message) -VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE +VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VtolVehicleStatus.msg) +**TOPICS:** vtol_vehiclestatus + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------------- | -------- | ------------ | ---------- | --------------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| vehicle_vtol_state | `uint8` | | | current state of the vtol, see VEHICLE_VTOL_STATE | +| fixed_wing_system_failure | `bool` | | | vehicle in fixed-wing system failure failsafe mode (after quad-chute) | + +## Constants + +| Name | Type | Value | Description | +| --------------------------------------------------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | +| VEHICLE_VTOL_STATE_UNDEFINED | `uint8` | 0 | +| VEHICLE_VTOL_STATE_TRANSITION_TO_FW | `uint8` | 1 | +| VEHICLE_VTOL_STATE_TRANSITION_TO_MC | `uint8` | 2 | +| VEHICLE_VTOL_STATE_MC | `uint8` | 3 | +| VEHICLE_VTOL_STATE_FW | `uint8` | 4 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VtolVehicleStatus.msg) + +::: details Click here to see original file ```c # VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE @@ -20,5 +49,6 @@ uint64 timestamp # time since system start (microseconds) uint8 vehicle_vtol_state # current state of the vtol, see VEHICLE_VTOL_STATE bool fixed_wing_system_failure # vehicle in fixed-wing system failure failsafe mode (after quad-chute) - ``` + +::: diff --git a/docs/en/msg_docs/Vtx.md b/docs/en/msg_docs/Vtx.md new file mode 100644 index 0000000000..7cf2657bf0 --- /dev/null +++ b/docs/en/msg_docs/Vtx.md @@ -0,0 +1,83 @@ +--- +pageClass: is-wide-page +--- + +# Vtx (UORB message) + +**TOPICS:** vtx + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | ----------- | ------------ | ---------- | -------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| protocol | `uint8` | | | +| device | `uint8` | | | +| mode | `uint8` | | | +| band | `int8` | | | Band number (0-23), negative values indicate frequency mode | +| channel | `int8` | | | Channel number (0-15), negative values indicate frequency mode | +| frequency | `uint16` | | | Frequency in MHz, zero indicates unknown | +| band_letter | `uint8` | | | Band letter as ASCII | +| band_name | `uint8[12]` | | | Band name in ASCII without null termination | +| power_level | `int8` | | | Current power level (0-15), negative values indicate unknown | +| power_label | `uint8[4]` | | | Current power label in ASCII without null termination | + +## Constants + +| Name | Type | Value | Description | +| ------------------------------------------------------------------- | ------- | ----- | ----------------------------------------- | +| BAND_NAME_LENGTH | `uint8` | 12 | +| POWER_LABEL_LENGTH | `uint8` | 4 | +| PROTOCOL_NONE | `uint8` | 0 | No protocol is detected, usually an error | +| PROTOCOL_SMART_AUDIO_V1 | `uint8` | 10 | +| PROTOCOL_SMART_AUDIO_V2 | `uint8` | 20 | +| PROTOCOL_SMART_AUDIO_V2_1 | `uint8` | 21 | +| PROTOCOL_TRAMP | `uint8` | 100 | +| DEVICE_UNKNOWN | `uint8` | 0 | +| DEVICE_PEAK_THOR_T67 | `uint8` | 20 | +| DEVICE_RUSH_MAX_SOLO | `uint8` | 40 | +| MODE_NORMAL | `uint8` | 0 | +| MODE_PIT | `uint8` | 1 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Vtx.msg) + +::: details Click here to see original file + +```c +uint64 timestamp # time since system start (microseconds) + +uint8 BAND_NAME_LENGTH = 12 +uint8 POWER_LABEL_LENGTH = 4 + +uint8 PROTOCOL_NONE = 0 # No protocol is detected, usually an error +uint8 PROTOCOL_SMART_AUDIO_V1 = 10 +uint8 PROTOCOL_SMART_AUDIO_V2 = 20 +uint8 PROTOCOL_SMART_AUDIO_V2_1 = 21 +uint8 PROTOCOL_TRAMP = 100 +uint8 protocol + +uint8 DEVICE_UNKNOWN = 0 +uint8 DEVICE_PEAK_THOR_T67 = 20 +uint8 DEVICE_RUSH_MAX_SOLO = 40 +uint8 device + +uint8 MODE_NORMAL = 0 +uint8 MODE_PIT = 1 +uint8 mode + +# Band and Channel are 0-indexed! But the user expects a 1-indexed display! +int8 band # Band number (0-23), negative values indicate frequency mode +int8 channel # Channel number (0-15), negative values indicate frequency mode +uint16 frequency # Frequency in MHz, zero indicates unknown + +uint8 band_letter # Band letter as ASCII +uint8[12] band_name # Band name in ASCII without null termination + +# Also 0-indexed, but the user expects a 1-indexed display! +int8 power_level # Current power level (0-15), negative values indicate unknown +uint8[4] power_label # Current power label in ASCII without null termination +``` + +::: diff --git a/docs/en/msg_docs/WheelEncoders.md b/docs/en/msg_docs/WheelEncoders.md index 8a10dc11ad..d5ae526c7a 100644 --- a/docs/en/msg_docs/WheelEncoders.md +++ b/docs/en/msg_docs/WheelEncoders.md @@ -1,8 +1,24 @@ +--- +pageClass: is-wide-page +--- + # WheelEncoders (UORB message) +**TOPICS:** wheel_encoders +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/WheelEncoders.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ----------- | ------------ | ------------ | ---------- | -------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| wheel_speed | `float32[2]` | rad/s | | +| wheel_angle | `float32[2]` | rad | | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/WheelEncoders.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -10,5 +26,6 @@ uint64 timestamp # time since system start (microseconds) # Two wheels: 0 right, 1 left float32[2] wheel_speed # [rad/s] float32[2] wheel_angle # [rad] - ``` + +::: diff --git a/docs/en/msg_docs/Wind.md b/docs/en/msg_docs/Wind.md index 7ddb2e62eb..c30a092752 100644 --- a/docs/en/msg_docs/Wind.md +++ b/docs/en/msg_docs/Wind.md @@ -1,11 +1,42 @@ +--- +pageClass: is-wide-page +--- + # Wind (UORB message) -Wind estimate (from EKF2) +Wind estimate (from EKF2). Contains the system-wide estimate of horizontal wind velocity and its variance. Published by the navigation filter (EKF2) for use by other flight modules and libraries. -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/Wind.msg) +**TOPICS:** wind estimator_wind + +## Fields + +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ---------------- | --------- | ------------ | ---------- | --------------------------------------------------------------------------------- | +| timestamp | `uint64` | us | | Time since system start | +| timestamp_sample | `uint64` | us | | Timestamp of the raw data | +| windspeed_north | `float32` | m/s | | Wind component in north / X direction | +| windspeed_east | `float32` | m/s | | Wind component in east / Y direction | +| variance_north | `float32` | (m/s)^2 | | Wind estimate error variance in north / X direction (Invalid: 0 if not estimated) | +| variance_east | `float32` | (m/s)^2 | | Wind estimate error variance in east / Y direction (Invalid: 0 if not estimated) | +| tas_innov | `float32` | m/s | | True airspeed innovation | +| tas_innov_var | `float32` | (m/s)^2 | | True airspeed innovation variance | +| beta_innov | `float32` | rad | | Sideslip measurement innovation | +| beta_innov_var | `float32` | rad^2 | | Sideslip measurement innovation variance | + +## Constants + +| Name | Type | Value | Description | +| ----------------------------------------------- | -------- | ----- | ----------- | +| MESSAGE_VERSION | `uint32` | 0 | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/Wind.msg) + +::: details Click here to see original file ```c # Wind estimate (from EKF2) @@ -31,5 +62,6 @@ float32 beta_innov # [rad] Sideslip measurement innovation float32 beta_innov_var # [rad^2] Sideslip measurement innovation variance # TOPICS wind estimator_wind - ``` + +::: diff --git a/docs/en/msg_docs/YawEstimatorStatus.md b/docs/en/msg_docs/YawEstimatorStatus.md index 888f7628ba..d167a6f0be 100644 --- a/docs/en/msg_docs/YawEstimatorStatus.md +++ b/docs/en/msg_docs/YawEstimatorStatus.md @@ -1,8 +1,30 @@ +--- +pageClass: is-wide-page +--- + # YawEstimatorStatus (UORB message) +**TOPICS:** yaw_estimatorstatus +## Fields -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/YawEstimatorStatus.msg) +| Name | Type | Unit [Frame] | Range/Enum | Description | +| ------------------- | ------------ | ------------ | ---------- | ----------------------------------------------------------------- | +| timestamp | `uint64` | | | time since system start (microseconds) | +| timestamp_sample | `uint64` | | | the timestamp of the raw data (microseconds) | +| yaw_composite | `float32` | | | composite yaw from GSF (rad) | +| yaw_variance | `float32` | | | composite yaw variance from GSF (rad^2) | +| yaw_composite_valid | `bool` | | | +| yaw | `float32[5]` | | | yaw estimate for each model in the filter bank (rad) | +| innov_vn | `float32[5]` | | | North velocity innovation for each model in the filter bank (m/s) | +| innov_ve | `float32[5]` | | | East velocity innovation for each model in the filter bank (m/s) | +| weight | `float32[5]` | | | weighting for each model in the filter bank | + +## Source Message + +[Source file (GitHub)](https://github.com/PX4/PX4-Autopilot/blob/main/msg/YawEstimatorStatus.msg) + +::: details Click here to see original file ```c uint64 timestamp # time since system start (microseconds) @@ -16,5 +38,6 @@ float32[5] yaw # yaw estimate for each model in the filter bank (rad) float32[5] innov_vn # North velocity innovation for each model in the filter bank (m/s) float32[5] innov_ve # East velocity innovation for each model in the filter bank (m/s) float32[5] weight # weighting for each model in the filter bank - ``` + +::: diff --git a/docs/en/msg_docs/index.md b/docs/en/msg_docs/index.md index c6e0c5c298..e9c41e150c 100644 --- a/docs/en/msg_docs/index.md +++ b/docs/en/msg_docs/index.md @@ -13,90 +13,63 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m ## Versioned Messages -- [ActuatorMotors](ActuatorMotors.md) — Motor control message -- [ActuatorServos](ActuatorServos.md) — Servo control message -- [AirspeedValidated](AirspeedValidated.md) +- [ActuatorMotors](ActuatorMotors.md) — Motor control message. +- [ActuatorServos](ActuatorServos.md) — Servo control message. +- [AirspeedValidated](AirspeedValidated.md) — Validated airspeed. - [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply. - [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request. -- [BatteryStatus](BatteryStatus.md) — Battery status -- [ConfigOverrides](ConfigOverrides.md) — Configurable overrides by (external) modes or mode executors -- [Event](Event.md) — Events interface -- [FixedWingLateralSetpoint](FixedWingLateralSetpoint.md) — Fixed Wing Lateral Setpoint message - Used by the fw_lateral_longitudinal_control module - At least one of course, airspeed_direction, or lateral_acceleration must be finite. -- [FixedWingLongitudinalSetpoint](FixedWingLongitudinalSetpoint.md) — Fixed Wing Longitudinal Setpoint message - Used by the fw_lateral_longitudinal_control module - If pitch_direct and throttle_direct are not both finite, then the controller relies on altitude/height_rate and equivalent_airspeed to control vertical motion. - If both altitude and height_rate are NAN, the controller maintains the current altitude. -- [GotoSetpoint](GotoSetpoint.md) — Position and (optional) heading setpoints with corresponding speed constraints - Setpoints are intended as inputs to position and heading smoothers, respectively - Setpoints do not need to be kinematically consistent - Optional heading setpoints may be specified as controlled by the respective flag - Unset optional setpoints are not controlled - Unset optional constraints default to vehicle specifications +- [BatteryStatus](BatteryStatus.md) — Battery status. +- [ConfigOverrides](ConfigOverrides.md) — Configurable overrides by (external) modes or mode executors. +- [Event](Event.md) — Events interface. +- [FixedWingLateralSetpoint](FixedWingLateralSetpoint.md) — Fixed Wing Lateral Setpoint message. Used by the fw_lateral_longitudinal_control module. At least one of course, airspeed_direction, or lateral_acceleration must be finite. +- [FixedWingLongitudinalSetpoint](FixedWingLongitudinalSetpoint.md) — Fixed Wing Longitudinal Setpoint message. Used by the fw_lateral_longitudinal_control module. If pitch_direct and throttle_direct are not both finite, then the controller relies on altitude/height_rate and equivalent_airspeed to control vertical motion. If both altitude and height_rate are NAN, the controller maintains the current altitude. +- [GotoSetpoint](GotoSetpoint.md) — Position and (optional) heading setpoints with corresponding speed constraints. Setpoints are intended as inputs to position and heading smoothers, respectively. Setpoints do not need to be kinematically consistent. Optional heading setpoints may be specified as controlled by the respective flag. Unset optional setpoints are not controlled. Unset optional constraints default to vehicle specifications. - [HomePosition](HomePosition.md) — GPS home position in WGS84 coordinates. -- [LateralControlConfiguration](LateralControlConfiguration.md) — Fixed Wing Lateral Control Configuration message - Used by the fw_lateral_longitudinal_control module to constrain FixedWingLateralSetpoint messages. -- [LongitudinalControlConfiguration](LongitudinalControlConfiguration.md) — Fixed Wing Longitudinal Control Configuration message - Used by the fw_lateral_longitudinal_control module and TECS to constrain FixedWingLongitudinalSetpoint messages - and configure the resultant setpoints. +- [LateralControlConfiguration](LateralControlConfiguration.md) — Fixed Wing Lateral Control Configuration message. Used by the fw_lateral_longitudinal_control module to constrain FixedWingLateralSetpoint messages. +- [LongitudinalControlConfiguration](LongitudinalControlConfiguration.md) — Fixed Wing Longitudinal Control Configuration message. Used by the fw_lateral_longitudinal_control module and TECS to constrain FixedWingLongitudinalSetpoint messages. and configure the resultant setpoints. - [ManualControlSetpoint](ManualControlSetpoint.md) -- [ModeCompleted](ModeCompleted.md) — Mode completion result, published by an active mode. - The possible values of nav_state are defined in the VehicleStatus msg. - Note that this is not always published (e.g. when a user switches modes or on - failsafe activation) +- [ModeCompleted](ModeCompleted.md) — Mode completion result, published by an active mode. The possible values of nav_state are defined in the VehicleStatus msg. Note that this is not always published (e.g. when a user switches modes or on. failsafe activation). +- [RaptorInput](RaptorInput.md) — Raptor Input. +- [RaptorStatus](RaptorStatus.md) — Raptor Status. - [RegisterExtComponentReply](RegisterExtComponentReply.md) -- [RegisterExtComponentRequest](RegisterExtComponentRequest.md) — Request to register an external component -- [TrajectorySetpoint](TrajectorySetpoint.md) — Trajectory setpoint in NED frame - Input to PID position controller. - Needs to be kinematically consistent and feasible for smooth flight. - setting a value to NaN means the state should not be controlled +- [RegisterExtComponentRequest](RegisterExtComponentRequest.md) — Request to register an external component. +- [TrajectorySetpoint](TrajectorySetpoint.md) — Trajectory setpoint in NED frame. Input to PID position controller. Needs to be kinematically consistent and feasible for smooth flight. setting a value to NaN means the state should not be controlled. - [UnregisterExtComponent](UnregisterExtComponent.md) - [VehicleAngularVelocity](VehicleAngularVelocity.md) -- [VehicleAttitude](VehicleAttitude.md) — This is similar to the mavlink message ATTITUDE_QUATERNION, but for onboard use - The quaternion uses the Hamilton convention, and the order is q(w, x, y, z) +- [VehicleAttitude](VehicleAttitude.md) — This is similar to the mavlink message ATTITUDE_QUATERNION, but for onboard use. The quaternion uses the Hamilton convention, and the order is q(w, x, y, z). - [VehicleAttitudeSetpoint](VehicleAttitudeSetpoint.md) -- [VehicleCommand](VehicleCommand.md) — Vehicle Command uORB message. Used for commanding a mission / action / etc. - Follows the MAVLink COMMAND_INT / COMMAND_LONG definition -- [VehicleCommandAck](VehicleCommandAck.md) — Vehicle Command Ackonwledgement uORB message. - Used for acknowledging the vehicle command being received. - Follows the MAVLink COMMAND_ACK message definition +- [VehicleCommand](VehicleCommand.md) — Vehicle Command uORB message. Used for commanding a mission / action / etc. Follows the MAVLink COMMAND_INT / COMMAND_LONG definition. +- [VehicleCommandAck](VehicleCommandAck.md) — Vehicle Command Ackonwledgement uORB message. Used for acknowledging the vehicle command being received. Follows the MAVLink COMMAND_ACK message definition. - [VehicleControlMode](VehicleControlMode.md) -- [VehicleGlobalPosition](VehicleGlobalPosition.md) — Fused global position in WGS84. - This struct contains global position estimation. It is not the raw GPS - measurement (@see vehicle_gps_position). This topic is usually published by the position - estimator, which will take more sources of information into account than just GPS, - e.g. control inputs of the vehicle in a Kalman-filter implementation. +- [VehicleGlobalPosition](VehicleGlobalPosition.md) — Fused global position in WGS84. This struct contains global position estimation. It is not the raw GPS. measurement (@see vehicle_gps_position). This topic is usually published by the position. estimator, which will take more sources of information into account than just GPS,. e.g. control inputs of the vehicle in a Kalman-filter implementation. - [VehicleLandDetected](VehicleLandDetected.md) -- [VehicleLocalPosition](VehicleLocalPosition.md) — Fused local position in NED. - The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +- [VehicleLocalPosition](VehicleLocalPosition.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. +- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data. - [VehicleRatesSetpoint](VehicleRatesSetpoint.md) -- [VehicleStatus](VehicleStatus.md) — Encodes the system state of the vehicle published by commander -- [VtolVehicleStatus](VtolVehicleStatus.md) — VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE -- [Wind](Wind.md) — Wind estimate (from EKF2) +- [VehicleStatus](VehicleStatus.md) — Encodes the system state of the vehicle published by commander. +- [VtolVehicleStatus](VtolVehicleStatus.md) — VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE. +- [Wind](Wind.md) — Wind estimate (from EKF2). ## Unversioned Messages -- [ActionRequest](ActionRequest.md) — Action request for the vehicle's main state +- [ActionRequest](ActionRequest.md) — Action request for the vehicle's main state. - [ActuatorArmed](ActuatorArmed.md) - [ActuatorControlsStatus](ActuatorControlsStatus.md) - [ActuatorOutputs](ActuatorOutputs.md) -- [ActuatorServosTrim](ActuatorServosTrim.md) — Servo trims, added as offset to servo outputs +- [ActuatorServosTrim](ActuatorServosTrim.md) — Servo trims, added as offset to servo outputs. - [ActuatorTest](ActuatorTest.md) -- [AdcReport](AdcReport.md) -- [Airspeed](Airspeed.md) — Airspeed data from sensors -- [AirspeedWind](AirspeedWind.md) — Wind estimate (from airspeed_selector) -- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) -- [BatteryInfo](BatteryInfo.md) — Battery information +- [AdcReport](AdcReport.md) — ADC raw data. +- [Airspeed](Airspeed.md) — Airspeed data from sensors. +- [AirspeedWind](AirspeedWind.md) — Wind estimate (from airspeed_selector). +- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) — Autotune attitude control status. +- [BatteryInfo](BatteryInfo.md) — Battery information. - [ButtonEvent](ButtonEvent.md) - [CameraCapture](CameraCapture.md) - [CameraStatus](CameraStatus.md) - [CameraTrigger](CameraTrigger.md) - [CanInterfaceStatus](CanInterfaceStatus.md) -- [CellularStatus](CellularStatus.md) — Cellular status -- [CollisionConstraints](CollisionConstraints.md) — Local setpoint constraints in NED frame - setting something to NaN means that no limit is provided +- [CellularStatus](CellularStatus.md) — Cellular status. +- [CollisionConstraints](CollisionConstraints.md) — Local setpoint constraints in NED frame. setting something to NaN means that no limit is provided. - [ControlAllocatorStatus](ControlAllocatorStatus.md) - [Cpuload](Cpuload.md) - [DatamanRequest](DatamanRequest.md) @@ -105,12 +78,12 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [DebugKeyValue](DebugKeyValue.md) - [DebugValue](DebugValue.md) - [DebugVect](DebugVect.md) -- [DifferentialPressure](DifferentialPressure.md) -- [DistanceSensor](DistanceSensor.md) — DISTANCE_SENSOR message data +- [DeviceInformation](DeviceInformation.md) — Device information. +- [DifferentialPressure](DifferentialPressure.md) — Differential-pressure (airspeed) sensor. +- [DistanceSensor](DistanceSensor.md) — DISTANCE_SENSOR message data. - [DistanceSensorModeChangeRequest](DistanceSensorModeChangeRequest.md) - [DronecanNodeStatus](DronecanNodeStatus.md) -- [Ekf2Timestamps](Ekf2Timestamps.md) — this message contains the (relative) timestamps of the sensor inputs used by EKF2. - It can be used for reproducible replay. +- [Ekf2Timestamps](Ekf2Timestamps.md) — this message contains the (relative) timestamps of the sensor inputs used by EKF2. It can be used for reproducible replay. - [EscReport](EscReport.md) - [EscStatus](EscStatus.md) - [EstimatorAidSource1d](EstimatorAidSource1d.md) @@ -122,24 +95,22 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [EstimatorGpsStatus](EstimatorGpsStatus.md) - [EstimatorInnovations](EstimatorInnovations.md) - [EstimatorSelectorStatus](EstimatorSelectorStatus.md) -- [EstimatorSensorBias](EstimatorSensorBias.md) — Sensor readings and in-run biases in SI-unit form. Sensor readings are compensated for static offsets, - scale errors, in-run bias and thermal drift (if thermal compensation is enabled and available). +- [EstimatorSensorBias](EstimatorSensorBias.md) — Sensor readings and in-run biases in SI-unit form. Sensor readings are compensated for static offsets,. scale errors, in-run bias and thermal drift (if thermal compensation is enabled and available). - [EstimatorStates](EstimatorStates.md) - [EstimatorStatus](EstimatorStatus.md) - [EstimatorStatusFlags](EstimatorStatusFlags.md) - [FailsafeFlags](FailsafeFlags.md) — Input flags for the failsafe state machine set by the arming & health checks. - [FailureDetectorStatus](FailureDetectorStatus.md) - [FigureEightStatus](FigureEightStatus.md) -- [FixedWingLateralGuidanceStatus](FixedWingLateralGuidanceStatus.md) — Fixed Wing Lateral Guidance Status message - Published by fw_pos_control module to report the resultant lateral setpoints and NPFG debug outputs -- [FixedWingLateralStatus](FixedWingLateralStatus.md) — Fixed Wing Lateral Status message - Published by the fw_lateral_longitudinal_control module to report the resultant lateral setpoint -- [FixedWingRunwayControl](FixedWingRunwayControl.md) — Auxiliary control fields for fixed-wing runway takeoff/landing +- [FixedWingLateralGuidanceStatus](FixedWingLateralGuidanceStatus.md) — Fixed Wing Lateral Guidance Status message. Published by fw_pos_control module to report the resultant lateral setpoints and NPFG debug outputs. +- [FixedWingLateralStatus](FixedWingLateralStatus.md) — Fixed Wing Lateral Status message. Published by the fw_lateral_longitudinal_control module to report the resultant lateral setpoint. +- [FixedWingRunwayControl](FixedWingRunwayControl.md) — Auxiliary control fields for fixed-wing runway takeoff/landing. - [FlightPhaseEstimation](FlightPhaseEstimation.md) - [FollowTarget](FollowTarget.md) - [FollowTargetEstimator](FollowTargetEstimator.md) - [FollowTargetStatus](FollowTargetStatus.md) - [FuelTankStatus](FuelTankStatus.md) +- [GainCompression](GainCompression.md) - [GeneratorStatus](GeneratorStatus.md) - [GeofenceResult](GeofenceResult.md) - [GeofenceStatus](GeofenceStatus.md) @@ -151,13 +122,13 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [GimbalManagerSetAttitude](GimbalManagerSetAttitude.md) - [GimbalManagerSetManualControl](GimbalManagerSetManualControl.md) - [GimbalManagerStatus](GimbalManagerStatus.md) -- [GpioConfig](GpioConfig.md) — GPIO configuration -- [GpioIn](GpioIn.md) — GPIO mask and state -- [GpioOut](GpioOut.md) — GPIO mask and state -- [GpioRequest](GpioRequest.md) — Request GPIO mask to be read +- [GpioConfig](GpioConfig.md) — GPIO configuration. +- [GpioIn](GpioIn.md) — GPIO mask and state. +- [GpioOut](GpioOut.md) — GPIO mask and state. +- [GpioRequest](GpioRequest.md) — Request GPIO mask to be read. - [GpsDump](GpsDump.md) — This message is used to dump the raw gps communication to the log. - [GpsInjectData](GpsInjectData.md) -- [Gripper](Gripper.md) — # Used to command an actuation in the gripper, which is mapped to a specific output in the control allocation module +- [Gripper](Gripper.md) — # Used to command an actuation in the gripper, which is mapped to a specific output in the control allocation module. - [HealthReport](HealthReport.md) - [HeaterStatus](HeaterStatus.md) - [HoverThrustEstimate](HoverThrustEstimate.md) @@ -165,34 +136,32 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [InternalCombustionEngineControl](InternalCombustionEngineControl.md) - [InternalCombustionEngineStatus](InternalCombustionEngineStatus.md) - [IridiumsbdStatus](IridiumsbdStatus.md) -- [IrlockReport](IrlockReport.md) — IRLOCK_REPORT message data +- [IrlockReport](IrlockReport.md) — IRLOCK_REPORT message data. - [LandingGear](LandingGear.md) - [LandingGearWheel](LandingGearWheel.md) - [LandingTargetInnovations](LandingTargetInnovations.md) -- [LandingTargetPose](LandingTargetPose.md) — Relative position of precision land target in navigation (body fixed, north aligned, NED) and inertial (world fixed, north aligned, NED) frames -- [LaunchDetectionStatus](LaunchDetectionStatus.md) — Status of the launch detection state machine (fixed-wing only) -- [LedControl](LedControl.md) — LED control: control a single or multiple LED's. - These are the externally visible LED's, not the board LED's -- [LogMessage](LogMessage.md) — A logging message, output with PX4_WARN, PX4_ERR, PX4_INFO +- [LandingTargetPose](LandingTargetPose.md) — Relative position of precision land target in navigation (body fixed, north aligned, NED) and inertial (world fixed, north aligned, NED) frames. +- [LaunchDetectionStatus](LaunchDetectionStatus.md) — Status of the launch detection state machine (fixed-wing only). +- [LedControl](LedControl.md) — LED control: control a single or multiple LED's. These are the externally visible LED's, not the board LED's. +- [LogMessage](LogMessage.md) — A logging message, output with PX4_WARN, PX4_ERR, PX4_INFO. - [LoggerStatus](LoggerStatus.md) - [MagWorkerData](MagWorkerData.md) - [MagnetometerBiasEstimate](MagnetometerBiasEstimate.md) - [ManualControlSwitches](ManualControlSwitches.md) - [MavlinkLog](MavlinkLog.md) -- [MavlinkTunnel](MavlinkTunnel.md) — MAV_TUNNEL_PAYLOAD_TYPE enum +- [MavlinkTunnel](MavlinkTunnel.md) — MAV_TUNNEL_PAYLOAD_TYPE enum. - [MessageFormatRequest](MessageFormatRequest.md) - [MessageFormatResponse](MessageFormatResponse.md) - [Mission](Mission.md) - [MissionResult](MissionResult.md) - [MountOrientation](MountOrientation.md) - [NavigatorMissionItem](NavigatorMissionItem.md) -- [NavigatorStatus](NavigatorStatus.md) — Current status of a Navigator mode - The possible values of nav_state are defined in the VehicleStatus msg. -- [NeuralControl](NeuralControl.md) — Neural control +- [NavigatorStatus](NavigatorStatus.md) — Current status of a Navigator mode. The possible values of nav_state are defined in the VehicleStatus msg. +- [NeuralControl](NeuralControl.md) — Neural control. - [NormalizedUnsignedSetpoint](NormalizedUnsignedSetpoint.md) - [ObstacleDistance](ObstacleDistance.md) — Obstacle distances in front of the sensor. -- [OffboardControlMode](OffboardControlMode.md) — Off-board control mode -- [OnboardComputerStatus](OnboardComputerStatus.md) — ONBOARD_COMPUTER_STATUS message data +- [OffboardControlMode](OffboardControlMode.md) — Off-board control mode. +- [OnboardComputerStatus](OnboardComputerStatus.md) — ONBOARD_COMPUTER_STATUS message data. - [OpenDroneIdArmStatus](OpenDroneIdArmStatus.md) - [OpenDroneIdOperatorId](OpenDroneIdOperatorId.md) - [OpenDroneIdSelfId](OpenDroneIdSelfId.md) @@ -200,22 +169,21 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [OrbTest](OrbTest.md) - [OrbTestLarge](OrbTestLarge.md) - [OrbTestMedium](OrbTestMedium.md) -- [OrbitStatus](OrbitStatus.md) — ORBIT_YAW_BEHAVIOUR -- [ParameterResetRequest](ParameterResetRequest.md) — ParameterResetRequest : Used by the primary to reset one or all parameter value(s) on the remote -- [ParameterSetUsedRequest](ParameterSetUsedRequest.md) — ParameterSetUsedRequest : Used by a remote to update the used flag for a parameter on the primary -- [ParameterSetValueRequest](ParameterSetValueRequest.md) — ParameterSetValueRequest : Used by a remote or primary to update the value for a parameter at the other end -- [ParameterSetValueResponse](ParameterSetValueResponse.md) — ParameterSetValueResponse : Response to a set value request by either primary or secondary -- [ParameterUpdate](ParameterUpdate.md) — This message is used to notify the system about one or more parameter changes +- [OrbitStatus](OrbitStatus.md) — ORBIT_YAW_BEHAVIOUR. +- [ParameterResetRequest](ParameterResetRequest.md) — ParameterResetRequest : Used by the primary to reset one or all parameter value(s) on the remote. +- [ParameterSetUsedRequest](ParameterSetUsedRequest.md) — ParameterSetUsedRequest : Used by a remote to update the used flag for a parameter on the primary. +- [ParameterSetValueRequest](ParameterSetValueRequest.md) — ParameterSetValueRequest : Used by a remote or primary to update the value for a parameter at the other end. +- [ParameterSetValueResponse](ParameterSetValueResponse.md) — ParameterSetValueResponse : Response to a set value request by either primary or secondary. +- [ParameterUpdate](ParameterUpdate.md) — This message is used to notify the system about one or more parameter changes. - [Ping](Ping.md) - [PositionControllerLandingStatus](PositionControllerLandingStatus.md) - [PositionControllerStatus](PositionControllerStatus.md) -- [PositionSetpoint](PositionSetpoint.md) — this file is only used in the position_setpoint triple as a dependency -- [PositionSetpointTriplet](PositionSetpointTriplet.md) — Global position setpoint triplet in WGS84 coordinates. - This are the three next waypoints (or just the next two or one). -- [PowerButtonState](PowerButtonState.md) — power button state notification message -- [PowerMonitor](PowerMonitor.md) — power monitor message +- [PositionSetpoint](PositionSetpoint.md) — this file is only used in the position_setpoint triple as a dependency. +- [PositionSetpointTriplet](PositionSetpointTriplet.md) — Global position setpoint triplet in WGS84 coordinates. This are the three next waypoints (or just the next two or one). +- [PowerButtonState](PowerButtonState.md) — power button state notification message. +- [PowerMonitor](PowerMonitor.md) — power monitor message. - [PpsCapture](PpsCapture.md) -- [PurePursuitStatus](PurePursuitStatus.md) — Pure pursuit status +- [PurePursuitStatus](PurePursuitStatus.md) — Pure pursuit status. - [PwmInput](PwmInput.md) - [Px4ioStatus](Px4ioStatus.md) - [QshellReq](QshellReq.md) @@ -224,15 +192,15 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [RateCtrlStatus](RateCtrlStatus.md) - [RcChannels](RcChannels.md) - [RcParameterMap](RcParameterMap.md) -- [RoverAttitudeSetpoint](RoverAttitudeSetpoint.md) — Rover Attitude Setpoint -- [RoverAttitudeStatus](RoverAttitudeStatus.md) — Rover Attitude Status -- [RoverPositionSetpoint](RoverPositionSetpoint.md) — Rover Position Setpoint -- [RoverRateSetpoint](RoverRateSetpoint.md) — Rover Rate setpoint -- [RoverRateStatus](RoverRateStatus.md) — Rover Rate Status -- [RoverSteeringSetpoint](RoverSteeringSetpoint.md) — Rover Steering setpoint -- [RoverThrottleSetpoint](RoverThrottleSetpoint.md) — Rover Throttle setpoint -- [RoverVelocitySetpoint](RoverVelocitySetpoint.md) — Rover Velocity Setpoint -- [RoverVelocityStatus](RoverVelocityStatus.md) — Rover Velocity Status +- [RoverAttitudeSetpoint](RoverAttitudeSetpoint.md) — Rover Attitude Setpoint. +- [RoverAttitudeStatus](RoverAttitudeStatus.md) — Rover Attitude Status. +- [RoverPositionSetpoint](RoverPositionSetpoint.md) — Rover Position Setpoint. +- [RoverRateSetpoint](RoverRateSetpoint.md) — Rover Rate setpoint. +- [RoverRateStatus](RoverRateStatus.md) — Rover Rate Status. +- [RoverSpeedSetpoint](RoverSpeedSetpoint.md) — Rover Speed Setpoint. +- [RoverSpeedStatus](RoverSpeedStatus.md) — Rover Velocity Status. +- [RoverSteeringSetpoint](RoverSteeringSetpoint.md) — Rover Steering setpoint. +- [RoverThrottleSetpoint](RoverThrottleSetpoint.md) — Rover Throttle setpoint. - [Rpm](Rpm.md) - [RtlStatus](RtlStatus.md) - [RtlTimeEstimate](RtlTimeEstimate.md) @@ -240,72 +208,64 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [SensorAccel](SensorAccel.md) - [SensorAccelFifo](SensorAccelFifo.md) - [SensorAirflow](SensorAirflow.md) -- [SensorBaro](SensorBaro.md) -- [SensorCombined](SensorCombined.md) — Sensor readings in SI-unit form. - These fields are scaled and offset-compensated where possible and do not - change with board revisions and sensor updates. -- [SensorCorrection](SensorCorrection.md) — Sensor corrections in SI-unit form for the voted sensor +- [SensorBaro](SensorBaro.md) — Barometer sensor. +- [SensorCombined](SensorCombined.md) — Sensor readings in SI-unit form. These fields are scaled and offset-compensated where possible and do not. change with board revisions and sensor updates. +- [SensorCorrection](SensorCorrection.md) — Sensor corrections in SI-unit form for the voted sensor. - [SensorGnssRelative](SensorGnssRelative.md) — GNSS relative positioning information in NED frame. The NED frame is defined as the local topological system at the reference station. -- [SensorGps](SensorGps.md) — GPS position in WGS84 coordinates. - the field 'timestamp' is for the position & velocity (microseconds) +- [SensorGnssStatus](SensorGnssStatus.md) — Gnss quality indicators. +- [SensorGps](SensorGps.md) — GPS position in WGS84 coordinates. the field 'timestamp' is for the position & velocity (microseconds). - [SensorGyro](SensorGyro.md) - [SensorGyroFft](SensorGyroFft.md) - [SensorGyroFifo](SensorGyroFifo.md) - [SensorHygrometer](SensorHygrometer.md) - [SensorMag](SensorMag.md) - [SensorOpticalFlow](SensorOpticalFlow.md) -- [SensorPreflightMag](SensorPreflightMag.md) — Pre-flight sensor check metrics. - The topic will not be updated when the vehicle is armed -- [SensorSelection](SensorSelection.md) — Sensor ID's for the voted sensors output on the sensor_combined topic. - Will be updated on startup of the sensor module and when sensor selection changes -- [SensorUwb](SensorUwb.md) — UWB distance contains the distance information measured by an ultra-wideband positioning system, - such as Pozyx or NXP Rddrone. +- [SensorPreflightMag](SensorPreflightMag.md) — Pre-flight sensor check metrics. The topic will not be updated when the vehicle is armed. +- [SensorSelection](SensorSelection.md) — Sensor ID's for the voted sensors output on the sensor_combined topic. Will be updated on startup of the sensor module and when sensor selection changes. +- [SensorTemp](SensorTemp.md) +- [SensorUwb](SensorUwb.md) — UWB distance contains the distance information measured by an ultra-wideband positioning system,. such as Pozyx or NXP Rddrone. - [SensorsStatus](SensorsStatus.md) — Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. - [SensorsStatusImu](SensorsStatusImu.md) — Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. - [SystemPower](SystemPower.md) -- [TakeoffStatus](TakeoffStatus.md) — Status of the takeoff state machine currently just available for multicopters -- [TaskStackInfo](TaskStackInfo.md) — stack information for a single running process +- [TakeoffStatus](TakeoffStatus.md) — Status of the takeoff state machine currently just available for multicopters. +- [TaskStackInfo](TaskStackInfo.md) — stack information for a single running process. - [TecsStatus](TecsStatus.md) - [TelemetryStatus](TelemetryStatus.md) - [TiltrotorExtraControls](TiltrotorExtraControls.md) - [TimesyncStatus](TimesyncStatus.md) -- [TrajectorySetpoint6dof](TrajectorySetpoint6dof.md) — Trajectory setpoint in NED frame - Input to position controller. +- [TrajectorySetpoint6dof](TrajectorySetpoint6dof.md) — Trajectory setpoint in NED frame. Input to position controller. - [TransponderReport](TransponderReport.md) -- [TuneControl](TuneControl.md) — This message is used to control the tunes, when the tune_id is set to CUSTOM - then the frequency, duration are used otherwise those values are ignored. -- [UavcanParameterRequest](UavcanParameterRequest.md) — UAVCAN-MAVLink parameter bridge request type -- [UavcanParameterValue](UavcanParameterValue.md) — UAVCAN-MAVLink parameter bridge response type -- [UlogStream](UlogStream.md) — Message to stream ULog data from the logger. Corresponds to the LOGGING_DATA - mavlink message -- [UlogStreamAck](UlogStreamAck.md) — Ack a previously sent ulog_stream message that had - the NEED_ACK flag set +- [TuneControl](TuneControl.md) — This message is used to control the tunes, when the tune_id is set to CUSTOM. then the frequency, duration are used otherwise those values are ignored. +- [UavcanParameterRequest](UavcanParameterRequest.md) — UAVCAN-MAVLink parameter bridge request type. +- [UavcanParameterValue](UavcanParameterValue.md) — UAVCAN-MAVLink parameter bridge response type. +- [UlogStream](UlogStream.md) — Message to stream ULog data from the logger. Corresponds to the LOGGING_DATA. mavlink message. +- [UlogStreamAck](UlogStreamAck.md) — Ack a previously sent ulog_stream message that had. the NEED_ACK flag set. - [VehicleAcceleration](VehicleAcceleration.md) -- [VehicleAirData](VehicleAirData.md) +- [VehicleAirData](VehicleAirData.md) — Vehicle air data. - [VehicleAngularAccelerationSetpoint](VehicleAngularAccelerationSetpoint.md) -- [VehicleConstraints](VehicleConstraints.md) — Local setpoint constraints in NED frame - setting something to NaN means that no limit is provided +- [VehicleConstraints](VehicleConstraints.md) — Local setpoint constraints in NED frame. setting something to NaN means that no limit is provided. - [VehicleImu](VehicleImu.md) — IMU readings in SI-unit form. - [VehicleImuStatus](VehicleImuStatus.md) -- [VehicleLocalPositionSetpoint](VehicleLocalPositionSetpoint.md) — Local position setpoint in NED frame - Telemetry of PID position controller to monitor tracking. - NaN means the state was not controlled +- [VehicleLocalPositionSetpoint](VehicleLocalPositionSetpoint.md) — Local position setpoint in NED frame. Telemetry of PID position controller to monitor tracking. NaN means the state was not controlled. - [VehicleMagnetometer](VehicleMagnetometer.md) - [VehicleOpticalFlow](VehicleOpticalFlow.md) — Optical flow in XYZ body frame in SI units. - [VehicleOpticalFlowVel](VehicleOpticalFlowVel.md) -- [VehicleRoi](VehicleRoi.md) — Vehicle Region Of Interest (ROI) +- [VehicleRoi](VehicleRoi.md) — Vehicle Region Of Interest (ROI). - [VehicleThrustSetpoint](VehicleThrustSetpoint.md) - [VehicleTorqueSetpoint](VehicleTorqueSetpoint.md) -- [VelocityLimits](VelocityLimits.md) — Velocity and yaw rate limits for a multicopter position slow mode only +- [VelocityLimits](VelocityLimits.md) — Velocity and yaw rate limits for a multicopter position slow mode only. +- [Vtx](Vtx.md) - [WheelEncoders](WheelEncoders.md) - [YawEstimatorStatus](YawEstimatorStatus.md) - [AirspeedValidatedV0](AirspeedValidatedV0.md) - [ArmingCheckReplyV0](ArmingCheckReplyV0.md) -- [BatteryStatusV0](BatteryStatusV0.md) — Battery status -- [EventV0](EventV0.md) — this message is required here in the msg_old folder because other msg are depending on it - Events interface +- [ArmingCheckRequestV0](ArmingCheckRequestV0.md) — Arming check request. +- [BatteryStatusV0](BatteryStatusV0.md) — Battery status. +- [ConfigOverridesV0](ConfigOverridesV0.md) — Configurable overrides by (external) modes or mode executors. +- [EventV0](EventV0.md) — this message is required here in the msg_old folder because other msg are depending on it. Events interface. - [HomePositionV0](HomePositionV0.md) — GPS home position in WGS84 coordinates. +- [RegisterExtComponentReplyV0](RegisterExtComponentReplyV0.md) +- [RegisterExtComponentRequestV0](RegisterExtComponentRequestV0.md) — Request to register an external component. - [VehicleAttitudeSetpointV0](VehicleAttitudeSetpointV0.md) -- [VehicleLocalPositionV0](VehicleLocalPositionV0.md) — Fused local position in NED. - The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -- [VehicleStatusV0](VehicleStatusV0.md) — Encodes the system state of the vehicle published by commander +- [VehicleLocalPositionV0](VehicleLocalPositionV0.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. +- [VehicleStatusV0](VehicleStatusV0.md) — Encodes the system state of the vehicle published by commander. diff --git a/docs/en/neural_networks/index.md b/docs/en/neural_networks/index.md new file mode 100644 index 0000000000..4379f079f9 --- /dev/null +++ b/docs/en/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/en/neural_networks/mc_neural_network_control.md b/docs/en/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..0c1cc83b57 --- /dev/null +++ b/docs/en/neural_networks/mc_neural_network_control.md @@ -0,0 +1,123 @@ +# MC Neural Networks Control + + + +::: warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +::: tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: + +## Neural Network PX4 Firmware + +::: warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Input + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### Output + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/en/advanced/nn_module_utilities.md b/docs/en/neural_networks/nn_module_utilities.md similarity index 97% rename from docs/en/advanced/nn_module_utilities.md rename to docs/en/neural_networks/nn_module_utilities.md index d00f8aff63..b1df217ded 100644 --- a/docs/en/advanced/nn_module_utilities.md +++ b/docs/en/neural_networks/nn_module_utilities.md @@ -2,7 +2,7 @@ The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. -The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md). +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. ::: tip @@ -75,7 +75,7 @@ Which timing library is included and used is based on wether PX4 is built with N ## Changing the setpoint -The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message’s position fields to define its target. +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. To follow a trajectory, you can send updated setpoints. For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. Note that this is not included in upstream PX4. diff --git a/docs/en/neural_networks/raptor.md b/docs/en/neural_networks/raptor.md new file mode 100644 index 0000000000..c82b78ad6c --- /dev/null +++ b/docs/en/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +::: warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## Overview + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## Structure + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## Features + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## Usage + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### Setup + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +::: warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### Troubleshooting + +#### Logging + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/en/advanced/tflm.md b/docs/en/neural_networks/tflm.md similarity index 90% rename from docs/en/advanced/tflm.md rename to docs/en/neural_networks/tflm.md index 2c30ac5216..57b2847867 100644 --- a/docs/en/advanced/tflm.md +++ b/docs/en/neural_networks/tflm.md @@ -1,6 +1,6 @@ # TensorFlow Lite Micro (TFLM) -The PX4 [Multicopter Neural Network](../advanced/neural_networks.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. @@ -68,7 +68,7 @@ The `_input_tensor` is also defined, it is fetched from `_control_interpreter->i The `_input_tensor` is filled in the `PopulateInputTensor()` function. `_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. -The inputs used in the control network is covered in [Neural Networks](../advanced/neural_networks.md). +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). ### Outputs diff --git a/docs/en/payloads/generic_actuator_control.md b/docs/en/payloads/generic_actuator_control.md index 46b0248bf1..82bd1f4df9 100644 --- a/docs/en/payloads/generic_actuator_control.md +++ b/docs/en/payloads/generic_actuator_control.md @@ -56,7 +56,6 @@ To use a generic actuator in a mission: 1. Change the waypoint mission item to a "Set actuator" mission item: ![Set actuator mission item](../../assets/qgc/plan/mission_item_editors/mission_item_select_set_actuator.png) - - Select the header on the waypoint mission editor to open the **Select Mission Command** editor. - Select the category **Advanced**, and then the **Set actuator** item (if the item is not present, try a more recent version of _QGroundControl_ or a daily build). This will change the mission item type to "Set actuator". diff --git a/docs/en/peripherals/adsb_flarm.md b/docs/en/peripherals/adsb_flarm.md index 000150418c..802f197e82 100644 --- a/docs/en/peripherals/adsb_flarm.md +++ b/docs/en/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder It has been tested with the following devices: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## Hardware Setup diff --git a/docs/en/peripherals/dshot.md b/docs/en/peripherals/dshot.md index fdd986e06a..2030946d1a 100644 --- a/docs/en/peripherals/dshot.md +++ b/docs/en/peripherals/dshot.md @@ -11,6 +11,10 @@ DShot is an alternative ESC protocol that has several advantages over [PWM](../p This topic shows how to connect and configure DShot ESCs. +## Supported ESC + +[ESCs & Motors > Supported ESCs](../peripherals/esc_motors#supported-esc) has a list of supported ESC (check "Protocols" column for DShot ESC). + ## Wiring/Connections {#wiring} DShot ESC are wired the same way as [PWM ESCs](pwm_escs_and_servo.md). @@ -76,7 +80,6 @@ The most important ones are: ``` - Permanently set the spin direction of a motor connected to FMU output pin 1 (while motors are _not_ spinning): - - Set spin direction to `reversed`: ```sh @@ -104,7 +107,6 @@ The most important ones are: ``` ::: info - - The commands will have no effect if the motors are spinning, or if the ESC is already set to the corresponding direction. - The ESC will revert to its last saved direction (normal or reversed) on reboot if `save` is not called after changing the direction. diff --git a/docs/en/peripherals/esc_motors.md b/docs/en/peripherals/esc_motors.md index e6c97d00a3..7fddeb999d 100644 --- a/docs/en/peripherals/esc_motors.md +++ b/docs/en/peripherals/esc_motors.md @@ -3,80 +3,44 @@ Many PX4 drones use brushless motors that are driven by the flight controller via an Electronic Speed Controller (ESC). The ESC takes a signal from the flight controller and uses it to set control the level of power delivered to the motor. -PX4 supports a number of common protocols for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). +PX4 supports a number of [common protocols](../esc/esc_protocols.md) for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). + +## Supported ESC + +The following list is non-exhaustive. + +| ESC Device | Protocols | Firmwares | Notes | +| ------------------------------ | ------------------------------------ | ------------------------ | ----------------------------------------------------- | +| [ARK 4IN1 ESC] | [Dshot], [PWM] | [AM32] | Has versions with/without connnectors | +| [Holybro Kotleta 20] | [DroneCAN], [PWM] | [PX4 Sapog ESC Firmware] | | +| [Vertiq Motor & ESC modules] | [Dshot], [OneShot], Multishot, [PWM] | Vertiq firmware | Larger modules support DroneCAN, ESC and Motor in one | +| [RaccoonLab CAN PWM ESC nodes] | [DroneCAN], Cyphal | | Cyphal and DroneCAN notes for PWM ESC | +| [VESC ESCs] | [DroneCAN], [PWM] | VESC project firmware | | +| [Zubax Telega] | [DroneCAN], [PWM] | Telega-based | ESC and Motor in one | + + + +[ARK 4IN1 ESC]: ../esc/ark_4in1_esc.md +[AM32]: https://am32.ca/ +[PX4 Sapog ESC Firmware]: ../dronecan/sapog.md +[VESC ESCs]: ../peripherals/vesc.md +[DroneCAN]: ../dronecan/escs.md +[Dshot]: ../peripherals/dshot.md +[OneShot]: ../peripherals/oneshot.md +[PWM]: ../peripherals/pwm_escs_and_servo.md +[Holybro Kotleta 20]: ../dronecan/holybro_kotleta.md +[Vertiq Motor & ESC modules]: ../peripherals/vertiq.md +[RaccoonLab CAN PWM ESC nodes]: ../dronecan/raccoonlab_nodes.md +[Zubax Telega]: ../dronecan/zubax_telega.md + +## See Also For more information see: +- [ESC Protocols](../esc/esc_protocols.md) — overview of main ESC/Servo protocols supported by PX4 - [PWM ESCs and Servos](../peripherals/pwm_escs_and_servo.md) - [OneShot ESCs and Servos](../peripherals/oneshot.md) - [DShot](../peripherals/dshot.md) - [DroneCAN ESCs](../dronecan/escs.md) - [ESC Calibration](../advanced_config/esc_calibration.md) - [ESC Firmware and Protocols Overview](https://oscarliang.com/esc-firmware-protocols/) (oscarliang.com) - -A high level overview of the main ESC/Servo protocols supported by PX4 is given below. - -## ESC Protocols - -### PWM - -[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). - -PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired power level. -The pulse wdith typically ranges between 1000uS for zero power and 2000uS for full power. -The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50Hz and 490 Hz (the theoretical maximum being 500Hz for a very small "off" cycle). -A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. -For PWM servos 50Hz is usually sufficient, and many don't support higher rates. - -![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) - -In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the range values representing low and high values can vary significantly. -Unlike [dshot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) -- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### Oneshot 125 - -[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. -They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). -There are a number of variants of the OneShot protocol, which support different rates. -PX4 only supports OneShot 125. - -OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125us to 250us for zero to full power). -This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. -For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. -The actual supported rate depends on the ESC used. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### DShot - -[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduce latency, in particular racing multicopters, VTOL vehicles, and so on. - -It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). -In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can revers motor spin directions - -PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). -Selecting a higher rate DShot ESC in the UI result in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. - -### DroneCAN - -[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. -The PX4 implementation is currently limited to update rates of 200Hz. - -DroneCAN shares many similar benefits to [Dshot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. - -[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). diff --git a/docs/en/peripherals/gripper.md b/docs/en/peripherals/gripper.md index 07886d70ca..da62f315d2 100644 --- a/docs/en/peripherals/gripper.md +++ b/docs/en/peripherals/gripper.md @@ -72,7 +72,6 @@ To set the actuation timeout: There are two easy ways to open and close the gripper. While the drone is on a bench and the propellers are removed: - - Run the `payload_deliverer` test in the QGC [MAVLink Shell](../debug/mavlink_shell.md): ```sh diff --git a/docs/en/peripherals/mavlink_peripherals.md b/docs/en/peripherals/mavlink_peripherals.md index 111d723ffd..9a790a9218 100644 --- a/docs/en/peripherals/mavlink_peripherals.md +++ b/docs/en/peripherals/mavlink_peripherals.md @@ -28,7 +28,6 @@ The parameters for each instance are: For more information see [Serial Port Configuration](../peripherals/serial_configuration.md). - [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) - Specify the telemetry mode/target (the set of messages to stream for the current instance and their rate). The default values are: - - _Normal_: Standard set of messages for a GCS. - _Custom_ or _Magic_: Nothing (in the default PX4 implementation). Modes may be used for testing when developing a new mode. diff --git a/docs/en/peripherals/remote_id.md b/docs/en/peripherals/remote_id.md index 399b2cf973..60d3413661 100644 --- a/docs/en/peripherals/remote_id.md +++ b/docs/en/peripherals/remote_id.md @@ -165,7 +165,6 @@ PX4 v1.14 streams these messages by default (in streaming modes: normal, onboard - [OPEN_DRONE_ID_LOCATION](https://mavlink.io/en/messages/common.html#OPEN_DRONE_ID_LOCATION) (1 Hz) - UAV location, altitude, direction, and speed. - [OPEN_DRONE_ID_SYSTEM](https://mavlink.io/en/messages/common.html#OPEN_DRONE_ID_SYSTEM) (1 Hz) Operator location/altitude, multiple aircraft information (group/swarm, if applicable), full timestamp and possible category/class information. - - Implementation assumes operator is located at vehicle home position (does not yet support getting operator position from GCS). This is believed to be compliant for broadcast-only Remote IDs. @@ -243,7 +242,7 @@ If the Remote ID CAN node is present and the messages are not being received, th 2. Navigate to the [Application settings](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/general.html): **Application Settings > General > Miscellaneous**. 3. Select `Enable Remote ID`. The Remote ID tab should appear. - + ::: info If this option is not present you may be in a very recent version of QGC. In that case, open the view at: **Application Settings > Remote ID**. diff --git a/docs/en/peripherals/serial_configuration.md b/docs/en/peripherals/serial_configuration.md index 9228a0ad5a..65650feef5 100644 --- a/docs/en/peripherals/serial_configuration.md +++ b/docs/en/peripherals/serial_configuration.md @@ -106,7 +106,6 @@ The following ports are commonly mapped to specific functions on all boards: This is configured by default as a MAVLink port the onboard profile (for companion computers). The configuration for MAVLink is unique to this port (it doesn't use the `MAV_X_CONFIG` parameters). - - [SYS_USB_AUTO](../advanced_config/parameter_reference.md#SYS_USB_AUTO) sets whether the port is set to no partiular protocol, autodetects the protocol, or sets the comms link to MAVLink. - [USB_MAV_MODE](../advanced_config/parameter_reference.md#USB_MAV_MODE) sets the MAVLink profile that is used if MAVLink is set or detected. diff --git a/docs/en/peripherals/vertiq.md b/docs/en/peripherals/vertiq.md index 82c7611f16..224118a8bf 100644 --- a/docs/en/peripherals/vertiq.md +++ b/docs/en/peripherals/vertiq.md @@ -38,6 +38,18 @@ Instructions for integrating the motor/ESC using with DroneCAN can be found in [ These instructions walk you through setting the correct parameters for enabling the flight controller's DroneCAN drivers, setting the correct configuration parameters for communication with Vertiq modules on the DroneCAN bus, ESC configuration, and testing that your flight controller can properly control your modules over DroneCAN. +#### LED Configuration for Vertiq Modules + +::: info +This configuration is only required if you have the optional [Vertiq LED module add-on](https://www.vertiq.co/add-ons). +Standard Vertiq ESC modules do not include LEDs. +::: + +Vertiq LED Add-on modules have two LEDs per ESC (RGB for status, White for anti-collision). +See [DroneCAN Lights](../dronecan/index.md#lights) for configuration instructions. + +The `light_id` for each LED is calculated as: `esc_index × 3 + BASE_ID`, where `BASE_ID` is 1 for RGB and 2 for White. + ### DShot/PWM Configuration Instructions for integrating the motor/ESC using PWM and DShot can be found in [PWM and DShot Control with a Flight Controller](https://iqmotion.readthedocs.io/en/latest/tutorials/pwm_control_flight_controller.html). diff --git a/docs/en/power_module/ark_12s_pab_power_module.md b/docs/en/power_module/ark_12s_pab_power_module.md index 77c33cf32e..63c6223758 100644 --- a/docs/en/power_module/ark_12s_pab_power_module.md +++ b/docs/en/power_module/ark_12s_pab_power_module.md @@ -13,25 +13,21 @@ Order this module from: ## Hardware Specifications - **TI INA238 Digital Power Monitor** - - 0.0001 Ohm Shunt - I2C Interface - **5.2V 6A Step-Down Regulator** - - 66V Maximum Input Voltage - 10V Minimum Input Voltage at 6A Out - Output Over-Current Protection - **Connections** - - Solder Pads Battery Input - Solder Pads Battery Output - 6 Pin Molex CLIK-Mate Output - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) - **Other** - - USA Built - Includes 6 Pin Molex CLIK-Mate Cable diff --git a/docs/en/power_module/ark_12s_payload_power_module.md b/docs/en/power_module/ark_12s_payload_power_module.md new file mode 100644 index 0000000000..4693bf1976 --- /dev/null +++ b/docs/en/power_module/ark_12s_payload_power_module.md @@ -0,0 +1,56 @@ +# ARK 12S Payload Power Module + +The [ARK 12S Payload Power Module](https://arkelectron.com/product/ark-12s-payload-power-module/) is a dual 5V 6A and 12V 6A power supply and digital power monitor designed for the Pixhawk Autopilot Bus Carrier boards. + +This is similar to the [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) except that the additional 12V 6A supply allows easier powering of a payload. + +![ARK 12S Payload Power Module](../../assets/hardware/power_module/ark_power_modules//ark_12s_payload_power.jpg) + +## Where to Buy + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-12s-payload-power-module/) (US) + +## Hardware Specifications + +- **TI INA238 Digital Power Monitor** + - 0.0001 Ohm Shunt + - I2C Interface + +- **5.2V 6A Step-Down Regulator** + - 10V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **12.0V 6A Step-Down Regulator** + - 15V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **75V Maximum Input Voltage** + +- **Connections** + - Solder Pads Battery Input + - Solder Pads Battery Output + - 6 Pin Molex CLIK-Mate Output + - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) + - 4 Pin Molex CLIK-Mate 12V Output + +- **Other** + - USA Built + - Includes 6 Pin Molex CLIK-Mate Cable + +- **Additional Information** + - Weight: 20.5 g + - Dimensions: 3.7 cm x 3.5 cm x 1.3 cm + +## PX4 Setup + +- Disable the `SENS_EN_INA226` parameter if it is enabled. +- Enable the `SENS_EN_INA238` parameter. +- Reboot the flight controller. +- Set the `INA238_SHUNT` parameter to 0.0001. +- Reboot the flight controller. + +## See Also + +- [ARK 12S Payload Power Module Documentation](https://docs.arkelectron.com/power/ark-12s-payload-power-module) (ARK Docs) diff --git a/docs/en/power_module/ark_pab_power_module.md b/docs/en/power_module/ark_pab_power_module.md index 7ee5f0d024..20eddbeeb8 100644 --- a/docs/en/power_module/ark_pab_power_module.md +++ b/docs/en/power_module/ark_pab_power_module.md @@ -6,35 +6,36 @@ Note that at 60A and 20°C without cooling, the 5V regulator is de-rated to a 3A ![ARK PAB Power Module](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_module.jpg) +This power module is also available without connectors: + +![ARK PAB Power Module No Connector](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_no_connector.jpg) + ## Where to Buy Order this module from: -- [ARK Electronics](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module No Connector](https://arkelectron.com/product/ark-pab-power-module-no-connector/) (US) ## Hardware Specifications - **TI INA226 Digital Power Monitor** - - 0.0005 Ohm Shunt - I2C Interface - **5.2V 6A Step-Down Regulator** - - 33V Maximum Input Voltage - 5.8V Minimum Input Voltage at 6A Out - Output Over-Voltage Protection - Output Over-Current Protection - **Connections** - - - XT60 Battery Input - - XT60 Battery Output + - XT60 Battery Input / Solder Pad Battery Input (No Connector version) + - XT60 Battery Output / Solder Pad Battery Output (No Connector version) - 6 Pin Molex CLIK-Mate Output - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) - **Other** - - USA Built - FCC Compliant - Includes 6 Pin Molex CLIK-Mate Cable diff --git a/docs/en/power_module/cuav_hv_pm.md b/docs/en/power_module/cuav_hv_pm.md index 7093c588ed..48e169a7f8 100644 --- a/docs/en/power_module/cuav_hv_pm.md +++ b/docs/en/power_module/cuav_hv_pm.md @@ -1,9 +1,9 @@ # CUAV HV PM (High-Voltage Power Module) -The CUAV® *HV_PM* power module is a "high voltage" power module independently developed by CUAV. +The CUAV® _HV_PM_ power module is a "high voltage" power module independently developed by CUAV. :::tip -The *HV_PM* is included in the CUAV V5+/V5 nano kit, but is also be sold separately. +The _HV_PM_ is included in the CUAV V5+/V5 nano kit, but is also be sold separately. There are different cables depending on the flight controller (Pixhack v3, V5+/V5 nano, Pixhawk). It can be used with other flight controllers, but you may need to modify the cable pin. ::: @@ -12,7 +12,7 @@ It can be used with other flight controllers, but you may need to modify the cab - **Higher voltage input:** 10V-60V (3s~14s battery) - **Accurate battery monitor:** - - **Voltage detection accuracy:** +-0.1v; + - **Voltage detection accuracy:** +-0.1v; - **Current detection accuracy:** +-0.2A - **BEC (5v) max current:** 5A - **Max (detection) current:** 60A @@ -31,5 +31,6 @@ It can be used with other flight controllers, but you may need to modify the cab [Battery Estimation Tuning](../config/battery.md) describes how to configure the battery and power module. The key configuration settings for `HV_PM` are: + - **Voltage divider:** 18 - **Amps per volt:** 24 A/V diff --git a/docs/en/power_module/holybro_pm02.md b/docs/en/power_module/holybro_pm02.md index 0f88cabf20..adb6447710 100644 --- a/docs/en/power_module/holybro_pm02.md +++ b/docs/en/power_module/holybro_pm02.md @@ -9,7 +9,6 @@ The module can be used with other flight controllers that require an analog powe ![Holybro PM02](../../assets/hardware/power_module/holybro_pm02/pm02.jpg) - ## Specifications - **Rated current**: 60A diff --git a/docs/en/power_module/holybro_pm03d.md b/docs/en/power_module/holybro_pm03d.md index 7f6825a0c2..526beebf69 100644 --- a/docs/en/power_module/holybro_pm03d.md +++ b/docs/en/power_module/holybro_pm03d.md @@ -31,13 +31,13 @@ The PM is **NOT** compatible with flight controllers that require an analog powe - **Mounting**: 45 x 45mm - **Weight**: 59g - **Connections**: - - XT-60 for battery - - XT-30 for motor & peripheral device (battery voltage) - - Solder pads in each corner (battery voltage) - - CLIK-Mate 2.0mm for flight controller (5.2V/3A standalone BEC) - - JST GH 4pin (5.2V/3A, BEC shared with 5.2V triple row pin header) - - 2x Triple row pin header (5.2V/3A, BEC shared with JST GH 4pin) - - 2x Triple row pin header (8V or 12V selectable by moving header jumper, 3A) +- XT-60 for battery +- XT-30 for motor & peripheral device (battery voltage) +- Solder pads in each corner (battery voltage) +- CLIK-Mate 2.0mm for flight controller (5.2V/3A standalone BEC) +- JST GH 4pin (5.2V/3A, BEC shared with 5.2V triple row pin header) +- 2x Triple row pin header (5.2V/3A, BEC shared with JST GH 4pin) +- 2x Triple row pin header (8V or 12V selectable by moving header jumper, 3A) ## Package Contents @@ -46,8 +46,8 @@ The PM is **NOT** compatible with flight controllers that require an analog powe - 1x Electrolytic capacitor: 220uF 63V (pre-soldered) - 1x 2.0mm pitch CLIK-Mate 6pin cable (To power flight controller) - 4pin JST GH to USB Type C -- 4pin JST GH to barrel plug (2.1*5.5mm) -- 4pin JST GH to barrel plug (2.5*5.5mm) +- 4pin JST GH to barrel plug (2.1\*5.5mm) +- 4pin JST GH to barrel plug (2.5\*5.5mm) - 4pin Pin Dupont Cable (2pc) - Nylon standoffs & nuts diff --git a/docs/en/power_module/holybro_pm06_pixhawk4mini_power_module.md b/docs/en/power_module/holybro_pm06_pixhawk4mini_power_module.md index ea8ac4f99a..9821c35cea 100644 --- a/docs/en/power_module/holybro_pm06_pixhawk4mini_power_module.md +++ b/docs/en/power_module/holybro_pm06_pixhawk4mini_power_module.md @@ -4,7 +4,6 @@ This power module has integrated power distribution board and provides regulated ![PM06](../../assets/hardware/power_module/holybro_pm06_14s/pm06v2_pm06v2-14s.jpg) - ## Specifications - **PCB Current:** 120A continued @@ -18,7 +17,7 @@ This power module has integrated power distribution board and provides regulated ## Mechanical Specifications - **Dimensions:** 35x35x5mm -- **Mounting hole:** 30.5mm*30.5mm +- **Mounting hole:** 30.5mm\*30.5mm - **Weight:** 24g ## Where to Buy diff --git a/docs/en/power_module/holybro_pm07_pixhawk4_power_module.md b/docs/en/power_module/holybro_pm07_pixhawk4_power_module.md index a1791ff177..0e7f7414fe 100644 --- a/docs/en/power_module/holybro_pm07_pixhawk4_power_module.md +++ b/docs/en/power_module/holybro_pm07_pixhawk4_power_module.md @@ -33,14 +33,12 @@ This module can be purchased as bundle with [Pixhawk 4](../assembly/quick_start_ [Pixhawk 4 Power Module (PM07)](https://holybro.com/collections/power-modules-pdbs/products/pixhawk-4-power-module-pm07) - ## Wiring/Connections Wiring and connection information can be found in: [Pixhawk 4 > Power](../assembly/quick_start_pixhawk4.md#power). ![Pixhawk 4 - Power Management Board](../../assets/hardware/power_module/holybro_pm07/pixhawk4_power_management_board.png) - ## Further Information [Quick Start Guide](https://docs.holybro.com/power-module-and-pdb/power-module/pm07-quick-start-guide) (Holybro) diff --git a/docs/en/power_module/index.md b/docs/en/power_module/index.md index 05eb28f553..fe78d1c223 100644 --- a/docs/en/power_module/index.md +++ b/docs/en/power_module/index.md @@ -27,6 +27,7 @@ This section provides information about a number of power modules and power dist - Digital (I2C) voltage and current power modules (for Pixhawk FMUv6X and FMUv5X derived controllers): - [ARK PAB Power Module](../power_module/ark_pab_power_module.md) - [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](../power_module/ark_12s_payload_power_module.md) - [Holybro PM02D](../power_module/holybro_pm02d.md) - [Holybro PM03D](../power_module/holybro_pm03d.md) - [DroneCAN](../dronecan/index.md) power modules diff --git a/docs/en/power_module/sky-drones_smartap-pdb.md b/docs/en/power_module/sky-drones_smartap-pdb.md index 6447feff24..3ea985b7b4 100644 --- a/docs/en/power_module/sky-drones_smartap-pdb.md +++ b/docs/en/power_module/sky-drones_smartap-pdb.md @@ -21,7 +21,6 @@ SmartAP PDB makes connecting high-power lines easier and much more reliable. - Integrated electromagnetic sounder (buzzer) - Power output for the flight controller (both 5V regulated and battery voltage level output) - ## Size and Weight - Length: 65mm @@ -38,12 +37,10 @@ The key configuration settings are: - Voltage divider: 15.51 - Amps per volt: 36.00 - ## Where to buy [SmartAP PDB](https://sky-drones.com/parts/smartap-pdb.html) - ## Wiring / Pinout SmartAP Power Distribution Board pinout diagram is shown below. @@ -61,7 +58,6 @@ The current sensor is located on the bottom side of the PDB. ![SmartAP PDB](../../assets/hardware/power_module/sky-drones_smartap-pdb/smartap-pdb-current-sensor.png) - ## Further Information - [Buy SmartAP PDB](https://sky-drones.com/power/smartap-pdb.html) diff --git a/docs/en/releases/1.13.md b/docs/en/releases/1.13.md index fdda97c87f..7357fe68cd 100644 --- a/docs/en/releases/1.13.md +++ b/docs/en/releases/1.13.md @@ -24,7 +24,6 @@ ### Common - **Explicit Joystick source selection ([PR#17404](https://github.com/PX4/PX4-Autopilot/pull/17404))** - - Possibility to: - Explicitly allow just one source - Fall back to other source in air diff --git a/docs/en/releases/1.16.md b/docs/en/releases/1.16.md index 0fac823996..42019f52d1 100644 --- a/docs/en/releases/1.16.md +++ b/docs/en/releases/1.16.md @@ -129,6 +129,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) @@ -138,6 +139,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). - Parameter to always start mavlink stream via USB. ([PX4-Autopilot#22234](https://github.com/PX4/PX4-Autopilot/pull/22234)) - Refactor: MAVLink message handling in one function, reference instead of pointer to main instance ([PX4-Autopilo#23219](https://github.com/PX4/PX4-Autopilot/pull/22234)) - mavlink log handler rewrite for improved effeciency ([PX4-Autopilo#23219](https://github.com/PX4/PX4-Autopilot/pull/22234)) + ### Multi-Rotor - [Multirotor] add yaw torque low pass filter ([PX4-Autopilot#24173](https://github.com/PX4/PX4-Autopilot/pull/24173)) diff --git a/docs/en/releases/1.17.md b/docs/en/releases/1.17.md new file mode 100644 index 0000000000..67728cca98 --- /dev/null +++ b/docs/en/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +::: warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Read Before Upgrading + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Major Changes + +- TBD + +## Upgrade Guide + +## Other changes + +### Hardware Support + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### Control + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Estimation + +- TBD + + + +### Simulation + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- TBD + +### Ethernet + +- TBD + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- TBD + + + +### VTOL + +- TBD + +### Fixed-wing + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### Rover + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- TBD diff --git a/docs/en/releases/index.md b/docs/en/releases/index.md index 7c5aa295c5..cb00c401d5 100644 --- a/docs/en/releases/index.md +++ b/docs/en/releases/index.md @@ -2,11 +2,16 @@ A list of PX4 release notes, they contain a list of the changes that went into each release, explaining the included features, bug fixes, deprecations and updates in detail. -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) - [v1.13](../releases/1.13.md) - [v1.12](../releases/1.12.md) -The full archive of releases for the PX4 autopilot project can be found on [GitHub](https://github.com/PX4/PX4-Autopilot/releases) +The full archive of releases for the PX4 autopilot project can be found on [GitHub](https://github.com/PX4/PX4-Autopilot/releases). + +:::info +For maintainers, see [Release Process](../releases/release_process.md) for the tagging and publishing workflow. +::: diff --git a/docs/en/releases/main.md b/docs/en/releases/main.md index 45c5ef51c6..acee02d522 100644 --- a/docs/en/releases/main.md +++ b/docs/en/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). ::: warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Read Before Upgrading -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -44,7 +44,8 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Control -- TBD +- Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Estimation @@ -52,27 +53,52 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Sensors -- TBD +- Add [sbgECom INS driver](../sensor/sbgecom.md) ([PX4-Autopilot#24137](https://github.com/PX4/PX4-Autopilot/pull/24137)) +- Quick magnetometer calibration now supports specifying an arbitrary initial heading ([PX4-Autopilot#24637](https://github.com/PX4/PX4-Autopilot/pull/24637)) ### Simulation - TBD + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - TBD -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- TBD + + ### MAVLink - TBD +### RC + +- Parse ELRS Status and Link Statistics TX messages in the CRSF parser. + ### Multi-Rotor -- TBD +- Removed parameters `MPC_{XY/Z/YAW}_MAN_EXPO` and use default value instead, as they were not deemed necessary anymore. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). +- Renamed `MPC_HOLD_DZ` to `MAN_DEADZONE` to have it globally available in modes that allow for a dead zone. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### VTOL @@ -80,12 +106,25 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Fixed-wing +- TBD + + ### Rover +- TBD + + ### ROS 2 diff --git a/docs/en/releases/release_process.md b/docs/en/releases/release_process.md new file mode 100644 index 0000000000..73745a0cd3 --- /dev/null +++ b/docs/en/releases/release_process.md @@ -0,0 +1,301 @@ +# Release Process + +This page documents the PX4 release process for maintainers. It covers the steps from preparing a release candidate through to the final announcement. + +## Overview + +PX4 uses a branch-based release workflow: + +- **`release/X.Y`** (e.g., `release/1.17`, `release/2.0`) - The active development branch for a specific release where changes are merged and tested +- **`stable`** - Points to the latest stable release tag; reset after each release +- **`beta`** - For flight testers to validate release candidates + +The target release cycle is approximately 6 months, best effort. The actual cadence depends on testing results and maintainer availability, with an ongoing goal to shorten the cycle. + +Releases are tracked on the [PX4 Release Project Board](https://github.com/orgs/PX4/projects/45), which is reused and renamed for each release cycle. + +### Release Tag Progression + +Release branches go through the following tag stages: + +| Stage | Example | Branch Status | What Gets Merged | +| ---------- | ---------------- | -------------- | --------------------------------------------------- | +| **Alpha** | `v1.18.0-alpha1` | Open for fixes | Bug fixes and regression fixes only | +| **Beta** | `v1.18.0-beta1` | Open for fixes | Bug fixes and regression fixes only | +| **RC** | `v1.18.0-rc1` | Frozen | Nothing (unless veto vote passes) | +| **Stable** | `v1.18.0` | Open for fixes | Bug fixes and regression fixes (for point releases) | + +::: info +New features are never merged to release branches. Once a release branch is created from `main`, only bug fixes and regression fixes are accepted. New features must target `main` and will be included in the next release cycle. +::: + +## Starting a New Release Cycle + +A new release cycle begins immediately after a stable release is published. This involves two votes during the [Weekly Community Q&A Call](../contribute/dev_call.md) when approving a stable release: + +1. **Vote to publish the current release** - Approve the stable release for publication +2. **Vote on the next release name/number** - Decide the version number for the next release (e.g., v1.18 or v2.0) + +### Prepare Release Notes Before Branching + +Release notes are built incrementally in [`main.md`](../releases/main.md), which accumulates changes as they land on `main`. Before creating the release branch: + +1. Rename `main.md` to the version-specific file (e.g., `docs/en/releases/1.18.md`) +2. Add the new file to `SUMMARY.md` and `releases/index.md` +3. Reset `main.md` to a clean template for the next release cycle +4. Verify that documentation for all included contributions is complete +5. Search for instances of `main (planned for:` and replace with the release version now that it is known. + So, for example `` is replaced with `` + +::: tip +Community members are encouraged to document changes as they are merged into `main`. This distributes the documentation workload and ensures changes are captured while they're fresh. +::: + +### Create the Release Branch + +Once the next release version is decided, create the new release branch from `main` in PX4-Autopilot and the companion repositories: + +```sh +# PX4-Autopilot +git checkout main && git pull +git checkout -b release/1.18 +git push origin release/1.18 +``` + +Matching release branches must also be created in: + +- [PX4/px4_msgs](https://github.com/PX4/px4_msgs) +- [Auterion/px4-ros2-interface-lib](https://github.com/Auterion/px4-ros2-interface-lib) + +After creating the companion branches, update the [ROS integration test workflow](https://github.com/PX4/PX4-Autopilot/blob/main/.github/workflows/ros_integration_tests.yml) on the release branch to clone `px4-ros2-interface-lib` from the matching release branch: + +```diff +- git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib.git ++ git clone --recursive --branch release/1.18 https://github.com/Auterion/px4-ros2-interface-lib.git +``` + +::: warning +Once the release branches are created, they only accept bug fixes and regression fixes. All new feature development continues on `main`. +::: + +### Create the Alpha Tag + +Immediately after creating the release branch, create the first alpha tag to mark the beginning of the release cycle: + +```sh +# On the new release branch +git checkout release/1.18 + +# Create the signed alpha tag +git tag -s v1.18.0-alpha1 -m "v1.18.0-alpha1" +git push origin v1.18.0-alpha1 +``` + +Subsequent alpha tags can be created as fixes are merged (e.g., `v1.18.0-alpha2`, `v1.18.0-alpha3`). + +## Release Steps + +### 1. Review and Merge PRs (Alpha Phase) + +During the alpha phase, review pull requests targeting the release branch: + +- Review PRs according to the project's [contribution guidelines](../contribute/code.md) +- Merge **bug fixes and regression fixes only** +- New features must target `main`, not the release branch +- Create additional alpha tags as fixes are merged (e.g., `v1.18.0-alpha2`) + +### 2. Alpha Testing + +The _Dronecode Test Team_ (provided by [Ascend Engineering](https://www.ascendengineer.com) — Dronecode Silver member) conducts initial flight testing of alpha builds using: + +- The [test cards](../test_and_ci/test_flights.md) documented in the PX4 guide +- A hardware matrix covering supported flight controllers and airframes + +Alpha testing focuses on identifying regressions and blockers early. The alpha phase is complete when: + +- All test cards pass across the core hardware matrix (no critical or high-severity failures) +- All identified regressions have fixes merged or have been triaged as non-blocking +- Release notes and documentation for included changes are complete + +### 3. Create Beta Tag + +Once the alpha exit criteria above are met, create the first beta tag: + +```sh +# On the release branch +git checkout release/1.18 +git pull + +# Create the signed beta tag +git tag -s v1.18.0-beta1 -m "v1.18.0-beta1" +git push origin v1.18.0-beta1 +``` + +### 4. Beta Testing + +Beta builds are published for wider community validation. Unlike alpha testing (which is conducted by the Dronecode Test Team on the core hardware matrix), beta testing focuses on: + +- **Community testing** — beta builds are made available for community members to test on their own hardware and airframe configurations +- **Extended hardware coverage** — testing on hardware and configurations beyond the core test matrix +- **Real-world flight scenarios** — longer flights, mission testing, and edge cases not covered by standard test cards + +During beta, continue to: + +- Review and merge **bug fixes and regression fixes only** +- Create additional beta tags as fixes are merged (e.g., `v1.18.0-beta2`, `v1.18.0-beta3`) + +### 5. Create Release Candidate Tag + +The beta phase is complete when: + +- No new critical or high-severity issues are reported for at least one beta tag cycle +- All beta-reported regressions have fixes merged or have been triaged as non-blocking + +Once the beta exit criteria are met, create the first release candidate: + +```sh +# On the release branch +git checkout release/1.18 +git pull + +# Create the signed RC tag +git tag -s v1.18.0-rc1 -m "v1.18.0-rc1" +git push origin v1.18.0-rc1 +``` + +::: warning +The branch is now frozen. No PRs will be merged unless a veto vote passes (see below). +::: + +::: tip +Tags must be GPG-signed. Ensure your GitHub account is [configured for GPG signing](https://docs.github.com/en/authentication/managing-commit-signature-verification). Only maintainers with registered GPG keys can create release tags. +::: + +### 6. RC Testing and Branch Freeze + +During RC testing, the release branch is frozen: + +- No PRs are merged by default +- Testing focuses on final validation before stable release +- Any issues found are documented and evaluated + +#### Veto Vote for Critical Fixes + +If a critical issue is discovered during RC testing that must be fixed before release: + +1. Raise the issue during the [Weekly Community Q&A Call](../contribute/dev_call.md) +2. Present the case for why the fix is critical +3. Maintainers vote on whether to merge the fix +4. If approved, merge the fix and create a new RC tag (e.g., `v1.18.0-rc2`) + +### 7. Release Vote + +The release vote takes place during the [Weekly Community Q&A Call](../contribute/dev_call.md): + +- Present the release status and test results +- **Vote 1:** Core maintainers vote on whether to publish the release +- **Vote 2:** Decide the name/number of the next release version +- The call happens Wednesdays at 17:00 CET on [Discord](https://discord.gg/BDYmr6FA6Q) + +### 8. Create and Push Release Tag + +After a successful vote, create the final release tag: + +```sh +# On the release branch +git checkout release/1.18 +git pull + +# Create the signed release tag +git tag -s v1.18.0 -m "v1.18.0" +git push origin v1.18.0 +``` + +### 9. Update the Stable Branch + +Reset the `stable` branch to point to the new release tag: + +```sh +git checkout stable +git reset --hard v1.18.0 +git push --force origin stable +``` + +::: warning +This is a force push that rewrites the stable branch history. Ensure you have the correct tag before executing. +::: + +### 10. GitHub Release (Automated) + +When a version tag is pushed, the [build_all_targets.yml](https://github.com/PX4/PX4-Autopilot/blob/main/.github/workflows/build_all_targets.yml) GitHub Actions workflow automatically: + +1. Builds firmware for all supported targets +2. Uploads firmware artifacts to AWS S3 (`Firmware/vX.Y.Z/` and updates `Firmware/stable/`) +3. Creates a **draft release** on GitHub with all `.px4` firmware files attached + +### 11. Publish GitHub Release + +Edit the draft release on GitHub: + +- Add a brief description of major changes +- Link to the full release notes in the documentation (e.g., `releases/1.18.md`) +- Publish the release + +### 12. Finalize Documentation + +Review and finalize the release notes that have been developed throughout the release cycle: + +- Ensure all noteworthy changes, new features, and upgrade guides are documented +- Review for completeness and accuracy +- See existing [release notes](../releases/index.md) for the expected format + +### 13. Announce the Release + +Announce the release through official channels: + +- [PX4 Discuss Forum](https://discuss.px4.io/) +- [PX4 Discord](https://discord.gg/dronecode) +- Social media (Twitter/X, LinkedIn) +- Dronecode newsletter + +### 14. Start Next Release Cycle + +Immediately after publishing, start the next release cycle: + +- Create the new release branch from `main` (see [Create the Release Branch](#create-the-release-branch)) +- Create the alpha tag for the new release +- Create the initial documentation for the next release +- Rename and prepare the project board (see [Project Board Management](#project-board-management)) + +## Point Releases + +After a stable release is published, the release branch reopens for bug fixes and regression fixes to support point releases (e.g., `v1.18.1`). + +For patch releases: + +1. Merge bug fixes and regression fixes to the release branch +2. Create beta tags for testing if needed (e.g., `v1.18.1-beta1`) +3. Create RC tags for final validation (e.g., `v1.18.1-rc1`) +4. After testing and vote, tag the point release +5. Update stable branch and publish + +## Project Board Management + +The [PX4 Release Project Board](https://github.com/orgs/PX4/projects/45) is reused across release cycles to track issues and PRs for the current release. + +### After a Release + +Once a release is published: + +1. **Rename the project board** to reflect the next release version (e.g., "v1.17 Release" → "v1.18 Release") +2. **Review remaining items**: + - Close items that are no longer relevant + - Move incomplete items that should carry over to the next release + - Remove items that were descoped or deferred indefinitely +3. **Update the board description** if needed to reflect the new release target + +## See Also + +- [Source Code Management](../contribute/code.md) - Branching model and contribution guidelines +- [Test Flights](../test_and_ci/test_flights.md) - Flight test procedures and test cards +- [Weekly Community Q&A Call](../contribute/dev_call.md) - Where release votes happen diff --git a/docs/en/ros/mavros_custom_messages.md b/docs/en/ros/mavros_custom_messages.md index 5f18636ad6..3549abea35 100644 --- a/docs/en/ros/mavros_custom_messages.md +++ b/docs/en/ros/mavros_custom_messages.md @@ -2,6 +2,7 @@ :::warning This article has been tested against: + - **Ubuntu:** 20.04 - **ROS:** Noetic - **PX4 Firmware:** v1.13 @@ -13,13 +14,14 @@ However these steps are fairly general and so it should work with other distros/ ## MAVROS Installation -Follow *Source Installation* instructions from [mavlink/mavros](https://github.com/mavlink/mavros/blob/master/mavros/index.md) to install "ROS Kinetic". +Follow _Source Installation_ instructions from [mavlink/mavros](https://github.com/mavlink/mavros/blob/master/mavros/index.md) to install "ROS Kinetic". ## MAVROS 1. We start by creating a new MAVROS plugin, in this example named **keyboard_command.cpp** (in **workspace/src/mavros/mavros_extras/src/plugins**) by using the code below: The code subscribes a 'char' message from ROS topic `/mavros/keyboard_command/keyboard_sub` and sends it as a MAVLink message. + ```c #include #include @@ -66,6 +68,7 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c ``` 1. Edit **mavros_plugins.xml** (in **workspace/src/mavros/mavros_extras**) and add the following lines: + ```xml Accepts keyboard command. @@ -73,10 +76,11 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c ``` 1. Edit **CMakeLists.txt** (in **workspace/src/mavros/mavros_extras**) and add the following line in `add_library`. + ```cmake - add_library( + add_library( ... - src/plugins/keyboard_command.cpp + src/plugins/keyboard_command.cpp ) ``` @@ -93,6 +97,7 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c ## PX4 Changes 1. Inside **common.xml** (in **PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0**), add your MAVLink message as following (same procedure as for MAVROS section above): + ```xml ... @@ -106,10 +111,11 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c Make sure that the **common.xml** files in the following directories are exactly the same: - `PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0` - `workspace/src/mavlink/message_definitions/v1.0` - are exactly the same. - ::: + are exactly the same. + ::: 1. Make your own uORB message file **key_command.msg** in (PX4-Autopilot/msg). For this example the "key_command.msg" has only the code: + ``` uint64 timestamp # time since system start (microseconds) char cmd @@ -142,6 +148,7 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c 1. Edit **mavlink_receiver.cpp** (in **PX4-Autopilot/src/modules/mavlink**). This is where PX4 receives the MAVLink message sent from ROS, and publishes it as a uORB topic. + ```cpp ... void MavlinkReceiver::handle_message(mavlink_message_t *msg) @@ -221,7 +228,7 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c int error_counter = 0; - for (int i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { int poll_ret = px4_poll(fds, 1, 1000); @@ -258,10 +265,10 @@ Follow *Source Installation* instructions from [mavlink/mavros](https://github.c ``` menuconfig MODULES_KEY_RECEIVER - bool "key_receiver" - default n - ---help--- - Enable support for key_receiver + bool "key_receiver" + default n + ---help--- + Enable support for key_receiver ``` @@ -283,7 +290,7 @@ Now you are ready to build all your work! ### Build for ROS 1. In your workspace enter: `catkin build`. -1. Beforehand, you have to set your "px4.launch" in (/workspace/src/mavros/mavros/launch). +1. Beforehand, you have to set your "px4.launch" in (/workspace/src/mavros/mavros/launch). Edit "px4.launch" as below. If you are using USB to connect your computer with Pixhawk, you have to set "fcu_url" as shown below. But, if you are using CP2102 to connect your computer with Pixhawk, you have to replace "ttyACM0" with "ttyUSB0". @@ -301,22 +308,25 @@ Now you are ready to build all your work! ### Build for PX4 1. Clean the previously built PX4-Autopilot directory. In the root of **PX4-Autopilot** directory: - ```sh - make clean - ``` -1. Build PX4-Autopilot and upload [in the normal way](../dev_setup/building_px4.md#nuttx-pixhawk-based-boards). + ```sh + make clean + ``` - For example: - - - to build for Pixhawk 4/FMUv5 execute the following command in the root of the PX4-Autopilot directory: - ```sh - make px4_fmu-v5_default upload - ``` - - to build for SITL execute the following command in the root of the PX4-Autopilot directory (using jmavsim simulation): - ```sh - make px4_sitl jmavsim - ``` +1. Build PX4-Autopilot and upload [in the normal way](../dev_setup/building_px4.md#nuttx-pixhawk-based-boards). + + For example: + - to build for Pixhawk 4/FMUv5 execute the following command in the root of the PX4-Autopilot directory: + + ```sh + make px4_fmu-v5_default upload + ``` + + - to build for SITL execute the following command in the root of the PX4-Autopilot directory (using jmavsim simulation): + + ```sh + make px4_sitl jmavsim + ``` ## Running the Code @@ -338,6 +348,7 @@ Next test if the MAVROS message is sent to PX4. 1. Enter the Pixhawk nutshell through UDP. Replace xxx.xx.xxx.xxx with your IP. + ```sh cd PX4-Autopilot/Tools ./mavlink_shell.py xxx.xx.xxx.xxx:14557 --baudrate 57600 diff --git a/docs/en/ros/mavros_installation.md b/docs/en/ros/mavros_installation.md index 0929b843df..b8c395e468 100644 --- a/docs/en/ros/mavros_installation.md +++ b/docs/en/ros/mavros_installation.md @@ -26,7 +26,7 @@ They cover the _ROS Melodic and Noetic_ releases. ::: tab ROS Noetic (Ubuntu 20.04) -If you're working with [ROS Noetic](https://wiki.ros.org/noetic) on Ubuntu 20.04: +If you're working with [ROS "Noetic"](https://wiki.ros.org/noetic) on Ubuntu 20.04: 1. Install PX4 without the simulator toolchain: 1. [Download PX4 Source Code](../dev_setup/building_px4.md): @@ -57,7 +57,7 @@ If you're working with [ROS Noetic](https://wiki.ros.org/noetic) on Ubuntu 20.04 ::: tab ROS Melodic (Ubuntu 18.04) -If you're working with ROS "Melodic on Ubuntu 18.04: +If you're working with ROS "Melodic" on Ubuntu 18.04: 1. Download the [ubuntu_sim_ros_melodic.sh](https://raw.githubusercontent.com/PX4/Devguide/master/build_scripts/ubuntu_sim_ros_melodic.sh) script in a bash shell: diff --git a/docs/en/ros2/multi_vehicle.md b/docs/en/ros2/multi_vehicle.md index e295d49932..abed4ee206 100644 --- a/docs/en/ros2/multi_vehicle.md +++ b/docs/en/ros2/multi_vehicle.md @@ -38,12 +38,12 @@ This mismatch can be fixed by manually using `PX4_UXRCE_DDS_NS` on the first ins The default client configuration in simulation is summarized as follows: -| `PX4_UXRCE_DDS_NS` | `px4_instance` | `UXRCE_DDS_KEY` | client namespace | -|-------------------|----------------|------------------|-----------------------| -| not provided | 0 | `px4_instance+1` | none | -| provided | 0 | `px4_instance+1` | `PX4_UXRCE_DDS_NS` | -| not provided | >0 | `px4_instance+1` | `px4_${px4_instance}` | -| provided | >0 | `px4_instance+1` | `PX4_UXRCE_DDS_NS` | +| `PX4_UXRCE_DDS_NS` | `px4_instance` | `UXRCE_DDS_KEY` | client namespace | +| ------------------ | -------------- | ---------------- | --------------------- | +| not provided | 0 | `px4_instance+1` | none | +| provided | 0 | `px4_instance+1` | `PX4_UXRCE_DDS_NS` | +| not provided | >0 | `px4_instance+1` | `px4_${px4_instance}` | +| provided | >0 | `px4_instance+1` | `PX4_UXRCE_DDS_NS` | ## Adjusting the `target_system` value diff --git a/docs/en/ros2/offboard_control.md b/docs/en/ros2/offboard_control.md index 56701bfe21..f16256cd4d 100644 --- a/docs/en/ros2/offboard_control.md +++ b/docs/en/ros2/offboard_control.md @@ -1,6 +1,6 @@ # ROS 2 Offboard Control Example -The following C++ example shows how to do position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. +The following C++ example shows how to do multicopter position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. The example starts sending setpoints, enters offboard mode, arms, ascends to 5 metres, and waits. While simple, it shows the main principles of how to use offboard control and how to send vehicle commands. @@ -22,7 +22,7 @@ To subscribe to data coming from nodes that publish in a different frame (for ex ## Trying it out -Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the simulator, install ROS 2, and start the XRCE-DDS Agent. +Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the multicopter simulator, install ROS 2, and start the XRCE-DDS Agent. After that we can follow a similar set of steps to those in [ROS 2 User Guide > Build ROS 2 Workspace](../ros2/user_guide.md#build-ros-2-workspace) to run the example. diff --git a/docs/en/ros2/px4_ros2_control_interface.md b/docs/en/ros2/px4_ros2_control_interface.md index e7e3151c6c..6032e6d2d5 100644 --- a/docs/en/ros2/px4_ros2_control_interface.md +++ b/docs/en/ros2/px4_ros2_control_interface.md @@ -13,7 +13,7 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta ::: -The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library that simplifies controlling PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. Developers use the library to create and dynamically register modes written using ROS 2. These modes are dynamically registered with PX4, and appear to be part of PX4 to a ground station or other external system. @@ -25,6 +25,12 @@ These classes abstract the internal setpoints used by PX4, and that can therefor PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +::: tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://auterion.github.io/px4-ros2-interface-lib/python/index.html). +You are welcome to add and contribute missing classes. +::: + ## Overview This diagram provides a conceptual overview of how the control interface modes and mode executors interact with PX4. @@ -262,9 +268,9 @@ This section steps through an example of how to create a mode executor class. class MyModeExecutor : public px4_ros2::ModeExecutorBase // [1] { public: - MyModeExecutor(rclcpp::Node & node, px4_ros2::ModeBase & owned_mode) // [2] - : ModeExecutorBase(node, px4_ros2::ModeExecutorBase::Settings{}, owned_mode), - _node(node) + MyModeExecutor(px4_ros2::ModeBase & owned_mode) // [2] + : ModeExecutorBase(px4_ros2::ModeExecutorBase::Settings{}, owned_mode), + _node(owned_mode.node()) { } enum class State // [3] @@ -340,9 +346,10 @@ The used types also define the compatibility with different vehicle types. The following sections provide a list of supported setpoint types: -- [GotoSetpointType](#go-to-setpoint-gotosetpointtype): Smooth position and (optionally) heading control -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): Smooth position and (optionally) heading control +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype): Direct control of motors and flight surface servo setpoints +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). @@ -350,15 +357,21 @@ The other setpoint types are currently experimental, and can be found in: [px4_r You can add your own setpoint types by adding a class that inherits from `px4_ros2::SetpointBase`, sets the configuration flags according to what the setpoint requires, and then publishes any topic containing a setpoint. ::: -#### Go-to Setpoint (GotoSetpointType) +#### Go-to Setpoint (MulticopterGotoSetpointType) + + + + ::: info This setpoint type is currently only supported for multicopters. ::: -Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::GotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/goto.hpp) setpoint type. +Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::MulticopterGotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) setpoint type. The setpoint type is streamed to FMU based position and heading smoothers formulated with time-optimal, maximum-jerk trajectories, with velocity and acceleration constraints. +There is also a [`px4_ros2::MulticopterGotoGlobalSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) class that allows to send setpoints in global coordinates. + The most trivial use is simply inputting a 3D position into the update method: ```cpp @@ -403,7 +416,7 @@ _goto_setpoint->update( #### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) - + ::: info This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. @@ -543,13 +556,47 @@ For example to control a quadrotor, you need to set the first 4 motors according If you want to control an actuator that does not control the vehicle's motion, but for example a payload servo, see [below](#controlling-an-independent-actuator-servo). ::: +#### Rover Setpoints + + + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +::: info +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (Overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint, **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). All combinations of "left" and "right" setpoints are valid. + +For ease of use we expose these valid combinations as new SetpointTypes. +::: + +The RoverSetpointTypes exposed through the control interface are combinations of these setpoints that lead to a valid control input: + +| SetpointType | Position | Speed | Throttle | Attitude | Rate | Steering | Control Flags | +| ----------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- | --------- | --------- | --------- | --------- | ------------------------------------------------------ | +| [RoverPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverPositionSetpointType.html#details) | ✓ | (✓) | (✓) | (✓) | (✓) | (✓) | Position, Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedAttitudeSetpointType.html) | | ✓ | (✓) | ✓ | (✓) | (✓) | Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedRateSetpointType.html) | | ✓ | (✓) | | ✓ | (✓) | Velocity, Rate, Control Allocation | +| [RoverSpeedSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedSteeringSetpointType.html) | | ✓ | (✓) | | | ✓ | Velocity, Control Allocation | +| [RoverThrottleAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleAttitudeSetpointType.html) | | | ✓ | ✓ | (✓) | (✓) | Attitude, Rate, Control Allocation | +| [RoverThrottleRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleRateSetpointType.html) | | | ✓ | | ✓ | (✓) | Rate, Control Allocation | +| [RoverThrottleSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleSteeringSetpointType.html) | | | ✓ | | | ✓ | Control Allocation | + +✓ are the setpoints we publish, and (✓) are generated internally by the PX4 rover modules according to the hierarchy above. + +An example for a rover specific drive mode using the `RoverSpeedAttitudeSetpointType` is provided [here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/rover_velocity). + ### Controlling a VTOL - + To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: -- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`GotoSetpointType`](#go-to-setpoint-gotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). +- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`MulticopterGotoSetpointType`](#go-to-setpoint-multicoptergotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). - Fixed-wing mode: Use the [`FwLateralLongitudinalSetpointType`](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype). As long as the VTOL remains in either multicopter or fixed-wing mode throughout the external mode, no additional handling is required. diff --git a/docs/en/ros2/px4_ros2_interface_lib.md b/docs/en/ros2/px4_ros2_interface_lib.md index 42ea30d08c..d695ab7f21 100644 --- a/docs/en/ros2/px4_ros2_interface_lib.md +++ b/docs/en/ros2/px4_ros2_interface_lib.md @@ -6,17 +6,14 @@ At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. ::: -The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library that simplifies controlling and interacting with PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. -The library provides two high-level interfaces for developers: +The library provides three high-level interfaces for developers: 1. The [Control Interface](./px4_ros2_control_interface.md) allows developers to create and dynamically register modes written using ROS 2. It provides classes for sending different types of setpoints, ranging from high-level navigation tasks all the way down to direct actuator controls. 2. The [Navigation Interface](./px4_ros2_navigation_interface.md) enables sending vehicle position estimates to PX4 from ROS 2 applications, such as a VIO system. - - +3. [Waypoint Missions](./px4_ros2_waypoint_missions.md) allows waypoint missions to run entirely in ROS 2. ## Installation in a ROS 2 Workspace diff --git a/docs/en/ros2/px4_ros2_msg_translation_node.md b/docs/en/ros2/px4_ros2_msg_translation_node.md index f9dab8a42a..5587c4fdbb 100644 --- a/docs/en/ros2/px4_ros2_msg_translation_node.md +++ b/docs/en/ros2/px4_ros2_msg_translation_node.md @@ -305,7 +305,6 @@ The example describes the process of updating the `VehicleAttitude` message defi Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. For example, update references in those files:
- - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` - Replace `#include ` → `#include ` @@ -386,7 +385,6 @@ The example describes the process of updating the `VehicleAttitude` message defi ``` Version translation templates are provided here: - - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) @@ -440,7 +438,7 @@ For translations with multiple input topics, the translation continues once all - Services messages only support a linear history, i.e. no message splitting or merging. - Having both publishers and subscribers for two different versions of the same topic is currently not handled by the translation node and would trigger infinite circular publications. This refers to the following problematic configuration: - + ``` app 1: pub topic_v1, sub topic_v1 app 2: pub topic_v2, sub topic_v2 diff --git a/docs/en/ros2/px4_ros2_waypoint_missions.md b/docs/en/ros2/px4_ros2_waypoint_missions.md new file mode 100644 index 0000000000..4484e1c136 --- /dev/null +++ b/docs/en/ros2/px4_ros2_waypoint_missions.md @@ -0,0 +1,190 @@ +# PX4 ROS 2 Waypoint Missions + + + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) provides a high-level interface for executing ROS-based waypoint missions in ROS 2. +The main use-case is for creating missions where a custom behavior is required, such as a pickup action within a mission. + +::: warning +ROS 2 missions are not compatible with MAVLink mission definitions, plan files, or ground stations. +They completely bypass the existing PX4 mission mode and waypoint logic, and cannot be planned or displayed within a ground station. +::: + +ROS 2 waypoint missions are effectively special PX4 ROS 2 custom modes that are run based on the content of a [JSON mission definition](#mission-definition). +Mission definitions can contain actions that reference existing PX4 modes, such as Takeoff mode or RTL, and can also be extended with arbitrary custom actions written in ROS. +A [mode executor](px4_ros2_control_interface.md#mode-executor) is used to schedule the modes. + +Mission definitions can be hard coded in the custom mission mode (either in code or statically loaded from a JSON string), or directly generated within the application. +They can also be dynamically loaded based on modification of a particular JSON file — this allows for building a more generic mission framework with a fixed set of custom actions. +The file can then be written by any other application, for example a HTTP or MAVFTP server. + +The current implementation only supports multicopters but is designed to be extendable to any other vehicle type. + +## Comparison to PX4/MAVLink Missions + +There are some benefits and drawbacks to using ROS-based missions, which are provided in the following paragraphs. + +### Benefits + +- Allows to extend mission capabilities by registering custom actions. +- More control over how the mission is executed. + A custom trajectory executor can be implemented, which can use any of the existing PX4 setpoint types to track the trajectory. +- Reduced complexity on the flight controller side by running non-safety-critical and non-real-time code on a more high-level companion computer. +- It can be extended to support other trajectory types, like Bezier or Dubin curves. + +### Drawbacks + +- QGroundControl currently does not display the mission or progress during execution, and cannot upload or download a mission. + Therefore you will need another mechanism to provide a mission, such as from a web server, a custom GCS, or by generating it directly inside the application. +- The current implementation only supports multicopters (it uses the [GotoSetpointType](../ros2/px4_ros2_control_interface.md#go-to-setpoint-multicoptergotosetpointtype), which only works for multicopters, and VTOL in MC mode). + It is designed to be extendable to any other vehicle type. + +## Overview + +This diagram provides a conceptual overview of the main classes and their interactions: + +![Waypoint missions overview diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg) + + + +Missions can be defined in [JSON](#mission-definition), either as a file, or directly inside the application. +There is a file change monitor (`MissionFileMonitor`), that can be used to automatically load a mission from a specific file whenever it is created by another application (e.g. upload via MAVFTP or a cloud service). + +The **`MissionExecutor`** class contains the state machine to progress the mission index, and is at the core of the implementation: + +- Internally, it builds on top of the [Modes and Mode Executors](px4_ros2_control_interface.md#overview) and registers itself through a custom mode and executor with PX4. +- It handles switching in and out of missions: it gets activated when the user switches to the custom mode that represents the mission and the vehicle is armed. + The mode name can be customized (`My Mission` in the example below). + The mission can be paused, which makes the vehicle switch into _Hold mode_. + To resume the mission, the custom mode has to be selected again. +- When an action switches into another mode (for example Takeoff), QGroundControl will display this mode until it is completed. + The mission executor will then automatically continue. +- Custom actions can be registered. +- The mission can be set. + It then checks that all the actions which the mission defines are available and can be run. +- The state can be stored persistently by providing a file name, allowing for battery swapping. + +The **`ActionInterface`** is an interface class for custom actions. +They are identified by a name, and any number of these can be registered with the `MissionExecutor`. +A custom action is then run whenever a mission item with matching name is executed, and any extra arguments from the JSON definition are passed as arguments (for example an altitude for a takeoff action). +Actions can call other actions, run any mode (PX4 or external by its ID), run a trajectory, or run any other external action before deciding when to continue the mission. + +There is a set of default actions, for example for RTL, Land, etc. +These simply trigger the corresponding PX4 mode. +They can be disabled or replaced with custom implementations. +There are also some special actions (which can be replaced as well): + +- `OnFailure`: this is called in case of a failure, e.g. a mode switch failed, a non-existing action is called (by another action) or by an explicit call to `MissionExecutor::abort()`. + The default is to run RTL, with fallback to Land. +- `OnResume`: this is called when resuming a mission (either from the ground or in-air). + It handles a number of cases: + - when called with an argument `action="storeState"`: this can be used to store the current position when the mission is deactivated, so it can be resumed from the same position. + Currently it does not store anything. + - otherwise, when called without a valid mission index or 0, it directly continues. + - otherwise, when called while in-air, it also directly continues. + - otherwise, if landed and if the current mission item is an action that supports resuming from landed, it continues to let the action handle the resuming. + - otherwise, if landed, it finds the takeoff action from the mission, runs it, and then flies to the previous waypoint from the current index to continue the mission. +- `ChangeSettings`: this can be used to change the mission settings, such as the velocity. + The settings are applied to all following items in the mission. + +The **`TrajectoryExecutorInterface`** is an interface class to execute segments of a trajectory. +It can use any setpoint that PX4 and the current vehicle supports for tracking the trajectory. +This class is vehicle-type specific. +The current default implementation (`multicopter::WaypointTrajectoryExecutor`) uses a Goto setpoint (and thus is limited to multicopters). +The default can be replaced with a custom implementation. + +## Usage + +The following provides a small example. +It defines a custom action and a mission that uses it. + +```c++ +class CustomAction : public px4_ros2::ActionInterface { +public: + CustomAction(px4_ros2::ModeBase & mode) : _node(mode.node()) { } + + std::string name() const override {return "customAction";} + + void run( + const std::shared_ptr & handler, + const px4_ros2::ActionArguments & arguments, + const std::function & on_completed) override + { + RCLCPP_INFO(_node.get_logger(), "Running custom action"); + // Do something... + + on_completed(); + } +private: + rclcpp::Node & _node; +}; + +class MyMission { +public: + MyMission(const std::shared_ptr & node) : _node(node) + { + const auto mission = px4_ros2::Mission(nlohmann::json::parse(R"( + { + "version": 1, + "mission": { + "items": [ + { + "type": "takeoff" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.3977419, + "y": 8.5455939, + "z": 500, + "frame": "global" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.39791657, + "y": 8.54595214, + "z": 500, + "frame": "global" + }, + { + "type": "customAction" + }, + { + "type": "rtl" + } + ] + } + } +)")); + _mission_executor = std::make_unique("My Mission", + px4_ros2::MissionExecutor::Configuration().addCustomAction(), *node); + + if (!_mission_executor->doRegister()) { + throw std::runtime_error("Failed to register mission executor"); + } + _mission_executor->setMission(mission); + + _mission_executor->onProgressUpdate([&](int current_index) { + RCLCPP_INFO(_node->get_logger(), "Current mission index: %i", current_index); + }); + _mission_executor->onCompleted([&] { + RCLCPP_INFO(_node->get_logger(), "Mission completed callback"); + }); + } + +private: + std::shared_ptr _node; + std::unique_ptr _mission_executor; +}; +``` + +A full example with a few custom actions can be found under [github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include). + +## Mission Definition + +The mission JSON file can contain mission defaults and a list of mission items, including user-defined types with custom arguments. +Waypoint coordinates currently need to be defined in global frame, and other frame types might be added in future. + +The schema can be found under [github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml). +It provides more details and can be used to validate a JSON file. diff --git a/docs/en/ros2/user_guide.md b/docs/en/ros2/user_guide.md index 4fb40695f5..332c9b00dd 100644 --- a/docs/en/ros2/user_guide.md +++ b/docs/en/ros2/user_guide.md @@ -152,7 +152,7 @@ To setup and start the agent: 1. Enter the following commands to fetch and build the agent from source: ```sh - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build diff --git a/docs/en/sensor/accelerometer.md b/docs/en/sensor/accelerometer.md index da249b1934..6de3d5bd21 100644 --- a/docs/en/sensor/accelerometer.md +++ b/docs/en/sensor/accelerometer.md @@ -5,7 +5,7 @@ PX4 uses accelerometer data for velocity estimation. You should not need to attach an accelometer as a stand-alone external device: - Most flight controllers, such as those in the [Pixhawk Series](../flight_controller/pixhawk_series.md), include an accelerometer as part of the flight controller's [Inertial Motion Unit (IMU)](https://en.wikipedia.org/wiki/Inertial_measurement_unit). -- Gyroscopes are present as part of an [external INS, ARHS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). +- Gyroscopes are present as part of an [external INS, AHRS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). The accelerometer must be calibrated before first use of the vehicle: diff --git a/docs/en/sensor/barometer.md b/docs/en/sensor/barometer.md index 46f77a8d8b..598bdc3d11 100644 --- a/docs/en/sensor/barometer.md +++ b/docs/en/sensor/barometer.md @@ -30,17 +30,51 @@ If needed, you can: - Change the selection order of barometers using the [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) parameters for each barometer. - Disable a barometer by setting its [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) value to `0`. -## Calibration +## Baro Auto-Calibration (Developers) -Barometers don't require calibration. +::: tip +This section documents the automated calibration mechanisms that ensure accurate altitude measurements throughout flight operations. +It is intended primarily for a developer audience who want to understand the underlying mechanisms. +::: - +The system implements two complementary calibration approaches that work together to maintain altitude measurement precision. +Both calibrations are initiated at the beginning after a system boot. +Relative calibration is performed first, followed by GNSS-barometric calibration. -## Developer Information +### Relative Calibration + +Relative baro calibration is **always enabled** and operates automatically during system initialization. +This calibration establishes offset corrections for all secondary baro sensors relative to the primary (selected) sensor. + +This calibration: + +- Eliminates altitude jumps when switching between baro sensors during flight. +- Ensures consistent altitude readings across all available baro sensors. +- Maintains seamless sensor redundancy and failover capability. + +### GNSS-Baro Calibration + +::: info +GNSS-baro calibration requires an operational GNSS receiver with vertical accuracy (EPV) ≤ 8 meters. +Relative calibration must already have completed. +::: + +GNSS-baro calibration adjusts baro sensor offsets to align with absolute altitude measurements from the GNSS receiver. +This calibration is controlled by the [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) parameter (enabled by default). + +The algorithm monitors GNSS quality, collects altitude differences over a 2-second filtered window, and verifies stability within 4m tolerance. +Once stable, it uses binary search to calculate pressure offsets that align baro altitude with GNSS altitude (0.1m precision), then applies the offset to all sensors and saves the parameters. + +Notes: + +- **EKF Independence**: GNSS-baro calibration operates independently of EKF2 altitude fusion settings. +- **Execution Timing**: Calibration runs even when [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) altitude fusion is disabled. +- **One-Time Process**: Each calibration session completes once per system startup. +- **Persistence**: Calibration offsets are saved to parameters and persist across reboots. +- **Faulty GNSS Vulnerability**: If GNSS data is faulty during boot, the calibration will use incorrect altitude reference. + See [Faulty GNSS Data During Boot](../advanced_config/tuning_the_ecl_ekf.md#faulty-gnss-data-during-boot) for mitigation strategies. + +## See Also - [Baro driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer) - [Modules Reference: Baro (Driver)](../modules/modules_driver_baro.md) documentation. diff --git a/docs/en/sensor/grf_lidar.md b/docs/en/sensor/grf_lidar.md new file mode 100644 index 0000000000..836596e026 --- /dev/null +++ b/docs/en/sensor/grf_lidar.md @@ -0,0 +1,69 @@ +# Lightware GRF250/GRF500 Gimbal Lidar + +LightWare [GRF250](https://lightwarelidar.com/shop/grf-250/) and [GRF500](https://lightwarelidar.com/shop/grf-500/) are small and light Lidar modules with a range of 250m and 500m, respectively. + +![LightWare GRF250 Gimbal Lidar](../../assets/hardware/sensors/lidar_lightware/grf_500.png) + +::: info +The Lidar driver is not included in the default build of PX4. +You will need to [create and use a custom build](#add-the-driver-to-the-px4-build). +::: + +## Where to Buy + +Order these modules from: + +- [GRF250](https://lightwarelidar.com/shop/grf-250/) +- [GRF500](https://lightwarelidar.com/shop/grf-500/) + +## Hardware Setup + +The rangefinder can be connected to any unused serial port, such as `TELEM2`. +[Parameter Configuration](#parameter-configuration) explains how to configure the port to use and the other properties of the rangefinder. + +## PX4 Setup + +### Add the Driver to the PX4 Build + +The [lightware_grf_serial](../modules/modules_driver_distance_sensor.md#lightware-grf-serial) driver for this Lidar is not included in PX4 firmware by default. +In order to use these modules you will first need to update the firmware configuration to add the driver, and then build the firmware. + +1. Update the firmware configuration. You can use either of the following options: + - Menuconfig: + 1. Install and open [menuconfig](../hardware/porting_guide_config.md#px4-menuconfig-setup) + 2. In [menuconfig](../hardware/porting_guide_config.md#px4-menuconfig-setup), navigate to **Drivers > Distance sensors** + 3. Select/Enable `lightware_grf_serial` + 4. Save the configuration + + - Manually update `default.px4` to include the configuration key: + 1. Open the `default.px4board` config file that corresponds to the board you want to build for. + For example, to add the driver to `fmu-v6x` boards you would update [/boards/px4/fmu-v6x/default.px4board ](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6x/default.px4board) + 2. Add the following line and save the file: + + ```txt + CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_GRF_SERIAL=y + ``` + +2. [Build PX4](../dev_setup/building_px4.md) for your flight controller target and upload the new firmware. + +### Parameter Configuration + +You will need to configure PX4 to indicate the serial port to which the sensor is connected (as per [Serial Port Configuration](../peripherals/serial_configuration.md)) and also the orientation and other properties of the sensor. + +The [parameters to change](../advanced_config/parameters.md) are listed in the table. + +| Parameter | Description | +| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | +| [SENS_EN_GRF_CFG](../advanced_config/parameter_reference.md#SENS_EN_GRF_CFG) | Set to the serial port the sensor is connected to. | +| [GRF_UPDATE_CFG](../advanced_config/parameter_reference.md#GRF_UPDATE_CFG) | Set the update rate. | +| [GRF_SENS_MODEL](../advanced_config/parameter_reference.md#GRF_SENS_MODEL) | Set the update rate. | + +## Testing + +You can confirm that the sensor is correctly configured by connecting QGroundControl, and observing that [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) is present in the [MAVLink Inspector](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_inspector.html). + +Moving the sensor around at various distances from a surface will have the `current_distance` value change. + +## Troubleshooting + +If you are having problems with connecting to the sensor you may need to unassign a the default serial port. [Unassign Default Serial Port](../peripherals/serial_configuration.md) diff --git a/docs/en/sensor/inertial_navigation_systems.md b/docs/en/sensor/inertial_navigation_systems.md index 7d03ce3299..bdf7f39b6d 100644 --- a/docs/en/sensor/inertial_navigation_systems.md +++ b/docs/en/sensor/inertial_navigation_systems.md @@ -9,6 +9,8 @@ However PX4 can also use some INS devices as either sources of raw data, or as a INS systems that can be used as a replacement for EKF2 in PX4: - [InertialLabs](../sensor/inertiallabs.md) +- [MicroStrain](../sensor/microstrain.md): Includes VRU, AHRS, INS, and GNSS/INS devices. +- [SBG Systems](../sensor/sbgecom.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. - [VectorNav](../sensor/vectornav.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. ## PX4 Firmware diff --git a/docs/en/sensor/inertiallabs.md b/docs/en/sensor/inertiallabs.md index c86ab79e64..2d677e0d53 100644 --- a/docs/en/sensor/inertiallabs.md +++ b/docs/en/sensor/inertiallabs.md @@ -5,7 +5,6 @@ A universal protocol is used for [all Inertial Labs sensors](https://inertiallab ![INS-U](../../assets/hardware/sensors/inertial/ilabs-ins-u.png) - Benefits to PX4 users: - Higher accuracy heading, pitch, and roll estimates diff --git a/docs/en/sensor/microstrain.md b/docs/en/sensor/microstrain.md new file mode 100644 index 0000000000..9a6964180d --- /dev/null +++ b/docs/en/sensor/microstrain.md @@ -0,0 +1,188 @@ +# MicroStrain (INS, IMU, VRU, AHRS) + +MicroStrain by HBK provides high-performance inertial sensors engineered for reliability and precision in challenging environments. +Widely used across industries like aerospace, robotics, industrial automation, and research, MicroStrain sensors are optimized for real-time, accurate motion tracking and orientation data. + +![CV7](../../assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png) + +The driver currently supports the following hardware: + +- [`MicroStrain CV7-AR`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/vertical-reference-units--vru-/3dm-cv7-ar): Inertial Measurement Unit (IMU) and Vertical Reference Unit (VRU) +- [`MicroStrain CV7-AHRS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/attitude-and-heading-reference-systems--ahrs-/3dm-cv7-ahrs): Inertial Measurement Unit (IMU) and Attitude Heading Reference System (AHRS) +- [`MicroStrain CV7-INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS). +- [`MicroStrain CV7-GNSS/INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-gnss-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS) combined with dual multiband (GNSS) receivers. + +PX4 can use these sensors to provide raw IMU data for EKF2 or to replace EKF2 as an external INS. +For more information, including user manuals and datasheets, please refer to the sensors product page. + +## Where to Buy + +MicroStrain sensors can be purchased through HBK's official [MicroStrain product page](https://www.hbkworld.com/en/products/transducers/inertial-sensors) or through authorized distributors globally. +For large orders, custom requirements, or technical inquiries, reach out directly to [sales](https://www.hbkworld.com/en/contact-us/contact-sales-microstrain) + +## Hardware Setup + +### Wiring + +Connect the main UART port of the MicroStrain sensor to any unused serial port on the flight controller. +This port needs to be specified while starting the device. + +### Mounting + +The MicroStrain sensor can be mounted in any orientation. +The default coordinate system uses X for the front, Y for the right, and Z for down, with directions marked on the device. + +## Firmware Configuration + +### PX4 Configuration + +To use the MicroStrain driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_MICROSTRAIN` or `CONFIG_COMMON_INS`. +2. Configure the driver mode by setting [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) + - To use the MicroStrain sensor to provide raw IMU data to EKF2 + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 0 + 2. Update the [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) parameter to account for the added MicroStrain sensor. + 3. Enable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 1 + 4. To prioritize MicroStrain sensor output, adjust the priority level of individual sensors from 0-100 using the following parameters: + - [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO) + - [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO) + - [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO) + - [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) + + where `n` corresponds to the index of the corresponding sensor. + + ::: tip + Sensors can be identified by their device id, which can be found by checking the parameters: + - [CAL_ACCn_ID](../advanced_config/parameter_reference.md#CAL_ACC0_ID) + - [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) + - [CAL_MAGn_ID](../advanced_config/parameter_reference.md#CAL_MAG0_ID) + - [CAL_BAROn_ID](../advanced_config/parameter_reference.md#CAL_BARO0_ID) + + ::: + + - To use the MicroStrain sensor as an external INS + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 1 + 2. Disable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 0 + +3. Reboot and start the driver + - `microstrain start -d ` + - To start the driver automatically when the flight controller powers on, set [SENS_MS_CFG](../advanced_config/parameter_reference.md#SENS_MS_CFG) to the sensor’s connected port. + +## MicroStrain Configuration + +1. Rates: + - By default, accel and gyro data are published at 500 Hz, magnetometer at 50 Hz, and barometric pressure at 50 Hz. + This can be changed by adjusting the following parameters: + - [MS_IMU_RATE_HZ](../advanced_config/parameter_reference.md#MS_IMU_RATE_HZ) + - [MS_MAG_RATE_HZ](../advanced_config/parameter_reference.md#MS_MAG_RATE_HZ) + - [MS_BARO_RATE_HZ](../advanced_config/parameter_reference.md#MS_BARO_RATE_HZ) + + - Global position, local position, attitude and odometry will be published at 250 Hz by default. + This can be configured via: + - [MS_FILT_RATE_HZ](../advanced_config/parameter_reference.md#MS_FILT_RATE_HZ) + + - For the CV7-GNSS/INS, the GNSS receiver 1 and 2 will publish data at 5Hz by default. + This can be changed using: + - [MS_GNSS_RATE_HZ](../advanced_config/parameter_reference.md#MS_GNSS_RATE_HZ) + + - The driver will automatically configure data outputs based on the specific sensor model and available data streams. + - The driver is scheduled to run at twice the fastest configured data rate. + +2. Aiding measurements: + - If supported, GNSS position and velocity aiding are always enabled. + - Internal/external magnetometer and heading aiding, as well as optical flow aiding, are disabled by default. They can be enabled using the following parameters: + - [MS_INT_MAG_EN](../advanced_config/parameter_reference.md#MS_INT_MAG_EN) + - [MS_INT_HEAD_EN](../advanced_config/parameter_reference.md#MS_INT_HEAD_EN) + - [MS_EXT_HEAD_EN](../advanced_config/parameter_reference.md#MS_EXT_HEAD_EN) + - [MS_EXT_MAG_EN](../advanced_config/parameter_reference.md#MS_EXT_MAG_EN) + - [MS_OPT_FLOW_EN](../advanced_config/parameter_reference.md#MS_OPT_FLOW_EN) + + - The aiding frames for external sources can be configured using the following parameters: + - [MS_EHEAD_YAW](../advanced_config/parameter_reference.md#MS_EHEAD_YAW) + - [MS_EMAG_ROLL](../advanced_config/parameter_reference.md#MS_EMAG_ROLL) + - [MS_EMAG_PTCH](../advanced_config/parameter_reference.md#MS_EMAG_PTCH) + - [MS_EMAG_YAW](../advanced_config/parameter_reference.md#MS_EMAG_YAW) + - [MS_OFLW_OFF_X](../advanced_config/parameter_reference.md#MS_OFLW_OFF_X) + - [MS_OFLW_OFF_Y](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Y) + - [MS_OFLW_OFF_Z](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Z) + - [SENS_FLOW_ROT](../advanced_config/parameter_reference.md#SENS_FLOW_ROT) + + - The uncertainty for optical flow and external magnetometer aiding must be specified using the following parameters: + - [MS_EMAG_UNCERT](../advanced_config/parameter_reference.md#MS_EMAG_UNCERT) + - [MS_OFLW_UNCERT](../advanced_config/parameter_reference.md#MS_OFLW_UNCERT) + + ::: tip + 1. When optical flow aiding is enabled, the sensor uses the `vehicle_optical_flow_vel` output from the flight controller as a body-frame velocity aiding measurement. + 2. If the MicroStrain sensor does not support these aiding sources but they are enabled, sensor initialization will fail. + + ::: + +3. Initial heading alignment: + - Initial heading alignment is set to kinematic by default. This can be changed by adjusting + - [MS_ALIGNMENT](../advanced_config/parameter_reference.md#MS_ALIGNMENT) + +4. GNSS Aiding Source Control (GNSS/INS only) + - The Source of the GNSS aiding data can be configured using: + - [MS_GNSS_AID_SRC](../advanced_config/parameter_reference.md#MS_GNSS_AID_SRC) + +5. Sensor to vehicle transform: + - If the sensor is mounted in an orientation different from the vehicle frame. A sensor to vehicle transform can be enabled using + - [MS_SVT_EN](../advanced_config/parameter_reference.md#MS_SVT_EN) + + - The transform is defined using the following parameters + - [MS_SENSOR_ROLL](../advanced_config/parameter_reference.md#MS_SENSOR_ROLL) + - [MS_SENSOR_PTCH](../advanced_config/parameter_reference.md#MS_SENSOR_PTCH) + - [MS_SENSOR_YAW](../advanced_config/parameter_reference.md#MS_SENSOR_YAW) + +6. IMU ranges: + - The accelerometer and gyroscope ranges on the device are configurable using: + - [MS_ACCEL_RANGE](../advanced_config/parameter_reference.md#MS_ACCEL_RANGE) + - [MS_GYRO_RANGE](../advanced_config/parameter_reference.md#MS_GYRO_RANGE) + + ::: tip + Available range settings depend on the specific [sensor](https://www.hbkworld.com/en/products/transducers/inertial-sensors) and can be found in the corresponding user manual. + By default, the ranges are not changed. + + ::: + +7. GNSS Lever arm offsets: + - The lever arm offset for the external GNSS receiver can be configured using: + - [MS_GNSS_OFF1_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_X) + - [MS_GNSS_OFF1_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Y) + - [MS_GNSS_OFF1_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Z) + + - For dual-antenna configurations, the second GNSS receiver’s offset is configured using: + - [MS_GNSS_OFF2_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_X) + - [MS_GNSS_OFF2_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Y) + - [MS_GNSS_OFF2_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Z) + +## Published Data + +The MicroStrain driver continuously publishes sensor data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) +- [sensor_baro](../msg_docs/SensorBaro.md) + +For GNSS/INS devices, GPS data is also published to: + +- [sensor_gps](../msg_docs/SensorGps.md) + +If used as an external INS replacing EKF2, it publishes: + +- [vehicle_global_position](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) +- [vehicle_odometry](../msg_docs/VehicleOdometry.md) + +otherwise the same data is published to the following topics + +- `external_ins_global_position` +- `external_ins_attitude` +- `external_ins_local_position` + +::: tip +Published topics can be viewed using the `listener` command. +::: diff --git a/docs/en/sensor/optical_flow.md b/docs/en/sensor/optical_flow.md index f4fa4fcf0c..f76a40b4bb 100644 --- a/docs/en/sensor/optical_flow.md +++ b/docs/en/sensor/optical_flow.md @@ -55,7 +55,7 @@ Reducing the optical flow scale factor can improve the situation. It has a PAW3902 optical flow sensor, Broadcom AFBR-S50LV85D 30 meter distance sensor, and Invensense ICM-42688-P 6-Axis IMU. [ARK Flow MR](../dronecan/ark_flow_mr.md) is a [DroneCAN](../dronecan/index.md) optical flow sensor, [distance sensor](../sensor/rangefinders.md), and IMU, for mid-range applications. -It has a PixArt PAA3905 optical flow sensor, Broadcom AFBR-S50LX85D 50 meter distance sensor, and Invensense IIM-42653 6-Axis IMU. +It has a PixArt PAA3905 optical flow sensor, Broadcom AFBR-S50LX85D 50 meter distance sensor, and Invensense IIM-42653 6-Axis IMU. ### Holybro H-Flow diff --git a/docs/en/sensor/rangefinders.md b/docs/en/sensor/rangefinders.md index 69deebdc35..425b129241 100644 --- a/docs/en/sensor/rangefinders.md +++ b/docs/en/sensor/rangefinders.md @@ -15,11 +15,69 @@ This is a subset of the rangefinders that can be used with PX4. There may also be other DroneCAN rangefinders than those listed here. ::: -### ARK Flow & AKR Flow MR +| Rangefinder | Technology | Range (min – max) | Connections | NDAA | Notes | +| ------------------------------------------- | --------------- | ------------------------ | ---------------------- | ---- | ----------------------------------- | +| [Ainstein US-D1 Standard Radar Altimeter] | Microwave radar | ~50 m | UART | ✔️ | | +| [ARK DIST SR] | ToF (850 nm IR) | 8 cm to ~30 m | DroneCAN, UART | ✔️ | | +| [ARK DIST MR] | ToF (IR) | 8 cm to ~50 m | DroneCAN, UART | ✔️ | | +| [Benewake TFmini] | ToF (IR laser) | ~12 m | UART | ~ | | +| [Holybro ST VL53L1X Lidar] | ToF (IR) | up to ~4 m | I2C | ~ | | +| [LeddarOne] | ToF (IR) | 1 cm – 40 m | UART | ~ | | +| [Lidar-Lite] | ToF (IR laser) | 5 cm – 40 m | I2C, PWM | ~ | | +| [LightWare SF11/C] | ToF (IR laser) | up to ~120 m | UART, I2C | ~ | | +| [LightWare LW20/C] | ToF (IR laser) | up to ~100 m | I2C | ~ | Waterproof (IP67) + servo | +| [LightWare SF45/B] | ToF (IR laser) | ~50 m | UART | ~ | Rotary lidar (collision prevention) | +| [MaxBotix I2CXL-MaxSonar-EZ] | Ultrasonic | | I2C | ~ | | +| [RaccoonLab Cyphal & DroneCAN µRANGEFINDER] | ToF (IR) | ~0.1 m – ~8 m | DroneCAN, Cyphal | ~ | | +| [TeraRanger Evo 60 m] | ToF (IR) | 0.5 m – 60 m | I2C | ~ | | +| [TeraRanger Evo 600Hz] | ToF (IR) | 0.75 m – 8 m | I2C | ~ | High update rate (600 Hz) | +| [LightWare SF02] _(disc.)_ | ToF (IR laser) | ~50 m | UART | ~ | Discontinued | +| [LightWare SF10/A] _(disc.)_ | ToF (IR laser) | ~25 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/B] _(disc.)_ | ToF (IR laser) | ~50 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/C] _(disc.)_ | ToF (IR laser) | ~100 m | UART, I2C | ~ | Discontinued | +| [Lanbao PSK-CM8JL65-CC5] _(disc.)_ | ToF (IR) | 0.17 m – 8 m | UART | ✖️ | Discontinued | +| [TeraRanger One] _(disc.)_ | ToF (IR) | ~0.2 m – ~14 m (typical) | I2C (adapter required) | ~ | Discontinued | -[ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md) are open-source Time-of-Flight (ToF) and optical flow sensor modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. -It can be connected to the flight controller via its CAN1 port, allowing additional sensors to connect through its CAN2 port. -It supports [DroneCAN](../dronecan/index.md), runs [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and is packed into a tiny form factor. +[Ainstein US-D1 Standard Radar Altimeter]: ../sensor/ulanding_radar.md +[ARK DIST SR]: ../dronecan/ark_dist.md +[ARK DIST MR]: ../dronecan/ark_dist_mr.md +[Benewake TFmini]: ../sensor/tfmini.md +[Holybro ST VL53L1X Lidar]: #holybro-st-vl53l1x-lidar +[Lanbao PSK-CM8JL65-CC5]: ../sensor/cm8jl65_ir_distance_sensor.md +[LeddarOne]: ../sensor/leddar_one.md +[Lidar-Lite]: ../sensor/lidar_lite.md +[LightWare Lidar]: ../sensor/sfxx_lidar.md +[LightWare SF11/C]: ../sensor/sfxx_lidar.md +[LightWare LW20/C]: ../sensor/sfxx_lidar.md +[LightWare SF45/B]: ../sensor/sfxx_lidar.md +[LightWare SF02]: ../sensor/sfxx_lidar.md +[LightWare SF10/A]: ../sensor/sfxx_lidar.md +[LightWare SF10/B]: ../sensor/sfxx_lidar.md +[LightWare SF10/C]: ../sensor/sfxx_lidar.md +[MaxBotix I2CXL-MaxSonar-EZ]: #maxbotix-i2cxl-maxsonar-ez +[TeraRanger Evo 60 m]: ../sensor/teraranger.md +[TeraRanger Evo 600Hz]: ../sensor/teraranger.md +[TeraRanger One]: ../sensor/teraranger.md + +These adaptors allows you to connect a non-CAN rangefinder via the CAN interface. +Note that the range depends on the connected rangefinder + +| Adaptor | Connections | NDAA | +| ------------------------------------------------------- | ---------------- | ---- | +| **Avionics Anonymous UAVCAN Laser Altimeter Interface** | DroneCAN | ~ | +| [RaccoonLab Cyphal & DroneCAN Rangefinder Adapter] | DroneCAN, Cyphal | ~ | + +[RaccoonLab Cyphal & DroneCAN µRANGEFINDER]: #raccoonlab-cyphal-and-dronecan-μrangefinder +[RaccoonLab Cyphal & DroneCAN Rangefinder Adapter]: #raccoonlab-cyphal-and-dronecan-rangefinder-adapter + +Note that some [Optical Flow](../sensor/optical_flow.md) sensors also include a rangefinder, such as [ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md). + +### ARK DIST SR & ARK DIST MR + +[ARK DIST SR](../dronecan/ark_dist.md) and [ARK DIST MR](../dronecan/ark_dist_mr.md) are open-source Time-of-Flight (ToF) rangefinder modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. + +The sensors support [DroneCAN](../dronecan/index.md), run [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and are packed into a tiny form factor. +They can be connected to a flight controller via its `CAN1` port, allowing additional sensors to connected through the `CAN2` port. ### Holybro ST VL53L1X Lidar diff --git a/docs/en/sensor/sbgecom.md b/docs/en/sensor/sbgecom.md new file mode 100644 index 0000000000..2115f1f4c1 --- /dev/null +++ b/docs/en/sensor/sbgecom.md @@ -0,0 +1,146 @@ +# SBG Systems INS/AHRS (Pulse, Ellipse, etc.) + +[SBG-Systems](https://www.sbg-systems.com/) designs, manufactures, and support an extensive range of state-of-the-art inertial sensors such as Inertial Measurement Units (IMU), Attitude and Heading Reference Systems (AHRS), Inertial Navigation Systems with embedded GNSS (INS/GNSS), and so on. + +PX4 supports [all SBG Systems products](https://www.sbg-systems.com/products/) and can use these as an [external INS](../sensor/inertial_navigation_systems.md) (bypassing/replacing the EKF2 estimator), or as a source of raw sensor data provided to the navigation estimator. + +![Ellipse](../../assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png) + +## Overview + +SBG Systems products provide a range of benefits to PX4 users and can be integrated for: + +- Higher accuracy heading, pitch, and roll estimates +- More robust and reliable GNSS positioning +- Improved positioning and attitude performance in GNSS-contested environments +- Performance under challenging dynamic conditions (e.g. catapult launches, VTOL operations, high-g or high angular rate operations) + +The sbgECom PX4 driver is streamlined to provide a simple plug-and-play architecture, removing engineering obstacles and allowing the acceleration of the design, development, and launch of platforms to keep pace with the rapid rate of innovation. + +The driver supports [all SBG Systems products](https://www.sbg-systems.com/products/). +In particular the following systems are recommended: + +- **Pulse:** Recommended for fixed-wing systems without hovering, where static heading is not necessary. +- **Ellipse:** Recommended for multicopter systems where hovering and low dynamics requires the use of static heading. + +## Where to Buy + +SBG Systems solutions are available directly from [MySBG](https://my.sbg-systems.com) (FR) or through their Global Sales Representatives. For more information on their solutions or for international orders, please contact contact@sbg-systems.com. + +## Hardware Setup + +### Wiring + +Connect any unused flight controller serial interface, such as a spare `GPS` or `TELEM` port, to the SBG Systems product MAIN port (required by PX4). + +### Mounting + +The SBG Systems product sensor can be mounted in any orientation, in any position on the vehicle, without regard to center of gravity. +All SBG Systems product sensors default to a coordinate system of x-forward, y-right, and z-down, making the default mounting as connector-back, base down. +This can be changed to any rigid rotation using the sbgECom Reference Frame Rotation register. + +If using a GNSS-enabled product, the GNSS antenna must be mounted rigidly with respect to the inertial sensor and with an unobstructed sky view. If using a dual-GNSS-enabled product (Ellipse-D), the secondary antenna must be mounted rigidly with respect to the primary antenna and the inertial sensor with an unobstructed sky view. + +For more mounting and configuration requirements and recommendations, see the relevant [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +## Firmware Configuration + +### PX4 Configuration + +To use the sbgECom driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_SBGECOM` or `CONFIG_COMMON_INS`. +2. [Set the parameter](../advanced_config/parameters.md) [SENS_SBG_CFG](../advanced_config/parameter_reference.md#SENS_SBG_CFG) to the hardware port connected to the SBG Systems product (for more information see [Serial Port Configuration](../peripherals/serial_configuration.md)). + + ::: warning + Disable or change port of other sensors that are using the same one, for example [GPS_1_CONFIG](../advanced_config/parameter_reference.md#GPS_1_CONFIG) if using GPS1 port. + ::: + +3. Set [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) to the desired default baudrate value. +4. Allow the sbgECom driver to initialize by restarting PX4. +5. Configure driver to provide IMU data, GNSS data and INS : + 1. Set [SBG_MODE](../advanced_config/parameter_reference.md#SBG_MODE) to the desired mode. + 2. Make sensor module select sensors by enabling [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE). + 3. Prioritize SBG Systems sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + + ::: tip + In most cases the external IMU (SBG) is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + + Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. + The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. + ::: + + ::: warning + When configuring both SBG Systems and Pixhawk sensors to have non-zero priority, if the selected sensor is errored (timeout), it can change during operation without being notified. + In this case, MAVLink messages will be updated with the newly selected sensor. + + If you don't want to have this fallback mechanism, you must disable unwanted sensors. + ::: 4. If using the sbgECom as an INS, disable EKF2 using [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN). + +6. Restart PX4. + +Once enabled, the module will be detected on boot. +IMU data should be published at 200Hz. + +## SBG Systems Configuration + +All High Performance and Ellipse 3.0 and higher SBG Systems INS can be configured directly from PX4 firmware: + +1. Enable [SBG_CONFIGURE_EN](../advanced_config/parameter_reference.md#SBG_CONFIGURE_EN). +2. Provide a JSON file `sbg_settings.json` containing SBG Systems INS settings to be applied in your PX4 board `extras` directory (ex: `boards/px4/fmu-v5/extras`). The settings JSON file will be installed in `/etc/extras/sbg_settings.json` on the board. + + ::: tip + The settings can be retrieved using [sbgEComAPI](https://github.com/SBG-Systems/sbgECom/tree/main/tools/sbgEComApi) or [sbgInsRestApi](https://developer.sbg-systems.com/sbgInsRestApi/1.3/#tag/Settings) and then modified as a JSON file. + ::: + + ::: tip + The settings file can be provided in the SD card in q`/fs/microsd/etc/extras/sbg_settings.json` to avoid rebuilding a new firmware to change JSON settings file. + ::: + +3. For testing purpose, it's also possible to modify SBG Systems INS settings on the fly: + - By passing a JSON file path as argument when starting sbgecom driver (ex: `sbgecom start -f /fs/microsd/new_sbg_settings.json`) + - By passing a JSON string as argument when starting sbgecom driver: (ex: `sbgecom start -s {"output":{"comA":{"messages":{"airData":"onChange"}}}}`) + +For older Ellipse SBG Systems INS or to configure any SBG Systems INS directly, all commands and registers can be found in the [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +::: warning +If the baudrate of the serial port on the INS product (used to communicate with PX4) is changed, the parameter [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) must be changed to match. +::: + +## Published Data + +Upon initialization, the driver should print the following information to console (printed using `PX4_INFO`) + +- Unit model number +- Unit hardware version +- Unit serial number +- Unit firmware number + +This should be accessible using the [`dmesg`](../modules/modules_system.md#dmesg) command. + +The sbgECom driver always publishes the unit's data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) + +if configured as a GNSS, publishes: + +- [sensor_gps](../msg_docs/SensorGps.md) + +and, if configured as an INS, publishes: + +- [estimator_status](../msg_docs/EstimatorStatus.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_global_positon](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) + +::: tip +Published topics can be viewed using the `listener` command. +::: + +## Hardware Specifications + +- [Product Briefs](https://www.sbg-systems.com/products/) +- [Datasheets](https://www.sbg-systems.com/contact/#products) diff --git a/docs/en/sensor/sfxx_lidar.md b/docs/en/sensor/sfxx_lidar.md index 57ad174826..2ca57d9972 100644 --- a/docs/en/sensor/sfxx_lidar.md +++ b/docs/en/sensor/sfxx_lidar.md @@ -1,4 +1,4 @@ -# LightWare Lidar (SF1X/SF02/LW20/SF45) +# LightWare Lidar (SF1X/SF02/LW20/SF45/GRF250/GRF500) LightWare develops a range of light-weight, general purpose, laser altimeters ("Lidar") suitable for mounting on UAVs. These are useful for applications including terrain following, precision hovering (e.g. for photography), warning of regulatory height limits, anti-collision sensing etc. @@ -9,11 +9,14 @@ These are useful for applications including terrain following, precision hoverin The following models are supported by PX4, and can be connected to either the I2C or Serial bus (the tables below indicates what bus can be used for each model). -| Model | Range (m) | Bus | Description | -| ---------------------------------------------------------- | --------- | ----------------- | ------------------------------------------------------------------------------------------ | -| [SF11/C](https://lightwarelidar.com/products/sf11-c-100-m) | 100 | Serial or I2C bus | -| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C bus | Waterproofed (IP67) with servo for sense-and-avoid applications | -| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Serial | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| Model | Range (m) | Bus | Description | +| ------------------------------------------------------- | --------- | ----------------- | ------------------------------------------------------------------------------------------ | +| [SF11/C](https://lightwarelidar.com/shop/sf11-c-100-m/) | 100 | Serial or I2C bus | +| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C bus | Waterproofed (IP67) with servo for sense-and-avoid applications | +| [SF30/D](https://lightwarelidar.com/shop/sf30-d-200-m/) | 200 | I2C bus | Waterproofed (IP67) | +| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Serial | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| [GRF250](../sensor/grf_lidar.md) | 250 | Serial or I2C | Gimbal Range Finder | +| [GRF500](../sensor/grf_lidar.md) | 500 | Serial or I2C | Gimbal Range Finder | ::: details Discontinued @@ -66,6 +69,9 @@ VTOL vehicles may choose to also set [SF1XX_MODE](../advanced_config/parameter_r ::: tip [SF45/B](../sensor/sf45_rotating_lidar.md) setup is covered in the linked document. ::: +::: tip +[GRF250/GRF500](../sensor/grf_lidar.md) setup is covered in the linked document. +::: ### Hardware diff --git a/docs/en/sensor/vectornav.md b/docs/en/sensor/vectornav.md index b6291f4e4e..cbe8f7b53a 100644 --- a/docs/en/sensor/vectornav.md +++ b/docs/en/sensor/vectornav.md @@ -55,11 +55,9 @@ To use the VectorNav driver: 1. Disable magnetometer preflight checks by setting [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG) to `0`. 1. Allow the VectorNav driver to initialize by restarting PX4. 1. Configure driver as either an external INS or to provide raw data: - - If using the VectorNav as an external INS, set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `INS`. This disables EKF2. - If using the VectorNav as external inertial sensors: - 1. Set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `Sensors Only` 1. If internal sensors are enabled, prioritize VectorNav sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). diff --git a/docs/en/sensor_bus/i2c_development.md b/docs/en/sensor_bus/i2c_development.md index b1ddfa21bf..0a0ccf07e7 100644 --- a/docs/en/sensor_bus/i2c_development.md +++ b/docs/en/sensor_bus/i2c_development.md @@ -4,9 +4,10 @@ I2C is a packet-switched serial communication protocol that allows multiple mast It is intended for attaching lower-speed peripheral ICs to processors and microcontrollers in short-distance, intra-board communication. Pixhawk/PX4 support it for: -* Connecting off board components that require higher data rates than provided by a strict serial UART, such as rangefinders. -* Compatibility with peripheral devices that only support I2C. -* Allowing multiple devices to attach to a single bus (useful for conserving ports). + +- Connecting off board components that require higher data rates than provided by a strict serial UART, such as rangefinders. +- Compatibility with peripheral devices that only support I2C. +- Allowing multiple devices to attach to a single bus (useful for conserving ports). For example, LEDs, Compass, rangefinders etc. ::: info @@ -22,15 +23,17 @@ The bus is not fast enough even with a single device attached to allow vibration Drivers should `#include ` and then provide an implementation of the abstract base class `I2C` defined in **I2C.hpp** for the target hardware (i.e. for NuttX [here](https://github.com/PX4/PX4-Autopilot/blob/main/src/lib/drivers/device/nuttx/I2C.hpp)). -A small number of drivers will also need to include headers for their type of device (**drv_*.h**) in [/src/drivers/](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers) - e.g. [drv_led.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/drivers/drv_led.h). +A small number of drivers will also need to include headers for their type of device (**drv\_\*.h**) in [/src/drivers/](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers) - e.g. [drv_led.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/drivers/drv_led.h). To include a driver in firmware you must add the driver to the board-specific cmake file that corresponds to the target you want to build for. You can do this for a single driver: + ``` CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_LASER_I2C=y ``` You can also include all drivers of a particular type. + ``` CONFIG_COMMON_DISTANCE_SENSOR=y ``` @@ -44,12 +47,13 @@ For example, you can see/search for `CONFIG_DRIVERS_DISTANCE_SENSOR_LIGHTWARE_LA To find I2C driver examples, search for **i2c.h** in [/src/drivers/](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers). Just a few examples are: -* [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_laser_i2c) - I2C driver for [Lightware SF1XX LIDAR](../sensor/sfxx_lidar.md). -* [drivers/distance_sensor/lightware_laser_serial](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_laser_serial) - Serial driver for [Lightware SF1XX LIDAR](../sensor/sfxx_lidar.md). -* [drivers/ms5611](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer/ms5611) - I2C Driver for the MS5611 and MS6507 barometric pressure sensor connected via I2C (or SPI). + +- [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_laser_i2c) - I2C driver for [Lightware SF1XX LIDAR](../sensor/sfxx_lidar.md). +- [drivers/distance_sensor/lightware_laser_serial](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/distance_sensor/lightware_laser_serial) - Serial driver for [Lightware SF1XX LIDAR](../sensor/sfxx_lidar.md). +- [drivers/ms5611](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer/ms5611) - I2C Driver for the MS5611 and MS6507 barometric pressure sensor connected via I2C (or SPI). ## Further Information -* [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) (Wikipedia) -* [I2C Comparative Overview](https://learn.sparkfun.com/tutorials/i2c) (learn.sparkfun.com) -* [Driver Framework](../middleware/drivers.md) +- [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) (Wikipedia) +- [I2C Comparative Overview](https://learn.sparkfun.com/tutorials/i2c) (learn.sparkfun.com) +- [Driver Framework](../middleware/drivers.md) diff --git a/docs/en/sensor_bus/i2c_general.md b/docs/en/sensor_bus/i2c_general.md index 2715b604e3..9242b7c70b 100644 --- a/docs/en/sensor_bus/i2c_general.md +++ b/docs/en/sensor_bus/i2c_general.md @@ -4,9 +4,9 @@ It is recommended for: -* Connecting offboard components that require low bandwidth and low latency communication, e.g. [rangefinders](../sensor/rangefinders.md), [magnetometers](../gps_compass/magnetometer.md), [airspeed sensors](../sensor/airspeed.md) and [tachometers](../sensor/tachometers.md). -* Compatibility with peripheral devices that only support I2C. -* Allowing multiple devices to attach to a single bus, which is useful for conserving ports. +- Connecting offboard components that require low bandwidth and low latency communication, e.g. [rangefinders](../sensor/rangefinders.md), [magnetometers](../gps_compass/magnetometer.md), [airspeed sensors](../sensor/airspeed.md) and [tachometers](../sensor/tachometers.md). +- Compatibility with peripheral devices that only support I2C. +- Allowing multiple devices to attach to a single bus, which is useful for conserving ports. I2C allows multiple master devices to connect to multiple slave devices using only 2 wires per connection (SDA, SCL). in theory, a bus can support 128 devices, each accessed via its unique address. @@ -15,7 +15,6 @@ in theory, a bus can support 128 devices, each accessed via its unique address. UAVCAN would normally be preferred where higher data rates are required, and on larger vehicles where sensors are mounted further from the flight controller. ::: - ## Wiring I2C uses a pair of wires: SDA (serial data) and SCL (serial clock). @@ -29,7 +28,6 @@ To ensure reliable communication and to reduce crosstalk it is advised to apply ![Cable twisting](../../assets/hardware/cables/i2c_jst-gh_cable.jpg) - ## Checking the Bus and Device Status A useful tool for bus analysis is [i2cdetect](../modules/modules_command.md#i2cdetect). @@ -41,8 +39,8 @@ The tool can be run in the PX4 terminal with the following command: ``` i2cdetect -b 1 ``` -where the bus number is specified after `-b` parameter +where the bus number is specified after `-b` parameter ## Common problems @@ -62,8 +60,9 @@ The bandwidth available for each device generally decreases as more devices are If too many devices are added, it can cause transmission errors and network unreliability. There are several ways to reduce the problem: -* Dividing the devices into groups, each with approximately the same number of devices, and connecting each group to one autopilot port -* Increase bus speed limit (usually set to 100kHz for external I2C bus) + +- Dividing the devices into groups, each with approximately the same number of devices, and connecting each group to one autopilot port +- Increase bus speed limit (usually set to 100kHz for external I2C bus) ### Excessive Wiring Capacitance @@ -71,9 +70,10 @@ The electrical capacity of bus wiring increases as more devices/wires are added. The problem can be analyzed using an oscilloscope, where we see that the edges of SDA/SCL signals are no longer sharp. There are several ways to reduce the problem: -* Dividing the devices into groups, each with approximately the same number of devices, and connecting each group to one autopilot port -* Using the shorter and higher quality I2C cables, see the [cable wiring page](../assembly/cable_wiring.md#i2c-cables) for details -* Separating the devices with a weak open-drain driver to smaller buses with lower capacitance by using [I2C Bus Accelerators](#i2c-bus-accelerators) + +- Dividing the devices into groups, each with approximately the same number of devices, and connecting each group to one autopilot port +- Using the shorter and higher quality I2C cables, see the [cable wiring page](../assembly/cable_wiring.md#i2c-cables) for details +- Separating the devices with a weak open-drain driver to smaller buses with lower capacitance by using [I2C Bus Accelerators](#i2c-bus-accelerators) ## I2C Bus Accelerators @@ -81,6 +81,7 @@ I2C bus accelerators are separate circuits that can be used to support longer wi They work by physically dividing an I2C network into 2 parts and using their own transistors to amplify I2C signals. Available accelerators include: + - [Thunderfly TFI2CEXT01](https://docs.thunderfly.cz/avionics/TFI2CEXT01/): ![I2C bus extender](../../assets/peripherals/i2c_tfi2cext/tfi2cext01a_bottom.jpg) - This has Dronecode connectors and is hence very easy to add to a Pixhawk I2C setup. @@ -89,7 +90,7 @@ Available accelerators include: ### I2C Level Converter function Some I2C devices have 5V on the data lines, while the Pixhawk connector standard port expects these lines to be 3.3 V. -You can use the TFI2CEXT01 as a level converter to connect 5V devices to a Pixhawk I2C port. This feature is possible because the SCL and SDA lines of TFI2CEXT01 are 5V tolerant. +You can use the TFI2CEXT01 as a level converter to connect 5V devices to a Pixhawk I2C port. This feature is possible because the SCL and SDA lines of TFI2CEXT01 are 5V tolerant. ## I2C Address Translators @@ -112,6 +113,6 @@ Software development for I2C devices is described in [I2C Bus (Development Overv ## Further Information -* [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) (Wikipedia) -* [I2C Comparative Overview](https://learn.sparkfun.com/tutorials/i2c) (learn.sparkfun.com) -* [Driver Framework](../middleware/drivers.md) +- [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) (Wikipedia) +- [I2C Comparative Overview](https://learn.sparkfun.com/tutorials/i2c) (learn.sparkfun.com) +- [Driver Framework](../middleware/drivers.md) diff --git a/docs/en/sensor_bus/translator_tfi2cadt.md b/docs/en/sensor_bus/translator_tfi2cadt.md index 0f00b6a610..0c12106d78 100644 --- a/docs/en/sensor_bus/translator_tfi2cadt.md +++ b/docs/en/sensor_bus/translator_tfi2cadt.md @@ -28,7 +28,7 @@ If you need your own value for address translation, changing the configuration r ## Example of Use The tachometer sensor [TFRPM01](../sensor/thunderfly_tachometer.md) can be set to two different addresses using a solder jumper. -If the autopilot has three buses, only 6 sensors can be connected and no bus remains free (2 available addresses * 3 I2C ports). +If the autopilot has three buses, only 6 sensors can be connected and no bus remains free (2 available addresses \* 3 I2C ports). In some multicopters or VTOL solutions, there is a need to measure the RPM of 8 or more elements. The [TFI2CADT01](https://www.tindie.com/products/26353/) is highly recommended in this case. @@ -39,7 +39,6 @@ By adding another TFI2CADT01, 4 more devices can be connected to the same bus. [![Connection of multiple sensors](https://mermaid.ink/img/pako:eNptkd9rwjAQx_-VcE8dtJB2ukEfBLEWfJCJy8CHvgRznQH7gzSBDfF_33VZB2oCyf3I576XcBc4dgohh08j-xMTRdUyWuX2I6LNErY7zJh0tuv1ubNP_7csSRZsudlHS22GHlGxAduhM3fEfrdNI1GS4emK8a85fwSyGyC9A0S5yVbrg_DZKfLtCxH9JsjhaU7VvI7pfK3_NCg_NXmO3pwl5uYt9D0yAXoWoFNP4yM9H-kspJ0FtF8CdObpURtiaNA0UisaymWsrsCesMEKcnIV1tKdbQVVeyXU9UpaXCttOwO5NQ5jGKf1_t0ep9gzhZY04sYnrz9BI4mU)](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNptkd9rwjAQx_-VcE8dtJB2ukEfBLEWfJCJy8CHvgRznQH7gzSBDfF_33VZB2oCyf3I576XcBc4dgohh08j-xMTRdUyWuX2I6LNErY7zJh0tuv1ubNP_7csSRZsudlHS22GHlGxAduhM3fEfrdNI1GS4emK8a85fwSyGyC9A0S5yVbrg_DZKfLtCxH9JsjhaU7VvI7pfK3_NCg_NXmO3pwl5uYt9D0yAXoWoFNP4yM9H-kspJ0FtF8CdObpURtiaNA0UisaymWsrsCesMEKcnIV1tKdbQVVeyXU9UpaXCttOwO5NQ5jGKf1_t0ep9gzhZY04sYnrz9BI4mU) - - ::: info TFI2CADT01 does not contain any I2C buffer or accelerator. As it adds additional capacitance on the bus, we advise combining it with some bus booster, e.g. [TFI2CEXT01](https://docs.thunderfly.cz/avionics/TFI2CEXT01/). @@ -62,4 +60,4 @@ As it adds additional capacitance on the bus, we advise combining it with some b ### Other Resources -* Datasheet of [LTC4317](https://www.analog.com/media/en/technical-documentation/data-sheets/4317fa.pdf) +- Datasheet of [LTC4317](https://www.analog.com/media/en/technical-documentation/data-sheets/4317fa.pdf) diff --git a/docs/en/sim_gazebo_gz/index.md b/docs/en/sim_gazebo_gz/index.md index f4df3ea569..8f4ed2fee8 100644 --- a/docs/en/sim_gazebo_gz/index.md +++ b/docs/en/sim_gazebo_gz/index.md @@ -20,6 +20,8 @@ See [Simulation](../simulation/index.md) for general information about simulator Gazebo Harmonic is installed by default on Ubuntu 22.04 as part of the normal [development environment setup](../dev_setup/dev_env_linux_ubuntu.md#simulation-and-nuttx-pixhawk-targets). +Gazebo versions Harmonic, Ionic, and Jetty are supported on Ubuntu 24.04. The latest installed Gazebo release is used by default. + :::info The PX4 installation scripts are based on the instructions: [Binary Installation on Ubuntu](https://gazebosim.org/docs/harmonic/install_ubuntu/) (gazebosim.org). ::: @@ -48,22 +50,23 @@ This runs both the PX4 SITL instance and the Gazebo client. The supported vehicles and `make` commands are listed below. Note that all gazebo make targets have the prefix `gz_`. -| Vehicle | Command | `PX4_SYS_AUTOSTART` | -| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------- | -| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | -| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | -| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | -| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | -| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | -| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | -| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | -| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | -| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | -| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | -| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_r1_rover` | 4009 | -| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 4012 | -| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | -| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| Vehicle | Command | `PX4_SYS_AUTOSTART` | +| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------- | +| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | +| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | +| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | +| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | +| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | +| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | +| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | +| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | +| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | +| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | +| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | +| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_rover_differential` | 50000 | +| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 51000 | +| [Mecanum Rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) | `make px4_sitl gz_rover_mecanum` | 52000 | All [vehicle models](../sim_gazebo_gz/vehicles.md) (and [worlds](#specify-world)) are included as a submodule from the [Gazebo Models Repository](../sim_gazebo_gz/gazebo_models.md) repository. @@ -132,6 +135,7 @@ HEADLESS=1 make px4_sitl gz_x500 ``` ### Set Custom Takeoff Location + The takeoff location in Gazebo Classic can be set using environment variables. The variables to set are: PX4_HOME_LAT, PX4_HOME_LON, and PX4_HOME_ALT. @@ -162,16 +166,16 @@ PX4_GZ_WORLD=windy make px4_sitl gz_x500 The [supported worlds](../sim_gazebo_gz/worlds.md) are listed below. -| World | Command | Description | -| ----------------- | ---------------------------------- | ----------------------------------------------------------- | -| `default` | `make px4_sitl *` | Empty world (a grey plane) | -| `aruco` | `make px4_sitl *_aruco` | Empty world with aruco marker for testing precision landing | -| `baylands` | `make px4_sitl *_baylands` | Baylands world surrounded by water | -| `lawn` | `make px4_sitl *_lawn` | Lawn world for testing rovers | -| `rover` | `make px4_sitl *_rover` | Rover world (optimised/preferred) | -| `walls` | `make px4_sitl *_walls` | Wall world for testing collision prevention | -| `windy` | `make px4_sitl *_windy` | Empty world with wind enabled | -| `moving_platform` | `make px4_sitl *_moving_platform` | World with moving takeoff / landing platform | +| World | Command | Description | +| ----------------- | --------------------------------- | ----------------------------------------------------------- | +| `default` | `make px4_sitl *` | Empty world (a grey plane) | +| `aruco` | `make px4_sitl *_aruco` | Empty world with aruco marker for testing precision landing | +| `baylands` | `make px4_sitl *_baylands` | Baylands world surrounded by water | +| `lawn` | `make px4_sitl *_lawn` | Lawn world for testing rovers | +| `rover` | `make px4_sitl *_rover` | Rover world (optimised/preferred) | +| `walls` | `make px4_sitl *_walls` | Wall world for testing collision prevention | +| `windy` | `make px4_sitl *_windy` | Empty world with wind enabled | +| `moving_platform` | `make px4_sitl *_moving_platform` | World with moving takeoff / landing platform | :::warning Note that if no world is specified, PX4 will use the `default` world. @@ -250,13 +254,11 @@ where `ARGS` is a list of environment variables including: - `PX4_GZ_MODEL_NAME`: Sets the name of an _existing_ model in the gazebo simulation. If provided, the startup script tries to bind a new PX4 instance to the Gazebo resource matching exactly that name. - - The setting is mutually exclusive with `PX4_SIM_MODEL`. - `PX4_SIM_MODEL`: Sets the name of a new Gazebo model to be spawned in the simulator. If provided, the startup script looks for a model in the Gazebo resource path that matches the given variable, spawns it and binds a new PX4 instance to it. - - The setting is mutually exclusive with `PX4_GZ_MODEL_NAME`. ::: info @@ -266,7 +268,6 @@ where `ARGS` is a list of environment variables including: - `PX4_GZ_MODEL_POSE`: Sets the spawning position and orientation of the model when `PX4_SIM_MODEL` is adopted. If provided, the startup script spawns the model at a pose following the syntax `"x,y,z,roll,pitch,yaw"`, where the positions are given in metres and the angles are in radians. - - If omitted, the zero pose `[0,0,0,0,0,0]` is used. - If less then 6 values are provided, the missing ones are fixed to zero. - This can only be used with `PX4_SIM_MODEL` (not `PX4_GZ_MODEL_NAME`). @@ -274,7 +275,6 @@ where `ARGS` is a list of environment variables including: - `PX4_GZ_WORLD`: Sets the Gazebo world file for a new simulation. If it is not given, then [default](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) is used. - - This variable is ignored if an existing simulation is already running. - This value should be [specified for the selected airframe](#adding-new-worlds-and-models) but may be overridden using this argument. - If the [moving platform world](../sim_gazebo_gz/worlds.md#moving-platform) is selected using `PX4_GZ_WORLD=moving_platform` (or any world using the moving platform plugin), the platform can be configured using environment variables: @@ -283,7 +283,6 @@ where `ARGS` is a list of environment variables including: - `PX4_SIMULATOR=GZ`: Sets the simulator, which for Gazebo must be `gz`. - - This value should be [set for the selected airframe](#adding-new-worlds-and-models), in which case it does not need to be set as an argument. - `PX4_GZ_STANDALONE`: @@ -371,7 +370,6 @@ To add a new model: ``` 1. Add CMake Target for the [airframe](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt). - - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` @@ -383,7 +381,6 @@ To add a new world: 1. Add your world to the list of worlds found in the [`CMakeLists.txt` here](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/CMakeLists.txt). This is required in order to allow `CMake` to generate correct targets. - - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` diff --git a/docs/en/sim_gazebo_gz/vehicles.md b/docs/en/sim_gazebo_gz/vehicles.md index 679aec83ff..10f377d465 100644 --- a/docs/en/sim_gazebo_gz/vehicles.md +++ b/docs/en/sim_gazebo_gz/vehicles.md @@ -185,7 +185,7 @@ make px4_sitl gz_tiltrotor [Differential Rover](../frames_rover/index.md#differential) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. ```sh -make px4_sitl gz_r1_rover +make px4_sitl gz_rover_differential ``` ![Differential Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_differential.png) @@ -199,3 +199,13 @@ make px4_sitl gz_rover_ackermann ``` ![Ackermann Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_ackermann.png) + +### Mecanum Rover + +[Mecanum Rover](../frames_rover/index.md#mecanum) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. + +```sh +make px4_sitl gz_rover_mecanum +``` + +![Mecanum Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_mecanum.png) diff --git a/docs/en/sim_gazebo_gz/worlds.md b/docs/en/sim_gazebo_gz/worlds.md index 5f72e222b2..8d10d50754 100644 --- a/docs/en/sim_gazebo_gz/worlds.md +++ b/docs/en/sim_gazebo_gz/worlds.md @@ -85,8 +85,8 @@ PX4_GZ_MODEL_POSE=0,0,2.2 PX4_GZ_WORLD=moving_platform make px4_sitl gz_standard The plugin can be configured with the following environment variables: - - `PX4_GZ_PLATFORM_VEL`: Platform speed (m/s). - - `PX4_GZ_PLATFORM_HEADING_DEG`: Platform heading and direction of velocity (degrees). 0 = east, positive direction is counterclockwise. +- `PX4_GZ_PLATFORM_VEL`: Platform speed (m/s). +- `PX4_GZ_PLATFORM_HEADING_DEG`: Platform heading and direction of velocity (degrees). 0 = east, positive direction is counterclockwise. [PX4-gazebo-models/main/worlds/moving_platform.sdf](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/moving_platform.sdf) diff --git a/docs/en/sim_sih/index.md b/docs/en/sim_sih/index.md index c134b8aca8..07767e72ef 100644 --- a/docs/en/sim_sih/index.md +++ b/docs/en/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH as SITL (without hardware) from PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Benefits @@ -339,6 +339,7 @@ You can find a full list of available values for `PWM_MAIN_FUNCn` [here](../adva Alternatively, you can use the [`PWM_AUX_FUNCn`](../advanced_config/parameter_reference.md#PWM_AUX_FUNC1) parameters. You may also configure the output as desired: + - Disarmed PWM: ([`PWM_MAIN_DISn`](../advanced_config/parameter_reference.md#PWM_MAIN_DIS1) / [`PWM_AUX_DIS1`](../advanced_config/parameter_reference.md#PWM_AUX_DIS1)) - Minimum PWM ([`PWM_MAIN_MINn`](../advanced_config/parameter_reference.md#PWM_MAIN_MIN1) / [`PWM_AUX_MINn`](../advanced_config/parameter_reference.md#PWM_AUX_MIN1)) - Maximum PWM ([`PWM_MAIN_MAXn`](../advanced_config/parameter_reference.md#PWM_MAIN_MAX1) / [`PWM_AUX_MAXn`](../advanced_config/parameter_reference.md#PWM_AUX_MAX1)) diff --git a/docs/en/simulation/community_supported_simulators.md b/docs/en/simulation/community_supported_simulators.md index 6e201601c2..a7bbda97c0 100644 --- a/docs/en/simulation/community_supported_simulators.md +++ b/docs/en/simulation/community_supported_simulators.md @@ -12,10 +12,10 @@ See [Toolchain Installation](../dev_setup/dev_env.md) for information about the The tools have variable levels of support from their communities (some are well supported and others are not). Questions about these tools should be raised on the [discussion forums](../contribute/support.md#forums-and-chat) -| Simulator | Description | -| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Simulation-In-Hardware](../sim_sih/index.md) (SIH) |

A simulator implemented in C++ as a PX4 module directly in the Firmware [code](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/simulator_sih). It can be ran in SITL directly on the computer or as an alternative to HITL offering a hard real-time simulation directly on the hardware autopilot.

Supported Vehicles: Quad, Hexa, Plane, Tailsitter, Standard VTOL, Ackermann Rover

| -| [FlightGear](../sim_flightgear/index.md) |

A simulator that provides physically and visually realistic simulations. In particular it can simulate many weather conditions, including thunderstorms, snow, rain and hail, and can also simulate thermals and different types of atmospheric flows. [Multi-vehicle simulation](../sim_flightgear/multi_vehicle.md) is also supported.

Supported Vehicles: Plane, Autogyro, Rover

| -| [JMAVSim](../sim_jmavsim/index.md) |

A simple multirotor/quad simulator. This was previously part of the PX4 development toolchain but was removed in favour of [Gazebo](../sim_gazebo_gz/index.md).

Supported Vehicles: Quad

| -| [JSBSim](../sim_jsbsim/index.md) |

A simulator that provides advanced flight dynamics models. This can be used to model realistic flight dynamics based on wind tunnel data.

Supported Vehicles: Plane, Quad, Hex

| -| [AirSim](../sim_airsim/index.md) |

A cross platform simulator that provides physically and visually realistic simulations. This simulator is resource intensive, and requires a significantly more powerful computer than the other simulators described here.

Supported Vehicles: Iris (MultiRotor model and a configuration for PX4 QuadRotor in the X configuration).

| +| Simulator | Description | +| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [Simulation-In-Hardware](../sim_sih/index.md) (SIH) |

A simulator implemented in C++ as a PX4 module directly in the Firmware [code](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/simulator_sih). It can be ran in SITL directly on the computer or as an alternative to HITL offering a hard real-time simulation directly on the hardware autopilot.

Supported Vehicles: Quad, Hexa, Plane, Tailsitter, Standard VTOL, Ackermann Rover

| +| [FlightGear](../sim_flightgear/index.md) |

A simulator that provides physically and visually realistic simulations. In particular it can simulate many weather conditions, including thunderstorms, snow, rain and hail, and can also simulate thermals and different types of atmospheric flows. [Multi-vehicle simulation](../sim_flightgear/multi_vehicle.md) is also supported.

Supported Vehicles: Plane, Autogyro, Rover

| +| [JMAVSim](../sim_jmavsim/index.md) |

A simple multirotor/quad simulator. This was previously part of the PX4 development toolchain but was removed in favour of [Gazebo](../sim_gazebo_gz/index.md).

Supported Vehicles: Quad

| +| [JSBSim](../sim_jsbsim/index.md) |

A simulator that provides advanced flight dynamics models. This can be used to model realistic flight dynamics based on wind tunnel data.

Supported Vehicles: Plane, Quad, Hex

| +| [AirSim](../sim_airsim/index.md) |

A cross platform simulator that provides physically and visually realistic simulations. This simulator is resource intensive, and requires a significantly more powerful computer than the other simulators described here.

Supported Vehicles: Iris (MultiRotor model and a configuration for PX4 QuadRotor in the X configuration).

| diff --git a/docs/en/smart_batteries/index.md b/docs/en/smart_batteries/index.md index 6ddc032842..805ad60619 100644 --- a/docs/en/smart_batteries/index.md +++ b/docs/en/smart_batteries/index.md @@ -5,7 +5,8 @@ This allows for more more reliable flight planning notification of failure condi The information may include some of: remaining charge, time-to-empty (estimated), cell voltages (rated max/min, current voltage, etc.), temperature, currents, fault information, battery vendor, chemistry, etc. PX4 supports (at least) following smart batteries: -* [Rotoye Batmon](../smart_batteries/rotoye_batmon.md) + +- [Rotoye Batmon](../smart_batteries/rotoye_batmon.md) ### Further Information diff --git a/docs/en/smart_batteries/rotoye_batmon.md b/docs/en/smart_batteries/rotoye_batmon.md index 64120b5da8..a50eba58e2 100644 --- a/docs/en/smart_batteries/rotoye_batmon.md +++ b/docs/en/smart_batteries/rotoye_batmon.md @@ -7,12 +7,10 @@ It can be purchased as a standalone unit or as part of a factory-assembled smart ![Pre-assembled Rotoye smart battery](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye-pack.jpg) - ## Where to Buy [Rotoye Store](https://rotoye.com/batmon/): Batmon kits, custom smart-batteries, and accessories - ## Wiring/Connections The Rotoye Batmon system uses an XT-90 battery connector with I2C pins, and an opti-isolator board to transmit data. @@ -21,7 +19,6 @@ The Rotoye Batmon system uses an XT-90 battery connector with I2C pins, and an o More details can be found [here](https://github.com/rotoye/batmon_reader) - ## Software Setup ### Build PX4 Firmware @@ -31,7 +28,7 @@ More details can be found [here](https://github.com/rotoye/batmon_reader) git clone https://github.com/rotoye/PX4-Autopilot.git cd PX4-Autopilot ``` -1. Checkout the *batmon_4.03* branch +1. Checkout the _batmon_4.03_ branch ```sh git fetch origin batmon_4.03 git checkout batmon_4.03 @@ -40,16 +37,17 @@ More details can be found [here](https://github.com/rotoye/batmon_reader) ### Configure Parameters -In *QGroundControl*: +In _QGroundControl_: + 1. Set the following [parameters](../advanced_config/parameters.md): - `BATx_SOURCE` to `External`, - - `SENS_EN_BAT` to `true`, + - `SENS_EN_BAT` to `true`, - `BAT_SMBUS_MODEL` to `3:Rotoye` 1. Open the [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) 1. Start the [batt_smbus driver](../modules/modules_driver.md) in the console. For example, to run two BatMons on the same bus: - ```sh - batt_smbus start -X -b 1 -a 11 # External bus 1, address 0x0b + ```sh + batt_smbus start -X -b 1 -a 11 # External bus 1, address 0x0b batt_smbus start -X -b 1 -a 12 # External bus 1, address 0x0c ``` diff --git a/docs/en/test_and_ci/continous_integration.md b/docs/en/test_and_ci/continous_integration.md index 0cbae2fca9..86033febbc 100644 --- a/docs/en/test_and_ci/continous_integration.md +++ b/docs/en/test_and_ci/continous_integration.md @@ -1,3 +1,194 @@ # PX4 Continuous Integration -PX4 builds and testing are performed using GitHub actions and a Jenkins server. +PX4 uses GitHub Actions for continuous integration, with different workflows handling code builds, testing, and documentation. + +## Documentation CI + +The documentation pipeline handles building, deploying, and translating the PX4 User Guide. +All documentation CI is consolidated into a single orchestrator workflow organized in tiers. + +### Docs Orchestrator + +**Workflow file:** [`docs-orchestrator.yml`](https://github.com/PX4/PX4-Autopilot/blob/main/.github/workflows/docs-orchestrator.yml) + +This is the main documentation workflow. It runs on pull requests, pushes to `main` and `release/**` branches, and manual `workflow_dispatch` triggers, performing different jobs depending on the trigger event. +Jobs are organized in tiers, where each tier depends on the previous one completing successfully. + +#### Tier Structure + +| Tier | Job | PR | Push / Dispatch | Description | +| ---- | -------------- | ---------------------------- | --------------- | ------------------------------------------------------------- | +| T1 | Detect Changes | Yes | — | Checks if source code files changed (triggers metadata regen) | +| T2 | PR Metadata | Yes (conditional) | — | Builds PX4 SITL and regenerates all auto-generated docs | +| T2 | Metadata Sync | — | Yes | Builds PX4 SITL, regenerates metadata, auto-commits | +| T2 | Link Check | Yes | — | Checks for broken links in changed files, posts PR comment | +| T3 | Build Site | Yes (if docs/source changed) | Yes (after T2) | Builds the VitePress documentation site | +| T4 | Deploy | — | Yes | Deploys to AWS S3 | + +#### Pull Request Flow + +When a PR modifies files in `docs/**` or the orchestrator workflow file itself, the workflow validates the changes: + +```txt +PR Event + │ + ▼ +┌─────────────────────────────────────┐ +│ T1: Detect Changes │ +│ • Checks if src/msg/ROMFS changed │ +└─────────────────┬───────────────────┘ + │ + ┌───────┴───────┐ + ▼ ▼ +┌──────────────────┐ ┌─────────────────────────┐ +│ T2: PR Metadata │ │ T2: Link Check (~30s) │ +│ (conditional) │ │ • Detects changed .md │ +│ • Builds SITL │ │ • Runs filtered check │ +│ • Generates │ │ • Posts PR comment │ +│ metadata │ │ • Runs full check │ +│ • Builds │ └────────────┬────────────┘ +│ failsafe web │ │ +└────────┬─────────┘ │ + └───────────┬────────────┘ + ▼ +┌─────────────────────────────────────┐ +│ T3: Build Site (~7-10 min) │ +│ (skipped if only workflow YAML │ +│ changed — no docs/source changes) │ +│ • Builds VitePress site │ +│ • Verifies no build errors │ +└─────────────────┬───────────────────┘ + │ + ▼ + DONE +``` + +| Job | Duration | Description | +| ---------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| **T1: Detect Changes** | ~10s | Determines if metadata regeneration is needed | +| **T2: PR Metadata** | ~10-15m | Rebuilds PX4 SITL and regenerates all metadata (only if source files changed) | +| **T2: Link Check** | ~30s | Checks for broken links in changed markdown files and posts a sticky comment to the PR (skipped on fork PRs) | +| **T3: Build Site** | ~7-10m | Builds the VitePress site to verify there are no build errors. Skipped when only the workflow YAML changed (no docs or source changes). | + +#### Push / Dispatch Flow (main/release branches) + +When changes are pushed to `main` or `release/**` branches (or a `workflow_dispatch` is triggered), the workflow regenerates metadata, builds, and deploys. +Only `main` and `release/*` branches are accepted for deploy — other branches will fail with a clear error. + +```txt +Push / Dispatch Event + │ + ▼ +┌─────────────────────────────────────┐ +│ T2: Metadata Sync (~10-15 min) │ +│ • Builds px4_sitl_default │ +│ • Generates parameter/airframe/ │ +│ module documentation │ +│ • Builds failsafe web simulator │ +│ • Formats with Prettier │ +│ • Auto-commits if changes detected │ +│ (with [skip ci]) │ +└─────────────────┬───────────────────┘ + │ + ▼ +┌─────────────────────────────────────┐ +│ T3: Build Site (~7-10 min) │ +│ • Builds VitePress site │ +│ • Uploads build artifact │ +└─────────────────┬───────────────────┘ + │ + ▼ +┌─────────────────────────────────────┐ +│ T4: Deploy (~3 min) │ +│ • Syncs to AWS S3 │ +│ • HTML: 60s cache │ +│ • Assets: 24h immutable cache │ +└─────────────────────────────────────┘ +``` + +| Job | Duration | Description | +| --------------------- | -------- | ------------------------------------------------------------------------------------------------- | +| **T2: Metadata Sync** | ~10-15m | Rebuilds PX4 SITL, regenerates all metadata, formats with Prettier, auto-commits with `[skip ci]` | +| **T3: Build Site** | ~7-10m | Builds the VitePress documentation site | +| **T4: Deploy** | ~3m | Syncs built site to AWS S3 (HTML: 60s cache, assets: 24h cache) | + +Crowdin upload is handled by a separate workflow (see below). + +#### Generated Metadata + +The metadata regeneration job creates the following auto-generated documentation: + +| Type | Output | Description | +| ------------------ | ------------------------------------------------ | -------------------------------------------- | +| Parameters | `docs/en/advanced_config/parameter_reference.md` | Complete parameter reference | +| Airframes | `docs/en/airframes/airframe_reference.md` | Airframe configurations | +| Modules | `docs/en/modules/*.md` | Module documentation | +| Messages | `docs/en/msg_docs/*.md` | uORB message documentation | +| uORB Graphs | `docs/public/middleware/*.json` | Topic dependency graphs | +| Failsafe Simulator | `docs/public/config/failsafe/*` | Interactive failsafe simulator (WebAssembly) | + +::: warning +Do not manually edit the auto-generated files listed above. They are overwritten on every push to main. +::: + +#### Path Triggers + +The workflow triggers on different paths depending on the event: + +**Push** (main/release branches): + +| Path | Reason | +| ------------------------ | ------------------------------------- | +| `docs/**` | Documentation source files | +| `src/**` | Source code changes affect metadata | +| `msg/**` | Message definitions affect metadata | +| `ROMFS/**` | ROMFS files affect metadata | +| `Tools/module_config/**` | Module configuration affects metadata | + +**Pull Request:** + +| Path | Reason | +| ----------------------------------------- | ------------------------------ | +| `docs/**` | Documentation source files | +| `.github/workflows/docs-orchestrator.yml` | Changes to the workflow itself | + +Source-only changes on PRs are detected at runtime by the T1: Detect Changes job using [dorny/paths-filter](https://github.com/dorny/paths-filter), which conditionally triggers the T2: PR Metadata job. + +### Crowdin Download Workflow + +**Workflow file:** [`docs_crowdin_download.yml`](https://github.com/PX4/PX4-Autopilot/blob/main/.github/workflows/docs_crowdin_download.yml) + +This scheduled workflow downloads completed translations from Crowdin and creates pull requests. + +| Setting | Value | +| -------------------- | ------------------------------------------------------- | +| **Schedule** | Every Sunday at 00:00 UTC | +| **Target Languages** | Korean (ko), Ukrainian (uk), Chinese Simplified (zh-CN) | + +**Process:** + +1. Downloads translations for each target language from Crowdin +2. Creates a separate PR for each language with new translations +3. PRs are labeled "Documentation" and assigned for review + +### Caching Strategy + +The workflows use caching to speed up builds: + +| Cache | Size | Purpose | +| ------------ | ----- | ------------------------------------- | +| ccache | 1GB | C++ compilation cache for SITL builds | +| node_modules | ~26MB | Node.js dependencies for VitePress | + +### Infrastructure + +Jobs run on [runs-on](https://runs-on.com/) self-hosted runners with S3 cache: + +| Job | Runner | +| ------------------ | ------------------------------ | +| T1: Detect Changes | ubuntu-latest | +| T2: PR Metadata | 4 CPU (with px4-dev container) | +| T2: Metadata Sync | 4 CPU (with px4-dev container) | +| T2: Link Check | ubuntu-latest | +| T3: Build Site | 4 CPU | +| T4: Deploy | ubuntu-latest | diff --git a/docs/en/test_and_ci/docker.md b/docs/en/test_and_ci/docker.md index 43f0ee5eb8..82308fe62f 100644 --- a/docs/en/test_and_ci/docker.md +++ b/docs/en/test_and_ci/docker.md @@ -1,12 +1,11 @@ # PX4 Docker Containers -Docker containers are provided for the complete [PX4 development toolchain](../dev_setup/dev_env.md#supported-targets) including NuttX and Linux based hardware, [Gazebo Classic](../sim_gazebo_classic/index.md) simulation, and [ROS](../simulation/ros_interface.md). +Docker containers are provided for the complete [PX4 development toolchain](../dev_setup/dev_env.md#supported-targets) including NuttX and Linux based hardware, [Gazebo](../sim_gazebo_gz/index.md) simulation, and [ROS 2](../ros2/user_guide.md). This topic shows how to use the [available docker containers](#px4_containers) to access the build environment in a local Linux computer. ::: info -Dockerfiles and README can be found on [Github here](https://github.com/PX4/PX4-containers/tree/master?tab=readme-ov-file#container-hierarchy). -They are built automatically on [Docker Hub](https://hub.docker.com/u/px4io/). +The recommended `px4-dev` container is built from the [Dockerfile in the PX4-Autopilot source tree](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/setup/Dockerfile) by the [Container build workflow](https://github.com/PX4/PX4-Autopilot/actions/workflows/dev_container.yml). ::: ## Prerequisites @@ -35,33 +34,36 @@ sudo usermod -aG docker $USER # Log in/out again before using docker! ``` -## Container Hierarchy {#px4_containers} +## px4-dev Container (Recommended) {#px4_containers} -The available containers are on [GitHub here](https://github.com/PX4/PX4-containers/tree/master?tab=readme-ov-file#container-hierarchy). +The **`px4-dev`** container is the recommended container for building PX4 firmware. +It is a single, multi-architecture container (linux/amd64 and linux/arm64) based on Ubuntu 24.04 that includes everything needed to build PX4 for NuttX hardware targets. -These allow testing of various build targets and configurations (the included tools can be inferred from their names). -The containers are hierarchical, such that containers have the functionality of their parents. -For example, the partial hierarchy below shows that the docker container with NuttX build tools (`px4-dev-nuttx-focal`) does not include ROS 2, while the simulation containers do: +It is published to both registries simultaneously: -```plain -- px4io/px4-dev-base-focal - - px4io/px4-dev-nuttx-focal - - px4io/px4-dev-simulation-focal - - px4io/px4-dev-ros-noetic - - px4io/px4-dev-ros2-foxy - - px4io/px4-dev-ros2-rolling -- px4io/px4-dev-base-jammy - - px4io/px4-dev-nuttx-jammy -``` +- **GitHub Container Registry:** [ghcr.io/px4/px4-dev](https://github.com/PX4/PX4-Autopilot/pkgs/container/px4-dev) +- **Docker Hub:** [px4io/px4-dev](https://hub.docker.com/r/px4io/px4-dev) -The most recent version can be accessed using the `latest` tag: `px4io/px4-dev-nuttx-focal:latest` -(available tags are listed for each container on _hub.docker.com_. -For example, the `px4io/px4-dev-nuttx-focal` tags can be found on [hub.docker.com here](https://hub.docker.com/r/px4io/px4-dev-nuttx-focal/tags?page=1&ordering=last_updated)). +The container includes: + +- Ubuntu 24.04 base +- ARM cross-compiler (`gcc-arm-none-eabi`) and Xtensa compiler (for ESP32 targets) +- Build tools: `cmake`, `ninja`, `ccache`, `make` +- Python 3 with PX4 build dependencies +- NuttX toolchain libraries (`libnewlib-arm-none-eabi`, etc.) + +The container is built from the [Dockerfile](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/setup/Dockerfile) in the PX4 source tree using the [Container build workflow](https://github.com/PX4/PX4-Autopilot/actions/workflows/dev_container.yml). +Images are tagged with the PX4 version (e.g. `px4io/px4-dev:v1.16.0`). :::tip -Typically you should use a recent container, but not necessarily the `latest` (as this changes too often). +A `px4-sim` container with simulation tools (Gazebo Harmonic) is planned to complement `px4-dev` for simulation workflows. ::: +### Legacy Containers + +The older per-distro containers from [PX4/PX4-containers](https://github.com/PX4/PX4-containers) (e.g. `px4-dev-nuttx-jammy`, `px4-dev-ros2-humble`, etc.) are no longer recommended. +They will be replaced by `px4-dev` (for builds) and the upcoming `px4-sim` (for simulation). + ## Use the Docker Container The following instructions show how to build PX4 source code on the host computer using a toolchain running in a docker container. @@ -121,7 +123,7 @@ Where, - ``: The host computer directory to be mapped to `` in the container. This should normally be the **PX4-Autopilot** directory. - ``: The location of the shared (source) directory when inside the container. - ``: A name for the docker container being created. This can later be used if we need to reference the container again. -- `:`: The container with version tag to start - e.g.: `px4io/px4-dev-ros:2017-10-23`. +- `:`: The container with version tag to start - e.g.: `px4io/px4-dev:v1.16.0`. - ``: The command to invoke on the new container. E.g. `bash` is used to open a bash shell in the container. The concrete example below shows how to open a bash shell and share the directory **~/src/PX4-Autopilot** on the host computer. @@ -137,7 +139,7 @@ docker run -it --privileged \ -v /tmp/.X11-unix:/tmp/.X11-unix:ro \ -e DISPLAY=:0 \ --network host \ ---name=px4-ros px4io/px4-dev-ros2-foxy:2022-07-31 bash +--name=px4-dev px4io/px4-dev:v1.16.0 bash ``` ::: info @@ -155,7 +157,7 @@ Verify if everything works by running, for example, SITL: ```sh cd src/PX4-Autopilot #This is -make px4_sitl_default gazebo-classic +make px4_sitl gz_x500 ``` ### Re-enter the Container @@ -219,7 +221,7 @@ This ensures that all files created within the container will be accessible on t #### Graphics Driver Issues -It's possible that running Gazebo Classic will result in a similar error message like the following: +It's possible that running Gazebo will result in a similar error message like the following: ```sh libGL error: failed to load driver: swrast @@ -239,7 +241,7 @@ Any recent Linux distribution should work. The following configuration is tested: -- OS X with VMWare Fusion and Ubuntu 14.04 (Docker container with GUI support on Parallels make the X-Server crash). +- OS X with VMWare Fusion and Ubuntu 22.04 (Docker container with GUI support on Parallels make the X-Server crash). **Memory** diff --git a/docs/en/test_and_ci/index.md b/docs/en/test_and_ci/index.md index a906ed8f46..dbb1aa7c11 100644 --- a/docs/en/test_and_ci/index.md +++ b/docs/en/test_and_ci/index.md @@ -9,8 +9,8 @@ Test topics include: - [Unit Tests](../test_and_ci/unit_tests.md) - [Continuous Integration (CI)](../test_and_ci/continous_integration.md) - [Integration Testing](../test_and_ci/integration_testing.md) - - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) - - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) - - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) + - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) + - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) + - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) - [Docker](../test_and_ci/docker.md) - [Maintenance](../test_and_ci/maintenance.md) diff --git a/docs/en/test_and_ci/test_flights.md b/docs/en/test_and_ci/test_flights.md index f9579c1ccb..91a7681f97 100644 --- a/docs/en/test_and_ci/test_flights.md +++ b/docs/en/test_and_ci/test_flights.md @@ -28,5 +28,7 @@ These are run by the test team as part of release testing, and for more signific - [MC_04 - Failsafe Testing](../test_cards/mc_04_failsafe_testing.md) - [MC_05 - Indoor Flight (Manual Modes)](../test_cards/mc_05_indoor_flight_manual_modes.md) - [MC_06 - Indoor Flight (Optical Flow)](../test_cards/mc_06_optical_flow.md) -- [MC_07 - VIO (Visual-Inertial Odometry)](../test_cards/mc_07_vio.md) +- [MC_07 - Optical Flow Low Mount](../test_cards/mc_07_optical_flow_low_mount.md) - [MC_08 - DSHOT ESC](../test_cards/mc_08_dshot.md) +- [MC_09 - VIO (Visual-Inertial Odometry)](../test_cards/mc_09_vio.md) +- [MC_10 - Optical Flow / GPS Mixed](../test_cards/mc_10_optical_flow_gps_mixed.md) diff --git a/docs/en/test_cards/mc_04_failsafe_testing.md b/docs/en/test_cards/mc_04_failsafe_testing.md index 4042e094d2..3947be6b2e 100644 --- a/docs/en/test_cards/mc_04_failsafe_testing.md +++ b/docs/en/test_cards/mc_04_failsafe_testing.md @@ -9,10 +9,10 @@ Test RC loss, data link loss, and low battery failsafes. - Verify RC Loss action is Return to Land - Verify Data Link Loss action is Return to Land and the timeout is 10 seconds - Verify Battery failsafe - - Action is Return to Land - - Battery Warn Level is 25% - - Battery Failsafe Level is 20% - - Battery Emergency Level is 15% + - Action is Return to Land + - Battery Warn Level is 25% + - Battery Failsafe Level is 20% + - Battery Emergency Level is 15% ## Flight Tests @@ -28,7 +28,6 @@ Test RC loss, data link loss, and low battery failsafes.     ❏ Disconnect telemetry, vehicle should return to home position after 10 seconds, wait for the descent and reconnect the telemetry radio - ❏ Battery Failsafe     ❏ Confirm the warning message is received in QGC diff --git a/docs/en/test_cards/mc_06_optical_flow.md b/docs/en/test_cards/mc_06_optical_flow.md index 8a7eb71211..22877115e6 100644 --- a/docs/en/test_cards/mc_06_optical_flow.md +++ b/docs/en/test_cards/mc_06_optical_flow.md @@ -2,25 +2,23 @@ ## Objective -To test that optical flow works as expected +Test that optical flow works as expected ## Preflight -Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation -([Setup Information here](../sensor/optical_flow.md)) +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation ([setup information here](../sensor/optical_flow.md)) -Ensure there are no other sources of positioning besides optical flow +Ensure there are no other sources of positioning besides optical flow: - [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` - [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` - [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` -- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` -Ensure that the drone can go into Altitude / Position flight mode while still on the ground +Ensure that the drone can go into Altitude / Position mode while still on the ground ## Flight Tests -❏ Altitude flight mode +❏ [Altitude mode](../flight_modes_mc/altitude.md)     ❏ Vertical position should hold current value with stick centered @@ -28,7 +26,7 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Throttle response set to climb/descent rate -❏ Position flight mode +❏ [Position mode](../flight_modes_mc/position.md)     ❏ Horizontal position should hold current value with stick centered @@ -38,6 +36,16 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates +❏ Varying height terrain + +    ❏ Put boxes on the ground to create varying heights in terrain + +    ❏ Take off in position mode and fly over the boxes such that the downward facing rangefinder varies in value + +    ❏ Do a few passes with varying amounts of time over the boxes (1-30 seconds if possible) + +    ❏ Drone should not raise in height when flying over boxes + ## Landing ❏ Land in either Position or Altitude mode with the throttle below 40% @@ -47,7 +55,8 @@ Ensure that the drone can go into Altitude / Position flight mode while still on ## Expected Results - Take-off should be smooth as throttle is raised -- Drone should hold altitude in Altitude Flight mode without wandering -- Drone should hold position within 1 meter in Position Flight mode without pilot moving sticks +- Drone should hold altitude in Altitude mode without wandering (over surface with many features) +- Drone should hold position within 1 meter in Position mode without pilot moving sticks - No oscillations should present in any of the above flight modes +- Drone should not raise in height when flying over boxes - Upon landing, copter should not bounce on the ground diff --git a/docs/en/test_cards/mc_07_optical_flow_low_mount.md b/docs/en/test_cards/mc_07_optical_flow_low_mount.md new file mode 100644 index 0000000000..73c06f4e4a --- /dev/null +++ b/docs/en/test_cards/mc_07_optical_flow_low_mount.md @@ -0,0 +1,45 @@ +# Test MC_07 - Optical Flow Low Sensor + +## Objective + +Test that optical flow works as expected with a low mounted optical flow sensor + +## Preflight + +Ensure that the drone's optical flow sensor is mounted more than an inch off of the ground + +Ensure that [MPC_THR_MIN](../advanced_config/parameter_reference.md#MPC_THR_MIN) is tuned correctly for landing + +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +([Setup Information here](../sensor/optical_flow.md)) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into [Position mode](../flight_modes_mc/position.md) while still on the ground + +## Flight Tests + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Landing + +❏ Land in Position mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Expected Results + +- Take-off should be smooth as throttle is raised +- Drone should stay in Position mode, NOT fall into [altitude](../flight_modes_mc/altitude.md) mode diff --git a/docs/en/test_cards/mc_08_dshot.md b/docs/en/test_cards/mc_08_dshot.md index 1ce413b34f..d2012aabd5 100644 --- a/docs/en/test_cards/mc_08_dshot.md +++ b/docs/en/test_cards/mc_08_dshot.md @@ -6,22 +6,22 @@ Regression test for DSHOT working with PX4 ## Preflight -- Ensure vehicle is using a DSHOT ESC. +- Ensure vehicle is using a DSHOT ESC - Parameter [DSHOT_BIDIR_EN](../advanced_config/parameter_reference.md#DSHOT_BIDIR_EN) is enabled - Parameter [DSHOT_TEL_CFG](../advanced_config/parameter_reference.md#DSHOT_TEL_CFG) is configured (if ESC supports telemetry) - Parameter [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) has Debug (`5`) checked ## Flight Tests -❏ Stabilized Flight mode +❏ [Stabilized mode](../flight_modes_mc/manual_stabilized.md) -    ❏ Takeoff in stabilized flight mode to ensure correct motor spin +    ❏ Takeoff in stabilized mode to ensure correct motor spin     ❏ Pitch/Roll/Yaw response 1:1     ❏ Throttle response 1:1 -❏ Position flight mode +❏ [Position mode](../flight_modes_mc/position.md)     ❏ Horizontal position should hold current value with stick centered @@ -41,6 +41,6 @@ Regression test for DSHOT working with PX4 - Download flight logs - Load into Data Plot Juggler -- Ensure data is logged for esc_status/esc.0x/esc_rpm +- Ensure data is logged for `esc_status`/`esc.0x`/`esc_rpm` ![Reference frames](../../assets/test_cards/dshot_log_output.png) diff --git a/docs/en/test_cards/mc_09_vio.md b/docs/en/test_cards/mc_09_vio.md new file mode 100644 index 0000000000..994fa9e4cf --- /dev/null +++ b/docs/en/test_cards/mc_09_vio.md @@ -0,0 +1,52 @@ +# Test MC_09 - VIO (Visual-Inertial Odometry) + +## Objective + +Test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Landing + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Expected Results + +- Take-off should be smooth as throttle is raised +- Drone should hold altitude in Altitude mode without wandering +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- No oscillations should present in any of the above flight modes +- Upon landing, copter should not bounce on the ground diff --git a/docs/en/test_cards/mc_10_optical_flow_gps_mixed.md b/docs/en/test_cards/mc_10_optical_flow_gps_mixed.md new file mode 100644 index 0000000000..740900f911 --- /dev/null +++ b/docs/en/test_cards/mc_10_optical_flow_gps_mixed.md @@ -0,0 +1,74 @@ +# Test MC_10 - Optical Flow / GPS Mixed + +## Objective + +Test that optical flow mixed with GPS works as expected + +## Preflight + +[Setup optical flow and GPS](../sensor/optical_flow.md) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `7` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `1` +- [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF): `1` (GPS) + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +❏ GPS Cutout + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Open QGC and navigate to MAVLink Console + +    ❏ Type `gps off` to disable GPS + +    ❏ Drone should maintain position hold via optical flow + +❏ GPS Degredation + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Fly under a metal surface (or other GPS blocking structure) + +    ❏ Ensure drone does not lose position hold or start drifting + +    ❏ Fly out of metal structure to regain GPS + +❏ GPS Acquisition + +    ❏ Takeoff in position mode in non-GPS environment + +    ❏ Fly into a GPS rich environment (outdoors) + +    ❏ Ensure drone acquires GPS position + +## Expected Results + +- Take-off should be smooth as throttle is raised +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- Drone should hold position in GPS rich environment as well as non-GPS environment +- No oscillations should present in any of the above flight modes diff --git a/docs/en/uart/user_configurable_serial_driver.md b/docs/en/uart/user_configurable_serial_driver.md index 9fbe168a66..3809ad25a6 100644 --- a/docs/en/uart/user_configurable_serial_driver.md +++ b/docs/en/uart/user_configurable_serial_driver.md @@ -24,7 +24,6 @@ where, To make driver configurable: 1. Create a YAML module configuration file: - - Add a new file in the driver's source directory named **module.yaml** - Insert the following text and adjust as needed: diff --git a/docs/en/uorb/uorb_documentation.md b/docs/en/uorb/uorb_documentation.md new file mode 100644 index 0000000000..a596014216 --- /dev/null +++ b/docs/en/uorb/uorb_documentation.md @@ -0,0 +1,170 @@ +# uORB Documentation Standard + +This topic demonstrates and explains how to document uORB messages. + +::: info +At time of writing many topics have not been updated. +::: + +## Overview + +The [AirspeedValidated](../msg_docs/AirspeedValidated.md) message shown below is a good example of a uORB topic that has been documented to the current standard. + +```py +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + +uint32 MESSAGE_VERSION = 1 + +uint64 timestamp # [us] Time since system start + +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) + +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed + +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch +``` + +The main things to note are: + +- Documentation is added using formatted uORB comments. + Any text on a line after the `#` character is a comment, except for lines that start with the text `# TOPIC` (which indicates a multi-topic message). +- The message starts with a comment block consisting of short description (mandatory), followed by a longer description and then a space. +- Field and constants almost all have comments. + The comments are added on the same line as the field/constant, separated by one space. +- Fields: + - Comments are all on the same line as the field (extra lines become internal comments). + - Comments start with metadata, such as the units (`[m/s]`, `[rad/s]`) or allowed values (`[@enum SOURCE]`), and can also list invalid values (`[@invalid NaN]`) and allowed ranges (`[@range min, max]`). + - Units are required except for boolean fields or for fields with an enum value. + `[-]` is used to indicate unitless fields. + - Comments follow the metadata after a space. + The line should not be terminated in a full stop. +- Constants: + - Don't have metadata: the description follows the comment marker after one space. + - Some constants, such as `MESSAGE_VERSION`, don't need documentation because they are standardized. + - Constants with the same name prefix are grouped together as enums after the associated field. + +The following sections expand on the allowed formats. + +## Message Description + +Every message should start with a comment block that describes the message: + +```py +# Short description (mandatory) +# +# Longer description for the message if needed. +# Can be multiline, and should have punctuation. +# Should be followed by an empty line. +``` + +This consists of a mandatory short description, optionally followed by an empty comment line, and then a longer description. + +Short description (mandatory): + +- A succinct explanation for the purpose of the message. +- Usually just one line without a terminating full stop. +- Minimally it may just mirror the message name. +- For example, [`AirspeedValidated`](../msg_docs/AirspeedValidated.md) above has the short description `Validated airspeed`. + +Long description (Optional): + +- Additional context required to understand how the message is used. +- In particular this should be anything that can't be inferred from the name, fields or constants, such as the publishers and expected consumers. + It might also cover whether the message is only used for a particular frame type or mode. +- The message is often multiline and contains punctuation. +- May include comment lines that are empty, in order to indicate paragraphs. + +Both short and long descriptions may be multi-line. +Single line descriptions should not include a terminating full stop, but multiline comments should do so. + +The message description block ends at the first non-comment line, which should be an empty line, but might be a field or constant. +Any subsequent comment lines are considered "internal comments". + +### Fields + +A typical field comment looks like this: + +```py +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +``` + +Field comments must all be on the same line as the field, and consist of optional metadata followed by a description: + +- `metadata` (Optional) + - Information about the field units and allowed values: + - `[]` + - The unit of measurement inside square brackets (note, no `@` delineator indicates a unit), such as `[m]` for metres. + - Allowed units include: `m`, `m/s`, `m/s^2`, `rad`, `rad/s`, `rpm`, `V`, `A`, `mA`, `mAh`, `W`, `dBm`, `s`, `ms`, `us`, `Ohm`, `MB`, `Kb/s`, `degC`, `Pa`. + - Units are required unless clearly invalid, such as when the field is a boolean, or is an enum value. + - Unitless values should be specified as `[-]`. + Note though that units are not required for boolean fields or enum fields. + - `[@enum ]` + - The `enum_name` gives the prefix of constant values in the message that can be assigned to the field. + Note that enums in uORB are just a naming convention: they are not explicitly declared. + Multiple enum names allowed for a field indicates a possible error in the field design. + - `[@range , ]` + - The allowed range of the field, specified as a `lower_value` and/or an `upper_value`. + Either value can be omitted to indicate an unbounded upper or lower value. + For example `[@range 0, 3]`, `[@range 5.3, ]`, `[@range , 3]`. + - `[@invalid ]` + - The `value` to set the field to indicate that the field doesn't contain valid data, such as `[@invalid NaN]`. + The `description` is optional, and might be used to indicate the conditions under which data is invalid. + - `[@frame ]` + - The `frame` in which the field is set, such as `[@frame NED]` or `[@frame Body]`. +- `description` + - A concise description of the purpose of the field, and including any important information that can't be inferred from the name! + Use a capital first letter, and omit the full stop if the description is a single sentence. + Multiple sentences may also omit the final full stop. + +### Constants + +Constants follow the documentation conventions as fields except they only have a description (no metadata). +Documentation for a constant might look like this: + +```py +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +``` + +Constants are often grouped together following a field as enum values. +Note below how the prefix `SOURCE` for the values is specified as an enum against the _field_. + +```py +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +... +``` + +A small number of constants have a standardised meaning and do not require documentation. +These are: + +- `ORB_QUEUE_LENGTH` +- `MESSAGE_VERSION` + +### `# TOPICS` + +The prefix `# TOPICS` is used to indicate topic names for multi-topic messages. +For example, the [VehicleGlobalPosition.msg](../msg_docs/VehicleGlobalPosition.md) message definition is used to define the topic ids as shown: + +```text +# TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position +# TOPICS estimator_global_position +# TOPICS aux_global_position +``` + +At time of writing there is no format for documenting these. diff --git a/docs/en/vtx/index.md b/docs/en/vtx/index.md new file mode 100644 index 0000000000..b94dd8fdb8 --- /dev/null +++ b/docs/en/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## Getting Started + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Parameters: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Configuration Parameters + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). diff --git a/docs/index.md b/docs/index.md index 20f2371f3e..6ac4d4ab85 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,9 +4,9 @@ layout: home hero: name: "PX4" - text: "User Guide" - tagline: PX4 is the Open Source Autopilot for Professional Drone Developers. - image: /logo_pro_small.png + text: "Autopilot" + tagline: Open-source flight stack for drones and autonomous vehicles. BSD-3 licensed. Vendor neutral. + image: /px4-logo.svg actions: - theme: brand text: Read the docs @@ -20,22 +20,21 @@ hero: features: - title: Modular Architecture - details: PX4 is highly modular and extensible both in terms of hardware and software. It utilizes a port-based architecture - which means when developers add components, the extended system does not lose robustness or performance. - - title: Open Source - details: PX4 is co-developed with a global development community. The flightstack is not just fulfilling the needs of one lab or one company, but has been intended as a general toolkit and is widely used and adopted in the industry. - - title: Configurability - details: PX4 offers optimised APIs and SDKs for developers working with integrations. All the modules are self-contained and can be easily exchanged against a different module without modifying the core. Features are easy to deploy and reconfigure. - - title: Autonomy Stack - details: PX4 is designed to be deeply coupled with embedded computer vision for autonomous capabilities . The framework lowers the barrier of entry for developers working on localization and obstacle detection algorithms. - - title: Real-world Validation - details: Thousands of commercial PX4 based systems have been deployed worldwide. In parallel, dedicated flight test team clocking up thousands of flight hours each month running hardware and software tests to ensure the codebase's safety and reliability. + details: Built on uORB, a DDS-compatible publish/subscribe middleware. Every module runs as its own thread, fully parallelized and thread safe. Build custom configurations and strip out what you don't need. + - title: Wide Hardware Support + details: Supports Pixhawk-standard flight controllers and a growing range of boards beyond that standard. DroneCAN peripherals run PX4 firmware in CAN node mode. No vendor lock-in. + - title: Developer Friendly + details: First-class MAVLink and DDS/ROS 2 integration. Comprehensive SITL simulation, hardware-in-the-loop testing, and log analysis tools. MAVSDK provides a high-level SDK/API for programmatic vehicle interaction. + - title: Autonomy Ready + details: Extensible architecture for advanced autonomy. External modes, offboard control, and DDS/ROS 2 interfaces provide the building blocks for computer vision, GPS-denied navigation, and custom flight behaviors. + - title: Proven at Scale + details: Millions of vehicles deployed worldwide across commercial, defense, and research applications. Continuous flight testing validates the codebase across multirotors, fixed-wing, VTOL, helicopters, rovers, and more. - title: Permissive License - details: PX4 is free to use and modify under the terms of the permissive BSD 3-clause license. Which means the software also allows proprietary use and allows the releases under the license to be incorporated into proprietary products. + details: BSD 3-Clause. Use it, modify it, ship it in proprietary products. You only need to include the original copyright notice and license text. - title: Interoperability - details: Beyond being a robust flight stack, PX4 offers an ecosystem of supported devices. The project also leads the standardarization effort for the advancement of communications, peripherals integration, and power management solutions. - - - title: Powerful Safety Features - details: Great safety features including automated failsafe behaviour, support for different return modes, parachutes etc. are by default already included in the codebase. The features are easily configurable and tunable for custom systems. + details: Part of a modular ecosystem. PX4 (autopilot), MAVLink (protocol), QGroundControl (ground station), Pixhawk (hardware standard), MAVSDK (SDK/API), and ROS 2 via DDS or Zenoh. All Dronecode projects, all open source. + - title: Vendor Neutral Governance + details: Hosted by the Dronecode Foundation under the Linux Foundation. No single company owns the name or controls the roadmap. Community-driven with a weekly open dev call. search: false footer: BSD 3-clause license diff --git a/docs/ko/SUMMARY.md b/docs/ko/SUMMARY.md index 59604e5db7..844175e86c 100644 --- a/docs/ko/SUMMARY.md +++ b/docs/ko/SUMMARY.md @@ -7,6 +7,7 @@ - [위치 모드 (멀티콥터)](flight_modes_mc/position.md) - [Position Slow Mode (MC)](flight_modes_mc/position_slow.md) - [고도 모드 (멀티콥터)](flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](flight_modes_mc/manual_stabilized.md) - [아크로 모드 (멀티콥터)](flight_modes_mc/acro.md) - [궤도 모드 (멀티콥터)](flight_modes_mc/orbit.md) @@ -34,7 +35,7 @@ - [정압 축적](advanced_config/static_pressure_buildup.md) - [Flying (Basics)](flying/basic_flying_mc.md) - [완성 기체](complete_vehicles_mc/index.md) - - [ModalAI Starling (PX4 Dev Kit)](complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling](complete_vehicles_mc/modalai_starling.md) - [PX4 비전 키트](complete_vehicles_mc/px4_vision_kit.md) - [마인드레이서 BNF & RTF](complete_vehicles_mc/mindracer_BNF_RTF.md) - [마인드레이서 210](complete_vehicles_mc/mindracer210.md) @@ -55,11 +56,14 @@ - [DJI F450 (CUAV v5 nano)](frames_multicopter/dji_f450_cuav_5nano.md) - [Planes (Fixed-Wing)](frames_plane/index.md) + - [Features](features_fw/index.md) + - [Gain compression](features_fw/gain_compression.md) - [Assembly](assembly/assembly_fw.md) - [Config/Tuning](config_fw/index.md) - [Auto-tune](config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](flying/basic_flying_fw.md) @@ -89,6 +93,7 @@ - [후방 이동 튜닝](config_vtol/vtol_back_transition_tuning.md) - [항속 센서 미장착 VTOL](config_vtol/vtol_without_airspeed_sensor.md) - [VTOL 날씨 풍향](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [비행 모드 ](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -124,6 +129,7 @@ - [LED 신호 정의](getting_started/led_meanings.md) - [알람 소리 정의](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Hardware Selection & Setup](hardware/drone_parts.md) - [비행 컨트롤러 (오토파일럿)](flight_controller/index.md) @@ -157,6 +163,7 @@ - [mRo (3DR) Pixhawk 배선 퀵 스타트](assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](flight_controller/mindpx.md) - [AirMind MindRacer](flight_controller/mindracer.md) - [ARK Electronics ARKV6X](flight_controller/ark_v6x.md) @@ -180,12 +187,16 @@ - [Wiring Quickstart](assembly/quick_start_durandal.md) - [Holybro Pix32 v5](flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](assembly/quick_start_holybro_pix32_v5.md) + - [MicoAir H743 Lite](flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](flight_controller/modalai_voxl_2.md) - [mRo Control Zero F7](flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](flight_controller/spracingh7extreme.md) + - [SVehicle E2](flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](flight_controller/thepeach_r1.md) + - [AP-H743-R1](flight_controller/x-mav_ap-h743r1.md) - [Experimental Autopilots](flight_controller/autopilot_experimental.md) - [BeagleBone Blue](flight_controller/beaglebone_blue.md) - [Raspberry Pi 2/3 Navio2](flight_controller/raspberry_pi_navio2.md) @@ -238,18 +249,22 @@ - [TFSlot Airspeed Sensor](sensor/airspeed_tfslot.md) - [Barometers](sensor/barometer.md) - [거리 센서](sensor/rangefinders.md) + - [Ainstein US-D1 Standard Radar Altimeter](sensor/ulanding_radar.md) + - [ARK DIST SR (CAN/UART)](dronecan/ark_dist.md) + - [ARK DIST MR (CAN/UART)](dronecan/ark_dist_mr.md) + - [Benewake TFmini 라이다](sensor/tfmini.md) + - [LeddarOne 라이다](sensor/leddar_one.md) + - [Lidar-Lite](sensor/lidar_lite.md) - [Lightware Lidars (SF/LW)](sensor/sfxx_lidar.md) - [Lightware SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md) - - [Ainstein US-D1 Standard Radar Altimeter](sensor/ulanding_radar.md) - - [LeddarOne 라이다](sensor/leddar_one.md) - - [Benewake TFmini 라이다](sensor/tfmini.md) - - [Lidar-Lite](sensor/lidar_lite.md) - [TeraRanger ](sensor/teraranger.md) - [✘ Lanbao PSK-CM8JL65-CC5](sensor/cm8jl65_ir_distance_sensor.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface (CAN)](dronecan/avanon_laser_interface.md) - [GNSS (GPS)](gps_compass/index.md) - [ARK GPS (CAN)](dronecan/ark_gps.md) + - [ARK DAN GPS](gps_compass/ark_dan_gps.md) - [ARK SAM GPS](gps_compass/ark_sam_gps.md) + - [ARK SAM GPS MINI](gps_compass/ark_sam_gps_mini.md) - [ARK TESEO GPS](dronecan/ark_teseo_gps.md) - [CUAV NEO 3 GPS](gps_compass/gps_cuav_neo_3.md) - [CUAV NEO 3 Pro GPS (CAN)](gps_compass/gps_cuav_neo_3pro.md) @@ -260,7 +275,11 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) + - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) + - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) - [ARK MOSAIC-X5 RTK GPS (CAN)](dronecan/ark_mosaic__rtk_gps.md) - [RTK GPS Heading with Dual u-blox F9P](gps_compass/u-blox_f9p_heading.md) - [CUAV C-RTK](gps_compass/rtk_gps_cuav_c-rtk.md) @@ -283,6 +302,8 @@ - [CubePilot Here+ (Discontined)](gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](sensor/inertial_navigation_systems.md) - [InertialLabs](sensor/inertiallabs.md) + - [MicroStrain](sensor/microstrain.md) + - [sbgECom](sensor/sbgecom.md) - [VectorNav](sensor/vectornav.md) - [광류 센서](sensor/optical_flow.md) - [ARK Flow](dronecan/ark_flow.md) @@ -298,15 +319,17 @@ - [ADSB/FLARM (트래픽 회피)](config/actuators.md) - [ESC 보정](advanced_config/esc_calibration.md) - [ESC와 모터](peripherals/esc_motors.md) + - [ESC Protocols](esc/esc_protocols.md) - [PWM ESC와 서보](peripherals/pwm_escs_and_servo.md) - [DShot ESCs](peripherals/dshot.md) - [OneShot ESCs and Servos](peripherals/oneshot.md) - [DroneCAN ESCs](dronecan/escs.md) - - [Zubax Telega](dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](dronecan/sapog.md) - - [Holybro Kotleta](dronecan/holybro_kotleta.md) - - [Vertiq](peripherals/vertiq.md) - - [VESC](peripherals/vesc.md) + - [ARK 4IN1 ESC](esc/ark_4in1_esc.md) + - [Holybro Kotleta](dronecan/holybro_kotleta.md) + - [Vertiq Motor/ESC Modules](peripherals/vertiq.md) + - [VESC Project ESCs](peripherals/vesc.md) + - [Zubax Telega ESCs](dronecan/zubax_telega.md) - [Radio Control (RC)](getting_started/rc_transmitter_receiver.md) - [무선 조종기 설정](config/radio.md) @@ -339,17 +362,20 @@ - [Satellite Comms (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) + - [Power Systems](power_systems/index.md) - [Battery Estimation Tuning](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) - [Power Modules/PDB](power_module/index.md) + - [ARK PAB Power Module](power_module/ark_pab_power_module.md) + - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](power_module/ark_12s_payload_power_module.md) - [CUAV HV 전원 모듈](power_module/cuav_hv_pm.md) - [CUAV CAN 전원 모듈](dronecan/cuav_can_pmu.md) - [Holybro PM02](power_module/holybro_pm02.md) - [Holybro PM07](power_module/holybro_pm07_pixhawk4_power_module.md) - [Holybro PM06 V2](power_module/holybro_pm06_pixhawk4mini_power_module.md) - - [ARK PAB Power Module](power_module/ark_pab_power_module.md) - - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) - [Holybro PM02D (digital)](power_module/holybro_pm02d.md) - [Holybro PM03D (digital)](power_module/holybro_pm03d.md) - [Pomegranate Systems Power Module](dronecan/pomegranate_systems_pm.md) @@ -432,6 +458,7 @@ - [Attitude Tuning](config_rover/attitude_tuning.md) - [Velocity Tuning](config_rover/velocity_tuning.md) - [Position Tuning](config_rover/position_tuning.md) + - [Apps & API](flight_modes_rover/api.md) - [Complete Vehicles](complete_vehicles_rover/index.md) - [Aion Robotics R1](complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](frames_sub/index.md) @@ -497,8 +524,10 @@ - [UART/Serial 포트](uart/index.md) - [포트 설정 가능 시리얼 드라이버](uart/user_configurable_serial_driver.md) - [RTK GPS (통합)](advanced/rtk_gps.md) + - [PPS Time Synchronization](advanced/pps_time_sync.md) - [미들웨어](middleware/index.md) - [uORB 메시지 전송](middleware/uorb.md) + - [uORB Docs Standard](uorb/uorb_documentation.md) - [uORB 그라프](middleware/uorb_graph.md) - [uORB Message Reference](msg_docs/index.md) - [Versioned](msg_docs/versioned_messages.md) @@ -561,6 +590,7 @@ - [DebugKeyValue](msg_docs/DebugKeyValue.md) - [DebugValue](msg_docs/DebugValue.md) - [DebugVect](msg_docs/DebugVect.md) + - [DeviceInformation](msg_docs/DeviceInformation.md) - [DifferentialPressure](msg_docs/DifferentialPressure.md) - [DistanceSensor](msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](msg_docs/DistanceSensorModeChangeRequest.md) @@ -593,6 +623,7 @@ - [FollowTargetEstimator](msg_docs/FollowTargetEstimator.md) - [FollowTargetStatus](msg_docs/FollowTargetStatus.md) - [FuelTankStatus](msg_docs/FuelTankStatus.md) + - [GainCompression](msg_docs/GainCompression.md) - [GeneratorStatus](msg_docs/GeneratorStatus.md) - [GeofenceResult](msg_docs/GeofenceResult.md) - [GeofenceStatus](msg_docs/GeofenceStatus.md) @@ -679,10 +710,10 @@ - [RoverPositionSetpoint](msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](msg_docs/RoverVelocityStatus.md) - [Rpm](msg_docs/Rpm.md) - [RtlStatus](msg_docs/RtlStatus.md) - [RtlTimeEstimate](msg_docs/RtlTimeEstimate.md) @@ -694,6 +725,7 @@ - [SensorCombined](msg_docs/SensorCombined.md) - [SensorCorrection](msg_docs/SensorCorrection.md) - [SensorGnssRelative](msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](msg_docs/SensorGnssStatus.md) - [SensorGps](msg_docs/SensorGps.md) - [SensorGyro](msg_docs/SensorGyro.md) - [SensorGyroFft](msg_docs/SensorGyroFft.md) @@ -703,6 +735,7 @@ - [SensorOpticalFlow](msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](msg_docs/SensorPreflightMag.md) - [SensorSelection](msg_docs/SensorSelection.md) + - [SensorTemp](msg_docs/SensorTemp.md) - [SensorUwb](msg_docs/SensorUwb.md) - [SensorsStatus](msg_docs/SensorsStatus.md) - [SensorsStatusImu](msg_docs/SensorsStatusImu.md) @@ -739,9 +772,13 @@ - [YawEstimatorStatus](msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](msg_docs/AirspeedValidatedV0.md) - [ArmingCheckReplyV0](msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](msg_docs/ArmingCheckRequestV0.md) - [BatteryStatusV0](msg_docs/BatteryStatusV0.md) + - [ConfigOverridesV0](msg_docs/ConfigOverridesV0.md) - [EventV0](msg_docs/EventV0.md) - [HomePositionV0](msg_docs/HomePositionV0.md) + - [RegisterExtComponentReplyV0](msg_docs/RegisterExtComponentReplyV0.md) + - [RegisterExtComponentRequestV0](msg_docs/RegisterExtComponentRequestV0.md) - [VehicleAttitudeSetpointV0](msg_docs/VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](msg_docs/VehicleStatusV0.md) @@ -754,6 +791,7 @@ - [Standard Modes Protocol](mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](middleware/uxrce_dds.md) - [UORB Bridged to ROS 2](middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](middleware/zenoh.md) - [모듈과 명령어](modules/modules_main.md) - [자동 튜닝](modules/modules_autotune.md) - [명령어](modules/modules_command.md) @@ -771,6 +809,7 @@ - [Rpm Sensor](modules/modules_driver_rpm_sensor.md) - [Radio Control](modules/modules_driver_radio_control.md) - [Transponder](modules/modules_driver_transponder.md) + - [adc](modules/modules_driver_adc.md) - [추정기](modules/modules_estimator.md) - [시뮬레이션](modules/modules_simulation.md) - [시스템](modules/modules_system.md) @@ -807,9 +846,11 @@ - [Camera Integration/Architecture](camera/camera_architecture.md) - [컴퓨터 비전](advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [Intel RealSense R200용 드라이버 설치](advanced/realsense_intel_driver.md) - [상태 추정기 전환](advanced/switching_state_estimators.md) - [트리 외부 모듈](advanced/out_of_tree_modules.md) @@ -843,6 +884,10 @@ - [시험 MC_04 - 안전 장치 시험](test_cards/mc_04_failsafe_testing.md) - [Test MC_05 - Manual Modes (Inside)](test_cards/mc_05_indoor_flight_manual_modes.md) - [Test MC_06 - Optical Flow (Inside)](test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](test_cards/mc_10_optical_flow_gps_mixed.md) - [단위 테스트](test_and_ci/unit_tests.md) - [Fuzz Tests](test_and_ci/fuzz_tests.md) - [지속 통합](test_and_ci/continous_integration.md) @@ -863,6 +908,7 @@ - [PX4 ROS 2 Interface Library](ros2/px4_ros2_interface_lib.md) - [Control Interface](ros2/px4_ros2_control_interface.md) - [Navigation Interface](ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](ros/ros1.md) - [ROS/MAVROS 설치 가이드](ros/mavros_installation.md) @@ -887,6 +933,7 @@ - [출시](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/ko/_sidebar.md b/docs/ko/_sidebar.md index 79834ec3ad..d0d8d7b773 100644 --- a/docs/ko/_sidebar.md +++ b/docs/ko/_sidebar.md @@ -1,15 +1,14 @@ - [Introduction](/index.md) - - [기본 개념](/getting_started/px4_basic_concepts.md) - [멀티콥터](/frames_multicopter/index.md) - - [Features](/features_mc/index.md) - [비행 모드 ](/flight_modes_mc/index.md) - [위치 모드 (멀티콥터)](/flight_modes_mc/position.md) - [Position Slow Mode (MC)](/flight_modes_mc/position_slow.md) - [고도 모드 (멀티콥터)](/flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](/flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](/flight_modes_mc/manual_stabilized.md) - [아크로 모드 (멀티콥터)](/flight_modes_mc/acro.md) - [궤도 모드 (멀티콥터)](/flight_modes_mc/orbit.md) @@ -37,7 +36,7 @@ - [정압 축적](/advanced_config/static_pressure_buildup.md) - [Flying (Basics)](/flying/basic_flying_mc.md) - [완성 기체](/complete_vehicles_mc/index.md) - - [ModalAI Starling](/complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling (PX4 Dev Kit)](/complete_vehicles_mc/modalai_starling.md) - [PX4 비전 키트](/complete_vehicles_mc/px4_vision_kit.md) - [마인드레이서 BNF & RTF](/complete_vehicles_mc/mindracer_BNF_RTF.md) - [마인드레이서 210](/complete_vehicles_mc/mindracer210.md) @@ -58,12 +57,14 @@ - [DJI F450 (CUAV v5 nano)](/frames_multicopter/dji_f450_cuav_5nano.md) - [Planes (Fixed-Wing)](/frames_plane/index.md) - + - [Features](/features_fw/index.md) + - [Gain compression](/features_fw/gain_compression.md) - [Assembly](/assembly/assembly_fw.md) - [Config/Tuning](/config_fw/index.md) - [Auto-tune](/config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](/config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](/config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](/config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](/config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](/config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](/flying/basic_flying_fw.md) @@ -86,7 +87,6 @@ - [Wing Wing Z84 (Pixracer)](/frames_plane/wing_wing_z84.md) - [수직이착륙기(VTOL)](/frames_vtol/index.md) - - [Assembly](/assembly/assembly_vtol.md) - [VTOL 설정 및 튜닝](/config_vtol/index.md) - [Auto-tune](/config/autotune_vtol.md) @@ -111,7 +111,6 @@ - [Complete Vehicles](/complete_vehicles_vtol/index.md) - [Operations](/config/operations.md) - - [안전 설정](/config/safety_intro.md) - [Safety Configuration (Failsafes)](/config/safety.md) - [Failsafe Simulation](/config/safety_simulation.md) @@ -132,7 +131,6 @@ - [QGroundControl Flight-Readiness Status](/flying/pre_flight_checks.md) - [Hardware Selection & Setup](/hardware/drone_parts.md) - - [비행 컨트롤러 (오토파일럿)](/flight_controller/index.md) - [Flight Controller Selection](/getting_started/flight_controller_selection.md) - [Pixhawk Series](/flight_controller/pixhawk_series.md) @@ -164,18 +162,18 @@ - [mRo (3DR) Pixhawk 배선 퀵 스타트](/assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](/flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](/flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](/flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](/flight_controller/mindpx.md) - [AirMind MindRacer](/flight_controller/mindracer.md) - [ARK Electronics ARKV6X](/flight_controller/ark_v6x.md) - [ARK FPV Flight Controller](/flight_controller/ark_fpv.md) - [ARK Pi6X Flow Flight Controller](/flight_controller/ark_pi6x.md) - - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV Nora](/flight_controller/cuav_nora.md) - [CUAV V5+ (FMUv5)](/flight_controller/cuav_v5_plus.md) - [Wiring Quickstart](/assembly/quick_start_cuav_v5_plus.md) - [CUAV V5 nano (FMUv5)](/flight_controller/cuav_v5_nano.md) - [CUAV V5 nano 배선 퀵 스타트](/assembly/quick_start_cuav_v5_nano.md) - - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) + - [CUAV X25 EVO](/flight_controller/cuav_x25-evo.md) - [CubePilot Cube Orange+ (CubePilot)](/flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange (CubePilot)](/flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](/flight_controller/cubepilot_cube_yellow.md) @@ -188,13 +186,13 @@ - [Wiring Quickstart](/assembly/quick_start_durandal.md) - [Holybro Pix32 v5](/flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](/assembly/quick_start_holybro_pix32_v5.md) - - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) - - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [MicoAir H743 Lite](/flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](/flight_controller/modalai_voxl_2.md) - - [mRobotics-X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - - [mRo Control Zero F7)](/flight_controller/mro_control_zero_f7.md) + - [mRo Control Zero F7](/flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](/flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](/flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](/flight_controller/spracingh7extreme.md) + - [SVehicle E2](/flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](/flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](/flight_controller/thepeach_r1.md) - [Experimental Autopilots](/flight_controller/autopilot_experimental.md) @@ -206,18 +204,20 @@ - [Discontinued Autopilots/Vehicles](/flight_controller/autopilot_discontinued.md) - [Drotek Dropix (FMUv2)](/flight_controller/dropix.md) - [Omnibus F4 SD](/flight_controller/omnibus_f4_sd.md) - - [BetaFPV Beta75X 2S Brushless Whoop](/complete_vehicles_mc/betafpv_beta75x.md) - [Bitcraze Crazyflie 2.0 ](/complete_vehicles_mc/crazyflie2.md) - [Aerotenna OcPoC-Zynq Mini](/flight_controller/ocpoc_zynq.md) + - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV v5](/flight_controller/cuav_v5.md) + - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) - [Holybro Kakute F7](/flight_controller/kakutef7.md) - [Holybro Pixfalcon](/flight_controller/pixfalcon.md) - [Holybro pix32 (FMUv2)](/flight_controller/holybro_pix32.md) + - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) + - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [mRo X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - [mRo AUAV-X2](/flight_controller/auav_x2.md) - [NXP RDDRONE-FMUK66 FMU](/flight_controller/nxp_rddrone_fmuk66.md) - [3DR Pixhawk 1](/flight_controller/pixhawk.md) - - [Snapdragon Flight](/flight_controller/snapdragon_flight.md) - - [Intel® Aero RTF Drone](/complete_vehicles_mc/intel_aero.md) - [Pixhawk Autopilot Bus (PAB) & Carriers](/flight_controller/pixhawk_autopilot_bus.md) - [ARK Electronics Pixhawk Autopilot Bus Carrier](/flight_controller/ark_pab.md) - [Mounting the Flight Controller](/assembly/mount_and_orient_controller.md) @@ -229,7 +229,9 @@ - [Bootloader Update](/advanced_config/bootloader_update.md) - [Bootloader Update FMUv6X-RT via USB](/advanced_config/bootloader_update_v6xrt.md) - [Bootloader Flashing onto Betaflight Systems](/advanced_config/bootloader_update_from_betaflight.md) + - [Airframe Selection](/config/airframe.md) + - [센서](/sensor/index.md) - [가속도계](/sensor/accelerometer.md) - [Calibration](/config/accelerometer.md) @@ -241,6 +243,7 @@ - [나침반 전력 보정](/advanced_config/compass_power_compensation.md) - [항속 센서](/sensor/airspeed.md) - [Calibration](/config/airspeed.md) + - [Airspeed Validation](/advanced_config/airspeed_validation.md) - [TFSlot Airspeed Sensor](/sensor/airspeed_tfslot.md) - [Barometers](/sensor/barometer.md) - [거리 센서](/sensor/rangefinders.md) @@ -272,6 +275,7 @@ - [CUAV C-RTK](/gps_compass/rtk_gps_cuav_c-rtk.md) - [CUAV C-RTK2 PPK/RTK GNSS](/gps_compass/rtk_gps_cuav_c-rtk2.md) - [CUAV C-RTK 9Ps](/gps_compass/rtk_gps_cuav_c-rtk-9ps.md) + - [DATAGNSS NANO HRTK GNSS](/gps_compass/rtk_gps_datagnss_nano_hrtk.md) - [DATAGNSS GEM1305 RTK GNSS](/gps_compass/rtk_gps_gem1305.md) - [Femtones MINI2 Receiver](/gps_compass/rtk_gps_fem_mini2.md) - [Freefly RTK GPS](/gps_compass/rtk_gps_freefly.md) @@ -287,6 +291,9 @@ - [Trimble MB-Two](/gps_compass/rtk_gps_trimble_mb_two.md) - [CubePilot Here+ (Discontined)](/gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](/sensor/inertial_navigation_systems.md) + - [InertialLabs](/sensor/inertiallabs.md) + - [MicroStrain](/sensor/microstrain.md) + - [sbgECom](/sensor/sbgecom.md) - [VectorNav](/sensor/vectornav.md) - [광류 센서](/sensor/optical_flow.md) - [ARK Flow](/dronecan/ark_flow.md) @@ -297,6 +304,7 @@ - [ThunderFly TFRPM01 타코미터 센서](/sensor/thunderfly_tachometer.md) - [IMU Factory Calibration](/advanced_config/imu_factory_calibration.md) - [센서 온도 보정](/advanced_config/sensor_thermal_calibration.md) + - [액츄에이터](/actuators/index.md) - [ADSB/FLARM (트래픽 회피)](/config/actuators.md) - [ESC 보정](/advanced_config/esc_calibration.md) @@ -308,19 +316,22 @@ - [Zubax Telega](/dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](/dronecan/sapog.md) - [Holybro Kotleta](/dronecan/holybro_kotleta.md) - - [Zubax Orel](/dronecan/zubax_orel.md) - [Vertiq](/peripherals/vertiq.md) - [VESC](/peripherals/vesc.md) + - [Radio Control (RC)](/getting_started/rc_transmitter_receiver.md) - [무선 조종기 설정](/config/radio.md) - [비행 모드](/config/flight_mode.md) + - [Joysticks](/config/joystick.md) + - [Data Links](/data_links/index.md) - [MAVLink 텔레메트리(OSD/GCS) ](/peripherals/mavlink_peripherals.md) - [텔레메트리 무선통신](/telemetry/index.md) - [SiK 무선통신](/telemetry/sik_radio.md) - [RFD900 (SiK) 텔레메트리](/telemetry/rfd900_telemetry.md) + - [ThunderFly TFSIK01 Telemetry Radio](/telemetry/tfsik_telemetry.md) - [HolyBro (SIK) Telemetry Radio](/telemetry/holybro_sik_radio.md) - [Wifi 텔레메트리](/telemetry/telemetry_wifi.md) - [ESP8266 WiFi 모듈](/telemetry/esp8266_wifi_module.md) @@ -338,6 +349,7 @@ - [TBS Crossfire (CRSF) Telemetry](/telemetry/crsf_telemetry.md) - [Satellite Comms (Iridium/RockBlock)](/advanced_features/satcom_roadblock.md) + - [Power Systems](/power_systems/index.md) - [Battery Estimation Tuning](/config/battery.md) - [Battery Chemistry Overview](/power_systems/battery_chemistry.md) @@ -356,6 +368,7 @@ - [Sky-Drones SmartAP PDB](/power_module/sky-drones_smartap-pdb.md) - [Smart/MAVLink Batteries](/smart_batteries/index.md) - [Rotoye Batmon 배터리 스마트 키트](/smart_batteries/rotoye_batmon.md) + - [탑재중량과 카메라](/payloads/index.md) - [Use Cases](/payloads/use_cases.md) - [Package Delivery Mission](/flying/package_delivery_mission.md) @@ -367,19 +380,25 @@ - [Gimbal \(Mount\) Configuration](/advanced/gimbal_control.md) - [Grippers](/peripherals/gripper.md) - [Servo Gripper](/peripherals/gripper_servo.md) + - [Peripherals](/peripherals/index.md) - [ADSB/FLARM/UTM (Traffic Avoidance)](/peripherals/adsb_flarm.md) - [낙하산](/peripherals/parachute.md) - [Remote ID](/peripherals/remote_id.md) + - [I2C Peripherals](/sensor_bus/i2c_general.md) - [I2C bus accelerators](/sensor_bus/i2c_general.md#i2c-bus-accelerators) - [TFI2CADT01 I2C address translator](/sensor_bus/translator_tfi2cadt.md) + - [CAN Peripherals](/can/index.md) + - [DroneCAN Peripherals](/dronecan/index.md) - [PX4 DroneCAN Firmware](/dronecan/px4_cannode_fw.md) - [ARK CANnode](/dronecan/ark_cannode.md) - [RaccoonLab CAN Nodes](/dronecan/raccoonlab_nodes.md) + - [배선 개요](/assembly/cable_wiring.md) + - [보조 컴퓨터](/companion_computer/index.md) - [Pixhawk + Companion Setup](/companion_computer/pixhawk_companion.md) - [RPi Pixhawk Companion](/companion_computer/pixhawk_rpi.md) @@ -395,16 +414,19 @@ - [리얼센스 T265 트래킹 카메라 (VIO)](/camera/camera_intel_realsense_t265_vio.md) - [동영상 스트리밍](/companion_computer/video_streaming.md) - [Video Streaming using WFB-ng Wifi (Long range)](/companion_computer/video_streaming_wfb_ng_wifi.md) + - [직렬 포트 설정 ](/peripherals/serial_configuration.md) + - [PX4 이더넷 설정](/advanced_config/ethernet_setup.md) + - [Standard Configuration](/config/index.md) + - [고급 설정](/advanced_config/index.md) - [Using PX4's Navigation Filter (EKF2)](/advanced_config/tuning_the_ecl_ekf.md) - [매개변수 검색 및 수정](/advanced_config/parameters.md) - [전체 매개변수 정의서](/advanced_config/parameter_reference.md) - [Other Vehicles](/airframes/index.md) - - [Airships (experimental)](/frames_airship/index.md) - [Autogyros (experimental)](/frames_autogyro/index.md) - [선더플라이 Auto-G2 (Holybro pix32)](/frames_autogyro/thunderfly_auto_g2.md) @@ -412,17 +434,18 @@ - [Helicopter (experimental)](/frames_helicopter/index.md) - [Helicopter Config/Tuning](/config_heli/index.md) - [Rovers (experimental)](/frames_rover/index.md) - - [Ackermann Rovers](/frames_rover/ackermann.md) - - [Drive Modes](/flight_modes_rover/ackermann.md) - - [Configuration/Tuning](/config_rover/ackermann.md) - - [Differential Rovers](/frames_rover/differential.md) - - [Drive Modes](/flight_modes_rover/differential.md) - - [Configuration/Tuning](/config_rover/differential.md) - - [Aion Robotics R1](/frames_rover/aion_r1.md) - - [Mecanum Rovers](/frames_rover/mecanum.md) - - [Drive Modes](/flight_modes_rover/mecanum.md) - - [Configuration/Tuning](/config_rover/mecanum.md) - - [(Deprecated) Rover Position Control](/frames_rover/rover_position_control.md) + - [Drive Modes](/flight_modes_rover/index.md) + - [Manual](/flight_modes_rover/manual.md) + - [Auto](/flight_modes_rover/auto.md) + - [Configuration/Tuning](/config_rover/index.md) + - [Basic Setup](/config_rover/basic_setup.md) + - [Rate Tuning](/config_rover/rate_tuning.md) + - [Attitude Tuning](/config_rover/attitude_tuning.md) + - [Velocity Tuning](/config_rover/velocity_tuning.md) + - [Position Tuning](/config_rover/position_tuning.md) + - [Apps & API](/flight_modes_rover/api.md) + - [Complete Vehicles](/complete_vehicles_rover/index.md) + - [Aion Robotics R1](/complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](/frames_sub/index.md) - [블루로브2](/frames_sub/bluerov2.md) - [기체 프레임 정의서](/airframes/airframe_reference.md) @@ -486,6 +509,7 @@ - [UART/Serial 포트](/uart/index.md) - [포트 설정 가능 시리얼 드라이버](/uart/user_configurable_serial_driver.md) - [RTK GPS (통합)](/advanced/rtk_gps.md) + - [PPS Time Synchronization](/advanced/pps_time_sync.md) - [미들웨어](/middleware/index.md) - [uORB 메시지 전송](/middleware/uorb.md) - [uORB 그라프](/middleware/uorb_graph.md) @@ -534,6 +558,7 @@ - [Airspeed](/msg_docs/Airspeed.md) - [AirspeedWind](/msg_docs/AirspeedWind.md) - [AutotuneAttitudeControlStatus](/msg_docs/AutotuneAttitudeControlStatus.md) + - [BatteryInfo](/msg_docs/BatteryInfo.md) - [ButtonEvent](/msg_docs/ButtonEvent.md) - [CameraCapture](/msg_docs/CameraCapture.md) - [CameraStatus](/msg_docs/CameraStatus.md) @@ -552,6 +577,7 @@ - [DifferentialPressure](/msg_docs/DifferentialPressure.md) - [DistanceSensor](/msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](/msg_docs/DistanceSensorModeChangeRequest.md) + - [DronecanNodeStatus](/msg_docs/DronecanNodeStatus.md) - [Ekf2Timestamps](/msg_docs/Ekf2Timestamps.md) - [EscReport](/msg_docs/EscReport.md) - [EscStatus](/msg_docs/EscStatus.md) @@ -626,6 +652,7 @@ - [MountOrientation](/msg_docs/MountOrientation.md) - [NavigatorMissionItem](/msg_docs/NavigatorMissionItem.md) - [NavigatorStatus](/msg_docs/NavigatorStatus.md) + - [NeuralControl](/msg_docs/NeuralControl.md) - [NormalizedUnsignedSetpoint](/msg_docs/NormalizedUnsignedSetpoint.md) - [ObstacleDistance](/msg_docs/ObstacleDistance.md) - [OffboardControlMode](/msg_docs/OffboardControlMode.md) @@ -665,10 +692,10 @@ - [RoverPositionSetpoint](/msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](/msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](/msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](/msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](/msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](/msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](/msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](/msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](/msg_docs/RoverVelocityStatus.md) - [Rpm](/msg_docs/Rpm.md) - [RtlStatus](/msg_docs/RtlStatus.md) - [RtlTimeEstimate](/msg_docs/RtlTimeEstimate.md) @@ -680,6 +707,7 @@ - [SensorCombined](/msg_docs/SensorCombined.md) - [SensorCorrection](/msg_docs/SensorCorrection.md) - [SensorGnssRelative](/msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](/msg_docs/SensorGnssStatus.md) - [SensorGps](/msg_docs/SensorGps.md) - [SensorGyro](/msg_docs/SensorGyro.md) - [SensorGyroFft](/msg_docs/SensorGyroFft.md) @@ -689,6 +717,7 @@ - [SensorOpticalFlow](/msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](/msg_docs/SensorPreflightMag.md) - [SensorSelection](/msg_docs/SensorSelection.md) + - [SensorTemp](/msg_docs/SensorTemp.md) - [SensorUwb](/msg_docs/SensorUwb.md) - [SensorsStatus](/msg_docs/SensorsStatus.md) - [SensorsStatusImu](/msg_docs/SensorsStatusImu.md) @@ -724,7 +753,13 @@ - [Wind](/msg_docs/Wind.md) - [YawEstimatorStatus](/msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](/msg_docs/AirspeedValidatedV0.md) + - [ArmingCheckReplyV0](/msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](/msg_docs/ArmingCheckRequestV0.md) + - [BatteryStatusV0](/msg_docs/BatteryStatusV0.md) + - [EventV0](/msg_docs/EventV0.md) + - [HomePositionV0](/msg_docs/HomePositionV0.md) - [VehicleAttitudeSetpointV0](/msg_docs/VehicleAttitudeSetpointV0.md) + - [VehicleLocalPositionV0](/msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](/msg_docs/VehicleStatusV0.md) - [MAVLink Messaging](/mavlink/index.md) - [Adding Messages](/mavlink/adding_messages.md) @@ -734,6 +769,8 @@ - [Protocols/Microservices](/mavlink/protocols.md) - [Standard Modes Protocol](/mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](/middleware/uxrce_dds.md) + - [UORB Bridged to ROS 2](/middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](/middleware/zenoh.md) - [모듈과 명령어](/modules/modules_main.md) - [자동 튜닝](/modules/modules_autotune.md) - [명령어](/modules/modules_command.md) @@ -751,6 +788,7 @@ - [Rpm Sensor](/modules/modules_driver_rpm_sensor.md) - [Radio Control](/modules/modules_driver_radio_control.md) - [Transponder](/modules/modules_driver_transponder.md) + - [adc](/modules/modules_driver_adc.md) - [추정기](/modules/modules_estimator.md) - [시뮬레이션](/modules/modules_simulation.md) - [시스템](/modules/modules_system.md) @@ -763,7 +801,7 @@ - [Debugging with GDB](/debug/gdb_debugging.md) - [SWD Debug Port](/debug/swd_debug.md) - [JLink Probe](/debug/probe_jlink.md) - - [Black Magic/DroneCode Probe](/debug/probe_bmp.md) + - [Black Magic/Zubax BugFace BF1 Probe](/debug/probe_bmp.md) - [STLink Probe](/debug/probe_stlink.md) - [MCU-Link Probe](/debug/probe_mculink.md) - [Hardfault Debugging](/debug/gdb_hardfault.md) @@ -787,6 +825,9 @@ - [Camera Integration/Architecture](/camera/camera_architecture.md) - [컴퓨터 비전](/advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](/tutorials/motion-capture.md) + - [Neural Networks](/advanced/neural_networks.md) + - [Neural Network Module Utilities](/advanced/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](/advanced/tflm.md) - [Intel RealSense R200용 드라이버 설치](/advanced/realsense_intel_driver.md) - [상태 추정기 전환](/advanced/switching_state_estimators.md) - [트리 외부 모듈](/advanced/out_of_tree_modules.md) @@ -818,8 +859,14 @@ - [시험 MC_02 - 완전 자동](/test_cards/mc_02_full_autonomous.md) - [시험 MC_03 - 자동 / 수동 혼합](/test_cards/mc_03_auto_manual_mix.md) - [시험 MC_04 - 안전 장치 시험](/test_cards/mc_04_failsafe_testing.md) - - [시험 MC_05 - 실내 비행 (수동 모드)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_05 - Manual Modes (Inside)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_06 - Optical Flow (Inside)](/test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](/test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](/test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](/test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](/test_cards/mc_10_optical_flow_gps_mixed.md) - [단위 테스트](/test_and_ci/unit_tests.md) + - [Fuzz Tests](/test_and_ci/fuzz_tests.md) - [지속 통합](/test_and_ci/continous_integration.md) - [Integration Testing](/test_and_ci/integration_testing.md) - [MAVSDK 통합 테스트](/test_and_ci/integration_testing_mavsdk.md) @@ -838,6 +885,7 @@ - [PX4 ROS 2 Interface Library](/ros2/px4_ros2_interface_lib.md) - [Control Interface](/ros2/px4_ros2_control_interface.md) - [Navigation Interface](/ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](/ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](/ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](/ros/ros1.md) - [ROS/MAVROS 설치 가이드](/ros/mavros_installation.md) @@ -862,8 +910,8 @@ - [출시](/releases/index.md) - [main (alpha)](/releases/main.md) - - [1.16 (release candidate)](/releases/1.16.md) - - [1.15 (stable)](/releases/1.15.md) + - [1.16 (stable)](/releases/1.16.md) + - [1.15](/releases/1.15.md) - [1.14](/releases/1.14.md) - [1.13](/releases/1.13.md) - [1.12](/releases/1.12.md) diff --git a/docs/ko/advanced/gimbal_control.md b/docs/ko/advanced/gimbal_control.md index 1f378ef3fd..e0d9495f5f 100644 --- a/docs/ko/advanced/gimbal_control.md +++ b/docs/ko/advanced/gimbal_control.md @@ -74,7 +74,7 @@ For example, you might have the following settings to assign the gimbal roll, pi ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -The PWM values to use for the disarmed, maximum and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low and high position in the slider. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. The values may also be provided in gimbal documentation. ## Gimbal Control in Missions @@ -131,7 +131,7 @@ The on-screen gimbal control can be used to move/test a connected MAVLink camera 2. Open QGroundControl and enable the on-screen camera control (Application settings). - ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) + ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) 3. Make sure the vehicle is armed and flying, e.g. by entering with `commander takeoff`. diff --git a/docs/ko/advanced/neural_networks.md b/docs/ko/advanced/neural_networks.md index 690ffadce9..039259fd5f 100644 --- a/docs/ko/advanced/neural_networks.md +++ b/docs/ko/advanced/neural_networks.md @@ -1,115 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Input - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### 출력 - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/ko/advanced/pps_time_sync.md b/docs/ko/advanced/pps_time_sync.md new file mode 100644 index 0000000000..f0a67858b9 --- /dev/null +++ b/docs/ko/advanced/pps_time_sync.md @@ -0,0 +1,135 @@ +# PPS Time Synchronization (PX4 Integration) + +[Pulse Per Second](https://en.wikipedia.org/wiki/Pulse-per-second_signal) (PPS) time synchronization provides high-precision timing for GNSS receivers. +This page explains how PPS is integrated into PX4 and how to configure it. + +## 개요 + +PPS (Pulse Per Second) is a timing signal provided by GNSS receivers that outputs an electrical pulse once per second, synchronized to UTC time. +The PPS signal provides a highly accurate timing reference that PX4 can use to: + +- Refine GNSS time measurements and compensate for clock drift +- Provide precise UTC timestamps for camera capture events (for photogrammetry and mapping applications) +- Enable offline position refinement through accurate time correlation + +## 지원 하드웨어 + +PPS time synchronization can be supported on flight controllers that have a hardware timer input pin that can be configured for PPS capture, by [enabling the PPS capture driver](#enable-pps-driver-in-board-configuration) in the board configuration. + +Supported boards include (at time of writing): + +- [Ark FMUv6x](../flight_controller/ark_v6x.md) +- Auterion FMUv6x +- Auterion FMUv6s + +## 설정 + +### Enable PPS Driver in Board Configuration + +The [PPS capture driver](../modules/modules_driver.md#pps-capture) must be enabled in the board configuration. +This is done by adding the following to your board's configuration: + +```ini +CONFIG_DRIVERS_PPS_CAPTURE=y +``` + +### Configure PPS Parameters + +The configuration varies depending on your flight controller hardware. + +#### FMUv6X + +For FMUv6X-based flight controllers, configure PWM AUX Timer 3 and Function 9: + +```sh +param set PWM_AUX_TIM3 -2 +param set PWM_AUX_FUNC9 2064 +param set PPS_CAP_ENABLE 1 +``` + +#### FMUv6S + +For FMUv6S-based flight controllers, configure PWM MAIN Timer 3 and Function 10: + +```sh +param set PWM_MAIN_TIM3 -2 +param set PWM_MAIN_FUNC10 2064 +param set PPS_CAP_ENABLE 1 +``` + +### 배선 + +The wiring configuration depends on your specific flight controller. + +#### Skynode X (FMUv6x) + +Connect the PPS signal from your GNSS module to the flight controller using the 11-pin or 6-pin GPS connector: + +For detailed pinout information, refer to: + +- [Skynode GPS Peripherals - Pinouts](https://docs.auterion.com/hardware-integration/skynode/peripherals/gps#pinouts) + +#### Skynode S (FMUv6S) + +For FMUv6S, you need to route the PPS signal separately: + +1. Connect your GNSS module using the standard 6-pin GPS connector: [Skynode S GPS Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#gps) +2. Connect the PPS signal from your GNSS module to the **PPM_IN** pin: [Skynode S Extras 1 Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#extras-1) + +#### ARK Jetson Carrier Board (FMUv6x) + +For ARK FMUv6X on the Jetson carrier board: + +1. Connect your GNSS module using either the 10-pin or 6-pin GPS connector: [ARK PAB GPS1 Interface](../flight_controller/ark_pab#gps1) +2. Connect the PPS signal to the **FMU_CAP** pin: [ARK PAB ADIO Interface](../flight_controller/ark_pab.md#adio) + +## 검증 + +After configuring PPS, you can verify that it is working correctly: + +1. Connect to the [PX4 System Console](../debug/system_console.md) (via MAVLink shell or serial console). + +2. Wait for GNSS fix. + +3. Check the PPS capture status to confirm it is up and running: + + ```sh + pps_capture status + ``` + +4. You can also check the [PpsCapture](../msg_docs/PpsCapture.md) uORB topic + + ```sh + listener pps_capture + ``` + + Where you should see: `timestamp`, `rtc_timestamp`, and `pps_rate_exceeded_counter`. + +### PPS Capture Driver + +The PPS capture driver is located in `src/drivers/pps_capture` and uses hardware timer input capture to precisely measure the arrival time of each PPS pulse. + +주요 기능: + +- Sub-microsecond pulse capture precision (hardware-dependent) +- Automatic drift calculation and compensation +- Integration with the GNSS driver for refined time stamping + +See also: + +- [PPS Capture Driver Documentation](../modules/modules_driver.md#pps-capture) +- [PpsCapture Message](../msg_docs/PpsCapture.md) + +### Time Synchronization Flow + +1. GNSS module sends position/time data at ~1-20 Hz. +2. GNSS module outputs PPS pulse at 1 Hz, precisely aligned to UTC second boundary. +3. PPS capture driver measures the exact time of the PPS pulse arrival using hardware timer. +4. Driver calculates the offset between GNSS time (from UART data) and autopilot clock (from PPS measurement). +5. This offset is used to correct GNSS timestamps and improve sensor fusion accuracy. + +The PPS signal provides much higher temporal precision than the transmitted time data, which has latency and jitter from serial communication. + +:::warning +If the PPS driver does not sending any data for 5 seconds (despite having `PPS_CAP_ENABLE` set to 1), the `EKF2_GPS_DELAY` will be used instead for estimating the latency. +::: diff --git a/docs/ko/advanced/system_tunes.md b/docs/ko/advanced/system_tunes.md index ab40a399ba..a0674238f8 100644 --- a/docs/ko/advanced/system_tunes.md +++ b/docs/ko/advanced/system_tunes.md @@ -52,7 +52,7 @@ On Windows, one option is to use _Melody Master_ within _Dosbox_. 7. 음악을 저장할 준비가 끝나면: - Press **F2** to give the tune a name and save it in the _/Music_ sub folder of your Melody Master installation. - Press **F7**, the scroll down the list of output formats on the right to get to ANSI. - The file will be exported to the _root_ of the Melody Master directory (with the same name and a file-type specific extension). + The file will be exported to the _root_ of the Melody Master directory (with the same name and a file-type specific extension). 8. 파일을 여십시오. 출력 내용은 다음과 같습니다: diff --git a/docs/ko/advanced_config/advanced_flight_controller_orientation_leveling.md b/docs/ko/advanced_config/advanced_flight_controller_orientation_leveling.md index 0eed5dba4f..ef16e98d4b 100644 --- a/docs/ko/advanced_config/advanced_flight_controller_orientation_leveling.md +++ b/docs/ko/advanced_config/advanced_flight_controller_orientation_leveling.md @@ -23,7 +23,7 @@ You can locate the parameters in QGroundControl as shown below: 1. Open QGroundControl menu: **Settings > Parameters > Sensor Calibration**. 2. The parameters as located in the section as shown below (or you can search for them): - ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) + ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) ## Parameter Summary diff --git a/docs/ko/advanced_config/airspeed_validation.md b/docs/ko/advanced_config/airspeed_validation.md index 67ba9f4037..2bbb437632 100644 --- a/docs/ko/advanced_config/airspeed_validation.md +++ b/docs/ko/advanced_config/airspeed_validation.md @@ -10,36 +10,13 @@ By default, the [Missing Data](#missing-data-check), [Data Stuck](#data-stuck-ch You can configure which checks are active using the [ASPD_DO_CHECKS](#aspd_do_checks_table) parameter. ::: -## Airspeed in PX4 - -PX4 handles multiple types of airspeed: - -- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). - -- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. - -- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. - While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. - -- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). - -The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. - ## CAS Scale Estimation -PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. -To compute the final TAS, standard environment conversions are applied (CAS → TAS). - -This CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. +Calibrated Airspeed (CAS) is the measured Indicated Airspeed (IAS) scaled to correct for sensor-specific and installation-related errors. +CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. If the estimated CAS scale is inaccurate, it can mask real airspeed faults or trigger false positives. -If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, you can manually set it using [ASPD_SCALE_n](#aspd_scale_n_table) (where `n` is the sensor number). -[ASPD_SCALE_APPLY](#aspd_scale_apply_table) can be used to configure when/if the estimated scale is applied. - -:::info -For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). -The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for [ASPD_SCALE_n](#aspd_scale_n_table). -::: +If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, follow the steps outlined in [Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md#recommended-first-flight-process). ## Validation Checks diff --git a/docs/ko/advanced_config/bootloader_update.md b/docs/ko/advanced_config/bootloader_update.md index 243258cbde..23739955e1 100644 --- a/docs/ko/advanced_config/bootloader_update.md +++ b/docs/ko/advanced_config/bootloader_update.md @@ -37,8 +37,8 @@ You can enable this key in your own custom firmware if needed. 2. [Update the Firmware](../config/firmware.md#custom) with an image containing the new/desired bootloader. - ::: info - The updated bootloader might be included the default firmware for your board or supplied in custom firmware. + ::: info + The updated bootloader might be included the default firmware for your board or supplied in custom firmware. ::: @@ -47,7 +47,7 @@ You can enable this key in your own custom firmware if needed. 4. [Find and enable](../advanced_config/parameters.md) the parameter [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 5. 재부팅하십시오 (보드의 연결을 끊고 다시 연결하십시오.). - 부트로더 업데이트는 수초내에 완료됩니다. + 부트로더 업데이트는 수초내에 완료됩니다. Generally at this point you may then want to [update the firmware](../config/firmware.md) again using the correct/newly installed bootloader. @@ -89,81 +89,81 @@ The following steps explain how you can "manually" update the bootloader using a 1. Get a binary containing the bootloader (either from dev team or [build it yourself](#building-the-px4-bootloader)). 2. Get a [Debug Probe](../debug/swd_debug.md#debug-probes-for-px4-hardware). - Connect the probe your PC via USB and setup the `gdbserver`. + Connect the probe your PC via USB and setup the `gdbserver`. 3. Go into the directory containing the binary and run the command for your target bootloader in the terminal: - - FMUv6X + - FMUv6X - ```sh - arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf + ``` - - FMUv6X-RT + - FMUv6X-RT - ```sh - arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf + ``` - - FMUv5 + - FMUv5 - ```sh - arm-none-eabi-gdb px4fmuv5_bl.elf - ``` + ```sh + arm-none-eabi-gdb px4fmuv5_bl.elf + ``` - ::: info - H7 Bootloaders from [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) are named with pattern `*._bootloader.elf`. - Bootloaders from [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) are named with the pattern `*_bl.elf`. + ::: info + H7 Bootloaders from [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) are named with pattern `*._bootloader.elf`. + Bootloaders from [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) are named with the pattern `*_bl.elf`. ::: 4. The _gdb terminal_ appears and it should display (something like) the following output: - ```sh - GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git - Copyright (C) 2017 Free Software Foundation, Inc. - License GPLv3+: GNU GPL version 3 or later - This is free software: you are free to change and redistribute it. - There is NO WARRANTY, to the extent permitted by law. - Type "show copying" and "show warranty" for details. - This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". - Type "show configuration" for configuration details. - For bug reporting instructions, please see: - . - Find the GDB manual and other documentation resources online at: - . - For help, type "help". - Type "apropos word" to search for commands related to "word"... - Reading symbols from px4fmuv5_bl.elf...done. - ``` + ```sh + GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git + Copyright (C) 2017 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from px4fmuv5_bl.elf...done. + ``` 5. Find your `` by running an `ls` command in the **/dev/serial/by-id** directory. 6. Now connect to the debug probe with the following command: - ```sh - tar ext /dev/serial/by-id/ - ``` + ```sh + tar ext /dev/serial/by-id/ + ``` 7. Power on the Pixhawk with another USB cable and connect the probe to the `FMU-DEBUG` port. - ::: info - If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). + ::: info + If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). ::: 8. Use the following command to scan for the Pixhawk\`s SWD and connect to it: - ```sh - (gdb) mon swdp_scan - (gdb) attach 1 - ``` + ```sh + (gdb) mon swdp_scan + (gdb) attach 1 + ``` 9. 이제 바이너리를 픽스호크에 로드하십시오: - ```sh - (gdb) load - ``` + ```sh + (gdb) load + ``` After the bootloader has updated you can [Load PX4 Firmware](../config/firmware.md) using _QGroundControl_. @@ -182,25 +182,25 @@ To update the bootloader: 1. SD카드를 삽입합니다 (발생 가능한 문제들의 디버깅을 위한 부트 로그 기록을 가능하게 합니다.) 2. [Update the Firmware](../config/firmware.md) to PX4 _master_ version (when updating the firmware, check **Advanced settings** and then select **Developer Build (master)** from the dropdown list). - _QGroundControl_ will automatically detect that the hardware supports FMUv2 and install the appropriate Firmware. + _QGroundControl_ will automatically detect that the hardware supports FMUv2 and install the appropriate Firmware. - ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) + ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) - 기체가 재부팅될 때까지 기다리십시오. + 기체가 재부팅될 때까지 기다리십시오. 3. [Find and enable](../advanced_config/parameters.md) the parameter [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 4. 재부팅하십시오 (보드의 연결을 끊고 다시 연결하십시오.). - 부트로더 업데이트는 수초내에 완료됩니다. + 부트로더 업데이트는 수초내에 완료됩니다. 5. Then [Update the Firmware](../config/firmware.md) again. - This time _QGroundControl_ should autodetect the hardware as FMUv3 and update the Firmware appropriately. + This time _QGroundControl_ should autodetect the hardware as FMUv3 and update the Firmware appropriately. - ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) + ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) - ::: info - If the hardware has the [Silicon Errata](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata) it will still be detected as FMUv2 and you will see that FMUv2 was re-installed (in console). - In this case you will not be able to install FMUv3 hardware. + ::: info + If the hardware has the [Silicon Errata](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata) it will still be detected as FMUv2 and you will see that FMUv2 was re-installed (in console). + In this case you will not be able to install FMUv3 hardware. ::: diff --git a/docs/ko/advanced_config/bootloader_update_from_betaflight.md b/docs/ko/advanced_config/bootloader_update_from_betaflight.md index 4498e65fa6..e1c4203c71 100644 --- a/docs/ko/advanced_config/bootloader_update_from_betaflight.md +++ b/docs/ko/advanced_config/bootloader_update_from_betaflight.md @@ -89,7 +89,7 @@ Flight controllers that have bootloader PX4-Autopilot `make` targets, can build The list of controllers for which this applies can be obtained by running the following `make` command, and noting the `make` targets that end in `_bootloader` ``` -$make list_config_targets +$ make list_config_targets ... cuav_nora_bootloader diff --git a/docs/ko/advanced_config/compass_power_compensation.md b/docs/ko/advanced_config/compass_power_compensation.md index cc6802ce8b..e5703d53a0 100644 --- a/docs/ko/advanced_config/compass_power_compensation.md +++ b/docs/ko/advanced_config/compass_power_compensation.md @@ -44,7 +44,7 @@ The process is demonstrated for a multicopter, but is equally valid for other ve - 기체에 시동을 걸고 스로틀을 천천히 최대로 올립니다. - 스로틀을 천천히 0까지 낮춥니다. - 기체 시동을 끄십시오. - > 참고 진동을 면밀히 관찰하고, 신중하게 테스트를 진행하십시오. + > 참고 진동을 면밀히 관찰하고, 신중하게 테스트를 진행하십시오. ::: info Perform the test carefully and closely monitor the vibrations. diff --git a/docs/ko/advanced_config/esc_calibration.md b/docs/ko/advanced_config/esc_calibration.md index 30f2c46a09..eb272206b1 100644 --- a/docs/ko/advanced_config/esc_calibration.md +++ b/docs/ko/advanced_config/esc_calibration.md @@ -94,29 +94,29 @@ ESC를 보정하려면 : - 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. - The correct value should make the motor spin immediately and reliably as you move the slider from disarmed to minimum. + 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. + The correct value should make the motor spin immediately and reliably as you move the slider from disarmed to minimum. - To find the "optimal" minimum value, move the slider to the bottom (disarmed). - Then increase the PWM output's `disarmed` setting in small increments (e.g. 1025us, 1050us, etc), until the motor starts to spin reliably (it is better to be a little too high than a little too low). - Enter this value into the `minimum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. + To find the "optimal" minimum value, move the slider to the bottom (disarmed). + Then increase the PWM output's `disarmed` setting in small increments (e.g. 1025us, 1050us, etc), until the motor starts to spin reliably (it is better to be a little too high than a little too low). + Enter this value into the `minimum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. - The maximum value for a motor (default: `1900us`) should be chosen such that increasing the value doesn't make the motor spin any faster. - You can confirm that the motor spins quickly at the maximum setting in [Actuator Testing](../config/actuators.md#actuator-testing), by moving the associated test output slider to the top position. + You can confirm that the motor spins quickly at the maximum setting in [Actuator Testing](../config/actuators.md#actuator-testing), by moving the associated test output slider to the top position. - To find the "optimal" maximum value, first move the slider to the bottom (disarmed). - Then increase the PWM output's `disarmed` setting to near the default maximum (`1900`) - the motors should spin up. - Listen to the tone of the motor as you increase the PWM maximum value for the output in increments (e.g. 1925us, 1950us, etc). - The optimal value is found at the point when the sound of the motors does not change as you increase the value of the output. - Enter this value into the `maximum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. + To find the "optimal" maximum value, first move the slider to the bottom (disarmed). + Then increase the PWM output's `disarmed` setting to near the default maximum (`1900`) - the motors should spin up. + Listen to the tone of the motor as you increase the PWM maximum value for the output in increments (e.g. 1925us, 1950us, etc). + The optimal value is found at the point when the sound of the motors does not change as you increase the value of the output. + Enter this value into the `maximum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. - The disarmed value for a motor (default: `1000us`) should make the motor stop and stay stopped. - You can confirm this in [Actuator Testing](../config/actuators.md#actuator-testing) by moving the test output slider to the snap position at the bottom of the slider and observing that the motor does not spin. + You can confirm this in [Actuator Testing](../config/actuators.md#actuator-testing) by moving the test output slider to the snap position at the bottom of the slider and observing that the motor does not spin. - If the ESC spins with the default value of 1000us then the ESC is not properly calibrated. - If using an ESC that can't be calibrated, you should reduce the PWM output value for the output to below where the motor does not spin anymore (such as 950us or 900us). + If the ESC spins with the default value of 1000us then the ESC is not properly calibrated. + If using an ESC that can't be calibrated, you should reduce the PWM output value for the output to below where the motor does not spin anymore (such as 950us or 900us). ::: info VTOL and fixed-wing motors do not need any special PWM configuration. diff --git a/docs/ko/advanced_config/ethernet_setup.md b/docs/ko/advanced_config/ethernet_setup.md index 79f58d86da..0b92e9d940 100644 --- a/docs/ko/advanced_config/ethernet_setup.md +++ b/docs/ko/advanced_config/ethernet_setup.md @@ -25,6 +25,7 @@ It may also be supported on other boards. Supported flight controllers include: +- [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) - [CUAV Pixhawk V6X](../flight_controller/cuav_pixhawk_v6x.md) - [Holybro Pixhawk 5X](../flight_controller/pixhawk5x.md) - [Holybro Pixhawk 6X](../flight_controller/pixhawk6x.md) @@ -87,14 +88,14 @@ To set the above "example" configuration using the _QGroundControl_: 3. Enter commands "like" the ones below into the _MAVLink Console_ (to write the values to the configuration file): - ```sh - echo DEVICE=eth0 > /fs/microsd/net.cfg - echo BOOTPROTO=fallback >> /fs/microsd/net.cfg - echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg - echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg - echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg - echo DNS=10.41.10.254 >>/fs/microsd/net.cfg - ``` + ```sh + echo DEVICE=eth0 > /fs/microsd/net.cfg + echo BOOTPROTO=fallback >> /fs/microsd/net.cfg + echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg + echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg + echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg + echo DNS=10.41.10.254 >>/fs/microsd/net.cfg + ``` 4. Once the network configuration has been set you can disconnect the USB cable. @@ -113,36 +114,36 @@ Note that there are many more [examples](https://github.com/canonical/netplan/tr To setup the Ubuntu Computer: 1. In a terminal, create and open a `netplan` configuration file: `/etc/netplan/01-network-manager-all.yaml` - Below we do this using the _nano_ text editor. + Below we do this using the _nano_ text editor. - ``` - sudo nano /etc/netplan/01-network-manager-all.yaml - ``` + ``` + sudo nano /etc/netplan/01-network-manager-all.yaml + ``` 2. Copy and paste the following configuration information into the file (note: the indentations are important!): - ``` - network: - version: 2 - renderer: NetworkManager - ethernets: - enp2s0: - addresses: - - 10.41.10.1/24 - nameservers: - addresses: [10.41.10.1] - routes: - - to: 10.41.10.1 - via: 10.41.10.1 - ``` + ``` + network: + version: 2 + renderer: NetworkManager + ethernets: + enp2s0: + addresses: + - 10.41.10.1/24 + nameservers: + addresses: [10.41.10.1] + routes: + - to: 10.41.10.1 + via: 10.41.10.1 + ``` - Save and exit the editor. + Save and exit the editor. 3. Apply the _netplan_ configuration by entering the following command into the Ubuntu terminal. - ``` - sudo netplan apply - ``` + ``` + sudo netplan apply + ``` ### Companion Computer Ethernet Network Setup @@ -189,9 +190,9 @@ To connect QGroundControl to PX4 over Ethernet: 3. Start QGroundControl and [define a comm link](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/settings_view.html) (**Application Settings > Comm Links**) specifying the _server address_ and port as the IP address and port assigned in PX4, respectively. - Assuming that the values are set as described in the rest of this topic the setup will look like this: + Assuming that the values are set as described in the rest of this topic the setup will look like this: - ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) + ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) 4. QGroundControl should then connect if you select this link. @@ -205,14 +206,14 @@ To setup MAVSDK-Python running on a companion computer: 1. [Set up the Ethernet Network](#setting-up-the-ethernet-network) so your companion computer and PX4 run on the same network. 2. Modify the [PX4 Ethernet Port Configuration](#px4-ethernet-network-setup) to connect to a companion computer. - You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). + You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). 3. Follow the instructions in [MAVSDK-python](https://github.com/mavlink/MAVSDK-Python) to install and use MAVSDK. - For example, your code will connect to the PX4 using: + For example, your code will connect to the PX4 using: - ```python - await drone.connect(system_address="udp://10.41.10.2:14540") - ``` + ```python + await drone.connect(system_address="udp://10.41.10.2:14540") + ``` :::info MAVSDK can connect to the PX4 on port `14550` if you don't modify the PX4 Ethernet port configuration. @@ -235,38 +236,38 @@ To set up ROS 2: 1. Connect your flight controller and companion computer via Ethernet. 2. [Start the uXRCE-DDS client on PX4](../middleware/uxrce_dds.md#starting-the-client), either manually or by customizing the system startup script. - Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). + Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). 3. [Start the micro XRCE-DDS agent on the companion computer](../middleware/uxrce_dds.md#starting-the-agent). - For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. + For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 4. Run a [listener node](../ros2/user_guide.md#running-the-example) in a new terminal to confirm the connection is established: - ```sh - source ~/ws_sensor_combined/install/setup.bash - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + source ~/ws_sensor_combined/install/setup.bash + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` - If everything is setup correctly, the following output should be displayed in the terminal: + If everything is setup correctly, the following output should be displayed in the terminal: - ```sh - RECEIVED SENSOR COMBINED DATA - ============================= - ts: 855801598 - gyro_rad[0]: -0.00339938 - gyro_rad[1]: 0.00440091 - gyro_rad[2]: 0.00513893 - gyro_integral_dt: 4997 - accelerometer_timestamp_relative: 0 - accelerometer_m_s2[0]: -0.0324082 - accelerometer_m_s2[1]: 0.0392213 - accelerometer_m_s2[2]: -9.77914 - accelerometer_integral_dt: 4997 - ``` + ```sh + RECEIVED SENSOR COMBINED DATA + ============================= + ts: 855801598 + gyro_rad[0]: -0.00339938 + gyro_rad[1]: 0.00440091 + gyro_rad[2]: 0.00513893 + gyro_integral_dt: 4997 + accelerometer_timestamp_relative: 0 + accelerometer_m_s2[0]: -0.0324082 + accelerometer_m_s2[1]: 0.0392213 + accelerometer_m_s2[2]: -9.77914 + accelerometer_integral_dt: 4997 + ``` ## See Also diff --git a/docs/ko/advanced_config/prearm_arm_disarm.md b/docs/ko/advanced_config/prearm_arm_disarm.md index be52c15811..8926c0011f 100644 --- a/docs/ko/advanced_config/prearm_arm_disarm.md +++ b/docs/ko/advanced_config/prearm_arm_disarm.md @@ -55,19 +55,17 @@ RC controllers will use different sticks for throttle and yaw [based on their mo - _Arm:_ Left-stick to right, right-stick to bottom. - _Disarm:_ Left-stick to left, right-stick to the bottom. -The required hold time can be configured using [COM_RC_ARM_HYST](#COM_RC_ARM_HYST). Note that by default ([COM_DISARM_MAN](#COM_DISARM_MAN)) you can also disarm in flight using gestures/buttons: you may choose to disable this to avoid accidental disarming. -| 매개변수 | 설명 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | -| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | -| [COM_RC_ARM_HYST](../advanced_config/parameter_reference.md#COM_RC_ARM_HYST) | Time that RC stick must be held in arm/disarm position before arming/disarming occurs (default: `1` second). | +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | +| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | ## Arming Button/Switch {#arm_disarm_switch} An _arming button_ or "momentary switch" can be configured to trigger arm/disarm _instead_ of [gesture-based arming](#arm_disarm_gestures) (setting an arming switch disables arming gestures). -The button should be held down for ([nominally](#COM_RC_ARM_HYST)) one second to arm (when disarmed) or disarm (when armed). +The button should be held down for one second to arm (when disarmed) or disarm (when armed). A two-position switch can also be used for arming/disarming, where the respective arm/disarm commands are sent on switch _transitions_. @@ -77,10 +75,10 @@ Two-position arming switches are primarily used in/recommended for racing drones The switch or button is assigned (and enabled) using [RC_MAP_ARM_SW](#RC_MAP_ARM_SW), and the switch "type" is configured using [COM_ARM_SWISBTN](#COM_ARM_SWISBTN). -| 매개변수 | 설명 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [RC_MAP_ARM_SW](../advanced_config/parameter_reference.md#RC_MAP_ARM_SW) | RC arm 스위치 채널 (기본값 : 0 - 할당되지 않음). 정의된 경우 지정된 RC 채널(버튼/스위치)이 스틱 제스처 대신 시동용으로 사용됩니다.
**Note:**
- This setting _disables the stick gesture_!
- This setting applies to RC controllers. It does not apply to Joystick controllers that are connected via _QGroundControl_. | -| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | 시동 스위치는 순간적으로 동작하는 버튼입니다.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a button or momentary button where the arm/disarm command ae sent after holding down button for set time ([COM_RC_ARM_HYST](#COM_RC_ARM_HYST)). | +| 매개변수 | 설명 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [RC_MAP_ARM_SW](../advanced_config/parameter_reference.md#RC_MAP_ARM_SW) | RC arm 스위치 채널 (기본값 : 0 - 할당되지 않음). 정의된 경우 지정된 RC 채널(버튼/스위치)이 스틱 제스처 대신 시동용으로 사용됩니다.
**Note:**
- This setting _disables the stick gesture_!
- This setting applies to RC controllers. It does not apply to Joystick controllers that are connected via _QGroundControl_. | +| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | 시동 스위치는 순간적으로 동작하는 버튼입니다.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a momentary button where the arm/disarm command is sent after holding down the button for one second. | :::info The switch can also be set as part of _QGroundControl_ [Flight Mode](../config/flight_mode.md) configuration. @@ -153,14 +151,14 @@ It corresponds to: [COM_PREARM_MODE=1](#COM_PREARM_MODE) (safety switch) and [CB 시작 절차는 다음과 같습니다: 1. 전원 인가 - - 모든 액츄에이터를 시동 해제 상태로 잠금 - - 시동 걸기 불가능 + - 모든 액츄에이터를 시동 해제 상태로 잠금 + - 시동 걸기 불가능 2. 안전 스위치 누름 - - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) - - 시스템 안전 장치 꺼짐: 시동 가능 + - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) + - 시스템 안전 장치 꺼짐: 시동 가능 3. 시동 명령 인가 - - 시스템에 시동이 걸림 - - 모든 모터와 액츄에이터를 움직일 수 있음 + - 시스템에 시동이 걸림 + - 모든 모터와 액츄에이터를 움직일 수 있음 ### COM_PREARM_MODE = Disabled and Safety Switch @@ -170,14 +168,14 @@ This corresponds to [COM_PREARM_MODE=0](#COM_PREARM_MODE) (Disabled) and [CBRK_I 시작 절차는 다음과 같습니다: 1. 전원 인가 - - 모든 액츄에이터를 시동 해제 상태로 잠금 - - 시동 걸기 불가능 + - 모든 액츄에이터를 시동 해제 상태로 잠금 + - 시동 걸기 불가능 2. 안전 스위치 누름 - - _All actuators stay locked into disarmed position (same as disarmed)._ - - 시스템 안전 장치 꺼짐: 시동 가능 + - _All actuators stay locked into disarmed position (same as disarmed)._ + - 시스템 안전 장치 꺼짐: 시동 가능 3. 시동 명령 인가 - - 시스템에 시동이 걸림 - - 모든 모터와 액츄에이터를 움직일 수 있음 + - 시스템에 시동이 걸림 + - 모든 모터와 액츄에이터를 움직일 수 있음 ### COM_PREARM_MODE = Always and Safety Switch @@ -188,13 +186,13 @@ This corresponds to [COM_PREARM_MODE=2](#COM_PREARM_MODE) (Always) and [CBRK_IO_ 시작 절차는 다음과 같습니다: 1. 전원 인가 - - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) - - 시동 걸기 불가능 + - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) + - 시동 걸기 불가능 2. 안전 스위치 누름 - - 시스템 안전 장치 꺼짐: 시동 가능 + - 시스템 안전 장치 꺼짐: 시동 가능 3. 시동 명령 인가 - - 시스템에 시동이 걸림 - - 모든 모터와 액츄에이터를 움직일 수 있음 + - 시스템에 시동이 걸림 + - 모든 모터와 액츄에이터를 움직일 수 있음 ### COM_PREARM_MODE = Safety or Disabled and No Safety Switch @@ -204,11 +202,11 @@ This corresponds to [COM_PREARM_MODE=0 or 1](#COM_PREARM_MODE) (Disabled/Safety 시작 절차는 다음과 같습니다: 1. 전원 인가 - - 모든 액츄에이터를 시동 해제 상태로 잠금 - - 시스템 안전 장치 꺼짐: 시동 가능 + - 모든 액츄에이터를 시동 해제 상태로 잠금 + - 시스템 안전 장치 꺼짐: 시동 가능 2. 시동 명령 인가 - - 시스템에 시동이 걸림 - - 모든 모터와 액츄에이터를 움직일 수 있음 + - 시스템에 시동이 걸림 + - 모든 모터와 액츄에이터를 움직일 수 있음 ### COM_PREARM_MODE = Always and No Safety Switch @@ -218,11 +216,11 @@ This corresponds to [COM_PREARM_MODE=2](#COM_PREARM_MODE) (Always) and [CBRK_IO_ 시작 절차는 다음과 같습니다: 1. 전원 인가 - - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) - - 시스템 안전 장치 꺼짐: 시동 가능 + - 시스템이 시동전 상태로 전환: 추진 모터를 제외한 모든 액츄에이터 동작 가능(예: 보조익) + - 시스템 안전 장치 꺼짐: 시동 가능 2. 시동 명령 인가 - - 시스템에 시동이 걸림 - - 모든 모터와 액츄에이터를 움직일 수 있음 + - 시스템에 시동이 걸림 + - 모든 모터와 액츄에이터를 움직일 수 있음 ### 매개변수 diff --git a/docs/ko/advanced_config/sensor_thermal_calibration.md b/docs/ko/advanced_config/sensor_thermal_calibration.md index cab8e86fa9..fd240fd6da 100644 --- a/docs/ko/advanced_config/sensor_thermal_calibration.md +++ b/docs/ko/advanced_config/sensor_thermal_calibration.md @@ -94,11 +94,11 @@ PX4는 두 가지 보정 절차를 지원합니다. 9. Open a terminal window in the **Firmware/Tools** directory and run the python calibration script: - ```sh - python process_sensor_caldata.py - ``` + ```sh + python process_sensor_caldata.py + ``` - This will generate a **.pdf** file showing the measured data and curve fits for each sensor, and a **.params** file containing the calibration parameters. + This will generate a **.pdf** file showing the measured data and curve fits for each sensor, and a **.params** file containing the calibration parameters. 10. Power the board, connect _QGroundControl_ and load the parameter from the generated **.params** file onto the board using _QGroundControl_. 매개변수의 갯수가 많이지므로, 로드 시간이 길어질 수 있습니다. diff --git a/docs/ko/advanced_config/tuning_the_ecl_ekf.md b/docs/ko/advanced_config/tuning_the_ecl_ekf.md index da280bff3a..63d5fbfae6 100644 --- a/docs/ko/advanced_config/tuning_the_ecl_ekf.md +++ b/docs/ko/advanced_config/tuning_the_ecl_ekf.md @@ -158,29 +158,29 @@ Three axis body fixed magnetometer data at a minimum rate of 5Hz is required to Magnetometer data fusion can be configured using [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE): 0. Automatic: - - The magnetometer readings only affect the heading estimate before arming, and the whole attitude after arming. - - Heading and tilt errors are compensated when using this method. - - Incorrect magnetic field measurements can degrade the tilt estimate. - - The magnetometer biases are estimated whenever observable. + - The magnetometer readings only affect the heading estimate before arming, and the whole attitude after arming. + - Heading and tilt errors are compensated when using this method. + - Incorrect magnetic field measurements can degrade the tilt estimate. + - The magnetometer biases are estimated whenever observable. 1. Magnetic heading: - - Only the heading is corrected. - The tilt estimate is never affected by incorrect magnetic field measurements. - - Tilt errors that could arise when flying without velocity/position aiding are not corrected when using this method. - - The magnetometer biases are estimated whenever observable. + - Only the heading is corrected. + The tilt estimate is never affected by incorrect magnetic field measurements. + - Tilt errors that could arise when flying without velocity/position aiding are not corrected when using this method. + - The magnetometer biases are estimated whenever observable. 2. Deprecated 3. Deprecated 4. Deprecated 5. None: - - Magnetometer data is never used. - This is useful when the data can never be trusted (e.g.: high current close to the sensor, external anomalies). - - The estimator will use other sources of heading: [GPS heading](#yaw-measurements) or external vision. - - When using GPS measurements without another source of heading, the heading can only be initialized after sufficient horizontal acceleration. - See [Estimate yaw from vehicle movement](#yaw-from-gps-velocity) below. + - Magnetometer data is never used. + This is useful when the data can never be trusted (e.g.: high current close to the sensor, external anomalies). + - The estimator will use other sources of heading: [GPS heading](#yaw-measurements) or external vision. + - When using GPS measurements without another source of heading, the heading can only be initialized after sufficient horizontal acceleration. + See [Estimate yaw from vehicle movement](#yaw-from-gps-velocity) below. 6. Init only: - - Magnetometer data is only used to initialize the heading estimate. - This is useful when the data can be used before arming but not afterwards (e.g.: high current after the vehicle is armed). - - After initialization, the heading is constrained using other observations. - - Unlike mag type `None`, when combined with GPS measurements, this method allows position controlled modes to run directly during takeoff. + - Magnetometer data is only used to initialize the heading estimate. + This is useful when the data can be used before arming but not afterwards (e.g.: high current after the vehicle is armed). + - After initialization, the heading is constrained using other observations. + - Unlike mag type `None`, when combined with GPS measurements, this method allows position controlled modes to run directly during takeoff. The following selection tree can be used to select the right option: @@ -242,8 +242,8 @@ A good tuning is obtained as follows: 2. Extract the `.ulg` log file using, for example, [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) - ::: info - The same log file can be used to tune the [multirotor wind estimator](#mc_wind_estimation_using_drag). + ::: info + The same log file can be used to tune the [multirotor wind estimator](#mc_wind_estimation_using_drag). ::: @@ -351,6 +351,60 @@ The `hpos_drift_rate`, `vpos_drift_rate` and `hspd` are calculated over a period Note that `ekf2_gps_drift` is not logged! ::: +#### GNSS Fault Detection + +PX4's GNSS fault detection protects against malicious or erroneous GNSS signals using selective fusion control based on measurement validation. + +The fault detection logic depends on the GPS mode, and also operates differently for horizontal position and altitude measurements. +The mode is set using the [EKF2_GPS_MODE](../advanced_config/parameter_reference.md#EKF2_GPS_MODE) parameter: + +- **Automatic (`0`)** (Default): Assumes that GNSS is generally reliable and is likely to be recovered. + EKF2 resets on fusion timeouts if no other source of position is available. +- **Dead-reckoning (`1`)**: Assumes that GNSS might be lost indefinitely, so resets should be avoided while we have other estimates of position data. + EKF2 may reset if no other sources of position or velocity are available. + If GNSS altitude OR horizontal position data drifts, the system disables fusion of both measurements simultaneously (even if one would still pass validation) and avoids performing resets. + +##### Detection Logic + +Horizontal Position: + +- **Automatic mode**: Horizontal position resets to GNSS data if no other horizontal position source is currently being fused (e.g., Auxiliary Global Position - AGP). +- **Dead-reckoning mode**: Horizontal position resets to GNSS data only if no other horizontal position OR velocity source is currently being fused (e.g., AGP, airspeed, optical flow). + +Altitude: + +- The altitude logic is more complex due to the height reference sensor ([EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)) parameter, which is typically set to GNSS or baro in GNSS-denied scenarios. +- If height reference is set to baro, GNSS-based height resets are prevented (except when baro fusion fails completely and height reference automatically switches to GNSS). +- When height reference is set to GNSS: +- **Automatic mode**: Resets occur on drifting GNSS altitude measurements. +- **Dead-reckoning mode**: When validation starts failing, the system prevents GNSS altitude resets and labels the GNSS data as faulty. + +##### Faulty GNSS Data During Boot + +The system cannot automatically detect faulty GNSS data during vehicle boot as no baseline comparison exists. + +If GNSS fusion is enabled ([EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL)), operators will observe incorrect positions on maps and should disable GNSS fusion, then manually set the correct position via ground control station. +The global position gets corrected, and if [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) was enabled, baro offsets are automatically adjusted (through bias correction, not parameter changes). + +##### Enabling GNSS Fusion Mid-Flight + +With Faulty GNSS Data: + +- **Automatic mode**: Vehicle will reset to faulty position - potentially dangerous. +- **Dead-reckoning mode**: Large measurement differences cause GNSS rejection and fault detection activation. + +With Valid GNSS Data: + +- **Automatic mode**: Vehicle will reset to GNSS measurements. +- **Dead-reckoning mode**: If estimated position/altitude is close enough to measurements, fusion resumes; if too far apart, data gets labeled as faulty. + +##### 참고 + +- **Dual Detection**: Horizontal and altitude checks run completely separately but both lead to the same result when triggered - all GNSS fusion gets disabled. +- **Recovery**: Only the specific check that labeled data as invalid can re-enable fusion. +- **Alternative Sources**: Dead-reckoning mode provides enhanced protection by requiring absence of alternative navigation sources before allowing resets. +- **Boot Vulnerability**: Initial faulty GNSS data cannot be detected automatically; requires operator intervention and manual position correction. + ### 거리 측정기 [Range finder](../sensor/rangefinders.md) distance to ground is used by a single state filter to estimate the vertical position of the terrain relative to the height datum. @@ -458,8 +512,8 @@ A good tuning is obtained as follows: 1. Fly once in [Position mode](../flight_modes_mc/position.md) repeatedly forwards/backwards/left/right/up/down between rest and maximum speed (best results are obtained when this testing is conducted in still conditions). 2. Extract the **.ulg** log file using, for example, [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) - ::: info - The same **.ulg** log file can also be used to tune the [static pressure position error coefficients](#correction-for-static-pressure-position-error). + ::: info + The same **.ulg** log file can also be used to tune the [static pressure position error coefficients](#correction-for-static-pressure-position-error). ::: 3. Use the log with the [mc_wind_estimator_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/mc_wind_estimator) Python script to obtain the optimal set of parameters. diff --git a/docs/ko/advanced_features/precland.md b/docs/ko/advanced_features/precland.md index 158f541566..a53948dca0 100644 --- a/docs/ko/advanced_features/precland.md +++ b/docs/ko/advanced_features/precland.md @@ -38,14 +38,14 @@ If it is not visible the vehicle immediately performs a _normal_ landing at the 정밀 착륙에는 세 단계가 있습니다. 1. **Horizontal approach:** The vehicle approaches the target horizontally while keeping its current altitude. - Once the position of the target relative to the vehicle is below a threshold ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), the next phase is entered. - If the target is lost during this phase (not visible for longer than [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). + Once the position of the target relative to the vehicle is below a threshold ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), the next phase is entered. + If the target is lost during this phase (not visible for longer than [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). 2. **Descent over target:** The vehicle descends, while remaining centered over the target. - If the target is lost during this phase (not visible for longer than `PLD_BTOUT`), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). + If the target is lost during this phase (not visible for longer than `PLD_BTOUT`), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). 3. **Final approach:** When the vehicle is close to the ground (closer than [PLD_FAPPR_ALT](../advanced_config/parameter_reference.md#PLD_FAPPR_ALT)), it descends while remaining centered over the target. - 만약 목표물이 이 단계에서 잡히지 않는다면, 기체는 정밀 착륙의 모드와 무관하게 계속 하강합니다. + 만약 목표물이 이 단계에서 잡히지 않는다면, 기체는 정밀 착륙의 모드와 무관하게 계속 하강합니다. Search procedures are initiated in the first and second steps, and will run at most [PLD_MAX_SRCH](../advanced_config/parameter_reference.md#PLD_MAX_SRCH) times. 착륙 단계 흐름도 diff --git a/docs/ko/advanced_features/satcom_roadblock.md b/docs/ko/advanced_features/satcom_roadblock.md index d28351c8c9..e93526cd95 100644 --- a/docs/ko/advanced_features/satcom_roadblock.md +++ b/docs/ko/advanced_features/satcom_roadblock.md @@ -54,19 +54,19 @@ To [switch between the two antennas modes](https://docs.groundcontrol.com/iot/ro 모듈의 기본 보드 속도는 19200입니다. However, the PX4 _iridiumsbd_ driver requires a baud rate of 115200 so it needs to be changed using the [AT commands](https://www.groundcontrol.com/wp-content/uploads/2022/02/IRDM_ISU_ATCommandReferenceMAN0009_Rev2.0_ATCOMM_Oct2012.pdf). 1. Connect to the module with using a 19200/8-N-1 setting and check if the communication is working using the command: `AT`. - The response should be: `OK`. + The response should be: `OK`. 2. baudrate 속도를 변경합니다. - ``` - AT+IPR=9 - ``` + ``` + AT+IPR=9 + ``` 3. 이제 115200/8-N-1 설정을 사용하여 모델에 다시 연결하고 다음을 사용하여 설정을 저장합니다. - ``` - AT&W0 - ``` + ``` + AT&W0 + ``` 이제 이 모듈을 PX4에서 사용할 수 있습니다. @@ -101,55 +101,55 @@ Log in to the [account](https://rockblock.rock7.com/Operations) and register the 릴레이 서버는 Ubuntu 16.04 또는 14.04 버전에서 실행하여야 합니다. 1. 메시지 릴레이로 작동하는 서버에는 고정 IP 주소와 열린 TCP 포트 2개가 있어야 합니다. - - `5672` for the _RabbitMQ_ message broker (can be changed in the _rabbitmq_ settings) - - `45679` for the HTTP POST interface (can be changed in the **relay.cfg** file) + - `5672` for the _RabbitMQ_ message broker (can be changed in the _rabbitmq_ settings) + - `45679` for the HTTP POST interface (can be changed in the **relay.cfg** file) 2. 필요한 Python 모듈을 설치합니다. - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 3. Install the `rabbitmq` message broker: - ```sh - sudo apt install rabbitmq-server - ``` + ```sh + sudo apt install rabbitmq-server + ``` 4. 브로커 자격 증명을 구성합니다(암호를 PWD로 변경). - ```sh - sudo rabbitmqctl add_user iridiumsbd PWD - sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" - ``` + ```sh + sudo rabbitmqctl add_user iridiumsbd PWD + sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" + ``` 5. Clone the [SatComInfrastructure](https://github.com/acfloria/SatComInfrastructure) repository: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 6. Go to the location of the _SatComInfrastructure_ repo and configure the broker's queues: - ```sh - ./setup_rabbit.py localhost iridiumsbd PWD - ``` + ```sh + ./setup_rabbit.py localhost iridiumsbd PWD + ``` 7. 설정을 확인합니다. - ```sh - sudo rabbitmqctl list_queues - ``` + ```sh + sudo rabbitmqctl list_queues + ``` - This should give you a list of 4 queues: `MO`, `MO_LOG`, `MT`, `MT_LOG` + This should give you a list of 4 queues: `MO`, `MO_LOG`, `MT`, `MT_LOG` 8. Edit the `relay.cfg` configuration file to reflect your settings. 9. 분리 모드에서 릴레이 스크립트를 실행합니다. - ```sh - screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py - ``` + ```sh + screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py + ``` 기타 지침은 다음과 같습니다. @@ -177,15 +177,15 @@ Log in to the [account](https://rockblock.rock7.com/Operations) and register the 1. 필요한 Python 모듈을 설치합니다. - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 2. SatComInfrarastructure 저장소 복제: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 3. Edit the **udp2rabbit.cfg** configuration file to reflect your settings. @@ -193,20 +193,20 @@ Log in to the [account](https://rockblock.rock7.com/Operations) and register the 5. 다음 매개 변수를 사용하여 QGC에서 UDP 연결을 추가합니다. - - 접속 포트: 10000 - - 대상 호스트: 127.0.0.1:10001 - - 높은 지연 시간: 확인됨 + - 접속 포트: 10000 + - 대상 호스트: 127.0.0.1:10001 + - 높은 지연 시간: 확인됨 - ![High Latency Link Settings](../../assets/satcom/linksettings.png) + ![High Latency Link Settings](../../assets/satcom/linksettings.png) ### 검증 1. Open a terminal on the ground station computer and change to the location of the _SatComInfrastructure_ repository. - Then start the **udp2rabbit.py** script: + Then start the **udp2rabbit.py** script: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 2. Send a test message from [RockBlock Account](https://rockblock.rock7.com/Operations) to the created delivery group in the `Test Delivery Groups` tab. @@ -217,35 +217,35 @@ If in the terminal where the `udp2rabbit.py` script is running within a couple o ## 시스템 실행 1. Start _QGroundControl_. - 먼저 높은 지연 시간 링크를 수동으로 연결한 다음, 일반 텔레메트리 링크를 연결합니다. + 먼저 높은 지연 시간 링크를 수동으로 연결한 다음, 일반 텔레메트리 링크를 연결합니다. - ![Connect the High Latency link](../../assets/satcom/linkconnect.png) + ![Connect the High Latency link](../../assets/satcom/linkconnect.png) 2. Open a terminal on the ground station computer and change to the location of the _SatComInfrastructure_ repository. - Then start the **udp2rabbit.py** script: + Then start the **udp2rabbit.py** script: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 3. 기체의 전원을 켭니다. 4. Wait until the first `HIGH_LATENCY2` message is received on QGC. - This can be checked either using the _MAVLink Inspector_ widget or on the toolbar with the _LinkIndicator_. - If more than one link is connected to the active vehicle the _LinkIndicator_ shows all of them by clicking on the name of the shown link: + This can be checked either using the _MAVLink Inspector_ widget or on the toolbar with the _LinkIndicator_. + If more than one link is connected to the active vehicle the _LinkIndicator_ shows all of them by clicking on the name of the shown link: - ![Link Toolbar](../../assets/satcom/linkindicator.jpg) + ![Link Toolbar](../../assets/satcom/linkindicator.jpg) - 링크 표시기는 항상 우선 순위 링크의 이름을 표시합니다. + 링크 표시기는 항상 우선 순위 링크의 이름을 표시합니다. 5. 이제 위성 통신 시스템을 사용할 준비가 되었습니다.우선 순위 링크(명령 전송 링크)는 다음 방법으로 결정됩니다. - - 사용자가 링크를 명령하지 않으면, 지연 시간이 큰 링크보다 일반적인 텔레메트리 링크가 선호됩니다. - - 기체가 시동을 켜고 텔레메트리 링크가 끊어지면(특정 시간 동안 MAVLink 메시지가 수신되지 않을 경우), 오토파일럿과 QGC는 일반 텔레메트리에서 긴 대기 시간 링크로 되돌아갑니다. - 텔레메트리 링크가 복구되는 즉시 QGC와 자동 조종기가 다시 이 링크로 전환됩니다. - - The user can select a priority link over the `LinkIndicator` on the toolbar. - 이 링크가 활성화되어 있거나 사용자가 다른 우선 순위 링크를 선택하면 이 링크는 우선 순위 링크로 유지됩니다. + - 사용자가 링크를 명령하지 않으면, 지연 시간이 큰 링크보다 일반적인 텔레메트리 링크가 선호됩니다. + - 기체가 시동을 켜고 텔레메트리 링크가 끊어지면(특정 시간 동안 MAVLink 메시지가 수신되지 않을 경우), 오토파일럿과 QGC는 일반 텔레메트리에서 긴 대기 시간 링크로 되돌아갑니다. + 텔레메트리 링크가 복구되는 즉시 QGC와 자동 조종기가 다시 이 링크로 전환됩니다. + - The user can select a priority link over the `LinkIndicator` on the toolbar. + 이 링크가 활성화되어 있거나 사용자가 다른 우선 순위 링크를 선택하면 이 링크는 우선 순위 링크로 유지됩니다. - ![Prioritylink Selection](../../assets/satcom/linkselection.png) + ![Prioritylink Selection](../../assets/satcom/linkselection.png) ## 문제 해결 diff --git a/docs/ko/airframes/airframe_reference.md b/docs/ko/airframes/airframe_reference.md index 4ee1518c4a..0ae87398fc 100644 --- a/docs/ko/airframes/airframe_reference.md +++ b/docs/ko/airframes/airframe_reference.md @@ -618,6 +618,10 @@ div.frame_variant td, div.frame_variant th { Axial SCX10 2 Trail Honcho 유지보수: John Doe <john@example.com>

SYS_AUTOSTART = 51001

+ + NXP B3RB Rover Ackermann + 유지보수: John Doe <john@example.com>

SYS_AUTOSTART = 51002

+ Generic Rover Mecanum 유지보수: John Doe <john@example.com>

SYS_AUTOSTART = 52000

@@ -631,7 +635,16 @@ div.frame_variant td, div.frame_variant th { ### Free-Flyer
- + + + + + + + + + +
공통 출력
  • Motor1: back left thruster, +x thrust
  • Motor2: front left thruster, -x thrust
  • Motor3: back right thruster, +x thrust
  • Motor4: front right thruster, -x thrust
  • Motor5: front left thruster, +y thrust
  • Motor6: front right thruster, -y thrust
  • Motor7: back left thruster, +y thrust
  • Motor8: back right thruster, -y thrust
@@ -641,7 +654,7 @@ div.frame_variant td, div.frame_variant th { - KTH-ATMOS + KTH-ATMOS Maintainer: DISCOWER

SYS_AUTOSTART = 70000

diff --git a/docs/ko/assembly/_assembly.md b/docs/ko/assembly/_assembly.md index 29e71c2760..555111defd 100644 --- a/docs/ko/assembly/_assembly.md +++ b/docs/ko/assembly/_assembly.md @@ -285,13 +285,13 @@ A particular vehicle might have more/fewer motors and actuators, but the wiring The following sections explain each part in more detail. :::tip -If you're using [DroneCAN ESC](../peripherals/esc_motors.md#dronecan) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. +If you're using [DroneCAN ESC](../dronecan/escs.md) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. ::: ### Flight Controller Power Pixhawk FCs require a regulated power supply that can supply at around 5V/3A continuous (check your specific FC)! -This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC transmitter, and low power telemetry radio, but not for motors, actuators, and other peripherals. +This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC receiver, and low power telemetry radio, but not for motors, actuators, and other peripherals. [Power modules](../power_module/index.md) are commonly used to "split off" this regulated power supply for the FC and also to provide measurements of the battery voltage and total current to the whole system — which PX4 can use to estimate power levels. The power module is connected to the FC power port, which is normally labeled `POWER` (or `POWER 1` or `POWER 2` for FCs that have redundant power supply). @@ -426,7 +426,6 @@ They recommend sensors, power systems, and other components from the same manufa - [Drone Components & Parts](../getting_started/px4_basic_concepts.md#drone-components-parts) (Basic Concepts) - [Payloads](../getting_started/px4_basic_concepts.md#payloads) (Basic Concepts) - [Hardware Selection & Setup](../hardware/drone_parts.md) — information about connecting and configuring specific flight controllers, sensors and other peripherals (e.g. airspeed sensor for planes). - - [Mounting the Flight Controller](../assembly/mount_and_orient_controller.md) - [Vibration Isolation](../assembly/vibration_isolation.md) - [Mounting a Compass](../assembly/mount_gps_compass.md) diff --git a/docs/ko/camera/fc_connected_camera.md b/docs/ko/camera/fc_connected_camera.md index d5f9afb870..f8a87bb31a 100644 --- a/docs/ko/camera/fc_connected_camera.md +++ b/docs/ko/camera/fc_connected_camera.md @@ -188,16 +188,16 @@ The following sections are out of date and need retesting. 1. On the PX4 console: - ```shell - camera_trigger test - ``` + ```shell + camera_trigger test + ``` 2. From _QGroundControl_: - Click on **Trigger Camera** in the main instrument panel. - These shots are not logged or counted for geotagging. + Click on **Trigger Camera** in the main instrument panel. + These shots are not logged or counted for geotagging. - ![QGC Test Camera](../../assets/camera/qgc_test_camera.png) + ![QGC Test Camera](../../assets/camera/qgc_test_camera.png) ## Sony QX-1 example (Photogrammetry) diff --git a/docs/ko/camera/mavlink_v1_camera.md b/docs/ko/camera/mavlink_v1_camera.md index 84420f968f..b0984e8e4a 100644 --- a/docs/ko/camera/mavlink_v1_camera.md +++ b/docs/ko/camera/mavlink_v1_camera.md @@ -86,7 +86,7 @@ The document explains how, but in summary: 1. Modify an unused `MAV_n_CONFIG` parameter, such as [MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG), so that it is assigned to port to which your camera is connected. 2. Set the corresponding [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). - This ensures that the right set of MAVLink messages are emitted and forwarded. + This ensures that the right set of MAVLink messages are emitted and forwarded. 3. You may need to set some of the other parameters, depending on your connection - such as the baud rate. Then connect and configure the camera as recommended in its user guide. diff --git a/docs/ko/camera/mavlink_v2_camera.md b/docs/ko/camera/mavlink_v2_camera.md index 8802875469..58f931d717 100644 --- a/docs/ko/camera/mavlink_v2_camera.md +++ b/docs/ko/camera/mavlink_v2_camera.md @@ -112,7 +112,7 @@ The linked document explains how, but in summary: 1. Modify an unused `MAV_n_CONFIG` parameter, such as [MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG), so that it is assigned to port to which you connected the camera/companion computer. 2. Set the corresponding [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). - This ensures that the right set of MAVLink messages are emitted for a companion computer (or camera). + This ensures that the right set of MAVLink messages are emitted for a companion computer (or camera). 3. Set [MAV_2_FORWARD](../advanced_config/parameter_reference.md#MAV_2_FORWARD) to enable forwarding of communications from the port to other ports, such as the one that is connected to the ground station. 4. You may need to set some of the other parameters, depending on your connection type and any particular requirements of the camera on the expected baud rate, and so on. diff --git a/docs/ko/can/index.md b/docs/ko/can/index.md index 137f639189..d628ee0ede 100644 --- a/docs/ko/can/index.md +++ b/docs/ko/can/index.md @@ -1,9 +1,19 @@ -# CAN +# CAN (DroneCAN & Cyphal) [Controller Area Network (CAN)](https://en.wikipedia.org/wiki/CAN_bus) is a robust wired network that allows drone components such as flight controller, ESCs, sensors, and other peripherals, to communicate with each other. -Because it is designed to be democratic and uses differential signaling, it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. + +It is particularly recommended on larger vehicles. + +## 개요 + +CAN it is designed to be democratic and uses differential signaling. +For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN also allows status feedback from peripherals and convenient firmware upgrades over the bus. +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 supports two software protocols for communicating with CAN devices: - [DroneCAN](../dronecan/index.md): PX4 recommends this for most common setups. @@ -18,29 +28,36 @@ In 2022 the project split into two: the original version of UAVCAN (UAVCAN v0) w The differences between the two protocols are outlined in [Cyphal vs. DroneCAN](https://forum.opencyphal.org/t/cyphal-vs-dronecan/1814). ::: -:::warning PX4 does not support other CAN software protocols for drones such as KDECAN (at time of writing). -::: ## 배선 The wiring for CAN networks is the same for both DroneCAN and Cyphal/CAN (in fact, for all CAN networks). -Devices are connected in a chain in any order. +Devices within a network are connected in a _daisy-chain_ in any order (this differs from UARTs peripherals, where you attach just one component per port). + +:::warning +Don't connect each CAN peripheral to a separate CAN port! +Unlike UARTs, CAN peripherals are designed to be daisy chained, with additional ports such as `CAN2` used for [redundancy](redundancy). +::: + At either end of the chain, a 120Ω termination resistor should be connected between the two data lines. Flight controllers and some GNSS modules have built in termination resistors for convenience, thus should be placed at opposite ends of the chain. Otherwise, you can use a termination resistor such as [this one from Zubax Robotics](https://shop.zubax.com/products/uavcan-micro-termination-plug?variant=6007985111069), or solder one yourself if you have access to a JST-GH crimper. The following diagram shows an example of a CAN bus connecting a flight controller to 4 CAN ESCs and a GNSS. +It includes a redundant bus connected to `CAN 2`. ![CAN Wiring](../../assets/can/uavcan_wiring.svg) The diagram does not show any power wiring. Refer to your manufacturer instructions to confirm whether components require separate power or can be powered from the CAN bus itself. +:::info For more information, see [Cyphal/CAN device interconnection](https://wiki.zubax.com/public/cyphal/CyphalCAN-device-interconnection?pageId=2195476) (kb.zubax.com). While the article is written with the Cyphal protocol in mind, it applies equally to DroneCAN hardware and any other CAN setup. For more advanced scenarios, consult with [On CAN bus topology and termination](https://forum.opencyphal.org/t/on-can-bus-topology-and-termination/1685). +::: ### 커넥터 @@ -54,7 +71,30 @@ However, as long as the device firmware supports DroneCAN or Cyphal, it can be u DroneCAN and Cyphal/CAN support using a second (redundant) CAN interface. This is completely optional but increases the robustness of the connection. -All Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +### Flight Controllers with Multiple CAN Ports + +[Flight Controllers](../flight_controller/index.md) may have up to three independent CAN ports, such as `CAN1`, `CAN2`, `CAN3` (neither DroneCAN or Cyphal support more than three). +Note that you can't have both DroneCAN and Cyphal running on PX4 at the same time. + +:::tip +You only _need_ one CAN port to support an arbitrary number of CAN devices using a particular CAN protocol. +Don't connect each CAN peripheral to a separate CAN port! +::: + +Generally you'll daisy all CAN peripherals off a single port, and if there is more than one CAN port, use the second one for [redundancy](redundancy). +If three are three ports, you might use the remaining network for devices that support another CAN protocol. + +The documentation for your flight controller should indicate which ports are supported/enabled. +At runtime you can check what DroneCAN ports are enabled and their status using the following command on the [MAVLink Shell](../debug/mavlink_shell.md) (or some other console): + +```sh +uavcan status +``` + +Note that you can also check the number of supported CAN interfaces for a board by searching for `CONFIG_BOARD_UAVCAN_INTERFACES` in its [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#) configuration file. ## 펌웨어 diff --git a/docs/ko/companion_computer/holybro_pixhawk_jetson_baseboard.md b/docs/ko/companion_computer/holybro_pixhawk_jetson_baseboard.md index a0d29a92bc..be5e958812 100644 --- a/docs/ko/companion_computer/holybro_pixhawk_jetson_baseboard.md +++ b/docs/ko/companion_computer/holybro_pixhawk_jetson_baseboard.md @@ -892,95 +892,95 @@ These instructions approximately mirror the [PX4 Ethernet setup](../advanced_con Next we modify the Jetson IP address to be on the same network as the Pixhawk: 1. Make sure `netplan` is installed. - You can check by running the following command: + You can check by running the following command: - ```sh - netplan -h - ``` + ```sh + netplan -h + ``` - If not, install it using the commands: + If not, install it using the commands: - ```sh - sudo apt update - sudo apt install netplan.io - ``` + ```sh + sudo apt update + sudo apt install netplan.io + ``` 2. Check `system_networkd` is running: - ```sh - sudo systemctl status systemd-networkd - ``` + ```sh + sudo systemctl status systemd-networkd + ``` - You should see output like below if it is active: + You should see output like below if it is active: - ```sh - ● systemd-networkd.service - Network Configuration - Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) - Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago - TriggeredBy: ● systemd-networkd.socket - Docs: man:systemd-networkd.service(8) - Main PID: 2452 (systemd-network) - Status: "Processing requests..." - Tasks: 1 (limit: 18457) - Memory: 2.7M - CPU: 157ms - CGroup: /system.slice/systemd-networkd.service - └─2452 /lib/systemd/systemd-networkd + ```sh + ● systemd-networkd.service - Network Configuration + Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) + Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago + TriggeredBy: ● systemd-networkd.socket + Docs: man:systemd-networkd.service(8) + Main PID: 2452 (systemd-network) + Status: "Processing requests..." + Tasks: 1 (limit: 18457) + Memory: 2.7M + CPU: 157ms + CGroup: /system.slice/systemd-networkd.service + └─2452 /lib/systemd/systemd-networkd - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed - Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - ``` + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed + Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + ``` - If `system_networkd` is not running, it can be enabled using: + If `system_networkd` is not running, it can be enabled using: - ```sh - sudo systemctl start systemd-networkd - sudo systemctl enable systemd-networkd - ``` + ```sh + sudo systemctl start systemd-networkd + sudo systemctl enable systemd-networkd + ``` 3. Open the Netplan configuration file (so we can set up a static IP for the Jetson). - The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). - Below we use `nano` to open the file, but you can use your preferred text editor: + The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). + Below we use `nano` to open the file, but you can use your preferred text editor: - ```sh - sudo nano /etc/netplan/01-netcfg.yaml - ``` + ```sh + sudo nano /etc/netplan/01-netcfg.yaml + ``` 4. Modify the yaml configuration, by overwriting the contents with the following information and then saving: - ```sh - network: - version: 2 - renderer: networkd - ethernets: - eth0: - dhcp4: no - addresses: - - 10.41.10.1/24 - routes: - - to: 0.0.0.0/0 - via: 10.41.10.254 - nameservers: - addresses: - - 10.41.10.254 - ``` + ```sh + network: + version: 2 + renderer: networkd + ethernets: + eth0: + dhcp4: no + addresses: + - 10.41.10.1/24 + routes: + - to: 0.0.0.0/0 + via: 10.41.10.254 + nameservers: + addresses: + - 10.41.10.254 + ``` - This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . + This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . 5. Apply the changes using the following command: - ```sh - sudo netplan apply - ``` + ```sh + sudo netplan apply + ``` The Pixhawk Ethernet address is set to `10.41.10.2` by default, which is on the same subnet. We can test our changes above by pinging the Pixhawk from within the Jetson terminal: diff --git a/docs/ko/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md b/docs/ko/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md index 0081c04f3c..8229e9454e 100644 --- a/docs/ko/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md +++ b/docs/ko/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md @@ -69,15 +69,15 @@ To install the RPi CM4 companion computer: 1. Disconnect the `FAN` wiring. - ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) + ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) 2. Remove these 4 screws on the back side of the baseboard. - ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) + ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) 3. Remove the baseboard case, install the CM4, and use the 4 screws to attach it (as shown): - ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) + ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) 4. Reattach the cover. @@ -115,29 +115,29 @@ To flash a RPi image onto EMMC. 1. Switch Dip-Switch to `RPI`. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) 2. Connect computer to USB-C _CM4 Slave_ port used to power & flash the RPi. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) 3. Get `usbboot`, build it and run it. - ```sh - sudo apt install libusb-1.0-0-dev - git clone --depth=1 https://github.com/raspberrypi/usbboot - cd usbboot - make - sudo ./rpiboot - ``` + ```sh + sudo apt install libusb-1.0-0-dev + git clone --depth=1 https://github.com/raspberrypi/usbboot + cd usbboot + make + sudo ./rpiboot + ``` 4. You can now install your preferred Linux distro using The `rpi-imager`. - Make sure you add WiFi and SSH settings (hidden behind the gear/advanced symbol). + Make sure you add WiFi and SSH settings (hidden behind the gear/advanced symbol). - ```sh - sudo apt install rpi-imager - rpi-imager - ``` + ```sh + sudo apt install rpi-imager + rpi-imager + ``` 5. Once done, unplugging USB-C CM4 Slave (this will unmount the volumes, and power off the CM4). @@ -146,8 +146,8 @@ To flash a RPi image onto EMMC. 7. Power on CM4 by providing power to USB-C CM4 Slave port. 8. To check if it's booting/working you can either: - - Check there is HDMI output - - Connect via SSH (if set up in rpi-imager, and WiFi is available). + - Check there is HDMI output + - Connect via SSH (if set up in rpi-imager, and WiFi is available). ## Configure PX4 to CM4 MAVLink Serial Connection @@ -167,13 +167,13 @@ To enable this MAVLink instance on the FC: 1. Connect a computer running QGroundControl via USB Type C port on the baseboard labeled `FC` - ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) + ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) 2. [Set the parameters](../advanced_config/parameters.md): - - `MAV_1_CONFIG` = `102` - - `MAV_1_MODE = 2` - - `SER_TEL2_BAUD` = `921600` + - `MAV_1_CONFIG` = `102` + - `MAV_1_MODE = 2` + - `SER_TEL2_BAUD` = `921600` 3. Reboot the FC. @@ -185,13 +185,13 @@ On the RPi side: 2. 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` - - `serial port hardware enabled` → `Yes` + - Go to `3 Interface Options`, then `I6 Serial Port`. + Then choose: + - `login shell accessible over serial → No` + - `serial port hardware enabled` → `Yes` 3. Finish, and reboot. - This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. + This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. 4. Now MAVLink traffic should be available on `/dev/serial0` at a baudrate of 921600. @@ -201,9 +201,9 @@ On the RPi side: 2. Install MAVSDK Python: - ```sh - python3 -m pip install mavsdk - ``` + ```sh + python3 -m pip install mavsdk + ``` 3. Copy an example from the [MAVSDK-Python examples](https://github.com/mavlink/MAVSDK-Python/tree/main/examples). diff --git a/docs/ko/companion_computer/pixhawk_rpi.md b/docs/ko/companion_computer/pixhawk_rpi.md index 149c44b8bc..8dc16701da 100644 --- a/docs/ko/companion_computer/pixhawk_rpi.md +++ b/docs/ko/companion_computer/pixhawk_rpi.md @@ -132,50 +132,50 @@ Enter the following commands (in sequence) a terminal to configure Ubuntu for RP 1. Install `raspi-config`: - ```sh - sudo apt update - sudo apt upgrade - sudo apt-get install raspi-config - ``` + ```sh + sudo apt update + sudo apt upgrade + sudo apt-get install raspi-config + ``` 2. Open `raspi-config`: - ```sh - sudo raspi-config - ``` + ```sh + sudo raspi-config + ``` 3. 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. + - Select **No** to disable serial login shell. + - Select **Yes** to enable the serial interface. + - Click **Finish** and restart the RPi. 4. Open the firmware boot configuration file in the `nano` editor on RPi: - ```sh - sudo nano /boot/firmware/config.txt - ``` + ```sh + sudo nano /boot/firmware/config.txt + ``` 5. Append the following text to the end of the file (after the last line): - ```sh - enable_uart=1 - dtoverlay=disable-bt - ``` + ```sh + enable_uart=1 + dtoverlay=disable-bt + ``` 6. 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**. + - In `nano` you can save the file using the following sequence of keyboard shortcuts: **ctrl+x**, **ctrl+y**, **Enter**. 7. Check that the serial port is available. - In this case we use the following terminal commands to list the serial devices: + In this case we use the following terminal commands to list the serial devices: - ```sh - cd / - ls /dev/ttyAMA0 - ``` + ```sh + cd / + ls /dev/ttyAMA0 + ``` - The result of the command should include the RX/TX connection `/dev/ttyAMA0` (note that this serial port is also available as `/dev/serial0`). + The result of the command should include the RX/TX connection `/dev/ttyAMA0` (note that this serial port is also available as `/dev/serial0`). The RPi is now setup to work with RPi and communicate using the `/dev/ttyAMA0` serial port. Note that we'll install more software in the following sections to work with MAVLink and ROS 2. @@ -199,39 +199,39 @@ First check the Pixhawk `TELEM 2` configuration: 2. Open QGroundControl (the vehicle should connect). 3. [Check/change the following parameters](../advanced_config/parameters.md) in QGroundControl: - ```ini - MAV_1_CONFIG = TELEM2 - UXRCE_DDS_CFG = 0 (Disabled) - SER_TEL2_BAUD = 57600 - ``` + ```ini + MAV_1_CONFIG = TELEM2 + UXRCE_DDS_CFG = 0 (Disabled) + SER_TEL2_BAUD = 57600 + ``` - Note that the parameters may already be set appropriately. - For information about how serial ports and MAVLink configuration work see [Serial Port Configuration](../peripherals/serial_configuration.md) and [MAVLink Peripherals](../peripherals/mavlink_peripherals.md). + Note that the parameters may already be set appropriately. + For information about how serial ports and MAVLink configuration work see [Serial Port Configuration](../peripherals/serial_configuration.md) and [MAVLink Peripherals](../peripherals/mavlink_peripherals.md). Then install setup MAVProxy on the RPi using the following terminal commands: 1. Install MAVProxy: - ```sh - sudo apt install python3-pip - sudo pip3 install mavproxy - sudo apt remove modemmanager - ``` + ```sh + sudo apt install python3-pip + sudo pip3 install mavproxy + sudo apt remove modemmanager + ``` 2. Run MAVProxy, setting the port to connect to `/dev/ttyAMA0` and the baud rate to match the PX4: - ```sh - sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 - ``` + ```sh + sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 + ``` - ::: info - Note that above we used `/dev/serial0`, but we could equally well have used `/dev/ttyAMA0`. - If we were connecting via USB then we would instead set the port as `/dev/ttyACM0`: + ::: info + Note that above we used `/dev/serial0`, but we could equally well have used `/dev/ttyAMA0`. + If we were connecting via USB then we would instead set the port as `/dev/ttyACM0`: - ```sh - sudo chmod a+rw /dev/ttyACM0 - sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 - ``` + ```sh + sudo chmod a+rw /dev/ttyACM0 + sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 + ``` ::: @@ -259,27 +259,27 @@ The configuration steps are: 2. [Check/change the following parameters](../advanced_config/parameters.md) in QGroundControl: - ```ini - MAV_1_CONFIG = 0 (Disabled) - UXRCE_DDS_CFG = 102 (TELEM2) - SER_TEL2_BAUD = 921600 - ``` + ```ini + MAV_1_CONFIG = 0 (Disabled) + UXRCE_DDS_CFG = 102 (TELEM2) + SER_TEL2_BAUD = 921600 + ``` - [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) and [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) disable MAVLink on TELEM2 and enable the uXRCE-DDS client on TELEM2, respectively. - The `SER_TEL2_BAUD` rate sets the comms link data rate.\ - You could similarly configure a connection to `TELEM1` using either `MAV_1_CONFIG` or `MAV_0_CONFIG`. + [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) and [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) disable MAVLink on TELEM2 and enable the uXRCE-DDS client on TELEM2, respectively. + The `SER_TEL2_BAUD` rate sets the comms link data rate. + You could similarly configure a connection to `TELEM1` using either `MAV_1_CONFIG` or `MAV_0_CONFIG`. - ::: info - You will need to reboot the flight controller to apply any changes to these parameters. + ::: info + You will need to reboot the flight controller to apply any changes to these parameters. ::: 3. Check that the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module is now running. - YOu can do this by running the following command in the QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): + YOu can do this by running the following command in the QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - ```sh - uxrce_dds_client status - ``` + ```sh + uxrce_dds_client status + ``` :::info If the client module is not running you can start it manually in the MAVLink console: @@ -300,32 +300,32 @@ The steps to setup ROS 2 and the Micro XRCE-DDS Agent on the RPi are: 2. Install the git using the RPi terminal: - ```sh - sudo apt install git - ``` + ```sh + sudo apt install git + ``` 3. Install the uXRCE_DDS agent: - ```sh - git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` - See [uXRCE-DDS > Micro XRCE-DDS Agent Installation](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) for alternative ways of installing the agent. + See [uXRCE-DDS > Micro XRCE-DDS Agent Installation](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) for alternative ways of installing the agent. 4. Start the agent in the RPi terminal: - ```sh - sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 - ``` + ```sh + sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 + ``` - Note how we use the serial port set up earlier and the same baud rate as for PX4. + Note how we use the serial port set up earlier and the same baud rate as for PX4. Now that both the agent and client are running, you should see activity on both the MAVLink console and the RPi terminal. You can view the available topics using the following command on the RPi: diff --git a/docs/ko/companion_computer/video_streaming_wfb_ng_wifi.md b/docs/ko/companion_computer/video_streaming_wfb_ng_wifi.md index c8c752c6cc..d6350cf92b 100644 --- a/docs/ko/companion_computer/video_streaming_wfb_ng_wifi.md +++ b/docs/ko/companion_computer/video_streaming_wfb_ng_wifi.md @@ -80,18 +80,18 @@ If you use a special "very" high power cards from Taobao/Aliexpress then you MUS 5. Setup camera pipeline. Open `/etc/systemd/system/fpv-camera.service` and uncomment pipeline according to your camera (PI camera or Logitech camera) 6. Open `/etc/wifibroadcast.cfg` and configure WiFi channel according to your antenna setup (or use default #165 for 5.8GHz) 7. Configure PX4 to output telemetry stream at speed 1500 Kbps (other UART speeds doesn't match well to RPi frequency dividers). - Connect Pixhawk UART to Raspberry Pi UART. - In `/etc/wifibroadcast.cfg` uncomment `peer = 'serial:ttyS0:1500000'` in `[drone_mavlink]` section. + Connect Pixhawk UART to Raspberry Pi UART. + In `/etc/wifibroadcast.cfg` uncomment `peer = 'serial:ttyS0:1500000'` in `[drone_mavlink]` section. ### Using a Linux Laptop as GCS (Harder than using a RPi) 1. On **ground** Linux development computer: - ```sh - sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted - git clone -b stable https://github.com/svpcom/wfb-ng.git - cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb - ``` + ```sh + sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted + git clone -b stable https://github.com/svpcom/wfb-ng.git + cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb + ``` 2. Follow the [Setup HOWTO](https://github.com/svpcom/wfb-ng/wiki/Setup-HOWTO) to complete installation diff --git a/docs/ko/complete_vehicles_mc/amov_F410_drone.md b/docs/ko/complete_vehicles_mc/amov_F410_drone.md index 94ca9e2fb5..8299e20a35 100644 --- a/docs/ko/complete_vehicles_mc/amov_F410_drone.md +++ b/docs/ko/complete_vehicles_mc/amov_F410_drone.md @@ -22,7 +22,7 @@ It is pre-installed with PX4 v1.15.4 at time of writing (a more recent version m - Compatibility with many different components, providing platform for loading other user sensors, preparing for functional model development. - Abundant power supply making it perfect for installing additional sensors and onboard computers (including 5 external output voltages, 3 channels of 5V, 2 channels of 12V). - Pc-SDK support. - This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! + This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! - The [documentation](https://docs.amovlab.com/f450-v6c-wiki/#/en/) shows many of the options. 7. Quasi-smart battery. The battery has a hard housing design that makes easy to install and remove. It provides accurate power estimates, but does not have some more advanced "smart battery" features. diff --git a/docs/ko/complete_vehicles_mc/crazyflie2.md b/docs/ko/complete_vehicles_mc/crazyflie2.md index 7ed011efe1..14dde9d1af 100644 --- a/docs/ko/complete_vehicles_mc/crazyflie2.md +++ b/docs/ko/complete_vehicles_mc/crazyflie2.md @@ -51,54 +51,54 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the source code of the PX4 Bootloader: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git + ``` 2. Navigate into the top directory of the source code and compile it using: - ```sh - make crazyflie_bl - ``` + ```sh + make crazyflie_bl + ``` 3. Put the Crazyflie 2.0 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Hold down the reset button (see figure below...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Hold down the reset button (see figure below...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 4. Install _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.0 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin + ``` - When powering on the Crazyflie 2.0 the yellow LED should blink. + When powering on the Crazyflie 2.0 the yellow LED should blink. 6. Download the source code of the PX4 autopilot: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Navigate into the top directory of the source code and compile it using: - ```sh - make bitcraze_crazyflie_default upload - ``` + ```sh + make bitcraze_crazyflie_default upload + ``` 8. When prompted to plug in device, plug in Crazyflie 2.0. - The yellow LED should start blinking indicating bootloader mode. - Then the red LED should turn on indicating that the flashing process has started. + The yellow LED should start blinking indicating bootloader mode. + Then the red LED should turn on indicating that the flashing process has started. 9. Wait for completion. diff --git a/docs/ko/complete_vehicles_mc/crazyflie21.md b/docs/ko/complete_vehicles_mc/crazyflie21.md index a2e19aaecd..4a76f17b6a 100644 --- a/docs/ko/complete_vehicles_mc/crazyflie21.md +++ b/docs/ko/complete_vehicles_mc/crazyflie21.md @@ -64,56 +64,56 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the source code of the PX4 Bootloader: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules + ``` 2. Navigate into the top directory of the source code and compile it using: - ```sh - make crazyflie21_bl - ``` + ```sh + make crazyflie21_bl + ``` 3. Put the Crazyflie 2.1 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Ensure battery is disconnected. - - Hold down the reset button (see figure below...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Ensure battery is disconnected. + - Hold down the reset button (see figure below...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 4. Install _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.1 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin + ``` - When powering on the Crazyflie 2.1 the yellow LED should blink. + When powering on the Crazyflie 2.1 the yellow LED should blink. 6. Download the source code of the PX4 autopilot: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Navigate into the top directory of the source code and compile it using: - ```sh - cd PX4-Autopilot/ - make bitcraze_crazyflie21_default upload - ``` + ```sh + cd PX4-Autopilot/ + make bitcraze_crazyflie21_default upload + ``` 8. When prompted to plug in device, plug in Crazyflie 2.1. - The yellow LED should start blinking indicating bootloader mode. - Then the red LED should turn on indicating that the flashing process has started. + The yellow LED should start blinking indicating bootloader mode. + Then the red LED should turn on indicating that the flashing process has started. 9. Wait for completion. @@ -124,20 +124,20 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the latest [Crazyflie 2.1 bootloader](https://github.com/bitcraze/crazyflie2-stm-bootloader/releases) 2. Put the Crazyflie 2.1 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Ensure battery is disconnected. - - Hold down the reset button. - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Ensure battery is disconnected. + - Hold down the reset button. + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 3. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.1 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin + ``` - When powering on the Crazyflie 2.1 the yellow LED should blink. + When powering on the Crazyflie 2.1 the yellow LED should blink. 4. Install the latest Bitcraze Crazyflie 2.1 Firmware using [this](https://www.bitcraze.io/documentation/tutorials/getting-started-with-crazyflie-2-x/#update-fw) tutorial. diff --git a/docs/ko/complete_vehicles_mc/modalai_starling.md b/docs/ko/complete_vehicles_mc/modalai_starling.md index faac2fb639..5e23e68c72 100644 --- a/docs/ko/complete_vehicles_mc/modalai_starling.md +++ b/docs/ko/complete_vehicles_mc/modalai_starling.md @@ -1,127 +1,39 @@ -# ModalAI Starling (PX4 Autonomy Developer Kit) +# ModalAI Starling 2 -The [Starlings](https://www.modalai.com/pages/starlings) are SLAM development drones supercharged by [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -Powered by Blue UAS Framework autopilot, VOXL 2, the Starling weighs only 275g and boasts an impressive 30 minutes of autonomous indoor flight time. +The [Starlings](https://www.modalai.com/pages/starlings) are NDAA-compliant SLAM development drones based on the [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -![Overview](../../assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg) +## 개요 -The ModalAI PX4 Autonomy Developer Kit is a Starling-based development drone. -It houses a [VOXL 2](../flight_controller/modalai_voxl_2.md), which is a powerful companion computer and PX4 flight controller in one small package, image sensors, GPS, and connectivity modem, and is ready-to-fly out-of-the-box. -The Starling features ModalAI's [open SDK](https://docs.modalai.com/voxl-developer-bootcamp/) that has pre-configured autonomy models for computer vision assisted flight. -This development drone is meant to help you get to market faster and accelerate your application development and prototyping. +Starling drones house _VOXL 2_, which is a powerful companion computer, a PX4 flight controller, image sensors, GPS, and connectivity modem, in one small package. +The Starlings feature ModalAI's open source [VOXL SDK](https://gitlab.com/voxl-public/voxl-sdk) that has pre-configured autonomy models for computer vision assisted flight. -This guide explains the minimal additional setup required to get the UAV ready to fly. -It also covers a hardware overview, first flight, setting up WiFi, and more. - -:::info -For complete and regularly updated documentation, please visit . -::: +These development drones are ready-to-fly out-of-the-box. +They are designed to help you get to market faster and accelerate your application development and prototyping. :::info If you are new to VOXL, be sure to familiarize yourself with the core features of VOXL hardware and software by reviewing the [VOXL Bootcamp](https://docs.modalai.com/voxl-developer-bootcamp/). ::: +:::info +For complete and regularly updated documentation, please visit and . +::: + +## Starling 2 + +The [Starling 2](https://www.modalai.com/products/starling-2) is an NDAA-compliant development drone supercharged by the VOXL SDK and equipped with a new image sensor suite for precise, indoor visual navigation and SLAM. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 weighs 280g and boasts an impressive 40 minutes of autonomous flight time. + +![Image of the front of Starling 2](../../assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png) + +## Starling 2 Max + +The [Starling 2 Max](https://www.modalai.com/products/starling-2-max) is VOXL 2-powered, NDAA-compliant development drone supercharged by VOXL SDK specifically designed for computer vision-based, long-range dead reckoning with a 500g payload capacity. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 Max weighs 500g and boasts an impressive 55 minutes of autonomous flight time. + +![Image of front of a Starling 2 Max](../../assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png) + ## 구매처 -[ModalAI PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit?variant=46969885950256) +[ModalAI Starling 2](https://www.modalai.com/products/starling-2) -## Hardware Overview - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg) - -| Callout | 설명 | MPN | -| ------- | -------------------------------------------------------- | ---------------- | -| A | VOXL 2 | MDK-M0054-1 | -| B | VOXL 4-in-1 ESC | MDK-M0117-1 | -| C | Barometer Shield Cap | M10000533 | -| D | ToF Image Sensor (PMD) | MDK-M0040 | -| E | Tracking Image Sensor (OV7251) | M0014 | -| F | Hires Image Sensor (IMX214) | M0025-2 | -| G | AC600 WiFi Dongle | AWUS036EACS | -| H | GNSS GPS Module & Compass | M10-5883 | -| I | 915MHz ELRS Receiver | BetaFPV Nano RX | -| J | USB C Connector on VOXL 2 (not shown) | | -| K | VOXL Power Module | MCCA-M0041-5-B-T | -| L | 4726FM Propellor | M10000302 | -| M | Motor 1504 | | -| N | XT30 Power Connector | | - -## Datasheet - -### 사양 - -| 부품 | 사양 | -| --------------- | ----------------------------------------------------------------- | -| 오토파일럿 | VOXL2 | -| Take-off Weight | 275g (172g without battery) | -| Diagonal Size | 211mm | -| Flight Time | > 30 minutes | -| 모터 | 1504 | -| Propellers | 120mm | -| 프레임 | 3mm Carbon Fiber | -| ESC | ModalAI VOXL 4-in-1 ESC V2 | -| GPS | UBlox M10 | -| 무선 수신기 | 915mhz ELRS | -| 전원 모듈 | ModalAI Power Module v3 - 5V/6A | -| Battery | Sony VTC6 3000mah 2S, or any 2S 18650 battery with XT30 connector | -| 고도 | 83mm | -| Width | 187mm (Props folded) | -| Length | 142mm (Props folded) | - -### Hardware Wiring Diagram - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg) - -## Tutorials - -### ELRS Set Up - -Binding your ELRS (ExpressLRS) receiver to a transmitter is a crucial step in preparing your VOXL 2 based PX4 Autonomy Developer Kit by ModalAI for flight. -This process ensures a secure and responsive connection between your drone and its control system. - -Follow this guide to bind your ELRS receiver to your transmitter. - -#### Setting up the Receiver - -1. **Power On the Receiver**: Once your drone is powered on, you'll notice the ELRS receiver's blue LED flashing. - This is an indication that the receiver is on but has not yet established a connection with a transmitter. - - ![Starling Receiver](../../assets/hardware/complete_vehicles/modalai_starling/starling-photo.png) - -2. **Enter Binding Mode**: To initiate binding, open a terminal and execute the `adb shell` and `voxl-elrs -bind` commands. - You'll observe the receiver's LED switch to a flashing in a heartbeat pattern, signaling that it is now in binding mode. - - ![Boot Screenshot](../../assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png) - -#### Setting up the Transmitter - -1. **Access the Menu**: On your Commando 8 radio transmitter included in the kit, press the left mode button to open the menu system. - - ![Press Menu on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-1.png) - -2. **Navigate to ExpressLRS**: Use the right button to select the first menu entry, which should be "ExpressLRS." - -3. **Find the Bind Option**: With the "ExpressLRS" option selected, scroll down to the bottom of the menu to locate the "Bind" section. This can be done by pressing the right button downwards until you reach the "Bind" option. - - ![Press Binding on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-2.png) - -4. **Initiate Binding**: Select "Bind" to put the transmitter into binding mode. You will know the process has been successful when the transmitter emits a beep, indicating a successful bind. - -#### Completing the Binding Process - -Once the transmitter is set to bind mode, the ELRS receiver on the drone will change its LED from flashing to a steady light, signifying a successful connection between the receiver and the transmitter. - -- **Power Cycle**: After the binding process is complete, it's essential to power cycle the VOXL 2 before attempting to fly. - This means turning off the VOXL 2 and then turning it back on. - This step ensures that all settings are properly applied and that the system recognizes the newly established connection. - -You should now have a successfully bound ELRS receiver to your transmitter, ready for use with the PX4 Autonomy Kit by ModalAI. -A secure connection is vital for the reliable operation of your drone, so always confirm the binding status before flight. - -### 비디오 - -- [VOXL 2 Starling Hardware Overview](https://youtu.be/M9OiMpbEYOg) -- [VOXL 2 Starling First Flight Tutorial](https://youtu.be/Cpbbye3Z6co) -- [VOXL 2 Starling ELRS Set Up](https://youtu.be/7OwGS-kcFVg) +[ModalAI Starling 2 Max](https://www.modalai.com/products/starling-2-max) diff --git a/docs/ko/complete_vehicles_mc/px4_vision_kit.md b/docs/ko/complete_vehicles_mc/px4_vision_kit.md index 3322995f53..732cca2f3b 100644 --- a/docs/ko/complete_vehicles_mc/px4_vision_kit.md +++ b/docs/ko/complete_vehicles_mc/px4_vision_kit.md @@ -42,17 +42,17 @@ This kit is still highly recommended for developing and testing vision solutions ## Warnings and Notifications 1. The kit is intended for computer vision projects that use a forward-facing camera (it does not have downward or rear-facing depth cameras). - Consequently it can't be used (without modification) for testing features that require a downward-facing camera. + Consequently it can't be used (without modification) for testing features that require a downward-facing camera. 2. Obstacle avoidance in missions can only be tested when GPS is available (missions use GPS coordinates). - Collision prevention can be tested in position mode provided there is a good position lock from either GPS or optical flow. + Collision prevention can be tested in position mode provided there is a good position lock from either GPS or optical flow. 3. The port labeled `USB1` may jam the GPS if used with a _USB3_ peripheral (disable GPS-dependent functionality including missions). - This is why the boot image is supplied on a _USB2.0_ memory stick. + This is why the boot image is supplied on a _USB2.0_ memory stick. 4. PX4 Vision v1 with ECN 010 or above (carrier board RC05 and up), the _UP Core_ can be powered by either the DC plug or with battery. - ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) + ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) 5. All PX4 Vision v1.5 _UP Core_ can be powered by either the DC plug or with battery. @@ -132,37 +132,37 @@ In addition, users will need ground station hardware/software: ## First-time Setup 1. Attach a [compatible RC receiver](../getting_started/rc_transmitter_receiver.md#connecting-receivers) to the vehicle (not supplied with kit): - - Remove/unscrew the top plate (where the battery goes) using an H2.0 hex key tool. - - [Connect the receiver to the flight controller](../assembly/quick_start_pixhawk4.md#radio-control). - - Re-attach the top plate. - - Mount the RC receiver on the _UP Core_ carrier board plate at the back of the vehicle (use zipties or double-sided tape). - - Ensure the antennas are clear of any obstructions and electrically isolated from the frame (e.g. secure them under the carrier board or to the vehicle arms or legs). + - Remove/unscrew the top plate (where the battery goes) using an H2.0 hex key tool. + - [Connect the receiver to the flight controller](../assembly/quick_start_pixhawk4.md#radio-control). + - Re-attach the top plate. + - Mount the RC receiver on the _UP Core_ carrier board plate at the back of the vehicle (use zipties or double-sided tape). + - Ensure the antennas are clear of any obstructions and electrically isolated from the frame (e.g. secure them under the carrier board or to the vehicle arms or legs). 2. [Bind](../getting_started/rc_transmitter_receiver.md#binding) the RC ground and air units (if not already done). - The binding procedure depends on the specific radio system used (read the receiver manual). + The binding procedure depends on the specific radio system used (read the receiver manual). 3. Raise the GPS mast to the vertical position and screw the cover onto the holder on the base plate. (Not required for v1.5) - ![Raise GPS mast](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) + ![Raise GPS mast](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) 4. Insert the pre-imaged USB2.0 stick from the kit into the _UP Core_ port labeled `USB1` (highlighted below). - ![UP Core: USB1 Port ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) + ![UP Core: USB1 Port ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) 5. Power the vehicle with a fully charged battery. - ::: info - Ensure propellers are removed before connecting the battery. + ::: info + Ensure propellers are removed before connecting the battery. ::: 6. Connect the ground station to the vehicle WiFi network (after a few seconds) using the following default credentials: - - **SSID:** pixhawk4 - - **Password:** pixhawk4 + - **SSID:** pixhawk4 + - **Password:** pixhawk4 - :::tip - WiFi network SSID, password, and other credentials may be changed after connecting (if desired), by using a web browser to open the URL: `http://192.168.4.1`. - The baud rate must not be changed from 921600. + :::tip + WiFi network SSID, password, and other credentials may be changed after connecting (if desired), by using a web browser to open the URL: `http://192.168.4.1`. + The baud rate must not be changed from 921600. ::: @@ -170,39 +170,39 @@ In addition, users will need ground station hardware/software: 8. [Configure/calibrate](../config/index.md) the vehicle: - ::: info - The vehicle should arrive pre-calibrated (e.g. with firmware, airframe, battery, and sensors all setup). - You will however need to calibrate the radio system (that you just connected) and it is often worth re-doing the compass calibration. + ::: info + The vehicle should arrive pre-calibrated (e.g. with firmware, airframe, battery, and sensors all setup). + You will however need to calibrate the radio system (that you just connected) and it is often worth re-doing the compass calibration. ::: - - [Calibrate the Radio System](../config/radio.md) - - [Calibrate the Compass](../config/compass.md) + - [Calibrate the Radio System](../config/radio.md) + - [Calibrate the Compass](../config/compass.md) 9. (Optional) Configure a [Flight Mode selector switch](../config/flight_mode.md) on the remote controller. - ::: info - Modes can also be changed using _QGroundControl_ + ::: info + Modes can also be changed using _QGroundControl_ ::: - We recommend RC controller switches are define for: + We recommend RC controller switches are define for: - - [Position Mode](../flight_modes_mc/position.md) - a safe manual flight mode that can be used to test collision prevention. - - [Mission Mode](../flight_modes_mc/mission.md) - run missions and test obstacle avoidance. - - [Return Mode](../flight_modes_mc/return.md) - return vehicle safely to its launch point and land. + - [Position Mode](../flight_modes_mc/position.md) - a safe manual flight mode that can be used to test collision prevention. + - [Mission Mode](../flight_modes_mc/mission.md) - run missions and test obstacle avoidance. + - [Return Mode](../flight_modes_mc/return.md) - return vehicle safely to its launch point and land. 10. Attach the propellers with the rotations as shown: - ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) + ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) - - The propellers directions can be determined from the labels: _6045_ (normal, counter-clockwise) and _6045_**R** (reversed, clockwise). + - The propellers directions can be determined from the labels: _6045_ (normal, counter-clockwise) and _6045_**R** (reversed, clockwise). - ![Propeller identification](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) + ![Propeller identification](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) - - Screw down firmly using the provided propellor nuts: + - Screw down firmly using the provided propellor nuts: - ![Propeller nuts](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) + ![Propeller nuts](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) ## Fly the Drone with Avoidance @@ -212,30 +212,30 @@ When the vehicle setup described above is complete: 2. Wait until the boot sequence completes and the avoidance system has started (the vehicle will reject arming commands during boot). - :::tip - The boot/startup process takes around 1 minute from the supplied USB stick (or 30 seconds from [internal memory](#install_image_mission_computer)). + :::tip + The boot/startup process takes around 1 minute from the supplied USB stick (or 30 seconds from [internal memory](#install_image_mission_computer)). ::: 3. Check that the avoidance system has started properly: - - The _QGroundControl_ notification log displays the message: **Avoidance system connected**. + - The _QGroundControl_ notification log displays the message: **Avoidance system connected**. - ![QGC Log showing avoidance system has started](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) + ![QGC Log showing avoidance system has started](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) - - A red laser is visible on the front of the _Structure Core_ camera. + - A red laser is visible on the front of the _Structure Core_ camera. 4. Wait for the GPS LED to turn green. - This means that the vehicle has a GPS fix and is ready to fly! + This means that the vehicle has a GPS fix and is ready to fly! 5. Connect the ground station to the vehicle WiFi network. 6. Find a safe outdoor location for flying, ideally with a tree or some other convenient obstacle for testing PX4 Vision. 7. To test [collision prevention](../computer_vision/collision_prevention.md), enable [Position Mode](../flight_modes_mc/position.md) and fly manually towards an obstacle. - The vehicle should slow down and then stop within 6m of the obstacle (the distance can be [changed](../advanced_config/parameters.md) using the [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST) parameter). + The vehicle should slow down and then stop within 6m of the obstacle (the distance can be [changed](../advanced_config/parameters.md) using the [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST) parameter). 8. To test obstacle avoidance, create a mission where the path is blocked by an obstacle. - Then switch to [Mission Mode](../flight_modes_mc/mission.md) to run the mission, and observe the vehicle moving around the obstacle and then returning to the planned course. + Then switch to [Mission Mode](../flight_modes_mc/mission.md) to run the mission, and observe the vehicle moving around the obstacle and then returning to the planned course. ## Development using the Kit @@ -280,22 +280,22 @@ To flash the USB image to the _UP Core_: 2. [Login to the companion computer](#login_mission_computer) (as described above). 3. Open a terminal and run the following command to copy the image onto internal memory (eMMC). - The terminal will prompt for a number of responses during the flashing process. + The terminal will prompt for a number of responses during the flashing process. - ```sh - cd ~/catkin_ws/src/px4vision_ros/tools - sudo ./flash_emmc.sh - ``` + ```sh + cd ~/catkin_ws/src/px4vision_ros/tools + sudo ./flash_emmc.sh + ``` - ::: info - All information saved in the _UP Core_ computer will be removed when executing this script. + ::: info + All information saved in the _UP Core_ computer will be removed when executing this script. ::: 4. Pull out the USB stick. 5. Restart the vehicle. - The _UP Core_ computer will now boot from internal memory (eMMC). + The _UP Core_ computer will now boot from internal memory (eMMC). ### Boot the Companion Computer @@ -319,23 +319,23 @@ To login to the companion computer: 1. Connect a keyboard and mouse to the _UP Core_ via port `USB2`: - ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) + ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) - - Use the USB-JST cable from the kit to get a USB A connector + - Use the USB-JST cable from the kit to get a USB A connector - ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) + ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) - - A USB hub can be attached to the cable if the keyboard and mouse have separate connectors. + - A USB hub can be attached to the cable if the keyboard and mouse have separate connectors. 2. Connect a monitor to the _UP Core_ HDMI port. - ![UP Core: HDMI port](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) + ![UP Core: HDMI port](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) - The Ubuntu login screen should then appear on the monitor. + The Ubuntu login screen should then appear on the monitor. 3. Login to the _UP Core_ using the credentials: - - **Username:** px4vision - - **Password:** px4vision + - **Username:** px4vision + - **Password:** px4vision ### Developing/Extending PX4 Avoidance @@ -350,39 +350,39 @@ To integrate a different planner, this needs to be disabled. 1. Disable the avoidance process using the following command: - ```sh - systemctl stop avoidance.service - ``` + ```sh + systemctl stop avoidance.service + ``` - You can simply reboot the machine to restart the service. + You can simply reboot the machine to restart the service. - Other useful commands are: + Other useful commands are: - ```sh - # restart service - systemctl start avoidance.service + ```sh + # restart service + systemctl start avoidance.service - # disable service (stop service and do not restart after boot) - systemctl disable avoidance.service + # disable service (stop service and do not restart after boot) + systemctl disable avoidance.service - # enable service (start service and enable restart after boot) - systemctl enable avoidance.service - ``` + # enable service (start service and enable restart after boot) + systemctl enable avoidance.service + ``` 2. The source code of the obstacle avoidance package can be found in https://github.com/PX4/PX4-Avoidance which is located in `~/catkin_ws/src/avoidance`. 3. Make changes to the code! To get the latest code of avoidance pull the code from the avoidance repo: - ```sh - git pull origin - git checkout origin/master - ``` + ```sh + git pull origin + git checkout origin/master + ``` 4. Build the package - ```sh - catkin build local_planner - ``` + ```sh + catkin build local_planner + ``` The ROS workspace is placed in `~/catkin_ws`. For reference on developing in ROS and using the catkin workspace, see the [ROS catkin tutorials](https://wiki.ros.org/catkin/Tutorials). diff --git a/docs/ko/complete_vehicles_rover/aion_r1.md b/docs/ko/complete_vehicles_rover/aion_r1.md index 51ec65d57c..7399c97675 100644 --- a/docs/ko/complete_vehicles_rover/aion_r1.md +++ b/docs/ko/complete_vehicles_rover/aion_r1.md @@ -54,15 +54,15 @@ Use _QGroundControl_ for rover configuration: First configure the serial connection: 1. Navigate to the [Parameters](../advanced_config/parameters.md) section in QGroundControl. - - Set the [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) parameter to the serial port to which the RoboClaw is connected (such as `GPS2`). - - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) specifies the number of encoder counts required for one wheel revolution. - This value should be left at `1200` for the tested `RoboClaw 2x15A Motor Controller`. - Adjust the value based on your specific encoder and wheel setup. - - RoboClaw motor controllers must be assigned a unique address on the bus. - The default address is 128 and you should not need to change this (if you do, update the PX4 parameter [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) to match). + - Set the [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) parameter to the serial port to which the RoboClaw is connected (such as `GPS2`). + - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) specifies the number of encoder counts required for one wheel revolution. + This value should be left at `1200` for the tested `RoboClaw 2x15A Motor Controller`. + Adjust the value based on your specific encoder and wheel setup. + - RoboClaw motor controllers must be assigned a unique address on the bus. + The default address is 128 and you should not need to change this (if you do, update the PX4 parameter [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) to match). - ::: info - PX4 does not support multiple RoboClaw motor controllers in the same vehicle — each controller needs a unique address on the bus, and there is only one parameter for setting the address in PX4 (`RBCLW_ADDRESS`). + ::: info + PX4 does not support multiple RoboClaw motor controllers in the same vehicle — each controller needs a unique address on the bus, and there is only one parameter for setting the address in PX4 (`RBCLW_ADDRESS`). ::: @@ -71,12 +71,12 @@ Then configure the actuator configuration: 1. Navigate to [Actuators Configuration & Testing](../config/actuators.md) in QGroundControl. 2. Select the RoboClaw driver from the list of _Actuator Outputs_. - For the channel assignments, disarm, minimum, and maximum values, please refer to the image below. + For the channel assignments, disarm, minimum, and maximum values, please refer to the image below. - ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) + ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) - For systems with more than two motors, it is possible to assign the same function to several motors. - The reason for the unusual values, can be found in the [RoboClaw User Manual](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) under `Compatibility Commands` for `Packet Serial`: + For systems with more than two motors, it is possible to assign the same function to several motors. + The reason for the unusual values, can be found in the [RoboClaw User Manual](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) under `Compatibility Commands` for `Packet Serial`: ```plain Drive motor forward. Valid data range is 0 - 127. A value of 127 = full speed forward, 64 = diff --git a/docs/ko/computer_vision/collision_prevention.md b/docs/ko/computer_vision/collision_prevention.md index 08f02cef31..b8e9a0ef2a 100644 --- a/docs/ko/computer_vision/collision_prevention.md +++ b/docs/ko/computer_vision/collision_prevention.md @@ -203,85 +203,85 @@ The Lua script works by extracting the `obstacle_distance_fused` data at each ti 2. Configure PX4 to publish obstacle distance data (so that it is available to PlotJuggler): - Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: + Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: - ```sh - - topic: /fmu/out/obstacle_distance_fused - type: px4_msgs::msg::ObstacleDistance - ``` + ```sh + - topic: /fmu/out/obstacle_distance_fused + type: px4_msgs::msg::ObstacleDistance + ``` - For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. + For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. 3. Open PlotJuggler and navigate to the **Tools > Reactive Script Editor** section. - In the **Script Editor** tab, add following scripts in the appropriate sections: + In the **Script Editor** tab, add following scripts in the appropriate sections: - - **Global code, executed once:** + - **Global code, executed once:** - ```lua - obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") - obs_dist_min = Timeseries.new("obstacle_distance_minimum") - ``` + ```lua + obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") + obs_dist_min = Timeseries.new("obstacle_distance_minimum") + ``` - - **function(tracker_time)** + - **function(tracker_time)** - ```lua - obs_dist_fused_xy:clear() + ```lua + obs_dist_fused_xy:clear() - i = 0 - angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") - increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") - min_dist = 65535 + i = 0 + angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") + increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") + min_dist = 65535 - -- Cache increment and angle_offset values at tracker_time to avoid repeated calls - local angle_offset_value = angle_offset:atTime(tracker_time) - local increment_value = increment:atTime(tracker_time) + -- Cache increment and angle_offset values at tracker_time to avoid repeated calls + local angle_offset_value = angle_offset:atTime(tracker_time) + local increment_value = increment:atTime(tracker_time) - if increment_value == nil or increment_value <= 0 then - print("Invalid increment value: " .. tostring(increment_value)) - return - end + if increment_value == nil or increment_value <= 0 then + print("Invalid increment value: " .. tostring(increment_value)) + return + end - local max_steps = math.floor(360 / increment_value) + local max_steps = math.floor(360 / increment_value) - while i < max_steps do - local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) - local distance = TimeseriesView.find(str) - if distance == nil then - print("No distance data for: " .. str) - break - end + while i < max_steps do + local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) + local distance = TimeseriesView.find(str) + if distance == nil then + print("No distance data for: " .. str) + break + end - local dist = distance:atTime(tracker_time) - if dist ~= nil and dist < 65535 then - -- Calculate angle and Cartesian coordinates - local angle = angle_offset_value + i * increment_value - local y = dist * math.cos(math.rad(angle)) - local x = dist * math.sin(math.rad(angle)) + local dist = distance:atTime(tracker_time) + if dist ~= nil and dist < 65535 then + -- Calculate angle and Cartesian coordinates + local angle = angle_offset_value + i * increment_value + local y = dist * math.cos(math.rad(angle)) + local x = dist * math.sin(math.rad(angle)) - obs_dist_fused_xy:push_back(x, y) + obs_dist_fused_xy:push_back(x, y) - -- Update minimum distance - if dist < min_dist then - min_dist = dist - end - end + -- Update minimum distance + if dist < min_dist then + min_dist = dist + end + end - i = i + 1 - end + i = i + 1 + end - -- Push minimum distance once after the loop - if min_dist < 65535 then - obs_dist_min:push_back(tracker_time, min_dist) - else - print("No valid minimum distance found") - end - ``` + -- Push minimum distance once after the loop + if min_dist < 65535 then + obs_dist_min:push_back(tracker_time, min_dist) + else + print("No valid minimum distance found") + end + ``` 4. Enter a name for the script on the top right, and press **Save**. - Once saved, the script should appear in the _Active Scripts_ section. + Once saved, the script should appear in the _Active Scripts_ section. 5. Start streaming the data using the approach described in [Plotting uORB Topic Data in Real Time using PlotJuggler](../debug/plotting_realtime_uorb_data.md). - You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. + You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. Note that you have to press **Save** again to re-enable the scripts after loading a new log file or otherwise clearing data. diff --git a/docs/ko/computer_vision/visual_inertial_odometry.md b/docs/ko/computer_vision/visual_inertial_odometry.md index 305ee02bf4..9601bae4ce 100644 --- a/docs/ko/computer_vision/visual_inertial_odometry.md +++ b/docs/ko/computer_vision/visual_inertial_odometry.md @@ -125,15 +125,15 @@ Perform the following checks to verify that VIO is working properly _before_ you 이러한 단계가 유지되면, 첫 번째 비행을 시도할 수 있습니다. 1. Put the vehicle on the ground and start streaming `ODOMETRY` feedback (as above). - 스로틀 스틱을 내리고 모터를 작동시키십시오. + 스로틀 스틱을 내리고 모터를 작동시키십시오. - 이때 왼쪽 스틱을 가장 낮은 위치에 놓고, 위치 제어로 전환합니다. - 초록불이 켜져야 합니다. - 녹색 표시등은 위치 피드백을 사용할 수 있고, 위치 제어가 활성화되었음을 알려줍니다. + 이때 왼쪽 스틱을 가장 낮은 위치에 놓고, 위치 제어로 전환합니다. + 초록불이 켜져야 합니다. + 녹색 표시등은 위치 피드백을 사용할 수 있고, 위치 제어가 활성화되었음을 알려줍니다. 2. 기체가 고도를 유지하도록 스로틀 스틱을 중간(데드 존)에 놓습니다. - 스틱을 올리면 기준 고도가 증가하고 값을 낮추면 감소합니다. - Similarly, the other stick will change the position over the ground. + 스틱을 올리면 기준 고도가 증가하고 값을 낮추면 감소합니다. + Similarly, the other stick will change the position over the ground. 3. Increase the value of the throttle stick and the vehicle will take off. Move it back to the middle immediately afterwards. diff --git a/docs/ko/concept/flight_tasks.md b/docs/ko/concept/flight_tasks.md index 435baec653..d8316fa1ba 100644 --- a/docs/ko/concept/flight_tasks.md +++ b/docs/ko/concept/flight_tasks.md @@ -38,24 +38,24 @@ The instructions below might be used to create a task named _MyTask_: - Update the copyright to the current year - ```cmake - ############################################################################ - # - # Copyright (c) 2021 PX4 Development Team. All rights reserved. - # - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2021 PX4 Development Team. All rights reserved. + # + ``` - Modify the code to reflect the new task - e.g. replace `FlightTaskOrbit` with `FlightTaskMyTask`. - The code will look something like this: + The code will look something like this: - ```cmake - px4_add_library(FlightTaskMyTask - FlightTaskMyTask.cpp - ) + ```cmake + px4_add_library(FlightTaskMyTask + FlightTaskMyTask.cpp + ) - target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) - target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - ``` + target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) + target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + ``` 4. Update the header file (in this case **FlightTaskMyTask.hpp**): Most tasks reimplement the virtual methods `activate()` and `update()`, and in this example we also have a private variable. @@ -141,35 +141,35 @@ The instructions below might be used to create a task named _MyTask_: - 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 - ... - * @value 0 Direct velocity - * @value 3 Smoothed velocity - * @value 4 Acceleration based - * @value 5 My task - * @group Multicopter Position Control - */ - PARAM_DEFINE_INT32(MPC_POS_MODE, 5); - ``` + ```c + ... + * @value 0 Direct velocity + * @value 3 Smoothed velocity + * @value 4 Acceleration based + * @value 5 My task + * @group Multicopter Position Control + */ + PARAM_DEFINE_INT32(MPC_POS_MODE, 5); + ``` - Add a case for your new option in the switch for the parameter [FlightModeManager.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/flight_mode_manager/FlightModeManager.cpp#L266-L285) to enable the task when `_param_mpc_pos_mode` has the right value. - ```cpp - ... - // manual position control - ... - switch (_param_mpc_pos_mode.get()) { - ... - case 3: - error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); - break; - case 5: // Add case for new task: MyTask - error = switchTask(FlightTaskIndex::MyTask); - break; - case 4: - .... - ... - ``` + ```cpp + ... + // manual position control + ... + switch (_param_mpc_pos_mode.get()) { + ... + case 3: + error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); + break; + case 5: // Add case for new task: MyTask + error = switchTask(FlightTaskIndex::MyTask); + break; + case 4: + .... + ... + ``` ## 신규 비행 작업 테스트 diff --git a/docs/ko/concept/system_startup.md b/docs/ko/concept/system_startup.md index c1f29f7664..058b7577c7 100644 --- a/docs/ko/concept/system_startup.md +++ b/docs/ko/concept/system_startup.md @@ -1,7 +1,7 @@ # 시스템 시작 PX4 시작은 쉘 스크립트에 의해 제어됩니다. -On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/MacOS). +On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/macOS). The scripts that are only used on Posix are located in [ROMFS/px4fmu_common/init.d-posix](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d-posix). All files starting with a number and underscore (e.g. `10000_airplane`) are predefined airframe configurations. @@ -13,9 +13,9 @@ The first executed file is the [init.d/rcS](https://github.com/PX4/PX4-Autopilot 다음 섹션은 PX4가 실행되는 운영 체제에 따라 달라집니다. -## POSIX (Linux/MacOS) +## POSIX (Linux/macOS) -Posix에서 시스템 셸은 스크립트 인터프리터로 사용됩니다(예: /bin/sh, Ubuntu에서 dash에 심볼릭 링크됨). +On POSIX, the system shell is used as script interpreter (e.g. /bin/sh, being symlinked to dash on Ubuntu). 동작하기 위한 몇가지 조건이 있습니다. - PX4 모듈은 시스템에서 개별적으로 실행할 수 있어야합니다. @@ -59,7 +59,7 @@ cd /build/px4_sitl_default/bin ### Dynamic Modules 일반적으로 모든 모듈은 단일 PX4 실행 파일로 컴파일됩니다. -However, on Posix, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. +However, on POSIX, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. ```sh dyn ./test.px4mod @@ -95,6 +95,8 @@ This is documented below. The best way to customize the system startup is to introduce a [new frame configuration](../dev_airframes/adding_a_new_frame.md). The frame configuration file can be included in the firmware or on an SD Card. +#### Dynamic Customization + If you only need to "tweak" the existing configuration, such as starting one more application or setting the value of a few parameters, you can specify these by creating two files in the `/etc/` directory of the SD Card: - [/etc/config.txt](#customizing-the-configuration-config-txt): modify parameter values @@ -111,7 +113,7 @@ Windows에서 편집하는 경우 적절한 편집기를 사용하여야 합니 These files are referenced in PX4 code as `/fs/microsd/etc/config.txt` and `/fs/microsd/etc/extras.txt`, where the root folder of the microsd card is identified by the path `/fs/microsd`. ::: -#### 구성 사용자 정의(config.txt) +##### 구성 사용자 정의(config.txt) The `config.txt` file can be used to modify parameters. It is loaded after the main system has been configured and _before_ it is booted. @@ -123,7 +125,7 @@ param set-default PWM_MAIN_DIS3 1000 param set-default PWM_MAIN_MIN3 1120 ``` -#### Starting Additional Applications (extras.txt) +##### Starting Additional Applications (extras.txt) The `extras.txt` can be used to start additional applications after the main system boot. 일반적으로, 페이로드 콘트롤러나 유사한 선택적 사용자 지정 구성 요소들입니다. @@ -150,3 +152,37 @@ Calling an unknown command in system boot files may result in boot failure. mandatory_app start # Will abort boot if mandatory_app is unknown or fails ``` + +#### Additional Init-File Customization + +In rare cases where the desired setup cannot be achieved through frame configuration or dynamic customization, you can add a script that will be compiled into the binary for a particular `make` target build variant. + +:::warning +In almost all cases, you should use a frame configuration. +This method should only be used for edge-cases such as customizing `cannode` based boards. +::: + +단계는 다음과 같습니다: + +- Add a new init script in `boards///init` that will run during board startup. + 예: + + ```sh + # File: boards///init/rc.additional + param set-default + ``` + +- Add a new board variant in `boards///.px4board` that includes the additional script. + 예: + + ```sh + # File: boards///var.px4board + CONFIG_BOARD_ADDITIONAL_INIT="rc.additional" + ``` + +- Compile the firmware with your new variant by appending the variant name to the compile target. + 예: + + ```sh + make _var + ``` diff --git a/docs/ko/config/_autotune.md b/docs/ko/config/_autotune.md index a6eab14e0e..ec9ec69753 100644 --- a/docs/ko/config/_autotune.md +++ b/docs/ko/config/_autotune.md @@ -43,13 +43,13 @@ To make sure the vehicle is stable enough for auto-tuning: 2. Take off and
hover at 1m above ground in [Altitude mode](../flight_modes_mc/altitude.md) or [Stabilized mode](../flight_modes_mc/manual_stabilized.md)
fly at cruise speed in [Position mode](../flight_modes_fw/position.md) or [Altitude mode](../flight_modes_fw/altitude.md)
. 3. Use the RC transmitter roll stick to perform the following maneuver, tilting the vehicle just a few degrees: _roll left > roll right > center_ (The whole maneuver should take about 3 seconds). - 기체는 2번의 진동 이내에서 안정화되어야 합니다. + 기체는 2번의 진동 이내에서 안정화되어야 합니다. 4. 각각의 시도에서 더 큰 진폭으로 기울이면서 기동을 반복합니다. - 기체가 ~20도에서 2번의 진동 내에서 안정화될 수 있으면 다음 단계로 이동합니다. + 기체가 ~20도에서 2번의 진동 내에서 안정화될 수 있으면 다음 단계로 이동합니다. 5. 피치 축에서 동일한 동작을 반복합니다. - As above, start with small angles and confirm that the vehicle can stabilise itself within 2 oscillations before increasing the tilt. + As above, start with small angles and confirm that the vehicle can stabilise itself within 2 oscillations before increasing the tilt. If the drone can stabilize itself within 2 oscillations it is ready for the [auto-tuning procedure](#auto-tuning-procedure). @@ -72,41 +72,55 @@ The test steps are: 1. Perform the [pre-tuning test](#pre-tuning-test). 2. Takeoff using RC control
in [Altitude mode](../flight_modes_mc/altitude.md). - Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
- Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). - This will guide the plane to fly in circle at constant altitude and speed.
+ Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
+ Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). + This will guide the plane to fly in circle at constant altitude and speed.
3. Enable autotune. -
-

TIP

+
+

TIP

- If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. + If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. -
+
- 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: + 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: - ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) + ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) - 2. Select either the _Rate Controller_ or _Attitude Controller_ tabs. + 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). + 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. - -4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. - The progress is shown in the progress bar, next to the _Autotune_ button. + 4. Read the warning popup and click on **OK** to start tuning.
+4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. + The progress is shown in the progress bar, next to the _Autotune_ button. + +
+ +4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. When [`FW_AT_SYSID_TYPE`](../advanced_config/parameter_reference.md#FW_AT_SYSID_TYPE) is set to linear/logarithmic sine sweep (recommended), the max rates reached during the maneuvers are 75% of the maximum configured roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. The progress is shown in the progress bar, next to the _Autotune_ button. + +
+
+ 5. Manually land and disarm to apply the new tuning parameters. - Takeoff carefully and manually test that the vehicle is stable. + Takeoff carefully and manually test that the vehicle is stable.
5. The tuning will be immediately/automatically be applied and tested in flight (by default). - PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + +The figure below shows how steps 4 and 5 might look in flight on the pitch axis. +The pitch rate gradually increases up until it reaches the target. +This amplitude is then held while the signal frequency is increased. +You can then see how the tuned system is able to follow the setpoint in the test signal. + +
@@ -174,9 +188,20 @@ Fast oscillations (more than 1 oscillation per second): this is because the gain ### 자동 튜닝 실패 +
+ If the drone was not moving enough during auto-tuning, the system identification algorithm might have issues to find the correct coefficients. -Increase the
[MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP)
[FW_AT_SYSID_AMP](../advanced_config/parameter_reference.md#FW_AT_SYSID_AMP)
parameter by steps of 1 and trigger the auto-tune again. +Increase the [MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP) parameter by steps of 1 and trigger the auto-tune again. + +
+
+ +By default, the autotune maneuvers ensure that a sufficient angular rate is reached for system identification, corresponding to 75% of the configured maximum roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. + +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. + +
### The drone oscillates after auto-tuning diff --git a/docs/ko/config/actuators.md b/docs/ko/config/actuators.md index 8206bd3ce0..48ceecb4bd 100644 --- a/docs/ko/config/actuators.md +++ b/docs/ko/config/actuators.md @@ -161,6 +161,7 @@ The fields are: [Generally you should use the default actuator value](#actuator-roll-pitch-and-yaw-scaling). - `Trim`: An offset added to the actuator so that it is centered without input. 이것은 시행착오를 거쳐 결정될 수 있습니다. + Prefer using the improved `PWM_CENT` instead: [PWM control surfaces](actuators.md#pwm-control-surfaces-that-move-both-directions-about-a-neutral-point). - (Advanced) `Slew Rate`: Limits the minimum time in which the motor/servo signal is allowed to pass through its full output range, in seconds. - The setting limits the rate of change of an actuator (if not specified then no rate limit is applied). It is intended for actuators that may be damaged or cause flight disturbance if they move too fast — such as the tilting actuators on a tiltrotor VTOL vehicle, or fast moving flaps, respectively. @@ -448,9 +449,9 @@ Instructions: 4. One motor will start spinning (click **Spin Motor Again** if it stops spinning too quickly to note.) - 지오메트리 섹션에서 해당 모터를 선택합니다. + 지오메트리 섹션에서 해당 모터를 선택합니다. - ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) + ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) 5. 모든 모터를 할당한 후 도구는 출력에 대한 올바른 모터 매핑을 설정한 다음 종료됩니다. @@ -467,15 +468,15 @@ To assign an actuator: 1. First assign functions to the outputs that you think are _likely_ to be correct in the _Actuator Outputs_ section. 2. Toggle the **Enable sliders** switch in _Actuator Testing_ section. 3. 테스트하려는 액추에이터의 슬라이더를 이동합니다. - - 모터는 최소 추력 위치로 이동하여야 합니다. - - 서보는 중간 위치 근처로 이동하여야 합니다. + - 모터는 최소 추력 위치로 이동하여야 합니다. + - 서보는 중간 위치 근처로 이동하여야 합니다. 4. 어떤 액츄에이터가 차량에서 움직이는 지 확인하십시오. - This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). - - 올바른 액츄에이터가 움직이면 다음 단계로 진행합니다. - - 잘못된 액츄에이터가 움직이면 출력 할당을 변경합니다. - - 아무 것도 움직이지 않으면, 슬라이더를 범위 중간에 늘리고 필요한 경우 더 높입니다. - 그 후 아무 것도 움직이지 않으면, 출력이 연결되지 않거나 모터에 전원이 공급되지 않거나 출력 설정에 오류가 있을 수 있습니다. - 문제를 해결하여야 합니다("무엇이든"이 움직이는지 확인하기 위하여 다른 액추에이터 출력을 시도할 수 있음). + This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). + - 올바른 액츄에이터가 움직이면 다음 단계로 진행합니다. + - 잘못된 액츄에이터가 움직이면 출력 할당을 변경합니다. + - 아무 것도 움직이지 않으면, 슬라이더를 범위 중간에 늘리고 필요한 경우 더 높입니다. + 그 후 아무 것도 움직이지 않으면, 출력이 연결되지 않거나 모터에 전원이 공급되지 않거나 출력 설정에 오류가 있을 수 있습니다. + 문제를 해결하여야 합니다("무엇이든"이 움직이는지 확인하기 위하여 다른 액추에이터 출력을 시도할 수 있음). 5. 슬라이더를 "무장 해제" 위치로 되돌립니다(모터의 경우 슬라이더 하단, 서보의 경우 슬라이더 중앙). 6. 모든 액추에이터에 대하여 반복합니다. @@ -501,32 +502,32 @@ Remove propellers! For each motor: 1. 모터 슬라이더를 아래로 당겨서 아래쪽에 찰칵 소리가 나도록 합니다. - In this position the motor is set to the outputs `disarmed` value. - - 모터가 이 위치에서 회전하지 않는 지 확인하십시오. - - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. + In this position the motor is set to the outputs `disarmed` value. + - 모터가 이 위치에서 회전하지 않는 지 확인하십시오. + - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. 2. Slowly move the slider up until it snaps to the _minimum_ position. - In this position the motor is set to the outputs `minimum` value. - - 이 위치에서 모터가 매우 느리게 회전하는 지 확인합니다. - - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. + In this position the motor is set to the outputs `minimum` value. + - 이 위치에서 모터가 매우 느리게 회전하는 지 확인합니다. + - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. - ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) - ::: info - For DShot output, this is not required. + ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) + ::: info + For DShot output, this is not required. ::: 3. Increase the slider value to a level where you can verify that the motor is spinning in the correct direction and that it would give a positive thrust in the expected direction. - - The expected thrust direction can vary by vehicle type. - For example in multicopters the thrust should always point upwards, while in a fixed-wing vehicle the thrust will push the vehicle forwards. - - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). - Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. - - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). + - The expected thrust direction can vary by vehicle type. + For example in multicopters the thrust should always point upwards, while in a fixed-wing vehicle the thrust will push the vehicle forwards. + - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). + Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. + - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). 4. Increase the slider value to the maximum value, so the motor is spinning quickly. - Reduce the value of the PWM output's `maximum` value just below the default. - Listen to the tone of the motors as you increase the value in small (25us) increments. - The "optimal" maximum value is the value at which you last hear a change in the tone. + Reduce the value of the PWM output's `maximum` value just below the default. + Listen to the tone of the motors as you increase the value in small (25us) increments. + The "optimal" maximum value is the value at which you last hear a change in the tone. ### 조종면 설정 @@ -542,40 +543,76 @@ If you're using PWM servos, PWM50 is far more common. If a high rate servo is _really_ needed, DShot offers better value. ::: -#### Control surfaces that move both directions about a neutral point +##### PWM: Control surfaces that move both directions about a neutral point + +To facilitate setting the neutral point of the servos, a bilinear curve function can be defined using the following parameters `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` for each servo. This allows for unequal deflections in the positive and negative direction: + +![Asymmetric Servo Deflections](../../assets/config/actuators/servo_pwm_center.png) + +To set this up: + +1. Set all surface `Trim` to `0.00` for all surfaces: + + ![PWM Trimming](../../assets/config/actuators/control_surface_trim.png) + +2. Set the `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` value so that the surface will stay at the neutral (aligned with airfoil) position. + This is usually around `1500` for PWM servos (near the center of the servo range). + + ![Control Surface Trimming](../../assets/config/actuators/pwm_center_output.png) + +3. Gradually increase the `Maximum` for each servo until the desired deflection is reached. Check the deflection with a remote manual mode while [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) is set to `Always` or use the sliders. + +4. Gradually decrease the `Minimum` for each servo, until the desired deflection is reached. + +5. Set `Disarmed` value to the desired value. It is usually desirable to have it the same as the `Center` value. + +:::info +If you want to retain the linear behaviour of the servo after setting the `Center`, make sure to adjust the `Minimum` or `Maximum`, such that both intervals (`min` to `cent` & `cent` to `max`) are equally large. + +![Linear PWM Adjustment](../../assets/config/actuators/servo_pwm_linear.png) +::: + +#### Non-PWM: Control surfaces that move both directions about a neutral point Control surfaces that move either direction around a neutral point include: ailerons, elevons, V-tails, A-tails, and rudders. To set these up: -1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. - This is usually around `1500` for PWM servos (near the centre of the servo range). +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. - ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) +1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. + This is usually around `1500` for PWM servos (near the centre of the servo range). + + ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) 2. Move the slider for the surface upwards (positive command) and verify that it moves in the direction defined in the [Control Surface Convention](#control-surface-deflection-convention). - - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. - - Rudders and other "purely vertical" surfaces should move right. + - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. + - Rudders and other "purely vertical" surfaces should move right. - ::: tip - It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). + ::: tip + It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). ::: - If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. + If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. 3. Move the slider again to the middle and check if the Control Surfaces are aligned in the neutral position of the wing. - - If it is not aligned, you can set the **Trim** value for the control surface. - ::: info - This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". - ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) + - If it is not aligned, you can set the **Trim** value for the control surface. + + ::: info + This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". + ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) ::: - - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. - Confirm that surface is in the neutral position. + - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. + Confirm that surface is in the neutral position. + +:::tip +If any servo has a `PWM_MAIN_CENTx` or `PWM_AUX_CENTx` not set to default (-1), the system will automatically remove `Trim` from all surfaces. This is done to prevent mixing of old and new trimming tools. +::: :::info Another way to test without using the sliders would be to set the [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) parameter to `Always`: @@ -595,15 +632,17 @@ For a flap, that is when the flap is fully retracted and flush with the wing. One approach for setting these up is: +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. 1. Set values `Disarmed` to `1500`, `Min` to `1200`, `Max` to `1700` so that the values are around the centre of the servo range. 2. Move the corresponding slider up and check the control moves and that it is extending (moving away from the disarmed position). - If not, click on the `Rev Range` checkbox to reverse the range. + If not, click on the `Rev Range` checkbox to reverse the range. 3. Enable slider in the disarmed position, them change the value of the `Disarmed` signal until the control is retracted/flush with wing. - This may require that the `Disarmed` value is increased or decreased: - - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. - - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. + This may require that the `Disarmed` value is increased or decreased: + - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. + - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. 4. The value that you did _not_ set to match `Disarmed` controls the maximum amount that the control surface can extend. - Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. + Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. +5. (Only PWM servos) Set the `Center` value to the middle between `Min` and `Max`. :::info Special note for flaps In some vehicle builds, flaps may be configured such that both flaps are controlled from a single output. @@ -627,7 +666,7 @@ For each of the tilt servos: 2. Position the slider for the servo in the lowest position, and verify that a positive value increase will point towards the `Angle at Min Tilt` (defined in the Geometry section). - ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) + ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) 3. Position the slider for the servo in the highest position, and verify that positive motor thrust will point towards the `Angle at Max Tilt` (as defined in the Geometry section). @@ -642,6 +681,11 @@ For each of the tilt servos: - 표준 VTOL: 멀티콥터 모터로 정의된 모터가 꺼집니다. - 틸트로터: 연결된 틸트 서보가 없는 모터는 꺼집니다. - 테이시터는 고정익 비행시에도 모터를 끄지 않습니다. +- The following formula can be used to migrate from surface trim to PWM trim: + + ```plain + PWM_MAIN_CENTx = ((PWM_MAX - PWM_MIN) / 2) * CA_SV_CSx_TRIM + PWM_MIN + ((PWM_MAX - PWM_MIN) / 2) + ``` ### 모터 역전 diff --git a/docs/ko/config/airspeed.md b/docs/ko/config/airspeed.md index 84673a452d..087bf0a188 100644 --- a/docs/ko/config/airspeed.md +++ b/docs/ko/config/airspeed.md @@ -27,18 +27,18 @@ Before calibration they must be [enabled via the corresponding parameter](../adv 4. Click the **Airspeed** sensor button. - ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) + ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) 5. 센서로 부는 바람을 막으십시오 (예: 손을 컵 모양으로 감쌀 수 있습니다). - 피톳 튜브의 구멍을 막지 않도록 주의하십시오. + 피톳 튜브의 구멍을 막지 않도록 주의하십시오. 6. Click **OK** to start the calibration. 7. 피톳 튜브의 끝에 입으로 바람을 불어 보정 완료 신호를 보냅니다. - :::tip - Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. - 교체한 센서는 튜브에 바람을 불어 넣을 때 큰 음의 차압을 판독하고 보정이 오류와 함께 중단됩니다. + :::tip + Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. + 교체한 센서는 튜브에 바람을 불어 넣을 때 큰 음의 차압을 판독하고 보정이 오류와 함께 중단됩니다. ::: diff --git a/docs/ko/config/compass.md b/docs/ko/config/compass.md index ef27d7a49e..c93f6f49ab 100644 --- a/docs/ko/config/compass.md +++ b/docs/ko/config/compass.md @@ -10,7 +10,7 @@ If you have [mounted the compass](../assembly/mount_gps_compass.md#compass-orien ## 개요 -You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to recalibrate it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. +You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to [recalibrate](#recalibration) it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. :::tip Indications of a poor compass calibration include multicopter circling during hover, toilet bowling (circling at increasing radius/spiraling-out, usually constant altitude, leading to fly-way), or veering off-path when attempting to fly straight. @@ -20,13 +20,16 @@ _QGroundControl_ should also notify the error `mag sensors inconsistent`. The process calibrates all compasses and autodetects the orientation of any external compasses. If any external magnetometers are available, it then disables the internal magnetometers (these are primarily needed for automatic rotation detection of external magnetometers). +### Types of Calibration + Several types of compass calibration are available: 1. [Complete](#complete-calibration): This calibration is required after installing the autopilot on an airframe for the first time or when the configuration of the vehicle has changed significantly. - It compensates for hard and soft iron effects by estimating an offset and a scale factor for each axis. + It compensates for hard and soft iron effects by estimating an offset and a scale factor for each axis. 2. [Partial](#partial-quick-calibration): This calibration can be performed as a routine when preparing the vehicle for a flight, after changing the payload, or simply when the compass rose seems inaccurate. - This type of calibration only estimates the offsets to compensate for a hard iron effect. -3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. This type of calibration only estimates the offsets to compensate for a hard iron effect. + This type of calibration only estimates the offsets to compensate for a hard iron effect. +3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. + This type of calibration only estimates the offsets to compensate for a hard iron effect. ## 보정 절차 @@ -35,13 +38,13 @@ Several types of compass calibration are available: Before starting the calibration: 1. 큰 금속 물체등과 같이 자기장이 강한 곳에서 멀리 떨어진 위치를 선택하십시오. - :::tip - Metal is not always obvious! 사무실 테이블 위에서나 (종종 금속 막대 포함) 또는 차량 옆에서 보정하지 마십시오. - 철근이 고르지 않게 분포된 콘크리트 슬래브 근처 장소들도 보정에 영향을 미칠 수 있습니다. + :::tip + Metal is not always obvious! 사무실 테이블 위에서나 (종종 금속 막대 포함) 또는 차량 옆에서 보정하지 마십시오. + 철근이 고르지 않게 분포된 콘크리트 슬래브 근처 장소들도 보정에 영향을 미칠 수 있습니다. ::: 2. Connect via telemetry radio rather than USB if at all possible. - USB can potentially cause significant magnetic interference. + USB can potentially cause significant magnetic interference. 3. If using an external compass (or a combined GPS/compass module), make sure it is [mounted](../assembly/mount_gps_compass.md) as far as possible from other electronics in order to reduce magnetic interference, and in a _supported orientation_. ### Complete Calibration @@ -54,29 +57,33 @@ Before starting the calibration: 3. Click the **Compass** sensor button. - ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) + ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) - ::: info - You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). 미리 설정하지 않았다면, 여기에서 설정할 수 있습니다. + ::: info + You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). + 미리 설정하지 않았다면, 여기에서 설정할 수 있습니다. ::: 4. Click **OK** to start the calibration. -5. 기체를 아래에 표시된 자세로 놓고 그대로 유지해주십시오 메시지가 표시되면(방향 이미지가 노란색으로 변함) 기체를 지정축을 기준으로 한 방향으로 회전시킵니다. 현재 방향에 대해 보정이 완료되면 화면의 그림이 녹색으로 바뀝니다. +5. 기체를 아래에 표시된 자세로 놓고 그대로 유지해주십시오 + 메시지가 표시되면(방향 이미지가 노란색으로 변함) 기체를 지정축을 기준으로 한 방향으로 회전시킵니다. + 현재 방향에 대해 보정이 완료되면 화면의 그림이 녹색으로 바뀝니다. - ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) + ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) 6. 드론의 모든 방향에 대해 보정 과정을 반복합니다. -Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). 그런 다음 다음 센서의 보정 작업을 진행합니다. +Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). +그런 다음 다음 센서의 보정 작업을 진행합니다. ### Partial "Quick" Calibration This calibration is similar to the well-known figure-8 compass calibration done on a smartphone: 1. Hold the vehicle in front of you and randomly perform partial rotations on all its axes. - 2-3 oscillations of ~30 degrees in every direction is usually sufficient. + 2-3 oscillations of ~30 degrees in every direction is usually sufficient. 2. Wait for the heading estimate to stabilize and verify that the compass rose is pointing to the correct direction (this can take a couple of seconds). 참고: @@ -92,14 +99,15 @@ This calibration is similar to the well-known figure-8 compass calibration done This calibration process leverages external knowledge of vehicle's orientation and location, and a World Magnetic Model (WMM) to calibrate the hard iron biases. -1. Ensure GNSS Fix. This is required to find the expected Earth magnetic field in WMM tables. +1. Ensure GNSS Fix. + This is required to find the expected Earth magnetic field in WMM tables. 2. Align the vehicle to face True North. - Be as accurate as possible for best results. + Be as accurate as possible for best results. 3. Open the [QGroundControl MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) and send the following command: - ```sh - commander calibrate mag quick - ``` + ```sh + commander calibrate mag quick + ``` 참고: @@ -112,6 +120,30 @@ This calibration process leverages external knowledge of vehicle's orientation a After the calibration is complete, check that the heading indicator and the heading of the arrow on the map are stable and match the orientation of the vehicle when turning it e.g. to the cardinal directions. +## Recalibration + +Recalibration is recommended whenever the magnetic environment of the vehicle has changed or when heading behavior appears unreliable. + +You can use either complete calibration or mag quick calibration depending on the size of the vehicle and your ability to rotate it through the required orientations. +Complete calibration provides the most accurate soft-iron compensation. + +Recalibrate the compass when: + +- _The compass module or its mounting orientation has changed._ + This includes replacing the GPS or mag unit, rotating the mast, or altering how the module is fixed to the airframe. +- _The vehicle has been exposed to a strong magnetic disturbance._ + Examples include transport or storage near large steel structures, welding operations near the airframe, or operation close to high-current equipment. +- _Structural, wiring, or payload changes may have altered the magnetic field around the sensors._ + New payloads, rerouted wires, additional batteries, or metal fasteners can introduce soft-iron effects that affect heading accuracy. +- _The vehicle is operated in a region with significantly different magnetic characteristics._ + Large changes in latitude, longitude, or magnetic inclination can require re-estimation of offsets. +- _QGroundControl reports magnetometer inconsistencies_. + For example, if you see the error `mag sensors inconsistent`. +- _Heading behavior does not match the vehicle’s observed orientation._ + Symptoms include drifting yaw, sudden heading jumps when attempting to fly straight, and toilet bowling +- _QGroundControl_ sends the error `mag sensors inconsistent`. + This indicates that multiple magnetometers are reporting different headings. + ## Additional Calibration/Configuration The process above will autodetect, [set default rotations](../advanced_config/parameter_reference.md#SENS_MAG_AUTOROT), calibrate, and prioritise, all available magnetometers. diff --git a/docs/ko/config/firmware.md b/docs/ko/config/firmware.md index 48b5674d79..f18547b496 100644 --- a/docs/ko/config/firmware.md +++ b/docs/ko/config/firmware.md @@ -61,10 +61,10 @@ Next you will need to specify the [vehicle airframe](../config/airframe.md) (and 2. Check **Advanced settings** and select the version from the dropdown list: - **Standard Version (stable):** The default version (i.e. no need to use advanced settings to install this!) - **Beta Testing (beta):** A beta/candidate release. - 신규 버전 출시 이전에 테스트 할 경우에만 사용할 수 있습니다. + 신규 버전 출시 이전에 테스트 할 경우에만 사용할 수 있습니다. - **Developer Build (master):** The latest build of PX4/PX4-Autopilot _main_ branch. - **Custom Firmware file...:** A custom firmware file (e.g. [that you have built locally](../dev_setup/building_px4.md)). - 사용자 정의 펌웨어 파일을 선택한 경우 다음 단계에서 파일 시스템에서 사용자 정의 펌웨어를 선택하여야 합니다. + 사용자 정의 펌웨어 파일을 선택한 경우 다음 단계에서 파일 시스템에서 사용자 정의 펌웨어를 선택하여야 합니다. 그러면 펌웨어 업데이트가 이전과 같이 계속됩니다. diff --git a/docs/ko/config/flight_mode.md b/docs/ko/config/flight_mode.md index da272589c7..aac54501f9 100644 --- a/docs/ko/config/flight_mode.md +++ b/docs/ko/config/flight_mode.md @@ -40,24 +40,24 @@ You can also separately specify channels for mapping a kill switch, return to la 3. Select **"Q" icon > Vehicle Setup > Flight Modes** (sidebar) to open _Flight Modes Setup_. - ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) + ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) 4. 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 **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. + - Select the flight mode that you want triggered for each switch position. 5. 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 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). 6. 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. diff --git a/docs/ko/config/safety.md b/docs/ko/config/safety.md index 3323b03aaa..afa785d204 100644 --- a/docs/ko/config/safety.md +++ b/docs/ko/config/safety.md @@ -106,7 +106,7 @@ There are several other "battery related" failsafe mechanisms that may be config | 설정 | 매개변수 | 설명 | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe @@ -121,36 +121,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Additional (and underlying) parameter settings are shown below. | 매개변수 | 설정 | 설명 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [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 old manual control setpoint until the timeout triggers. | +| [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. | | [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. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | 안전장치 동작 | Disabled, Loiter, Return, Land, Disarm, Terminate. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC 손실 예외 | Set the modes in which manual control loss is ignored: Mission, Hold, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC 손실 예외 | Set modes in which manual control loss is ignored. | ## 데이터 연결불량 안전장치 -The Data Link Loss failsafe is triggered if a telemetry link (connection to ground station) is lost. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) 설정에 관련된 기본 매개변수는 다음과 같습니다. -| 설정 | 매개변수 | 설명 | -| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| 데이터 연결불량 시간 초과 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 데이터 연결이 끊어진 후 안전 장치가 동작하기 전까지의 시간입니다. | -| 안전장치 동작 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | - -다음 설정도 가능하지만 QGC UI에 표시되지 않습니다. - -| 설정 | 매개변수 | 설명 | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| 설정 | 매개변수 | 설명 | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| 데이터 연결불량 시간 초과 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 데이터 연결이 끊어진 후 안전 장치가 동작하기 전까지의 시간입니다. | +| 안전장치 동작 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | +| 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 안전장치 @@ -206,23 +202,13 @@ The relevant parameters shown below. ### Position Loss Failsafe Action -The failure action is controlled by [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL), based on whether RC control is assumed to be available (and altitude information): - -- `0`: Remote control available. - Switch to _Altitude mode_ if a height estimate is available, otherwise _Stabilized mode_. -- `1`: Remote control _not_ available. - Switch to _Descend mode_ if a height estimate is available, otherwise enter flight termination. - _Descend mode_ is a landing mode that does not require a position estimate. +Multicopters will switch to [Altitude mode](../flight_modes_mc/altitude.md) if a height estimate is available, otherwise [Stabilized mode](../flight_modes_mc/manual_stabilized.md). Fixed-wing planes, and VTOLs not configured to land in hover ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)), have a parameter ([FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT)) that defines how long they will loiter (circle with a constant roll angle ([FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R)) at the current altitude) after losing position before attempting to land. If VTOLs have are configured to switch to hover for landing ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)) then they will first transition and then descend. The relevant parameters for all vehicles shown below. -| 매개변수 | 설명 | -| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL) | Position control navigation loss response during mission. Values: `0` - assume use of RC, `1` - Assume no RC. | - Parameters that only affect Fixed-wing vehicles: | 매개변수 | 설명 | @@ -286,18 +272,18 @@ The relevant parameters are listed in the table below. ## 고장 감지기 -고장 감지기를 사용하여 차량의 예기치 않게 전복되거나 외부의 고장 감지 시스템에 따른 보호 조치를 할 수 있습니다. +The failure detector allows a vehicle to take protective actions if it unexpectedly flips, detects a motor failure, or if it is notified by an external failure detection system. During **flight**, the failure detector can be used to trigger [flight termination](../advanced_config/flight_termination.md) if failure conditions are met, which may then launch a [parachute](../peripherals/parachute.md) or perform some other action. :::info -Failure detection during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). +Acting on a detected failure during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). ::: During **takeoff** the failure detector [attitude trigger](#attitude-trigger) invokes the [disarm action](#act_disarm) if the vehicle flips (disarm kills the motors but, unlike flight termination, will not launch a parachute or perform other failure actions). Note that this check is _always enabled on takeoff_, irrespective of the `CBRK_FLIGHTTERM` parameter. -The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/altitude.md), [Acro mode (FW)](../flight_modes_fw/altitude.md), and [Manual (FW)](../flight_modes_fw/manual.md)). +The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/acro.md), [Acro mode (FW)](../flight_modes_fw/acro.md), and [Manual (FW)](../flight_modes_fw/manual.md)). ### 자세 감지기 @@ -313,6 +299,26 @@ The failure detector is active in all vehicle types and modes, except for those | [FD_FAIL_P_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_P_TTRI) | Time to exceed [FD_FAIL_P](#FD_FAIL_P) for failure detection (default 0.3s). | | [FD_FAIL_R_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_R_TTRI) | Time to exceed [FD_FAIL_R](#FD_FAIL_R) for failure detection (default 0.3s). | +### Motor Failure Trigger + +The failure detector can be configured to detect a motor failure while armed (and trigger an associated action) in the following conditions: + +- A 300 ms timeout occurs in telemetry from an ESC that was previously available. +- The input current in the telemetry of an ESC which was previously positive gets too low for more than [`FD_ACT_MOT_TOUT`](FD_ACT_MOT_TOUT) ms. + The "too low" condition is defined by: + + ```text + {esc current} < {parameter FD_ACT_MOT_C2T} * {motor command between 0 and 1} + ``` + +| 매개변수 | 설명 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [FD_ACT_EN](../advanced_config/parameter_reference.md#FD_ACT_EN) | Enable/disable the motor failure trigger completely. | +| [FD_ACT_MOT_THR](../advanced_config/parameter_reference.md#FD_ACT_MOT_THR) | Minimum normalized [0,1] motor command below which motor under current is ignored. | +| [FD_ACT_MOT_C2T](../advanced_config/parameter_reference.md#FD_ACT_MOT_C2T) | Scale between normalized [0,1] motor command and expected minimally reported currrent when the rotor is healthy. | +| [FD_ACT_MOT_TOUT](../advanced_config/parameter_reference.md#FD_ACT_MOT_TOUT) | Time in miliseconds for which the under current detection condition needs to stay true. | +| [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) | Configure to not only warn about a motor failure but remove the first motor that detects a failure from the allocation effectiveness which turns off the motor and tries to operate the vehicle without it until disarming the next time. | + ### 외부 자동 작동 시스템 (ATS) The [failure detector](#failure-detector), if [enabled](#CBRK_FLIGHTTERM), can also be triggered by an external ATS system. diff --git a/docs/ko/config/safety_simulation.md b/docs/ko/config/safety_simulation.md index be2f6cb89a..bee01fc8d3 100644 --- a/docs/ko/config/safety_simulation.md +++ b/docs/ko/config/safety_simulation.md @@ -14,7 +14,7 @@ To use it: 2. Set the vehicle type 3. Set the other values in the **State** or any of the flags under **Conditions** - The **Intended Mode** corresponds to the commanded mode via RC or GCS (or external script). - The failsafe state machine can override this in case of a failsafe. + The failsafe state machine can override this in case of a failsafe. 4. Check the action under **Output** 5. Check what happens when changing mode or **Move the RC sticks** 6. Play with different settings and conditions! diff --git a/docs/ko/config_fw/airspeed_scale_handling.md b/docs/ko/config_fw/airspeed_scale_handling.md new file mode 100644 index 0000000000..02f745fc72 --- /dev/null +++ b/docs/ko/config_fw/airspeed_scale_handling.md @@ -0,0 +1,112 @@ +# Airspeed Scale Handling + +:::info +This section complements the existing [Airspeed Validation](../advanced_config/airspeed_validation.md) documentation. +::: + +The airspeed scale is used by PX4 to convert the measured airspeed (indicated airspeed) to the calibrated airspeed. +This scale can be set by [ASPD_SCALE_n](../advanced_config/parameter_reference.md#ASPD_SCALE_1) (where `n` is the sensor number), and logged in [AirspeedWind.msg](../msg_docs/AirspeedWind.md). + +Note that the airspeed scale is different from the airspeed sensor offset calibration done on the ground at 0 m/s. The airspeed scale accounts for errors in the airspeed measurement during flight, such as those caused by sensor placement or installation effects. + +This topic describes how to set an initial airspeed scale for a new fixed-wing vehicle during its first flight. Correct scale calibration ensures reliable airspeed data, accurate TAS calculation, robust PX4 airspeed validation, and consistent controller performance. + +## Airspeed in PX4 + +PX4 handles multiple types of airspeed: + +- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). +- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. +- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. + While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. +- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). + +The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. + +## CAS Scale Estimation + +PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. +To compute the final TAS, standard environment conversions are applied (CAS → TAS). + +:::warning +Important +A GNSS is required for scale estimation. +::: + +PX4 uses a two-stage approach to robustly estimate the scale: + +1. **Continuous EKF Estimation**: A wind estimator constantly compares your measured airspeed against what it expects based on ground velocity (from GNSS) and estimated wind. + If there's a consistent bias, it adjusts the scale estimate. + The estimated scale is logged in the `AirspeedWind.msg` as the `tas_scale_raw`. +2. **Validation**: To ensure robustness, PX4 collects airspeed and ground speed data across 12 different heading segments (every 30°). + This averages out wind estimation errors. + The validated scale is only updated when the new estimate demonstrably reduces the error between predicted and actual ground speeds across all headings. + The validated scale is logged in the `AirspeedWind.msg` as the `tas_scale_validated`. + +### Understanding the Scale: Physical Intuition + +The CAS scale is essentially a correction factor that accounts for systematic errors in your airspeed sensor installation. + +- A scale of 1.0 means your sensor reads perfectly (no correction needed) +- A scale > 1.0 (e.g., 1.1) means your sensor _under-reads_ by 10%, so measured airspeed (IAS) must be multiplied by 1.1 +- A scale < 1.0 (e.g., 0.9) means your sensor _over-reads_ by ~11%, so measured airspeed (IAS) must be multiplied by 0.9 + +### What Affects the Airspeed Scale + +The primary factor influencing the airspeed scale is **sensor placement**. + +Biased readings can be reflected in the scale estimate for pitot tubes installed: + +- In regions experiencing disturbed flow (commonly near blunt aircraft noses) +- Near propellers +- Under aerodynamic surfaces +- At an angle with respect to the airflow + +### Symptoms of Incorrect Scale + +Symptoms of an incorrectly scaled airspeed measurement include: + +- Stalling or overspeeding +- Persistent under- or overestimation of the TAS relative to wind-corrected groundspeed +- False positives or missed detections in [airspeed innovation checks](../advanced_config/airspeed_validation.md#innovation-check) +- Degraded tracking of the rate controllers + +## Recommended First Flight Process + +During the first flight of a new fixed-wing vehicle, allocate time for the CAS scale to converge to a reasonable initial estimate. +Follow these steps: + +1. **Set an Initial Scale** + + Set the CAS scale (`ASPD_SCALE_n`) to 1.0 (the default value). + When the scale is at exactly 1.0, PX4 automatically accelerates the learning process during the first 5 minutes of flight, allowing faster convergence to the correct scale value. + +2. **Perform a Flight** + + After takeoff, place the vehicle in loiter for about 15 minutes to allow the scale estimation to converge. + + ::: tip + Flying in circles (loiter/hold mode) is important as the scale-validation algorithm requires the aircraft to pass through multiple heading segments (12 segments covering all compass directions). + If these heading segments aren’t completed, PX4 cannot validate the estimated scale. + +::: + +3. **Check Scale Convergence** + + After the flight, review the estimated scale in logs. + Verify that: + + - `tas_scale_validated` in `AirspeedWind.msg` converged during flight. + - `true_airspeed_m_s` (TAS) in [AirspeedValidated.msg](../msg_docs/AirspeedValidated.md) is consistent with groundspeed corrected for wind. + +4. **Update the Airframe Configuration** + + If using an [airframe configuration file](../dev_airframes/adding_a_new_frame.md): update `ASPD_SCALE_n`with the estimated CAS scale for future flights. + For similar vehicles with similarly mounted sensors, this value is typically a reliable starting point. + +:::info +If you are not able to perform the steps outlined above ... + +For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). +The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for `ASPD_SCALE_n`. +::: diff --git a/docs/ko/config_fw/index.md b/docs/ko/config_fw/index.md index 60fe4c9b6c..2a0834860a 100644 --- a/docs/ko/config_fw/index.md +++ b/docs/ko/config_fw/index.md @@ -3,7 +3,7 @@ Fixed-wing configuration and calibration follows the same high level steps as other frames: selection of firmware, configuration of the frame including actuator/motor geometry and output mappings, sensor configuration and calibration, configuration of safety and other features, and finally tuning. :::info -This topic is the recommended entry point when performing first-time configuration and calibration of a new multicopter frame. +This topic is the recommended entry point when performing first-time configuration and calibration of a new fixed-wing frame. ::: The main steps are: @@ -20,3 +20,5 @@ The main steps are: - [Fixed-wing Altitude/Position Controller Tuning Guide](../config_fw/position_tuning_guide_fixedwing.md) - [Fixed-wing Trimming Guide](../config_fw/trimming_guide_fixedwing.md) + +- [Fixed-Wing Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md) diff --git a/docs/ko/config_fw/pid_tuning_guide_fixedwing.md b/docs/ko/config_fw/pid_tuning_guide_fixedwing.md index fb48245bc6..6d098e38bc 100644 --- a/docs/ko/config_fw/pid_tuning_guide_fixedwing.md +++ b/docs/ko/config_fw/pid_tuning_guide_fixedwing.md @@ -17,6 +17,8 @@ It is intended for advanced users / experts, as incorrect PID tuning may crash y - Excessive gains (and rapid servo motion) can violate the maximum forces of your airframe - increase gains carefully. - Roll and pitch tuning follow the same sequence. The only difference is that pitch is more sensitive to trim offsets, so [trimming](../config_fw/trimming_guide_fixedwing.md) has to be done carefully and integrator gains need more attention to compensate this. +- Disable automatic [gain compression](../features_fw/gain_compression.md) ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)) to avoid over-tuning. + Remember to re-enable it when tuning is done. ## Establishing the Airframe Baseline diff --git a/docs/ko/config_fw/position_tuning_guide_fixedwing.md b/docs/ko/config_fw/position_tuning_guide_fixedwing.md index 403ce4c12e..0908eaba3a 100644 --- a/docs/ko/config_fw/position_tuning_guide_fixedwing.md +++ b/docs/ko/config_fw/position_tuning_guide_fixedwing.md @@ -9,7 +9,7 @@ An incorrectly set gain during tuning can make altitude or heading control unsta ::: :::tip -All parameters are documented in the [Parameter Reference](../advanced_config/parameter_reference.md#fw-tecs). +All parameters are documented in the Parameter Reference [FW Performance](../advanced_config/parameter_reference.md#fw-performance) and [FW NPFG Control](../advanced_config/parameter_reference.md#fw-npfg-control) sections. 이 가이드에서는 중요한 매개변수들을 설명합니다. ::: @@ -78,7 +78,7 @@ Furthermore, these two values define the height rate limits commanded by the use ### FW Path Control Tuning (Position) -All path control parameters are described [here](../advanced_config/parameter_reference.md#fw-path-control). +All path control parameters are described in [FW NPFG Control (Parameter Reference)](../advanced_config/parameter_reference.md#fw-npfg-control). - [NPFG_PERIOD](../advanced_config/parameter_reference.md#NPFG_PERIOD) - This is the previously called L1 distance and defines the tracking point ahead of the aircraft it's following. A value of 10-20 meters works for most aircraft. diff --git a/docs/ko/config_fw/trimming_guide_fixedwing.md b/docs/ko/config_fw/trimming_guide_fixedwing.md index d83b874dfe..14db662282 100644 --- a/docs/ko/config_fw/trimming_guide_fixedwing.md +++ b/docs/ko/config_fw/trimming_guide_fixedwing.md @@ -29,10 +29,10 @@ The [Advanced Trimming](#advanced-trimming) section introduces parameters that c 1. Trim the servos by physically adjusting the linkages lengths if possible and fine tune by trimming the PWM channels (use `PWM_MAIN/AUX_TRIMx`) on the bench to properly set the control surfaces to their theoretical position. 2. Fly in stabilized mode at cruise speed and set the pitch setpoint offset (`FW_PSP_OFF`) to desired angle of attack. - 순항 속도에서 필요한 공격 각도는 날개 높이 비행 중에 일정한 고도를 유지하기 위해 비행기가 비행해야 하는 피치 각도에 해당합니다. - If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). + 순항 속도에서 필요한 공격 각도는 날개 높이 비행 중에 일정한 고도를 유지하기 위해 비행기가 비행해야 하는 피치 각도에 해당합니다. + If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). 3. Look at the actuator controls in the log file (upload it to [Flight Review](https://logs.px4.io) and check the _Actuator Controls_ plot for example) and set the pitch trim (`TRIM_PITCH`). - 이 값을 수평 비행 중의 피치 신호의 평균 오프셋으로 설정합니다. + 이 값을 수평 비행 중의 피치 신호의 평균 오프셋으로 설정합니다. 로그 조회가 필요가 없거나 수동 모드에서 편안하게 비행 할 수있는 경우 2 단계 전에 3 단계를 수행할 수 있습니다. You can then trim your remote (with the trim switches) and report the values to `TRIM_PITCH` (and remove the trims from your transmitter) or update `TRIM_PITCH` directly during flight via telemetry and QGC. diff --git a/docs/ko/config_heli/index.md b/docs/ko/config_heli/index.md index 93847d6b0e..bfa800eca5 100644 --- a/docs/ko/config_heli/index.md +++ b/docs/ko/config_heli/index.md @@ -53,15 +53,15 @@ To setup and configure a helicopter: 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: + 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: - | # | Angle | - | ------- | ----- | - | Servo 1 | 60° | - | Servo 2 | 180° | - | Servo 3 | 300° | + | # | Angle | + | ------- | ----- | + | Servo 1 | 60° | + | Servo 2 | 180° | + | Servo 3 | 300° | - warning and requirement + warning and requirement - `Arm Length (relative to each other)`: Radius from the swash plate center (top view). A shorter arm means the same servo motion moves the plate more. This allows the autopilot to compensate. @@ -72,7 +72,7 @@ To setup and configure a helicopter: - `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. - A larger value may improve user experience. + A larger value may improve user experience. 3. Remove the rotor blades and propellers diff --git a/docs/ko/config_mc/filter_tuning.md b/docs/ko/config_mc/filter_tuning.md index b206131c7d..2a7e2cd406 100644 --- a/docs/ko/config_mc/filter_tuning.md +++ b/docs/ko/config_mc/filter_tuning.md @@ -70,7 +70,7 @@ Airframes with more than two frequency noise spikes typically clean the first tw Dynamic notch filters use ESC RPM feedback and/or the onboard FFT analysis. The ESC RPM feedback is used to track the rotor blade pass frequency and its harmonics, while the FFT analysis can be used to track a frequency of another vibration source, such as a fuel engine. -ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/esc_motors.md#dshot) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). +ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/dshot.md) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). Before enabling, make sure that the ESC RPM is correct. You might have to adjust the [pole count of the motors](../advanced_config/parameter_reference.md#MOT_POLE_COUNT). @@ -166,11 +166,11 @@ In this case you might use the settings: [IMU_GYRO_NF0_FRQ=32](../advanced_confi ## 추가 팁 1. 허용 가능한 지연 시간은 기체 크기와 기대치에 따라 달라집니다. - FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). - For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. + FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). + For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. 2. You can start tuning at higher `IMU_GYRO_CUTOFF` values (e.g. 100Hz), which might be desirable because the default tuning of `IMU_GYRO_CUTOFF` is set very low (30Hz). - 유일한 주의 사항은 위험을 알고 있어야한다는 것입니다. - - 20 ~ 30 초 이상 비행하지 마십시오 - - 모터가 과열되지 않는 지 확인하십시오. - - 위의 설명처럼 이상한 소리와 과도한 소음을 체크하십시오. + 유일한 주의 사항은 위험을 알고 있어야한다는 것입니다. + - 20 ~ 30 초 이상 비행하지 마십시오 + - 모터가 과열되지 않는 지 확인하십시오. + - 위의 설명처럼 이상한 소리와 과도한 소음을 체크하십시오. diff --git a/docs/ko/config_mc/pid_tuning_guide_multicopter_basic.md b/docs/ko/config_mc/pid_tuning_guide_multicopter_basic.md index ecafb76696..efc5ebcfe7 100644 --- a/docs/ko/config_mc/pid_tuning_guide_multicopter_basic.md +++ b/docs/ko/config_mc/pid_tuning_guide_multicopter_basic.md @@ -72,7 +72,7 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 1. Arm the vehicle, takeoff, and hover (typically in [Position mode](../flight_modes_mc/position.md)). 2. Open _QGroundControl_ **Vehicle Setup > PID Tuning** - ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) + ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) 3. Select the **Rate Controller** tab. @@ -80,60 +80,60 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 5. Set the _Thrust curve_ value to: 0.3 (PWM, power-based controllers) or 1 (RPM-based ESCs) - ::: info - For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. - 그 결과 호버 추력에서 최적의 튜닝은 차량이 강한 추력으로 작동시 최적이 아닐 수 있습니다. + ::: info + For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. + 그 결과 호버 추력에서 최적의 튜닝은 차량이 강한 추력으로 작동시 최적이 아닐 수 있습니다. - 추력 곡선 값을 사용하여 비선형성을 보상할 수 있습니다. + 추력 곡선 값을 사용하여 비선형성을 보상할 수 있습니다. - - For PWM controllers, 0.3 is a good default (which may benefit from [further tuning](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve)). - - RPM 기반 컨트롤러의 경우 1을 사용합니다 (2 차 추력 곡선이 있으므로 추가 튜닝이 필요하지 않음). + - For PWM controllers, 0.3 is a good default (which may benefit from [further tuning](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve)). + - RPM 기반 컨트롤러의 경우 1을 사용합니다 (2 차 추력 곡선이 있으므로 추가 튜닝이 필요하지 않음). - For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). + For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). ::: 6. Set the _Select Tuning_ radio button to: **Roll**. 7. (Optionally) Select the **Automatic Flight Mode Switching** checkbox. - This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button + This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button 8. For rate controller tuning switch to _Acro mode_, _Stabilized mode_ or _Altitude mode_ (unless automatic switching is enabled). 9. Select the **Start** button in order to start tracking the setpoint and response curves. 10. Rapidly move the _roll stick_ full range and observe the step response on the plots. - :::tip - Stop tracking to enable easier inspection of the plots. - 확대/축소/이동시 자동으로 발생합니다. - Use the **Start** button to restart the plots, and **Clear** to reset them. + :::tip + Stop tracking to enable easier inspection of the plots. + 확대/축소/이동시 자동으로 발생합니다. + Use the **Start** button to restart the plots, and **Clear** to reset them. ::: 11. Modify the three PID values using the sliders (for roll rate-tuning these affect `MC_ROLLRATE_K`, `MC_ROLLRATE_I`, `MC_ROLLRATE_D`) and observe the step response again. - 슬라이더를 움직이면 값이 기체에 저장됩니다. - ::: info - The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). + 슬라이더를 움직이면 값이 기체에 저장됩니다. + ::: info + The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). ::: - The PID values can be adjusted as follows: - - P (비례) 또는 K 이득 : - - 더 많은 응답을 위해 이것을 늘리십시오. - - 응답이 오버 슈팅 및/또는 진동하는 경우 감소합니다 (특정 지점까지 D 게인 증가도 도움이 됨). - - D (미분) 이득 : - - 오버슈트 및 진동을 줄이기 위해이 값을 늘릴 수 있습니다. - - 소음을 증폭하고 모터가 뜨거워 질 수 있으므로 필요한 만큼만 늘리십시오. - - I (적분) 이득 : - - 정상 상태 오류를 줄이는 데 사용 - - 너무 낮으면 응답이 설정 값에 도달하지 못할 수 있습니다 (예 : 바람) - - 너무 높으면 느린 진동이 발생할 수 있습니다. + The PID values can be adjusted as follows: + - P (비례) 또는 K 이득 : + - 더 많은 응답을 위해 이것을 늘리십시오. + - 응답이 오버 슈팅 및/또는 진동하는 경우 감소합니다 (특정 지점까지 D 게인 증가도 도움이 됨). + - D (미분) 이득 : + - 오버슈트 및 진동을 줄이기 위해이 값을 늘릴 수 있습니다. + - 소음을 증폭하고 모터가 뜨거워 질 수 있으므로 필요한 만큼만 늘리십시오. + - I (적분) 이득 : + - 정상 상태 오류를 줄이는 데 사용 + - 너무 낮으면 응답이 설정 값에 도달하지 못할 수 있습니다 (예 : 바람) + - 너무 높으면 느린 진동이 발생할 수 있습니다. 12. 피치와 요에 대해 위의 튜닝 프로세스를 반복합니다. - - Use _Select Tuning_ radio button to select the axis to tune - - 적절한 스틱을 이동합니다 (예 : 피치 스틱, 요 스틱). - - 피치 튜닝의 경우 롤과 동일한 값으로 시작하십시오. - :::tip - Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. + - Use _Select Tuning_ radio button to select the axis to tune + - 적절한 스틱을 이동합니다 (예 : 피치 스틱, 요 스틱). + - 피치 튜닝의 경우 롤과 동일한 값으로 시작하십시오. + :::tip + Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. ::: @@ -141,10 +141,10 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 14. 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) + - 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) - ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) + ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) 완료되었습니다 ! 설정을 종료하기 전에 에어 모드를 다시 활성화하여야 합니다. diff --git a/docs/ko/config_rover/basic_setup.md b/docs/ko/config_rover/basic_setup.md index 78aba9a4a9..53b9e2ddb1 100644 --- a/docs/ko/config_rover/basic_setup.md +++ b/docs/ko/config_rover/basic_setup.md @@ -27,10 +27,18 @@ That is the minimum setup to use the rover in [Manual mode](../flight_modes_rover/manual.md#manual-mode). +:::info +The rest of the tuning on this page is not mandatory for [Manual mode](../flight_modes_rover/manual.md#manual-mode), but it will have an effect on the behaviour of the rover. +::: + +:::warning +Do not skip the rest of this setup if you intend to use more sophisticated modes! +All parameters will be mandatory for all subsequent modes, except those tagged as `(Optional)`. +::: + ## Geometric Parameters -Manual mode is also affected by (optional) acceleration/deceleration limits set using the geometric described below. -These limits are mandatory for all other modes. +First, we set up the geometric parameters of the rover: ![Geometric parameters](../../assets/config/rover/geometric_parameters.png) @@ -42,7 +50,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and 2. [RA_MAX_STR_ANG](#RA_MAX_STR_ANG) [deg]: Measure the maximum steering angle. 3. (Optional) [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) [deg/s]: Maximum steering rate you want to allow for your rover. - :::tip + ::: tip This value depends on your rover and use case. For bigger rovers there might be a mechanical limit that is easy to identify by steering the rover at a standstill and increasing [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) until you observe the steering rate to no longer be limited by the parameter. @@ -51,7 +59,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: - :::warning + ::: warning A low maximum steering rate makes the rover worse at tracking steering setpoints, which can lead to a poor performance in the subsequent modes. ::: @@ -85,7 +93,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and One approach to determine an appropriate value is: 1. From a standstill, give the rover full throttle until it reaches the maximum speed. - 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md). + 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md). 3. Divide the maximum speed by the time it took to reach it and set this as the value for [RO_ACCEL_LIM](#RO_ACCEL_LIM). Some RC rovers have enough torque to lift up if the maximum acceleration is not limited. @@ -109,6 +117,39 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: +## (Optional) Stick Input Mapping + +Input shaping can be used to adjust the default linear mapping from stick inputs $\in [-1, 1]$ to normalized setpoints $\in [-1, 1]$. Applying this specifically to the steering input, can provide a smoother driving experience, by enabling the user to make small adjustments when the stick is close to the center, but still send large inputs when moving them to the edges. +We provide this input shaping through the super exponential function: + +$$ +\delta = \frac{(f \cdot x^3 + x(1-f)) \cdot (1-g)}{1-g \cdot |x|} +$$ + +with: + +- $\delta \in [-1, 1]=$ Normalized steering setpoint. +- $x \in [-1, 1]=$ Normalized stick input. +- $f=$ [RO_YAW_EXPO](#RO_YAW_EXPO): `0` Purely linear input curve, `1` Purely cubic input curve. +- $g=$ [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO): `0` Pure Expo function, `0.7` reasonable shape enhancement for intuitive stick feel, `0.95` very strong bent input curve only near maxima have effect. + +In [Manual mode](../flight_modes_rover/manual.md#manual-mode) we can additionally scale $\delta$ with an additional parameter $r$: + +- Differential Rover: $r=$ [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)]. +- Mecanum Rover: $r=$ [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN)]. + +This scaling is useful to limit the normalized steering setpoint, if it is too aggresive for your rover in manual mode. + +You can experiment with the relationships graphically using the [PX4 SuperExpo Rover calculator](https://www.desmos.com/calculator/gwm8lrlanx). + +:::info +In [Acro](../flight_modes_rover/manual.md#acro-mode), [Stabilized](../flight_modes_rover/manual.md#stabilized-mode) and [Position](../flight_modes_rover/manual.md#position-mode) Mode, $\delta$ is instead scaled by $r=$ [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) for all rovers. This leads to a yaw rate setpoint $\dot{\psi} = \delta \cdot r \in$ [-[RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED), [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED)]. This parameter is setup during [rate tuning](rate_tuning.md). +::: + +:::info +The input shaping through [RO_YAW_EXPO](#RO_YAW_EXPO) and [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO) applies for all manual modes, while [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)/[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN) only affects full manual mode. +::: + You can now continue the configuration process with [rate tuning](rate_tuning.md). ## Parameter Overview @@ -118,6 +159,8 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md | [RO_MAX_THR_SPEED](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) | Speed the rover drives at maximum throttle | $m/s$ | | [RO_ACCEL_LIM](../advanced_config/parameter_reference.md#RO_ACCEL_LIM) | (Optional) Maximum allowed acceleration | $m/s^2$ | | [RO_DECEL_LIM](../advanced_config/parameter_reference.md#RO_DECEL_LIM) | (Optional) Maximum allowed deceleration | $m/s^2$ | +| [RO_YAW_EXPO](../advanced_config/parameter_reference.md#RO_YAW_EXPO) | (Optional) Yaw rate expo factor | $-$ | +| [RO_YAW_SUPEXPO](../advanced_config/parameter_reference.md#RO_YAW_SUPEXPO) | (Optional) Yaw rate super expo factor | $-$ | ### Ackermann Specific @@ -129,12 +172,14 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md ### Differential Specific -| 매개변수 | 설명 | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | m | +| 매개변수 | 설명 | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | $m$ | +| [RD_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RD_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | ### Mecanum Specific -| 매개변수 | 설명 | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | m | +| 매개변수 | 설명 | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | $m$ | +| [RM_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RM_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | diff --git a/docs/ko/config_rover/index.md b/docs/ko/config_rover/index.md index 8aa91b1c27..17af2f6742 100644 --- a/docs/ko/config_rover/index.md +++ b/docs/ko/config_rover/index.md @@ -25,18 +25,18 @@ Rovers use a custom build that must be flashed onto your flight controller inste 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: - ```sh - make px4_fmu-v6x_rover - ``` + ```sh + make px4_fmu-v6x_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)): - ```sh - CONFIG_MODULES_ROVER_ACKERMANN=y - CONFIG_MODULES_ROVER_DIFFERENTIAL=y - CONFIG_MODULES_ROVER_MECANUM=y - ``` + ```sh + CONFIG_MODULES_ROVER_ACKERMANN=y + CONFIG_MODULES_ROVER_DIFFERENTIAL=y + CONFIG_MODULES_ROVER_MECANUM=y + ``` 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). diff --git a/docs/ko/config_rover/position_tuning.md b/docs/ko/config_rover/position_tuning.md index 5425f0176d..e87c970c24 100644 --- a/docs/ko/config_rover/position_tuning.md +++ b/docs/ko/config_rover/position_tuning.md @@ -43,7 +43,7 @@ To tune the position controller configure the [parameters](../advanced_config/pa ::: -3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. +3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. If the tracking of these setpoints is not satisfactory adjust the values for [RO_SPEED_P](../advanced_config/parameter_reference.md#RO_SPEED_P) and [RO_SPEED_I](../advanced_config/parameter_reference.md#RO_SPEED_I). ## Path Following diff --git a/docs/ko/config_rover/velocity_tuning.md b/docs/ko/config_rover/velocity_tuning.md index 1f07e31659..8e7f44f954 100644 --- a/docs/ko/config_rover/velocity_tuning.md +++ b/docs/ko/config_rover/velocity_tuning.md @@ -28,7 +28,7 @@ To tune the velocity controller configure the following [parameters](../advanced 1. Set [RO_SPEED_P](#RO_SPEED_P) and [RO_SPEED_I](#RO_SPEED_I) to zero. This way the speed is only controlled by the feed-forward term, which makes it easier to tune. 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and then move the left stick of your controller up and/or down and hold it at a few different levels for a couple of seconds each. - 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. + 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. 4. If the actual speed of the rover is higher than the speed setpoint, increase [RO_MAX_THR_SPEED](#RO_MAX_THR_SPEED). If it is the other way around decrease the parameter and repeat until you are satisfied with the setpoint tracking. @@ -94,7 +94,7 @@ These steps are only necessary if you are tuning/want to unlock the manual [Posi The rover is now ready to drive in [Position mode](../flight_modes_rover/manual.md#position-mode) and the configuration can be continued with [position tuning](position_tuning.md). -## Attitude Controller Structure (Info Only) +## Velocity Controller Structure (Info Only) This section provides additional information for developers and people with experience in control system design. diff --git a/docs/ko/config_vtol/index.md b/docs/ko/config_vtol/index.md index 2cc478205c..651bc79d0d 100644 --- a/docs/ko/config_vtol/index.md +++ b/docs/ko/config_vtol/index.md @@ -9,3 +9,4 @@ As part of this you should calibrate the [Airspeed sensor](../config/airspeed.md - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/ko/config_vtol/vtol_ice_shedding.md b/docs/ko/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..ae719602af --- /dev/null +++ b/docs/ko/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,22 @@ +# VTOL Ice Shedding feature + +## 개요 + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::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 + +::: diff --git a/docs/ko/config_vtol/vtol_quad_configuration.md b/docs/ko/config_vtol/vtol_quad_configuration.md index 7c234d9653..d442eda0b6 100644 --- a/docs/ko/config_vtol/vtol_quad_configuration.md +++ b/docs/ko/config_vtol/vtol_quad_configuration.md @@ -11,7 +11,7 @@ For airframe specific documentation and build instructions see [VTOL Framebuilds 2. Flash the firmware for your current release or master (PX4 `main` branch build). 3. In the [Frame setup](../config/airframe.md) section select the appropriate VTOL airframe. - If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. + If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. ### 비행 / 전환 모드 스위치 diff --git a/docs/ko/contribute/code.md b/docs/ko/contribute/code.md index 8673e2516f..16535ea2eb 100644 --- a/docs/ko/contribute/code.md +++ b/docs/ko/contribute/code.md @@ -34,7 +34,7 @@ If you update an existing file you are not required to make the whole file compl ### Line Length -- Maximum line length is 120 characters. +- Maximum line length is 140 characters. ### File Extensions diff --git a/docs/ko/contribute/docs.md b/docs/ko/contribute/docs.md index b8d7bc1dbe..f0713b2edf 100644 --- a/docs/ko/contribute/docs.md +++ b/docs/ko/contribute/docs.md @@ -64,33 +64,33 @@ If you already have a clone of the [PX4-Autopilot](https://github.com/PX4/PX4-Au 4. 복사된 저장소를 로컬 컴퓨터에 복제합니다. - ```sh - cd ~/wherever/ - git clone https://github.com//PX4-Autopilot.git - ``` + ```sh + cd ~/wherever/ + git clone https://github.com//PX4-Autopilot.git + ``` - For example, to clone PX4 source fork for a user with Github account "john_citizen": + For example, to clone PX4 source fork for a user with Github account "john_citizen": - ```sh - git clone https://github.com/john_citizen/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/john_citizen/PX4-Autopilot.git + ``` 5. 로컬 저장소로 이동합니다. - ```sh - cd ~/wherever/PX4-Autopilot - ``` + ```sh + cd ~/wherever/PX4-Autopilot + ``` 6. Add a _remote_ called "upstream" to point to the "official" PX4 version of the library: - ```sh - git remote add upstream https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git remote add upstream https://github.com/PX4/PX4-Autopilot.git + ``` - :::tip - A "remote" is a handle to a particular repository. - The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. - Above you create a new remote _upstream_ that points to the PX4 project version of the documents. + :::tip + A "remote" is a handle to a particular repository. + The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. + Above you create a new remote _upstream_ that points to the PX4 project version of the documents. ::: @@ -100,111 +100,111 @@ Within the repository you created above: 1. Bring your copy of the repository `main` branch up to date: - ```sh - git checkout main - git fetch upstream main - git pull upstream main - ``` + ```sh + git checkout main + git fetch upstream main + git pull upstream main + ``` 2. Create a new branch for your changes: - ```sh - git checkout -b - ``` + ```sh + git checkout -b + ``` - This creates a local branch on your computer named `your_feature_branch_name`. + This creates a local branch on your computer named `your_feature_branch_name`. 3. 필요에 따라 문서를 변경합니다(다음 섹션에서 이에 대한 일반 지침). 4. 변경 사항에 완료되면 "커밋"을 사용하여, 로컬 브랜치에 추가합니다. - ```sh - git add - git commit -m "" - ``` + ```sh + git add + git commit -m "" + ``` - For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. + For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. 5. 로컬 분기(추가된 커밋 포함)를 Github의 분기된 저장소에 푸시합니다. - ```sh - git push origin your_feature_branch_name - ``` + ```sh + git push origin your_feature_branch_name + ``` 6. Go to your forked repository on Github in a web browser, e.g.: `https://github.com//PX4-Autopilot.git`. - 새 분기가 분기된 저장소로 푸시되었다는 메시지가 표시되어야 합니다. + 새 분기가 분기된 저장소로 푸시되었다는 메시지가 표시되어야 합니다. 7. 풀 요청(PR) 생성: - - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". - 클릭합니다. - - 풀 요청 템플릿이 생성됩니다. - 그것은 당신의 커밋을 나열하고 의미 있는 제목(하나의 커밋 PR의 경우 일반적으로 커밋 메시지)과 메시지(어떤 이유에서 수행했는지 설명)를 추가할 수 있습니다(반드시). - Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). - - Add the "Documentation" label. + - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". + 클릭합니다. + - 풀 요청 템플릿이 생성됩니다. + 그것은 당신의 커밋을 나열하고 의미 있는 제목(하나의 커밋 PR의 경우 일반적으로 커밋 메시지)과 메시지(어떤 이유에서 수행했는지 설명)를 추가할 수 있습니다(반드시). + Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). + - Add the "Documentation" label. 8. 완료하였습니다. - PX4 사용자 가이드 유지 관리자는 이제 귀하의 기여를 검투한 후에, 통합 여부를 결정합니다. - 때때로 변경 사항에 대한 질문을 확인하십시오. + PX4 사용자 가이드 유지 관리자는 이제 귀하의 기여를 검투한 후에, 통합 여부를 결정합니다. + 때때로 변경 사항에 대한 질문을 확인하십시오. ### 로컬에서 라이브러리 구축 로컬에서 라이브러리를 빌드하여, 변경 사항이 제대로 반영되었는 지를 테스트합니다. 1. Install the [Vitepress prerequisites](https://vitepress.dev/guide/getting-started#prerequisites): - - [Nodejs 18+](https://nodejs.org/en) - - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) + - [Nodejs 18+](https://nodejs.org/en) + - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) 2. Navigate to your local repository and the `/docs` subdirectory: - ```sh - cd ~/wherever/PX4-Autopilot/docs - ``` + ```sh + cd ~/wherever/PX4-Autopilot/docs + ``` 3. 종속성(Vuepress 포함)들을 설치합니다. - ```sh - yarn install - ``` + ```sh + yarn install + ``` 4. Preview and serve the library: - ```sh - yarn docs:dev - ``` + ```sh + yarn docs:dev + ``` - - Once the development/preview server has built the library (less than a minute for the first time) it will show you the URL you can preview the site on. - This will be something like: `http://localhost:5173/px4_user_guide/`. - - Stop serving using **CTRL+C** in the terminal prompt. + - Once the development/preview server has built the library (less than a minute for the first time) it will show you the URL you can preview the site on. + This will be something like: `http://localhost:5173/px4_user_guide/`. + - Stop serving using **CTRL+C** in the terminal prompt. 5. Open previewed pages in your local editor: - First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. - For example, you can enable VSCode as your default editor by entering: + First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. + For example, you can enable VSCode as your default editor by entering: - - Windows: + - Windows: - ```sh - set EDITOR=code - ``` + ```sh + set EDITOR=code + ``` - - Linux: + - Linux: - ```sh - export EDITOR=code - ``` + ```sh + export EDITOR=code + ``` - The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). + The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). 6. 다음을 사용하여 라이브러리를 빌드합니다. - ```sh - # Ubuntu - yarn docs:build + ```sh + # Ubuntu + yarn docs:build - # Windows - yarn docs:buildwin - ``` + # Windows + yarn docs:buildwin + ``` :::tip Use `yarn start` to preview changes _as you make them_ (documents are updated and served very quickly). @@ -257,38 +257,38 @@ When you add a new page you must also add it to `en/SUMMARY.md`! ## 스타일 가이드 1. 파일/파일명 - - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. - 폴더를 중첩하지 마십시오. - - Put new image files in an appropriate nested sub-folder of `/assets/`. - Deeper nesting is allowed/encouraged. - - Use descriptive names for folders and files. - In particular, image filenames should describe what they contain (don't name as "image1.png") - - Use lower case filenames and separate words using underscores (`_`). + - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. + 폴더를 중첩하지 마십시오. + - Put new image files in an appropriate nested sub-folder of `/assets/`. + Deeper nesting is allowed/encouraged. + - Use descriptive names for folders and files. + In particular, image filenames should describe what they contain (don't name as "image1.png") + - Use lower case filenames and separate words using underscores (`_`). 2. 이미지 - - 이미지는 최대한 가장 작은 크기와 가장 낮은 해상도를 사용합니다(이렇게 하면 대역폭이 좋지 않은 사용자의 다운로드 비용이 줄어듭니다). - - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). - - SVG files are preferred for diagrams. - PNG files are preferred over JPG for screenshots. + - 이미지는 최대한 가장 작은 크기와 가장 낮은 해상도를 사용합니다(이렇게 하면 대역폭이 좋지 않은 사용자의 다운로드 비용이 줄어듭니다). + - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). + - SVG files are preferred for diagrams. + PNG files are preferred over JPG for screenshots. 3. 내용 - - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). - - **Bold** for button presses and menu definitions. - - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. - - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. - - Headings and page titles should use "First Letter Capitalisation". - - The page title should be a first level heading (`#`). - All other headings should be h2 (`##`) or lower. - - 제목에는 스타일을 추가하지 마십시오. - - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. - - Break lines on sentences by preference. - Don't break lines based on some arbitrary line length. - - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). + - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). + - **Bold** for button presses and menu definitions. + - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. + - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. + - Headings and page titles should use "First Letter Capitalisation". + - The page title should be a first level heading (`#`). + All other headings should be h2 (`##`) or lower. + - 제목에는 스타일을 추가하지 마십시오. + - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. + - Break lines on sentences by preference. + Don't break lines based on some arbitrary line length. + - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). 4. Videos: - - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). - - Use instructional videos sparingly as they date badly, and are hard to maintain. - - Cool videos of airframes in flight are always welcome. + - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). + - Use instructional videos sparingly as they date badly, and are hard to maintain. + - Cool videos of airframes in flight are always welcome. ## 어디에서 변경 사항을 추가합니까? diff --git a/docs/ko/contribute/git_examples.md b/docs/ko/contribute/git_examples.md index d4e71a7deb..96773607f6 100644 --- a/docs/ko/contribute/git_examples.md +++ b/docs/ko/contribute/git_examples.md @@ -109,23 +109,23 @@ To switch between branches: 1. Clean up the current branch, de-initializing submodule and removing all build artifacts: - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` 2. Switch to a new branch or tag (here we first fetch the fictional branch "PR_test_branch" from the `upstream` remote): - ```sh - git fetch upstream PR_test_branch - git checkout PR_test_branch - ``` + ```sh + git fetch upstream PR_test_branch + git checkout PR_test_branch + ``` 3. Get the submodules for the new branch: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` @@ -138,35 +138,35 @@ To get the source code for a _specific older release_ (tag): 1. Clone the PX4-Autopilot repo and navigate into _PX4-Autopilot_ directory: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + ``` - :::note + :::note - You can reuse an existing repo rather than cloning a new one. - In this case clean the build environment (see [changing source trees](#changing-source-trees)): + You can reuse an existing repo rather than cloning a new one. + In this case clean the build environment (see [changing source trees](#changing-source-trees)): - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` ::: 2. Checkout code for particular tag (e.g. for tag v1.13.0-beta2) - ```sh - git checkout v1.13.0-beta2 - ``` + ```sh + git checkout v1.13.0-beta2 + ``` 3. Update submodules: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` ## Get a Release Branch diff --git a/docs/ko/debug/asset_tracking.md b/docs/ko/debug/asset_tracking.md new file mode 100644 index 0000000000..31461d4a29 --- /dev/null +++ b/docs/ko/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## 개요 + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## 비행 로그 분석 + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## See Also + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/ko/debug/eclipse_jlink.md b/docs/ko/debug/eclipse_jlink.md index 34ea6212f4..7aef08e6fc 100644 --- a/docs/ko/debug/eclipse_jlink.md +++ b/docs/ko/debug/eclipse_jlink.md @@ -53,17 +53,17 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal 7. 패키지를 업데이트합니다. - Click the small icon on the top right called _Open Perspective_ and open the _Packs_ perspective. - ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) + ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) - Click the **update all** button. - :::tip - This takes a VERY LONG TIME (10 minutes). - 누락된 패키지에 대한 오류를 무시하십시오. + :::tip + This takes a VERY LONG TIME (10 minutes). + 누락된 패키지에 대한 오류를 무시하십시오. ::: - ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) + ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) - The STM32Fxx devices are found in the Keil folder, install by right-clicking and then selecting **install** on the according device for F4 and F7. @@ -79,24 +79,24 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal ![Eclipse: Debug config](../../assets/debug/eclipse_settings_debug_config.png) 10. Then select _GDB SEGGER J-Link Debugging_ and then the **New config** button on the top left. - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) 11. 빌드 구성을 설정합니다. - - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. - - Choose _Disable Auto build_ + - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. + - Choose _Disable Auto build_ ::: info Remember that you must build the target from the command line before starting a debug session. ::: - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) 12. The _Debugger_ and _Startup_ tabs shouldn’t need any modifications (just verify your settings with the screenshots below) - ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) - ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) + ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) + ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) ## SEGGER Task-aware debugging @@ -109,16 +109,16 @@ To enable this feature for use in Eclipse: - Open a terminal in the root of your PX4-Autopilot source code - In the terminal, open `menuconfig` using the appropriate make target for the build. - This will be something like: + This will be something like: - ```sh - make px4_fmu-v5_default boardguiconfig - ``` + ```sh + make px4_fmu-v5_default boardguiconfig + ``` - (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). + (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). - Ensure that the _Enable TCBinfo struct for debug_ is selected as shown: - ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) + ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) 2. Compile the **jlink-nuttx.so** library in the terminal by running the following command in the terminal: `make jlink-nuttx` diff --git a/docs/ko/debug/failure_injection.md b/docs/ko/debug/failure_injection.md index 9c33504065..fdc4a49589 100644 --- a/docs/ko/debug/failure_injection.md +++ b/docs/ko/debug/failure_injection.md @@ -9,7 +9,7 @@ Failure injection is disabled by default, and can be enabled using the [SYS_FAIL Failure injection still in development. At time of writing (PX4 v1.14): -- 시뮬레이션에서만 사용할 수 있습니다(실제 비행에서 실패 주입 모두 지원 예정). +- Support may vary by failure type and between simulatiors and real vehicle. - It requires support in the simulator. It is supported in Gazebo Classic - 많은 실패 유형이 광범위하게 구현되지 않았습니다. @@ -19,7 +19,7 @@ At time of writing (PX4 v1.14): ## 장애 시스템 명령 -Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 console/shell, specifying both the target and type of the failure. +Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 [console/shell](../debug/consoles.md) (such as the [QGC MAVLink Console](../debug/mavlink_shell.md#qgroundcontrol-mavlink-console) or SITL _pxh shell_), specifying both the target and type of the failure. ### 구문 @@ -33,52 +33,68 @@ failure [-i ] - _component_: - 센서: - - `gyro`: Gyro. - - `accel`: Accelerometer. + - `gyro`: Gyroscope + - `accel`: Accelerometer - `mag`: Magnetometer - `baro`: Barometer - - `gps`: GPS + - `gps`: Global navigation satellite system - `optical_flow`: Optical flow. - - `vio`: Visual inertial odometry. + - `vio`: Visual inertial odometry - `distance_sensor`: Distance sensor (rangefinder). - - `airspeed`: Airspeed sensor. + - `airspeed`: Airspeed sensor - 시스템: - - `battery`: Battery. - - `motor`: Motor. - - `servo`: Servo. - - `avoidance`: Avoidance. - - `rc_signal`: RC Signal. - - `mavlink_signal`: MAVLink signal (data telemetry). + - `battery`: Battery + - `motor`: Motor + - `servo`: Servo + - `avoidance`: Avoidance + - `rc_signal`: RC Signal + - `mavlink_signal`: MAVLink data telemetry connection - _failure_type_: - - `ok`: Publish as normal (Disable failure injection). - - `off`: Stop publishing. - - `stuck`: Report same value every time (_could_ indicate a malfunctioning sensor). - - `garbage`: Publish random noise. 초기화되지 않은 메모리를 읽는 것처럼 보입니다. - - `wrong`: Publish invalid values (that still look reasonable/aren't "garbage"). - - `slow`: Publish at a reduced rate. - - `delayed`: Publish valid data with a significant delay. - - `intermittent`: Publish intermittently. + - `ok`: Publish as normal (Disable failure injection) + - `off`: Stop publishing + - `stuck`: Constantly report the same value which _can_ happen on a malfunctioning sensor + - `garbage`: Publish random noise. This looks like reading uninitialized memory + - `wrong`: Publish invalid values that still look reasonable/aren't "garbage" + - `slow`: Publish at a reduced rate + - `delayed`: Publish valid data with a significant delay + - `intermittent`: Publish intermittently - _instance number_ (optional): Instance number of affected sensor. 0 (기본값) 지정된 유형의 모든 센서를 나타냅니다. -### Example - -To simulate losing RC signal without having to turn off your RC controller: - -1. Enable the parameter [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN). -2. Enter the following commands on the MAVLink console or SITL _pxh shell_: - - ```sh - # Fail RC (turn publishing off) - failure rc_signal off - - # Restart RC publishing - failure rc_signal ok - ``` - ## MAVSDK 실패 플러그인 The [MAVSDK failure plugin](https://mavsdk.mavlink.io/main/en/cpp/api_reference/classmavsdk_1_1_failure.html) can be used to programmatically inject failures. It is used in [PX4 Integration Testing](../test_and_ci/integration_testing_mavsdk.md) to simulate failure cases (for example, see [PX4-Autopilot/test/mavsdk_tests/autopilot_tester.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/test/mavsdk_tests/autopilot_tester.cpp)). The plugin API is a direct mapping of the failure command shown above, with a few additional error signals related to the connection. + +## Example: RC signal + +To simulate losing RC signal without having to turn off your RC controller: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Fail RC (turn publishing off) + failure rc_signal off + + # Restart RC publishing + failure rc_signal ok + ``` + +## Example: Motor + +To stop a motor mid-flight without the system anticipating it or excluding it from allocation effectiveness: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enable [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) parameter to allow turning off motors. +3. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Turn off first motor + failure motor off -i 1 + + # Turn it back on + failure motor ok -i 1 + ``` diff --git a/docs/ko/dev_airframes/adding_a_new_frame.md b/docs/ko/dev_airframes/adding_a_new_frame.md index d7528cc6fb..98f1f6869d 100644 --- a/docs/ko/dev_airframes/adding_a_new_frame.md +++ b/docs/ko/dev_airframes/adding_a_new_frame.md @@ -37,8 +37,8 @@ Alternatively you can just append the modified parameters to the startup configu To add a frame configuration to firmware: 1. Create a new config file in the [init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) folder. - - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). - - Update the file with configuration parameters and apps (see section above). + - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). + - Update the file with configuration parameters and apps (see section above). 2. Add the name of the new frame config file to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt) in the relevant section for the type of vehicle. 3. [Build and upload](../dev_setup/building_px4.md) the software. @@ -292,37 +292,37 @@ If the airframe is for a **new group** you additionally need to: 2. Add a mapping between the new group name and image filename in the [srcparser.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/px4airframes/srcparser.py) method `GetImageName()` (follow the pattern below): - ```python - def GetImageName(self): - """ - Get parameter group image base name (w/o extension) - """ - if (self.name == "Standard Plane"): - return "Plane" - elif (self.name == "Flying Wing"): - return "FlyingWing" - ... - ... - return "AirframeUnknown" - ``` + ```python + def GetImageName(self): + """ + Get parameter group image base name (w/o extension) + """ + if (self.name == "Standard Plane"): + return "Plane" + elif (self.name == "Flying Wing"): + return "FlyingWing" + ... + ... + return "AirframeUnknown" + ``` 3. 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: + - 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: - ```xml - - ... - src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg - src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg - src/AutoPilotPlugins/Common/Images/Boat.svg - src/AutoPilotPlugins/Common/Images/FlyingWing.svg - ... - ``` + ```xml + + ... + src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg + src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg + src/AutoPilotPlugins/Common/Images/Boat.svg + src/AutoPilotPlugins/Common/Images/FlyingWing.svg + ... + ``` - ::: info - The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). + ::: info + The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). ::: diff --git a/docs/ko/dev_log/log_encryption.md b/docs/ko/dev_log/log_encryption.md index 4af14b648e..e8a9a04267 100644 --- a/docs/ko/dev_log/log_encryption.md +++ b/docs/ko/dev_log/log_encryption.md @@ -30,7 +30,7 @@ If another algorithm is supported in future, the process is _likely_ to remain t The encryption process for each new ULog is: 1. A XChaCha20 symmetric key is generated and encrypted using an RSA2048 public key. - This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). + This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). 2. When a log is captured, the ULog data is encrypted with the unwrapped symmetric key and the resulting data is appended into the end of the `.ulge` file immediately after the wrapped key data. After the flight, the `.ulge` file containing both the wrapped symmetric key and the encrypted log data can be found on the SD card. @@ -356,26 +356,26 @@ This section explains how you might manually run the same steps as the script (s 2. Use OpenSSL to generate a RSA2048 private and public key: - ```sh - openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 - ``` + ```sh + openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 + ``` 3. Create a public key from this private key: - ```sh - # Convert private_key.pem to a DER file - openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der - # From the DER file, generate a public key in hex format, separated by commas - xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub - ``` + ```sh + # Convert private_key.pem to a DER file + openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der + # From the DER file, generate a public key in hex format, separated by commas + xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub + ``` 4. Copy the keys into the appropriate locations expected by the rest of the toolchain (as shown in previous section). 5. To use this key, modify your `.px4board` file to point `CONFIG_PUBLIC_KEY1` to the file location of `public_key.pub`. - ```sh - CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" - ``` + ```sh + CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" + ``` ## Flight Review & Encrypted logs @@ -397,10 +397,10 @@ This can use logs that you have downloaded and decrypted yourself, or you can in 3. Add this key location into the server config file: `flight_review/app/config_default.ini`. - The line to add should look something like this (for the file above): + The line to add should look something like this (for the file above): - ```sh - ulge_private_key = ../private_key/private_key.pem - ``` + ```sh + ulge_private_key = ../private_key/private_key.pem + ``` 4. Follow the Flight Review Instructions to start your server. diff --git a/docs/ko/dev_log/logging.md b/docs/ko/dev_log/logging.md index 7892ff18a5..527e053184 100644 --- a/docs/ko/dev_log/logging.md +++ b/docs/ko/dev_log/logging.md @@ -33,16 +33,17 @@ 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. 변경할 가능성이 높은 매개변수가 아래에 설명되어 있습니다. -| 매개변수 | 설명 | -| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [SDLOG_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Logging Mode. Defines when logging starts and stops.
- `-1`: Logging disabled.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `4`: Log from first armed until shutdown. | -| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_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".
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_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Logging Mode. Defines when logging starts and stops.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `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.
- bit `0`: SD card logging.
- bit `1`: Mavlink logging. | +| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_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".
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: - Raw sensor data for comparison: [SDLOG_MODE=1](../advanced_config/parameter_reference.md#SDLOG_MODE) and [SDLOG_PROFILE=64](../advanced_config/parameter_reference.md#SDLOG_PROFILE). -- Disabling logging altogether: [SDLOG_MODE=`-1`](../advanced_config/parameter_reference.md#SDLOG_MODE) +- Disabling logging altogether: [SDLOG_BACKEND=`0`](../advanced_config/parameter_reference.md#SDLOG_BACKEND) ### Logger module @@ -159,7 +160,7 @@ ulog 스트리밍을 지원하는 다양한 클라이언트가 있습니다. - If log streaming does not start, make sure the `logger` is running (see above), and inspect the console output while starting. - 그래도 작동하지 않으면, MAVLink 2를 사용하고 있는지 확인하십시오. - Enforce it by setting `MAV_PROTO_VER` to 2. + `MAV_PROTO_VER` needs to be set to 2. - Log streaming uses a maximum of 70% of the configured MAVLink rate (`-r` parameter). 더 큰 전송율이 요구되는 상황에서는, 메세지가 사라집니다. The currently used percentage can be inspected with `mavlink status` (1.8% is used in this example): diff --git a/docs/ko/dev_log/ulog_file_format.md b/docs/ko/dev_log/ulog_file_format.md index 2af8fc1e78..3fa316935c 100644 --- a/docs/ko/dev_log/ulog_file_format.md +++ b/docs/ko/dev_log/ulog_file_format.md @@ -218,7 +218,7 @@ A key defined in the Information message must be unique. Meaning there must not | `char[value_len] ver_sw_branch` | git branch | "master" | | `uint32_t ver_sw_release` | 소프트웨어 버전 (아래 참고) | 0x010401ff | | `char[value_len] sys_os_name` | 운영체제 이름 | "Linux" | -| `char[value_len] sys_os_ve`r | 운영체제 버전 (git tag) | "9f82919" | +| `char[value_len] sys_os_ver` | 운영체제 버전 (git tag) | "9f82919" | | `uint32_t ver_os_release` | 운영체제 버전 (아래 참고) | 0x010401ff | | `char[value_len] sys_toolchain` | 툴체인 이름 | "GNU GCC" | | `char[value_len] sys_toolchain_ver` | 툴체인 버전 | "6.2.1" | @@ -491,6 +491,7 @@ Since the Definitions and Data Sections use the same message header format, they - [replay module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/replay) - [hardfault_log module](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hardfault_log): append hardfault crash data. - [pyulog](https://github.com/PX4/pyulog): python, ULog reader and writer library with CLI scripts. + The project also has tools to convert ULog to rosbag and other formats. - [ulog_cpp](https://github.com/PX4/ulog_cpp): C++, ULog reader and writer library. - [FlightPlot](https://github.com/PX4/FlightPlot): Java, log plotter. - [MAVLink](https://github.com/mavlink/mavlink): Messages for ULog streaming via MAVLink (note that appending data is not supported, at least not for cut off messages). @@ -501,6 +502,7 @@ Since the Definitions and Data Sections use the same message header format, they - [ulogreader](https://github.com/maxsun/ulogreader): Javascript, ULog reader and parser outputs log in JSON object format. - [Foxglove](https://foxglove.dev): an integrated visualization and diagnosis tool for robotics data that supports ULog files. - [TypeScript ULog parser](https://github.com/foxglove/ulog): TypeScript, ULog reader that outputs JS objects. +- [yule_log](https://crates.io/crates/yule_log): A streaming ULog parser written in Rust. ## 파일 형식 버전 이력 diff --git a/docs/ko/dev_setup/dev_env.md b/docs/ko/dev_setup/dev_env.md index 427f28d302..9ed3e0cfd8 100644 --- a/docs/ko/dev_setup/dev_env.md +++ b/docs/ko/dev_setup/dev_env.md @@ -2,22 +2,22 @@ The _supported platforms_ for PX4 development are: -- [Ubuntu Linux (22.04/20.04/18.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended +- [Ubuntu Linux (24.04/22.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended - [Windows (10/11)](../dev_setup/dev_env_windows_wsl.md) — via WSL2 -- [Mac OS](../dev_setup/dev_env_mac.md) +- [macOS](../dev_setup/dev_env_mac.md) ## 지원 대상 아래 표는 각 OS에서 구축 가능한 PX 대상을 보여줍니다. -| 대상 | Linux (Ubuntu) | Mac | 윈도우 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------: | :-: | :-: | -| **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 | ✓ | | ✓ | +| 대상 | Linux (Ubuntu) | macOS | 윈도우 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------: | :---: | :-: | +| **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) diff --git a/docs/ko/dev_setup/dev_env_linux_ubuntu.md b/docs/ko/dev_setup/dev_env_linux_ubuntu.md index 0da5fb51b3..f9602445b4 100644 --- a/docs/ko/dev_setup/dev_env_linux_ubuntu.md +++ b/docs/ko/dev_setup/dev_env_linux_ubuntu.md @@ -33,24 +33,24 @@ The script is intended to be run on _clean_ Ubuntu LTS installations, and may no 1. [Download PX4 Source Code](../dev_setup/building_px4.md): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 2. Run the **ubuntu.sh** with no arguments (in a bash shell) to install everything: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - - 스크립트가 진행되는 동안 모든 프롬프트를 확인합니다. - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - 스크립트가 진행되는 동안 모든 프롬프트를 확인합니다. + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. 3. If you need Gazebo Classic (Ubuntu 22.04 only) then you can manually remove Gazebo and install it by following the instructions in [Gazebo Classic > Installation](../sim_gazebo_classic/index.md#installation). diff --git a/docs/ko/dev_setup/dev_env_mac.md b/docs/ko/dev_setup/dev_env_mac.md index 5b31516462..63e8e3ca38 100644 --- a/docs/ko/dev_setup/dev_env_mac.md +++ b/docs/ko/dev_setup/dev_env_mac.md @@ -1,4 +1,4 @@ -# MacOS 개발 환경 +# macOS Development Environment 아래에서 macOS용 PX4 개발 환경 설정 방법을 설명합니다. PX4 빌드에 사용되어 집니다. @@ -22,8 +22,8 @@ The "base" macOS setup installs the tools needed for building firmware, and incl ### Environment Setup :::details -Apple Silicon Macbook users! -If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 by setting up an x86 terminal: +Apple Silicon MacBook users! +If you have an Apple M1, M2 etc. MacBook, make sure to run the terminal as x86 by setting up an x86 terminal: 1. Locate the Terminal application within the Utilities folder (**Finder > Go menu > Utilities**) 2. Select _Terminal.app_ and right-click on it, then choose **Duplicate**. @@ -38,21 +38,21 @@ First set up the environment 1. Enable more open files by appending the following line to the `~/.zshenv` file (creating it if necessary): - ```sh - echo ulimit -S -n 2048 >> ~/.zshenv - ``` + ```sh + echo ulimit -S -n 2048 >> ~/.zshenv + ``` - ::: info - If you don't do this, the build toolchain may report the error: `"LD: too many open files"` + ::: info + If you don't do this, the build toolchain may report the error: `"LD: too many open files"` ::: 2. Enforce Python 3 by appending the following lines to `~/.zshenv` - ```sh - # Point pip3 to MacOS system python 3 pip - alias pip3=/usr/bin/pip3 - ``` + ```sh + # Point pip3 to macOS system python 3 pip + alias pip3=/usr/bin/pip3 + ``` ### 공통 도구 @@ -62,19 +62,19 @@ To setup the environment to be able to build for Pixhawk/NuttX hardware (and ins 2. Run these commands in your shell to install the common tools: - ```sh - brew tap PX4/px4 - brew install px4-dev - ``` + ```sh + brew tap PX4/px4 + brew install px4-dev + ``` 3. Install the required Python packages: - ```sh - # install required packages using pip3 - python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - # if this fails with a permissions error, your Python install is in a system path - use this command instead: - sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - ``` + ```sh + # install required packages using pip3 + python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + # if this fails with a permissions error, your Python install is in a system path - use this command instead: + sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + ``` ## Gazebo Classic Simulation @@ -82,35 +82,35 @@ To setup the environment for [Gazebo Classic](../sim_gazebo_classic/index.md) si 1. Run the following commands in your shell: - ```sh - brew unlink tbb - sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb - brew install tbb@2020 - brew link tbb@2020 - ``` + ```sh + brew unlink tbb + sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb + brew install tbb@2020 + brew link tbb@2020 + ``` - ::: info - September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). - They can be removed once it is fixed (along with this note). + ::: info + September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). + They can be removed once it is fixed (along with this note). ::: 2. To install SITL simulation with Gazebo Classic: - ```sh - brew install --cask temurin - brew install --cask xquartz - brew install px4-sim-gazebo - ``` + ```sh + brew install --cask temurin + brew install --cask xquartz + brew install px4-sim-gazebo + ``` 3. Run the macOS setup script: `PX4-Autopilot/Tools/setup/macos.sh` - The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: + The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - cd PX4-Autopilot/Tools/setup - sh macos.sh - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + cd PX4-Autopilot/Tools/setup + sh macos.sh + ``` ## 다음 단계 diff --git a/docs/ko/dev_setup/dev_env_windows_cygwin_packager_setup.md b/docs/ko/dev_setup/dev_env_windows_cygwin_packager_setup.md index eeb68a0c98..24d5c91c24 100644 --- a/docs/ko/dev_setup/dev_env_windows_cygwin_packager_setup.md +++ b/docs/ko/dev_setup/dev_env_windows_cygwin_packager_setup.md @@ -135,31 +135,31 @@ The toolchain gets maintained and hence these instructions might not cover every 10. Download [**Apache Ant**](https://ant.apache.org/bindownload.cgi) as zip archive of the binaries for Windows and unpack the content to the folder `C:\PX4\toolchain\apache-ant`. - :::tip - Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. + :::tip + Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. ::: - ::: info - This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). + ::: info + This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). ::: 11. Download, build and add _genromfs_ to the path: - - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with + - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with ```sh cd /c/toolchain/genromfs git clone https://github.com/chexum/genromfs.git genromfs-src ``` - - Compile it with: + - Compile it with: ```sh cd genromfs-src make all ``` - - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** + - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** 12. Make sure all the binary folders of all the installed components are correctly listed in the `PATH` variable configured by [**setup-environment.bat**](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/scripts/setup-environment.bat). diff --git a/docs/ko/dev_setup/dev_env_windows_vm.md b/docs/ko/dev_setup/dev_env_windows_vm.md index 53106360c7..8d4c829fb7 100644 --- a/docs/ko/dev_setup/dev_env_windows_vm.md +++ b/docs/ko/dev_setup/dev_env_windows_vm.md @@ -57,12 +57,12 @@ VMWare performance is acceptable for basic usage (building Firmware) but not for 모든 설정은 호스트 운영 체제에서 사용하기 위한 것이므로, 네트워크 공격의 위험을 증가시키지 않는 화면 보호기 및 로컬 워크스테이션 보안 기능을 비활성화할 수 있습니다. 10. Once the new VM is booted up make sure you install _VMWare tools drivers and tools extension_ inside your guest system. - 이렇게 하면 다음과 같은 VM 사용의 성능과 유용성들이 향상됩니다. - - 크게 향상된 그래픽 성능 - - Proper support for hardware device usage like USB port allocation (important for target upload), proper mouse wheel scrolling, sound support - - 창 크기에 따른 게스트 디스플레이 해상도 조정 - - 호스트 시스템 클립보드 공유 - - 호스트 시스템 파일 공유 + 이렇게 하면 다음과 같은 VM 사용의 성능과 유용성들이 향상됩니다. + - 크게 향상된 그래픽 성능 + - Proper support for hardware device usage like USB port allocation (important for target upload), proper mouse wheel scrolling, sound support + - 창 크기에 따른 게스트 디스플레이 해상도 조정 + - 호스트 시스템 클립보드 공유 + - 호스트 시스템 파일 공유 11. Continue with [PX4 environment setup for Linux](../dev_setup/dev_env_linux.md) @@ -96,11 +96,11 @@ To allow this, you need to configure USB passthrough settings: 4. Add USB filters for the bootloader in VM: **VirtualBox > Settings > USB > Add new USB filter**. - Open the menu and plug in the USB cable connected to your autopilot. - Select the `...Bootloader` device when it appears in the UI. + Select the `...Bootloader` device when it appears in the UI. - ::: info - The bootloader device only appears for a few seconds after connecting USB. - If it disappears before you can select it, disconnect and then reconnect USB. + ::: info + The bootloader device only appears for a few seconds after connecting USB. + If it disappears before you can select it, disconnect and then reconnect USB. ::: diff --git a/docs/ko/dev_setup/dev_env_windows_wsl.md b/docs/ko/dev_setup/dev_env_windows_wsl.md index 0db75b34e0..fe782c5baa 100644 --- a/docs/ko/dev_setup/dev_env_windows_wsl.md +++ b/docs/ko/dev_setup/dev_env_windows_wsl.md @@ -33,7 +33,7 @@ _QGroundControl for Windows_ is additionally required if you need to: Note that you can also use it to monitor a simulation, but you must manually [connect to the simulation running in WSL](#qgroundcontrol-on-windows). :::info -Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. +Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. ::: :::info @@ -48,38 +48,38 @@ The benefit of WSL2 is that its virtual machine is deeply integrated into Window To install WSL2 with Ubuntu on a new installation of Windows 10 or 11: 1. Make sure your computer your computer's virtualization feature is enabled in the BIOS. - It's usually referred as "Virtualization Technology", "Intel VT-x" or "AMD-V" respectively + It's usually referred as "Virtualization Technology", "Intel VT-x" or "AMD-V" respectively 2. Open _cmd.exe_ as administrator. - This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. + This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. 3. Execute the following commands to install WSL2 and a particular Ubuntu version: - - Default version (Ubuntu 22.04): + - Default version (Ubuntu 22.04): - ```sh - wsl --install - ``` + ```sh + wsl --install + ``` - - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) + - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) - ```sh - wsl --install -d Ubuntu-20.04 - ``` + ```sh + wsl --install -d Ubuntu-20.04 + ``` - - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) + - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) - ```sh - wsl --install -d Ubuntu-22.04 - ``` + ```sh + wsl --install -d Ubuntu-22.04 + ``` - ::: info - You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: + ::: info + You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: ::: 4. WSL will prompt you for a user name and password for the Ubuntu installation. - Record these credentials as you will need them later on! + Record these credentials as you will need them later on! The command prompt is now a terminal within the newly installed Ubuntu environment. @@ -94,26 +94,26 @@ If you're using [Windows Terminal](https://learn.microsoft.com/en-us/windows/ter To open a WSL shell using a command prompt: 1. Open a command prompt: - - Press the Windows **Start** key. - - Type `cmd` and press **Enter** to open the prompt. + - Press the Windows **Start** key. + - Type `cmd` and press **Enter** to open the prompt. 2. To start WSL and access the WSL shell, execute the command: - ```sh - wsl -d - ``` + ```sh + wsl -d + ``` - 예: + 예: - ```sh - wsl -d Ubuntu - ``` + ```sh + wsl -d Ubuntu + ``` - ```sh - wsl -d Ubuntu-20.04 - ``` + ```sh + wsl -d Ubuntu-20.04 + ``` - If you only have one version of Ubuntu, you can just use `wsl`. + If you only have one version of Ubuntu, you can just use `wsl`. Enter the following commands to first close the WSL shell, and then shut down WSL: @@ -135,57 +135,57 @@ To install the development toolchain: 2. Execute the command `cd ~` to switch to the home folder of WSL for the next steps. - :::warning - This is important! - If you work from a location outside of the WSL file system you'll run into issues such as very slow execution and access right/permission errors. + :::warning + This is important! + If you work from a location outside of the WSL file system you'll run into issues such as very slow execution and access right/permission errors. ::: 3. Download the PX4 source code using `git` (which is already installed in WSL2): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 4. Run the **ubuntu.sh** installer script and acknowledge any prompts as the script progresses: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - ::: info - This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: + ::: info + This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. - - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). ::: 5. Restart the "WSL computer" after the script completes (exit the shell, shutdown WSL, and restart WSL): - ```sh - exit - wsl --shutdown - wsl - ``` + ```sh + exit + wsl --shutdown + wsl + ``` 6. Switch to the PX4 repository in the WSL home folder: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 7. Build the PX4 SITL target and test your environment: - ```sh - make px4_sitl - ``` + ```sh + make px4_sitl + ``` For more build options see [Building PX4 Software](../dev_setup/building_px4.md). @@ -205,26 +205,26 @@ To set up the integration: 5. In the WSL shell, switch to the PX4 folder: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 6. In the WSL shell, start VS Code: - ```sh - code . - ``` + ```sh + code . + ``` - This will open the IDE fully integrated with the WSL shell. + This will open the IDE fully integrated with the WSL shell. - Make sure you always open the PX4 repository in the Remote WSL mode. + Make sure you always open the PX4 repository in the Remote WSL mode. 7. Next time you want to develop WSL2 you can very easily open it again in Remote WSL mode by selecting **Open Recent** (as shown below). - This will start WSL for you. + This will start WSL for you. - ![](../../assets/toolchain/vscode/vscode_wsl.png) + ![](../../assets/toolchain/vscode/vscode_wsl.png) - Note however that the IP address of the WSL virtual machine will have changed, so you won't be able to monitor simulation from QGC for Windows (you can still monitor using QGC for Linux) + Note however that the IP address of the WSL virtual machine will have changed, so you won't be able to monitor simulation from QGC for Windows (you can still monitor using QGC for Linux) ## QGroundControl @@ -240,21 +240,21 @@ You can do this from within the WSL shell. 1. In a web browser, navigate to the QGC [Ubuntu download section](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#ubuntu) 2. Right-click on the **QGroundControl.AppImage** link, and select "Copy link address". - This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ + This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ 3. [Open a WSL shell](#opening-a-wsl-shell) and enter the following commands to download the appimage and make it executable (replace the AppImage URL where indicated): - ```sh - cd ~ - wget - chmod +x QGroundControl.AppImage - ``` + ```sh + cd ~ + wget + chmod +x QGroundControl.AppImage + ``` 4. Run QGroundControl: - ```sh - ./QGroundControl.AppImage - ``` + ```sh + ./QGroundControl.AppImage + ``` QGroundControl will launch and automatically connect to a running simulation and allow you to monitor and control your vehicle(s). @@ -270,15 +270,15 @@ These steps describe how you can connect to the simulation running in the WSL: 2. Check the IP address of the WSL virtual machine by running the command `ip addr | grep eth0`: - ```sh - $ ip addr | grep eth0 + ```sh + $ ip addr | grep eth0 - 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 - inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 - ``` + 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 + ``` - Copy the first part of the `eth0` interface `inet` address to the clipboard. - In this case: `172.18.46.131`. + Copy the first part of the `eth0` interface `inet` address to the clipboard. + In this case: `172.18.46.131`. 3. In QGC go to **Q > Application Settings > Comm Links** @@ -304,14 +304,14 @@ Do the following steps to flash your custom binary built in WSL: 1. If you haven't already built the binary in WSL e.g. with a [WSL shell](dev_env_windows_wsl.md#opening-a-wsl-shell) and by running: - ```sh - cd ~/PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + cd ~/PX4-Autopilot + make px4_fmu-v5 + ``` - ::: tip - Use the correct `make` target for your board. - `px4_fmu-v5` can be used for a Pixhawk 4 board. + ::: tip + Use the correct `make` target for your board. + `px4_fmu-v5` can be used for a Pixhawk 4 board. ::: @@ -325,12 +325,12 @@ Do the following steps to flash your custom binary built in WSL: 6. Continue and select the firmware binary you just built in WSL. - In the open dialog look for the "Linux" location with the penguin icon in the left pane. - It's usually all the way at the bottom. - Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` + In the open dialog look for the "Linux" location with the penguin icon in the left pane. + It's usually all the way at the bottom. + Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` - ::: info - You can add the folder to the favourites to access it quickly next time. + ::: info + You can add the folder to the favourites to access it quickly next time. ::: @@ -349,3 +349,9 @@ sudo add-apt-repository ppa:kisak/kisak-mesa sudo apt update sudo apt upgrade ``` + +### QGroundControl not connecting to PX4 SITL + +- The connection between PX4 SITL on WSL2 and QGroundControl on Windows requires [broadcasting](../simulation/index.md#enable-udp-broadcasting) or [streaming to a specific address](../simulation/index.md#enable-streaming-to-specific-address) to be enabled. + Streaming to a specific address should be enabled by default, but is something to check if a connection can't be established. +- Network traffic might be blocked by firewall or antivirus on you system. diff --git a/docs/ko/dev_setup/vscode.md b/docs/ko/dev_setup/vscode.md index cea5748cab..75ac6d2cdd 100644 --- a/docs/ko/dev_setup/vscode.md +++ b/docs/ko/dev_setup/vscode.md @@ -27,10 +27,10 @@ You must already have installed the command line [PX4 developer environment](../ - Select _Open folder ..._ option on the welcome page (or using the menu: **File > Open Folder**): - ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) + ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) - A file selection dialog will appear. - Select the **PX4-Autopilot** directory and then press **OK**. + Select the **PX4-Autopilot** directory and then press **OK**. The project files and configuration will then load into _VSCode_. @@ -49,9 +49,9 @@ You must already have installed the command line [PX4 developer environment](../ ::: - 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)). + - 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: - - 이것은 당신에게 달려 있습니다! Github와 IDE 간의 긴밀한 통합을 제공하여 워크플로를 단순화할 수 있습니다. + - 이것은 당신에게 달려 있습니다! Github와 IDE 간의 긴밀한 통합을 제공하여 워크플로를 단순화할 수 있습니다. - Other prompts are optional, and may be installed if they seem useful. @@ -63,21 +63,21 @@ You must already have installed the command line [PX4 developer environment](../ 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). - ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) + ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) - ::: info - The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). + ::: info + The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). ::: - Click the target on the config bar to display other options, and select the one you want (this will replace any selected target). - _Cmake_ will then configure your project (see notification in bottom right). - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) - Wait until configuration completes. - When this is done the notification will disappear and you'll be shown the build location: - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). + When this is done the notification will disappear and you'll be shown the build location: + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). 2. You can then kick off a build from the config bar (select either **Build** or **Debug**). ![Run debug or build](../../assets/toolchain/vscode/run_debug_build.jpg) diff --git a/docs/ko/dronecan/ark_cannode.md b/docs/ko/dronecan/ark_cannode.md index d87becac70..918d210e8f 100644 --- a/docs/ko/dronecan/ark_cannode.md +++ b/docs/ko/dronecan/ark_cannode.md @@ -83,9 +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: -| 매개변수 | 설명 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED 신호의 의미 diff --git a/docs/ko/dronecan/ark_dist.md b/docs/ko/dronecan/ark_dist.md new file mode 100644 index 0000000000..090ce27960 --- /dev/null +++ b/docs/ko/dronecan/ark_dist.md @@ -0,0 +1,98 @@ +# ARK DIST SR + +ARK DIST SR is a low range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). +It has an approximate range of between 8cm to 30m. + +![ARK DIST SR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-sr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- 센서 + - [Broadcom AFBR-S50LV85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lv85d) + - Typical distance range up to 30m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 84mA Average + - 86mA Max + +## 하드웨어 설정 + +### 배선 + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST SR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 설정 + +### DroneCAN + +#### Enable DroneCAN + +단계는 다음과 같습니다: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `30`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## See Also + +- [ARK DIST SR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/ko/dronecan/ark_dist_mr.md b/docs/ko/dronecan/ark_dist_mr.md new file mode 100644 index 0000000000..a65866d1bf --- /dev/null +++ b/docs/ko/dronecan/ark_dist_mr.md @@ -0,0 +1,97 @@ +# ARK DIST MR + +ARK DIST MR is a mid range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). + +![ARK DIST MR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-mr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- 센서 + - [Broadcom AFBR-S50LX85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lx85d) + - Typical distance range up to 50m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 78mA Average + - 84mA Max + +## 하드웨어 설정 + +### 배선 + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST MR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 설정 + +### DroneCAN + +#### Enable DroneCAN + +단계는 다음과 같습니다: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `50`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## See Also + +- [ARK DIST MR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/ko/dronecan/ark_flow.md b/docs/ko/dronecan/ark_flow.md index 780cd8a9bd..8ce7da3a11 100644 --- a/docs/ko/dronecan/ark_flow.md +++ b/docs/ko/dronecan/ark_flow.md @@ -94,6 +94,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -109,9 +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: -| 매개변수 | 설명 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED 신호의 의미 diff --git a/docs/ko/dronecan/ark_flow_mr.md b/docs/ko/dronecan/ark_flow_mr.md index 6ca91d771d..e949b4cfa3 100644 --- a/docs/ko/dronecan/ark_flow_mr.md +++ b/docs/ko/dronecan/ark_flow_mr.md @@ -91,6 +91,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -104,9 +105,10 @@ 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: -| 매개변수 | 설명 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED 신호의 의미 diff --git a/docs/ko/dronecan/ark_g5_rtk_gps.md b/docs/ko/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..92ab020b62 --- /dev/null +++ b/docs/ko/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 센서 + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 부저 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 크기 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 하드웨어 설정 + +### 배선 + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## LED 신호의 의미 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/ark_g5_rtk_heading_gps.md b/docs/ko/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..3b019a9b96 --- /dev/null +++ b/docs/ko/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 센서 + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 부저 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 크기 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 하드웨어 설정 + +### 배선 + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## LED 신호의 의미 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## See Also + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/ark_gps.md b/docs/ko/dronecan/ark_gps.md index 9d604f745d..4bcd150a6d 100644 --- a/docs/ko/dronecan/ark_gps.md +++ b/docs/ko/dronecan/ark_gps.md @@ -91,9 +91,17 @@ If the sensor is not centred within the vehicle you will also need to define sen - Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` if this is that last node on the CAN bus. - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK GPS from the vehicles centre of gravity. +### ARK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK GPS itself: + +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 신호의 의미 You will see green, blue and red LEDs on the ARK GPS when it is being flashed, and a blinking green LED if it is running properly. diff --git a/docs/ko/dronecan/ark_rtk_gps.md b/docs/ko/dronecan/ark_rtk_gps.md index 33d67fc4ee..e66dfbbcb6 100644 --- a/docs/ko/dronecan/ark_rtk_gps.md +++ b/docs/ko/dronecan/ark_rtk_gps.md @@ -20,6 +20,7 @@ Order this module from: - Multi-band RTK with fast convergence times and reliable performance - High update rate for highly dynamic applications - Centimetre accuracy in a small and energy efficient module + - Moving Base for Heading - Bosch BMM150 Magnetometer - Bosch BMP388 Barometer - Invensense ICM-42688-P 6-Axis IMU @@ -27,7 +28,7 @@ Order this module from: - Safety Button - 부저 - Two Pixhawk Standard CAN Connectors (4 Pin JST GH) -- F9P “UART 2” Connector +- F9P `UART 2` Connector - 3 Pin JST GH - TX, RX, GND - Pixhawk Standard Debug Connector (6 Pin JST SH) @@ -85,7 +86,34 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if - Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS from the vehicles centre of gravity. -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` on the GPS if this it that last node on the CAN bus. + +### ARK RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS itself: + +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. ### Setting Up Moving Baseline & GPS Heading @@ -128,10 +156,11 @@ Setup via UART: - On the _Moving Base_, set the following: - [GPS_UBX_MODE](../advanced_config/parameter_reference.md#GPS_UBX_MODE) to `2`. +For more information see [Rover and Moving Base](../dronecan/index.md#rover-and-moving-base) in the DroneCAN guide. + ## LED 신호의 의미 - The GPS status lights are located to the right of the connectors - - Blinking green is GPS fix - Blinking blue is received corrections and RTK Float - Solid blue is RTK Fixed diff --git a/docs/ko/dronecan/ark_rtk_gps_l1_l2.md b/docs/ko/dronecan/ark_rtk_gps_l1_l2.md new file mode 100644 index 0000000000..de5de1a5eb --- /dev/null +++ b/docs/ko/dronecan/ark_rtk_gps_l1_l2.md @@ -0,0 +1,163 @@ +# ARK RTK GPS L1 L5 + +[ARK RTK GPS L1 L5](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox F9P](https://www.u-blox.com/en/product/zed-f9p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK RTK GPS L1 L5](../../assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-rtk-gps-l1-l5/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- 센서 + - Ublox F9P GPS + - Multi-band GNSS receiver delivers centimetre level accuracy in seconds + - Concurrent reception of GPS, GLONASS, Galileo and BeiDou + - Multi-band RTK with fast convergence times and reliable performance + - High update rate for highly dynamic applications + - Centimetre accuracy in a small and energy efficient module + - Does not Support Moving Base for Heading + - Bosch BMM150 Magnetometer + - Bosch BMP388 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412CEU6 MCU +- Safety Button +- 부저 +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- F9P `UART 2` Connector + - 3 Pin JST GH + - TX, RX, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 170mA Average + - 180mA Max + +## 하드웨어 설정 + +### 배선 + +The ARK RTK GPS L1 L5 is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK RTK GPS L1 L5 runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK RTK GPS L1 L5 boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK RTK GPS L1 L5, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK RTK GPS L1 L5 CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS L1 L5 from the vehicles centre of gravity. + +### ARK RTK GPS L1 L5 Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS L1 L5 itself: + +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED 신호의 의미 + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK RTK GPS L1 L5 has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +### Updating Ublox F9P Module + +ARK RTK GPS L1 L5 comes with the Ublox F9P module up to date with version 1.13 or newer. However, you can check the version and update the firmware if desired. + +단계는 다음과 같습니다: + +1. [Download u-center from u-blox.com](https://www.u-blox.com/en/product/u-center) and install on your PC (Windows only) +2. Open the [u-blox ZED-F9P website](https://www.u-blox.com/en/product/zed-f9p-module#tab-documentation-resources) +3. Scroll down and click on the "Show Legacy Documents" box +4. Scroll down again to Firmware Update and download your desired firmware (at least version 1.13 is needed) +5. While holding down the safety switch on the ARK RTK GPS L1 L5, connect it to power via one of its CAN ports and hold until all 3 LEDs blink rapidly +6. Connect the ARK RTK GPS L1 L5 to your PC via its debug port with a cable such as the Black Magic Probe or an FTDI +7. Open u-center, select the COM port for the ARK RTK GPS L1 L5 and connect + ![U-Center Connect](../../assets/hardware/gps/ark/ark_rtk_gps_ucenter_connect.png) +8. Check the current firmware version by selecting View, Messages View, UBX, MON, VER + ![Check Version](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_version.png) +9. To update the firmware: + 1. Select Tools, Firmware Update + 2. The Firmware image field should be the .bin file downloaded from the u-blox ZED-F9P website + 3. Check the "Use this baudrate for update" checkbox and select 115200 from the drop-down + 4. Ensure the other checkboxes are as shown below + 5. Push the green GO button on the bottom left + 6. "Firmware Update SUCCESS" should be displayed if it updated successfully + ![Firmware Update](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_f9p_firmware_update.png) + +## See Also + +- [ARK RTK GPS L1 L5 Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/ark_x20_rtk_gps.md b/docs/ko/dronecan/ark_x20_rtk_gps.md new file mode 100644 index 0000000000..6473bae5db --- /dev/null +++ b/docs/ko/dronecan/ark_x20_rtk_gps.md @@ -0,0 +1,141 @@ +# ARK X20 RTK GPS + +[ARK X20 RTK GPS](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox ZED-X20P all-band high precision GNSS module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK X20 RTK GPS](../../assets/hardware/gps/ark/ark_x20_rtk_gps.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-x20-rtk-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- 센서 + - Ublox ZED-X20P + - All-band all constellation GNSS receiver + - Best position accuracy and availability in different environments + - RTK, PPP-RTK and PPP algorithms expanding the limits of performance + - Highest quality GNSS raw data + - u-blox end-to-end hardened security + - 25Hz update rate + - ST IIS2MDC Magnetometer + - Bosch BMP390 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412VGH6 MCU +- Safety Button +- 부저 +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- X20 “UART 2” Connector + - 4 Pin JST GH + - TX, RX, PPS, GND +- I2C Expansion Connector + - 4 Pin JST-GH + - 5.0V, SCL, SDA, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 144mA Average + - 157mA Max + +## 하드웨어 설정 + +### 배선 + +The ARK X20 RTK GPS is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### 장착 + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK X20 RTK GPS runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK X20 RTK GPS boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK X20 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +단계는 다음과 같습니다: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK X20 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 설정 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK X20 RTK GPS from the vehicles centre of gravity. + +### ARK X20 RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK X20 RTK GPS itself: + +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED 신호의 의미 + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK X20 RTK GPS has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +## See Also + +- [ARK X20 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) (ARK Docs) diff --git a/docs/ko/dronecan/escs.md b/docs/ko/dronecan/escs.md index 9742e3739e..6afea8c2e2 100644 --- a/docs/ko/dronecan/escs.md +++ b/docs/ko/dronecan/escs.md @@ -1,7 +1,14 @@ # DroneCAN ESCs PX4 supports DroneCAN compliant ESCs. -For more information, see the following articles for specific hardware/firmware: + +## Supported ESC + +:::info +[Supported ESCs](../peripherals/esc_motors#supported-esc) in _ESCs & Motors_ may include additional devices that are not listed below. +::: + +The following articles have specific hardware/firmware information: - [PX4 Sapog ESC Firmware](sapog.md) - [Holybro Kotleta 20](holybro_kotleta.md) @@ -9,3 +16,18 @@ For more information, see the following articles for specific hardware/firmware: - [Vertiq](../peripherals/vertiq.md) (larger modules) - [VESC Project](../peripherals/vesc.md) - [RaccoonLab Cyphal and DroneCAN PWM nodes](raccoonlab_nodes.md) + +## 하드웨어 설정 + +General DroneCAN hardware configuration is covered in [DroneCAN > Hardware Setup](../dronecan/index.md#hardware-setup). + +DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + +## PX4 설정 + +DroneCAN peripherals are configured by following the procedure outlined in [DroneCAN](../dronecan/index.md). + +In addition to the general setup, such as setting `UAVCAN_ENABLE` to `3`: + +- Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +- Configure the [motor order and servo outputs](../config/actuators.md). diff --git a/docs/ko/dronecan/holybro_h_rtk_zed_f9p_gps.md b/docs/ko/dronecan/holybro_h_rtk_zed_f9p_gps.md index 2bc989c83c..41302b0a1d 100644 --- a/docs/ko/dronecan/holybro_h_rtk_zed_f9p_gps.md +++ b/docs/ko/dronecan/holybro_h_rtk_zed_f9p_gps.md @@ -64,10 +64,10 @@ To update the "AP Periph" firmware to the latest version: 1. [Download the latest binary](https://firmware.ardupilot.org/AP_Periph/latest/HolybroG4_GPS/). 2. Update the firmware using either of the following approaches: - - Using ArduPilot: - 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. - 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. - - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). + - Using ArduPilot: + 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. + 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. + - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). Remember to change the firmware on the flight controller back to PX4 afterwards. @@ -98,14 +98,14 @@ In order to use dual ZED-F9P GPS heading in PX4, follow these steps: 1. Open the QGroundControl parameters page. 2. On the left side next to the parameters list, double-click on the _System_ section (this hides the section). 3. Components should be visible on the left panel. - Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). + Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). 4. 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 - - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. - This is the local offset (FRD) with respect to the autopilot. + - `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 + - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. + This is the local offset (FRD) with respect to the autopilot. ![QGC Setup](../../assets/hardware/gps/holybro_h_rtk_zed_f9p_rover/holybro_f9p_gps_qgc_setup.png) diff --git a/docs/ko/dronecan/index.md b/docs/ko/dronecan/index.md index c50f5bcfdb..8b6738922d 100644 --- a/docs/ko/dronecan/index.md +++ b/docs/ko/dronecan/index.md @@ -27,6 +27,8 @@ Connecting peripherals over DroneCAN has many benefits: - Wiring is less complicated as you can have a single bus for connecting all your ESCs and other DroneCAN peripherals. - Setup is easier as you configure ESC numbering by manually spinning each motor. - It allows users to configure and update the firmware of all CAN-connected devices centrally through PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## 지원 하드웨어 @@ -67,6 +69,8 @@ Supported hardware includes (this is not an exhaustive list): - [RaccoonLab RM3100 Magnetometer](https://docs.raccoonlab.co/guide/gps_mag_baro/mag_rm3100.html) - Distance sensors + - [ARK Dist](ark_dist.md) + - [Ark Dist MR](ark_dist_mr.md) - [ARK Flow](ark_flow.md) - [Ark Flow MR](ark_flow_mr.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface](../dronecan/avanon_laser_interface.md) @@ -102,6 +106,10 @@ If the DNA is still running and certain devices need to be manually configured, :::info The PX4 node ID can be configured using the [UAVCAN_NODE_ID](../advanced_config/parameter_reference.md#UAVCAN_NODE_ID) parameter. The parameter is set to 1 by default. + +Devices running the [PX4 DroneCAN firmware](px4_cannode_fw.md) (such as [ARK CANnode](ark_cannode.md)) can use the +[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter to set a static node ID. +Set it to 0 (default) for dynamic allocation, or to a value between 1-127 to use a specific static node ID. ::: :::warning @@ -276,6 +284,9 @@ PX4 DroneCAN parameters: [DroneCAN ESCs and servos](../dronecan/escs.md) require the [motor order and servo outputs](../config/actuators.md) to be configured. +Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +Note that DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + ## QGC CANNODE Parameter Configuration QGroundControl can inspect and modify parameters belonging to CAN devices attached to the flight controller, provided the device are connected to the flight controller before QGC is started. @@ -285,6 +296,11 @@ For example, the screenshot below shows the parameters for a CAN GPS with node i ![QGC Parameter showing selected DroneCAN node](../../assets/can/dronecan/qgc_can_parameters.png) +Common CANNODE parameters that you can configure include: + +- [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID): Set a static node ID (1-127) or use 0 for dynamic allocation. See [PX4 DroneCAN Firmware > Static Node ID](px4_cannode_fw.md#static-node-id) for more information. +- [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM): Enable CAN bus termination on the last node in the bus. + ## Device Specific Setup Most DroneCAN nodes require no further setup, unless specifically noted in their device-specific documentation. @@ -313,7 +329,10 @@ If successful, the firmware binary will be removed from the root directory and t **Q**: The motors aren't spinning when armed. -**A**: Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +**A**: + +- Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +- Make sure `UAVCAN_ESC_IFACE` is set to enable the CAN interface(s) used for ESCs. --- diff --git a/docs/ko/dronecan/pomegranate_systems_pm.md b/docs/ko/dronecan/pomegranate_systems_pm.md index d63d011d6c..3550f395b3 100644 --- a/docs/ko/dronecan/pomegranate_systems_pm.md +++ b/docs/ko/dronecan/pomegranate_systems_pm.md @@ -45,11 +45,11 @@ Source code and build instructions can be found on [the bitbucket](https://bitbu 1. Enable DroneCAN by setting the [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) parameter to `2` (Sensors Automatic Config) or `3`. 2. Enable DroneCAN battery monitoring by setting [UAVCAN_SUB_BAT](../advanced_config/parameter_reference.md#UAVCAN_SUB_BAT) to `1` or `2` ( depending on your battery). 3. Set the following module parameters using the [MAVLink console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - - Battery capacity in mAh: `battery_capacity_mAh` - - Battery voltage when _full_: `battery_full_V`, - - Battery voltage when _empty_: `battery_empty_V` - - Turn on current integration: `enable_current_track` - - (optional) Turn Off CANbus termination resistor :`enable_can_term` + - Battery capacity in mAh: `battery_capacity_mAh` + - Battery voltage when _full_: `battery_full_V`, + - Battery voltage when _empty_: `battery_empty_V` + - Turn on current integration: `enable_current_track` + - (optional) Turn Off CANbus termination resistor :`enable_can_term` **Example:** A Power Module with UAVCAN node id `125` connected to a `3S` LiPo with capacity of `5000mAh` can be configured with the following commands: diff --git a/docs/ko/dronecan/px4_cannode_fw.md b/docs/ko/dronecan/px4_cannode_fw.md index 65262d4152..3e29a57f5a 100644 --- a/docs/ko/dronecan/px4_cannode_fw.md +++ b/docs/ko/dronecan/px4_cannode_fw.md @@ -20,6 +20,26 @@ make ark_can-flow_default This will create an output in **build/ark_can-flow_default** named **XX-X.X.XXXXXXXX.uavcan.bin**. Follow the instructions at [DroneCAN firmware update](index.md#firmware-update) to flash the firmware. +## 설정 + +### Static Node ID + +By default, DroneCAN devices use [Dynamic Node Allocation (DNA)](index.md#node-id-allocation) to automatically obtain a unique node ID from the flight controller. +However, you can configure a static node ID using the [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter. + +To configure a static node ID: + +1. Set [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) to a value between 1-127 using [QGroundControl](index.md#qgc-cannode-parameter-configuration) +2. Reboot the device + +To return to dynamic allocation, set `CANNODE_NODE_ID` back to 0. +Note that when switching back to dynamic allocation, the flight controller will typically continue to allocate the same node ID that was previously used (this is normal DNA behavior). + +:::warning +When using static node IDs, you must ensure that each device on the CAN bus has a unique node ID. +Configuring two devices with the same ID will cause communication conflicts. +::: + ## 개발자 정보 This section has information that is relevant to developers who want to add support for new DroneCAN hardware to the PX4 Autopilot. diff --git a/docs/ko/dronecan/raccoonlab_power.md b/docs/ko/dronecan/raccoonlab_power.md index 89bbc203cb..7b62f10d27 100644 --- a/docs/ko/dronecan/raccoonlab_power.md +++ b/docs/ko/dronecan/raccoonlab_power.md @@ -7,9 +7,9 @@ CAN power connectors are designed for light unmanned aerial (UAV) and other vehi There are two types of devices: 1. `CAN-MUX` devices provide power from XT30 connector to CAN. - There are 2 variation of this type of the device with different number of connectors. + There are 2 variation of this type of the device with different number of connectors. 2. `Power connector node` is designed to pass current (up to 60A) to power load and CAN, measure voltage and current on load. - It behaves as Cyphal/DroneCAN node. + It behaves as Cyphal/DroneCAN node. Please refer to the RaccoonLab docs [CAN Power Connectors](https://docs.raccoonlab.co/guide/pmu/power/) page. diff --git a/docs/ko/esc/ark_4in1_esc.md b/docs/ko/esc/ark_4in1_esc.md new file mode 100644 index 0000000000..e558bb5668 --- /dev/null +++ b/docs/ko/esc/ark_4in1_esc.md @@ -0,0 +1,65 @@ +# ARK 4IN1 ESC (with/without Connectors) + +4 in 1 Electronic Speed Controller (ESC) that is made in the USA, NDAA compliant, and DIU Blue Framework listed. + +The ESC comes in variants without connectors that you can solder in place, and a variant that has built-in motor and battery connectors (no soldering required). + +![ARK 4IN1 ESC without connectors ](../../assets/hardware/esc/ark/ark_4_in_1_esc.jpg)![ARK 4IN1 ESC with connectors](../../assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg) + +## 구매처 + +Order this module from: + +- [4IN1 ESC (with connectors)](https://arkelectron.com/product/ark-4in1-esc/) (ARK Electronics - US) +- [ARK Electronics (without connectors)](https://arkelectron.com/product/ark-4in1-esc-cons/) (ARK Electronics US) + +## Hardware Specifications + +- Battery Voltage: 3-8s + - 6V Minimum + - 65V Absolute Maximum + +- Current Rating: 50A Continuous, 75A Burst Per Motor + +- [STM32F0](https://www.st.com/en/microcontrollers-microprocessors/stm32f0-series.html) + +- [AM32 Firmware](https://github.com/am32-firmware/AM32/pull/27) + +- Onboard Current Sensor, Serial Telemetry + - 100V/A + +- Input Protocols + - DShot (300, 600) + - Bi-directional DShot + - KISS Serial Telemetry + - PWM + +- 8 Pin JST-SH Input/Output + +- 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 + +- Dimensions (without connectors) + - Size: 43.00mm x 40.50mm x 7.60mm + - Mounting Pattern: 30.5mm + - Weight: 14.5g + +Other + +- Made in the USA +- Open source AM32 firmware +- [DIU Blue Framework Listed](https://www.diu.mil/blue-uas/framework) + +## See Also + +- [ARK 4IN1 ESC CONS](https://docs.arkelectron.com/electronic-speed-controller/ark-4in1-esc) (ARK Docs) diff --git a/docs/ko/esc/esc_protocols.md b/docs/ko/esc/esc_protocols.md new file mode 100644 index 0000000000..930d436de6 --- /dev/null +++ b/docs/ko/esc/esc_protocols.md @@ -0,0 +1,66 @@ +# ESC Protocols + +This topic lists the main [Electronic Speed Controller (ESC)](../peripherals/esc_motors.md) protocols supported by PX4. + +## DShot + +[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduced latency, in particular racing multicopters, VTOL vehicles, and so on. + +It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). +In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can reverse motor spin directions. + +PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). +Selecting a higher rate DShot ESC in the UI results in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. + +## DroneCAN + +[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. +The PX4 implementation is currently limited to update rates of 200 Hz. + +DroneCAN shares many similar benefits to [DShot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. + +[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). + +## PWM + +[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). + +PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired speed. +The pulse width typically ranges between 1000 μs for zero power and 2000 μs for full power. +The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50 Hz and 490 Hz (the theoretical maximum being 500 Hz for a very small "off" cycle). +A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. +For PWM servos 50 Hz is usually sufficient, and many don't support higher rates. + +![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) + +In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the pulse widths representing low and high values can vary significantly. +Unlike [DShot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) +- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) + +## OneShot 125 + +[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. +They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). +There are a number of variants of the OneShot protocol, which support different rates. +PX4 only supports OneShot 125. + +OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125 μs to 250 μs for zero to full power). +This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. +For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. +The actual supported rate depends on the ESC used. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) diff --git a/docs/ko/features_fw/gain_compression.md b/docs/ko/features_fw/gain_compression.md new file mode 100644 index 0000000000..855e64c08b --- /dev/null +++ b/docs/ko/features_fw/gain_compression.md @@ -0,0 +1,24 @@ +# Gain compression + + + +Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. +It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. + +This approach is a safe adaptive mechanism for stable aircraft: the PID gains remain unchanged when no oscillations are present, they are never increased beyond their nominal values, and they are bounded by a minimum limit. + +Gain compression can help prevent actuator damage and even loss of the vehicle in cases such as airspeed-sensor failure (loss of airspeed scaling) or in-flight changes in dynamics (e.g.: CG shifts, inertia changes), or other failures that could cause the angular-rate loop to become oscillatory. + +![Gain compression diagram](../../assets/config/fw/gain_compression_diagram.png) + +## 사용법 + +Gain compression is enabled by default ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)). + +It should be disabled during fixed wing [manual tuning](../config_fw/pid_tuning_guide_fixedwing.md) to avoid over-tuning. +It does not need to be disabled when autotuning. + +## 매개변수 + +- [FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN) +- [FW_GC_GAIN_MIN](../advanced_config/parameter_reference.md#FW_GC_GAIN_MIN) diff --git a/docs/ko/features_fw/index.md b/docs/ko/features_fw/index.md new file mode 100644 index 0000000000..7eab8e9c6c --- /dev/null +++ b/docs/ko/features_fw/index.md @@ -0,0 +1,5 @@ +# Fixedwing-Specific Features + +This section lists features that are specific to (or customised for) fixed-wings: + +- [Gain Compression](../features_fw/gain_compression.md) diff --git a/docs/ko/flight_controller/accton-godwit_ga1.md b/docs/ko/flight_controller/accton-godwit_ga1.md new file mode 100644 index 0000000000..bd968f852e --- /dev/null +++ b/docs/ko/flight_controller/accton-godwit_ga1.md @@ -0,0 +1,153 @@ +# Accton Godwit G-A1 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://cubepilot.org/#/home) for hardware support or compliance issues. +::: + +The G-A1 is a state-of-the-art flight controller developed derived from the [Pixhawk Autopilot v6X Standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-012%20Pixhawk%20Autopilot%20v6X%20Standard.pdf). + +It includes an STM32H753 double-precision floating-point FMU processor and an STM32F103 IO coprocessor, multiple IMUs with 6-axis inertial sensors, two pressure/temperature sensors, and a geomagnetic sensor. +It also has independent buses and power supplies, and is designed for safety and rich expansion capabilities. + +With an integrated 10/100M Ethernet Physical Layer (PHY), the G-A1 can also communicate with a mission computer (airborne computer), high-end surveying and mapping cameras, and other UxV-mounted equipment for high-speed communications, meeting the needs of advanced UxV systems. + +:::tip +Visit [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) for more information. +::: + +![AccGodwitGA1](../../assets/flight_controller/accton-godwit/ga1/outlook.png "Accton Godwit G-A1") + +![AccGodwitGA1 Top View](../../assets/flight_controller/accton-godwit/ga1/orientation.png "Accton Godwit G-A1 Top View") + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## 사양 + +### 프로세서 + +- STM32H753IIK (Arm® Cortex®-M7 480MHz) +- STM32F103 (Arm® Cortex®-M3, 72MHz) + +### 센서 + +- Bosch BMI088 (vibration isolated) +- TDK InvenSense ICM-42688-P x 2 (one vibration isolated) +- TDK Barometric Pressure and Temperature Sensor CP-20100 x 2 (one vibration isolated) +- PNI RM3100 Geomagnetic Sensor (vibration isolated) + +### 전원 + +- 4.6V to 5.7V + +### External ports + +- 2 CAN Buses (CAN1 and CAN2) +- 3 TELEM Ports (TELEM1, TELEM2 and TELEM3) +- 2 GPS Ports (GPS1 with safety switch, LED, buzzer, and GPS2) +- 1 PPM IN +- 1 SBUS OUT +- 2 USB Ports (1 TYPE-C and 1 JST GH1.25) +- 1 10/100Base-T Ethernet Port +- 1 DSM/SBUS RC +- 1 UART 4 +- 1 AD&IO Port +- 2 Debug Ports (1 IO Debug and 1 FMU Debug) +- 1 SPI6 Bus +- 4 Power Inputs (Power 1, Power 2, Power C1 and Power C2) +- 16 PWM Servo Outputs (A1-A8 from FMU and M1-M8 from IO) +- Micro SD Socket (supports SD 4.1 & SDIO 4.0 in two databus modes: 1 bit (default) and 4 bits) + +### Size and Dimensions + +- 92.2 (L) x 51.2 (W) x 28.3 (H) mm +- 77.6g (carrier board with IMU) + +## 구매처 + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) + +## 핀배열 + +![G-A1 Pin definition](../../assets/flight_controller/accton-godwit/ga1/pin_definition.png "G-A1 Pin definition") + +## UART Mapping + +| Serial# | Protocol | 포트 | 참고 | +| ------- | --------- | ------ | ---------- | +| SERIAL1 | Telem1 | UART7 | /dev/ttyS6 | +| SERIAL2 | Telem2 | UART5 | /dev/ttyS4 | +| SERIAL3 | GPS1 | USART1 | /dev/ttyS0 | +| SERIAL4 | GPS2 | UART8 | /dev/ttyS7 | +| SERIAL5 | Telem3 | USART2 | /dev/ttyS1 | +| SERIAL6 | UART4 | UART4 | /dev/ttyS3 | +| SERIAL7 | FMU Debug | USART3 | | +| SERIAL8 | OTG2 | USB | | + +## Wiring Diagram + +![G-A1 Wiring](../../assets/flight_controller/accton-godwit/ga1/wiring.png "G-A1 Wiring") + +## PWM Output + +PWM M1-M8 (IO Main PWM), A1-A8(FMU PWM). +All these 16 support normal PWM output formats. +FMU PWM A1-A6 can support DShot and B-Directional DShot. +A1-A8(FMU PWM) are grouped as: + +- Group 1: A1, A2, A3, A4 +- Group 2: A5, A6 +- Group 3: A7, A8 + +The motor and servo system should be connected to these ports according to the order outlined in the fuselage reference for your carrier. + +![G-A1 PWM Motor Servo](../../assets/flight_controller/accton-godwit/ga1/motor_servo.png "G-A1 PWM Motor Servo") + +## RC Input + +For DSM/SBUS receivers, connect them to the DSM/SBUS interface which provides dedicated 3.3V and 5V power pins respectively, and check above "Pinout" for detailed pin definition. +PPM receivers should be connected to the PPM interface. And other RC systems can be connected via other spare telemetry ports. + +![G-A1 Radio](../../assets/flight_controller/accton-godwit/ga1/radio.png "G-A1 Radio") + +## GPS/나침반 + +The Godwit G-A1 has a built-in compass +Due to potential interference, the autopilot is usually used with an external I2C compass as part of a GPS/Compass combination. + +![G-A1 GPS](../../assets/flight_controller/accton-godwit/ga1/gps.png "G-A1 GPS") + +## Power Connection and Battery Monitor + +This universal controller features a CAN PMU module that supports 3 to 14s lithium batteries. +To ensure proper connection, attach the module's 6-pin connector to the flight control Power C1 and/or Power C2 interface. + +This universal controller does not provide power to the servos. +To power them, an external BEC must be connected to the positive and negative terminals of any A1–A8 or M1–M8 port. + +![G-A1 Power](../../assets/flight_controller/accton-godwit/ga1/power.png "G-A1 Power") + +## SD 카드 + +The SD card is NOT included in the package, you need to prepare the SD card and insert it into the slot. + +![G-A1 SD Card](../../assets/flight_controller/accton-godwit/ga1/sdcard.png "G-A1 SD Card") + +## 펌웨어 + +The autopilot is compatible with PX4 firmware. And G-A1 can be detected by QGroundControl automatically. Users can also build it with target "accton-godwit_ga1" + +To [build PX4](../dev_setup/building_px4.md) for this target, open up the terminal and enter: + +```sh +make accton-godwit_ga1 +``` + +## More Information and Support + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) +- [support@accton-iot.com](mailto:support@accton-iot.com) diff --git a/docs/ko/flight_controller/autopilot_manufacturer_supported.md b/docs/ko/flight_controller/autopilot_manufacturer_supported.md index 45c768b388..780c5bcf81 100644 --- a/docs/ko/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/ko/flight_controller/autopilot_manufacturer_supported.md @@ -12,6 +12,7 @@ This category includes boards that are not fully compliant with the pixhawk stan 이 카테고리의 보드는 다음과 같습니다. +- [Accton Godwit GA1](../flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](../flight_controller/mindpx.md) - [AirMind MindRacer](../flight_controller/mindracer.md) - [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) (and [ARK Electronics Pixhawk Autopilot Bus Carrier](../flight_controller/ark_pab.md)) @@ -29,9 +30,13 @@ This category includes boards that are not fully compliant with the pixhawk stan - [Holybro Kakute H7](../flight_controller/kakuteh7.md) - [Holybro Durandal](../flight_controller/durandal.md) - [Holybro Pix32 v5](../flight_controller/holybro_pix32_v5.md) +- [MicoAir H743 Lite](../flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](../flight_controller/modalai_voxl_2.md) - [mRo Control Zero](../flight_controller/mro_control_zero_f7.md) +- [Radiolink PIX6](../flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](../flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](../flight_controller/spracingh7extreme.md) +- [Svehicle E2](../flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](../flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](../flight_controller/thepeach_r1.md) +- [X-MAV AP-H743-R1](../flight_controller/x-mav_ap-h743r1.md) diff --git a/docs/ko/flight_controller/micoair743-lite.md b/docs/ko/flight_controller/micoair743-lite.md new file mode 100644 index 0000000000..2bf4b980a0 --- /dev/null +++ b/docs/ko/flight_controller/micoair743-lite.md @@ -0,0 +1,153 @@ +# MicoAir743-Lite + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://micoair.com/) for hardware support or compliance issues. +::: + +MicoAir743-Lite is an ultra-high performance H743 flight controller with an unbeatable price, featuring the ICM45686 IMU sensor and integrated Bluetooth telemetry. + +![MicoAir743-Lite Front View](../../assets/flight_controller/micoair743_lite/front_view.png) + +Equipped with a high-performance H7 processor, the MicoAir743-Lite features a compact form factor with SH1.0 connectors (which are more suitable than Pixhawk-standard GH1.25 for this board size). +When paired with with Bluetooth telemetry, the board can be debugged with a phone or PC. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## MicoAir743-Lite (v1.1) + +![MicoAir743-Lite Back View](../../assets/flight_controller/micoair743_lite/back_view.png) + +## 요약 + +### Processors & Sensors + +- FMU Processor: STM32H743 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- 내장 센서 : + - Accel/Gyro: ICM-45686 (with BalancedGyro™ Technology) + - Barometer: SPA06 +- On-board Bluetooth Telemetry + - Connected to UART8 internally, baudrate 115200 + - Connecting to QGC (PC or Android phone) via Bluetooth +- 기타 특성: + - Operating & storage temperature: -20 ~ 85°c + +### 인터페이스 + +- 8 UART (TELEM / GPS / RC) +- 14 PWM outputs (10 supports DShot) +- Support multiple RC inputs (SBUS / CRSF / DSM) +- 1 GPS port +- 1 I2C port +- 2 ADC port2 (VBAT, Current) +- 1 DJI O3/O4 VTX connector +- 1 MicroSD Card Slot +- 1 USB Type-C + +### Electrical data + +- VBAT Input: + - 2\~6S (6\~27V) +- USB Power Input: + - 4.75\~5.25V +- BEC Output: + - 5V 2A (for controller, receiver, GPS, optical flow or other devices) + - 9V 2A (for video transmitter, camera) + +### Mechanical data + +- Mounting: 30.5 x 30.5mm, Φ4mm +- Dimensions: 36 x 36 x 8 mm +- Weight: 10g + +![MicoAir743-Lite Size](../../assets/flight_controller/micoair743_lite/size.png) + +## 구매처 + +Order from [MicoAir Tech Store](https://store.micoair.com/product/micoair743-lite/). + +## 핀배열 + +Pinouts definition can be found in the [MicoAir743-Lite_pinout.xlsx](https://raw.githubusercontent.com/PX4/PX4-Autopilot/refs/heads/main/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx) file. + +## 시리얼 포트 매핑 + +| UART | 장치 | 포트 | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | TELEM1 | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | GPS1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART5 | /dev/ttyS4 | TELEM3 | +| USART6 | /dev/ttyS5 | RC | +| UART7 | /dev/ttyS6 | URT6 | +| UART8 | /dev/ttyS7 | TELEM4 | + +## Interfaces Diagram + +:::note +All the connectors used on the board are SH1.0 +::: + +![MicoAir743-Lite Interface Diagram](../../assets/flight_controller/micoair743_lite/interfaces_diagram.png) + +## Sample Wiring Diagram + +![MicoAir743-Lite Wiring Diagram](../../assets/flight_controller/micoair743_lite/wiring_diagram.png) + +## 펌웨어 빌드 + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make micoair_h743-lite_default +``` + +## 펌웨어 설치 + +펌웨어는 일반적인 방법으로 설치할 수 있습니다. + +- 소스 빌드 및 업로드 + + ```sh + make micoair_h743-lite_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + 미리 빌드된 펌웨어나 사용자 지정 펌웨어를 사용할 수 있습니다. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## 무선 조종 + +A [Radio Control (RC) system](../getting_started/rc_transmitter_receiver.md) is required if you want to manually control your vehicle (PX4 does not require a radio system for autonomous flight modes). + +The RC port is connected to the FMU and you can attach a receiver that uses the protocols `DSM`, `SBUS`, `CSRF`, `GHST`, or other protocol listed in [Radio Control modules](../modules/modules_driver_radio_control.md). +You will need to enable the protocol by setting the corresponding parameter `RC_xxxx_PRT_CFG`, such as [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) for a [CRSF receiver](../telemetry/crsf_telemetry.md). + +## 지원 플랫폼 및 기체 + +일반 RC 서보 또는 Futaba S-Bus 서보로 제어 가능한 모든 멀티콥터/비행기/로버 또는 보트. +The complete set of supported configurations can be seen in the [Airframes Reference](../airframes/airframe_reference.md). + +## 주변 장치 + +- [MicoAir Telemetry Radio Modules](https://micoair.com/radio_telemetry/) +- [MicoAir Optical & Range Sensor](https://micoair.com/optical_range_sensor/) +- [MicoAir GPS](https://micoair.com/gps/) +- [MicoAir ESC Modules](https://micoair.com/esc/) + +## 추가 정보 + +- [MicoAir Tech.](https://micoair.com/) +- [Details about MicoAir743-Lite](https://micoair.com/flightcontroller_micoair743lite/) +- [QGroundControl Download and Install](https://docs.qgroundcontrol.com/Stable_V5.0/en/qgc-user-guide/getting_started/download_and_install.html) diff --git a/docs/ko/flight_controller/modalai_voxl_2.md b/docs/ko/flight_controller/modalai_voxl_2.md index f5d2c367d3..51a37f1928 100644 --- a/docs/ko/flight_controller/modalai_voxl_2.md +++ b/docs/ko/flight_controller/modalai_voxl_2.md @@ -74,7 +74,6 @@ PX4 mainline supports VOXL 2 (board documentation [here](https://github.com/PX4/ ## 구매처 -- [PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit) - [Starling 2](https://www.modalai.com/products/starling-2) - [Starling 2 MAX](https://www.modalai.com/products/starling-2-max) - [Sentinel Development Drone powered by VOXL 2](https://www.modalai.com/pages/sentinel) diff --git a/docs/ko/flight_controller/pixhawk_series.md b/docs/ko/flight_controller/pixhawk_series.md index 979404a53a..7bca3dc03a 100644 --- a/docs/ko/flight_controller/pixhawk_series.md +++ b/docs/ko/flight_controller/pixhawk_series.md @@ -100,6 +100,24 @@ PX4 _developers_ need to know the FMU version of their board, as this is require +### FMUv6 Comparison + +| 기능 | **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× | + ### 라이선스와 상표 Pixhawk project schematics and reference designs are licensed under [CC BY-SA 3](https://creativecommons.org/licenses/by-sa/3.0/legalcode). diff --git a/docs/ko/flight_controller/radiolink_pix6.md b/docs/ko/flight_controller/radiolink_pix6.md new file mode 100644 index 0000000000..ab54385075 --- /dev/null +++ b/docs/ko/flight_controller/radiolink_pix6.md @@ -0,0 +1,347 @@ +# RadiolinkPIX6 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://radiolink.com.cn/) for hardware support or compliance issues. +::: + +자동조종장치는 상용시스템 통합에 권장되지만, 학술 연구와 기타 용도에도 적합합니다. + +![RadiolinkPIX6](http://www.radiolink.com.cn/firmware/wiki/RadiolinkPIX6/RadiolinkPIX6.png) + +The Radiolink PIX6 is a high-performance flight controller. +Featuring STM32F7 CPU, vibration isolation of IMUs, redundant IMUs, integrated OSD chip, IMU heating, and DShot. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## 요약 + +- 프로세서 + - 32-bit ARM Cortex M7 core with DPFPU - STM32F765VIT6 + - 216 MHz/512 KB RAM/2 MB 플래시 + - 32-bit IOMCU co-processor - STM32F100 + - 32KB FRAM - FM25V02A + - AT7456E OSD +- 센서 + - Bosh BMI088 IMU (accel, gyro) + - InvenSense ICM-42688 IMU (accel, gyro) + - SPA06 barometer + - IST8310 magnetometer +- 전원 + - SMBUS/I2C Power Module Inputs (I2C) + - voltage and current monitor inputs (Analog) +- 인터페이스 + - 16 PWM Outputs with independent power rail for external power source + - 5x UART serial ports, 2 with HW flow control + - Camera Input and Video Output + - PPM/SBUS input, DSM/SBUS input + - RSSI(PWM 또는 전압) 입력 + - I2C, SPI, 2x CAN, USB + - 3.3V and 6.6V ADC inputs + - 부저와 안전 스위치 + - microSD card +- 중량과 크기 + - Weight 80g + - Size 94mm x 51.5mm x 14.5mm + +## 구매처 + +[Radiolink Amazon](https://www.radiolink.com.cn/pix6_where_to_buy)(International users) + +[Radiolink Taobao](https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bNMdSqV&ft=t&id=815993357068&skuId=5515756705284)(China Mainland user) + +## 커넥터 할당 + +### Top View + +![Pix6 top view](../../assets/flight_controller/radiolink_pix6/top_view.png) + +### Left View + +![Pix6 left view](../../assets/flight_controller/radiolink_pix6/left_view.png) + +### Right View + +![Pix6 right view](../../assets/flight_controller/radiolink_pix6/right_view.png) + +### Rear View + +![Pix6 rear view](../../assets/flight_controller/radiolink_pix6/rear_view.png) + +## 핀배열 + +Unless noted otherwise all connectors are JST GH. + +### TELEM1, TELEM2 포트 + +| 핀 | 신호 | 전압 | +| - | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | CTS | +3.3V | +| 5 | RTS | +3.3V | +| 6 | GND | GND | + +### OSD + +| 핀 | 신호 | 전압 | +| - | ---- | --------------------- | +| 1 | GND | GND | +| 2 | VOUT | +3.3V | +| 3 | VCC | +5V | +| 4 | GND | GND | +| 5 | VCC | +5V | +| 6 | VIN | +3.3V | + +### I2C port + +| 핀 | 신호 | 전압 | +| - | --- | -------------------------------------------------- | +| 1 | VCC | +5V | +| 2 | SCL | +3.3V (pullups) | +| 3 | SDA | +3.3V (pullups) | +| 4 | GND | GND | + +### CAN1, CAN2 ports + +| 핀 | 신호 | 전압 | +| - | -------------------------- | ---- | +| 1 | VCC | +5V | +| 2 | CAN_H | +12V | +| 3 | CAN_L | +12V | +| 4 | GND | GND | + +### GPS1 port + +| 핀 | 신호 | 전압 | +| - | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### GPS2 Port + +| 핀 | 신호 | 전압 | +| - | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### SPI + +| 핀 | 신호 | 전압 | +| - | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | SPI_SCK | +3.3V | +| 3 | SPI_MISO | +3.3V | +| 4 | SPI_MOSI | +3.3V | +| 5 | !SPI_NSS1 | +3.3V | +| 6 | !SPI_NSS2 | +3.3V | +| 7 | DRDY | +3.3V | +| 8 | GND | GND | + +### POWER1 (HY2.0-6P) + +Port for analog power monitors. + +| 핀 | 신호 | 전압 | +| - | ------- | ------------------------ | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | CURRENT | 최대 +3.3V | +| 4 | VOLTAGE | 최대 +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### POWER2 (HY2.0-6P) + +Port for digital (I2C) power monitor. + +| 핀 | 신호 | 전압 | +| - | --- | --------------------- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | SCL | +3.3V | +| 4 | SDA | +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### ADC 3.3V + +| 핀 | 신호 | 전압 | +| - | ------- | --------------------------- | +| 1 | VCC | +5V | +| 2 | ADC IN1 | 최대 +3.3V | +| 3 | GND | GND | +| 4 | ADC IN2 | up to +3.3v | +| 5 | GND | GND | + +### ADC 6.6V + +| 핀 | 신호 | 전압 | +| - | ------ | -------------------------- | +| 1 | VCC | +5V | +| 2 | ADC 입력 | up to 6.6V | +| 3 | GND | GND | + +### USB remote port + +| 핀 | 신호 | 전압 | +| - | ------- | --------------------- | +| 1 | USB VDD | +5V | +| 2 | DM | +3.3V | +| 3 | DP | +3.3V | +| 4 | GND | GND | + +### 스위치 + +| 핀 | 신호 | 전압 | +| - | -------------------------------------------------------- | --------------------- | +| 1 | VCC | +3.3V | +| 2 | !IO_LED_SAFETY | GND | +| 3 | SAFETY | GND | + +### Buzzer port + +| 핀 | 신호 | 전압 | +| - | ------- | --- | +| 1 | VCC | +5V | +| 2 | BUZZER- | +5V | + +### Spektrum/DSM Port (PH1.25-3P) + +| 핀 | 신호 | 전압 | +| - | --- | --------------------- | +| 1 | VCC | +3.3V | +| 2 | GND | GND | +| 3 | 신호 | +3.3V | + +### Debug port (SH1.0-8P) + +| 핀 | 신호 | 전압 | +| - | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | FMU_SWCLK | +3.3V | +| 3 | FMU_SWDIO | +3.3V | +| 4 | TX(UART7) | +3.3V | +| 5 | RX(UART7) | +3.3V | +| 6 | IO_SWCLK | +3.3V | +| 7 | IO_SWDIO | +3.3V | +| 8 | GND | GND | + +## 펌웨어 빌드 + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make radiolink_PIX6_default +``` + +## 펌웨어 설치 + +펌웨어는 일반적인 방법으로 설치할 수 있습니다. + +- 소스 빌드 및 업로드 + + ```sh + make radiolink_PIX6_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + 미리 빌드된 펌웨어나 사용자 지정 펌웨어를 사용할 수 있습니다. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## PX4 설정 + +In addition to the [basic configuration](../config/index.md), the following parameters are important: + +| 매개변수 | 설정 | +| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG) | 보드에 내부 자력계가 없기 때문에 비활성화하여야 합니다. 외부 자력계를 연결하여 활성화 할 수 있습니다. | + +### Powering the PIX6 + +The PIX6 has 2 dedicated power monitor ports, each with a 6 pin connector. +One is the Analog power monitor (`POWER1`), and the others is the I2C power monitor (`POWER2`). + +The power module that comes with the flight controller with a wide voltage input range of 2-12S (7.4-50.4V), a maximum detection current of 90A (single ESC maximum detection current is 22.5A), a BEC output voltage of 5.3±0.2V, and a BEC output current of 2A. + +![Radiolink power modules MODULES](../../assets/flight_controller/radiolink_pix6/radiolink_power_modules.png) + +The PIX6 also supports power modules from other manufacturers, such as [holybro_pm02d](../power_module/holybro_pm02d.md). + +## Recommended Accessories + +### GPS Modules + +Radiolink manufactures a variety of high-performance GPS,Dual Anti-interference Technology Worry-free of UAV High-power Image Transmission, High-Voltage Lines, or Other Strong Signal Interference. + +The PIX6 has 2 dedicated GPS ports, `GPS1` and `GPS2`, each with a 6 pin connector. + +Recommended modules include: + +- [Radiolink SE100](https://radiolink.com.cn/se100) +- [Radiolink TS100](https://radiolink.com.cn/ts100v2) +- [Radiolink RTK F9P](https://radiolink.com.cn/rtk_f9p) + +## 시리얼 포트 매핑 + +| UART | 장치 | 포트 | +| ------ | ---------- | --------------------------------- | +| UART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM1 (흐름 제어) | +| USART3 | /dev/ttyS2 | TELEM2 (흐름 제어) | +| UART4 | /dev/ttyS3 | GPS2 | +| UART7 | /dev/ttyS4 | 디버그 콘솔 | +| UART8 | /dev/ttyS5 | PX4IO | + +## Analog inputs + +The Radiolink PIX6 has 3 analog inputs, one 6V tolerant and two 3.3V tolerant. + +- ADC Pin12 -> ADC 6.6V Sense +- ADC Pin4 -> ADC IN1 3.3V Sense +- ADC Pin13 -> ADC IN2 3.3V Sense + +## 무선 조종 + +A [Radio Control (RC)](../getting_started/rc_transmitter_receiver.md) 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](../getting_started/rc_transmitter_receiver.md) and then _bind_ them so that they communicate (read the instructions that come with your specific transmitter/receiver). + +- Spektrum/DSM receivers connect to the **DSM/SBUS RC** input. +- PPM or SBUS receivers connect to the **RC IN** input port. +- CRSF receiver must be wired to a spare port (UART) on the Flight Controller. + Then you can bind the transmitter and receiver together. + +#### CRSF Parameter Configuration + +[Find and set](../advanced_config/parameters.md) the following parameters: + +1. Set [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) to the port that is connected to the CRSF receiver (such as `TELEM1`). + + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + + 포트 전송속도는 드라이버에 의해 설정되므로, 추가로 설정하지 않아도 됩니다. + +2. Enable [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) to activate Crossfire telemetry. + +For more information about selecting a radio system, receiver compatibility, and binding your transmitter/receiver pair, see: [Remote Control Transmitters & Receivers](../getting_started/rc_transmitter_receiver.md). diff --git a/docs/ko/flight_controller/svehicle_e2.md b/docs/ko/flight_controller/svehicle_e2.md new file mode 100644 index 0000000000..1e010d1aa5 --- /dev/null +++ b/docs/ko/flight_controller/svehicle_e2.md @@ -0,0 +1,177 @@ +# S-Vehicle E2 + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The _E2_ is an advanced autopilot manufactured by S-Vehicle®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![SVehicle-E2](../../assets/flight_controller/svehicle_e2/main.png) + +:::info +이 비행 컨트롤러는 [제조업체에서 지원](../flight_controller/autopilot_manufacturer_supported.md)합니다. +::: + +### Processors & Sensors + +- FMU Processor: STM32H753IIK6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- 내장 센서 : + - Accel/Gyro: BMI088 + - Accel/Gyro: ICM-42688-P + - Accel/Gyro: ICM-20649 + - Mag: RM3100 + - Barometer: 2x ICP-20100 + +### 인터페이스 + +- 14x PWM Servo Outputs +- 1x Dedicated R/C Input for Spektrum / DSM and S.Bus +- 1x Analog/PWM RSSI Input +- 2x TELEM Ports (with full flow control) +- 1x UART4 Port +- 2x GPS Ports + - 1x Full GPS plus Safety Switch Port (GPS1) + - 1x Basic GPS Port (with I2C, GPS2) +- 1x USB Port (TYPE-C) +- 1x Ethernet Port + - Transformerless application + - 100Mbps +- 3x I2C Bus Ports +- 1x SPI Bus + - 1x Chip Select Line + - 1x Data Ready Line + - 1x SPI Reset Line +- 2x CAN Ports +- 3x Power Input Ports + - ADC Power Input + - I2C Power Input + - DroneCAN/UAVCAN Power Input +- 2x AD Ports + - Analog Input (3.3V) + - Analog Input (6.6V - not supported by PX4) +- 1x Dedicated Debug Port + - FMU Debug + +## Purchase Channels + +Order from [S-Vehicle](https://svehicle.cn/). + +## 무선 조종 + +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). + +기체와 조종자가 통신하기 위하여 송신기와 수신기를 바인딩하여야 합니다. +송신기와 수신기의 매뉴얼을 참고하십시오. + +Spektrum/DSM receivers connect to the DSM/SBUS RC input. +PPM or SBUS receivers connect to the RC IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## 시리얼 포트 매핑 + +| UART | 장치 | 포트 | +| ------ | ---------- | -------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | 디버그 콘솔 | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | PX4IO/RC | +| UART7 | /dev/ttyS6 | TELEM1 | +| UART8 | /dev/ttyS7 | GPS2 | + +## PWM Output + +The E2-Plus flight controller supports up to 14 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 6 outputs (labelled 9 to 14) are the "auxiliary" outputs. +These are directly attached to the STM32H753 FMU controller . + +The 14 PWM outputs are: + +M1 - M8 are connected to the IOMCU +A1 - A6 are connected to the FMU + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 6 FMU PWM outputs are in 2 groups: + +A1 - A4 are in one group. +A5, A6 are in a 2nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.7V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V +- Current Ratings: + - TELEM1 and GPS2 combined output current limiter: 1.5A + - All other port combined output current limiter: 1.5A + +## Battery Monitoring + +The board has connectors for 3 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN +- POWER3 -- I2C + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor and I2C defaults configured which is enabled. + +The default PDB included with the E2+ is analog and must be connected to `POWER1`. + +## 펌웨어 빌드 + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make svehicle_e2_default +``` + +## 디버그 포트 + +The [PX4 System Console](../debug/system_console.md) and [SWD Interface](../debug/swd_debug.md) operate on the **FMU Debug** port. + +| 핀 | 신호 | 전압 | +| ------------------------- | ------------------------------- | --------------------- | +| 1(red) | 5V+ | +5V | +| 2 (흑) | DEBUG TX(출력) | +3.3V | +| 3 (흑) | DEBUG TX(입력) | +3.3V | +| 4 (흑) | FMU_SWDIO | +3.3V | +| 5 (흑) | FMU_SWCLK | +3.3V | +| 6 (흑) | GND | GND | + +For information about using this port see: + +- [SWD Debug Port](../debug/swd_debug.md) +- [PX4 System Console](../debug/system_console.md) (Note, the FMU console maps to USART3). +- All ports use GH1.25 ,power ports use ports on E2 uses the 6 circuit [2.00mm Pitch CLIK-Mate Wire-to-Board PCB Receptacle](https://www.molex.com/en-us/products/part-detail/5024430670). + +## 핀배열 + +![SVehicle-E2 Top Down Photo](../../assets/flight_controller/svehicle_e2/top.png) + +![SVehicle-E2 Bottom Photo](../../assets/flight_controller/svehicle_e2/back.jpeg) + +![SVehicle-E2 left Photo](../../assets/flight_controller/svehicle_e2/left.png) + +![SVehicle-E2 right Photo](../../assets/flight_controller/svehicle_e2/right.png) + +## 지원 플랫폼 및 기체 + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). diff --git a/docs/ko/flight_controller/x-mav_ap-h743r1.md b/docs/ko/flight_controller/x-mav_ap-h743r1.md new file mode 100644 index 0000000000..a7968d946c --- /dev/null +++ b/docs/ko/flight_controller/x-mav_ap-h743r1.md @@ -0,0 +1,148 @@ +# AP-H743-R1 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The AP-H743-R1 is an advanced autopilot manufactured by X-MAV®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png) + +:::info +이 비행 컨트롤러는 [제조업체에서 지원](../flight_controller/autopilot_manufacturer_supported.md)합니다. +::: + +### Processors & Sensors + +- FMU Processor: STM32H743VIT6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- 내장 센서 : + - Accel/Gyro: ICM-42688-P\*2(Version1), BMI270\*2(Version2) + - Mag: QMC5883P + - Barometer: DPS310(Version1),SPL06(Version2) + +### 인터페이스 + +- 15x PWM Servo Outputs +- 1x Dedicated S.Bus Input +- 3x TELEM Ports +- 1x SERIAL4 Port +- 2x GPS Ports +- 1x USB Port (TYPE-C) +- 3x I2C Bus Ports +- 2x CAN Ports +- 2x Power Input Ports + - ADC Power Input + - DroneCAN/UAVCAN Power Input +- 2x Dedicated Debug Port + - FMU Debug + - IO 디버그 + +## Purchase Channels + +Order from [X-MAV](https://www.x-mav.cn/). + +## 무선 조종 + +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). + +기체와 조종자가 통신하기 위하여 송신기와 수신기를 바인딩하여야 합니다. +송신기와 수신기의 매뉴얼을 참고하십시오. + +SBUS receivers connect to the SBUS-IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## 시리얼 포트 매핑 + +| UART | 장치 | 포트 | +| ------ | ---------- | ------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | TELEM1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART7 | /dev/ttyS4 | TELEM3 | +| UART8 | /dev/ttyS5 | SERIAL4 | + +## PWM Output + +The AP-H743-R1 flight controller supports up to 15 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 7 outputs (labelled A1 to A7) are the "auxiliary" outputs. +These are directly attached to the STM32H743 FMU controller . + +The 15 PWM outputs are: + +M1 - M8 are connected to the IOMCU. +A1 - A7 are connected to the FMU. + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 7 FMU PWM outputs are in 3 groups: + +- A1 - A4 are in one group. +- A5, A6 are in a 2nd group. +- A7 is in a 3nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.4V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V + +## Battery Monitoring + +The board has connectors for 2 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor configured which is enabled. + +## 펌웨어 빌드 + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make x-mav_ap-h743r1_default +``` + +## Pinouts and Size + +![AP-H743-R1 pinouts](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png) + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png) + +## 지원 플랫폼 및 기체 + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). + +## 디버그 포트 + +### SWD + +The [SWD interface](../debug/swd_debug.md) operate on the **FMU-DEBUG** port (`FMU-DEBUG`). + +The debug port (`FMU-DEBUG`) uses a [JST SM04B-GHS-TB](https://www.digikey.com/en/products/detail/jst-sales-america-inc/SM04B-GHS-TB/807788) connector and has the following pinout: + +| 핀 | 신호 | 전압 | +| ------------------------- | ------------------------------ | --------------------- | +| 1(red) | 5V+ | +5V | +| 2 (흑) | FMU_SWDIO | +3.3V | +| 3 (흑) | FMU_SWCLK | +3.3V | +| 4 (흑) | GND | GND | diff --git a/docs/ko/flight_modes/offboard.md b/docs/ko/flight_modes/offboard.md index 11f291ee72..42d4c0c2df 100644 --- a/docs/ko/flight_modes/offboard.md +++ b/docs/ko/flight_modes/offboard.md @@ -62,6 +62,11 @@ bool thrust_and_torque bool direct_actuator ``` +:::warning +The following list shows the `OffboardControlMode` options for copter, fixed-wing, and VTOL. +For rovers see the [rover section](#rover). +::: + The fields are ordered in terms of priority such that `position` takes precedence over `velocity` and later fields, `velocity` takes precedence over `acceleration`, and so on. The first field that has a non-zero value (from top to bottom) defines what valid estimate is required in order to use offboard mode, and the setpoint message(s) that can be used. For example, if the `acceleration` field is the first non-zero value, then PX4 requires a valid `velocity estimate`, and the setpoint must be specified using the `TrajectorySetpoint` message. @@ -90,20 +95,93 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - Velocity setpoint (`velocity` different from `NaN` and `position` set to `NaN`). Non-`NaN` values acceleration are used as feedforward terms for the inner loop controllers. - Acceleration setpoint (`acceleration` different from `NaN` and `position` and `velocity` set to `NaN`) - - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are \[m\], \[m/s\] and \[m/s^2\] for position, velocity and acceleration, respectively. + - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are `[m]`, `[m/s]` and `[m/s^2]` for position, velocity and acceleration, respectively. - [px4_msgs::msg::VehicleAttitudeSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) - The following input combination is supported: - quaternion `q_d` + thrust setpoint `thrust_body`. - Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in \[rad/s\]. + Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in `[rad/s]`. - - The quaternion represents the rotation between the drone body FRD (front, right, down) frame and the NED frame. The thrust is in the drone body FRD frame and expressed in normalized \[-1, 1\] values. + - The quaternion represents the rotation between the drone body FRD (front, right, down) frame and the NED frame. + The thrust is in the drone body FRD frame and expressed in normalized \[-1, 1\] values. - [px4_msgs::msg::VehicleRatesSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) - The following input combination is supported: - `roll`, `pitch`, `yaw` and `thrust_body`. - - All the values are in the drone body FRD frame. The rates are in \[rad/s\] while thrust_body is normalized in \[-1, 1\]. + - All the values are in the drone body FRD frame. + The rates are in `[rad/s]` while thrust_body is normalized in `[-1, 1]`. + +### 탐사선 + +Rover modules must set the control mode using `OffboardControlMode` and use the appropriate messages to configure the corresponding setpoints. +The approach is similar to other vehicle types, but the allowed control mode combinations and setpoints are different: + +| Category | 사용법 | Setpoints | +| -------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| (Recommended) [Rover Setpoints](#rover-setpoints) | General rover control | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md), [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md), [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md), [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md), [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md), [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| [Actuator Setpoints](#actuator-setpoints) | Direct actuator control | [ActuatorMotors](../msg_docs/ActuatorMotors.md), [ActuatorServos](../msg_docs/ActuatorServos.md) | +| (Deprecated) [Trajectory Setpoint](#deprecated-trajectory-setpoint) | General vehicle control | [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) | + +#### Rover Setpoints + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). + All combinations of "left" and "right" setpoints are valid. + +The following are all valid setpoint combinations and their respective control flags that must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md) (set all others to _false_). +Additionally, for some combinations we require certain setpoints to be published with `NAN` values so that the setpoints of interest are not overridden by the rover module (due to the hierarchy above). +✓ are the relevant setpoints we publish, and ✗ are the setpoint that need to be published with `NAN` values. + +| Setpoint Combination | Control Flag | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| -------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | +| Position | position | ✓ | | | | | | +| Speed + Attitude | velocity | | ✓ | | ✓ | | | +| Speed + Rate | velocity | | ✓ | | ✗ | ✓ | | +| Speed + Steering | velocity | | ✓ | | ✗ | ✗ | ✓ | +| Throttle + Attitude | attitude | | | ✓ | ✓ | | | +| Throttle + Rate | body_rate | | | ✓ | | ✓ | | +| Throttle + Steering | thrust_and_torque | | | ✓ | | | ✓ | + +:::info +If you intend to use the rover setpoints, we recommend using the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) instead since it simplifies the publishing of these setpoints. +::: + +#### Actuator Setpoints + +Instead of controlling the vehicle using position, speed, rate and other setpoints, you can directly control the motors and actuators using [ActuatorMotors](../msg_docs/ActuatorMotors.md) and [ActuatorServos](../msg_docs/ActuatorServos.md). +In [OffboardControlMode](../msg_docs/OffboardControlMode.md) set `direct_actuator` to _true_ and all other flags to _false_. + +:::info +This bypasses the rover modules including any limits on steering rates or accelerations and the inverse kinematics step. +We recommend using [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) and [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) instead for low level control (see [Rover Setpoints](#rover-setpoints)). +::: + +#### (Deprecated) Trajectory Setpoint + +:::warning +The [Rover Setpoints](#rover-setpoints) are a replacement for the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) and we highly recommend using those instead as they have a well defined behaviour and offer more flexibility. +::: + +The rover modules support the _position_, _velocity_ and _yaw_ fields of the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md). +However, only one of the fields is active at a time and is defined by the flags of [OffboardControlMode](../msg_docs/OffboardControlMode.md): + +| Control Mode Flag | Active Trajectory Setpoint Field | +| ----------------- | -------------------------------- | +| position | position | +| velocity | velocity | +| attitude | yaw | + +:::info +Ackermann rovers do not support the yaw setpoint. +::: ### Generic Vehicle @@ -116,8 +194,10 @@ The following offboard control modes bypass all internal PX4 control loops and s - [px4_msgs::msg::ActuatorMotors](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) + [px4_msgs::msg::ActuatorServos](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) - You directly control the motor outputs and/or servo outputs. - - Currently works at lower level than then `control_allocator` module. Do not publish these messages when not in offboard mode. - - All the values normalized in \[-1, 1\]. For outputs that do not support negative values, negative entries map to `NaN`. + - Currently works at lower level than then `control_allocator` module. + Do not publish these messages when not in offboard mode. + - All the values normalized in `[-1, 1]`. + For outputs that do not support negative values, negative entries map to `NaN`. - `NaN` maps to disarmed. ## MAVLink Messages @@ -207,41 +287,7 @@ The following MAVLink messages and their particular fields and field values are ### 탐사선 -- [SET_POSITION_TARGET_LOCAL_NED](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `x`, `y`, `z`) - - Specify the _type_ of the setpoint in `type_mask`: - - ::: info - The _setpoint type_ values below are not part of the MAVLink standard for the `type_mask` field. - :: - - 값들은 다음과 같습니다: - - - -12288 : Loiter 설정점 (설정점에 매우 가까워지면 기체는 멈춤). - - - Velocity setpoint (only `vx`, `vy`, `vz`) - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) and [MAV_FRAME_BODY_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_BODY_NED). - -- [SET_POSITION_TARGET_GLOBAL_INT](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_GLOBAL_INT) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `lat_int`, `lon_int`, `alt`) - - - Specify the _type_ of the setpoint in `type_mask` (not part of the MAVLink standard). - 값들은 다음과 같습니다: - - 다음 비트가 설정되지 않으면 정상적인 동작입니다. - - -12288 : Loiter 설정점 (설정점에 매우 가까워지면 기체는 멈춤). - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL). - -- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET) - - 다음 입력 조합이 지원됩니다. - - Attitude/orientation (`SET_ATTITUDE_TARGET.q`) with thrust setpoint (`SET_ATTITUDE_TARGET.thrust`). - ::: info - Only the yaw setting is actually used/extracted. - -::: +Rover does not support a MAVLink offboard API (ROS2 is supported). ## 오프보드 매개변수 diff --git a/docs/ko/flight_modes_fw/hold.md b/docs/ko/flight_modes_fw/hold.md index 9555a4f13e..6ee1566e5b 100644 --- a/docs/ko/flight_modes_fw/hold.md +++ b/docs/ko/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -It is usually activated with a pre-programmed switch. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ It is usually activated with a pre-programmed switch. ::: -## Technical Summary +## Loiter modes -The aircraft circles around the GPS hold position at the current altitude. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -RC stick movement is ignored. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### 매개변수 +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## 매개변수 Hold mode behaviour can be configured using the parameters below. | 매개변수 | 설명 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Minimum height for loiter mode (vehicle will ascend to this altitude if mode is engaged at a lower altitude). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## See Also -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/ko/flight_modes_fw/index.md b/docs/ko/flight_modes_fw/index.md index ac7acee269..20443d82a5 100644 --- a/docs/ko/flight_modes_fw/index.md +++ b/docs/ko/flight_modes_fw/index.md @@ -17,6 +17,8 @@ Manual-Easy: Airspeed is actively controlled if an airspeed sensor is installed. - [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). - [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. diff --git a/docs/ko/flight_modes_fw/mission.md b/docs/ko/flight_modes_fw/mission.md index 550cdd7630..0d5f695af6 100644 --- a/docs/ko/flight_modes_fw/mission.md +++ b/docs/ko/flight_modes_fw/mission.md @@ -29,32 +29,32 @@ At high level all vehicle types behave in the same way when MISSION mode is enga 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". + - If flying the vehicle will loiter. + - If landed the vehicle will "wait". 2. If a mission is stored and PX4 is flying it will execute the [mission/flight plan](../flying/missions.md) from the current step. - - A takeoff mission item will be treated as a normal waypoint. + - A takeoff mission item will be treated as a normal waypoint. 3. If a mission is stored and the vehicle is landed it will only takeoff if the active waypoint is a `Takeoff`. - If configured for catapult launch, the vehicle must also be launched (see [FW Takeoff/Landing in Mission](#mission-takeoff)). + If configured for catapult launch, the vehicle must also be launched (see [FW Takeoff/Landing in Mission](#mission-takeoff)). 4. If no mission is stored, or if PX4 has finished executing all mission commands: - - If flying the vehicle will loiter. - - If landed the vehicle will "wait". + - If flying the vehicle will loiter. + - If landed the vehicle will "wait". 5. You can manually change the current mission command by selecting it in _QGroundControl_. - ::: info - If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. - One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. + ::: info + If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. + One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. ::: 6. The mission will only reset when the vehicle is disarmed or when a new mission is uploaded. - :::tip - To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. - Enter the time to wait after landing before disarming the vehicle. + :::tip + To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. + Enter the time to wait after landing before disarming the vehicle. ::: @@ -167,6 +167,10 @@ Mission Items: - [MAV_CMD_OBLIQUE_SURVEY](https://mavlink.io/en/messages/common.html#MAV_CMD_OBLIQUE_SURVEY) - [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. GeoFence Definitions @@ -261,7 +265,7 @@ This pattern results in the following landing sequence: 1. **Fly to landing location**: The aircraft flies at its current altitude towards the loiter waypoint. 2. **Descending orbit to approach altitude**: On reaching the loiter radius of the waypoint, the vehicle performs a descending orbit until it reaches the "approach altitude" (the altitude of the loiter waypoint). - The vehicle continues to orbit at this altitude until it has a tanjential path towards the land waypoint, at which point the landing approach is initiated. + The vehicle continues to orbit at this altitude until it has a tanjential path towards the land waypoint, at which point the landing approach is initiated. 3. **Landing approach**: The aircraft follows the landing approach slope towards the land waypoint until the flare altitude is reached. 4. **Flare**: The vehicle flares until it touches down. diff --git a/docs/ko/flight_modes_fw/takeoff.md b/docs/ko/flight_modes_fw/takeoff.md index 23ded204ce..7cce984ec9 100644 --- a/docs/ko/flight_modes_fw/takeoff.md +++ b/docs/ko/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: @@ -93,7 +93,7 @@ To launch in this mode: 1. Arm the vehicle 2. Put the vehicle into _Takeoff mode_ 3. Launch/throw the vehicle (firmly) directly into the wind. - You can also shake the vehicle first, wait till the motor spins up and then throw it + You can also shake the vehicle first, wait till the motor spins up and then throw it ### Parameters (Launch Detector) diff --git a/docs/ko/flight_modes_mc/altitude.md b/docs/ko/flight_modes_mc/altitude.md index 7c0f13424b..b1d4bcadae 100644 --- a/docs/ko/flight_modes_mc/altitude.md +++ b/docs/ko/flight_modes_mc/altitude.md @@ -21,7 +21,7 @@ The diagram below shows the mode behaviour visually (for a [mode 2 transmitter]( RC/manual mode like [Stabilized mode](../flight_modes_mc/manual_stabilized.md) but with _altitude stabilization_ (centred sticks level vehicle and hold it to fixed altitude). The horizontal position of the vehicle can move due to wind (or pre-existing momentum). -- 중앙 스틱 (데드밴드 내부) : +- Centered sticks: - RPY sticks levels vehicle. - 스로틀(~ 50 %)은 현재 고도를 바람에 대해 일정하게 유지합니다. - Outside center: @@ -43,9 +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: -| 매개변수 | 설명 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 최대 수직 상승 속도. 기본값: 3 m/s. | -| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 최대 수직 하강 속도. 기본값: 1 m/s. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | -| `MPC_XXXX` | 대부분의 MPC_xxx 매개 변수는이 모드에서 비행 동작에 어느정도 영향을 미칩니다 . For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | +| 매개변수 | 설명 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 최대 수직 상승 속도. 기본값: 3 m/s. | +| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 최대 수직 하강 속도. 기본값: 1 m/s. | +| `MPC_XXXX` | 대부분의 MPC_xxx 매개 변수는이 모드에서 비행 동작에 어느정도 영향을 미칩니다 . For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | diff --git a/docs/ko/flight_modes_mc/altitude_cruise.md b/docs/ko/flight_modes_mc/altitude_cruise.md new file mode 100644 index 0000000000..a608e273fb --- /dev/null +++ b/docs/ko/flight_modes_mc/altitude_cruise.md @@ -0,0 +1,45 @@ +# Altitude Cruise Mode (Multicopter) + +   + +_Altitude Cruise mode_ is a _relatively_ easy-to-fly manual control mode in which roll and pitch sticks control vehicle movement in the left-right and forward-back directions (relative to the "front" of the vehicle), yaw stick controls rate of rotation over the horizontal plane, and throttle controls speed of ascent-descent. + +When the sticks are released/centered the vehicle will keep the current tilt and heading angle and maintain the current _altitude_. +If moving in the horizontal plane the vehicle will accelerate until the wind resistance equals the acceleration caused by the set tilt angle. +The vehicle will then continue to move with a constant velocity (unlike for Altitude mode, in which the vehicle will eventually slow down and stop). +If the wind blows the aircraft will drift in the direction of the wind even if flying perfectly level. + +:::tip +_Altitude Cruise mode_ is intended for long distance flights where the same tilt angle is kept for a long period of time. It is just like [Altitude](../flight_modes_mc/altitude.md) mode but does not go back to level tilt when the sticks are released. +::: + +The diagram below shows the mode behaviour visually (for a [mode 2 transmitter](../getting_started/rc_transmitter_receiver.md#transmitter_modes)). + +![Altitude Control MC - Mode2 RC Controller](../../assets/flight_modes/altitude_mc.png) + +## Technical Summary + +A manual mode that is similar to [Altitude mode](../flight_modes_mc/altitude.md) but with different interpretation of roll and pitch sticks. + +- Centered sticks: + - Roll/Pitch sticks: the current tilt is kept. + - Yaw: the current heading is kept. + - Throttle (~50%) holds current altitude. +- Outside center: + - Roll/Pitch sticks control the rate of change of the tilt angle, resulting in corresponding left-right and forward-back movement. A maximum stick deflection results in a tilting rate setpoint to go from level to max tilt within 0.5 seconds. + - Yaw stick deflection rotates the tilt angle either left or right, causing the vehicle to change course. It is _not_ causing a direct rotation around the body yaw axis like in [Acro mode](../flight_modes_mc/acro.md). + - 스로틀 스틱은 미리 정해진 최대 속도 (및 다른 축의 이동 속도)로 속도를 올리거나 내립니다. +- 이륙: + - 착륙했을 때 스로틀 스틱을 62.5 % (하단에서 전체 범위) 이상으로 올리면 기체가 이륙합니다. +- Manual control input is required (such as RC control, joystick) to enter this mode. Other than in all other manual modes, it's though possible to disable the manual control loss failsafe by setting the corresponding flag in [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT). In that case the current altitude, tilt and heading 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, and to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT). + +## 매개변수 + +Most of the relevant parameters are already covered in the corresponding section in the [Altitude mode](../flight_modes_mc/altitude.md). Here a list of parameters of particular importance for Altitude Cruise. + +| 매개변수 | 설명 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | The manual control failsafe can be disabled for Altitude Cruise by setting the corresponding bit in this parameter. | +| [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Data link lost failsafe action. Recommended to set if the manual control failsafe is disabled to avoid fly-aways. | +| [MPC_MAN_TILT_MAX](../advanced_config/parameter_reference.md#MPC_MAN_TILT_MAX) | The maximum tilt angle the vehicle will go to. At max stick deflection, it will take 0.5 seconds from level flight to this tilt angle. | diff --git a/docs/ko/flight_modes_mc/follow_me.md b/docs/ko/flight_modes_mc/follow_me.md index 09e5d2a7ee..c5ca434e6e 100644 --- a/docs/ko/flight_modes_mc/follow_me.md +++ b/docs/ko/flight_modes_mc/follow_me.md @@ -151,19 +151,19 @@ The follow-me behavior can be configured using the following parameters: 1. Set the [follow distance](#FLW_TGT_DST) to more than 12 meters (8 meters is a "recommended minimum"). - There is an inherent position bias (3 ~ 5 meters) between the target and the drone's GPS sensor, which makes the drone follow a 'ghost target' somewhere near the actual target. - This is more obvious when the follow distance is very small. - We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. + There is an inherent position bias (3 ~ 5 meters) between the target and the drone's GPS sensor, which makes the drone follow a 'ghost target' somewhere near the actual target. + This is more obvious when the follow distance is very small. + We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. 2. The speed at which you can change the follow angle depends on the [maximum tangential velocity](#FLW_TGT_MAX_VEL) setting. - Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. + Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. 3. Using the RC Adjustment for height, distance and angle, you can get some creative camera shots. - + - 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. + 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. ## 알려진 이슈들 diff --git a/docs/ko/flight_modes_mc/index.md b/docs/ko/flight_modes_mc/index.md index 752fd4aeb2..73cb4fc032 100644 --- a/docs/ko/flight_modes_mc/index.md +++ b/docs/ko/flight_modes_mc/index.md @@ -21,10 +21,12 @@ Manual-Easy: - [Stabilized mode](../flight_modes_mc/manual_stabilized.md) — Releasing the sticks levels and maintains the vehicle horizontal posture (but not altitude or position). The vehicle will continue to move with momentum, and both altitude and horizontal position may be affected by wind. This mode is also used if "Manual mode" is selected in a ground station. +- [Altitude Cruise mode](../flight_modes_mc/altitude_cruise.md) — Very similar to _Altitude mode_, with the difference that when the roll and pitch sticks are released the vehicle does not level out but keeps the tilt until further inputs are given. + Additionally it is possible to disable the manual control failsafe for this mode, having the vehicle continue on it's set path even if there are no new control inputs. Manual-Acrobatic -- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic maneuvers, such as rolls and loops. +- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic manoeuvrers, such as rolls and loops. Releasing the sticks stops the vehicle rotating in the roll, pitch, yaw axes, but does not otherwise stabilise the vehicle. Autonomous: diff --git a/docs/ko/flight_modes_mc/manual_stabilized.md b/docs/ko/flight_modes_mc/manual_stabilized.md index 129613235d..8127254ebf 100644 --- a/docs/ko/flight_modes_mc/manual_stabilized.md +++ b/docs/ko/flight_modes_mc/manual_stabilized.md @@ -31,7 +31,7 @@ Throttle is rescaled (see [below](#params)) and passed directly to control alloc 자동 조종 장치는 자세를 제어합니다. 즉, RC 스틱이 컨트롤러 데드 존 내부에 집중 될 때 롤과 피치 각을 제로로 조절합니다 (결과적으로 태도가 수평이 됨). 자동 조종 장치는 바람 (또는 다른 원인)으로 인한 드리프트를 보상하지 않습니다. -- 중앙 스틱 (데드밴드 내부) : +- Centered sticks: - Roll/Pitch sticks level vehicle. - Outside center: - Roll/Pitch sticks control tilt angle in those orientations, resulting in corresponding left-right and forward-back movement. diff --git a/docs/ko/flight_modes_mc/mission.md b/docs/ko/flight_modes_mc/mission.md index 915a7db55e..313aabcb18 100644 --- a/docs/ko/flight_modes_mc/mission.md +++ b/docs/ko/flight_modes_mc/mission.md @@ -31,33 +31,33 @@ At high level all vehicle types behave in the same way when MISSION mode is enga 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". + - If flying the vehicle will hold. + - If landed the vehicle will "wait". 2. If a mission is stored and PX4 is flying it will execute the [mission/flight plan](../flying/missions.md) from the current step. - - A `TAKEOFF` item is treated as a normal waypoint. + - A `TAKEOFF` item is treated as a normal waypoint. 3. If a mission is stored and PX4 is landed: - - PX4 will execute the [mission/flight plan](../flying/missions.md). - - If the mission does not have a `TAKEOFF` item then PX4 will fly the vehicle to the minimum altitude before executing the remainder of the flight plan from the current step. + - PX4 will execute the [mission/flight plan](../flying/missions.md). + - If the mission does not have a `TAKEOFF` item then PX4 will fly the vehicle to the minimum altitude before executing the remainder of the flight plan from the current step. 4. If no mission is stored, or if PX4 has finished executing all mission commands: - - If flying the vehicle will hold. - - If landed the vehicle will "wait". + - If flying the vehicle will hold. + - If landed the vehicle will "wait". 5. You can manually change the current mission command by selecting it in _QGroundControl_. - ::: info - If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. - One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. + ::: info + If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. + One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. ::: 6. The mission will only reset when the vehicle is disarmed or when a new mission is uploaded. - :::tip - To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. - Enter the time to wait after landing before disarming the vehicle. + :::tip + To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. + Enter the time to wait after landing before disarming the vehicle. ::: @@ -171,6 +171,9 @@ Mission Items: - [MAV_CMD_NAV_VTOL_TAKEOFF](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_VTOL_TAKEOFF) - `MAV_CMD_NAV_VTOL_TAKEOFF.param2` (transition heading) is ignored. Instead the heading to the next waypoint is used for the transition heading. +- [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) . GeoFence Definitions diff --git a/docs/ko/flight_modes_mc/position.md b/docs/ko/flight_modes_mc/position.md index 01f7b573e2..a70a503627 100644 --- a/docs/ko/flight_modes_mc/position.md +++ b/docs/ko/flight_modes_mc/position.md @@ -43,7 +43,7 @@ While very rare on a well calibrated vehicle, sometimes there may be problems wi RC mode where roll, pitch, throttle (RPT) sticks control movement in corresponding axes/directions. Centered sticks level vehicle and hold it to fixed altitude and position against wind. -- Centered roll, pitch, throttle sticks (within RC deadzone [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ)) hold x, y, z position steady against any disturbance like wind. +- Centered roll, pitch, throttle sticks (within RC deadzone [MAN_DEADZONE](#MAN_DEADZONE)) hold x, y, z position steady against any disturbance like wind. - Outside center: - Roll/Pitch sticks control horizontal acceleration over ground in the vehicle's left-right and forward-back directions (respectively). - Throttle stick controls speed of ascent-descent. @@ -62,12 +62,11 @@ All the parameters in the [Multicopter Position Control](../advanced_config/para | 매개변수 | 설명 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ) | Deadzone of sticks where position hold is enabled. Default: 0.1 (10% of full stick range). | +| [MAN_DEADZONE](../advanced_config/parameter_reference.md#MAN_DEADZONE) | Deadzone of sticks where position hold is enabled. Default: 0.1 (10% of full stick range). | | [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 최대 수직 상승 속도. 기본값: 3 m/s. | | [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 최대 수직 하강 속도. 기본값: 1 m/s. | | [MPC_LAND_ALT1](../advanced_config/parameter_reference.md#MPC_LAND_ALT1) | Altitude for triggering first phase of slow landing. Below this altitude descending velocity gets limited to a value between [MPC_Z_VEL_MAX_DN](#MPC_Z_VEL_MAX_DN) (or `MPC_Z_V_AUTO_DN`) and [MPC_LAND_SPEED](#MPC_LAND_SPEED). Value needs to be higher than [MPC_LAND_ALT2](#MPC_LAND_ALT2). Default 10m. | | [MPC_LAND_ALT2](../advanced_config/parameter_reference.md#MPC_LAND_ALT2) | Altitude for second phase of slow landing. Below this altitude descending velocity gets limited to [`MPC_LAND_SPEED`](#MPC_LAND_SPEED). Value needs to be lower than "MPC_LAND_ALT1". Default 5m. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | | `MPC_XXXX` | 대부분의 MPC_xxx 매개 변수는이 모드에서 비행 동작에 어느정도 영향을 미칩니다 . For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | | [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Stick input to movement translation strategy. From PX4 v1.12 the default (`Acceleration based`) is that stick position controls acceleration (in a similar way to a car accelerator pedal). Other options allow stick deflection to directly control speed over ground, with and without smoothing and acceleration limits. | | [MPC_ACC_HOR_MAX](../advanced_config/parameter_reference.md#MPC_ACC_HOR_MAX) | Maximum horizontal acceleration. | diff --git a/docs/ko/flight_modes_mc/throw_launch.md b/docs/ko/flight_modes_mc/throw_launch.md index a6212c185a..5b4a197bc7 100644 --- a/docs/ko/flight_modes_mc/throw_launch.md +++ b/docs/ko/flight_modes_mc/throw_launch.md @@ -43,16 +43,16 @@ Also ensure that the propellers do not spin on arming after enabling the feature In addition: 1. Wear safety equipment. - Eye protection and work gloves are recommended. + Eye protection and work gloves are recommended. 2. Have an easily accessible and tested [kill switch](../config/safety.md#kill-switch). - Remind the operator to be attentive and use the kill switch if needed. - Pilots tend to forget that vehicles are replaceable, but they are not! + Remind the operator to be attentive and use the kill switch if needed. + Pilots tend to forget that vehicles are replaceable, but they are not! 3. Test as much as possible without propellers. - Keep the tools for removing propellers nearby/readily accessible. + Keep the tools for removing propellers nearby/readily accessible. 4. Test this feature with at least two people — one handling the aircraft, the other one the remote control. 5. Keep in mind that after the throw, the exact behavior of the aircraft might be hard to predict as it depends heavily on the way it is thrown. - Sometimes it will stay perfectly in place, but sometimes (e.g., due to extensive roll), it might drift to one side while stabilizing. - Keep a safe distance! + Sometimes it will stay perfectly in place, but sometimes (e.g., due to extensive roll), it might drift to one side while stabilizing. + Keep a safe distance! On first flight of a new vehicle we recommend performing a [Throw Launch test without propellers](#throw-launch-pretest) (see below). @@ -65,13 +65,13 @@ The steps for this test are: 1. Dismount the propellers. 2. Set [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) to `Enabled`. 3. Arm the aircraft. - The engines should not spin, but the vehicle should be armed and keep playing the arming tune. + The engines should not spin, but the vehicle should be armed and keep playing the arming tune. 4. Throw the aircraft about 2m into the air. - If the aircraft is not thrown high enough, the motors will not turn on. + If the aircraft is not thrown high enough, the motors will not turn on. 5. The engines should start just after crossing the apex. 6. Engage the kill switch (ideally a second person operating the RC should do this). 7. Catch the drone. - Remember to use safety gloves! + Remember to use safety gloves! ## Throw Launch @@ -79,12 +79,12 @@ The steps for a throw launch are: 1. Set [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) to `Enabled`. 2. Arm the aircraft. - The propellers should not spin, but the vehicle should be armed and keep playing the arming tune. + The propellers should not spin, but the vehicle should be armed and keep playing the arming tune. 3. Throw the aircraft away from you, forward and up (about 2m away and 2m up is recommended). - - The vehicle must reach the speed of [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED) to detect launch, which by default is set to 5 m/s. - If this speed is not achieved, the motors will not start and the aircraft will fall to the ground. - - Try to avoid excessive rotation during the throw, as this might cause the drone to fail or behave unpredictably. - The exact meaning of "excessive rotation" depends on the platform: for instance, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md) used for the testing, still managed to recover after 2-3 full rotations. + - The vehicle must reach the speed of [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED) to detect launch, which by default is set to 5 m/s. + If this speed is not achieved, the motors will not start and the aircraft will fall to the ground. + - Try to avoid excessive rotation during the throw, as this might cause the drone to fail or behave unpredictably. + The exact meaning of "excessive rotation" depends on the platform: for instance, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md) used for the testing, still managed to recover after 2-3 full rotations. 4. After a downward velocity is detected (the vehicle reaches its apex and starts falling down), the motors should turn on and the vehicle will start flying in the current mode. ## 매개변수 diff --git a/docs/ko/flight_modes_rover/api.md b/docs/ko/flight_modes_rover/api.md new file mode 100644 index 0000000000..85b1eead64 --- /dev/null +++ b/docs/ko/flight_modes_rover/api.md @@ -0,0 +1,29 @@ +# Apps & API + +The rover modules have been tested and integrated with a subset of the available [Apps & API](../middleware/index.md) methods. +We specifically provide guides for using [ROS 2](../ros2/index.md) to interface a companion computer with PX4 via [uXRCE-DDS](../middleware/uxrce_dds.md). + +| Method | 설명 | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [PX4 ROS 2 Interface](#px4-ros-2-interface) (Recommended) | Register a custom mode and publish [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). | +| [ROS 2 Offboard Control](#ros-2-offboard-control) | Use the PX4 internal [Offboard Mode](../flight_modes/offboard.md) and publish messages defined in [dds_topics.yaml](../middleware/dds_topics.md). | + +## PX4 ROS 2 Interface + +We recommend the use of the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) which allows you to register a custom drive mode and exposes [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). + +By using these setpoints (instead of the PX4 internal rover setpoints), you are guaranteed to send valid control inputs to your vehicle and the control flags for the setpoints you are using are automatically set for you. +Registering a custom drive mode instead of using [ROS 2 Offboard Control](#ros-2-offboard-control) additionally provides the advantages listed [here](../concept/flight_modes.md#internal-vs-external-modes). + +To get familiar with this method, read through the guide for the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) where we also provide an example app for rover. + +## ROS 2 Offboard Control + +[ROS 2 Offboard Control](../ros2/offboard_control.md) uses the PX4 internal [Offboard Mode](../flight_modes/offboard.md). + +While you can subscribe/publish to all topics specified in [dds_topics.yaml](../middleware/dds_topics.md), not all rover modules support all of these topics (see [Supported Setpoints](../flight_modes/offboard.md#rover)). +Unlike the [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints) exposed through the [PX4 ROS 2 Interface](#px4-ros-2-interface), there is no guarantee that the published setpoints lead to a valid control input. + +In addition, the correct control mode flags must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md). +This requires a deeper understanding of PX4 and the structure of the rover modules. +For general information on setting up offboard mode read through [Offboard Mode](../flight_modes/offboard.md) and then consult [Supported Setpoints](../flight_modes/offboard.md#rover). diff --git a/docs/ko/flying/geofence.md b/docs/ko/flying/geofence.md index 41058158ae..751e0da3d2 100644 --- a/docs/ko/flying/geofence.md +++ b/docs/ko/flying/geofence.md @@ -43,7 +43,7 @@ Geofence planning is fully documented in [Plan View > GeoFence](https://docs.qgr - 펜스 중앙 마커를 사용하여 펜스를 올바른 위치로 이동할 수 있습니다. - 원형 울타리 테두리의 마커를 사용하여 반경을 변경할 수 있습니다. - 모서리 (정점)의 마커를 사용하여 다각형의 형상을 변경할 수 있습니다. - 기존 마커 사이의 선을 따라 중간을 클릭하면 추가 정점이 생성됩니다. + 기존 마커 사이의 선을 따라 중간을 클릭하면 추가 정점이 생성됩니다. 5. Use the _Geofence Editor_ to set a fence as an inclusion or exclusion, and to select a fence to edit (**Edit** radio button) or Delete (**Del** button). 6. 필요한 만큼 울타리를 추가하십시오. 7. Once finished, click on the **Upload** button (top right) to send the fence (along with rally points and mission) to the vehicle. diff --git a/docs/ko/flying/package_delivery_mission.md b/docs/ko/flying/package_delivery_mission.md index 4571bcb1c7..3d1390abf5 100644 --- a/docs/ko/flying/package_delivery_mission.md +++ b/docs/ko/flying/package_delivery_mission.md @@ -37,9 +37,9 @@ To create a package delivery mission (with a Gripper): - 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. - Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. + Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. - ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) + ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) 3. Add a waypoint on the map (anywhere) for the gripper release. To change this to a `Gripper Mechanism` select the "Waypoint" heading, and in the popup changing the group to "Advanced", then selecting `Gripper Mechanism`. diff --git a/docs/ko/frames_multicopter/dji_f450_cuav_5nano.md b/docs/ko/frames_multicopter/dji_f450_cuav_5nano.md index 82c0b52ee5..aa3f163b60 100644 --- a/docs/ko/frames_multicopter/dji_f450_cuav_5nano.md +++ b/docs/ko/frames_multicopter/dji_f450_cuav_5nano.md @@ -106,52 +106,52 @@ FrSky Taranis 조종기를 사용할 수 있습니다. 1. 제공된 나사를 이용하여 하판에 팔 4개를 결합합니다. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) 2. ESC (변속기) 의 양극 (빨강)과 음극 (검정)을 보드에 납땜합니다. - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) 3. 전원 모듈의 양극 (빨강)과 음극 (검정)을 납땜합니다. - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) 4. 위치에 따라 모터를 ESC에 연결합니다. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) 5. 각각의 모터를 해당하는 팔에 고정합니다. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) 6. (다리의 윗부분과 나사로 결합하여) 상판을 장착합니다. - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) 7. Add damping foam to the _CUAV V5 nano_ flight controller. - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) 8. FrSky 수신기를 양면 테이프를 이용하여 하판에 부착합니다. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) 9. 텔레메트리 모듈을 기체의 아랫판에 양면테이프를 이용하여 부착합니다. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) 10. 알루미늄 GPS 지지대를 밑판에 추가한후 GPS를 부착합니다. - ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) + ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) 11. Plug in Telemetry (`TELEM1`), GPS module (`GPS/SAFETY`), RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/ko/frames_multicopter/dji_f450_cuav_5plus.md b/docs/ko/frames_multicopter/dji_f450_cuav_5plus.md index d4588205c8..d96964b607 100644 --- a/docs/ko/frames_multicopter/dji_f450_cuav_5plus.md +++ b/docs/ko/frames_multicopter/dji_f450_cuav_5plus.md @@ -108,53 +108,53 @@ FrSky Taranis 조종기를 사용할 수 있습니다. 1. 제공된 나사를 이용하여 하판에 팔 4개를 결합합니다. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) 2. ESC (변속기) 의 양극 (빨강)과 음극 (검정)을 보드에 납땜합니다. - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) 3. 전원 모듈의 양극 (빨강)과 음극 (검정)을 납땜합니다. - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) 4. 위치에 따라 모터를 ESC에 연결합니다. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) 5. 각각의 모터를 해당하는 팔에 고정합니다. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) 6. (다리의 윗부분과 나사로 결합하여) 상판을 장착합니다. - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) 7. CUAV V5 + 비행 컨트롤러에 양면 테이프(3M)를 추가합니다 (내부 진동 감쇠 기능이있어 폼을 사용할 필요가 없음). - ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) + ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) 8. FrSky 수신기를 양면 테이프를 이용하여 하판에 부착합니다. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) 9. 텔레메트리 모듈을 기체의 아랫판에 양면테이프를 이용하여 부착합니다. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) 10. 알루미늄 GPS 지지대를 밑판에 추가한후 GPS를 부착합니다. 11. Plug in Telemetry (`TELEM1`) and GPS module (`GPS/SAFETY`) to the flight controller. - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) 12. Plug in the RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/ko/frames_multicopter/holybro_qav250_pixhawk4_mini.md b/docs/ko/frames_multicopter/holybro_qav250_pixhawk4_mini.md index 5677c2aac7..e8889c939f 100644 --- a/docs/ko/frames_multicopter/holybro_qav250_pixhawk4_mini.md +++ b/docs/ko/frames_multicopter/holybro_qav250_pixhawk4_mini.md @@ -103,79 +103,79 @@ Estimated time to assemble frame is 2 hours and 1.5 hours installing the autopil 1. 그림과 같이 15mm 나사를 사용하여 암을 버튼 플레이트에 부착합니다. - ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) + ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) 2. 짧은 판을 팔 위에 올려 놓습니다. - ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) + ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) 3. 15mm 나사에 너트를 끼웁니다 (다음 단계 참조). 4. Insert the plastic screws into the indicated holes (note that this part of the frame faces down when the vehicle is complete). - ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) + ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) 5. Add the plastic nuts to the screws (turn over, as shown) - ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) + ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) 6. Lower the power module over the plastic screws and then add the plastics standoffs - ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) + ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) 7. Put the flight controller plate on the standoffs (over the power module) - ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) + ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) 8. 모터를 부착합니다. 모터에는 회전 방향을 나타내는 화살표가 있습니다. - ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) + ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) 9. Use double sided tape from kit to attach the _Pixhawk 4 Mini_ to the flight controller plate. - ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) + ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) 10. Connect the power module's "power" cable to _Pixhawk 4 mini_. - ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) + ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) 11. Attach the aluminium standoffs to the button plate - ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) + ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) 12. Esc를 모터에 연결합니다. 이 이미지는 모터의 순서와 회전 방향을 나타냅니다. - ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) + ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) - ESC의 모터를 연결하고 모터가 올바른 방향으로회전하는 지 확인하십시오. - 모터가 반대쪽으로 회전하면 케이블 A를 패드 C로, C를 ESC의 패드 A로 변경하십시오. + ESC의 모터를 연결하고 모터가 올바른 방향으로회전하는 지 확인하십시오. + 모터가 반대쪽으로 회전하면 케이블 A를 패드 C로, C를 ESC의 패드 A로 변경하십시오. - :::warning - Test motor directions with propellers removed. + :::warning + Test motor directions with propellers removed. ::: - ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) + ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) 13. 신호 ESC 케이블을 Pixhawk의 PWM 출력에 올바른 순서로 연결합니다 (이전 이미지 참조). - ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) + ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) 14. 수신기 연결합니다. - - PPM 수신기를 사용하는 경우 PPM 포트에 연결하십시오. + - PPM 수신기를 사용하는 경우 PPM 포트에 연결하십시오. - ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) + ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) - - SBUS 수신기를 사용하는 경우 RC IN 포트에 연결합니다. + - SBUS 수신기를 사용하는 경우 RC IN 포트에 연결합니다. - ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) + ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) 15. 텔레메트리 모듈을 연결합니다. 이중 테이프로 모듈을 붙여넣고 텔레메트리 포트에 연결합니다. - ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) + ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) 16. GPS 모듈 연결 - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) - 제공된 3M 테이프 또는 페이스트를 사용하여 상단 플레이트에 모듈을 부착합니다. 그런 다음 그림과 같이 스탠드오프에 상단 플레이트를 놓습니다. + 제공된 3M 테이프 또는 페이스트를 사용하여 상단 플레이트에 모듈을 부착합니다. 그런 다음 그림과 같이 스탠드오프에 상단 플레이트를 놓습니다. - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) 17. 마지막 "필수"조립 단계는 배터리를 고정하기 위해 벨크로를 추가하는 것입니다. - ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) + ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) The "basic" frame build is now complete (though if you need them, you can find more information about connecting components in the [Pixhawk 4 Wiring Quickstart](../assembly/quick_start_pixhawk4.md)). @@ -190,17 +190,17 @@ If you have the "basic" version of the kit, you can now jump ahead to instructio 키트를 설치하는 단계는 다음과 같습니다. 1. Install the camera bracket on the frame - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) 2. Install the camera on the bracket - ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) + ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) 3. The power module on the complete kit comes with wiring ready to connect the Video Transmitter and Camera: - ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) - - Attach the camera connector - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) - The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. - - Connect the Video Transmitter (VTX) connector - ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) - The wires are: yellow=video out, black=ground, red=+voltage. + ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) + - Attach the camera connector + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) + The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. + - Connect the Video Transmitter (VTX) connector + ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) + The wires are: yellow=video out, black=ground, red=+voltage. 4. 테이프를 사용하여 비디오 송신기와 OSD 보드를 프레임에 고정합니다. :::info diff --git a/docs/ko/frames_multicopter/holybro_s500_v2_pixhawk4.md b/docs/ko/frames_multicopter/holybro_s500_v2_pixhawk4.md index 1a2c8bc8f6..282a02a0d7 100644 --- a/docs/ko/frames_multicopter/holybro_s500_v2_pixhawk4.md +++ b/docs/ko/frames_multicopter/holybro_s500_v2_pixhawk4.md @@ -115,11 +115,11 @@ FrSky Taranis 무선 조종기를 사용하여 조립하는 경우를 예시로 조립 예상 시간은 90분 정도이며 프레임 조립에 약 45분과 QGroundControl의 자동조종장치 설정에 45분정도 걸립니다. 1. 랜딩 기어 조립. - 먼저 착륙 기어를 수직 기둥에 조립합니다. 랜딩 기어 나사를 풀고, 수직 기둥을 삽입합니다. + 먼저 착륙 기어를 수직 기둥에 조립합니다. 랜딩 기어 나사를 풀고, 수직 기둥을 삽입합니다. - ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) + ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) - ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) + ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) 2. 전원 관리 보드를 랜딩 기어에 조립합니다. 조립된 전원 관리 보드에 수직 기둥이 있는 랜딩 기어를 나사로 고정합니다. @@ -132,132 +132,132 @@ M3X8 나사 (총 8개, 각 측면에 4개)로 연결합니다. ![Figure 4](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig4.jpg) 1. 전원 관리 보드에 팔을 조립합니다. - 전원 관리 보드에 팔을 조립합니다. + 전원 관리 보드에 팔을 조립합니다. - ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) + ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) - ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) + ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) - 각 팔에 총 2개의 M2 5X6 나사를 사용합니다. - 플레이트 바닥에서 나사를 삽입합니다. + 각 팔에 총 2개의 M2 5X6 나사를 사용합니다. + 플레이트 바닥에서 나사를 삽입합니다. - ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) + ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) - ESC 케이블이 팔 중앙을 통과하는지 확인하십시오. + ESC 케이블이 팔 중앙을 통과하는지 확인하십시오. - ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) + ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) 2. Assemble the 8_3 2.54mm pitch Horizontal Pin to the 10 to 10 pin cable (PWM) to the Power Management Board. - Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. + Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. - ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) + ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) - 3M 테이프 조각을 잘라 수평 핀 하단에 부착합니다. + 3M 테이프 조각을 잘라 수평 핀 하단에 부착합니다. - ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) + ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) - 수평 핀을 전원 관리 보드에 고정 : + 수평 핀을 전원 관리 보드에 고정 : - ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) + ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) - ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) + ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) 3. 모터를 팔에 조립합니다. M3X7 나사 16개, 모터 4개, 팔 4개가 필요합니다. - 각 팔에 모터를 장착하고, 팔의 바닥을 통해 나사를 삽입합니다. + 각 팔에 모터를 장착하고, 팔의 바닥을 통해 나사를 삽입합니다. - ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) + ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) - ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) + ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) - 4개의 모터를 팔에 장착 한 후, 케이블 (빨간색, 파란색, 검은 색)을 잡고 팔 나사산에 끼웁니다. - 색상으로 구분된 3개의 케이블을 ESC에 연결합니다. + 4개의 모터를 팔에 장착 한 후, 케이블 (빨간색, 파란색, 검은 색)을 잡고 팔 나사산에 끼웁니다. + 색상으로 구분된 3개의 케이블을 ESC에 연결합니다. - ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) + ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) - ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) + ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) 4. 프레임에 GPS를 장착합니다. - Pixhawk 4 GPS와 마운팅된 플레이트가 필요합니다. + Pixhawk 4 GPS와 마운팅된 플레이트가 필요합니다. - ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) + ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) - 보드 뒷면에 GPS 마스트를 장착하고 4개의 나사를 사용합니다. + 보드 뒷면에 GPS 마스트를 장착하고 4개의 나사를 사용합니다. - ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) + ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) - ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) + ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) - 테이프를 사용하고, GPS를 GPS 마스트 상단에 붙입니다. + 테이프를 사용하고, GPS를 GPS 마스트 상단에 붙입니다. - ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) + ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) 5. FrSky를 보드에 붙여 넣습니다. 양면 테이프 (3M)로 FrSky를 하단 보드에 붙여 넣습니다. - FrSky를 프레임에 부착합니다. + FrSky를 프레임에 부착합니다. - ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) + ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) - ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) + ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) 6. 텔레메트리를 프레임에 부착합니다. - 다음 단계는 Holybro 텔레메트리를 프레임에 부착하고 3M 테이프를 사용합니다. + 다음 단계는 Holybro 텔레메트리를 프레임에 부착하고 3M 테이프를 사용합니다. - ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) + ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) - ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) + ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) - 차량 전방을 향하는 프레임 내부에 부착하였습니다. - 아래의 사진에는 프레임 하단에있는 라디오가 표시됩니다. + 차량 전방을 향하는 프레임 내부에 부착하였습니다. + 아래의 사진에는 프레임 하단에있는 라디오가 표시됩니다. - ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) + ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) 7. Pixhawk 4를 플레이트에 장착합니다. - 양면 테이프를 사용하여 Pixhawk 4를 중앙 플레이트에 부착합니다. + 양면 테이프를 사용하여 Pixhawk 4를 중앙 플레이트에 부착합니다. - ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) + ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) - ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) + ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) - ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) + ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) - 다음 단계는 플레이트와 함께 Pixhawk 4를 프레임에 장착하는 것입니다. - M2 5X6 나사가 필요합니다. - 플레이트를 프레임에 맞추고 나사를 삽입합니다. - 플레이트를 장착하기 전에 전원 모듈에 테이프를 붙이는 것이 좋습니다(단단하게 고정됨). + 다음 단계는 플레이트와 함께 Pixhawk 4를 프레임에 장착하는 것입니다. + M2 5X6 나사가 필요합니다. + 플레이트를 프레임에 맞추고 나사를 삽입합니다. + 플레이트를 장착하기 전에 전원 모듈에 테이프를 붙이는 것이 좋습니다(단단하게 고정됨). - ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) + ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) - ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) + ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) 8. 프레임에 배터리 마운트 조립. - M2 5X6 나사와 배터리 마운트가 필요합니다. + M2 5X6 나사와 배터리 마운트가 필요합니다. - ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) + ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) - 긴 막대를 작은 링에 삽입합니다. + 긴 막대를 작은 링에 삽입합니다. - ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) + ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) - ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) + ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) - 프레임에 부착하고, 나사를 삽입하기 위해 사면이 모두 정렬되어 있는 지 확인하십시오. + 프레임에 부착하고, 나사를 삽입하기 위해 사면이 모두 정렬되어 있는 지 확인하십시오. - ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) + ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) - 작은 판을 다리에 조립하고, 사면 모두에서 나사로 조입니다. + 작은 판을 다리에 조립하고, 사면 모두에서 나사로 조입니다. - ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) + ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) - 마지막 단계는 플레이트를 부착하는 것입니다. + 마지막 단계는 플레이트를 부착하는 것입니다. - ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) + ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) 9. Pixhawk 4 배선. Pixhawk 4의 배선 방법은 몇 가지 방법이 있습니다. - 아래에는 Pixhawk에 필요한 전선들과 연결된 모양이 설명되어 있습니다. + 아래에는 Pixhawk에 필요한 전선들과 연결된 모양이 설명되어 있습니다. 10. 플러그인 원격 측정 및 GPS 모듈을 비행 컨트롤러에 연결합니다 (그림 37 참조). RC 수신기, 4 개의 ESC 모두를 비행 컨트롤러와 전원 모듈에 연결합니다. - ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) + ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) 완전히 조립된 키트의 예는 아래와 같습니다. diff --git a/docs/ko/frames_multicopter/holybro_x500V2_pixhawk5x.md b/docs/ko/frames_multicopter/holybro_x500V2_pixhawk5x.md index 71b00944d1..ccd6859e9e 100644 --- a/docs/ko/frames_multicopter/holybro_x500V2_pixhawk5x.md +++ b/docs/ko/frames_multicopter/holybro_x500V2_pixhawk5x.md @@ -93,92 +93,92 @@ Tools are included to do the assembly, however you may need: Estimate time to assemble is 55 min (25 minutes for frame, 30 minutes for autopilot installation/configuration) 1. Start by assembling the payload & battery holder. - Push the rubbers into grippers (Do not use sharp items to push them in!). - Next, pass the holders through the holder bars with the battery holder bases as Figure 3. + Push the rubbers into grippers (Do not use sharp items to push them in!). + Next, pass the holders through the holder bars with the battery holder bases as Figure 3. - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) - _Figure 2_: Payload holder components + _Figure 2_: Payload holder components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) - _Figure 3_: Payload holder assembled + _Figure 3_: Payload holder assembled 2. The next is to go for attaching the bottom plate to the payload holder. - You will need the parts as shown in Figure 4. - Then mount the base for power distribution board using nylon nuts as Figure 5. - Finally using 8 hex screws you can join the bottom plate to the payload holder (Figure 7) + You will need the parts as shown in Figure 4. + Then mount the base for power distribution board using nylon nuts as Figure 5. + Finally using 8 hex screws you can join the bottom plate to the payload holder (Figure 7) - ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) + ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) - _Figure 4_: Needed Materials + _Figure 4_: Needed Materials - ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) + ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) - _Figure 5_: PDB mount base + _Figure 5_: PDB mount base - ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) + ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) - _Figure 6_: Mounted pdb with nylon nuts + _Figure 6_: Mounted pdb with nylon nuts - ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) + ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) - _Figure 7_: Mounted Plate on payload holder + _Figure 7_: Mounted Plate on payload holder 3. Let's gather the stuff needed for mounting landing gear as Figure 8. - Use the hex screws to join landing gears to the bottom plate. - You also need to open three hex screws on each of the leg stands so you can push them into carbon fiber pipes. - Do not forget to tighten them back again. + Use the hex screws to join landing gears to the bottom plate. + You also need to open three hex screws on each of the leg stands so you can push them into carbon fiber pipes. + Do not forget to tighten them back again. - ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) + ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) - _Figure 8_: Required parts for landing gear attachment + _Figure 8_: Required parts for landing gear attachment - ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) + ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) - _Figure 9_: Landing gear attachment to the body + _Figure 9_: Landing gear attachment to the body 4. We will gather all the arms now to mount the top plate. - Please pay attention that the motor numbers on arms are a match with the ones mentioned on the top plate. - Fortunately, motors are mounted and ESCs have been connected in advance. - Start by passing through all the screws as you have the arms fixed in their own places (They have a guide as shown in Figure 11 to ensure they are in place) and tighten all nylon nuts a bit. - Then you can connect XT30 power connectors to the power board. - Please keep in mind that the signal wires have to be passed through the top plate such that we can connect them later to Pixhawk. + Please pay attention that the motor numbers on arms are a match with the ones mentioned on the top plate. + Fortunately, motors are mounted and ESCs have been connected in advance. + Start by passing through all the screws as you have the arms fixed in their own places (They have a guide as shown in Figure 11 to ensure they are in place) and tighten all nylon nuts a bit. + Then you can connect XT30 power connectors to the power board. + Please keep in mind that the signal wires have to be passed through the top plate such that we can connect them later to Pixhawk. - + - _Figure 10_: Connecting arms needed materials. + _Figure 10_: Connecting arms needed materials. - + - _Figure 11_: Guide for the arms mount + _Figure 11_: Guide for the arms mount 5. Tighten all 16 screws and nuts by using both hex wrench and nut driver. - ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) + ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) - _Figure 12_: Mounted top plate + _Figure 12_: Mounted top plate 6. Next you can mount your pixhawk on the top plate by using the stickers. - It is recommended to have the direction of your Pixhawk's arrow the same as the one mentioned on the top plate. + It is recommended to have the direction of your Pixhawk's arrow the same as the one mentioned on the top plate. - ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) + ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) - _Figure 13_: Sticker tapes on Pixhawk + _Figure 13_: Sticker tapes on Pixhawk 7. If you want to mount the GPS on the companion computer plate, you can now secure the GPS mount onto it using 4 screws and nuts. - + - _Figure 14_: Secure GPS mount onto companion plate + _Figure 14_: Secure GPS mount onto companion plate 8. 테이프를 사용하여 GPS를 GPS 마스트 상단에 붙이고 GPS 마스트를 장착합니다. - Make sure the arrow on the gps is pointing forward (Figure 15). + Make sure the arrow on the gps is pointing forward (Figure 15). - + - _Figure 15_: GPS and mast + _Figure 15_: GPS and mast 9. Finally, you can connect the Pixhawk interfaces such as telemetry radio to 'TELEM1' and motors signal cables accordingly. diff --git a/docs/ko/frames_multicopter/holybro_x500_pixhawk4.md b/docs/ko/frames_multicopter/holybro_x500_pixhawk4.md index 12b2c679bb..0e47b5149d 100644 --- a/docs/ko/frames_multicopter/holybro_x500_pixhawk4.md +++ b/docs/ko/frames_multicopter/holybro_x500_pixhawk4.md @@ -81,125 +81,125 @@ Additionally you will need a battery and receiver ([compatible radio system](../ 예상 조립 시간은 3.75시간(프레임은 180분, 오토파일럿 설치와 설정은 45분)입니다. 1. 랜딩기어 조립부터 시작합니다. - 랜딩 기어 나사를 풀고 수직 기둥을 삽입합니다(그림 1 및 2). + 랜딩 기어 나사를 풀고 수직 기둥을 삽입합니다(그림 1 및 2). - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) - _Figure 2_: Landing gear components + _Figure 2_: Landing gear components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) - _Figure 2_: Landing gear assembled + _Figure 2_: Landing gear assembled 2. 그런 다음, 그림 3에 표시된 4개의 모터 베이스를 통해 4개의 암을 넣습니다. - 로드가 베이스를 약간 돌출시키고 4개의 암 전체에서 일관성이 있는 지 확인하고, 모터 와이어가 바깥쪽을 향하도록 합니다. + 로드가 베이스를 약간 돌출시키고 4개의 암 전체에서 일관성이 있는 지 확인하고, 모터 와이어가 바깥쪽을 향하도록 합니다. - ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) + ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) - _Figure 3_: Attach arms to motor bases + _Figure 3_: Attach arms to motor bases 3. 4개의 나일론 나사와 나일론 스탠드오프를 삽입하고, 그림 4와 같이 4개의 나일론 너트를 사용하여 전원 모듈 PM07을 하단 플레이트에 부착합니다. - ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) + ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) - _Figure 4_: Attach power module + _Figure 4_: Attach power module 4. 각 암을 통해 4개의 모터 ESC를 공급하고, 그림 5에 표시된 모터에 3선 끝을 연결합니다. - + - _Figure 5_: Connect motors + _Figure 5_: Connect motors 5. Connect the ESCs power wires onto the power module PM07, black->black and red->red, ESC PWM signal wires goes to "FMU-PWM-Out". - 모터 ESC PWM 와이어를 올바른 순서로 연결하였는 지 확인하십시오. - Refer to Figure 7 for airframe motor number and connect to the corresponding number on the PM07 board. + 모터 ESC PWM 와이어를 올바른 순서로 연결하였는 지 확인하십시오. + Refer to Figure 7 for airframe motor number and connect to the corresponding number on the PM07 board. - ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) - _Figure 7_: ESC power module and signal wiring + ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) + _Figure 7_: ESC power module and signal wiring - 모터 상단의 색상은 회전 방향(그림 7-1)을 나타내며, 검은색 끝은 시계 방향, 흰색 끝은 반시계 방향입니다. - 모터 방향은 px4 quadrotor x 기체 정의서를 따라야 합니다(그림 7-2). + 모터 상단의 색상은 회전 방향(그림 7-1)을 나타내며, 검은색 끝은 시계 방향, 흰색 끝은 반시계 방향입니다. + 모터 방향은 px4 quadrotor x 기체 정의서를 따라야 합니다(그림 7-2). - + - _Figure 7_: Motor order/direction diagram + _Figure 7_: Motor order/direction diagram - + - _Figure 7-1_: Motor direction + _Figure 7-1_: Motor direction 6. 10핀 케이블을 FMU-PWM-in에 연결하고, 6핀 케이블을 PM07 전원 모듈의 PWR1에 연결합니다. - ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) + ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) - _Figure 8_: Power module PWM and power wiring + _Figure 8_: Power module PWM and power wiring 7. GPS를 상판에 장착하는 경우에는 4개의 나사와 너트를 사용하여 GPS 장착을 상판에 고정합니다. - + - _Figure 9_: Secure GPS mount onto top plate + _Figure 9_: Secure GPS mount onto top plate 8. 상판을 통하여 PM07 케이블을 공급합니다. - 양쪽에 4개의 U자형 나일론 스트랩, 나사 및 너트를 사용하여 상단 및 하단 플레이트를 연결하고, 모터 ESC 케이블이 그림 10과 같이 U자형 나일론 스트랩 내부에 있는 지 확인하고 너트를 느슨하게 유지합니다. + 양쪽에 4개의 U자형 나일론 스트랩, 나사 및 너트를 사용하여 상단 및 하단 플레이트를 연결하고, 모터 ESC 케이블이 그림 10과 같이 U자형 나일론 스트랩 내부에 있는 지 확인하고 너트를 느슨하게 유지합니다. - + - _Figure 10-1_: Feed power module cables through top plate + _Figure 10-1_: Feed power module cables through top plate - + - _Figure 10-2_: Connecting top and bottom plate + _Figure 10-2_: Connecting top and bottom plate 9. 암 튜브를 프레임에 약간 밀어 넣고, 돌출 정도(그림 11의 빨간색 사각형)가 4개의 암 모두에서 일정한 지 확인합니다. - 모든 모터가 위를 향하고 있는 지 확인후, 모든 너트와 나사를 조입니다. + 모든 모터가 위를 향하고 있는 지 확인후, 모든 너트와 나사를 조입니다. - ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) + ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) 10. 행거 개스킷을 행거 4개에 넣고 육각 나사 8개를 사용하여 하단 플레이트에 장착합니다(그림 11). - 나사 구멍은 그림 12에서 흰색 화살표로 표시되어 있습니다. - 설치가 더 쉽도록 드론을 옆으로 기울이는 것이 좋습니다. + 나사 구멍은 그림 12에서 흰색 화살표로 표시되어 있습니다. + 설치가 더 쉽도록 드론을 옆으로 기울이는 것이 좋습니다. - + - _Figure 11_: Hanger gaskets + _Figure 11_: Hanger gaskets - ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) + ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) - _Figure 12_: Screw holes + _Figure 12_: Screw holes 11. 행거 링에 슬라이드 바를 삽입합니다(그림 13). - 배터리 마운트와 플랫폼 보드를 조립하고, 그림 14와 같이 슬라이드 바에 장착합니다. + 배터리 마운트와 플랫폼 보드를 조립하고, 그림 14와 같이 슬라이드 바에 장착합니다. - ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) + ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) - _Figure 13_: Slide bars + _Figure 13_: Slide bars - + - _Figure 14_: Battery mount on slide bars + _Figure 14_: Battery mount on slide bars 12. 랜딩 기어를 하판에 장착합니다. - 이 설치 과정을 더 쉽게 하려면 드론을 옆으로 기울이는 것이 좋습니다. + 이 설치 과정을 더 쉽게 하려면 드론을 옆으로 기울이는 것이 좋습니다. - ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) + ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) - _Figure 15_: Landing Gear + _Figure 15_: Landing Gear 13. 테이프를 사용하여 GPS를 GPS 마스트 상단에 붙이고 GPS 마스트를 장착합니다. - GPS의 화살표가 전방을 가리키는 지 확인하십시오(그림 16). + GPS의 화살표가 전방을 가리키는 지 확인하십시오(그림 16). - + - _Figure 16_: GPS and mast + _Figure 16_: GPS and mast 14. 상판에 텔레메트리를 장착합니다. - Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. - Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. + Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. + Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. - ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) + ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) - _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. + _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. Please refer to [Pixhawk 4 Quick Start](../assembly/quick_start_pixhawk4.md) for more information. diff --git a/docs/ko/frames_multicopter/holybro_x500v2_pixhawk6c.md b/docs/ko/frames_multicopter/holybro_x500v2_pixhawk6c.md index 86543b5e5f..bee5047840 100644 --- a/docs/ko/frames_multicopter/holybro_x500v2_pixhawk6c.md +++ b/docs/ko/frames_multicopter/holybro_x500v2_pixhawk6c.md @@ -18,21 +18,21 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] **Screw**- Sunk Screw M2.5\*6 12pcs 1. Insert the hanger rubber ring gasket in each of their respective hangers. - Do not use sharp objects to press the rubbers inside. + Do not use sharp objects to press the rubbers inside. - [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) + [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) 2. Take the battery mounting board and screw it with the slide bar clip using the Sunk Screw M2.5\*6. - [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) + [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) 3. Screw 4 hangers to the Platform Board using Sunk Screw M2.5\*6. - [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) + [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) 4. Take the slide bar and insert 4 hangers to screw to the bottom plate later. - [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) + [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) 5. Now insert the battery holder and payload holders assembled in step 2 & 3 @@ -44,11 +44,11 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. Take the bottom plate and insert 4 M3\*14 screws and fasten the nylon standoffs on the same. - [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) + [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) 2. Place the Power distribution board and use the locknuts to assemble them. The power module PM02 (for Pixhawk 6C) would power this board - [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) + [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) 3. Use Socket Cap Screws M2.5\*6 and screw the bottom plate on the 4 hangers (that we inserted in the 2 bars on the 3rd step of the payload holder assembly) @@ -56,15 +56,15 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. To assemble the landing gear, loosen the pre-assembled screws of the Landing Gear-Cross Bar and insert the Landing Gear-Vertical Pole and fasten the same. - [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) + [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) - [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) + [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) 2. Use the Socket Cap Screw M3\*8 to screw the landing gears to the bottom plate - [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) + [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) - [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) + [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) Because it’s cumbersome to insert the wires once the top plate is assembled, do the wiring beforehand. Although the design is well built such that you can do this later as well. @@ -92,28 +92,28 @@ Note that the ESC connectors are color-coded and must be inserted in the PWM out 1. Putting the arms is quite simple as the motors come pre-assembled. - - Ensure that you have the right numbered arm with its motor on the respective side. + - Ensure that you have the right numbered arm with its motor on the respective side. - [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) + [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) - :::tip - Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. + :::tip + Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. ::: 2. Take one arm and insert the rectangle extrusion inside the rectangular hollow on the bottom plate. - [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) + [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) 3. While inserting the top plate on top of this the 3 piece assembly (bottom plate, top plate & arms) have to screwed using Socket Cap Screw M3\*38 and Flange Locknut M3. 4. Hold one side using the mini cross wrench provided in the developer kit. - [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) + [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) 5. Do not fasten any screws before all 3 motors are in place as this might make it difficult while you’re assembling the 3rd and 4th motor. - [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) + [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) ### Propellers @@ -132,13 +132,13 @@ The following parts can be placed as per usual. 1. Assemble the GPS by following the video. - [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) + [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) - This guide uses the GPS mount location suggested in Holybro’s guide. + This guide uses the GPS mount location suggested in Holybro’s guide. 2. Screw the GPS mount’s bottom end on the payload holder side using Locknut M3 & Screw M3\*10 - [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) + [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) ### Pixhawk 6C diff --git a/docs/ko/frames_rover/index.md b/docs/ko/frames_rover/index.md index 3d1af9f3fa..7cf786c054 100644 --- a/docs/ko/frames_rover/index.md +++ b/docs/ko/frames_rover/index.md @@ -57,15 +57,17 @@ Each wheel is driven by its own motor, and by controlling the speed and directio ## See Also -- [Drive Modes](../flight_modes_rover/index.md). +- [Drive Modes](../flight_modes_rover/index.md) - [Configuration/Tuning](../config_rover/index.md) +- [Apps & API](../flight_modes_rover/api.md) - [Complete Vehicles](../complete_vehicles_rover/index.md) ## 시뮬레이션 -[Gazebo](../sim_gazebo_gz/index.md) provides simulations for ackermann and differential rovers: +PX4 provides synthetic simulation models for [Gazebo](../sim_gazebo_gz/index.md) of all three rover types to test the software and validate changes and new features: - [Ackermann rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) - [Differential rover](../sim_gazebo_gz/vehicles.md#differential-rover) +- [Mecanum rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) ![Rover gazebo simulation](../../assets/airframes/rover/rover_simulation.png) diff --git a/docs/ko/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md b/docs/ko/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md index a55b0116ab..2e390ce6dc 100644 --- a/docs/ko/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md +++ b/docs/ko/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md @@ -67,45 +67,45 @@ RTF 키트는 아래와 같이 조립하여야 합니다. 1. 그림과 같이 윙 브래킷 내부에 고릴라 접착제를 펴서 바릅니다. - ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) + ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) 2. 브래킷에 카본 튜브를 부착합니다. 브래킷과 튜브는 흰색 표시를 사용하여 정렬합니다 (그림 참조). - ::: info - This is very important because the white mark indicates the center of gravity. + ::: info + This is very important because the white mark indicates the center of gravity. ::: - + 3. 다음 이미지는 다른 관점에서 막대들의 정렬을 보여줍니다. - ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) - ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) + ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) + ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) ### 2 단계 : 날개 부착 1. 두 탄소 튜브를 동체에 삽입합니다. - + 2. 각 튜브에있는 두 개의 흰색 표시 사이에 고릴라 접착제를 바릅니다 (빨간색 화살표로 표시됨). 중앙의 흰색 표시 (파란색 화살표)는 동체 중앙에 배치되고, 다른 표시는 측면에 배치됩니다. - + 3. 탄소 튜브가 동체 내부에 있으면, 튜브의 나머지 부분에 고릴라 접착제를 바르고 날개를 부착하십시오. 4. 동체에는 모터와 서보 케이블을 위한 두 개의 구멍이 있습니다. 구멍으로 케이블을 통과시킨 다음 날개를 동체에 연결합니다. - + 5. 동체 내에 제공된 커넥터를 사용하여 방금 날개에서 ESC로 통과한 신호 케이블을 연결합니다. ESC는 이미 모터에 연결되어 있으며, 올바른 순서로 회전하도록 설정되어 있습니다 (나중 단계에서 ESC PDB를 전원 모듈에 연결해야 함). - + 6. ESC와 마찬가지로 서보는 이미 설치되어 있습니다. 날개 (동체를 통과)에서 비행 컨트롤러로 신호 케이블을 연결합니다. - + 7. 다른 날개에 이 단계를 반복합니다. @@ -123,11 +123,11 @@ General information about connecting Dropix can be found in [Dropix Flight Contr 1. XT60 커넥터를 사용하여 ESC를 전원 모듈에 연결합니다. - + 2. 신호 케이블을 비행 컨트롤러로 연결합니다. - + #### 모터 배선 @@ -162,7 +162,7 @@ For example, you might wire it up like this example (orientation as if "sitting 3. ESC의 스로틀 모터 신호 케이블을 적절한 비행 컨트롤러 보조 포트에 연결합니다. ESC를 스로틀 모터에 연결합니다. - + 4. 수신기를 RC IN에 연결합니다. @@ -176,7 +176,7 @@ For example, you might wire it up like this example (orientation as if "sitting 1. 그림과 같이 원격 측정, 대기 속도 센서, GPS, 부저 및 안전 스위치를 연결합니다. - + #### 비행 컨트롤러 : 전원 모듈 및 외부 USB 연결 @@ -184,7 +184,7 @@ USB 포트, 전원 모듈 및 외부 USB에 대한 입력은 비행 컨트롤러 1. 그림과 같이 전원과 USB를 연결합니다. - + :::tip The external USB is optional. @@ -201,27 +201,27 @@ It is important that nothing obstructs airflow to the Pitot tube. 이것은 고 1. 비행기 전면에 피토 튜브를 설치합니다 - + 2. 연결 튜브를 고정하고 구부러 지거나 꼬이지 않았는 지 확인합니다. - + 3. 튜브를 대기 속도 센서에 연결합니다. - + #### 수신기 및 원격 측정 모듈 설치 / 연결 1. 수신기와 원격 측정 모듈을 차량 프레임 외부에 붙여 넣습니다. - + 2. Connect the receiver to the RC IN port on the _back_ of the dropix, as shown above (also see the [flight controller instructions](#dropix_back)). 3. Connect the telemetry module to the _front_ of the flight controller as shown below (see the [flight controller instructions](#dropix_front) for more detail on the pins). - + @@ -237,7 +237,7 @@ GPS / 나침반 모듈은 기본 방향으로 날개에 이미 장착되어 있 1. 비행 컨트롤러 방향을 270도로 설정합니다. - + 2. 진동 감쇠폼을 사용하여 컨트롤러를 제자리에 고정합니다. @@ -247,21 +247,21 @@ GPS / 나침반 모듈은 기본 방향으로 날개에 이미 장착되어 있 1. 모터가 올바른 방향으로 회전하는지 확인하십시오 (아래 QuadX 다이어그램 참조). - + - ::: info - If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). + ::: info + If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). ::: 2. 차량이 예상 무게 중심 주변에서 균형을 이루는 지 확인하십시오. - - 손가락으로 기체의 무게 중심을 잡고 차량이 안정적인지 확인하십시오. + - 손가락으로 기체의 무게 중심을 잡고 차량이 안정적인지 확인하십시오. - ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) + ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) - - 차량이 앞이나 뒤로 기울면 모터를 움직여 균형을 잡으십시오. + - 차량이 앞이나 뒤로 기울면 모터를 움직여 균형을 잡으십시오. - ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) + ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) ## 설정 @@ -271,7 +271,7 @@ Perform the normal [Basic Configuration](../config/index.md). 1. For [Airframe](../config/airframe.md) select the vehicle group/type as _Standard VTOL_ and the specific vehicle as [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) as shown below. - ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) + ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) 2. Set the [Autopilot Orientation](../config/flight_controller_orientation.md) to `ROTATION_YAW_270` as the autopilot is mounted [sideways](#flight_controller_orientation) with respect to the front of the vehicle. The compass is oriented forward, so you can leave that at the default (`ROTATION_NONE`). diff --git a/docs/ko/frames_vtol/vtol_quadplane_foxtech_loong_2160.md b/docs/ko/frames_vtol/vtol_quadplane_foxtech_loong_2160.md index 9decf9821c..ad64afc43e 100644 --- a/docs/ko/frames_vtol/vtol_quadplane_foxtech_loong_2160.md +++ b/docs/ko/frames_vtol/vtol_quadplane_foxtech_loong_2160.md @@ -99,33 +99,33 @@ Use a soldering iron to press the threaded inserts into the 3D-Printed parts. 1. Insert 10x M3 threaded inserts into the baseplate as shown in the picture: - ![Baseplate with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) + ![Baseplate with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) 2. Insert 2x M3 threaded inserts into the stack fixture as shown in the picture below: - ![Stack fixture with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) + ![Stack fixture with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) 3. Insert 2x M4 threaded inserts into the fan mount and radio mount as shown in the picture below. - ![Radio-mount](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) + ![Radio-mount](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) - If you would like to add a 40mm 5V fan to the fan mount, insert 4x M3 inserts. + If you would like to add a 40mm 5V fan to the fan mount, insert 4x M3 inserts. - ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) + ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) 4. Change the cable connector to a servo connector so it can be plugged into the servo rail to be powered. - ::: info - A fan might be needed if a powerful radio is used. + ::: info + A fan might be needed if a powerful radio is used. ::: - ![Fan-mount with fan](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) + ![Fan-mount with fan](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) 5. Remove the original mounting plate from the vehicle. - Tape the cables to the outside of the fuselage. + Tape the cables to the outside of the fuselage. - ![Empty fuselage](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) + ![Empty fuselage](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) 6. Slide the baseplate into the vehicle. @@ -142,9 +142,9 @@ The 40A power module provides power for the avionics when using Skynode (and com 1. Remove the case from the 40A PM. 2. Screw the PM with 2x M2x6mm to the bottom of the baseplate. 3. Create a cable to extend the XT60 connector to an XT30 that is mounted on the baseplate. - With that, the 6S battery power can be directly plugged into the XT30 connector with the pre-configured cable that comes with the vehicle. + With that, the 6S battery power can be directly plugged into the XT30 connector with the pre-configured cable that comes with the vehicle. - ![40A Power Module installation](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) + ![40A Power Module installation](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) If necessary, the 10V output of the radio port on the PM can also be exposed via an XT30 that can be mounted next to the 6S battery input XT60. @@ -153,17 +153,17 @@ If necessary, the 10V output of the radio port on the PM can also be exposed via #### Pitot Tube 1. The sensor can be installed with 2x M3x16mm screws in the front right corner of the baseplate. - Take care that the connector is facing the center of the fuselage. + Take care that the connector is facing the center of the fuselage. - ![Mounted airspeed sensor](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) + ![Mounted airspeed sensor](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) - Only the front tube (not as shown in the picture) is used; the other tube can be removed since our experience showed that the pressure inside the fuselage is sufficient as static pressure. + Only the front tube (not as shown in the picture) is used; the other tube can be removed since our experience showed that the pressure inside the fuselage is sufficient as static pressure. 2. When the stack is mounted inside the fuselage, the tube coming from the wing and the one from the airspeed sensor need to be spliced together. - Use some spit (that's the easiest way) to push them together and afterward use a heat shrink tube to reinforce the connection. + Use some spit (that's the easiest way) to push them together and afterward use a heat shrink tube to reinforce the connection. - :::warning - Use a heat source carefully since the foam starts to melt at high temperatures. + :::warning + Use a heat source carefully since the foam starts to melt at high temperatures. ::: @@ -175,22 +175,22 @@ If no lidar is mounted you should disable using fixed-wing actuation in hover to ::: 1. Mark the location to install the lidar with some tape or a pen. - Cut a hole inside the PVC shell and the foam, so that the lidar fits in place. + Cut a hole inside the PVC shell and the foam, so that the lidar fits in place. - ![Prepared lidar hole](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) + ![Prepared lidar hole](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) 2. Secure the lidar with hot glue. - ![Installed lidar](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) + ![Installed lidar](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) #### GPS/나침반 1. Use double sided tape to mount the GPS in the rear of the vehicle underneath the rear latch. - ![Installed GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) + ![Installed GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) - The arrow on the GPS for the orientation can be ignored. - The orientation will be detected by the flight controller during the calibration. + The arrow on the GPS for the orientation can be ignored. + The orientation will be detected by the flight controller during the calibration. ### 비행 콘트롤러 @@ -203,15 +203,15 @@ Install either the Pixhawk or Skynode onto the baseplate. #### Skynode 1. Use 4x M3x8 screws to mount the Skynode to the baseplate. - Make sure that the top of the "A" is facing to the front of the vehicle. + Make sure that the top of the "A" is facing to the front of the vehicle. 2. Plug the 40A Power Module into the upper one of the two power connectors. 3. Plug one (or if needed two) USB adapters into the 4-pin JST-GH connectors into the back of the Skynode and feed them to the front of the plate. - Fix the cables with zip ties in place. + Fix the cables with zip ties in place. 4. Tape a I2C splitter to the front right side of the baseplate (The splitter can be used to plug in ETH devices such as a radio link.) 5. Connect the I2C splitter with the ETH port in the back of the Skynode. 6. Plug in the two 40-pin cables into the front of the Skynode. 7. Plug in the USB-C extension cable and bend it over to the front. - The bend needs to be very tight, so that the plate will fit into the vehicle. + The bend needs to be very tight, so that the plate will fit into the vehicle. ![Installed Skynode](../../assets/airframes/vtol/foxtech_loong_2160/15-skynode.jpg) @@ -223,17 +223,17 @@ Install either the Pixhawk or Skynode onto the baseplate. 1. Tape the Skynode LTE antennas to the side of the fuselage as shown in the picture: - ![LTE-Antennas](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) + ![LTE-Antennas](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) 2. If you are using a radio telemetry module you can mount the antennas to the top of the fuselage. - In the front you can mount the antenna extension cable directly. + In the front you can mount the antenna extension cable directly. - ![WIFI-Antennas-Front](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) + ![WIFI-Antennas-Front](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) - In the back you can use the 3D-Printed antenna adapter. - The adapter can be glued in place with hot glue. + In the back you can use the 3D-Printed antenna adapter. + The adapter can be glued in place with hot glue. - ![WIFI-Antenna-Back](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) + ![WIFI-Antenna-Back](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) ### 12S Power Module diff --git a/docs/ko/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md b/docs/ko/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md index 9bb916d719..f8f16bf6d9 100644 --- a/docs/ko/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md +++ b/docs/ko/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md @@ -93,7 +93,7 @@ Flight controller and wing connectors removed from the vehicle. ### ESC 1. Unsolder the ESC PWM-signal and ground pins and solder some servo extension wire to the pins. - The cable should be long enough to connect the wire to the FMU pins of the flight controller. + The cable should be long enough to connect the wire to the FMU pins of the flight controller. 2. Unsolder the 3 female banana plug connectors of the rear motor (might not be necessary for the Pixhawk 6 integration). @@ -103,17 +103,17 @@ Flight controller and wing connectors removed from the vehicle. 5. Solder signal and GND wires to the PWM input ot the ESC. - ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) + ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) 6. Remove the female banana plug on the ESC. - This will give you more space to install the flight controller. + This will give you more space to install the flight controller. - ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) + ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) 7. Solder the rear motor wires to the ESC. - Make sure to connect such that the motor spins in the correct direction. + Make sure to connect such that the motor spins in the correct direction. - ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) + ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) ### Wing Connector @@ -122,9 +122,9 @@ This step is not essential, but makes the handling much easier and there is one 1. Glue the wing connectors into the 3D-Printed part with hot-glue or 5 min epoxy. 2. Glue the 3D-printed part with the connector in to the fuselage. - Make sure to properly align the connector while the glue cures. + Make sure to properly align the connector while the glue cures. - The easiest way to align the connector is to mount the wing while the glue is curing, but make sure that no glue is between the fuselage and the wing, otherwise the wing might get stuck. + The easiest way to align the connector is to mount the wing while the glue is curing, but make sure that no glue is between the fuselage and the wing, otherwise the wing might get stuck. The connector glued into the 3D-Printed part @@ -137,58 +137,58 @@ The connector glued into the fuselage. Make sure to properly align the connector ### Pixhawk Adapter Boards and BEC 1. Cut the foam as shown in the pictures to create space to mount the Pixhawk adapter boards and BEC with double sided tape. - The FMU board is placed on the left side (in flight direction) of the fuselage. - Solder a servo connector and a cable for the battery voltage to the BEC. + The FMU board is placed on the left side (in flight direction) of the fuselage. + Solder a servo connector and a cable for the battery voltage to the BEC. - ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) - ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) + ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) + ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) 2. Prepare the BEC to connect to the IO board and to the battery. - The BEC can also be soldered directly to the battery pads of the ESC. + The BEC can also be soldered directly to the battery pads of the ESC. - ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) + ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) 3. Mount the BEC with double sided tape. - ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) + ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) ### Cables 1. Cut the connectors off the servos and solder the servo extension cables to the cables. - Make sure that the cables are long enough to reach the Pixhawk adapter board. - If you own a crimp tool, then you can also directly add the connectors without soldering. + Make sure that the cables are long enough to reach the Pixhawk adapter board. + If you own a crimp tool, then you can also directly add the connectors without soldering. 2. Plug the servo cables into the adapter IO board in the following order: - - 1 - Aileron left - - 2 - Aileron right - - 3 - V-Tail left - - 4 - V-Tail right - - 5 - Tilt left - - 6 - Tilt right + - 1 - Aileron left + - 2 - Aileron right + - 3 - V-Tail left + - 4 - V-Tail right + - 5 - Tilt left + - 6 - Tilt right 3. Plug in the motor signal cables into the FMU adapter board in the following order: - - 1 - Front left - - 2 - Front right - - 3 - Rear + - 1 - Front left + - 2 - Front right + - 3 - Rear ### 센서 #### Pitot Tube 1. First check if the pitot tube fits into the 3D-Printed mount. - If this is the case, glue the pitot tube mount into place. + If this is the case, glue the pitot tube mount into place. - To align the tube feed it through the second hole from the right of the FPV front plate. - The mount will enable you to push the tube back into the fuselage to protect it during transportation and handling. - The sensor unit can be mounted on top of the 3D-Printed mount with double sided tape. + To align the tube feed it through the second hole from the right of the FPV front plate. + The mount will enable you to push the tube back into the fuselage to protect it during transportation and handling. + The sensor unit can be mounted on top of the 3D-Printed mount with double sided tape. 2. Glue the 3D-Printed mount into place. - ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) + ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) 3. The sensor can be mounted on top of the 3D-Printed mount. - ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) + ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) #### Lidar @@ -209,9 +209,9 @@ To mount the GPS: 2. Take the GPS out of the plastic case and unplug the connector. 3. Feed the cable through the carbon spar. 4. Glue the 3D-Printed part with 5 min epoxy in place. - ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) + ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) 5. After the glue has cured, screw the GPS with 4x M2.5x10 screws to the plate. - ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) + ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) #### USB Camera @@ -219,9 +219,9 @@ To mount the GPS: 2. Cut the USB-Adapter cable to be 25 cm and solder the two cables together. 3. To install the camera you need to cut a hole into the foam of the wall. - ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) + ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) - Then you can mount the camera with double sided tape to the wall. + Then you can mount the camera with double sided tape to the wall. ### 비행 콘트롤러 @@ -237,7 +237,7 @@ If a Skynode is used: 1. Place it at the on top of the ESCs and mark the 2 rear mounting locations on the injection molded plastic part of the ZMO. 2. Remove the Skynode from the vehicle and drill 2 holes with a 2.8 mm drill bit into the plastic part. - ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) + ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) 3. Put the Skynode back into place and screw it down with 2x M3x10 screws. Another option is to add some threaded inserts into the holes. @@ -245,9 +245,9 @@ Since the injection molded part of the ZMO is very thin, they need to be glued i 1. Screw the front Skynode mount with 2x M3x10 screws at the Skynode. 2. Then add some 5 min epoxy at the bottom of the mount and put a weight on top of the Skynode until the glue is cured. - To access the 2 mounting screws at the front, poke 2 holes from the top through the foam. + To access the 2 mounting screws at the front, poke 2 holes from the top through the foam. - ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) + ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) ### Antennas and RC Receiver @@ -258,14 +258,14 @@ An inexpensive example would be a [SiK Telemetry Radio](../telemetry/sik_radio.m ::: 1. One LTE antenna can be installed on the bottom of the vehicle. - For that you can feed the antenna wire through the opening for the ESC heat-sink. + For that you can feed the antenna wire through the opening for the ESC heat-sink. - ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) + ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) 2. The second antenna can be installed on the inside of the vehicle on the left side of the battery compartment. - The RC receiver can also be placed at the left side of the battery compartment. + The RC receiver can also be placed at the left side of the battery compartment. - ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) + ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) ## 소프트웨어 설정 @@ -332,9 +332,9 @@ If motors/servos were connected to different outputs than suggested, you will ne 1. Switch the vehicle into manual mode (either via the flight mode switch or type `commander mode manual` into the MAVLink shell). 2. Check if the motors point upwards. - If the motors point forwards then their associated Tilt servos need to be reversed (selecting the checkbox next to each servo). + If the motors point forwards then their associated Tilt servos need to be reversed (selecting the checkbox next to each servo). - ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) + ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) 3. Adjust the minimum (or, if revesed: maximum) value such that the rotor thrust can point backward (needed for proper yaw allocation in Multicopter mode). diff --git a/docs/ko/getting_started/px4_basic_concepts.md b/docs/ko/getting_started/px4_basic_concepts.md index c775392b81..228ddc5b50 100644 --- a/docs/ko/getting_started/px4_basic_concepts.md +++ b/docs/ko/getting_started/px4_basic_concepts.md @@ -3,7 +3,7 @@ 이 주제는 드론과 PX4 사용에 대한 기본적인 소개를 제공합니다 (주로 초보자를 위한 내용이지만, 경험이 있는 사용자에게도 좋은 입문 자료가 될 수 있습니다). 기본 개념에 이미 익숙하다면, [기본 조립](../assembly/index.md) 섹션으로 넘어가서 사용 중인 오토파일럿 하드웨어의 배선 방법을 배우실 수 있습니다. -펌웨어를 설치하고 _QGroundControl_을 사용해 비행체를 설정하려면\ +펌웨어를 설치하고 _QGroundControl_을 사용해 비행체를 설정하려면 [기본 설정](../config/index.md) 섹션을 참조하세요. ## 드론의 정의 @@ -26,7 +26,7 @@ 이들은 가장 인기 있는 비행체 유형 중 하나로, 조립이 쉽고 PX4가 제공하는 다양한 비행 모드를 통해 조종이 간편하며, 카메라 플랫폼으로도 매우 적합하기 때문입니다. - [헬리콥터](../frames_helicopter/index.md) — 헬리콥터는 멀티콥터와 유사한 이점을 제공하지만, 기계적으로 더 복잡하고 더 효율적입니다. 이들은 또한 조종이 훨씬 더 어렵습니다. -- [비행기 (고정익)](../frames_plane/index.md) — 고정익 기체는 멀티콥터보다 더 오래, 더 빠르게 비행할 수 있어 지상 조사 등에서 더 넓은 범위를 커버할 수 있습니다.\ +- [비행기 (고정익)](../frames_plane/index.md) — 고정익 기체는 멀티콥터보다 더 오래, 더 빠르게 비행할 수 있어 지상 조사 등에서 더 넓은 범위를 커버할 수 있습니다. 하지만 멀티콥터보다 조종과 착륙이 더 어렵고, 공중에 머무르거나 아주 느리게 비행해야 하는 경우(예: 수직 구조물 조사)에는 적합하지 않습니다. - [VTOL](../frames_vtol/index.md) (수직 이착륙) — 고정익/멀티콥터 하이브리드 기체는 두 가지 방식의 장점을 모두 제공합니다. 멀티콥터처럼 수직으로 이륙하고 호버링할 수 있으며, 비행 중에는 비행기처럼 전진 비행으로 전환해 더 넓은 지역을 커버할 수 있습니다. VTOL은 일반적으로 멀티콥터나 고정익 항공기보다 더 비싸며, 제작과 튜닝도 더 어렵습니다. diff --git a/docs/ko/gps_compass/ark_dan_gps.md b/docs/ko/gps_compass/ark_dan_gps.md new file mode 100644 index 0000000000..5ca819bd0c --- /dev/null +++ b/docs/ko/gps_compass/ark_dan_gps.md @@ -0,0 +1,62 @@ +# ARK DAN GPS + +[ARK DAN GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox DAN-F10N GPS and industrial magnetometer. + +![ARK DAN GPS](../../assets/hardware/gps/ark/ark_dan_gps.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dan-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DAN_GPS) +- 센서 + - [u-blox DAN-F10N](https://www.u-blox.com/en/product/dan-f10n-module) + - L1/L5/E5a/B2a bands + - Consistently strong performance regardless of installation + - Integrated SAW-LNA-SAW for exceptional out-of-band jamming immunity + - u-blox F10 proprietary dual-band multipath mitigation technology + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 25mA Average + - 44mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## 하드웨어 설정 + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 설정 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## 핀배열 + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | 전압 | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## See Also + +- [ARK DAN GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) (ARK Docs) diff --git a/docs/ko/gps_compass/ark_sam_gps.md b/docs/ko/gps_compass/ark_sam_gps.md index c45b9d8bfc..b9b51b1236 100644 --- a/docs/ko/gps_compass/ark_sam_gps.md +++ b/docs/ko/gps_compass/ark_sam_gps.md @@ -1,6 +1,6 @@ # ARK SAM GPS -[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps>) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. +[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. ![ARK SAM GPS](../../assets/hardware/gps/ark/ark_sam_gps.jpg) diff --git a/docs/ko/gps_compass/ark_sam_gps_mini.md b/docs/ko/gps_compass/ark_sam_gps_mini.md new file mode 100644 index 0000000000..a2b92ab5e0 --- /dev/null +++ b/docs/ko/gps_compass/ark_sam_gps_mini.md @@ -0,0 +1,61 @@ +# ARK SAM GPS MINI + +[ARK SAM GPS MINI](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. + +![ARK SAM GPS MINI](../../assets/hardware/gps/ark/ark_sam_gps_mini.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-sam-gps-mini/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_SAM_GPS/tree/main) +- 센서 + - [u-blox SAM-M10Q](https://www.u-blox.com/en/product/sam-m10q-module) + - Less than 38 mW power consumption without compromising GNSS performance + - Maximum position availability with 4 concurrent GNSS reception + - Advanced spoofing and jamming detection + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 15mA Average + - 20mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## 하드웨어 설정 + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 설정 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## 핀배열 + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | 전압 | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## See Also + +- [ARK SAM GPS MINI Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) (ARK Docs) diff --git a/docs/ko/gps_compass/index.md b/docs/ko/gps_compass/index.md index 13aa607cc1..d6afb08543 100644 --- a/docs/ko/gps_compass/index.md +++ b/docs/ko/gps_compass/index.md @@ -25,7 +25,9 @@ These have been tested by the PX4 dev team, or which are popular within the PX4 | 장치 | GPS | 나침반 | [CAN](../dronecan/index.md) | Buzzer / SafeSw / LED | 참고 | | :----------------------------------------------------------- | :---------: | :-----------------------: | :-------------------------: | :-------------------: | :---------------------------------------------------------- | | [ARK GPS](../dronecan/ark_gps.md) | M9N | BMM150 | ✓ | ✓ | + Baro, IMU | +| [ARK DAN GPS](../gps_compass/ark_dan_gps.md) | DAN-F10N | IIS2MDC | | ✓ | | | [ARK SAM GPS](../gps_compass/ark_sam_gps.md) | SAM-M10Q | IIS2MDC | | ✓ | | +| [ARK SAM GPS MINI ](../gps_compass/ark_sam_gps_mini.md) | SAM-M10Q | IIS2MDC | | ✓ | | | [ARK TESEO GPS](../dronecan/ark_teseo_gps.md) | Teseo-LIV4F | BMM150 | ✓ | ✓ | + Baro, IMU | | [Avionics Anonymous UAVCAN GNSS/Mag][avionics_anon_can_gnss] | SAM-M8Q | MMC5983MA | ✓ | ✘ | | | [CUAV NEO 3 GPS](../gps_compass/gps_cuav_neo_3.md) | M9N | IST8310 | | ✓ | | @@ -145,21 +147,21 @@ To ensure the port is set up correctly perform a [Serial Port Configuration](../ The following steps show how to configure a secondary GPS on the `GPS 2` port in _QGroundControl_: 1. [Find and set](../advanced_config/parameters.md) the parameter [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) to **GPS 2**. - - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. - - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. + - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. + - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. - ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) + ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) 2. 다른 매개변수를 표시하려면 기체를 재부팅하십시오. 3. Select the **Serial** tab, and open the [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD) parameter (`GPS 2` port baud rate): set it to _Auto_ (or 115200 for the Trimble). - ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) + ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) 보조 GPS 포트를 설정 후 : 1. 두 GPS 시스템의 데이터를 혼합하도록 ECL/EKF2 추정기를 설정합니다. - For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). + For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). ### DroneCAN GNSS Configuration @@ -197,11 +199,21 @@ It is possible to have low DOP (good satellite geometry) but still have high EPH EPH/EPV values therefore provide a more immediate and practical estimate of the actual GPS accuracy you can expect under current conditions. +### GNSS Position Fusion + +GNSS position fusion will not begin until yaw alignment is established. +If a magnetometer is available, the EKF aligns yaw using the magnetic heading, allowing GPS position fusion to start soon after boot. +If no magnetometer is present, the system must rely on GPS yaw (from a dual-antenna setup) or movement-based yaw estimation. +Until one of these provides a valid heading, the EKF will not start GPS position fusion, and the vehicle will remain in a “no position” state even though attitude data is valid. +This behavior prevents large position errors that could occur when the yaw reference is uncertain. + ## 개발자 정보 - GPS/RTK-GPS - [RTK-GPS](../advanced/rtk_gps.md) + - [PPS Time Synchronization](../advanced/pps_time_sync.md) - [GPS driver](../modules/modules_driver.md#gps) + - [PPS driver](../modules/modules_driver.md#pps-capture) - [DroneCAN Example](../dronecan/index.md) - 나침반 - [Driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/magnetometer) (Compasses) diff --git a/docs/ko/gps_compass/magnetometer.md b/docs/ko/gps_compass/magnetometer.md index a6c238c478..5474b68bbd 100644 --- a/docs/ko/gps_compass/magnetometer.md +++ b/docs/ko/gps_compass/magnetometer.md @@ -40,6 +40,7 @@ This list contains stand-alone magnetometer modules (without GNSS). | 장치 | 나침반 | DroneCan | | :--------------------------------------------------------------------------------------------------------------- | :----: | :------: | +| [ARK MAG](https://arkelectron.com/product/ark-mag/) | RM3100 | ✓ | | [Avionics Anonymous UAVCAN Magnetometer](https://www.tindie.com/products/avionicsanonymous/uavcan-magnetometer/) | ? | | | [Holybro DroneCAN RM3100 Compass/Magnetometer](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | | [RaccoonLab DroneCAN/Cyphal Magnetometer RM3100](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | diff --git a/docs/ko/gps_compass/rtk_gps.md b/docs/ko/gps_compass/rtk_gps.md index 1d40ffce20..07270685a5 100644 --- a/docs/ko/gps_compass/rtk_gps.md +++ b/docs/ko/gps_compass/rtk_gps.md @@ -21,50 +21,59 @@ PX4 supports the [u-blox M8P](https://www.u-blox.com/en/product/neo-m8p), [u-blo The table indicates devices that also output yaw, and that can provide yaw when two on-vehicle units are used. It also highlights devices that connect via the CAN bus, and those which support PPK (Post-Processing Kinematic). -| 장치 | GPS | 나침반 | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :------: | :------------------------------: | :-----------------------------------------------: | :-: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| 장치 | GPS | 나침반 | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :--------: | :---------------------------------: | :-: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK 참고: @@ -123,35 +132,36 @@ This should be set by default, but if not, follow the [MAVLink2 configuration in RTK GPS 연결은 기본적으로 플러그앤플레이입니다. 1. Start _QGroundControl_ and attach the base RTK GPS via USB to the ground station. - 장치가 자동으로 인식됩니다. + 장치가 자동으로 인식됩니다. 2. Start the vehicle and make sure it is connected to _QGroundControl_. - :::tip - _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). - RTK가 설정되는 동안 아이콘은 빨간색으로 표시되고, RTK GPS가 활성화되면 흰색으로 바뀝니다. - 아이콘을 클릭하여 현재 상태와 RTK 정확도를 확인할 수 있습니다. + :::tip + _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). + RTK가 설정되는 동안 아이콘은 빨간색으로 표시되고, RTK GPS가 활성화되면 흰색으로 바뀝니다. + 아이콘을 클릭하여 현재 상태와 RTK 정확도를 확인할 수 있습니다. ::: 3. _QGroundControl_ then starts the RTK setup process (known as "Survey-In"). - Survey-In은 기지국의 정확한 위치 추정치를 획득을 위한 시작 절차입니다. - The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). + Survey-In은 기지국의 정확한 위치 추정치를 획득을 위한 시작 절차입니다. + The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). - RTK GPS 상태 아이콘을 클릭하여 진행 상황을 추적할 수 있습니다. + RTK GPS 상태 아이콘을 클릭하여 진행 상황을 추적할 수 있습니다. - ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) + ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. Survey-in이 완료되면 : - - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - - 기체의 GPS가 RTK 모드로 전환됩니다. - The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) - ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) + - 기체의 GPS가 RTK 모드로 전환됩니다. + The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + + ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) ### GPS를 Yaw/Heading 소스로 설정 @@ -206,7 +216,7 @@ MAVLink2 프로토콜은 낮은 대역폭 채널을 보다 효율적으로 사 MAVLink2가 사용되는 지 확인하려면 : - Update the telemetry module firmware to the latest version (see [QGroundControl > Setup > Firmware](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/firmware.html)). -- Set [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) +- Ensure [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) is set to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) #### 튜닝 diff --git a/docs/ko/hardware/board_support_guide.md b/docs/ko/hardware/board_support_guide.md index 74026b2fc6..ad5dec6778 100644 --- a/docs/ko/hardware/board_support_guide.md +++ b/docs/ko/hardware/board_support_guide.md @@ -33,8 +33,8 @@ Boards that are not compliant with the requirements are [unsupported](#unsupport 6. 다음 내용을 포함하는 적절한 문서: - PX4 핀 정의를 아래에 매핑하는 완전한 핀배열 공개: - 1. 마이크로컨트롤러 핀 - 2. 물리적 외부 커넥터 + 1. 마이크로컨트롤러 핀 + 2. 물리적 외부 커넥터 - A block diagram or full schematic of the main components (sensors, power supply, etc.) that allows to infer software requirements and boot order - A manual of the finished product detailing its use diff --git a/docs/ko/hardware/porting_guide_nuttx.md b/docs/ko/hardware/porting_guide_nuttx.md index 5b46be49b3..4e0c325667 100644 --- a/docs/ko/hardware/porting_guide_nuttx.md +++ b/docs/ko/hardware/porting_guide_nuttx.md @@ -62,30 +62,30 @@ To run `qconfig` you may need to install additional Qt dependencies. 2. 소스 코드를 다운로드하고 기존 대상을 빌드할 수 있는 지 확인합니다. - ```sh - git clone --recursive https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + git clone --recursive https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + make px4_fmu-v5 + ``` 3. 동일한(또는 유사한) CPU 유형을 사용하는 기존 대상을 복사합니다. - 예: STM32F7의 경우 + 예: STM32F7의 경우 - ```sh - mkdir boards/manufacturer - cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 - ``` + ```sh + mkdir boards/manufacturer + cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 + ``` - Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. + Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. Next you need to go through all files under **boards/manufacturer/my-target-v1** and update them according to your board. 1. **firmware.prototype**: update the board ID and name 2. **default.px4board**: update the **VENDOR** and **MODEL** to match the directory names (**my-target-v1**). - 직렬 포트를 설정합니다. + 직렬 포트를 설정합니다. 3. Configure NuttX (**defconfig**) via `make manufacturer_my-target-v1 menuconfig`: Adjust the CPU and chip, configure the peripherals (UART's, SPI, I2C, ADC). 4. **nuttx-config/include/board.h**: Configure the NuttX pins. - 여러 가지 핀 옵션이 있는 주변 장치에서는 NuttX는 핀 정보을 알아야 합니다. - They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). + 여러 가지 핀 옵션이 있는 주변 장치에서는 NuttX는 핀 정보을 알아야 합니다. + They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). 5. **src**: go through all files under **src** and update them as needed, in particular **board_config.h**. 6. **init/rc.board_sensors**: start the sensors that are attached to the board. diff --git a/docs/ko/index.md b/docs/ko/index.md index 0e579b2428..4ae116f0c7 100644 --- a/docs/ko/index.md +++ b/docs/ko/index.md @@ -1,3 +1,8 @@ + +
# PX4 Autopilot 사용자 안내서 @@ -9,17 +14,22 @@ PX4 is the _Professional Autopilot_. 세계 각국에서 활동중인 여러 단체들의 지원을 받을 수 있습니다. PX4는 레이싱 드론, 운송용 드론, 자동차와 선박 등의 다양한 운송체에 적용하여 사용할 수 있습니다. :::tip -This guide contains everything you need to assemble, configure, and safely fly a PX4-based vehicle. 이 프로젝트에 기여하시려면, Check out the [Development](development/development.md) section. - +This guide contains everything you need to assemble, configure, and safely fly a PX4-based vehicle. +이 프로젝트에 기여하시려면, Check out the [Development](development/development.md) section. ::: +
+ :::warning + This guide is for the _development_ version of PX4 (`main` branch). Use the **Version** selector to find the current _stable_ version. Documented changes since the stable release are captured in the evolving [release note](releases/main.md). ::: +
+ ## 시작하기 [Basic Concepts](getting_started/px4_basic_concepts.md) should be read by all users! diff --git a/docs/ko/mavlink/standard_modes.md b/docs/ko/mavlink/standard_modes.md index 404e8e97c8..f04314dafd 100644 --- a/docs/ko/mavlink/standard_modes.md +++ b/docs/ko/mavlink/standard_modes.md @@ -2,7 +2,7 @@ -PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.md) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). +PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.html) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). The protocol allows you to discover all flight modes available to the vehicle, including PX4 External modes created using the [PX4 ROS 2 Control Interface](../ros2/px4_ros2_control_interface.md), and get or set the current mode. diff --git a/docs/ko/middleware/dds_topics.md b/docs/ko/middleware/dds_topics.md index 5bcfb87d5d..95784b2227 100644 --- a/docs/ko/middleware/dds_topics.md +++ b/docs/ko/middleware/dds_topics.md @@ -10,32 +10,35 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git ## Publications -| Topic | 형식 | Rate Limit | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | -| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | -| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | -| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | -| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | -| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | -| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | -| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | -| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | -| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | -| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | -| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | -| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | -| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | | -| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | -| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | -| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | -| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | -| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | -| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | | -| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | -| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | -| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | -| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| Topic | 형식 | Rate Limit | +| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | +| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | +| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | +| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | +| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | +| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | +| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | +| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | +| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | +| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | +| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | +| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | +| `/fmu/out/transponder_report` | [px4_msgs::msg::TransponderReport](../msg_docs/TransponderReport.md) | | +| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | +| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | 50.0 | +| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | +| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | +| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | +| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | +| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | +| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | 100.0 | +| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | +| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | +| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | +| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| `/fmu/out/wind` | [px4_msgs::msg::Wind](../msg_docs/Wind.md) | 1.0 | +| `/fmu/out/gimbal_device_attitude_status` | [px4_msgs::msg::GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) | 20.0 | ## Subscriptions @@ -72,6 +75,13 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git | /fmu/in/fixed_wing_lateral_setpoint | [px4_msgs::msg::FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) | | /fmu/in/longitudinal_control_configuration | [px4_msgs::msg::LongitudinalControlConfiguration](../msg_docs/LongitudinalControlConfiguration.md) | | /fmu/in/lateral_control_configuration | [px4_msgs::msg::LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) | +| /fmu/in/rover_position_setpoint | [px4_msgs::msg::RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | +| /fmu/in/rover_speed_setpoint | [px4_msgs::msg::RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | +| /fmu/in/rover_attitude_setpoint | [px4_msgs::msg::RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | +| /fmu/in/rover_rate_setpoint | [px4_msgs::msg::RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | +| /fmu/in/rover_throttle_setpoint | [px4_msgs::msg::RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | +| /fmu/in/rover_steering_setpoint | [px4_msgs::msg::RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| /fmu/in/landing_gear | [px4_msgs::msg::LandingGear](../msg_docs/LandingGear.md) | ## Subscriptions Multi @@ -85,193 +95,192 @@ They are not build into the module, and hence are neither published or subscribe :::details See messages -- [SensorCorrection](../msg_docs/SensorCorrection.md) -- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) -- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) -- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) -- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) -- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) -- [Px4ioStatus](../msg_docs/Px4ioStatus.md) -- [SatelliteInfo](../msg_docs/SatelliteInfo.md) -- [GeofenceResult](../msg_docs/GeofenceResult.md) -- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) -- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) -- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) -- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) -- [EventV0](../msg_docs/EventV0.md) -- [QshellRetval](../msg_docs/QshellRetval.md) -- [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) -- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) -- [RcChannels](../msg_docs/RcChannels.md) -- [SensorAccel](../msg_docs/SensorAccel.md) -- [GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) -- [EscStatus](../msg_docs/EscStatus.md) -- [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) -- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) -- [AirspeedWind](../msg_docs/AirspeedWind.md) -- [InputRc](../msg_docs/InputRc.md) -- [GpioIn](../msg_docs/GpioIn.md) -- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) -- [VehicleImu](../msg_docs/VehicleImu.md) -- [Event](../msg_docs/Event.md) -- [SensorUwb](../msg_docs/SensorUwb.md) -- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) -- [DatamanResponse](../msg_docs/DatamanResponse.md) -- [OrbTest](../msg_docs/OrbTest.md) -- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) -- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) -- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) -- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) -- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [BatteryInfo](../msg_docs/BatteryInfo.md) - [TakeoffStatus](../msg_docs/TakeoffStatus.md) -- [UlogStreamAck](../msg_docs/UlogStreamAck.md) -- [OrbTestLarge](../msg_docs/OrbTestLarge.md) -- [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) +- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md) +- [Airspeed](../msg_docs/Airspeed.md) +- [PpsCapture](../msg_docs/PpsCapture.md) +- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) - [CameraCapture](../msg_docs/CameraCapture.md) -- [VehicleRoi](../msg_docs/VehicleRoi.md) -- [ActuatorArmed](../msg_docs/ActuatorArmed.md) -- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) -- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) -- [GeofenceStatus](../msg_docs/GeofenceStatus.md) -- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) -- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) -- [PowerMonitor](../msg_docs/PowerMonitor.md) -- [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) -- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) -- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) -- [TecsStatus](../msg_docs/TecsStatus.md) -- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) -- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) -- [Ping](../msg_docs/Ping.md) -- [LedControl](../msg_docs/LedControl.md) -- [Wind](../msg_docs/Wind.md) -- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) -- [ActuatorTest](../msg_docs/ActuatorTest.md) -- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) -- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) -- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) -- [Gripper](../msg_docs/Gripper.md) -- [SensorMag](../msg_docs/SensorMag.md) -- [DebugValue](../msg_docs/DebugValue.md) -- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) -- [RcParameterMap](../msg_docs/RcParameterMap.md) -- [LandingGear](../msg_docs/LandingGear.md) -- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) +- [Px4ioStatus](../msg_docs/Px4ioStatus.md) +- [FuelTankStatus](../msg_docs/FuelTankStatus.md) +- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) - [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md) -- [UlogStream](../msg_docs/UlogStream.md) -- [GimbalControls](../msg_docs/GimbalControls.md) -- [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) -- [LogMessage](../msg_docs/LogMessage.md) -- [RoverVelocitySetpoint](../msg_docs/RoverVelocitySetpoint.md) +- [AirspeedWind](../msg_docs/AirspeedWind.md) +- [OrbTest](../msg_docs/OrbTest.md) +- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) - [GpioOut](../msg_docs/GpioOut.md) -- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) +- [Gripper](../msg_docs/Gripper.md) +- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [TuneControl](../msg_docs/TuneControl.md) +- [DebugVect](../msg_docs/DebugVect.md) +- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) +- [HomePositionV0](../msg_docs/HomePositionV0.md) +- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) +- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) +- [EstimatorBias](../msg_docs/EstimatorBias.md) +- [GpioConfig](../msg_docs/GpioConfig.md) +- [SystemPower](../msg_docs/SystemPower.md) +- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) +- [MissionResult](../msg_docs/MissionResult.md) +- [PowerButtonState](../msg_docs/PowerButtonState.md) +- [EscStatus](../msg_docs/EscStatus.md) +- [HealthReport](../msg_docs/HealthReport.md) +- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) +- [SensorGyro](../msg_docs/SensorGyro.md) +- [GpioRequest](../msg_docs/GpioRequest.md) +- [DebugKeyValue](../msg_docs/DebugKeyValue.md) +- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) +- [ParameterUpdate](../msg_docs/ParameterUpdate.md) +- [SensorAirflow](../msg_docs/SensorAirflow.md) +- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) +- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) +- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) +- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) +- [ActionRequest](../msg_docs/ActionRequest.md) +- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) +- [PwmInput](../msg_docs/PwmInput.md) +- [PowerMonitor](../msg_docs/PowerMonitor.md) +- [Mission](../msg_docs/Mission.md) +- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) +- [FigureEightStatus](../msg_docs/FigureEightStatus.md) +- [RadioStatus](../msg_docs/RadioStatus.md) +- [VehicleRoi](../msg_docs/VehicleRoi.md) +- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) +- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) +- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) +- [Rpm](../msg_docs/Rpm.md) +- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) +- [Ping](../msg_docs/Ping.md) +- [QshellReq](../msg_docs/QshellReq.md) +- [SensorMag](../msg_docs/SensorMag.md) +- [EstimatorStates](../msg_docs/EstimatorStates.md) +- [SensorUwb](../msg_docs/SensorUwb.md) +- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) +- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) +- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) +- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) +- [SensorHygrometer](../msg_docs/SensorHygrometer.md) +- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) +- [AdcReport](../msg_docs/AdcReport.md) +- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md) +- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) +- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) +- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) +- [SensorCorrection](../msg_docs/SensorCorrection.md) +- [UlogStream](../msg_docs/UlogStream.md) +- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) +- [GpsInjectData](../msg_docs/GpsInjectData.md) +- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) +- [LoggerStatus](../msg_docs/LoggerStatus.md) +- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) +- [SensorBaro](../msg_docs/SensorBaro.md) +- [OrbTestMedium](../msg_docs/OrbTestMedium.md) +- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) +- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) +- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) +- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) +- [UlogStreamAck](../msg_docs/UlogStreamAck.md) +- [DatamanRequest](../msg_docs/DatamanRequest.md) +- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) +- [PositionSetpoint](../msg_docs/PositionSetpoint.md) +- [DatamanResponse](../msg_docs/DatamanResponse.md) +- [LedControl](../msg_docs/LedControl.md) +- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) +- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md) +- [Event](../msg_docs/Event.md) +- [ActuatorArmed](../msg_docs/ActuatorArmed.md) +- [GpioIn](../msg_docs/GpioIn.md) +- [SensorGyroFft](../msg_docs/SensorGyroFft.md) +- [SensorAccel](../msg_docs/SensorAccel.md) +- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) +- [GeneratorStatus](../msg_docs/GeneratorStatus.md) +- [DifferentialPressure](../msg_docs/DifferentialPressure.md) +- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) +- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) +- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) +- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) +- [RoverRateStatus](../msg_docs/RoverRateStatus.md) +- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) +- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) - [VelocityLimits](../msg_docs/VelocityLimits.md) - [MagWorkerData](../msg_docs/MagWorkerData.md) -- [ParameterUpdate](../msg_docs/ParameterUpdate.md) -- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) -- [SensorBaro](../msg_docs/SensorBaro.md) -- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) -- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) -- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) -- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) -- [Rpm](../msg_docs/Rpm.md) -- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) -- [MountOrientation](../msg_docs/MountOrientation.md) -- [ActionRequest](../msg_docs/ActionRequest.md) -- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) -- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) -- [LoggerStatus](../msg_docs/LoggerStatus.md) -- [GeneratorStatus](../msg_docs/GeneratorStatus.md) -- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) -- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) -- [LandingTargetPose](../msg_docs/LandingTargetPose.md) -- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) -- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) -- [OrbitStatus](../msg_docs/OrbitStatus.md) -- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) -- [EstimatorStatus](../msg_docs/EstimatorStatus.md) -- [DatamanRequest](../msg_docs/DatamanRequest.md) -- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) -- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) -- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) - [Cpuload](../msg_docs/Cpuload.md) -- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) -- [RoverRateStatus](../msg_docs/RoverRateStatus.md) -- [EscReport](../msg_docs/EscReport.md) -- [DebugArray](../msg_docs/DebugArray.md) -- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) -- [SensorHygrometer](../msg_docs/SensorHygrometer.md) -- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) -- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) -- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) -- [QshellReq](../msg_docs/QshellReq.md) -- [CameraStatus](../msg_docs/CameraStatus.md) -- [GpsInjectData](../msg_docs/GpsInjectData.md) -- [FigureEightStatus](../msg_docs/FigureEightStatus.md) -- [TransponderReport](../msg_docs/TransponderReport.md) -- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) +- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) - [MavlinkLog](../msg_docs/MavlinkLog.md) -- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) -- [FuelTankStatus](../msg_docs/FuelTankStatus.md) -- [Mission](../msg_docs/Mission.md) -- [PositionSetpoint](../msg_docs/PositionSetpoint.md) -- [MissionResult](../msg_docs/MissionResult.md) -- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) -- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) -- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) -- [DifferentialPressure](../msg_docs/DifferentialPressure.md) -- [CellularStatus](../msg_docs/CellularStatus.md) -- [GpsDump](../msg_docs/GpsDump.md) -- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) -- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) -- [NavigatorStatus](../msg_docs/NavigatorStatus.md) -- [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) -- [FollowTarget](../msg_docs/FollowTarget.md) -- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) -- [EstimatorStates](../msg_docs/EstimatorStates.md) -- [SensorGyro](../msg_docs/SensorGyro.md) -- [SensorAirflow](../msg_docs/SensorAirflow.md) -- [ButtonEvent](../msg_docs/ButtonEvent.md) -- [DebugKeyValue](../msg_docs/DebugKeyValue.md) -- [GpioConfig](../msg_docs/GpioConfig.md) -- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [SensorTemp](../msg_docs/SensorTemp.md) - [LandingGearWheel](../msg_docs/LandingGearWheel.md) -- [VehicleConstraints](../msg_docs/VehicleConstraints.md) -- [HealthReport](../msg_docs/HealthReport.md) -- [PowerButtonState](../msg_docs/PowerButtonState.md) -- [RadioStatus](../msg_docs/RadioStatus.md) -- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) -- [EstimatorBias](../msg_docs/EstimatorBias.md) -- [DebugVect](../msg_docs/DebugVect.md) -- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) -- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) -- [PpsCapture](../msg_docs/PpsCapture.md) -- [SensorSelection](../msg_docs/SensorSelection.md) -- [SystemPower](../msg_docs/SystemPower.md) -- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) -- [SensorGyroFft](../msg_docs/SensorGyroFft.md) -- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [OrbTestLarge](../msg_docs/OrbTestLarge.md) - [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md) -- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) -- [GpioRequest](../msg_docs/GpioRequest.md) -- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) -- [RtlStatus](../msg_docs/RtlStatus.md) -- [Airspeed](../msg_docs/Airspeed.md) -- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) -- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) -- [IrlockReport](../msg_docs/IrlockReport.md) -- [HeaterStatus](../msg_docs/HeaterStatus.md) -- [AdcReport](../msg_docs/AdcReport.md) -- [PwmInput](../msg_docs/PwmInput.md) -- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) -- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) -- [OrbTestMedium](../msg_docs/OrbTestMedium.md) -- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) -- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) -- [TuneControl](../msg_docs/TuneControl.md) -- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [CellularStatus](../msg_docs/CellularStatus.md) +- [QshellRetval](../msg_docs/QshellRetval.md) +- [OrbitStatus](../msg_docs/OrbitStatus.md) +- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) +- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) +- [LogMessage](../msg_docs/LogMessage.md) +- [SatelliteInfo](../msg_docs/SatelliteInfo.md) +- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) +- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) +- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) +- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md) +- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) +- [EstimatorStatus](../msg_docs/EstimatorStatus.md) +- [NeuralControl](../msg_docs/NeuralControl.md) +- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [RcParameterMap](../msg_docs/RcParameterMap.md) +- [SensorSelection](../msg_docs/SensorSelection.md) +- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) +- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) +- [ActuatorTest](../msg_docs/ActuatorTest.md) +- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) +- [MountOrientation](../msg_docs/MountOrientation.md) +- [CameraStatus](../msg_docs/CameraStatus.md) - [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md) -- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) -- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [FollowTarget](../msg_docs/FollowTarget.md) +- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) +- [ButtonEvent](../msg_docs/ButtonEvent.md) +- [DebugArray](../msg_docs/DebugArray.md) +- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) +- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) +- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) +- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) +- [VehicleImu](../msg_docs/VehicleImu.md) +- [GpsDump](../msg_docs/GpsDump.md) +- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) +- [DebugValue](../msg_docs/DebugValue.md) +- [LandingTargetPose](../msg_docs/LandingTargetPose.md) +- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) +- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) +- [RtlStatus](../msg_docs/RtlStatus.md) +- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) +- [GimbalControls](../msg_docs/GimbalControls.md) +- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) +- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) +- [HeaterStatus](../msg_docs/HeaterStatus.md) +- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [RcChannels](../msg_docs/RcChannels.md) +- [TecsStatus](../msg_docs/TecsStatus.md) +- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) +- [InputRc](../msg_docs/InputRc.md) +- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) +- [GeofenceResult](../msg_docs/GeofenceResult.md) +- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) +- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) +- [NavigatorStatus](../msg_docs/NavigatorStatus.md) +- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [EscReport](../msg_docs/EscReport.md) +- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) +- [GeofenceStatus](../msg_docs/GeofenceStatus.md) +- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) +- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) +- [EventV0](../msg_docs/EventV0.md) +- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md) +- [VehicleConstraints](../msg_docs/VehicleConstraints.md) +- [IrlockReport](../msg_docs/IrlockReport.md) ::: diff --git a/docs/ko/middleware/uorb.md b/docs/ko/middleware/uorb.md index 5dab1582fa..1928f9acf5 100644 --- a/docs/ko/middleware/uorb.md +++ b/docs/ko/middleware/uorb.md @@ -280,6 +280,8 @@ For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggl ## See Also +- [uORB Documentation Standard](../uorb/uorb_documentation.md) + - _PX4 uORB Explained_ Blog series - [Part 1](https://px4.io/px4-uorb-explained-part-1/) - [Part 2](https://px4.io/px4-uorb-explained-part-2/) diff --git a/docs/ko/middleware/uxrce_dds.md b/docs/ko/middleware/uxrce_dds.md index d9d83d1f48..b1f4a3b284 100644 --- a/docs/ko/middleware/uxrce_dds.md +++ b/docs/ko/middleware/uxrce_dds.md @@ -65,7 +65,7 @@ PX4 Micro XRCE-DDS Client is based on version `v2.x` which is not compatible wit On Ubuntu you can build from source and install the Agent standalone using the following commands: ```sh -git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git +git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build @@ -106,90 +106,146 @@ The development version, fetched using `--edge` above, does work. ### Build/Run within ROS 2 Workspace -The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace. +The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace). You must already have installed ROS 2 following the instructions in: [ROS 2 User Guide > Install ROS 2](../ros2/user_guide.md#install-ros-2). :::warning This approach will use the existing ROS 2 versions of the Agent dependencies, such as `fastcdr` and `fastdds`. -This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones. +This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones: + +| ROS 2 version | Micro-XRCE-DDS-Agent version | +| ------------- | -------------------------------------- | +| Foxy | v2.4.2 | +| Humble | v2.4.2 | +| Jazzy | v2.4.3 | + ::: To build the agent within ROS: 1. Create a workspace directory for the agent: - ```sh - mkdir -p ~/px4_ros_uxrce_dds_ws/src - ``` + ```sh + mkdir -p ~/px4_ros_uxrce_dds_ws/src + ``` 2. Clone the source code for the eProsima [Micro-XRCE-DDS-Agent](https://github.com/eProsima/Micro-XRCE-DDS-Agent) to the `/src` directory (the `main` branch is cloned by default): - ```sh - cd ~/px4_ros_uxrce_dds_ws/src - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - ``` + ::::tabs + + ::: tab jazzy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab humble + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab foxy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + :::: 3. Source the ROS 2 development environment, and compile the workspace using `colcon`: - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + source /opt/ros/jazzy/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - :::: + ::: tab foxy - This builds all the folders under `/src` using the sourced toolchain. + ```sh + source /opt/ros/foxy/setup.bash + colcon build + ``` + + +::: + + :::: + + This builds all the folders under `/src` using the sourced toolchain. To run the micro XRCE-DDS agent in the workspace: 1. Source the `local_setup.bash` to make the executables available in the terminal (also `setup.bash` if using a new terminal). - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/jazzy/setup.bash + source install/local_setup.bash + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/humble/setup.bash + source install/local_setup.bash + ``` ::: - :::: + ::: tab foxy + + ```sh + source /opt/ros/foxy/setup.bash + source install/local_setup.bash + ``` + + +::: + + :::: 1) Start the agent with settings for connecting to the uXRCE-DDS client running on the simulator: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` ## Starting Agent and Client @@ -235,7 +291,6 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_CFG](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG): Set the port to connect on, such as `TELEM2`, `Ethernet`, or `Wifi`. - If using an Ethernet connection: - - [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT): Use this to specify the agent UDP listening port. The default value is `8888`. @@ -259,14 +314,12 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi ``` - If using a serial connection: - - [SER_TEL2_BAUD](../advanced_config/parameter_reference.md#SER_TEL2_BAUD), [SER_URT6_BAUD](../advanced_config/parameter_reference.md#SER_URT6_BAUD) (and so on): Use the `_BAUD` parameter associated with the serial port to set the baud rate. For example, you'd set a value for `SER_TEL2_BAUD` if you are connecting to the companion using `TELEM2`. For more information see [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration). - Some setups might also need these parameters to be set: - - [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): The uXRCE-DDS key. If you're working in a multi-client, single agent configuration, each client should have a unique non-zero key. This is primarily important for multi-vehicle simulations, where all clients are connected in UDP to the same agent. @@ -279,6 +332,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge. This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. + Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. + See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -354,7 +412,7 @@ Therefore, ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)) or at runtime (which is useful for multi vehicle operations): +Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)), at runtime, or through a parameter (which is useful for multi vehicle operations): - One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. This technique can be used both in simulation and real vehicles. @@ -383,6 +441,23 @@ will generate topics under the namespaces: ::: +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. + This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. + This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. + +:::info +PX4 parameters cannot carry rich text strings. +Therefore, you cannot use [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to automatically start a client with an arbitrary message namespace through PX4. +You can however specify a namespace when starting the client, using the `-n` argument: + +```sh +# In etc/extras.txt on the MicroSD card +uxrce_dds_client start -n fancy_uav +``` + +This can be included in `etc/extras.txt` as part of a custom [System Startup](../concept/system_startup.md). +::: + ## PX4 ROS 2 QoS Settings PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers. @@ -443,6 +518,11 @@ publications: - topic: /fmu/out/vehicle_trajectory_waypoint_desired type: px4_msgs::msg::VehicleTrajectoryWaypoint + - topic: /fmu/out/vehicle_imu + type: px4_msgs::msg::VehicleImu + rate_limit: 50. + instance: 1 # OPTIONAL + subscriptions: - topic: /fmu/in/offboard_control_mode @@ -466,15 +546,18 @@ Each (`topic`,`type`) pairs defines: 1. A new `publication`, `subscription`, or `subscriptions_multi`, depending on the list to which it is added. 2. The topic _base name_, which **must** coincide with the desired uORB topic name that you want to publish/subscribe. - It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. - `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. + It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. + `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. 3. The topic [namespace](https://design.ros2.org/articles/topic_and_service_names.html#namespaces). - By default it is set to: - - `/fmu/out/` for topics that are _published_ by PX4. - - `/fmu/in/` for topics that are _subscribed_ by PX4. + By default it is set to: + - `/fmu/out/` for topics that are _published_ by PX4. + - `/fmu/in/` for topics that are _subscribed_ by PX4. 4. The message type (`VehicleOdometry`, `VehicleStatus`, `OffboardControlMode`, etc.) and the ROS 2 package (`px4_msgs`) that is expected to provide the message definition. 5. **(Optional)**: An additional `rate_limit` field (only for publication entries), which specifies the maximum rate (Hz) at which messages will be published on this topic by PX4 to ROS 2. - If left unspecified, the maximum publication rate limit is set to 100 Hz. + If left unspecified, the maximum publication rate limit is set to 100 Hz. +6. **(Optional)**: An additional `instance` field (only for publication entries), which lets you select which instance of a [multi-instance topic](./uorb.md#multi-instance) you want to be published to ROS 2. + If provided, this option changes the ROS 2 topic name of the advertised uORB topic appending the instance number: `fmu/out/[uorb topic name][instance]` (plus eventual namespace and message version). + In the example above the final topic name would be `/fmu/out/vehicle_imu1`. `subscriptions` and `subscriptions_multi` allow us to choose the uORB topic instance that ROS 2 topics are routed to: either a shared instance that may also be getting updates from internal PX4 uORB publishers, or a separate instance that is reserved for ROS2 publications, respectively. Without this mechanism all ROS 2 messages would be routed to the _same_ uORB topic instance (because ROS 2 does not have the concept of [multiple topic instances](../middleware/uorb.md#multi-instance)), and it would not be possible for PX4 subscribers to differentiate between streams from ROS 2 or PX4 publishers. diff --git a/docs/ko/middleware/zenoh.md b/docs/ko/middleware/zenoh.md new file mode 100644 index 0000000000..71ca88d941 --- /dev/null +++ b/docs/ko/middleware/zenoh.md @@ -0,0 +1,201 @@ +# Zenoh (PX4 ROS 2 rmw_zenoh) + + + +:::warning +실험 +At the time of writing, PX4 Zenoh-pico is experimental, and hence subject to change. +::: + +PX4 supports Zenoh as an alternative mechanism (to DDS) for bridging uORB topics to [ROS 2](../ros2/user_guide.md) (via the ROS 2 [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh) middleware). +This allows uORB messages to be published and subscribed on a companion computer as though they were ROS 2 topics. +It provides a fast and lightweight way to connect PX4 to ROS 2, making it easier for applications to access vehicle telemetry and send control commands. + +The following guide describes the architecture and various options for setting up the Zenoh client and router. +In particular, it covers the options that are most important to PX4 users exploring Zenoh as an alternative communication layer for ROS 2. + +## 아키텍쳐 + +The Zenoh-based middleware consists of a client running on PX4 and a Zenoh router running on the companion computer, with bi-directional data exchange between them over a UART, TCP, UDP, or multicast-UDP link. +The router acts as a broker and discovery service, enabling PX4 to publish and subscribe to topics in the global Zenoh data space. +This allows seamless integration with ROS 2 nodes using [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh), and supports flexible deployment across distributed systems. + +![Architecture PX4 Zenoh-Pico with ROS 2](../../assets/middleware/zenoh/architecture-px4-zenoh.svg) + +The client is the _PX4 Zenoh-Pico Node_ referred to above, which is implemented in the [PX4 `zenoh` module](../modules/modules_driver.md#zenoh). +This is based on Zenoh-Pico, a minimalistic version of [Eclipse Zenoh](https://zenoh.io/) (a data-centric protocol designed for real-time, distributed, and resource-constrained environments). + +The router suggested above is [zenohd](https://github.com/eclipse-zenoh/zenoh/tree/main/zenohd). + +:::info +UART is supported by Zenoh but has not yet implemented in the PX4 Zenoh-Pico node. +::: + +## ROS 2 Zenoh Bring-up on Linux Companion + +In order for PX4 uORB topics to be shared with ROS 2 applications, you will need the PX4 Zenoh-Pico Node client running on your FMU, connected to a Zenoh router running on the companion computer (or elsewhere in the network). + +First select Zenoh as the ROS 2 transport by setting the `RMW_IMPLEMENTATION` environment variable as shown: + +```sh +export RMW_IMPLEMENTATION=rmw_zenoh_cpp +``` + +Then start the Zenoh router using the command: + +```sh +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +For more information about the Zenoh Router see the [rmw_zenoh](https://github.com/ros2/rmw_zenoh?tab=readme-ov-file#start-the-zenoh-router) documentation. + +## PX4 Zenoh-Pico Node Setup + +### PX4 Firmware + +Before setting up the Zenoh communication, first make sure that your firmware contains the driver that implements the [`zenoh` driver](../modules/modules_driver.md#zenoh), which provides the implementation of the _PX4 Zenoh-Pico Node_. + +You can check if the module is present on your board by searching for the key `CONFIG_MODULES_ZENOH=y` in your board's `default.px4board` KConfig file. +For example, you can see that the module is present in `px4_fmu-v6xrt` build targets from [/boards/px4/fmu-v6xrt/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#L91). + +If `CONFIG_MODULES_ZENOH=y` is not preset you can add this key to your board configuration and rebuild. +Note that due to flash constraints you may need to remove other components in order to include the module (such as the [`uxrce_dds_client` module](../modules/modules_system.md#uxrce-dds-client), which you will not need if you are using Zenoh). + +The table below shows some of the PX4 targets that include Zenoh by default. + +| PX4 Target | 참고 | +| ---------------------- | -------------------------------------------------------------------------------------------------------------- | +| `px4_fmu-v6xrt` | For [FMUv6X-RT](../flight_controller/nxp_mr_vmu_rt1176.md) (reference platform for testing) | +| `nxp_tropic-community` | | +| `nxp_mr-tropic` | | +| `nxp_mr-canhubk344` | | +| `px4_sitl_zenoh` | Zenoh-enabled simulation build | +| `px4_fmu-v6x_zenoh` | Zenoh-enabled firmware for FMUv6X | + +Zenoh is not included in the default `px4_fmu-` targets for any firmware other than `px4_fmu-v6xrt` (`px4_sitl_zenoh` and `px4_fmu-v6x_zenoh` [are build variants](../dev_setup/building_px4.md#px4-make-build-targets)). + +:::tip +You can check if Zenoh is present at runtime by using QGroundControl to [find the parameter](../advanced_config/parameters.md#finding-a-parameter) [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE). +If present, the module is installed. +::: + +### Enable Zenoh on PX4 Startup + +Set the [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE) parameter to `1` to enable Zenoh on PX4 startup. + +### Configure Zenoh Network + +Set up PX4 to connect to the companion computer running `zenohd`. + +PX4's default IP address of the Zenoh daemon host is `10.41.10.1`. +If you're using a different IP for the Zenoh daemon, run the following command (replacing the address) in a PX4 shell and then reboot: + +```sh +zenoh config net client tcp/10.41.10.1:7447#iface=eth0 +``` + +Note that for the simulation target with Zeroh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. + +:::warning +Any changes to the network configuration require a PX4 system reboot to take effect. +::: + +:::tip +See [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) for more information about Ethernet configuration. +::: + +### PX4 Zenoh-pico Node configuration + +The **default configuration** is auto-generated from the [dds_topics.yaml](../middleware/dds_topics.md) file in the PX4 repository. +This file specifies which uORB message definitions are to be published/subscribed by ROS 2 applications, and hence (indirectly) which topics are compiled into the zenoh module. + +To inspect the current Zenoh configuration: + +```sh +zenoh config +``` + +The PX4 Zenoh-pico node stores its configuration on the **SD card** under the `zenoh` folder. +This folder contains three key files: + +- **`net.txt`** – Defines the **Zenoh network configuration**. +- **`pub.csv`** – Maps **uORB topics to ROS2 topics** (used for publishing). +- **`sub.csv`** – Maps **ROS2 topics to uORB topics** (used for subscribing). + +### 4. Modifying Topic Mappings + +Zenoh topic mappings define how data flows between PX4's internal uORB topics and external ROS2 topics via Zenoh. +These mappings are stored in `pub.csv` and `sub.csv` on the SD card, and can be modified at runtime using the `zenoh config` CLI tool. + +:::warning +Any changes to the topic mappings require a PX4 system reboot to take effect. +::: + +There are two types of mappings you can modify: + +- **Publisher mappings**: Forward data from a uORB topic to a Zenoh topic. +- **Subscriber mappings**: Receive data from a Zenoh topic and publish it to a uORB topic. + +The main operations and their commands are: + +- Publish a uORB topic to a Zenoh topic: + + ```sh + zenoh config add publisher [uorb_instance] + ``` + +- Subscribe to a Zenoh topic and forward it to a uORB topic: + + ```sh + zenoh config add subscriber [uorb_instance] + ``` + +- Remove existing mappings: + + ```sh + zenoh config delete publisher + zenoh config delete subscriber + ``` + +After modifying the mappings, reboot PX4 to apply the changes. +The updated configuration will be loaded from the SD card during startup. + +## Communicating with PX4 from ROS 2 via Zenoh + +Once your PX4 FMU is publishing data into ROS 2, you can inspect the available topics and their contents using standard ROS 2 CLI tools: + +```sh +ros2 topic list +``` + +Check topic type and publishers/subscribers: + +```sh +ros2 topic info -v /fmu/out/vehicle_status +Type: px4_msgs/msg/VehicleStatus + +Publisher count: 1 + +Node name: px4_aabbcc00000000000000000000000000 +Node namespace: / +Topic type: px4_msgs/msg/VehicleStatus +Topic type hash: RIHS01_828bddbb7d4c2aa6ad93757955f6893be1ec5d8f11885ec7715bcdd76b5226c9 +Endpoint type: PUBLISHER +GID: 82.99.74.2c.b6.7d.93.44.91.4d.fe.14.93.58.40.16 +QoS profile: + Reliability: RELIABLE + History (Depth): KEEP_LAST (7) + Durability: VOLATILE + Lifespan: Infinite + Deadline: Infinite + Liveliness: AUTOMATIC + Liveliness lease duration: Infinite + +Subscription count: 0 +``` + +### PX4 ROS 2 Interface with Zenoh + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) works out of the box with Zenoh as a transport backend. +This means you can publish and subscribe to PX4 topics over Zenoh without changing your ROS 2 nodes or dealing with DDS configuration. +For setup details and supported message types, refer to the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). diff --git a/docs/ko/modules/hello_sky.md b/docs/ko/modules/hello_sky.md index f32e85ec7b..58e6469aa5 100644 --- a/docs/ko/modules/hello_sky.md +++ b/docs/ko/modules/hello_sky.md @@ -28,151 +28,155 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 1. Create a new directory **PX4-Autopilot/src/examples/px4_simple_app**. 2. Create a new C file in that directory named **px4_simple_app.c**: - - 기본 헤더를 페이지 상단에 복사합니다. - 이것은 기여한 모든 파일에 첨부하여야 합니다. + - 기본 헤더를 페이지 상단에 복사합니다. + 이것은 기여한 모든 파일에 첨부하여야 합니다. - ```c - /**************************************************************************** - * - * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - ``` + ```c + /**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + ``` - - 기본 헤더 아래에 다음 코드를 복사합니다. - 이것은 기여한 모든 파일에 첨부하여야 합니다. + - 기본 헤더 아래에 다음 코드를 복사합니다. + 이것은 기여한 모든 파일에 첨부하여야 합니다. - ```c - /** - * @file px4_simple_app.c - * Minimal application example for PX4 autopilot - * - * @author Example User - */ + ```c + /** + * @file px4_simple_app.c + * Minimal application example for PX4 autopilot + * + * @author Example User + */ - #include + #include - __EXPORT int px4_simple_app_main(int argc, char *argv[]); + __EXPORT int px4_simple_app_main(int argc, char *argv[]); - int px4_simple_app_main(int argc, char *argv[]) - { - PX4_INFO("Hello Sky!"); - return OK; - } - ``` + int px4_simple_app_main(int argc, char *argv[]) + { + PX4_INFO("Hello Sky!"); + return OK; + } + ``` + + :::tip + + The main function must be named `_main` and exported from the module as shown. - :::tip - The main function must be named `_main` and exported from the module as shown. ::: - :::tip - `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). - There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. - Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + :::tip + + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). + There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. + Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 3. Create and open a new _cmake_ definition file named **CMakeLists.txt**. - 아래 텍스트를 복사하십시오. + 아래 텍스트를 복사하십시오. - ```cmake - ############################################################################ - # - # Copyright (c) 2015 PX4 Development Team. All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions - # are met: - # - # 1. Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # 2. Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in - # the documentation and/or other materials provided with the - # distribution. - # 3. Neither the name PX4 nor the names of its contributors may be - # used to endorse or promote products derived from this software - # without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - # POSSIBILITY OF SUCH DAMAGE. - # - ############################################################################ - px4_add_module( - MODULE examples__px4_simple_app - MAIN px4_simple_app - STACK_MAIN 2000 - SRCS - px4_simple_app.c - DEPENDS - ) - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2015 PX4 Development Team. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in + # the documentation and/or other materials provided with the + # distribution. + # 3. Neither the name PX4 nor the names of its contributors may be + # used to endorse or promote products derived from this software + # without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + ############################################################################ + px4_add_module( + MODULE examples__px4_simple_app + MAIN px4_simple_app + STACK_MAIN 2000 + SRCS + px4_simple_app.c + DEPENDS + ) + ``` - The `px4_add_module()` method builds a static library from a module description. + The `px4_add_module()` method builds a static library from a module description. - - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). - - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. + - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). + - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. - :::tip - The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). + :::tip + The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). ::: - ::: info - If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). - Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. - You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` + ::: info + If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). + Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. + You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` ::: 4. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). - 아래 텍스트를 복사하십시오. + 아래 텍스트를 복사하십시오. - ``` - menuconfig EXAMPLES_PX4_SIMPLE_APP - bool "px4_simple_app" - default n - ---help--- - Enable support for px4_simple_app - ``` + ```text + menuconfig EXAMPLES_PX4_SIMPLE_APP + bool "px4_simple_app" + default n + ---help--- + Enable support for px4_simple_app + ``` ## 애플리케이션/펌웨어 빌드 @@ -440,6 +444,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e */ #include +#include #include #include #include diff --git a/docs/ko/modules/module_template.md b/docs/ko/modules/module_template.md index 67d029f407..761257acc6 100644 --- a/docs/ko/modules/module_template.md +++ b/docs/ko/modules/module_template.md @@ -22,27 +22,27 @@ PX4-Autopilot contains a template for writing a new application (module) that ru 요약 1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)): - ``` - ... - DEPENDS - px4_work_queue - ``` + ``` + ... + DEPENDS + px4_work_queue + ``` 2. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp)) 3. 생성자 초기화에서 작업을 추가할 대기열을 지정합니다. - The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: + The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: - ```cpp - WorkItemExample::WorkItemExample() : - ModuleParams(nullptr), - ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) - { - } - ``` + ```cpp + WorkItemExample::WorkItemExample() : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) + { + } + ``` - ::: info - The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). + ::: info + The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). ::: diff --git a/docs/ko/modules/modules_driver.md b/docs/ko/modules/modules_driver.md index 919f0df5d4..cbcd7b8448 100644 --- a/docs/ko/modules/modules_driver.md +++ b/docs/ko/modules/modules_driver.md @@ -2,6 +2,7 @@ 하위 카테고리: +- [Adc](modules_driver_adc.md) - [Airspeed Sensor](modules_driver_airspeed_sensor.md) - [Baro](modules_driver_baro.md) - [Camera](modules_driver_camera.md) @@ -14,98 +15,6 @@ - [Rpm Sensor](modules_driver_rpm_sensor.md) - [Transponder](modules_driver_transponder.md) -## MCP23009 - -Source: [drivers/gpio/mcp23009](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/gpio/mcp23009) - -### Usage {#MCP23009_usage} - -``` -MCP23009 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 37 - [-D ] Direction - default: 0 - [-O ] Output - default: 0 - [-P ] Pullups - default: 0 - [-U ] Update Interval [ms] - default: 0 - - stop - - status print status info -``` - -## adc - -Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) - -### 설명 - -ADC driver. - -### Usage {#adc_usage} - -``` -adc [arguments...] - Commands: - start - - test - [-n] Do not publish ADC report, only system power - - stop - - status print status info -``` - -## ads1115 - -Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) - -### 설명 - -Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. - -The driver is included by default in firmware for boards that do not have an internal analog to digital converter, -such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) -(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). - -It is enabled/disabled using the -[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) -parameter, and is disabled by default. -If enabled, internal ADCs are not used. - -### Usage {#ads1115_usage} - -``` -ads1115 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 72 - - stop - - status print status info -``` - ## atxxxx Source: [drivers/osd/atxxxx](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/atxxxx) @@ -808,6 +717,64 @@ lsm303agr [arguments...] status print status info ``` +## mcp230xx + +Source: [lib/drivers/mcp_common](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/mcp_common) + +### Usage {#mcp230xx_usage} + +``` +mcp230xx [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 39 + [-D ] Direction (1=Input, 0=Output) + default: 0 + [-O ] Output + default: 0 + [-P ] Pullups + default: 0 + [-U ] Update Interval [ms] + default: 0 + [-M ] First minor number + default: 0 + + stop + + status print status info +``` + +## mcp9808 + +Source: [drivers/temperature_sensor/mcp9808](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/temperature_sensor/mcp9808) + +### Usage {#mcp9808_usage} + +``` +mcp9808 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 24 + + stop + + status print status info +``` + ## msp_osd Source: [drivers/osd/msp_osd](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/msp_osd) diff --git a/docs/ko/modules/modules_driver_adc.md b/docs/ko/modules/modules_driver_adc.md new file mode 100644 index 0000000000..ff15a90fa4 --- /dev/null +++ b/docs/ko/modules/modules_driver_adc.md @@ -0,0 +1,107 @@ +# Modules Reference: Adc (Driver) + +## TLA2528 + +Source: [drivers/adc/tla2528](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/tla2528) + +### Usage {#TLA2528_usage} + +``` +TLA2528 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` + +## adc + +Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) + +### 설명 + +ADC driver. + +### Usage {#adc_usage} + +``` +adc [arguments...] + Commands: + start + + test + [-n] Do not publish ADC report, only system power + + stop + + status print status info +``` + +## ads1115 + +Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) + +### 설명 + +Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. + +The driver is included by default in firmware for boards that do not have an internal analog to digital converter, +such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) +(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). + +It is enabled/disabled using the +[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) +parameter, and is disabled by default. +If enabled, internal ADCs are not used. + +### Usage {#ads1115_usage} + +``` +ads1115 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 72 + + stop + + status print status info +``` + +## ads7953 + +Source: [drivers/adc/ads7953](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads7953) + +### Usage {#ads7953_usage} + +``` +ads7953 [arguments...] + Commands: + start + [-s] Internal SPI bus(es) + [-S] External SPI bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-c ] chip-select pin (for internal SPI) or index (for external SPI) + [-m ] SPI mode + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` diff --git a/docs/ko/modules/modules_driver_distance_sensor.md b/docs/ko/modules/modules_driver_distance_sensor.md index 6e61c2ef42..3d34e69be4 100644 --- a/docs/ko/modules/modules_driver_distance_sensor.md +++ b/docs/ko/modules/modules_driver_distance_sensor.md @@ -104,7 +104,7 @@ Source: [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4 ### 설명 -I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20. +I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20, SF30/d. Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html diff --git a/docs/ko/modules/modules_driver_ins.md b/docs/ko/modules/modules_driver_ins.md index 6b5c8f46ef..ca390b9321 100644 --- a/docs/ko/modules/modules_driver_ins.md +++ b/docs/ko/modules/modules_driver_ins.md @@ -45,6 +45,41 @@ MicroStrain [arguments...] status Driver status ``` +## eulernav_bahrs + +Source: [drivers/ins/eulernav_bahrs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/eulernav_bahrs) + +### 설명 + +Serial bus driver for the EULER-NAV Baro-Inertial AHRS. + +### 예 + +Attempt to start driver on a specified serial device. + +``` +eulernav_bahrs start -d /dev/ttyS1 +``` + +Stop driver + +``` +eulernav_bahrs stop +``` + +### Usage {#eulernav_bahrs_usage} + +``` +eulernav_bahrs [arguments...] + Commands: + start Start driver + -d Serial device + + status Print driver status + + stop Stop driver +``` + ## ilabs Source: [drivers/ins/ilabs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/ilabs) @@ -90,6 +125,31 @@ ilabs [arguments...] status Print driver status ``` +## sbgecom + +Source: [drivers/ins/sbgecom](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/sbgecom) + +Description du module + +### Usage {#sbgecom_usage} + +``` +sbgecom [arguments...] + Commands: + start Start driver + [-d ] Serial device + default: /dev/ttyS0 + [-b ] Baudrate device + default: 921600 + [-f ] Config JSON file path + default: /etc/extras/sbg_settings\.json + [-s ] Config JSON string + + status Driver status + + stop Stop driver +``` + ## vectornav Source: [drivers/ins/vectornav](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/vectornav) diff --git a/docs/ko/modules/modules_driver_radio_control.md b/docs/ko/modules/modules_driver_radio_control.md index c226610884..90ce2f7b85 100644 --- a/docs/ko/modules/modules_driver_radio_control.md +++ b/docs/ko/modules/modules_driver_radio_control.md @@ -17,6 +17,8 @@ crsf_rc [arguments...] [-d ] RC device values: , default: /dev/ttyS3 + inject Inject frame data bytes (for testing) + stop status print status info diff --git a/docs/ko/modules/modules_system.md b/docs/ko/modules/modules_system.md index a62410de31..8be479bba8 100644 --- a/docs/ko/modules/modules_system.md +++ b/docs/ko/modules/modules_system.md @@ -127,6 +127,10 @@ commander [arguments...] check Run preflight checks + safety Change prearm safety state + on|off [on] to activate safety, [off] to deactivate safety and allow + control surface movements + arm [-f] Force arming (do not run preflight checks) @@ -140,9 +144,9 @@ commander [arguments...] transition VTOL transition mode Change flight mode - manual|acro|offboard|stabilized|altctl|posctl|position:slow|auto:mission|au - to:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1 - Flight mode + manual|acro|offboard|stabilized|altctl|posctl|altitude_cruise|position:slow + |auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto: + precland|ext1 Flight mode pair @@ -154,6 +158,9 @@ commander [arguments...] lat|lon|alt Origin latitude longitude altitude + set_heading Set current heading + heading degrees from True North [0 360] + poweroff Power off board (if supported) stop @@ -1062,7 +1069,9 @@ uxrce_dds_client [arguments...] values: [-p ] Agent listening port. If not provided, defaults to UXRCE_DDS_PRT - [-n ] Client DDS namespace + [-n ] Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is + between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will + be used stop diff --git a/docs/ko/msg_docs/ActionRequest.md b/docs/ko/msg_docs/ActionRequest.md index 3579870754..1c724dabb7 100644 --- a/docs/ko/msg_docs/ActionRequest.md +++ b/docs/ko/msg_docs/ActionRequest.md @@ -15,25 +15,25 @@ Request are published by `manual_control` and subscribed by the `commander` and # It allows mapping triggers from various external interfaces like RC channels or MAVLink to cause an action. # Request are published by `manual_control` and subscribed by the `commander` and `vtol_att_control` modules. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint8 action # [@enum ACTION] Requested action -uint8 ACTION_DISARM = 0 # Disarm vehicle -uint8 ACTION_ARM = 1 # Arm vehicle -uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming -uint8 ACTION_UNKILL = 3 # Revert a kill action -uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) -uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. -uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight -uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight -uint8 ACTION_TERMINATION = 8 # Irreversably output failsafe values on all outputs, trigger parachute +uint8 action # [@enum ACTION] Requested action +uint8 ACTION_DISARM = 0 # Disarm vehicle +uint8 ACTION_ARM = 1 # Arm vehicle +uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming +uint8 ACTION_UNKILL = 3 # Revert a kill action +uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) +uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. +uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight +uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight +uint8 ACTION_TERMINATION = 8 # Irreversibly output failsafe values on all outputs, trigger parachute -uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture -uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position -uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position -uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held -uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism +uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture +uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position +uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position +uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held +uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism -uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. +uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. ``` diff --git a/docs/ko/msg_docs/ActuatorMotors.md b/docs/ko/msg_docs/ActuatorMotors.md index 06fbd1b908..701465d6ea 100644 --- a/docs/ko/msg_docs/ActuatorMotors.md +++ b/docs/ko/msg_docs/ActuatorMotors.md @@ -15,14 +15,14 @@ Published by the vehicle's allocation and consumed by the ESC protocol drivers e uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint16 reversible_flags # Bitset indicating which motors are configured to be reversible +uint16 reversible_flags # [-] Bitset indicating which motors are configured to be reversible -uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 # -uint8 NUM_CONTROLS = 12 -float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) +uint8 NUM_CONTROLS = 12 # +float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) ``` diff --git a/docs/ko/msg_docs/ActuatorServos.md b/docs/ko/msg_docs/ActuatorServos.md index ffe01e2f49..ea053f67a3 100644 --- a/docs/ko/msg_docs/ActuatorServos.md +++ b/docs/ko/msg_docs/ActuatorServos.md @@ -15,10 +15,10 @@ Published by the vehicle's allocation and consumed by the actuator output driver uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint8 NUM_CONTROLS = 8 -float32[8] control # [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. +uint8 NUM_CONTROLS = 8 # +float32[8] control # [-] [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. ``` diff --git a/docs/ko/msg_docs/AdcReport.md b/docs/ko/msg_docs/AdcReport.md index f4e3cea36d..50fde63ff5 100644 --- a/docs/ko/msg_docs/AdcReport.md +++ b/docs/ko/msg_docs/AdcReport.md @@ -1,13 +1,21 @@ # AdcReport (UORB message) +ADC raw data. + +Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AdcReport.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint32 device_id # unique device ID for the sensor that does not change between power cycles -int16[12] channel_id # ADC channel IDs, negative for non-existent, TODO: should be kept same as array index -int32[12] raw_data # ADC channel raw value, accept negative value, valid if channel ID is positive -uint32 resolution # ADC channel resolution -float32 v_ref # ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) +# ADC raw data. +# +# Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + +uint64 timestamp # [us] Time since system start +uint32 device_id # [-] unique device ID for the sensor that does not change between power cycles +int16[16] channel_id # [-] ADC channel IDs, negative for non-existent, TODO: should be kept same as array index +int32[16] raw_data # [-] ADC channel raw value, accept negative value, valid if channel ID is positive +uint32 resolution # [-] ADC channel resolution +float32 v_ref # [V] ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) ``` diff --git a/docs/ko/msg_docs/Airspeed.md b/docs/ko/msg_docs/Airspeed.md index 7309747f66..949af8d5e7 100644 --- a/docs/ko/msg_docs/Airspeed.md +++ b/docs/ko/msg_docs/Airspeed.md @@ -13,10 +13,10 @@ It is subscribed by the airspeed selector module, which validates the data from # This is published by airspeed sensor drivers, CAN airspeed sensors, simulators. # It is subscribed by the airspeed selector module, which validates the data from multiple sensors and passes on a single estimation to the EKF, controllers and telemetry providers. -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Timestamp of the raw data -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed -float32 true_airspeed_m_s # [m/s] True airspeed -float32 confidence # [@range 0,1] Confidence value for this sensor +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +float32 indicated_airspeed_m_s # [m/s] Indicated airspeed +float32 true_airspeed_m_s # [m/s] True airspeed +float32 confidence # [@range 0,1] Confidence value for this sensor ``` diff --git a/docs/ko/msg_docs/AirspeedValidated.md b/docs/ko/msg_docs/AirspeedValidated.md index 9034960626..61f607e7fa 100644 --- a/docs/ko/msg_docs/AirspeedValidated.md +++ b/docs/ko/msg_docs/AirspeedValidated.md @@ -1,29 +1,39 @@ # AirspeedValidated (UORB message) +Validated airspeed + +Provides information about airspeed (indicated, true, calibrated) and the source of the data. +Used by controllers, estimators and for airspeed reporting to operator. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/AirspeedValidated.msg) ```c +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + + uint32 MESSAGE_VERSION = 1 -uint64 timestamp # time since system start (microseconds) +uint64 timestamp # [us] Time since system start -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed (IAS), set to NAN if invalid -float32 calibrated_airspeed_m_s # [m/s] Calibrated airspeed (CAS), set to NAN if invalid -float32 true_airspeed_m_s # [m/s] True airspeed (TAS), set to NAN if invalid +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) -int8 airspeed_source # Source of currently published airspeed values -int8 DISABLED = -1 -int8 GROUND_MINUS_WIND = 0 -int8 SENSOR_1 = 1 -int8 SENSOR_2 = 2 -int8 SENSOR_3 = 3 -int8 SYNTHETIC = 4 +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed -# debug states -float32 calibrated_ground_minus_wind_m_s # CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid -float32 calibraded_airspeed_synth_m_s # synthetic airspeed in m/s, set to NAN if invalid -float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] -float32 throttle_filtered # filtered fixed-wing throttle [-] -float32 pitch_filtered # filtered pitch [rad] +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch ``` diff --git a/docs/ko/msg_docs/ArmingCheckReply.md b/docs/ko/msg_docs/ArmingCheckReply.md index d5e3322506..14af54f0d1 100644 --- a/docs/ko/msg_docs/ArmingCheckReply.md +++ b/docs/ko/msg_docs/ArmingCheckReply.md @@ -1,6 +1,6 @@ # ArmingCheckReply (UORB message) -Arming check reply. +Arming check reply This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -12,7 +12,7 @@ The message is not used by internal/FMU components, as their mode requirements a [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckReply.msg) ```c -# Arming check reply. +# Arming check reply # # This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. # The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -21,39 +21,39 @@ The message is not used by internal/FMU components, as their mode requirements a # Note that the external component is identified by its registration_id, which is allocated to the component during registration (arming_check_id in RegisterExtComponentReply). # The message is not used by internal/FMU components, as their mode requirements are known at compile time. -uint32 MESSAGE_VERSION = 1 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # [us] Time since system start. -uint8 request_id # Id of ArmingCheckRequest for which this is a response. -uint8 registration_id # Id of external component emitting this response. +uint8 request_id # [-] Id of ArmingCheckRequest for which this is a response +uint8 registration_id # [-] Id of external component emitting this response -uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies. +uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies -uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] -bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json). +uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] +bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json) -bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed. +bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed -uint8 num_events # Number of queued failure messages (Event) in the events field. +uint8 num_events # Number of queued failure messages (Event) in the events field -Event[5] events # Arming failure reasons (Queue of events to report to GCS). +Event[5] events # Arming failure reasons (Queue of events to report to GCS) # Mode requirements -bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope). -bool mode_req_attitude # Requires an attitude estimate. -bool mode_req_local_alt # Requires a local altitude estimate. -bool mode_req_local_position # Requires a local position estimate. -bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate. -bool mode_req_global_position # Requires a global position estimate. -bool mode_req_global_position_relaxed # Requires a relaxed global position estimate. -bool mode_req_mission # Requires an uploaded mission. -bool mode_req_home_position # Requires a home position (such as RTL/Return mode). -bool mode_req_prevent_arming # Prevent arming (such as in Land mode). -bool mode_req_manual_control # Requires a manual controller +bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope) +bool mode_req_attitude # Requires an attitude estimate +bool mode_req_local_alt # Requires a local altitude estimate +bool mode_req_local_position # Requires a local position estimate +bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate +bool mode_req_global_position # Requires a global position estimate +bool mode_req_global_position_relaxed # Requires a relaxed global position estimate +bool mode_req_mission # Requires an uploaded mission +bool mode_req_home_position # Requires a home position (such as RTL/Return mode) +bool mode_req_prevent_arming # Prevent arming (such as in Land mode) +bool mode_req_manual_control # Requires a manual controller -uint8 ORB_QUEUE_LENGTH = 4 # +uint8 ORB_QUEUE_LENGTH = 4 ``` diff --git a/docs/ko/msg_docs/ArmingCheckRequest.md b/docs/ko/msg_docs/ArmingCheckRequest.md index cfa4b52c23..d093dfb5e1 100644 --- a/docs/ko/msg_docs/ArmingCheckRequest.md +++ b/docs/ko/msg_docs/ArmingCheckRequest.md @@ -1,6 +1,6 @@ # ArmingCheckRequest (UORB message) -Arming check request. +Arming check request Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -12,7 +12,7 @@ The reply will also include the registration_id for each external component, pro [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckRequest.msg) ```c -# Arming check request. +# Arming check request # # Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. # All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -21,10 +21,12 @@ The reply will also include the registration_id for each external component, pro # The reply will include the published request_id, allowing correlation of all arming check information for a particular request. # The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 -uint64 timestamp # [us] Time since system start. +uint64 timestamp # [us] Time since system start -uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint8 request_id # [-] Id of this request. Allows correlation with associated ArmingCheckReply messages. + +uint32 valid_registrations_mask # [-] Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) ``` diff --git a/docs/ko/msg_docs/ArmingCheckRequestV0.md b/docs/ko/msg_docs/ArmingCheckRequestV0.md new file mode 100644 index 0000000000..f5680c11f2 --- /dev/null +++ b/docs/ko/msg_docs/ArmingCheckRequestV0.md @@ -0,0 +1,30 @@ +# ArmingCheckRequestV0 (UORB message) + +Arming check request. + +Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. + +The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckRequestV0.msg) + +```c +# Arming check request. +# +# Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +# All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +# The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. +# +# The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +# The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start. + +uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. + +``` diff --git a/docs/ko/msg_docs/AutotuneAttitudeControlStatus.md b/docs/ko/msg_docs/AutotuneAttitudeControlStatus.md index 734a671ffd..31a47ef204 100644 --- a/docs/ko/msg_docs/AutotuneAttitudeControlStatus.md +++ b/docs/ko/msg_docs/AutotuneAttitudeControlStatus.md @@ -1,42 +1,59 @@ # AutotuneAttitudeControlStatus (UORB message) +Autotune attitude control status + +This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +and is subscribed to by the respective attitude controllers to command rate setpoints. + +The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AutotuneAttitudeControlStatus.msg) ```c -uint64 timestamp # time since system start (microseconds) +# Autotune attitude control status +# +# This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +# and is subscribed to by the respective attitude controllers to command rate setpoints. +# +# The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. -float32[5] coeff # coefficients of the identified discrete-time model -float32[5] coeff_var # coefficients' variance of the identified discrete-time model -float32 fitness # fitness of the parameter estimate -float32 innov -float32 dt_model +uint64 timestamp # [us] Time since system start -float32 kc -float32 ki -float32 kd -float32 kff -float32 att_p +float32[5] coeff # [-] Coefficients of the identified discrete-time model +float32[5] coeff_var # [-] Coefficients' variance of the identified discrete-time model +float32 fitness # [-] Fitness of the parameter estimate +float32 innov # [rad/s] Innovation (residual error between model and measured output) +float32 dt_model # [s] Model sample time used for identification -float32[3] rate_sp -float32 u_filt -float32 y_filt +float32 kc # [-] Proportional rate-loop gain (ideal form) +float32 ki # [-] Integral rate-loop gain (ideal form) +float32 kd # [-] Derivative rate-loop gain (ideal form) +float32 kff # [-] Feedforward rate-loop gain +float32 att_p # [-] Proportional attitude gain -uint8 STATE_IDLE = 0 -uint8 STATE_INIT = 1 -uint8 STATE_ROLL = 2 -uint8 STATE_ROLL_PAUSE = 3 -uint8 STATE_PITCH = 4 -uint8 STATE_PITCH_PAUSE = 5 -uint8 STATE_YAW = 6 -uint8 STATE_YAW_PAUSE = 7 -uint8 STATE_VERIFICATION = 8 -uint8 STATE_APPLY = 9 -uint8 STATE_TEST = 10 -uint8 STATE_COMPLETE = 11 -uint8 STATE_FAIL = 12 -uint8 STATE_WAIT_FOR_DISARM = 13 +float32[3] rate_sp # [rad/s] Rate setpoint commanded to the attitude controller. -uint8 state +float32 u_filt # [-] Filtered input signal (normalized torque setpoint) used in system identification. +float32 y_filt # [rad/s] Filtered output signal (angular velocity) used in system identification. + +uint8 state # [@enum STATE] Current state of the autotune procedure. +uint8 STATE_IDLE = 0 # Idle (not running) +uint8 STATE_INIT = 1 # Initialize filters and setup +uint8 STATE_ROLL_AMPLITUDE_DETECTION = 2 # FW only: determine required excitation amplitude (roll) +uint8 STATE_ROLL = 3 # Roll-axis excitation and model identification +uint8 STATE_ROLL_PAUSE = 4 # Pause to return to level flight +uint8 STATE_PITCH_AMPLITUDE_DETECTION = 5 # FW only: determine required excitation amplitude (pitch) +uint8 STATE_PITCH = 6 # Pitch-axis excitation and model identification +uint8 STATE_PITCH_PAUSE = 7 # Pause to return to level flight +uint8 STATE_YAW_AMPLITUDE_DETECTION = 8 # FW only: determine required excitation amplitude (yaw) +uint8 STATE_YAW = 9 # Yaw-axis excitation and model identification +uint8 STATE_YAW_PAUSE = 10 # Pause to return to level flight +uint8 STATE_VERIFICATION = 11 # Verify model and candidate gains +uint8 STATE_APPLY = 12 # Apply gains +uint8 STATE_TEST = 13 # Test gains in closed-loop +uint8 STATE_COMPLETE = 14 # Tuning completed successfully +uint8 STATE_FAIL = 15 # Tuning failed (model invalid or controller unstable) +uint8 STATE_WAIT_FOR_DISARM = 16 # Waiting for disarm before finalizing ``` diff --git a/docs/ko/msg_docs/BatteryStatus.md b/docs/ko/msg_docs/BatteryStatus.md index 7204a2a12f..ec2c19c59e 100644 --- a/docs/ko/msg_docs/BatteryStatus.md +++ b/docs/ko/msg_docs/BatteryStatus.md @@ -2,7 +2,7 @@ Battery status -Battery status information for up to 4 battery instances. +Battery status information for up to 3 battery instances. These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. Battery instance information is also logged and streamed in MAVLink telemetry. @@ -11,81 +11,82 @@ Battery instance information is also logged and streamed in MAVLink telemetry. ```c # Battery status # -# Battery status information for up to 4 battery instances. +# Battery status information for up to 3 battery instances. # These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. # Battery instance information is also logged and streamed in MAVLink telemetry. uint32 MESSAGE_VERSION = 1 -uint8 MAX_INSTANCES = 4 +uint8 MAX_INSTANCES = 3 -uint64 timestamp # [us] Time since system start -bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. -float32 voltage_v # [V] [@invalid 0] Battery voltage -float32 current_a # [A] [@invalid -1] Battery current -float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) -float32 discharged_mah # [mAh] [@invalid -1] Discharged amount -float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity -float32 scale # [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag -float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load -float32 temperature # [°C] [@invalid NaN] Temperature of the battery -uint8 cell_count # [@invalid 0] Number of cells +uint64 timestamp # [us] Time since system start + +bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. +float32 voltage_v # [V] [@invalid 0] Battery voltage +float32 current_a # [A] [@invalid -1] Battery current +float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) +float32 discharged_mah # [mAh] [@invalid -1] Discharged amount +float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity +float32 scale # [-] [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag +float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load +float32 temperature # [°C] [@invalid NaN] Temperature of the battery +uint8 cell_count # [-] [@invalid 0] Number of cells -uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 source # [@enum SOURCE] Battery source +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) -uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 -uint16 capacity # [mAh] Capacity of the battery when fully charged -uint16 cycle_count # Number of discharge cycles the battery has experienced -uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge -uint16 manufacture_date # Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 -uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity -uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation -uint8 id # ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed -uint16 interface_error # Interface error counter +uint8 priority # [-] Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 +uint16 capacity # [mAh] Capacity of the battery when fully charged +uint16 cycle_count # [-] Number of discharge cycles the battery has experienced +uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge +uint16 manufacture_date # [-] Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 +uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity +uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation +uint8 id # [-] ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed +uint16 interface_error # [-] Interface error counter -float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages -float32 max_cell_voltage_delta # Max difference between individual cell voltages +float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages +float32 max_cell_voltage_delta # [V] Max difference between individual cell voltages -bool is_powering_off # Power off event imminent indication, false if unknown -bool is_required # Set if the battery is explicitly required before arming +bool is_powering_off # Power off event imminent indication, false if unknown +bool is_required # Set if the battery is explicitly required before arming -uint8 warning # [@enum WARNING STATE] Current battery warning -uint8 WARNING_NONE = 0 # No battery low voltage warning active -uint8 WARNING_LOW = 1 # Low voltage warning -uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately -uint8 WARNING_EMERGENCY = 3 # Immediate landing required -uint8 WARNING_FAILED = 4 # Battery has failed completely -uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field -uint8 STATE_CHARGING = 7 # Battery is charging +uint8 warning # [@enum WARNING STATE] Current battery warning +uint8 WARNING_NONE = 0 # No battery low voltage warning active +uint8 WARNING_LOW = 1 # Low voltage warning +uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately +uint8 WARNING_EMERGENCY = 3 # Immediate landing required +uint8 WARNING_FAILED = 4 # Battery has failed completely +uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field +uint8 STATE_CHARGING = 7 # Battery is charging -uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication -uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged -uint8 FAULT_SPIKES = 1 # Voltage spikes -uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed -uint8 FAULT_OVER_CURRENT = 3 # Over-current -uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature -uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault -uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) -uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware -uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system -uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem -uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming -uint8 FAULT_COUNT = 11 # Counter. Keep this as last element +uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication +uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged +uint8 FAULT_SPIKES = 1 # Voltage spikes +uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed +uint8 FAULT_OVER_CURRENT = 3 # Over-current +uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature +uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault +uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) +uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware +uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system +uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem +uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming +uint8 FAULT_COUNT = 11 # Counter. Keep this as last element -float32 full_charge_capacity_wh # [Wh] Compensated battery capacity -float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining -uint16 over_discharge_count # Number of battery overdischarge -float32 nominal_voltage # [V] Nominal voltage of the battery pack +float32 full_charge_capacity_wh # [Wh] Compensated battery capacity +float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining +uint16 over_discharge_count # [-] Number of battery overdischarge +float32 nominal_voltage # [V] Nominal voltage of the battery pack -float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate -float32 ocv_estimate # [V] Open circuit voltage estimate -float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate -float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of charge estimate -float32 voltage_prediction # [V] Predicted voltage -float32 prediction_error # [V] Prediction error -float32 estimation_covariance_norm # Norm of the covariance matrix +float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate +float32 ocv_estimate # [V] Open circuit voltage estimate +float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate +float32 volt_based_soc_estimate # [-] [@range 0, 1] Normalized volt based state of charge estimate +float32 voltage_prediction # [V] Predicted voltage +float32 prediction_error # [V] Prediction error +float32 estimation_covariance_norm # [-] Norm of the covariance matrix ``` diff --git a/docs/ko/msg_docs/BatteryStatusV0.md b/docs/ko/msg_docs/BatteryStatusV0.md index 86500d17a6..cd900a1f17 100644 --- a/docs/ko/msg_docs/BatteryStatusV0.md +++ b/docs/ko/msg_docs/BatteryStatusV0.md @@ -32,9 +32,9 @@ uint8 cell_count # [@invalid 0] Number of cells uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 uint16 capacity # [mAh] Capacity of the battery when fully charged diff --git a/docs/ko/msg_docs/CellularStatus.md b/docs/ko/msg_docs/CellularStatus.md index 6579d3fe85..04ca0a65dc 100644 --- a/docs/ko/msg_docs/CellularStatus.md +++ b/docs/ko/msg_docs/CellularStatus.md @@ -11,39 +11,39 @@ This is currently used only for logging cell status from MAVLink. # # This is currently used only for logging cell status from MAVLink. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint16 status # [@enum STATUS_FLAG] Status bitmap -uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable -uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable -uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized -uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked -uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down -uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state -uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state -uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections -uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register -uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use -uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated -uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered -uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected +uint16 status # [@enum STATUS_FLAG] Status bitmap +uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable +uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable +uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized +uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked +uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down +uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state +uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state +uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections +uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register +uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use +uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated +uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered +uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected -uint8 failure_reason # [@enum FAILURE_REASON] Failure reason -uint8 FAILURE_REASON_NONE = 0 # No error -uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown -uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing -uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection +uint8 failure_reason # [@enum FAILURE_REASON] Failure reason +uint8 FAILURE_REASON_NONE = 0 # No error +uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown +uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing +uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection -uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type -uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None -uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM -uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE +uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type +uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None +uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM +uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE -uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value -uint16 mcc # [@invalid UINT16_MAX] Mobile country code -uint16 mnc # [@invalid UINT16_MAX] Mobile network code -uint16 lac # [@invalid 0] Location area code +uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value +uint16 mcc # [@invalid UINT16_MAX] Mobile country code +uint16 mnc # [@invalid UINT16_MAX] Mobile network code +uint16 lac # [@invalid 0] Location area code ``` diff --git a/docs/ko/msg_docs/ConfigOverrides.md b/docs/ko/msg_docs/ConfigOverrides.md index 37f88d4923..caa4d0816b 100644 --- a/docs/ko/msg_docs/ConfigOverrides.md +++ b/docs/ko/msg_docs/ConfigOverrides.md @@ -7,7 +7,7 @@ Configurable overrides by (external) modes or mode executors ```c # Configurable overrides by (external) modes or mode executors -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -15,7 +15,7 @@ bool disable_auto_disarm # Prevent the drone from automatically disarmin bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout - +bool disable_auto_set_home # Prevent the drone from automatically setting the home position on arm or takeoff int8 SOURCE_TYPE_MODE = 0 int8 SOURCE_TYPE_MODE_EXECUTOR = 1 diff --git a/docs/ko/msg_docs/ConfigOverridesV0.md b/docs/ko/msg_docs/ConfigOverridesV0.md new file mode 100644 index 0000000000..91e2cf5b48 --- /dev/null +++ b/docs/ko/msg_docs/ConfigOverridesV0.md @@ -0,0 +1,30 @@ +# ConfigOverridesV0 (UORB message) + +Configurable overrides by (external) modes or mode executors + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ConfigOverridesV0.msg) + +```c +# Configurable overrides by (external) modes or mode executors + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +bool disable_auto_disarm # Prevent the drone from automatically disarming after landing (if configured) + +bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) +int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout + + +int8 SOURCE_TYPE_MODE = 0 +int8 SOURCE_TYPE_MODE_EXECUTOR = 1 +int8 source_type + +uint8 source_id # ID depending on source_type + +uint8 ORB_QUEUE_LENGTH = 4 + +# TOPICS config_overrides config_overrides_request + +``` diff --git a/docs/ko/msg_docs/ControlAllocatorStatus.md b/docs/ko/msg_docs/ControlAllocatorStatus.md index b355b772b6..4068e7b4f4 100644 --- a/docs/ko/msg_docs/ControlAllocatorStatus.md +++ b/docs/ko/msg_docs/ControlAllocatorStatus.md @@ -24,5 +24,6 @@ int8[16] actuator_saturation # Indicates actuator saturation status. # Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value. uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/ko/msg_docs/DeviceInformation.md b/docs/ko/msg_docs/DeviceInformation.md new file mode 100644 index 0000000000..d415461f94 --- /dev/null +++ b/docs/ko/msg_docs/DeviceInformation.md @@ -0,0 +1,45 @@ +# DeviceInformation (UORB message) + +Device information + +Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +as well as tracking of the used firmware versions on the devices. + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DeviceInformation.msg) + +```c +# Device information +# +# Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +# as well as tracking of the used firmware versions on the devices. + +uint64 timestamp # time since system start (microseconds) + +uint8 device_type # [@enum DEVICE_TYPE] Type of the device. Matches MAVLink DEVICE_TYPE enum + +uint8 DEVICE_TYPE_GENERIC = 0 # Generic/unknown sensor +uint8 DEVICE_TYPE_AIRSPEED = 1 # Airspeed sensor +uint8 DEVICE_TYPE_ESC = 2 # ESC +uint8 DEVICE_TYPE_SERVO = 3 # Servo +uint8 DEVICE_TYPE_GPS = 4 # GPS +uint8 DEVICE_TYPE_MAGNETOMETER = 5 # Magnetometer +uint8 DEVICE_TYPE_PARACHUTE = 6 # Parachute +uint8 DEVICE_TYPE_RANGEFINDER = 7 # Rangefinder +uint8 DEVICE_TYPE_WINCH = 8 # Winch +uint8 DEVICE_TYPE_BAROMETER = 9 # Barometer +uint8 DEVICE_TYPE_OPTICAL_FLOW = 10 # Optical flow +uint8 DEVICE_TYPE_ACCELEROMETER = 11 # Accelerometer +uint8 DEVICE_TYPE_GYROSCOPE = 12 # Gyroscope +uint8 DEVICE_TYPE_DIFFERENTIAL_PRESSURE = 13 # Differential pressure +uint8 DEVICE_TYPE_BATTERY = 14 # Battery +uint8 DEVICE_TYPE_HYGROMETER = 15 # Hygrometer + +char[32] vendor_name # Name of the device vendor +char[32] model_name # Name of the device model + +uint32 device_id # [-] [@invalid 0 if not available] Unique device ID for the sensor. Does not change between power cycles. +char[24] firmware_version # [-] [@invalid empty if not available] Firmware version. +char[24] hardware_version # [-] [@invalid empty if not available] Hardware version. +char[33] serial_number # [-] [@invalid empty if not available] Device serial number or unique identifier. + +``` diff --git a/docs/ko/msg_docs/DifferentialPressure.md b/docs/ko/msg_docs/DifferentialPressure.md index f5fd908df9..83adb2d03e 100644 --- a/docs/ko/msg_docs/DifferentialPressure.md +++ b/docs/ko/msg_docs/DifferentialPressure.md @@ -1,17 +1,24 @@ # DifferentialPressure (UORB message) +Differential-pressure (airspeed) sensor + +This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DifferentialPressure.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Differential-pressure (airspeed) sensor +# +# This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 differential_pressure_pa # differential pressure reading in Pascals (may be negative) - -float32 temperature # Temperature provided by sensor in degrees Celsius, NAN if unknown - -uint32 error_count # Number of errors detected by driver +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 differential_pressure_pa # [Pa] Differential pressure reading (may be negative) +float32 temperature # [degC] [@invalid NaN if unknown] Temperature +uint32 error_count # [-] Number of errors detected by driver ``` diff --git a/docs/ko/msg_docs/EscReport.md b/docs/ko/msg_docs/EscReport.md index 5fc5456bbd..277402ae69 100644 --- a/docs/ko/msg_docs/EscReport.md +++ b/docs/ko/msg_docs/EscReport.md @@ -16,6 +16,19 @@ uint8 esc_state # State of ESC - depend on Vendor uint8 actuator_function # actuator output function (one of Motor1...MotorN) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR2 = 102 +uint8 ACTUATOR_FUNCTION_MOTOR3 = 103 +uint8 ACTUATOR_FUNCTION_MOTOR4 = 104 +uint8 ACTUATOR_FUNCTION_MOTOR5 = 105 +uint8 ACTUATOR_FUNCTION_MOTOR6 = 106 +uint8 ACTUATOR_FUNCTION_MOTOR7 = 107 +uint8 ACTUATOR_FUNCTION_MOTOR8 = 108 +uint8 ACTUATOR_FUNCTION_MOTOR9 = 109 +uint8 ACTUATOR_FUNCTION_MOTOR10 = 110 +uint8 ACTUATOR_FUNCTION_MOTOR11 = 111 +uint8 ACTUATOR_FUNCTION_MOTOR12 = 112 + uint16 failures # Bitmask to indicate the internal ESC faults int8 esc_power # Applied power 0-100 in % (negative values reserved) diff --git a/docs/ko/msg_docs/EstimatorStatus.md b/docs/ko/msg_docs/EstimatorStatus.md index e36871df1a..aca77484b9 100644 --- a/docs/ko/msg_docs/EstimatorStatus.md +++ b/docs/ko/msg_docs/EstimatorStatus.md @@ -21,6 +21,7 @@ uint8 GPS_CHECK_FAIL_MAX_VERT_DRIFT = 7 # 7 : maximum allowed vertical position uint8 GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR = 8 # 8 : maximum allowed horizontal speed fail - requires stationary vehicle uint8 GPS_CHECK_FAIL_MAX_VERT_SPD_ERR = 9 # 9 : maximum allowed vertical velocity discrepancy fail uint8 GPS_CHECK_FAIL_SPOOFED = 10 # 10 : GPS signal is spoofed +uint8 GPS_CHECK_FAIL_JAMMED = 11 # 11 : GPS signal is jammed uint64 control_mode_flags # Bitmask to indicate EKF logic state uint8 CS_TILT_ALIGN = 0 # 0 - true if the filter tilt alignment is complete @@ -52,7 +53,9 @@ uint8 CS_SYNTHETIC_MAG_Z = 25 # 25 - true when we are using a synthesized measur uint8 CS_VEHICLE_AT_REST = 26 # 26 - true when the vehicle is at rest uint8 CS_GPS_YAW_FAULT = 27 # 27 - true when the GNSS heading has been declared faulty and is no longer being used uint8 CS_RNG_FAULT = 28 # 28 - true when the range finder has been declared faulty and is no longer being used -uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurements are being fused +uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurement fusion is intended +uint8 CS_GNSS_FAULT = 45 # 45 - true if GNSS measurements have been declared faulty and are no longer used +uint8 CS_YAW_MANUAL = 46 # 46 - true if yaw has been set manually uint32 filter_fault_flags # Bitmask to indicate EKF internal faults # 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error diff --git a/docs/ko/msg_docs/EstimatorStatusFlags.md b/docs/ko/msg_docs/EstimatorStatusFlags.md index 19a6a00d23..aa7250fe1e 100644 --- a/docs/ko/msg_docs/EstimatorStatusFlags.md +++ b/docs/ko/msg_docs/EstimatorStatusFlags.md @@ -54,6 +54,9 @@ bool cs_valid_fake_pos # 41 - true if a valid constant position is bein bool cs_constant_pos # 42 - true if the vehicle is at a constant position bool cs_baro_fault # 43 - true when the current baro has been declared faulty and is no longer being used bool cs_gnss_vel # 44 - true if GNSS velocity measurement fusion is intended +bool cs_gnss_fault # 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty +bool cs_yaw_manual # 46 - true if yaw has been set manually +bool cs_gnss_hgt_fault # 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty # fault status uint32 fault_status_changes # number of filter fault status (fs) changes diff --git a/docs/ko/msg_docs/FailureDetectorStatus.md b/docs/ko/msg_docs/FailureDetectorStatus.md index 88e3ca4c24..a112a1e642 100644 --- a/docs/ko/msg_docs/FailureDetectorStatus.md +++ b/docs/ko/msg_docs/FailureDetectorStatus.md @@ -17,5 +17,6 @@ bool fd_motor float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed) uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/ko/msg_docs/GainCompression.md b/docs/ko/msg_docs/GainCompression.md new file mode 100644 index 0000000000..e26c1e8fcc --- /dev/null +++ b/docs/ko/msg_docs/GainCompression.md @@ -0,0 +1,12 @@ +# GainCompression (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GainCompression.msg) + +```c +uint64 timestamp # Time since system start (microseconds) + +float32[3] compression_gains # [-] [@frame FRD] [@range 0, 1] Multiplicative gain to modify the output of the controller per axis +float32[3] spectral_damper_hpf # [-] [@frame FRD] Squared output of spectral damper high-pass filter +float32[3] spectral_damper_out # [-] [@frame FRD] Spectral damper output squared + +``` diff --git a/docs/ko/msg_docs/GimbalDeviceAttitudeStatus.md b/docs/ko/msg_docs/GimbalDeviceAttitudeStatus.md index 2c8c6eca9b..0935029087 100644 --- a/docs/ko/msg_docs/GimbalDeviceAttitudeStatus.md +++ b/docs/ko/msg_docs/GimbalDeviceAttitudeStatus.md @@ -14,6 +14,9 @@ uint16 DEVICE_FLAGS_NEUTRAL = 2 uint16 DEVICE_FLAGS_ROLL_LOCK = 4 uint16 DEVICE_FLAGS_PITCH_LOCK = 8 uint16 DEVICE_FLAGS_YAW_LOCK = 16 +uint16 DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32 +uint16 DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64 + float32[4] q float32 angular_velocity_x diff --git a/docs/ko/msg_docs/GpioIn.md b/docs/ko/msg_docs/GpioIn.md index 039ed02851..589e7d7841 100644 --- a/docs/ko/msg_docs/GpioIn.md +++ b/docs/ko/msg_docs/GpioIn.md @@ -6,6 +6,7 @@ GPIO mask and state ```c # GPIO mask and state +uint8 MAX_INSTANCES = 8 uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id diff --git a/docs/ko/msg_docs/GpsDump.md b/docs/ko/msg_docs/GpsDump.md index 1f96901671..03910da906 100644 --- a/docs/ko/msg_docs/GpsDump.md +++ b/docs/ko/msg_docs/GpsDump.md @@ -9,11 +9,15 @@ This message is used to dump the raw gps communication to the log. uint64 timestamp # time since system start (microseconds) +uint8 INSTANCE_MAIN = 0 +uint8 INSTANCE_SECONDARY = 1 + uint8 instance # Instance of GNSS receiver +uint32 device_id uint8 len # length of data, MSB bit set = message to the gps device, # clear = message from the device uint8[79] data # data to write to the log -uint8 ORB_QUEUE_LENGTH = 8 +uint8 ORB_QUEUE_LENGTH = 16 ``` diff --git a/docs/ko/msg_docs/InputRc.md b/docs/ko/msg_docs/InputRc.md index d116542a6b..fbae6e0254 100644 --- a/docs/ko/msg_docs/InputRc.md +++ b/docs/ko/msg_docs/InputRc.md @@ -37,11 +37,13 @@ bool rc_lost # RC receiver connection status: True,if no frame has arrived in uint16 rc_lost_frame_count # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_total_frame_count # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_ppm_frame_length # Length of a single PPM frame. Zero for non-PPM systems +uint16 rc_frame_rate # RC frame rate in msg/second. 0 = invalid uint8 input_source # Input source uint16[18] values # measured pulse widths for each of the supported channels int8 link_quality # link quality. Percentage 0-100%. -1 = invalid float32 rssi_dbm # Actual rssi in units of dBm. NaN = invalid +int8 link_snr # link signal to noise ratio in units of dB. -1 = invalid ``` diff --git a/docs/ko/msg_docs/PurePursuitStatus.md b/docs/ko/msg_docs/PurePursuitStatus.md index 96577a0220..8d54ba473e 100644 --- a/docs/ko/msg_docs/PurePursuitStatus.md +++ b/docs/ko/msg_docs/PurePursuitStatus.md @@ -7,11 +7,11 @@ Pure pursuit status ```c # Pure pursuit status -uint64 timestamp # [us] Time since system start -float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller -float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller -float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path -float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint -float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint +uint64 timestamp # [us] Time since system start +float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller +float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller +float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path +float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint +float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint ``` diff --git a/docs/ko/msg_docs/RegisterExtComponentReply.md b/docs/ko/msg_docs/RegisterExtComponentReply.md index 860fa6ecb5..119703472a 100644 --- a/docs/ko/msg_docs/RegisterExtComponentReply.md +++ b/docs/ko/msg_docs/RegisterExtComponentReply.md @@ -3,7 +3,7 @@ [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentReply.msg) ```c -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -17,6 +17,8 @@ int8 arming_check_id # arming check registration ID (-1 if invalid) int8 mode_id # assigned mode ID (-1 if invalid) int8 mode_executor_id # assigned mode executor ID (-1 if invalid) +bool not_user_selectable # mode cannot be selected by the user + uint8 ORB_QUEUE_LENGTH = 2 ``` diff --git a/docs/ko/msg_docs/RegisterExtComponentReplyV0.md b/docs/ko/msg_docs/RegisterExtComponentReplyV0.md new file mode 100644 index 0000000000..cceec88d5c --- /dev/null +++ b/docs/ko/msg_docs/RegisterExtComponentReplyV0.md @@ -0,0 +1,22 @@ +# RegisterExtComponentReplyV0 (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg) + +```c +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID from the request +char[25] name # name from the request + +uint16 px4_ros2_api_version + +bool success +int8 arming_check_id # arming check registration ID (-1 if invalid) +int8 mode_id # assigned mode ID (-1 if invalid) +int8 mode_executor_id # assigned mode executor ID (-1 if invalid) + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/ko/msg_docs/RegisterExtComponentRequest.md b/docs/ko/msg_docs/RegisterExtComponentRequest.md index 545737c64a..814ea6e51b 100644 --- a/docs/ko/msg_docs/RegisterExtComponentRequest.md +++ b/docs/ko/msg_docs/RegisterExtComponentRequest.md @@ -7,7 +7,7 @@ Request to register an external component ```c # Request to register an external component -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -26,7 +26,7 @@ bool register_mode_executor # registering an executor also requires a mod bool enable_replace_internal_mode # set to true if an internal mode should be replaced uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) - +bool not_user_selectable # mode cannot be selected by the user uint8 ORB_QUEUE_LENGTH = 2 diff --git a/docs/ko/msg_docs/RegisterExtComponentRequestV0.md b/docs/ko/msg_docs/RegisterExtComponentRequestV0.md new file mode 100644 index 0000000000..58e99a484e --- /dev/null +++ b/docs/ko/msg_docs/RegisterExtComponentRequestV0.md @@ -0,0 +1,33 @@ +# RegisterExtComponentRequestV0 (UORB message) + +Request to register an external component + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg) + +```c +# Request to register an external component + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID, set this to a random value +char[25] name # either the requested mode name, or component name + +uint16 LATEST_PX4_ROS2_API_VERSION = 1 # API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. + +uint16 px4_ros2_api_version # Set to LATEST_PX4_ROS2_API_VERSION + +# Components to be registered +bool register_arming_check +bool register_mode # registering a mode also requires arming_check to be set +bool register_mode_executor # registering an executor also requires a mode to be registered (which is the owned mode by the executor) + +bool enable_replace_internal_mode # set to true if an internal mode should be replaced +uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* +bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) + + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/ko/msg_docs/RoverAttitudeSetpoint.md b/docs/ko/msg_docs/RoverAttitudeSetpoint.md index bd436278ca..ca75a6e3e2 100644 --- a/docs/ko/msg_docs/RoverAttitudeSetpoint.md +++ b/docs/ko/msg_docs/RoverAttitudeSetpoint.md @@ -7,7 +7,7 @@ Rover Attitude Setpoint ```c # Rover Attitude Setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint ``` diff --git a/docs/ko/msg_docs/RoverAttitudeStatus.md b/docs/ko/msg_docs/RoverAttitudeStatus.md index e6df929abd..f5a9ce1f02 100644 --- a/docs/ko/msg_docs/RoverAttitudeStatus.md +++ b/docs/ko/msg_docs/RoverAttitudeStatus.md @@ -7,8 +7,8 @@ Rover Attitude Status ```c # Rover Attitude Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw -float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) +uint64 timestamp # [us] Time since system start +float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw +float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) ``` diff --git a/docs/ko/msg_docs/RoverPositionSetpoint.md b/docs/ko/msg_docs/RoverPositionSetpoint.md index b45aa0515f..751536e7f9 100644 --- a/docs/ko/msg_docs/RoverPositionSetpoint.md +++ b/docs/ko/msg_docs/RoverPositionSetpoint.md @@ -7,11 +7,11 @@ Rover Position Setpoint ```c # Rover Position Setpoint -uint64 timestamp # [us] Time since system start -float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position -float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track -float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed -float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with -float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel +uint64 timestamp # [us] Time since system start +float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position +float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track +float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed +float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with +float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel ``` diff --git a/docs/ko/msg_docs/RoverRateSetpoint.md b/docs/ko/msg_docs/RoverRateSetpoint.md index 9bffa41b80..9bb844e802 100644 --- a/docs/ko/msg_docs/RoverRateSetpoint.md +++ b/docs/ko/msg_docs/RoverRateSetpoint.md @@ -7,7 +7,7 @@ Rover Rate setpoint ```c # Rover Rate setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint ``` diff --git a/docs/ko/msg_docs/RoverRateStatus.md b/docs/ko/msg_docs/RoverRateStatus.md index 684e4c458a..70345fe315 100644 --- a/docs/ko/msg_docs/RoverRateStatus.md +++ b/docs/ko/msg_docs/RoverRateStatus.md @@ -7,9 +7,9 @@ Rover Rate Status ```c # Rover Rate Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate -float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) -float32 pid_yaw_rate_integral # [] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller +uint64 timestamp # [us] Time since system start +float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate +float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) +float32 pid_yaw_rate_integral # [-] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller ``` diff --git a/docs/ko/msg_docs/RoverSpeedSetpoint.md b/docs/ko/msg_docs/RoverSpeedSetpoint.md new file mode 100644 index 0000000000..84176cd1c3 --- /dev/null +++ b/docs/ko/msg_docs/RoverSpeedSetpoint.md @@ -0,0 +1,14 @@ +# RoverSpeedSetpoint (UORB message) + +Rover Speed Setpoint + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedSetpoint.msg) + +```c +# Rover Speed Setpoint + +uint64 timestamp # [us] Time since system start +float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction +float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction + +``` diff --git a/docs/ko/msg_docs/RoverSpeedStatus.md b/docs/ko/msg_docs/RoverSpeedStatus.md new file mode 100644 index 0000000000..4213e1e5df --- /dev/null +++ b/docs/ko/msg_docs/RoverSpeedStatus.md @@ -0,0 +1,18 @@ +# RoverSpeedStatus (UORB message) + +Rover Velocity Status + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedStatus.msg) + +```c +# Rover Velocity Status + +uint64 timestamp # [us] Time since system start +float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction +float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_x_integral # [-] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction +float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction +float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_y_integral # [-] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction + +``` diff --git a/docs/ko/msg_docs/RoverSteeringSetpoint.md b/docs/ko/msg_docs/RoverSteeringSetpoint.md index 3e40a3986b..974f3fc4c9 100644 --- a/docs/ko/msg_docs/RoverSteeringSetpoint.md +++ b/docs/ko/msg_docs/RoverSteeringSetpoint.md @@ -7,7 +7,7 @@ Rover Steering setpoint ```c # Rover Steering setpoint -uint64 timestamp # [us] Time since system start -float32 normalized_steering_setpoint # [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels +uint64 timestamp # [us] Time since system start +float32 normalized_steering_setpoint # [-] [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels ``` diff --git a/docs/ko/msg_docs/RoverThrottleSetpoint.md b/docs/ko/msg_docs/RoverThrottleSetpoint.md index f1c4f7f653..bd5ee93d55 100644 --- a/docs/ko/msg_docs/RoverThrottleSetpoint.md +++ b/docs/ko/msg_docs/RoverThrottleSetpoint.md @@ -7,8 +7,8 @@ Rover Throttle setpoint ```c # Rover Throttle setpoint -uint64 timestamp # [us] Time since system start -float32 throttle_body_x # [] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis -float32 throttle_body_y # [] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis +uint64 timestamp # [us] Time since system start +float32 throttle_body_x # [-] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis +float32 throttle_body_y # [-] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis ``` diff --git a/docs/ko/msg_docs/RoverVelocitySetpoint.md b/docs/ko/msg_docs/RoverVelocitySetpoint.md deleted file mode 100644 index 65103082b8..0000000000 --- a/docs/ko/msg_docs/RoverVelocitySetpoint.md +++ /dev/null @@ -1,15 +0,0 @@ -# RoverVelocitySetpoint (UORB message) - -Rover Velocity Setpoint - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocitySetpoint.msg) - -```c -# Rover Velocity Setpoint - -uint64 timestamp # [us] Time since system start -float32 speed # [m/s] [@range -inf (Backwards), inf (Forwards)] Speed setpoint -float32 bearing # [rad] [@range -pi,pi] [@frame NED] [@invalid: NaN, speed is defined in body x direction] Bearing setpoint -float32 yaw # [rad] [@range -pi, pi] [@frame NED] [@invalid NaN, Defaults to vehicle yaw] Mecanum only: Yaw setpoint - -``` diff --git a/docs/ko/msg_docs/RoverVelocityStatus.md b/docs/ko/msg_docs/RoverVelocityStatus.md deleted file mode 100644 index dfd7756afa..0000000000 --- a/docs/ko/msg_docs/RoverVelocityStatus.md +++ /dev/null @@ -1,18 +0,0 @@ -# RoverVelocityStatus (UORB message) - -Rover Velocity Status - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocityStatus.msg) - -```c -# Rover Velocity Status - -uint64 timestamp # [us] Time since system start -float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction -float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_x_integral # [] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction -float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction -float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_y_integral # [] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction - -``` diff --git a/docs/ko/msg_docs/SensorBaro.md b/docs/ko/msg_docs/SensorBaro.md index cf834ccf36..ef4d7a8f28 100644 --- a/docs/ko/msg_docs/SensorBaro.md +++ b/docs/ko/msg_docs/SensorBaro.md @@ -1,18 +1,25 @@ # SensorBaro (UORB message) +Barometer sensor + +This is populated by barometer drivers and used by the EKF2 estimator. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorBaro.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Barometer sensor +# +# This is populated by barometer drivers and used by the EKF2 estimator. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 pressure # static pressure measurement in Pascals - -float32 temperature # temperature in degrees Celsius - -uint32 error_count +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 pressure # [Pa] Static pressure measurement +float32 temperature # [degC] Temperature. +uint32 error_count # [-] Number of errors detected by driver. uint8 ORB_QUEUE_LENGTH = 4 diff --git a/docs/ko/msg_docs/SensorGnssStatus.md b/docs/ko/msg_docs/SensorGnssStatus.md new file mode 100644 index 0000000000..70602b85fc --- /dev/null +++ b/docs/ko/msg_docs/SensorGnssStatus.md @@ -0,0 +1,19 @@ +# SensorGnssStatus (UORB message) + +Gnss quality indicators + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssStatus.msg) + +```c +# Gnss quality indicators + +uint64 timestamp # time since system start (microseconds) +uint32 device_id # unique device ID for the sensor that does not change between power cycles + +bool quality_available # Set to true if quality indicators are available +uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available +uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available +uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available +uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available + +``` diff --git a/docs/ko/msg_docs/SensorGps.md b/docs/ko/msg_docs/SensorGps.md index c8d09e9472..1b5fb3cf41 100644 --- a/docs/ko/msg_docs/SensorGps.md +++ b/docs/ko/msg_docs/SensorGps.md @@ -38,18 +38,26 @@ float32 vdop # Vertical dilution of precision int32 noise_per_ms # GPS noise per millisecond uint16 automatic_gain_control # Automatic gain control monitor -uint8 JAMMING_STATE_UNKNOWN = 0 -uint8 JAMMING_STATE_OK = 1 -uint8 JAMMING_STATE_WARNING = 2 -uint8 JAMMING_STATE_CRITICAL = 3 -uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical -int32 jamming_indicator # indicates jamming is occurring +uint8 JAMMING_STATE_UNKNOWN = 0 #default +uint8 JAMMING_STATE_OK = 1 +uint8 JAMMING_STATE_MITIGATED = 2 +uint8 JAMMING_STATE_DETECTED = 3 +uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected +int32 jamming_indicator # indicates jamming is occurring -uint8 SPOOFING_STATE_UNKNOWN = 0 -uint8 SPOOFING_STATE_NONE = 1 -uint8 SPOOFING_STATE_INDICATED = 2 -uint8 SPOOFING_STATE_MULTIPLE = 3 -uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical +uint8 SPOOFING_STATE_UNKNOWN = 0 #default +uint8 SPOOFING_STATE_OK = 1 +uint8 SPOOFING_STATE_MITIGATED = 2 +uint8 SPOOFING_STATE_DETECTED = 3 +uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected + +# Combined authentication state (e.g. Galileo OSNMA) +uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default +uint8 AUTHENTICATION_STATE_INITIALIZING = 1 +uint8 AUTHENTICATION_STATE_ERROR = 2 +uint8 AUTHENTICATION_STATE_OK = 3 +uint8 AUTHENTICATION_STATE_DISABLED = 4 +uint8 authentication_state # GPS signal authentication state float32 vel_m_s # GPS ground speed, (metres/sec) float32 vel_n_m_s # GPS North velocity, (metres/sec) @@ -63,6 +71,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi uint8 satellites_used # Number of satellites used +uint32 SYSTEM_ERROR_OK = 0 #default +uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1 +uint32 SYSTEM_ERROR_CONFIGURATION = 2 +uint32 SYSTEM_ERROR_SOFTWARE = 4 +uint32 SYSTEM_ERROR_ANTENNA = 8 +uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16 +uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32 +uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64 +uint32 system_error # General errors with the connected GPS receiver + float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) float32 heading_accuracy # heading accuracy (rad, [0, 2PI]) diff --git a/docs/ko/msg_docs/SensorTemp.md b/docs/ko/msg_docs/SensorTemp.md new file mode 100644 index 0000000000..5ed50541fe --- /dev/null +++ b/docs/ko/msg_docs/SensorTemp.md @@ -0,0 +1,11 @@ +# SensorTemp (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorTemp.msg) + +```c +uint64 timestamp # time since system start (microseconds) + +uint32 device_id # unique device ID for the sensor that does not change between power cycles +float32 temperature # Temperature provided by sensor (Celsius) + +``` diff --git a/docs/ko/msg_docs/VehicleAirData.md b/docs/ko/msg_docs/VehicleAirData.md index 75363b8571..dccfefc095 100644 --- a/docs/ko/msg_docs/VehicleAirData.md +++ b/docs/ko/msg_docs/VehicleAirData.md @@ -1,22 +1,26 @@ # VehicleAirData (UORB message) +Vehicle air data + +Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +Includes calculated data such as barometric altitude and air density. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAirData.msg) ```c +# Vehicle air data +# +# Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +# Includes calculated data such as barometric altitude and air density. -uint64 timestamp # time since system start (microseconds) - -uint64 timestamp_sample # the timestamp of the raw data (microseconds) - -uint32 baro_device_id # unique device ID for the selected barometer - -float32 baro_alt_meter # Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH. -float32 baro_pressure_pa # Absolute pressure in Pascals -float32 ambient_temperature # Abient temperature in degrees Celsius -uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed - -float32 rho # air density - -uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +uint32 baro_device_id # Unique device ID for the selected barometer +float32 baro_alt_meter # [m] [@frame MSL] Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH +float32 baro_pressure_pa # [Pa] Absolute pressure +float32 ambient_temperature # [degC] Ambient temperature +uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed +float32 rho # [kg/m^3] Air density +uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. ``` diff --git a/docs/ko/msg_docs/VehicleCommand.md b/docs/ko/msg_docs/VehicleCommand.md index 19557cf496..225f680857 100644 --- a/docs/ko/msg_docs/VehicleCommand.md +++ b/docs/ko/msg_docs/VehicleCommand.md @@ -28,7 +28,7 @@ uint16 VEHICLE_CMD_DO_ORBIT = 34 # Start orbiting on the circumference of a circ uint16 VEHICLE_CMD_DO_FIGUREEIGHT = 35 # Start flying on the outline of a figure eight defined by the parameters. |[m] Major radius|[m] Minor radius|[m/s] Velocity|Orientation|Latitude/X|Longitude/Y|Altitude/Z| uint16 VEHICLE_CMD_NAV_ROI = 80 # Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |[@enum VEHICLE_ROI] Region of interest mode.|MISSION index/ target ID.|ROI index (allows a vehicle to manage multiple ROI's)|Unused|x the location of the fixed ROI (see MAV_FRAME)|y|z| uint16 VEHICLE_CMD_NAV_PATHPLANNING = 81 # Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning|0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid|Unused|[deg] [@range 0, 360] Yaw angle at goal, in compass degrees|Latitude/X of goal|Longitude/Y of goal|Altitude/Z of goal| -uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Unused|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| +uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Transition heading, 0: Default, 3: Use specified transition heading|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_VTOL_LAND = 85 # Transition to MC and land at location. |Unused|Unused|Unused|Desired yaw angle.|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_GUIDED_LIMITS = 90 # Set limits for external control. |[s] Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout|[m] Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit|[m] Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit|[m] Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit|Unused|Unused|Unused| uint16 VEHICLE_CMD_NAV_GUIDED_MASTER = 91 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -69,6 +69,7 @@ uint16 VEHICLE_CMD_DO_PARACHUTE=208 # Mission command to trigger a parachute. |a uint16 VEHICLE_CMD_DO_MOTOR_TEST=209 # Motor test command. |Instance (@range 1, )|throttle type|throttle|timeout [s]|Motor count|Test order|Unused| uint16 VEHICLE_CMD_DO_INVERTED_FLIGHT=210 # Change to/from inverted flight. |inverted (0=normal, 1=inverted)|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GRIPPER = 211 # Command to operate a gripper. +uint16 VEHICLE_CMD_DO_AUTOTUNE_ENABLE = 212 # Enable autotune module. |1 to enable|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL=214 # Mission command to set TRIG_INTERVAL for this flight. |[m] Camera trigger distance|Shutter integration time (ms)|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT=220 # Mission command to control a camera or antenna mount, using a quaternion as reference. |q1 - quaternion param #1, w (1 in null-rotation)|q2 - quaternion param #2, x (0 in null-rotation)|q3 - quaternion param #3, y (0 in null-rotation)|q4 - quaternion param #4, z (0 in null-rotation)|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GUIDED_MASTER=221 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -96,6 +97,7 @@ uint16 VEHICLE_CMD_REQUEST_CAMERA_INFORMATION = 521 # Request camera information uint16 VEHICLE_CMD_SET_CAMERA_MODE = 530 # Set camera capture mode (photo, video, etc.). uint16 VEHICLE_CMD_SET_CAMERA_ZOOM = 531 # Set camera zoom. uint16 VEHICLE_CMD_SET_CAMERA_FOCUS = 532 +uint16 VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE = 620 # Set an external estimate of vehicle attitude in degrees. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000 # Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE = 1001 # Gimbal configuration to set which sysid/compid is in primary and secondary control. uint16 VEHICLE_CMD_IMAGE_START_CAPTURE = 2000 # Start image capture sequence. @@ -106,6 +108,7 @@ uint16 VEHICLE_CMD_LOGGING_START = 2510 # Start streaming ULog data. uint16 VEHICLE_CMD_LOGGING_STOP = 2511 # Stop streaming ULog data. uint16 VEHICLE_CMD_CONTROL_HIGH_LATENCY = 2600 # Control starting/stopping transmitting data over the high latency link. uint16 VEHICLE_CMD_DO_VTOL_TRANSITION = 3000 # Command VTOL transition. +uint16 VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE = 5300 # Command safety on/off. |1 to activate safety, 0 to deactivate safety and allow control surface movements|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST = 3001 # Request arm authorization. uint16 VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY = 30001 # Prepare a payload deployment in the flight plan. uint16 VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY = 30002 # Control a pre-programmed payload deployment. @@ -185,6 +188,10 @@ int8 ARMING_ACTION_ARM = 1 uint8 GRIPPER_ACTION_RELEASE = 0 uint8 GRIPPER_ACTION_GRAB = 1 +# Used as param1 in DO_SET_SAFETY_SWITCH_STATE command. +uint8 SAFETY_OFF = 0 +uint8 SAFETY_ON = 1 + uint8 ORB_QUEUE_LENGTH = 8 float32 param1 # Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. diff --git a/docs/ko/msg_docs/VehicleOdometry.md b/docs/ko/msg_docs/VehicleOdometry.md index d559ded6c7..4213c23337 100644 --- a/docs/ko/msg_docs/VehicleOdometry.md +++ b/docs/ko/msg_docs/VehicleOdometry.md @@ -1,41 +1,44 @@ # VehicleOdometry (UORB message) -Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +Vehicle odometry data + +Fits ROS REP 147 for aerial vehicles [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleOdometry.msg) ```c -# Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +# Vehicle odometry data +# +# Fits ROS REP 147 for aerial vehicles uint32 MESSAGE_VERSION = 0 -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp sample -uint8 POSE_FRAME_UNKNOWN = 0 -uint8 POSE_FRAME_NED = 1 # NED earth-fixed frame -uint8 POSE_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 pose_frame # Position and orientation frame of reference +uint8 pose_frame # [@enum POSE_FRAME] Position and orientation frame of reference +uint8 POSE_FRAME_UNKNOWN = 0 # Unknown frame +uint8 POSE_FRAME_NED = 1 # North-East-Down (NED) navigation frame. Aligned with True North. +uint8 POSE_FRAME_FRD = 2 # Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. -float32[3] position # Position in meters. Frame of reference defined by local_frame. NaN if invalid/unknown -float32[4] q # Quaternion rotation from FRD body frame to reference frame. First value NaN if invalid/unknown +float32[3] position # [m] [@frame local frame] [@invalid NaN If invalid/unknown] Position. Origin is position of GC at startup. +float32[4] q # [-] [@invalid NaN First value if invalid/unknown] Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) -uint8 VELOCITY_FRAME_UNKNOWN = 0 -uint8 VELOCITY_FRAME_NED = 1 # NED earth-fixed frame -uint8 VELOCITY_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -uint8 velocity_frame # Reference frame of the velocity data +uint8 velocity_frame # [@enum VELOCITY_FRAME] Reference frame of the velocity data +uint8 VELOCITY_FRAME_UNKNOWN = 0 # Unknown frame +uint8 VELOCITY_FRAME_NED = 1 # NED navigation frame at current position. +uint8 VELOCITY_FRAME_FRD = 2 # FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. +uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -float32[3] velocity # Velocity in meters/sec. Frame of reference defined by velocity_frame variable. NaN if invalid/unknown +float32[3] velocity # [m/s] [@frame @velocity_frame] [@invalid NaN If invalid/unknown] Velocity. +float32[3] angular_velocity # [rad/s] [@frame @VELOCITY_FRAME_BODY_FRD] [@invalid NaN If invalid/unknown] Angular velocity in body-fixed frame -float32[3] angular_velocity # Angular velocity in body-fixed frame (rad/s). NaN if invalid/unknown +float32[3] position_variance # [m^2] Variance of position error +float32[3] orientation_variance # [rad^2] Variance of orientation/attitude error (expressed in body frame) +float32[3] velocity_variance # [m^2/s^2] Variance of velocity error -float32[3] position_variance -float32[3] orientation_variance -float32[3] velocity_variance - -uint8 reset_counter -int8 quality +uint8 reset_counter # [-] Reset counter. Counts reset events on attitude, velocity and position. +int8 quality # [-] [@invalid 0] Quality. Unused. # TOPICS vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry # TOPICS estimator_odometry diff --git a/docs/ko/msg_docs/VehicleStatus.md b/docs/ko/msg_docs/VehicleStatus.md index d1deeb0500..05e3f98bbb 100644 --- a/docs/ko/msg_docs/VehicleStatus.md +++ b/docs/ko/msg_docs/VehicleStatus.md @@ -20,20 +20,16 @@ uint8 ARMING_STATE_ARMED = 2 uint8 latest_arming_reason uint8 latest_disarming_reason -uint8 ARM_DISARM_REASON_TRANSITION_TO_STANDBY = 0 uint8 ARM_DISARM_REASON_STICK_GESTURE = 1 uint8 ARM_DISARM_REASON_RC_SWITCH = 2 uint8 ARM_DISARM_REASON_COMMAND_INTERNAL = 3 uint8 ARM_DISARM_REASON_COMMAND_EXTERNAL = 4 uint8 ARM_DISARM_REASON_MISSION_START = 5 -uint8 ARM_DISARM_REASON_SAFETY_BUTTON = 6 -uint8 ARM_DISARM_REASON_AUTO_DISARM_LAND = 7 -uint8 ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT = 8 -uint8 ARM_DISARM_REASON_KILL_SWITCH = 9 -uint8 ARM_DISARM_REASON_LOCKDOWN = 10 -uint8 ARM_DISARM_REASON_FAILURE_DETECTOR = 11 -uint8 ARM_DISARM_REASON_SHUTDOWN = 12 -uint8 ARM_DISARM_REASON_UNIT_TEST = 13 +uint8 ARM_DISARM_REASON_LANDING = 6 +uint8 ARM_DISARM_REASON_PREFLIGHT_INACTION = 7 +uint8 ARM_DISARM_REASON_KILL_SWITCH = 8 +uint8 ARM_DISARM_REASON_RC_BUTTON = 13 +uint8 ARM_DISARM_REASON_FAILSAFE = 14 uint64 nav_state_timestamp # time when current nav_state activated @@ -48,7 +44,7 @@ uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode uint8 NAVIGATION_STATE_POSITION_SLOW = 6 uint8 NAVIGATION_STATE_FREE5 = 7 -uint8 NAVIGATION_STATE_FREE4 = 8 +uint8 NAVIGATION_STATE_ALTITUDE_CRUISE = 8 # Altitude with Cruise mode uint8 NAVIGATION_STATE_FREE3 = 9 uint8 NAVIGATION_STATE_ACRO = 10 # Acro mode uint8 NAVIGATION_STATE_FREE2 = 11 diff --git a/docs/ko/msg_docs/index.md b/docs/ko/msg_docs/index.md index cb1c447eb4..7458c79a24 100644 --- a/docs/ko/msg_docs/index.md +++ b/docs/ko/msg_docs/index.md @@ -15,9 +15,9 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorMotors](ActuatorMotors.md) — Motor control message - [ActuatorServos](ActuatorServos.md) — Servo control message -- [AirspeedValidated](AirspeedValidated.md) -- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply. -- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request. +- [AirspeedValidated](AirspeedValidated.md) — Validated airspeed +- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply +- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request - [BatteryStatus](BatteryStatus.md) — Battery status - [ConfigOverrides](ConfigOverrides.md) — Configurable overrides by (external) modes or mode executors - [Event](Event.md) — Events interface @@ -70,7 +70,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [VehicleLandDetected](VehicleLandDetected.md) - [VehicleLocalPosition](VehicleLocalPosition.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data - [VehicleRatesSetpoint](VehicleRatesSetpoint.md) - [VehicleStatus](VehicleStatus.md) — Encodes the system state of the vehicle published by commander - [VtolVehicleStatus](VtolVehicleStatus.md) — VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE @@ -84,10 +84,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorOutputs](ActuatorOutputs.md) - [ActuatorServosTrim](ActuatorServosTrim.md) — Servo trims, added as offset to servo outputs - [ActuatorTest](ActuatorTest.md) -- [AdcReport](AdcReport.md) +- [AdcReport](AdcReport.md) — ADC raw data. - [Airspeed](Airspeed.md) — Airspeed data from sensors - [AirspeedWind](AirspeedWind.md) — Wind estimate (from airspeed_selector) -- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) +- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) — Autotune attitude control status - [BatteryInfo](BatteryInfo.md) — Battery information - [ButtonEvent](ButtonEvent.md) - [CameraCapture](CameraCapture.md) @@ -105,7 +105,8 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [DebugKeyValue](DebugKeyValue.md) - [DebugValue](DebugValue.md) - [DebugVect](DebugVect.md) -- [DifferentialPressure](DifferentialPressure.md) +- [DeviceInformation](DeviceInformation.md) — Device information +- [DifferentialPressure](DifferentialPressure.md) — Differential-pressure (airspeed) sensor - [DistanceSensor](DistanceSensor.md) — DISTANCE_SENSOR message data - [DistanceSensorModeChangeRequest](DistanceSensorModeChangeRequest.md) - [DronecanNodeStatus](DronecanNodeStatus.md) @@ -140,6 +141,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [FollowTargetEstimator](FollowTargetEstimator.md) - [FollowTargetStatus](FollowTargetStatus.md) - [FuelTankStatus](FuelTankStatus.md) +- [GainCompression](GainCompression.md) - [GeneratorStatus](GeneratorStatus.md) - [GeofenceResult](GeofenceResult.md) - [GeofenceStatus](GeofenceStatus.md) @@ -229,10 +231,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [RoverPositionSetpoint](RoverPositionSetpoint.md) — Rover Position Setpoint - [RoverRateSetpoint](RoverRateSetpoint.md) — Rover Rate setpoint - [RoverRateStatus](RoverRateStatus.md) — Rover Rate Status +- [RoverSpeedSetpoint](RoverSpeedSetpoint.md) — Rover Speed Setpoint +- [RoverSpeedStatus](RoverSpeedStatus.md) — Rover Velocity Status - [RoverSteeringSetpoint](RoverSteeringSetpoint.md) — Rover Steering setpoint - [RoverThrottleSetpoint](RoverThrottleSetpoint.md) — Rover Throttle setpoint -- [RoverVelocitySetpoint](RoverVelocitySetpoint.md) — Rover Velocity Setpoint -- [RoverVelocityStatus](RoverVelocityStatus.md) — Rover Velocity Status - [Rpm](Rpm.md) - [RtlStatus](RtlStatus.md) - [RtlTimeEstimate](RtlTimeEstimate.md) @@ -240,12 +242,13 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [SensorAccel](SensorAccel.md) - [SensorAccelFifo](SensorAccelFifo.md) - [SensorAirflow](SensorAirflow.md) -- [SensorBaro](SensorBaro.md) +- [SensorBaro](SensorBaro.md) — Barometer sensor - [SensorCombined](SensorCombined.md) — Sensor readings in SI-unit form. These fields are scaled and offset-compensated where possible and do not change with board revisions and sensor updates. - [SensorCorrection](SensorCorrection.md) — Sensor corrections in SI-unit form for the voted sensor - [SensorGnssRelative](SensorGnssRelative.md) — GNSS relative positioning information in NED frame. The NED frame is defined as the local topological system at the reference station. +- [SensorGnssStatus](SensorGnssStatus.md) — Gnss quality indicators - [SensorGps](SensorGps.md) — GPS position in WGS84 coordinates. the field 'timestamp' is for the position & velocity (microseconds) - [SensorGyro](SensorGyro.md) @@ -258,6 +261,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m The topic will not be updated when the vehicle is armed - [SensorSelection](SensorSelection.md) — Sensor ID's for the voted sensors output on the sensor_combined topic. Will be updated on startup of the sensor module and when sensor selection changes +- [SensorTemp](SensorTemp.md) - [SensorUwb](SensorUwb.md) — UWB distance contains the distance information measured by an ultra-wideband positioning system, such as Pozyx or NXP Rddrone. - [SensorsStatus](SensorsStatus.md) — Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. @@ -281,7 +285,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [UlogStreamAck](UlogStreamAck.md) — Ack a previously sent ulog_stream message that had the NEED_ACK flag set - [VehicleAcceleration](VehicleAcceleration.md) -- [VehicleAirData](VehicleAirData.md) +- [VehicleAirData](VehicleAirData.md) — Vehicle air data - [VehicleAngularAccelerationSetpoint](VehicleAngularAccelerationSetpoint.md) - [VehicleConstraints](VehicleConstraints.md) — Local setpoint constraints in NED frame setting something to NaN means that no limit is provided @@ -301,10 +305,14 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [YawEstimatorStatus](YawEstimatorStatus.md) - [AirspeedValidatedV0](AirspeedValidatedV0.md) - [ArmingCheckReplyV0](ArmingCheckReplyV0.md) +- [ArmingCheckRequestV0](ArmingCheckRequestV0.md) — Arming check request. - [BatteryStatusV0](BatteryStatusV0.md) — Battery status +- [ConfigOverridesV0](ConfigOverridesV0.md) — Configurable overrides by (external) modes or mode executors - [EventV0](EventV0.md) — this message is required here in the msg_old folder because other msg are depending on it Events interface - [HomePositionV0](HomePositionV0.md) — GPS home position in WGS84 coordinates. +- [RegisterExtComponentReplyV0](RegisterExtComponentReplyV0.md) +- [RegisterExtComponentRequestV0](RegisterExtComponentRequestV0.md) — Request to register an external component - [VehicleAttitudeSetpointV0](VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](VehicleLocalPositionV0.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. diff --git a/docs/ko/neural_networks/index.md b/docs/ko/neural_networks/index.md new file mode 100644 index 0000000000..016a8cbe0e --- /dev/null +++ b/docs/ko/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/ko/neural_networks/mc_neural_network_control.md b/docs/ko/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..ba696594a3 --- /dev/null +++ b/docs/ko/neural_networks/mc_neural_network_control.md @@ -0,0 +1,123 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +:::tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Input + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### 출력 + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/ko/neural_networks/nn_module_utilities.md b/docs/ko/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..5b21cb6817 --- /dev/null +++ b/docs/ko/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## 자동 실행 + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## 로깅 + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/ko/neural_networks/raptor.md b/docs/ko/neural_networks/raptor.md new file mode 100644 index 0000000000..4a7685e1c1 --- /dev/null +++ b/docs/ko/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## 개요 + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## 구조 + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## 특징 + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## 사용법 + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### 설정 + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### 문제 해결 + +#### 로깅 + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/ko/neural_networks/tflm.md b/docs/ko/neural_networks/tflm.md new file mode 100644 index 0000000000..d6d0d7ef1f --- /dev/null +++ b/docs/ko/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### 입력 + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### 출력 + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/ko/payloads/generic_actuator_control.md b/docs/ko/payloads/generic_actuator_control.md index 9bb2ba56fd..a2132bd7bd 100644 --- a/docs/ko/payloads/generic_actuator_control.md +++ b/docs/ko/payloads/generic_actuator_control.md @@ -60,7 +60,7 @@ To use a generic actuator in a mission: - Select the header on the waypoint mission editor to open the **Select Mission Command** editor. - Select the category **Advanced**, and then the **Set actuator** item (if the item is not present, try a more recent version of _QGroundControl_ or a daily build). - This will change the mission item type to "Set actuator". + This will change the mission item type to "Set actuator". 3. Select the actuators that are connected and set their values (these are normalized between -1 and 1). diff --git a/docs/ko/peripherals/adsb_flarm.md b/docs/ko/peripherals/adsb_flarm.md index 8ef5ee5983..539a220abd 100644 --- a/docs/ko/peripherals/adsb_flarm.md +++ b/docs/ko/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder It has been tested with the following devices: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## 하드웨어 설정 diff --git a/docs/ko/peripherals/dshot.md b/docs/ko/peripherals/dshot.md index 873ebe3d8a..020bd3a994 100644 --- a/docs/ko/peripherals/dshot.md +++ b/docs/ko/peripherals/dshot.md @@ -11,6 +11,10 @@ DShot is an alternative ESC protocol that has several advantages over [PWM](../p 이 항목에서는 DShot ESC 연결과 설정 방법을 설명합니다. +## Supported ESC + +[ESCs & Motors > Supported ESCs](../peripherals/esc_motors#supported-esc) has a list of supported ESC (check "Protocols" column for DShot ESC). + ## Wiring/Connections {#wiring} DShot ESC are wired the same way as [PWM ESCs](pwm_escs_and_servo.md). diff --git a/docs/ko/peripherals/esc_motors.md b/docs/ko/peripherals/esc_motors.md index 7fdbe37245..3705936825 100644 --- a/docs/ko/peripherals/esc_motors.md +++ b/docs/ko/peripherals/esc_motors.md @@ -3,80 +3,44 @@ Many PX4 drones use brushless motors that are driven by the flight controller via an Electronic Speed Controller (ESC). The ESC takes a signal from the flight controller and uses it to set control the level of power delivered to the motor. -PX4 supports a number of common protocols for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). +PX4 supports a number of [common protocols](../esc/esc_protocols.md) for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). + +## Supported ESC + +The following list is non-exhaustive. + +| ESC Device | Protocols | Firmwares | 참고 | +| ------------------------------ | ------------------------------------ | ------------------------ | ----------------------------------------------------- | +| [ARK 4IN1 ESC] | [Dshot], [PWM] | [AM32] | Has versions with/without connnectors | +| [Holybro Kotleta 20] | [DroneCAN], [PWM] | [PX4 Sapog ESC Firmware] | | +| [Vertiq Motor & ESC modules] | [Dshot], [OneShot], Multishot, [PWM] | Vertiq firmware | Larger modules support DroneCAN, ESC and Motor in one | +| [RaccoonLab CAN PWM ESC nodes] | [DroneCAN], Cyphal | | Cyphal and DroneCAN notes for PWM ESC | +| [VESC ESCs] | [DroneCAN], [PWM] | VESC project firmware | | +| [Zubax Telega] | [DroneCAN], [PWM] | Telega-based | ESC and Motor in one | + + + +[ARK 4IN1 ESC]: ../esc/ark_4in1_esc.md +[AM32]: https://am32.ca/ +[PX4 Sapog ESC Firmware]: ../dronecan/sapog.md +[VESC ESCs]: ../peripherals/vesc.md +[DroneCAN]: ../dronecan/escs.md +[Dshot]: ../peripherals/dshot.md +[OneShot]: ../peripherals/oneshot.md +[PWM]: ../peripherals/pwm_escs_and_servo.md +[Holybro Kotleta 20]: ../dronecan/holybro_kotleta.md +[Vertiq Motor & ESC modules]: ../peripherals/vertiq.md +[RaccoonLab CAN PWM ESC nodes]: ../dronecan/raccoonlab_nodes.md +[Zubax Telega]: ../dronecan/zubax_telega.md + +## See Also 더 자세한 정보는 다음을 참고하십시오. +- [ESC Protocols](../esc/esc_protocols.md) — overview of main ESC/Servo protocols supported by PX4 - [PWM ESCs and Servos](../peripherals/pwm_escs_and_servo.md) - [OneShot ESCs and Servos](../peripherals/oneshot.md) - [DShot](../peripherals/dshot.md) - [DroneCAN ESCs](../dronecan/escs.md) - [ESC Calibration](../advanced_config/esc_calibration.md) - [ESC Firmware and Protocols Overview](https://oscarliang.com/esc-firmware-protocols/) (oscarliang.com) - -A high level overview of the main ESC/Servo protocols supported by PX4 is given below. - -## ESC Protocols - -### PWM - -[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). - -PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired power level. -The pulse wdith typically ranges between 1000uS for zero power and 2000uS for full power. -The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50Hz and 490 Hz (the theoretical maximum being 500Hz for a very small "off" cycle). -A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. -For PWM servos 50Hz is usually sufficient, and many don't support higher rates. - -![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) - -In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the range values representing low and high values can vary significantly. -Unlike [dshot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) -- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### Oneshot 125 - -[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. -They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). -There are a number of variants of the OneShot protocol, which support different rates. -PX4 only supports OneShot 125. - -OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125us to 250us for zero to full power). -This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. -For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. -The actual supported rate depends on the ESC used. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### DShot - -[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduce latency, in particular racing multicopters, VTOL vehicles, and so on. - -It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). -In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can revers motor spin directions - -PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). -Selecting a higher rate DShot ESC in the UI result in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. - -### DroneCAN - -[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. -The PX4 implementation is currently limited to update rates of 200Hz. - -DroneCAN shares many similar benefits to [Dshot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. - -[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). diff --git a/docs/ko/peripherals/gripper.md b/docs/ko/peripherals/gripper.md index 8f2612d328..895a5fa865 100644 --- a/docs/ko/peripherals/gripper.md +++ b/docs/ko/peripherals/gripper.md @@ -75,13 +75,13 @@ To set the actuation timeout: - Run the `payload_deliverer` test in the QGC [MAVLink Shell](../debug/mavlink_shell.md): - ```sh - > payload_deliverer gripper_test - ``` + ```sh + > payload_deliverer gripper_test + ``` - ::: info - If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. - You might also run the `payload_deliverer start` command in the Nuttx shell. + ::: info + If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. + You might also run the `payload_deliverer start` command in the Nuttx shell. ::: diff --git a/docs/ko/peripherals/remote_id.md b/docs/ko/peripherals/remote_id.md index 5b242f847f..9e9d1f2e5e 100644 --- a/docs/ko/peripherals/remote_id.md +++ b/docs/ko/peripherals/remote_id.md @@ -245,11 +245,11 @@ If the Remote ID CAN node is present and the messages are not being received, th 2. Navigate to the [Application settings](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/general.html): **Application Settings > General > Miscellaneous**. 3. Select `Enable Remote ID`. - The Remote ID tab should appear. + The Remote ID tab should appear. - ::: info - If this option is not present you may be in a very recent version of QGC. - In that case, open the view at: **Application Settings > Remote ID**. + ::: info + If this option is not present you may be in a very recent version of QGC. + In that case, open the view at: **Application Settings > Remote ID**. ::: diff --git a/docs/ko/power_module/ark_12s_payload_power_module.md b/docs/ko/power_module/ark_12s_payload_power_module.md new file mode 100644 index 0000000000..e2cee5d122 --- /dev/null +++ b/docs/ko/power_module/ark_12s_payload_power_module.md @@ -0,0 +1,56 @@ +# ARK 12S Payload Power Module + +The [ARK 12S Payload Power Module](https://arkelectron.com/product/ark-12s-payload-power-module/) is a dual 5V 6A and 12V 6A power supply and digital power monitor designed for the Pixhawk Autopilot Bus Carrier boards. + +This is similar to the [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) except that the additional 12V 6A supply allows easier powering of a payload. + +![ARK 12S Payload Power Module](../../assets/hardware/power_module/ark_power_modules//ark_12s_payload_power.jpg) + +## 구매처 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-12s-payload-power-module/) (US) + +## Hardware Specifications + +- **TI INA238 Digital Power Monitor** + - 0.0001 Ohm Shunt + - I2C Interface + +- **5.2V 6A Step-Down Regulator** + - 10V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **12.0V 6A Step-Down Regulator** + - 15V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **75V Maximum Input Voltage** + +- **Connections** + - Solder Pads Battery Input + - Solder Pads Battery Output + - 6 Pin Molex CLIK-Mate Output + - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) + - 4 Pin Molex CLIK-Mate 12V Output + +- **Other** + - USA Built + - Includes 6 Pin Molex CLIK-Mate Cable + +- **Additional Information** + - Weight: 20.5 g + - Dimensions: 3.7 cm x 3.5 cm x 1.3 cm + +## PX4 Setup + +- Disable the `SENS_EN_INA226` parameter if it is enabled. +- Enable the `SENS_EN_INA238` parameter. +- Reboot the flight controller. +- Set the `INA238_SHUNT` parameter to 0.0001. +- Reboot the flight controller. + +## See Also + +- [ARK 12S Payload Power Module Documentation](https://docs.arkelectron.com/power/ark-12s-payload-power-module) (ARK Docs) diff --git a/docs/ko/power_module/ark_pab_power_module.md b/docs/ko/power_module/ark_pab_power_module.md index 923c921816..f8de846243 100644 --- a/docs/ko/power_module/ark_pab_power_module.md +++ b/docs/ko/power_module/ark_pab_power_module.md @@ -6,35 +6,36 @@ Note that at 60A and 20°C without cooling, the 5V regulator is de-rated to a 3A ![ARK PAB Power Module](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_module.jpg) +This power module is also available without connectors: + +![ARK PAB Power Module No Connector](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_no_connector.jpg) + ## 구매처 Order this module from: -- [ARK Electronics](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module No Connector](https://arkelectron.com/product/ark-pab-power-module-no-connector/) (US) ## Hardware Specifications - **TI INA226 Digital Power Monitor** - - 0.0005 Ohm Shunt - I2C Interface - **5.2V 6A Step-Down Regulator** - - 33V Maximum Input Voltage - 5.8V Minimum Input Voltage at 6A Out - Output Over-Voltage Protection - Output Over-Current Protection - **Connections** - - - XT60 Battery Input - - XT60 Battery Output + - XT60 Battery Input / Solder Pad Battery Input (No Connector version) + - XT60 Battery Output / Solder Pad Battery Output (No Connector version) - 6 Pin Molex CLIK-Mate Output - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) - **Other** - - USA Built - FCC Compliant - Includes 6 Pin Molex CLIK-Mate Cable diff --git a/docs/ko/power_module/index.md b/docs/ko/power_module/index.md index 86d6aa1c63..7fceb5e8ac 100644 --- a/docs/ko/power_module/index.md +++ b/docs/ko/power_module/index.md @@ -27,6 +27,7 @@ This section provides information about a number of power modules and power dist - Digital (I2C) voltage and current power modules (for Pixhawk FMUv6X and FMUv5X derived controllers): - [ARK PAB Power Module](../power_module/ark_pab_power_module.md) - [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](../power_module/ark_12s_payload_power_module.md) - [Holybro PM02D](../power_module/holybro_pm02d.md) - [Holybro PM03D](../power_module/holybro_pm03d.md) - [DroneCAN](../dronecan/index.md) power modules diff --git a/docs/ko/releases/1.14.md b/docs/ko/releases/1.14.md index 7d931c6d47..b93a593b00 100644 --- a/docs/ko/releases/1.14.md +++ b/docs/ko/releases/1.14.md @@ -72,18 +72,18 @@ For users upgrading from previous versions, please take a moment to review the f 1. The actuator changes require you to verify vehicle geometry and motors/servos mappings match your vehicle. In QGC, find the [Actuator Configuration Dashboard](../config/actuators.md), and make sure to confirm the airframe geometry matches actuals from your vehicle, as well as update motor and ensure motors and servos are mapped to outputs as they are wired to the frame and with the correct ESC type specified. Note: take advantage of the sliders in the UI. They can be used to confirm motor wiring. - We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). + We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). - The calibration is critical if you are using a custom mixer file or the airframe you assigned in an earlier version is not present in PX4 v1.14. + The calibration is critical if you are using a custom mixer file or the airframe you assigned in an earlier version is not present in PX4 v1.14. - However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. + However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. 2. Default disarmed PWM was changed from 900us to 1000us. - Verify if you previously used the default PWM disarmed values and if the changes impact your setup. - For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. + Verify if you previously used the default PWM disarmed values and if the changes impact your setup. + For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. 3. Fast-RTPS users must port their code to the new uXRCE-DDS interface. - Application code should only require minor modifications. These include (minimally): + Application code should only require minor modifications. These include (minimally): Modifying topic names to match the new naming pattern, which changed from `fmu//out` to `fmu/out/`, and [Adusting the QoS settings](../ros2/user_guide.md#ros-2-subscriber-qos-settings). diff --git a/docs/ko/releases/1.16.md b/docs/ko/releases/1.16.md index b91d344bc2..27124c57fb 100644 --- a/docs/ko/releases/1.16.md +++ b/docs/ko/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/ko/releases/1.17.md b/docs/ko/releases/1.17.md new file mode 100644 index 0000000000..4d757780d5 --- /dev/null +++ b/docs/ko/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Read Before Upgrading + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Major Changes + +- TBD + +## Upgrade Guide + +## Other changes + +### Hardware Support + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### 제어 + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Estimation + +- TBD + + + +### 시뮬레이션 + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- TBD + +### Ethernet + +- TBD + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- TBD + + + +### 수직이착륙기(VTOL) + +- TBD + +### Fixed-wing + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### 탐사선 + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- TBD diff --git a/docs/ko/releases/index.md b/docs/ko/releases/index.md index 7df22a6bf7..67c9428937 100644 --- a/docs/ko/releases/index.md +++ b/docs/ko/releases/index.md @@ -2,7 +2,8 @@ PX4 릴리스 노트는 각 릴리스의 변경 사항들을 설명합니다. -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/ko/releases/main.md b/docs/ko/releases/main.md index ba15118e44..8ef3533c8d 100644 --- a/docs/ko/releases/main.md +++ b/docs/ko/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Read Before Upgrading -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -44,7 +44,8 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 제어 -- TBD +- Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Estimation @@ -52,27 +53,52 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 센서 -- TBD +- Add [sbgECom INS driver](../sensor/sbgecom.md) ([PX4-Autopilot#24137](https://github.com/PX4/PX4-Autopilot/pull/24137)) +- Quick magnetometer calibration now supports specifying an arbitrary initial heading ([PX4-Autopilot#24637](https://github.com/PX4/PX4-Autopilot/pull/24637)) ### 시뮬레이션 - TBD + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - TBD -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- TBD + + ### MAVLink - TBD +### RC + +- Parse ELRS Status and Link Statistics TX messages in the CRSF parser. + ### Multi-Rotor -- TBD +- Removed parameters `MPC_{XY/Z/YAW}_MAN_EXPO` and use default value instead, as they were not deemed necessary anymore. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). +- Renamed `MPC_HOLD_DZ` to `MAN_DEADZONE` to have it globally available in modes that allow for a dead zone. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### 수직이착륙기(VTOL) @@ -80,12 +106,25 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Fixed-wing +- TBD + + ### 탐사선 +- TBD + + ### ROS 2 diff --git a/docs/ko/ros/mavros_custom_messages.md b/docs/ko/ros/mavros_custom_messages.md index 5cefc4644e..ecc129c4bd 100644 --- a/docs/ko/ros/mavros_custom_messages.md +++ b/docs/ko/ros/mavros_custom_messages.md @@ -110,7 +110,7 @@ Follow _Source Installation_ instructions from [mavlink/mavros](https://github.c - `PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0` - `workspace/src/mavlink/message_definitions/v1.0` - are exactly the same. + are exactly the same. ::: diff --git a/docs/ko/ros/mavros_installation.md b/docs/ko/ros/mavros_installation.md index a049519917..5d7dd2eb68 100644 --- a/docs/ko/ros/mavros_installation.md +++ b/docs/ko/ros/mavros_installation.md @@ -148,21 +148,21 @@ Now you are ready to do the build: 2. 릴리스 또는 최신 버전을 사용하여 소스에서 MAVROS를 설치합니다. - 출시/안정 - ```sh - rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall + ``` - 최신 소스 - ```sh - rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall + ``` - ```sh - # For fetching all the dependencies into your catkin_ws, - # just add '--deps' to the above scripts, E.g.: - # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall - ``` + ```sh + # For fetching all the dependencies into your catkin_ws, + # just add '--deps' to the above scripts, E.g.: + # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall + ``` 3. Create workspace & deps diff --git a/docs/ko/ros/offboard_control.md b/docs/ko/ros/offboard_control.md index b17b96abe7..878d32bc68 100644 --- a/docs/ko/ros/offboard_control.md +++ b/docs/ko/ros/offboard_control.md @@ -38,9 +38,9 @@ Enable MAVLink on the serial port that you connect to the companion computer (se 1. 하나는 자동조종장치의 UART 포트에 연결합니다. 2. One connected to a ground station computer - Example radios include: + Example radios include: - - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) + - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) [![Mermaid graph: mavlink channel](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9) diff --git a/docs/ko/ros2/offboard_control.md b/docs/ko/ros2/offboard_control.md index 2820b8280e..993ce0a6d6 100644 --- a/docs/ko/ros2/offboard_control.md +++ b/docs/ko/ros2/offboard_control.md @@ -1,6 +1,6 @@ # ROS 2 오프보드 제어 예 -The following C++ example shows how to do position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. +The following C++ example shows how to do multicopter position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. The example starts sending setpoints, enters offboard mode, arms, ascends to 5 metres, and waits. While simple, it shows the main principles of how to use offboard control and how to send vehicle commands. @@ -22,7 +22,7 @@ To subscribe to data coming from nodes that publish in a different frame (for ex ## Trying it out -Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the simulator, install ROS 2, and start the XRCE-DDS Agent. +Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the multicopter simulator, install ROS 2, and start the XRCE-DDS Agent. After that we can follow a similar set of steps to those in [ROS 2 User Guide > Build ROS 2 Workspace](../ros2/user_guide.md#build-ros-2-workspace) to run the example. diff --git a/docs/ko/ros2/px4_ros2_control_interface.md b/docs/ko/ros2/px4_ros2_control_interface.md index 890858df38..63ccc917cb 100644 --- a/docs/ko/ros2/px4_ros2_control_interface.md +++ b/docs/ko/ros2/px4_ros2_control_interface.md @@ -14,7 +14,7 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta ::: -The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library that simplifies controlling PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. Developers use the library to create and dynamically register modes written using ROS 2. These modes are dynamically registered with PX4, and appear to be part of PX4 to a ground station or other external system. @@ -26,6 +26,12 @@ These classes abstract the internal setpoints used by PX4, and that can therefor PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +:::tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: + ## 개요 This diagram provides a conceptual overview of how the control interface modes and mode executors interact with PX4. @@ -108,92 +114,92 @@ The following steps are required to get started: 2. Clone the repository into the workspace: - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - ::: info - To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. - See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + ::: info + To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. + See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). ::: 3. Build the workspace: - ```sh - cd .. - colcon build - source install/setup.bash - ``` + ```sh + cd .. + colcon build + source install/setup.bash + ``` 4. In a different shell, start PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (here we use Gazebo-Classic, but you can use any model or simulator) + (here we use Gazebo-Classic, but you can use any model or simulator) 5. Run the micro XRCE agent in a new shell (you can keep it running afterward): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 6. Start QGroundControl. - ::: info - Use QGroundControl Daily, which supports dynamically updating the list of modes. + ::: info + Use QGroundControl Daily, which supports dynamically updating the list of modes. ::: 7. Back in the ROS 2 terminal, run one of the example modes: - ```sh - ros2 run example_mode_manual_cpp example_mode_manual - ``` + ```sh + ros2 run example_mode_manual_cpp example_mode_manual + ``` - You should get an output like this showing 'My Manual Mode' mode being registered: + You should get an output like this showing 'My Manual Mode' mode being registered: - ```sh - [DEBUG] [example_mode_manual]: Checking message compatibility... - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply - [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) - ``` + ```sh + [DEBUG] [example_mode_manual]: Checking message compatibility... + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply + [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) + ``` 8. On the PX4 shell, you can check that PX4 registered the new mode: - ```sh - commander status - ``` + ```sh + commander status + ``` - The output should contain: + The output should contain: - ```plain - INFO [commander] Disarmed - INFO [commander] navigation mode: Position - INFO [commander] user intended navigation mode: Position - INFO [commander] in failsafe: no - INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode - ``` + ```plain + INFO [commander] Disarmed + INFO [commander] navigation mode: Position + INFO [commander] user intended navigation mode: Position + INFO [commander] in failsafe: no + INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode + ``` 9. At this point you should be able to see the mode in QGroundControl as well: - ![QGC Modes](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_modes.png) + ![QGC Modes](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_modes.png) 10. Select the mode, make sure you have a manual control source (physical or virtual joystick), and arm the vehicle. - The mode will then activate, and it should print the following output: + The mode will then activate, and it should print the following output: - ```sh - [DEBUG] [example_mode_manual]: Mode 'My Manual Mode' activated - ``` + ```sh + [DEBUG] [example_mode_manual]: Mode 'My Manual Mode' activated + ``` 11. Now you are ready to create your own mode. @@ -266,9 +272,9 @@ This section steps through an example of how to create a mode executor class. class MyModeExecutor : public px4_ros2::ModeExecutorBase // [1] { public: - MyModeExecutor(rclcpp::Node & node, px4_ros2::ModeBase & owned_mode) // [2] - : ModeExecutorBase(node, px4_ros2::ModeExecutorBase::Settings{}, owned_mode), - _node(node) + MyModeExecutor(px4_ros2::ModeBase & owned_mode) // [2] + : ModeExecutorBase(px4_ros2::ModeExecutorBase::Settings{}, owned_mode), + _node(owned_mode.node()) { } enum class State // [3] @@ -344,9 +350,10 @@ The used types also define the compatibility with different vehicle types. The following sections provide a list of supported setpoint types: -- [GotoSetpointType](#go-to-setpoint-gotosetpointtype): Smooth position and (optionally) heading control -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): Smooth position and (optionally) heading control +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype): Direct control of motors and flight surface servo setpoints +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). @@ -354,15 +361,21 @@ The other setpoint types are currently experimental, and can be found in: [px4_r You can add your own setpoint types by adding a class that inherits from `px4_ros2::SetpointBase`, sets the configuration flags according to what the setpoint requires, and then publishes any topic containing a setpoint. ::: -#### Go-to Setpoint (GotoSetpointType) +#### Go-to Setpoint (MulticopterGotoSetpointType) + + + + :::info This setpoint type is currently only supported for multicopters. ::: -Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::GotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/goto.hpp) setpoint type. +Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::MulticopterGotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) setpoint type. The setpoint type is streamed to FMU based position and heading smoothers formulated with time-optimal, maximum-jerk trajectories, with velocity and acceleration constraints. +There is also a [`px4_ros2::MulticopterGotoGlobalSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) class that allows to send setpoints in global coordinates. + The most trivial use is simply inputting a 3D position into the update method: ```cpp @@ -407,7 +420,7 @@ _goto_setpoint->update( #### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) - + :::info This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. @@ -419,7 +432,7 @@ This setpoint is streamed to the PX4 [_FwLateralLongitudinalControl_ module](../ To control the vehicle, at least one lateral **and** one longitudinal setpoint must be provided: 1. Of the longitudinal inputs: either `altitude` or `height_rate` must be finite to control vertical motion. - If both are set to `NAN`, the vehicle will maintain its current altitude. + If both are set to `NAN`, the vehicle will maintain its current altitude. 2. Of the lateral inputs: at least one of `course`, `airspeed_direction`, or `lateral_acceleration` must be finite. For a detailed description of the controllable parameters, please refer to message definitions ([FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) and [FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md)). @@ -547,13 +560,47 @@ For example to control a quadrotor, you need to set the first 4 motors according If you want to control an actuator that does not control the vehicle's motion, but for example a payload servo, see [below](#controlling-an-independent-actuator-servo). ::: +#### Rover Setpoints + + + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +:::info +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (Overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint, **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). All combinations of "left" and "right" setpoints are valid. + +For ease of use we expose these valid combinations as new SetpointTypes. +::: + +The RoverSetpointTypes exposed through the control interface are combinations of these setpoints that lead to a valid control input: + +| SetpointType | Position | Speed | 스로틀 | Attitude | 주파수 | Steering | Control Flags | +| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------ | +| [RoverPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverPositionSetpointType.html#details) | ✓ | (✓) | (✓) | (✓) | (✓) | (✓) | Position, Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedAttitudeSetpointType.html) | | ✓ | (✓) | ✓ | (✓) | (✓) | Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedRateSetpointType.html) | | ✓ | (✓) | | ✓ | (✓) | Velocity, Rate, Control Allocation | +| [RoverSpeedSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedSteeringSetpointType.html) | | ✓ | (✓) | | | ✓ | Velocity, Control Allocation | +| [RoverThrottleAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleAttitudeSetpointType.html) | | | ✓ | ✓ | (✓) | (✓) | Attitude, Rate, Control Allocation | +| [RoverThrottleRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleRateSetpointType.html) | | | ✓ | | ✓ | (✓) | Rate, Control Allocation | +| [RoverThrottleSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleSteeringSetpointType.html) | | | ✓ | | | ✓ | Control Allocation | + +✓ are the setpoints we publish, and (✓) are generated internally by the PX4 rover modules according to the hierarchy above. + +An example for a rover specific drive mode using the `RoverSpeedAttitudeSetpointType` is provided [here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/rover_velocity). + ### Controlling a VTOL - + To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: -- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`GotoSetpointType`](#go-to-setpoint-gotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). +- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`MulticopterGotoSetpointType`](#go-to-setpoint-multicoptergotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). - Fixed-wing mode: Use the [`FwLateralLongitudinalSetpointType`](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype). As long as the VTOL remains in either multicopter or fixed-wing mode throughout the external mode, no additional handling is required. @@ -568,24 +615,24 @@ Commanding transitions externally makes the user partially responsible for ensur 3. To command a transition, you can use the `toMulticopter()` or `toFixedwing()` methods on your VTOL object to set the desired state. 4. During transition, send the following combination of setpoints: - ```cpp - // Assuming the instance of the px4_ros2::VTOL object is called vtol + ```cpp + // Assuming the instance of the px4_ros2::VTOL object is called vtol - // Send TrajectorySetpointType as follows: - Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); - Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; + // Send TrajectorySetpointType as follows: + Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); + Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; - _trajectory_setpoint->update(velocity_sp, acceleration_sp); + _trajectory_setpoint->update(velocity_sp, acceleration_sp); - // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired + // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired - float course_sp = 0.F; // North + float course_sp = 0.F; // North - _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) - ``` + _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) + ``` - This will ensure that the transition is handled properly within PX4. - You can optionally pass a deceleration setpoint to `computeAccelerationSetpointDuringTransition()` to be used during back-transitions. + This will ensure that the transition is handled properly within PX4. + You can optionally pass a deceleration setpoint to `computeAccelerationSetpointDuringTransition()` to be used during back-transitions. To check the current state of the vehicle, use the `getCurrentState()` method on your `px4_ros2::VTOL` object. @@ -598,7 +645,7 @@ If you want to control an independent actuator (a servo), follow these steps: 1. [Configure the output](../payloads/generic_actuator_control.md#generic-actuator-control-with-mavlink). 2. Create an instance of [px4_ros2::PeripheralActuatorControls](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1PeripheralActuatorControls.html) in the constructor of your mode. 3. Call the `set()` method to control the actuator(s). - This can be done independently of any active setpoints. + This can be done independently of any active setpoints. ### 텔레메트리 diff --git a/docs/ko/ros2/px4_ros2_interface_lib.md b/docs/ko/ros2/px4_ros2_interface_lib.md index 9088245e54..9f1a0a6163 100644 --- a/docs/ko/ros2/px4_ros2_interface_lib.md +++ b/docs/ko/ros2/px4_ros2_interface_lib.md @@ -7,17 +7,14 @@ At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. ::: -The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library that simplifies controlling and interacting with PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. -The library provides two high-level interfaces for developers: +The library provides three high-level interfaces for developers: 1. The [Control Interface](./px4_ros2_control_interface.md) allows developers to create and dynamically register modes written using ROS 2. It provides classes for sending different types of setpoints, ranging from high-level navigation tasks all the way down to direct actuator controls. 2. The [Navigation Interface](./px4_ros2_navigation_interface.md) enables sending vehicle position estimates to PX4 from ROS 2 applications, such as a VIO system. - - +3. [Waypoint Missions](./px4_ros2_waypoint_missions.md) allows waypoint missions to run entirely in ROS 2. ## Installation in a ROS 2 Workspace diff --git a/docs/ko/ros2/px4_ros2_msg_translation_node.md b/docs/ko/ros2/px4_ros2_msg_translation_node.md index 0bb22c79c1..9ba03f22e5 100644 --- a/docs/ko/ros2/px4_ros2_msg_translation_node.md +++ b/docs/ko/ros2/px4_ros2_msg_translation_node.md @@ -27,36 +27,36 @@ The following steps describe how to install and run the translation node on your 1. (Optional) Create a new ROS 2 workspace in which to build the message translation node and its dependencies: - ```sh - mkdir -p /path/to/ros_ws/src - ``` + ```sh + mkdir -p /path/to/ros_ws/src + ``` 2. Run the following helper script to copy the message definitions and translation node into your ROS workspace directory. - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` 3. Build and source the workspace. - ```sh - colcon build - source /path/to/ros_ws/install/setup.bash - ``` + ```sh + colcon build + source /path/to/ros_ws/install/setup.bash + ``` 4. Finally, run the translation node. - ```sh - ros2 run translation_node translation_node_bin - ``` + ```sh + ros2 run translation_node translation_node_bin + ``` - You should see an output similar to: + You should see an output similar to: - ```sh - [INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: - [INFO] [1734525720.729594413] [translation_node]: Registered services and versions: - ``` + ```sh + [INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: + [INFO] [1734525720.729594413] [translation_node]: Registered services and versions: + ``` With the translation node running, any simultaneously running ROS 2 application designed to communicate with PX4 can do so, as long as it uses message versions recognized by the node. The translation node will print a warning if it encounters an unknown topic version. @@ -295,111 +295,111 @@ The example describes the process of updating the `VehicleAttitude` message defi 1. **Create an Archived Definition of the Current Versioned Message** - Copy the versioned `.msg` topic message file (or `.srv` service message file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`), and append its message version to the file name. + Copy the versioned `.msg` topic message file (or `.srv` service message file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`), and append its message version to the file name. - For example:
- Copy `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` + For example:
+ Copy `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` 2. **Update Translation References to the Archived Definition** - Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. + Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. - For example, update references in those files:
+ For example, update references in those files:
- - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` - - Replace `#include ` → `#include ` + - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` + - Replace `#include ` → `#include ` 3. **Update the Versioned Definition** - Update the versioned `.msg` topic message file (or `.srv` service message file) with required changes. + Update the versioned `.msg` topic message file (or `.srv` service message file) with required changes. - First increment the `MESSAGE_VERSION` field. - Then update the message fields that prompted the version change. + First increment the `MESSAGE_VERSION` field. + Then update the message fields that prompted the version change. - For example, update `msg/versioned/VehicleAttitude.msg` from: + For example, update `msg/versioned/VehicleAttitude.msg` from: - ```txt - uint32 MESSAGE_VERSION = 3 - uint64 timestamp - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 3 + uint64 timestamp + ... + ``` - to + to - ```txt - uint32 MESSAGE_VERSION = 4 # Increment - uint64 timestamp - float32 new_field # Make definition changes - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 4 # Increment + uint64 timestamp + float32 new_field # Make definition changes + ... + ``` 4. **Add a New Translation Header** - Add a new version translation to bridge the archived version and the updated current version, by creating a new translation header. + Add a new version translation to bridge the archived version and the updated current version, by creating a new translation header. - For example, create a direct translation header `translation_node/translations/translation_vehicle_attitude_v4.h`: + For example, create a direct translation header `translation_node/translations/translation_vehicle_attitude_v4.h`: - ```c++ - // Translate VehicleAttitude v3 <--> v4 - #include - #include + ```c++ + // Translate VehicleAttitude v3 <--> v4 + #include + #include - class VehicleAttitudeV4Translation { - public: - using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; - static_assert(MessageOlder::MESSAGE_VERSION == 3); + class VehicleAttitudeV4Translation { + public: + using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; + static_assert(MessageOlder::MESSAGE_VERSION == 3); - using MessageNewer = px4_msgs::msg::VehicleAttitude; - static_assert(MessageNewer::MESSAGE_VERSION == 4); + using MessageNewer = px4_msgs::msg::VehicleAttitude; + static_assert(MessageNewer::MESSAGE_VERSION == 4); - static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; + static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; - static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { - msg_newer.timestamp = msg_older.timestamp; - msg_newer.timestamp_sample = msg_older.timestamp_sample; - msg_newer.q[0] = msg_older.q[0]; - msg_newer.q[1] = msg_older.q[1]; - msg_newer.q[2] = msg_older.q[2]; - msg_newer.q[3] = msg_older.q[3]; - msg_newer.delta_q_reset = msg_older.delta_q_reset; - msg_newer.quat_reset_counter = msg_older.quat_reset_counter; + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.timestamp_sample = msg_older.timestamp_sample; + msg_newer.q[0] = msg_older.q[0]; + msg_newer.q[1] = msg_older.q[1]; + msg_newer.q[2] = msg_older.q[2]; + msg_newer.q[3] = msg_older.q[3]; + msg_newer.delta_q_reset = msg_older.delta_q_reset; + msg_newer.quat_reset_counter = msg_older.quat_reset_counter; - // Populate `new_field` with some value - msg_newer.new_field = -1; - } + // Populate `new_field` with some value + msg_newer.new_field = -1; + } - static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { - msg_older.timestamp = msg_newer.timestamp; - msg_older.timestamp_sample = msg_newer.timestamp_sample; - msg_older.q[0] = msg_newer.q[0]; - msg_older.q[1] = msg_newer.q[1]; - msg_older.q[2] = msg_newer.q[2]; - msg_older.q[3] = msg_newer.q[3]; - msg_older.delta_q_reset = msg_newer.delta_q_reset; - msg_older.quat_reset_counter = msg_newer.quat_reset_counter; + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.timestamp_sample = msg_newer.timestamp_sample; + msg_older.q[0] = msg_newer.q[0]; + msg_older.q[1] = msg_newer.q[1]; + msg_older.q[2] = msg_newer.q[2]; + msg_older.q[3] = msg_newer.q[3]; + msg_older.delta_q_reset = msg_newer.delta_q_reset; + msg_older.quat_reset_counter = msg_newer.quat_reset_counter; - // Discards `new_field` from MessageNewer - } - }; + // Discards `new_field` from MessageNewer + } + }; - REGISTER_TOPIC_TRANSLATION_DIRECT(VehicleAttitudeV4Translation); - ``` + REGISTER_TOPIC_TRANSLATION_DIRECT(VehicleAttitudeV4Translation); + ``` - Version translation templates are provided here: + Version translation templates are provided here: - - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) - - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) - - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) + - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) + - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) + - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) 5. **Include New Headers in `all_translations.h`** - Add all newly created headers to [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h) so that the translation node can find them. + Add all newly created headers to [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h) so that the translation node can find them. - For example, append the following line to `all_translation.h`: + For example, append the following line to `all_translation.h`: - ```c++ - #include "translation_vehicle_attitude_v4.h" - ``` + ```c++ + #include "translation_vehicle_attitude_v4.h" + ``` Note that in the example above and in most cases, step 4 only requires the developer to create a direct translation for the definition change. This is because the changes only involved a single message. diff --git a/docs/ko/ros2/px4_ros2_navigation_interface.md b/docs/ko/ros2/px4_ros2_navigation_interface.md index d6a2bd6b80..fd625d7331 100644 --- a/docs/ko/ros2/px4_ros2_navigation_interface.md +++ b/docs/ko/ros2/px4_ros2_navigation_interface.md @@ -22,80 +22,80 @@ The following steps are required to get started: 2. Clone the repository into the workspace: - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - ::: info - To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. - See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + ::: info + To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. + See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). ::: 3. Build the workspace: - ```sh - cd .. - colcon build - ``` + ```sh + cd .. + colcon build + ``` 4. In a different shell, start PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (here we use Gazebo-Classic, but you can use any model or simulator) + (here we use Gazebo-Classic, but you can use any model or simulator) 5. In yet a different shell, run the micro XRCE agent (you can keep it running afterward): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 6. Back in the ROS 2 terminal, source the workspace you just built (in step 3) and run the [global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation/global_navigation) example, which periodically sends dummy global position updates: - ```sh - source install/setup.bash - ros2 run example_global_navigation_cpp example_global_navigation - ``` + ```sh + source install/setup.bash + ros2 run example_global_navigation_cpp example_global_navigation + ``` - You should get an output like this showing that the global interface is successfully sending position updates: + You should get an output like this showing that the global interface is successfully sending position updates: - ```sh - [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! - [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. - [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. - ``` + ```sh + [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! + [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. + [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. + ``` 7. In the PX4 shell, you can check that PX4 receives global position updates: - ```sh - listener aux_global_position - ``` + ```sh + listener aux_global_position + ``` - The output should look like: + The output should look like: - ```sh - TOPIC: aux_global_position - aux_global_position - timestamp: 46916000 (0.528000 seconds ago) - timestamp_sample: 46916000 (0 us before timestamp) - lat: 12.343210 - lon: 23.454320 - alt: 12.40000 - alt_ellipsoid: 0.00000 - delta_alt: 0.00000 - eph: 0.31623 - epv: 0.44721 - terrain_alt: 0.00000 - lat_lon_reset_counter: 0 - alt_reset_counter: 0 - terrain_alt_valid: False - dead_reckoning: False - ``` + ```sh + TOPIC: aux_global_position + aux_global_position + timestamp: 46916000 (0.528000 seconds ago) + timestamp_sample: 46916000 (0 us before timestamp) + lat: 12.343210 + lon: 23.454320 + alt: 12.40000 + alt_ellipsoid: 0.00000 + delta_alt: 0.00000 + eph: 0.31623 + epv: 0.44721 + terrain_alt: 0.00000 + lat_lon_reset_counter: 0 + alt_reset_counter: 0 + terrain_alt_valid: False + dead_reckoning: False + ``` 8. Now you are ready to use the navigation interface to send your own position updates. diff --git a/docs/ko/ros2/px4_ros2_waypoint_missions.md b/docs/ko/ros2/px4_ros2_waypoint_missions.md new file mode 100644 index 0000000000..4a82072ff0 --- /dev/null +++ b/docs/ko/ros2/px4_ros2_waypoint_missions.md @@ -0,0 +1,190 @@ +# PX4 ROS 2 Waypoint Missions + + + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) provides a high-level interface for executing ROS-based waypoint missions in ROS 2. +The main use-case is for creating missions where a custom behavior is required, such as a pickup action within a mission. + +:::warning +ROS 2 missions are not compatible with MAVLink mission definitions, plan files, or ground stations. +They completely bypass the existing PX4 mission mode and waypoint logic, and cannot be planned or displayed within a ground station. +::: + +ROS 2 waypoint missions are effectively special PX4 ROS 2 custom modes that are run based on the content of a [JSON mission definition](#mission-definition). +Mission definitions can contain actions that reference existing PX4 modes, such as Takeoff mode or RTL, and can also be extended with arbitrary custom actions written in ROS. +A [mode executor](px4_ros2_control_interface.md#mode-executor) is used to schedule the modes. + +Mission definitions can be hard coded in the custom mission mode (either in code or statically loaded from a JSON string), or directly generated within the application. +They can also be dynamically loaded based on modification of a particular JSON file — this allows for building a more generic mission framework with a fixed set of custom actions. +The file can then be written by any other application, for example a HTTP or MAVFTP server. + +The current implementation only supports multicopters but is designed to be extendable to any other vehicle type. + +## Comparison to PX4/MAVLink Missions + +There are some benefits and drawbacks to using ROS-based missions, which are provided in the following paragraphs. + +### Benefits + +- Allows to extend mission capabilities by registering custom actions. +- More control over how the mission is executed. + A custom trajectory executor can be implemented, which can use any of the existing PX4 setpoint types to track the trajectory. +- Reduced complexity on the flight controller side by running non-safety-critical and non-real-time code on a more high-level companion computer. +- It can be extended to support other trajectory types, like Bezier or Dubin curves. + +### Drawbacks + +- QGroundControl currently does not display the mission or progress during execution, and cannot upload or download a mission. + Therefore you will need another mechanism to provide a mission, such as from a web server, a custom GCS, or by generating it directly inside the application. +- The current implementation only supports multicopters (it uses the [GotoSetpointType](../ros2/px4_ros2_control_interface.md#go-to-setpoint-multicoptergotosetpointtype), which only works for multicopters, and VTOL in MC mode). + It is designed to be extendable to any other vehicle type. + +## 개요 + +This diagram provides a conceptual overview of the main classes and their interactions: + +![Waypoint missions overview diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg) + + + +Missions can be defined in [JSON](#mission-definition), either as a file, or directly inside the application. +There is a file change monitor (`MissionFileMonitor`), that can be used to automatically load a mission from a specific file whenever it is created by another application (e.g. upload via MAVFTP or a cloud service). + +The **`MissionExecutor`** class contains the state machine to progress the mission index, and is at the core of the implementation: + +- Internally, it builds on top of the [Modes and Mode Executors](px4_ros2_control_interface.md#overview) and registers itself through a custom mode and executor with PX4. +- It handles switching in and out of missions: it gets activated when the user switches to the custom mode that represents the mission and the vehicle is armed. + The mode name can be customized (`My Mission` in the example below). + The mission can be paused, which makes the vehicle switch into _Hold mode_. + To resume the mission, the custom mode has to be selected again. +- When an action switches into another mode (for example Takeoff), QGroundControl will display this mode until it is completed. + The mission executor will then automatically continue. +- Custom actions can be registered. +- The mission can be set. + It then checks that all the actions which the mission defines are available and can be run. +- The state can be stored persistently by providing a file name, allowing for battery swapping. + +The **`ActionInterface`** is an interface class for custom actions. +They are identified by a name, and any number of these can be registered with the `MissionExecutor`. +A custom action is then run whenever a mission item with matching name is executed, and any extra arguments from the JSON definition are passed as arguments (for example an altitude for a takeoff action). +Actions can call other actions, run any mode (PX4 or external by its ID), run a trajectory, or run any other external action before deciding when to continue the mission. + +There is a set of default actions, for example for RTL, Land, etc. +These simply trigger the corresponding PX4 mode. +They can be disabled or replaced with custom implementations. +There are also some special actions (which can be replaced as well): + +- `OnFailure`: this is called in case of a failure, e.g. a mode switch failed, a non-existing action is called (by another action) or by an explicit call to `MissionExecutor::abort()`. + The default is to run RTL, with fallback to Land. +- `OnResume`: this is called when resuming a mission (either from the ground or in-air). + It handles a number of cases: + - when called with an argument `action="storeState"`: this can be used to store the current position when the mission is deactivated, so it can be resumed from the same position. + Currently it does not store anything. + - otherwise, when called without a valid mission index or 0, it directly continues. + - otherwise, when called while in-air, it also directly continues. + - otherwise, if landed and if the current mission item is an action that supports resuming from landed, it continues to let the action handle the resuming. + - otherwise, if landed, it finds the takeoff action from the mission, runs it, and then flies to the previous waypoint from the current index to continue the mission. +- `ChangeSettings`: this can be used to change the mission settings, such as the velocity. + The settings are applied to all following items in the mission. + +The **`TrajectoryExecutorInterface`** is an interface class to execute segments of a trajectory. +It can use any setpoint that PX4 and the current vehicle supports for tracking the trajectory. +This class is vehicle-type specific. +The current default implementation (`multicopter::WaypointTrajectoryExecutor`) uses a Goto setpoint (and thus is limited to multicopters). +The default can be replaced with a custom implementation. + +## 사용법 + +The following provides a small example. +It defines a custom action and a mission that uses it. + +```c++ +class CustomAction : public px4_ros2::ActionInterface { +public: + CustomAction(px4_ros2::ModeBase & mode) : _node(mode.node()) { } + + std::string name() const override {return "customAction";} + + void run( + const std::shared_ptr & handler, + const px4_ros2::ActionArguments & arguments, + const std::function & on_completed) override + { + RCLCPP_INFO(_node.get_logger(), "Running custom action"); + // Do something... + + on_completed(); + } +private: + rclcpp::Node & _node; +}; + +class MyMission { +public: + MyMission(const std::shared_ptr & node) : _node(node) + { + const auto mission = px4_ros2::Mission(nlohmann::json::parse(R"( + { + "version": 1, + "mission": { + "items": [ + { + "type": "takeoff" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.3977419, + "y": 8.5455939, + "z": 500, + "frame": "global" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.39791657, + "y": 8.54595214, + "z": 500, + "frame": "global" + }, + { + "type": "customAction" + }, + { + "type": "rtl" + } + ] + } + } +)")); + _mission_executor = std::make_unique("My Mission", + px4_ros2::MissionExecutor::Configuration().addCustomAction(), *node); + + if (!_mission_executor->doRegister()) { + throw std::runtime_error("Failed to register mission executor"); + } + _mission_executor->setMission(mission); + + _mission_executor->onProgressUpdate([&](int current_index) { + RCLCPP_INFO(_node->get_logger(), "Current mission index: %i", current_index); + }); + _mission_executor->onCompleted([&] { + RCLCPP_INFO(_node->get_logger(), "Mission completed callback"); + }); + } + +private: + std::shared_ptr _node; + std::unique_ptr _mission_executor; +}; +``` + +A full example with a few custom actions can be found under [github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include). + +## Mission Definition + +The mission JSON file can contain mission defaults and a list of mission items, including user-defined types with custom arguments. +Waypoint coordinates currently need to be defined in global frame, and other frame types might be added in future. + +The schema can be found under [github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml). +It provides more details and can be used to validate a JSON file. diff --git a/docs/ko/ros2/user_guide.md b/docs/ko/ros2/user_guide.md index d6c567dcd7..64e10d82e8 100644 --- a/docs/ko/ros2/user_guide.md +++ b/docs/ko/ros2/user_guide.md @@ -97,48 +97,48 @@ To install ROS 2 and its dependencies: 1. Install ROS 2. - :::: tabs + :::: tabs - ::: tab humble - To install ROS 2 "Humble" on Ubuntu 22.04: + ::: tab humble + To install ROS 2 "Humble" on Ubuntu 22.04: - ```sh - sudo apt update && sudo apt install locales - sudo locale-gen en_US en_US.UTF-8 - sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 - export LANG=en_US.UTF-8 - sudo apt install software-properties-common - sudo add-apt-repository universe - sudo apt update && sudo apt install curl -y - sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null - sudo apt update && sudo apt upgrade -y - sudo apt install ros-humble-desktop - sudo apt install ros-dev-tools - source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc - ``` + ```sh + sudo apt update && sudo apt install locales + sudo locale-gen en_US en_US.UTF-8 + sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + export LANG=en_US.UTF-8 + sudo apt install software-properties-common + sudo add-apt-repository universe + sudo apt update && sudo apt install curl -y + sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null + sudo apt update && sudo apt upgrade -y + sudo apt install ros-humble-desktop + sudo apt install ros-dev-tools + source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc + ``` - The instructions above are reproduced from the official installation guide: [Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). + The instructions above are reproduced from the official installation guide: [Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). + You can install _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - ::: tab foxy - To install ROS 2 "Foxy" on Ubuntu 20.04: + ::: tab foxy + To install ROS 2 "Foxy" on Ubuntu 20.04: - - Follow the official installation guide: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). + - Follow the official installation guide: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). + You can install _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - :::: + :::: 2. Some Python dependencies must also be installed (using **`pip`** or **`apt`**): - ```sh - pip install --user -U empy==3.3.4 pyros-genmsg setuptools - ``` + ```sh + pip install --user -U empy==3.3.4 pyros-genmsg setuptools + ``` ### Setup Micro XRCE-DDS Agent & Client @@ -155,22 +155,22 @@ To setup and start the agent: 2. Enter the following commands to fetch and build the agent from source: - ```sh - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` 3. Start the agent with settings for connecting to the uXRCE-DDS client running on the simulator: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` The agent is now running, but you won't see much until we start PX4 (in the next step). @@ -187,31 +187,31 @@ To start the simulator (and client): 1. Open a new terminal in the root of the **PX4 Autopilot** repo that was installed above. - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - - Start a PX4 [Gazebo](../sim_gazebo_gz/index.md) simulation using: + - Start a PX4 [Gazebo](../sim_gazebo_gz/index.md) simulation using: - ```sh - make px4_sitl gz_x500 - ``` + ```sh + make px4_sitl gz_x500 + ``` ::: - ::: tab foxy + ::: tab foxy - - Start a PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) simulation using: + - Start a PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) simulation using: - ```sh - make px4_sitl gazebo-classic - ``` + ```sh + make px4_sitl gazebo-classic + ``` ::: - :::: + :::: The agent and client are now running they should connect. @@ -261,52 +261,52 @@ To create and build the workspace: 2. Create and navigate into a new workspace directory using: - ```sh - mkdir -p ~/ws_sensor_combined/src/ - cd ~/ws_sensor_combined/src/ - ``` + ```sh + mkdir -p ~/ws_sensor_combined/src/ + cd ~/ws_sensor_combined/src/ + ``` - ::: info - A naming convention for workspace folders can make it easier to manage workspaces. + ::: info + A naming convention for workspace folders can make it easier to manage workspaces. ::: 3. Clone the example repository and [px4_msgs](https://github.com/PX4/px4_msgs) to the `/src` directory (the `main` branch is cloned by default, which corresponds to the version of PX4 we are running): - ```sh - git clone https://github.com/PX4/px4_msgs.git - git clone https://github.com/PX4/px4_ros_com.git - ``` + ```sh + git clone https://github.com/PX4/px4_msgs.git + git clone https://github.com/PX4/px4_ros_com.git + ``` 4. Source the ROS 2 development environment into the current terminal and compile the workspace using `colcon`: - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd .. - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd .. - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/foxy/setup.bash + colcon build + ``` ::: - :::: + :::: - This builds all the folders under `/src` using the sourced toolchain. + This builds all the folders under `/src` using the sourced toolchain. #### Running the Example @@ -322,42 +322,42 @@ In a new terminal: 1. Navigate into the top level of your workspace directory and source the ROS 2 environment (in this case "Humble"): - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/humble/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/humble/setup.bash + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/foxy/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/foxy/setup.bash + ``` ::: - :::: + :::: 2. Source the `local_setup.bash`. - ```sh - source install/local_setup.bash - ``` + ```sh + source install/local_setup.bash + ``` 3. Now launch the example. - Note here that we use `ros2 launch`, which is described below. + Note here that we use `ros2 launch`, which is described below. - ```sh - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` If this is working you should see data being printed on the terminal/console where you launched the ROS listener: @@ -385,18 +385,18 @@ If you were to use incompatible [message versions](../middleware/uorb.md#message 1. Include the [Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) into the example workspace or a separate workspace by running the following script: - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` 2. Build and run the translation node: - ```sh - colcon build - source install/local_setup.bash - ros2 run translation_node translation_node_bin - ``` + ```sh + colcon build + source install/local_setup.bash + ros2 run translation_node translation_node_bin + ``` ## Controlling a Vehicle diff --git a/docs/ko/sensor/accelerometer.md b/docs/ko/sensor/accelerometer.md index da249b1934..6de3d5bd21 100644 --- a/docs/ko/sensor/accelerometer.md +++ b/docs/ko/sensor/accelerometer.md @@ -5,7 +5,7 @@ PX4 uses accelerometer data for velocity estimation. You should not need to attach an accelometer as a stand-alone external device: - Most flight controllers, such as those in the [Pixhawk Series](../flight_controller/pixhawk_series.md), include an accelerometer as part of the flight controller's [Inertial Motion Unit (IMU)](https://en.wikipedia.org/wiki/Inertial_measurement_unit). -- Gyroscopes are present as part of an [external INS, ARHS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). +- Gyroscopes are present as part of an [external INS, AHRS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). The accelerometer must be calibrated before first use of the vehicle: diff --git a/docs/ko/sensor/barometer.md b/docs/ko/sensor/barometer.md index baef4bef21..77195062df 100644 --- a/docs/ko/sensor/barometer.md +++ b/docs/ko/sensor/barometer.md @@ -30,17 +30,51 @@ If needed, you can: - Change the selection order of barometers using the [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) parameters for each barometer. - Disable a barometer by setting its [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) value to `0`. -## Calibration +## Baro Auto-Calibration (Developers) -Barometers don't require calibration. +:::tip +This section documents the automated calibration mechanisms that ensure accurate altitude measurements throughout flight operations. +It is intended primarily for a developer audience who want to understand the underlying mechanisms. +::: - +The system implements two complementary calibration approaches that work together to maintain altitude measurement precision. +Both calibrations are initiated at the beginning after a system boot. +Relative calibration is performed first, followed by GNSS-barometric calibration. -## 개발자 정보 +### Relative Calibration + +Relative baro calibration is **always enabled** and operates automatically during system initialization. +This calibration establishes offset corrections for all secondary baro sensors relative to the primary (selected) sensor. + +This calibration: + +- Eliminates altitude jumps when switching between baro sensors during flight. +- Ensures consistent altitude readings across all available baro sensors. +- Maintains seamless sensor redundancy and failover capability. + +### GNSS-Baro Calibration + +:::info +GNSS-baro calibration requires an operational GNSS receiver with vertical accuracy (EPV) ≤ 8 meters. +Relative calibration must already have completed. +::: + +GNSS-baro calibration adjusts baro sensor offsets to align with absolute altitude measurements from the GNSS receiver. +This calibration is controlled by the [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) parameter (enabled by default). + +The algorithm monitors GNSS quality, collects altitude differences over a 2-second filtered window, and verifies stability within 4m tolerance. +Once stable, it uses binary search to calculate pressure offsets that align baro altitude with GNSS altitude (0.1m precision), then applies the offset to all sensors and saves the parameters. + +참고: + +- **EKF Independence**: GNSS-baro calibration operates independently of EKF2 altitude fusion settings. +- **Execution Timing**: Calibration runs even when [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) altitude fusion is disabled. +- **One-Time Process**: Each calibration session completes once per system startup. +- **Persistence**: Calibration offsets are saved to parameters and persist across reboots. +- **Faulty GNSS Vulnerability**: If GNSS data is faulty during boot, the calibration will use incorrect altitude reference. + See [Faulty GNSS Data During Boot](../advanced_config/tuning_the_ecl_ekf.md#faulty-gnss-data-during-boot) for mitigation strategies. + +## See Also - [Baro driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer) - [Modules Reference: Baro (Driver)](../modules/modules_driver_baro.md) documentation. diff --git a/docs/ko/sensor/inertial_navigation_systems.md b/docs/ko/sensor/inertial_navigation_systems.md index 4103634ea0..8a2ec11989 100644 --- a/docs/ko/sensor/inertial_navigation_systems.md +++ b/docs/ko/sensor/inertial_navigation_systems.md @@ -2,13 +2,34 @@ PX4 typically runs on flight controllers that include an IMU, such as the Pixhawk series, and fuse the sensor data along with GNSS information in the EKF2 estimator to determine vehicle attitude, heading, position, and velocity. -However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing the EKF. +However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing EKF2. -Systems that can be used in this way include: +## Supported INS Systems + +INS systems that can be used as a replacement for EKF2 in PX4: - [InertialLabs](../sensor/inertiallabs.md) +- [MicroStrain](../sensor/microstrain.md): Includes VRU, AHRS, INS, and GNSS/INS devices. +- [SBG Systems](../sensor/sbgecom.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. - [VectorNav](../sensor/vectornav.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. +## PX4 Firmware + +The driver module for your INS system may not be included in the PX4 firmware for your flight controller by default. + +You can check by searching the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6c/default.px4board#L25) configuration file for your target board for either: + +- `CONFIG_COMMON_INS`, which includes drivers for [all INS systems](https://github.com/PX4/PX4-Autopilot/blob/main/src/drivers/ins/Kconfig). +- The key for the particular INS system you are using, such as: + - `CONFIG_DRIVERS_INS_ILABS` + - `CONFIG_DRIVERS_INS_MICROSTRAIN` + - `CONFIG_DRIVERS_INS_VECTORNAV` + +If the required key is not present you can include the module in firmware by adding the key to the `default.px4board` file, or using the [kconfig board configuration tool](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) and then select the driver you want (`Drivers -> INS`). +Note that if you're working on a flight controller where flash memory is limited, you're better off installing just the modules you need. + +You will then need to rebuild the firmware. + ## Glossary ### Inertial Measurement Unit (IMU) diff --git a/docs/ko/sensor/inertiallabs.md b/docs/ko/sensor/inertiallabs.md index 63c9718c3b..b748a2fee3 100644 --- a/docs/ko/sensor/inertiallabs.md +++ b/docs/ko/sensor/inertiallabs.md @@ -57,11 +57,11 @@ To use the Inertial Labs driver: - For external INS, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `INS`. - For raw inertial sensors, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `Sensors Only`. - You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). + You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). - ::: tip - In most cases the external IMU is the highest-numbered. - You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + ::: tip + In most cases the external IMU is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. ::: diff --git a/docs/ko/sensor/microstrain.md b/docs/ko/sensor/microstrain.md new file mode 100644 index 0000000000..1cb0e1b8d5 --- /dev/null +++ b/docs/ko/sensor/microstrain.md @@ -0,0 +1,219 @@ +# MicroStrain (INS, IMU, VRU, AHRS) + +MicroStrain by HBK provides high-performance inertial sensors engineered for reliability and precision in challenging environments. +Widely used across industries like aerospace, robotics, industrial automation, and research, MicroStrain sensors are optimized for real-time, accurate motion tracking and orientation data. + +![CV7](../../assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png) + +The driver currently supports the following hardware: + +- [`MicroStrain CV7-AR`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/vertical-reference-units--vru-/3dm-cv7-ar): Inertial Measurement Unit (IMU) and Vertical Reference Unit (VRU) +- [`MicroStrain CV7-AHRS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/attitude-and-heading-reference-systems--ahrs-/3dm-cv7-ahrs): Inertial Measurement Unit (IMU) and Attitude Heading Reference System (AHRS) +- [`MicroStrain CV7-INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS). +- [`MicroStrain CV7-GNSS/INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-gnss-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS) combined with dual multiband (GNSS) receivers. + +PX4 can use these sensors to provide raw IMU data for EKF2 or to replace EKF2 as an external INS. +For more information, including user manuals and datasheets, please refer to the sensors product page. + +## 구매처 + +MicroStrain sensors can be purchased through HBK's official [MicroStrain product page](https://www.hbkworld.com/en/products/transducers/inertial-sensors) or through authorized distributors globally. +For large orders, custom requirements, or technical inquiries, reach out directly to [sales](https://www.hbkworld.com/en/contact-us/contact-sales-microstrain) + +## 하드웨어 설정 + +### 배선 + +Connect the main UART port of the MicroStrain sensor to any unused serial port on the flight controller. +This port needs to be specified while starting the device. + +### 장착 + +The MicroStrain sensor can be mounted in any orientation. +The default coordinate system uses X for the front, Y for the right, and Z for down, with directions marked on the device. + +## 펌웨어 설정 + +### PX4 설정 + +To use the MicroStrain driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_MICROSTRAIN` or `CONFIG_COMMON_INS`. + +2. Configure the driver mode by setting [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) + + - To use the MicroStrain sensor to provide raw IMU data to EKF2 + + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 0 + 2. Update the [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) parameter to account for the added MicroStrain sensor. + 3. Enable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 1 + 4. To prioritize MicroStrain sensor output, adjust the priority level of individual sensors from 0-100 using the following parameters: + + - [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO) + - [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO) + - [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO) + - [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) + + where `n` corresponds to the index of the corresponding sensor. + + ::: tip + Sensors can be identified by their device id, which can be found by checking the parameters: + + - [CAL_ACCn_ID](../advanced_config/parameter_reference.md#CAL_ACC0_ID) + - [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) + - [CAL_MAGn_ID](../advanced_config/parameter_reference.md#CAL_MAG0_ID) + - [CAL_BAROn_ID](../advanced_config/parameter_reference.md#CAL_BARO0_ID) + + +::: + + - To use the MicroStrain sensor as an external INS + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 1 + 2. Disable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 0 + +3. Reboot and start the driver + - `microstrain start -d ` + - To start the driver automatically when the flight controller powers on, set [SENS_MS_CFG](../advanced_config/parameter_reference.md#SENS_MS_CFG) to the sensor’s connected port. + +## MicroStrain Configuration + +1. Rates: + + - By default, accel and gyro data are published at 500 Hz, magnetometer at 50 Hz, and barometric pressure at 50 Hz. + This can be changed by adjusting the following parameters: + + - [MS_IMU_RATE_HZ](../advanced_config/parameter_reference.md#MS_IMU_RATE_HZ) + - [MS_MAG_RATE_HZ](../advanced_config/parameter_reference.md#MS_MAG_RATE_HZ) + - [MS_BARO_RATE_HZ](../advanced_config/parameter_reference.md#MS_BARO_RATE_HZ) + + - Global position, local position, attitude and odometry will be published at 250 Hz by default. + This can be configured via: + + - [MS_FILT_RATE_HZ](../advanced_config/parameter_reference.md#MS_FILT_RATE_HZ) + + - For the CV7-GNSS/INS, the GNSS receiver 1 and 2 will publish data at 5Hz by default. + This can be changed using: + + - [MS_GNSS_RATE_HZ](../advanced_config/parameter_reference.md#MS_GNSS_RATE_HZ) + + - The driver will automatically configure data outputs based on the specific sensor model and available data streams. + + - The driver is scheduled to run at twice the fastest configured data rate. + +2. Aiding measurements: + + - If supported, GNSS position and velocity aiding are always enabled. + + - Internal/external magnetometer and heading aiding, as well as optical flow aiding, are disabled by default. They can be enabled using the following parameters: + + - [MS_INT_MAG_EN](../advanced_config/parameter_reference.md#MS_INT_MAG_EN) + - [MS_INT_HEAD_EN](../advanced_config/parameter_reference.md#MS_INT_HEAD_EN) + - [MS_EXT_HEAD_EN](../advanced_config/parameter_reference.md#MS_EXT_HEAD_EN) + - [MS_EXT_MAG_EN](../advanced_config/parameter_reference.md#MS_EXT_MAG_EN) + - [MS_OPT_FLOW_EN](../advanced_config/parameter_reference.md#MS_OPT_FLOW_EN) + + - The aiding frames for external sources can be configured using the following parameters: + + - [MS_EHEAD_YAW](../advanced_config/parameter_reference.md#MS_EHEAD_YAW) + - [MS_EMAG_ROLL](../advanced_config/parameter_reference.md#MS_EMAG_ROLL) + - [MS_EMAG_PTCH](../advanced_config/parameter_reference.md#MS_EMAG_PTCH) + - [MS_EMAG_YAW](../advanced_config/parameter_reference.md#MS_EMAG_YAW) + - [MS_OFLW_OFF_X](../advanced_config/parameter_reference.md#MS_OFLW_OFF_X) + - [MS_OFLW_OFF_Y](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Y) + - [MS_OFLW_OFF_Z](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Z) + - [SENS_FLOW_ROT](../advanced_config/parameter_reference.md#SENS_FLOW_ROT) + + - The uncertainty for optical flow and external magnetometer aiding must be specified using the following parameters: + + - [MS_EMAG_UNCERT](../advanced_config/parameter_reference.md#MS_EMAG_UNCERT) + - [MS_OFLW_UNCERT](../advanced_config/parameter_reference.md#MS_OFLW_UNCERT) + + ::: tip + + 1. When optical flow aiding is enabled, the sensor uses the `vehicle_optical_flow_vel` output from the flight controller as a body-frame velocity aiding measurement. + 2. If the MicroStrain sensor does not support these aiding sources but they are enabled, sensor initialization will fail. + + +::: + +3. Initial heading alignment: + + - Initial heading alignment is set to kinematic by default. This can be changed by adjusting + + - [MS_ALIGNMENT](../advanced_config/parameter_reference.md#MS_ALIGNMENT) + +4. GNSS Aiding Source Control (GNSS/INS only) + + - The Source of the GNSS aiding data can be configured using: + + - [MS_GNSS_AID_SRC](../advanced_config/parameter_reference.md#MS_GNSS_AID_SRC) + +5. Sensor to vehicle transform: + + - If the sensor is mounted in an orientation different from the vehicle frame. A sensor to vehicle transform can be enabled using + + - [MS_SVT_EN](../advanced_config/parameter_reference.md#MS_SVT_EN) + + - The transform is defined using the following parameters + + - [MS_SENSOR_ROLL](../advanced_config/parameter_reference.md#MS_SENSOR_ROLL) + - [MS_SENSOR_PTCH](../advanced_config/parameter_reference.md#MS_SENSOR_PTCH) + - [MS_SENSOR_YAW](../advanced_config/parameter_reference.md#MS_SENSOR_YAW) + +6. IMU ranges: + + - The accelerometer and gyroscope ranges on the device are configurable using: + + - [MS_ACCEL_RANGE](../advanced_config/parameter_reference.md#MS_ACCEL_RANGE) + - [MS_GYRO_RANGE](../advanced_config/parameter_reference.md#MS_GYRO_RANGE) + + ::: tip + Available range settings depend on the specific [sensor](https://www.hbkworld.com/en/products/transducers/inertial-sensors) and can be found in the corresponding user manual. + By default, the ranges are not changed. + + +::: + +7. GNSS Lever arm offsets: + + - The lever arm offset for the external GNSS receiver can be configured using: + + - [MS_GNSS_OFF1_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_X) + - [MS_GNSS_OFF1_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Y) + - [MS_GNSS_OFF1_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Z) + + - For dual-antenna configurations, the second GNSS receiver’s offset is configured using: + + - [MS_GNSS_OFF2_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_X) + - [MS_GNSS_OFF2_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Y) + - [MS_GNSS_OFF2_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Z) + +## Published Data + +The MicroStrain driver continuously publishes sensor data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) +- [sensor_baro](../msg_docs/SensorBaro.md) + +For GNSS/INS devices, GPS data is also published to: + +- [sensor_gps](../msg_docs/SensorGps.md) + +If used as an external INS replacing EKF2, it publishes: + +- [vehicle_global_position](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) +- [vehicle_odometry](../msg_docs/VehicleOdometry.md) + +otherwise the same data is published to the following topics + +- `external_ins_global_position` +- `external_ins_attitude` +- `external_ins_local_position` + +:::tip +Published topics can be viewed using the `listener` command. +::: diff --git a/docs/ko/sensor/rangefinders.md b/docs/ko/sensor/rangefinders.md index a587ddd6c6..067cc0431e 100644 --- a/docs/ko/sensor/rangefinders.md +++ b/docs/ko/sensor/rangefinders.md @@ -15,11 +15,69 @@ This is a subset of the rangefinders that can be used with PX4. There may also be other DroneCAN rangefinders than those listed here. ::: -### ARK Flow & AKR Flow MR +| Rangefinder | Technology | Range (min – max) | 연결 | NDAA | 참고 | +| ------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------- | ------------------------------------------------------ | +| [Ainstein US-D1 Standard Radar Altimeter] | Microwave radar | ~50 m | UART | ✔️ | | +| [ARK DIST SR] | ToF (850 nm IR) | 8 cm to ~30 m | DroneCAN, UART | ✔️ | | +| [ARK DIST MR] | ToF (IR) | 8 cm to ~50 m | DroneCAN, UART | ✔️ | | +| [Benewake TFmini] | ToF (IR laser) | ~12 m | UART | ~ | | +| [Holybro ST VL53L1X Lidar] | ToF (IR) | up to ~4 m | I2C | ~ | | +| [LeddarOne] | ToF (IR) | 1 cm – 40 m | UART | ~ | | +| [Lidar-Lite] | ToF (IR laser) | 5 cm – 40 m | I2C, PWM | ~ | | +| [LightWare SF11/C] | ToF (IR laser) | up to ~120 m | UART, I2C | ~ | | +| [LightWare LW20/C] | ToF (IR laser) | up to ~100 m | I2C | ~ | Waterproof (IP67) + servo | +| [LightWare SF45/B] | ToF (IR laser) | ~50 m | UART | ~ | Rotary lidar (collision prevention) | +| [MaxBotix I2CXL-MaxSonar-EZ] | Ultrasonic | | I2C | ~ | | +| [RaccoonLab Cyphal & DroneCAN µRANGEFINDER] | ToF (IR) | ~0.1 m – ~8 m | DroneCAN, Cyphal | ~ | | +| [TeraRanger Evo 60 m] | ToF (IR) | 0.5 m – 60 m | I2C | ~ | | +| [TeraRanger Evo 600Hz] | ToF (IR) | 0.75 m – 8 m | I2C | ~ | High update rate (600 Hz) | +| [LightWare SF02] _(disc.)_ | ToF (IR laser) | ~50 m | UART | ~ | Discontinued | +| [LightWare SF10/A] _(disc.)_ | ToF (IR laser) | ~25 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/B] _(disc.)_ | ToF (IR laser) | ~50 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/C] _(disc.)_ | ToF (IR laser) | ~100 m | UART, I2C | ~ | Discontinued | +| [Lanbao PSK-CM8JL65-CC5] _(disc.)_ | ToF (IR) | 0.17 m – 8 m | UART | ✖️ | Discontinued | +| [TeraRanger One] _(disc.)_ | ToF (IR) | ~0.2 m – ~14 m (typical) | I2C (adapter required) | ~ | Discontinued | -[ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md) are open-source Time-of-Flight (ToF) and optical flow sensor modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. -CAN1 포트를 통해 비행 콘트롤러에 연결할 수 있으므로, CAN2 포트를 통해 추가 센서를 연결할 수 있습니다. -It supports [DroneCAN](../dronecan/index.md), runs [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and is packed into a tiny form factor. +[Ainstein US-D1 Standard Radar Altimeter]: ../sensor/ulanding_radar.md +[ARK DIST SR]: ../dronecan/ark_dist.md +[ARK DIST MR]: ../dronecan/ark_dist_mr.md +[Benewake TFmini]: ../sensor/tfmini.md +[Holybro ST VL53L1X Lidar]: #holybro-st-vl53l1x-lidar +[Lanbao PSK-CM8JL65-CC5]: ../sensor/cm8jl65_ir_distance_sensor.md +[LeddarOne]: ../sensor/leddar_one.md +[Lidar-Lite]: ../sensor/lidar_lite.md +[LightWare Lidar]: ../sensor/sfxx_lidar.md +[LightWare SF11/C]: ../sensor/sfxx_lidar.md +[LightWare LW20/C]: ../sensor/sfxx_lidar.md +[LightWare SF45/B]: ../sensor/sfxx_lidar.md +[LightWare SF02]: ../sensor/sfxx_lidar.md +[LightWare SF10/A]: ../sensor/sfxx_lidar.md +[LightWare SF10/B]: ../sensor/sfxx_lidar.md +[LightWare SF10/C]: ../sensor/sfxx_lidar.md +[MaxBotix I2CXL-MaxSonar-EZ]: #maxbotix-i2cxl-maxsonar-ez +[TeraRanger Evo 60 m]: ../sensor/teraranger.md +[TeraRanger Evo 600Hz]: ../sensor/teraranger.md +[TeraRanger One]: ../sensor/teraranger.md + +These adaptors allows you to connect a non-CAN rangefinder via the CAN interface. +Note that the range depends on the connected rangefinder + +| Adaptor | 연결 | NDAA | +| ------------------------------------------------------- | ---------------- | ----------------- | +| **Avionics Anonymous UAVCAN Laser Altimeter Interface** | DroneCAN | ~ | +| [RaccoonLab Cyphal & DroneCAN Rangefinder Adapter] | DroneCAN, Cyphal | ~ | + +[RaccoonLab Cyphal & DroneCAN µRANGEFINDER]: #raccoonlab-cyphal-and-dronecan-μrangefinder +[RaccoonLab Cyphal & DroneCAN Rangefinder Adapter]: #raccoonlab-cyphal-and-dronecan-rangefinder-adapter + +Note that some [Optical Flow](../sensor/optical_flow.md) sensors also include a rangefinder, such as [ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md). + +### ARK DIST SR & ARK DIST MR + +[ARK DIST SR](../dronecan/ark_dist.md) and [ARK DIST MR](../dronecan/ark_dist_mr.md) are open-source Time-of-Flight (ToF) rangefinder modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. + +The sensors support [DroneCAN](../dronecan/index.md), run [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and are packed into a tiny form factor. +They can be connected to a flight controller via its `CAN1` port, allowing additional sensors to connected through the `CAN2` port. ### Holybro ST VL53L1X Lidar @@ -146,11 +204,11 @@ To view the rangefinder output: 1. Open the menu **Q > Select Tool > Analyze Tools**: - ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) + ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) 2. Select the message `DISTANCE_SENSOR`, and then check the plot checkbox against `current_distance`. - The tool will then plot the result: - ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) + The tool will then plot the result: + ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) ### QGroundControl MAVLink Console diff --git a/docs/ko/sensor/sbgecom.md b/docs/ko/sensor/sbgecom.md new file mode 100644 index 0000000000..8c721b5ecb --- /dev/null +++ b/docs/ko/sensor/sbgecom.md @@ -0,0 +1,157 @@ +# SBG Systems INS/AHRS (Pulse, Ellipse, etc.) + +[SBG-Systems](https://www.sbg-systems.com/) designs, manufactures, and support an extensive range of state-of-the-art inertial sensors such as Inertial Measurement Units (IMU), Attitude and Heading Reference Systems (AHRS), Inertial Navigation Systems with embedded GNSS (INS/GNSS), and so on. + +PX4 supports [all SBG Systems products](https://www.sbg-systems.com/products/) and can use these as an [external INS](../sensor/inertial_navigation_systems.md) (bypassing/replacing the EKF2 estimator), or as a source of raw sensor data provided to the navigation estimator. + +![Ellipse](../../assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png) + +## 개요 + +SBG Systems products provide a range of benefits to PX4 users and can be integrated for: + +- Higher accuracy heading, pitch, and roll estimates +- More robust and reliable GNSS positioning +- Improved positioning and attitude performance in GNSS-contested environments +- Performance under challenging dynamic conditions (e.g. catapult launches, VTOL operations, high-g or high angular rate operations) + +The sbgECom PX4 driver is streamlined to provide a simple plug-and-play architecture, removing engineering obstacles and allowing the acceleration of the design, development, and launch of platforms to keep pace with the rapid rate of innovation. + +The driver supports [all SBG Systems products](https://www.sbg-systems.com/products/). +In particular the following systems are recommended: + +- **Pulse:** Recommended for fixed-wing systems without hovering, where static heading is not necessary. +- **Ellipse:** Recommended for multicopter systems where hovering and low dynamics requires the use of static heading. + +## 구매처 + +SBG Systems solutions are available directly from [MySBG](https://my.sbg-systems.com) (FR) or through their Global Sales Representatives. For more information on their solutions or for international orders, please contact contact@sbg-systems.com. + +## 하드웨어 설정 + +### 배선 + +Connect any unused flight controller serial interface, such as a spare `GPS` or `TELEM` port, to the SBG Systems product MAIN port (required by PX4). + +### 장착 + +The SBG Systems product sensor can be mounted in any orientation, in any position on the vehicle, without regard to center of gravity. +All SBG Systems product sensors default to a coordinate system of x-forward, y-right, and z-down, making the default mounting as connector-back, base down. +This can be changed to any rigid rotation using the sbgECom Reference Frame Rotation register. + +If using a GNSS-enabled product, the GNSS antenna must be mounted rigidly with respect to the inertial sensor and with an unobstructed sky view. If using a dual-GNSS-enabled product (Ellipse-D), the secondary antenna must be mounted rigidly with respect to the primary antenna and the inertial sensor with an unobstructed sky view. + +For more mounting and configuration requirements and recommendations, see the relevant [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +## 펌웨어 설정 + +### PX4 설정 + +To use the sbgECom driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_SBGECOM` or `CONFIG_COMMON_INS`. + +2. [Set the parameter](../advanced_config/parameters.md) [SENS_SBG_CFG](../advanced_config/parameter_reference.md#SENS_SBG_CFG) to the hardware port connected to the SBG Systems product (for more information see [Serial Port Configuration](../peripherals/serial_configuration.md)). + + ::: warning + Disable or change port of other sensors that are using the same one, for example [GPS_1_CONFIG](../advanced_config/parameter_reference.md#GPS_1_CONFIG) if using GPS1 port. + +::: + +3. Set [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) to the desired default baudrate value. + +4. Allow the sbgECom driver to initialize by restarting PX4. + +5. Configure driver to provide IMU data, GNSS data and INS : + + 1. Set [SBG_MODE](../advanced_config/parameter_reference.md#SBG_MODE) to the desired mode. + 2. Make sensor module select sensors by enabling [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE). + 3. Prioritize SBG Systems sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + + ::: tip + In most cases the external IMU (SBG) is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + + Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. + The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. + +::: + + ::: warning + When configuring both SBG Systems and Pixhawk sensors to have non-zero priority, if the selected sensor is errored (timeout), it can change during operation without being notified. + In this case, MAVLink messages will be updated with the newly selected sensor. + + If you don't want to have this fallback mechanism, you must disable unwanted sensors. + +::: + 4. If using the sbgECom as an INS, disable EKF2 using [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN). + +6. Restart PX4. + +Once enabled, the module will be detected on boot. +IMU data should be published at 200Hz. + +## SBG Systems Configuration + +All High Performance and Ellipse 3.0 and higher SBG Systems INS can be configured directly from PX4 firmware: + +1. Enable [SBG_CONFIGURE_EN](../advanced_config/parameter_reference.md#SBG_CONFIGURE_EN). + +2. Provide a JSON file `sbg_settings.json` containing SBG Systems INS settings to be applied in your PX4 board `extras` directory (ex: `boards/px4/fmu-v5/extras`). The settings JSON file will be installed in `/etc/extras/sbg_settings.json` on the board. + + ::: tip + The settings can be retrieved using [sbgEComAPI](https://github.com/SBG-Systems/sbgECom/tree/main/tools/sbgEComApi) or [sbgInsRestApi](https://developer.sbg-systems.com/sbgInsRestApi/1.3/#tag/Settings) and then modified as a JSON file. + +::: + + ::: tip + The settings file can be provided in the SD card in q`/fs/microsd/etc/extras/sbg_settings.json` to avoid rebuilding a new firmware to change JSON settings file. + +::: + +3. For testing purpose, it's also possible to modify SBG Systems INS settings on the fly: + - By passing a JSON file path as argument when starting sbgecom driver (ex: `sbgecom start -f /fs/microsd/new_sbg_settings.json`) + - By passing a JSON string as argument when starting sbgecom driver: (ex: `sbgecom start -s {"output":{"comA":{"messages":{"airData":"onChange"}}}}`) + +For older Ellipse SBG Systems INS or to configure any SBG Systems INS directly, all commands and registers can be found in the [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +:::warning +If the baudrate of the serial port on the INS product (used to communicate with PX4) is changed, the parameter [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) must be changed to match. +::: + +## Published Data + +Upon initialization, the driver should print the following information to console (printed using `PX4_INFO`) + +- Unit model number +- Unit hardware version +- Unit serial number +- Unit firmware number + +This should be accessible using the [`dmesg`](../modules/modules_system.md#dmesg) command. + +The sbgECom driver always publishes the unit's data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) + +if configured as a GNSS, publishes: + +- [sensor_gps](../msg_docs/SensorGps.md) + +and, if configured as an INS, publishes: + +- [estimator_status](../msg_docs/EstimatorStatus.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_global_positon](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) + +:::tip +Published topics can be viewed using the `listener` command. +::: + +## Hardware Specifications + +- [Product Briefs](https://www.sbg-systems.com/products/) +- [Datasheets](https://www.sbg-systems.com/contact/#products) diff --git a/docs/ko/sensor/sfxx_lidar.md b/docs/ko/sensor/sfxx_lidar.md index 8d0abeb0ae..ee0cb5e9d6 100644 --- a/docs/ko/sensor/sfxx_lidar.md +++ b/docs/ko/sensor/sfxx_lidar.md @@ -9,11 +9,14 @@ LightWare는 UAV에 장착에 적합한 경량의 범용 레이저 고도계( " 아래의 모델들은 PX4에서 지원되며, I2C 또는 직렬 버스에 연결할 수 있습니다 (아래 표는 각 모델에 사용할 수 있는 버스를 나타냄). -| 모델 | 범위 (m) | 버스 | 설명 | -| ---------------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- | -| [SF11/C](https://lightwarelidar.com/products/sf11-c-100-m) | 100 | 직렬 또는 I2C 버스 | | -| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C 버스 | 감지 및 회피 애플리케이션을 위한 서보가 있는 방수 (IP67) | -| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | 직렬 | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| 모델 | 범위 (m) | 버스 | 설명 | +| ------------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- | +| [SF11/C](https://lightwarelidar.com/shop/sf11-c-100-m/) | 100 | 직렬 또는 I2C 버스 | | +| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C 버스 | 감지 및 회피 애플리케이션을 위한 서보가 있는 방수 (IP67) | +| [SF30/D](https://lightwarelidar.com/shop/sf30-d-200-m/) | 200 | I2C 버스 | Waterproofed (IP67) | +| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | 직렬 | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| [GRF250](https://lightwarelidar.com/shop/grf-250/) | 250 | I2C | Gimbal Range Finder | +| [GRF500](https://lightwarelidar.com/shop/grf-500/) | 500 | I2C | Gimbal Range Finder | :::details Discontinued diff --git a/docs/ko/sensor/vectornav.md b/docs/ko/sensor/vectornav.md index 2f3c405750..dc8941aebc 100644 --- a/docs/ko/sensor/vectornav.md +++ b/docs/ko/sensor/vectornav.md @@ -61,18 +61,18 @@ To use the VectorNav driver: 5. Configure driver as either an external INS or to provide raw data: - If using the VectorNav as an external INS, set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `INS`. - This disables EKF2. + This disables EKF2. - If using the VectorNav as external inertial sensors: - 1. Set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `Sensors Only` - 2. If internal sensors are enabled, prioritize VectorNav sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + 1. Set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `Sensors Only` + 2. If internal sensors are enabled, prioritize VectorNav sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). - ::: tip - In most cases the external IMU (VN) is the highest-numbered. - You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + ::: tip + In most cases the external IMU (VN) is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. - Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. - The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. + Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. + The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. ::: diff --git a/docs/ko/sim_flightgear/index.md b/docs/ko/sim_flightgear/index.md index 18cf1ec945..db28a98dd7 100644 --- a/docs/ko/sim_flightgear/index.md +++ b/docs/ko/sim_flightgear/index.md @@ -40,33 +40,33 @@ These instructions were tested on Ubuntu 18.04 2. Install FlightGear: - ```sh - sudo add-apt-repository ppa:saiarcot895/flightgear - sudo apt update - sudo apt install flightgear - ``` + ```sh + sudo add-apt-repository ppa:saiarcot895/flightgear + sudo apt update + sudo apt install flightgear + ``` - This installs the latest stable FlightGear version from the PAA repository along with the FGdata package. + This installs the latest stable FlightGear version from the PAA repository along with the FGdata package. - :::tip - For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. - Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). + :::tip + For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. + Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). ::: 3. Check that you are able to run FlightGear: - ```sh - fgfs --launcher - ``` + ```sh + fgfs --launcher + ``` 4. Set write permissions to the **Protocols** folder in the FlightGear installation directory: - ```sh - sudo chmod a+w /usr/share/games/flightgear/Protocol - ``` + ```sh + sudo chmod a+w /usr/share/games/flightgear/Protocol + ``` - Setting the permissions is required because the PX4-FlightGear-Bridge puts the communication definition file here. + Setting the permissions is required because the PX4-FlightGear-Bridge puts the communication definition file here. Additional installation instructions can be found on [FlightGear wiki](https://wiki.flightgear.org/Howto:Install_Flightgear_from_a_PPA). diff --git a/docs/ko/sim_gazebo_classic/index.md b/docs/ko/sim_gazebo_classic/index.md index 4d0a1784e4..7b95cd2961 100644 --- a/docs/ko/sim_gazebo_classic/index.md +++ b/docs/ko/sim_gazebo_classic/index.md @@ -249,14 +249,14 @@ It is enabled by default in many vehicle SDF files: **solo.sdf**, **iris.sdf**, To enable/disable GPS noise: 1. Build any gazebo target in order to generate SDF files (for all vehicles). - 예: + 예: - ```sh - make px4_sitl gazebo-classic_iris - ``` + ```sh + make px4_sitl gazebo-classic_iris + ``` - :::tip - The SDF files are not overwritten on subsequent builds. + :::tip + The SDF files are not overwritten on subsequent builds. ::: @@ -264,17 +264,17 @@ To enable/disable GPS noise: 3. Search for the `gpsNoise` element: - ```xml - - - true - - ``` + ```xml + + + true + + ``` - - If it is present, GPS is enabled. - You can disable it by deleting the line: `true` - - If it is not present, GPS is disabled. - You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). + - If it is present, GPS is enabled. + You can disable it by deleting the line: `true` + - If it is not present, GPS is disabled. + You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). The next time you build/restart Gazebo Classic it will use the new GPS noise setting. diff --git a/docs/ko/sim_gazebo_classic/multi_vehicle_simulation.md b/docs/ko/sim_gazebo_classic/multi_vehicle_simulation.md index 1a53ef0973..01d1ba4493 100644 --- a/docs/ko/sim_gazebo_classic/multi_vehicle_simulation.md +++ b/docs/ko/sim_gazebo_classic/multi_vehicle_simulation.md @@ -68,36 +68,36 @@ To build an example setup, follow the steps below: 1. Clone the PX4/Firmware code, then build the SITL code: - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl gazebo-classic + ``` 2. Build the `micro xrce-dds agent` and the interface package following the [instructions here](../ros2/user_guide.md). 3. Run `Tools/simulation/gazebo-classic/sitl_multiple_run.sh`. - For example, to spawn 4 vehicles, run: + For example, to spawn 4 vehicles, run: - ```sh - ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 - ``` + ```sh + ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 + ``` - ::: info - Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). - MAVLink system id 1 is skipped. + ::: info + Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). + MAVLink system id 1 is skipped. ::: 4. Run `MicroXRCEAgent`. - It will automatically connect to all four vehicles: + It will automatically connect to all four vehicles: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` - ::: info - The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. + ::: info + The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. ::: @@ -117,27 +117,27 @@ To build an example setup, follow the step below: 1. Clone the PX4/PX4-Autopilot code, then build the SITL code - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl_default gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl_default gazebo-classic + ``` 2. Source your environment: - ```sh - source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default - export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo - ``` + ```sh + source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default + export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo + ``` 3. Run launch file: - ```sh - roslaunch px4 multi_uav_mavros_sitl.launch - ``` + ```sh + roslaunch px4 multi_uav_mavros_sitl.launch + ``` - ::: info - You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. + ::: info + You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. ::: @@ -253,45 +253,45 @@ This section shows how developers can simulate multiple vehicles using vehicle m 1. Install _xmlstarlet_ from your Linux terminal: - ```sh - sudo apt install xmlstarlet - ``` + ```sh + sudo apt install xmlstarlet + ``` 2. Use _roslaunch_ with the **multi_uav_mavros_sitl_sdf.launch** launch file: - ````sh - roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= - ``` + ````sh + roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= + ``` - ::: info - Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. + ::: info + Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. ::: - ```` + ```` This method is similar to using the xacro except that the SITL/Gazebo Classic port number is automatically inserted by _xmstarlet_ for each spawned vehicle, and does not need to be specified in the SDF file. To add a new vehicle, you need to make sure the model can be found (in order to spawn it in Gazebo Classic), and PX4 needs to have an appropriate corresponding startup script. 1. You can choose to do either of: - - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: + - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: - ```sh - $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf - ``` + ```sh + $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf + ``` - ::: info - Ensure you set the `vehicle` argument even if you hardcode the path to your model. + ::: info + Ensure you set the `vehicle` argument even if you hardcode the path to your model. ::: - - copy your model into the folder indicated above (following the same path convention). + - copy your model into the folder indicated above (following the same path convention). 2. The `vehicle` argument is used to set the `PX4_SIM_MODEL` environment variable, which is used by the default rcS (startup script) to find the corresponding startup settings file for the model. - Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. - For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). - For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). - For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. + Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. + For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). + For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). + For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. ## Additional Resources diff --git a/docs/ko/sim_gazebo_gz/gazebo_models.md b/docs/ko/sim_gazebo_gz/gazebo_models.md index 8d01f8e58b..880a74758e 100644 --- a/docs/ko/sim_gazebo_gz/gazebo_models.md +++ b/docs/ko/sim_gazebo_gz/gazebo_models.md @@ -101,15 +101,15 @@ This example explains how you can run standalone mode PX4 via two terminals on o 1. In one terminal run - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 + ``` 2. In a second terminal window run: - ```sh - python3 /path/to/simulation-gazebo --world windy - ``` + ```sh + python3 /path/to/simulation-gazebo --world windy + ``` No additional parameters have to be passed to the simulation-gazebo script in order for this example to work, as all Gazebo nodes run on the same host. See the example below for a more involved scenario with different hosts. diff --git a/docs/ko/sim_gazebo_gz/index.md b/docs/ko/sim_gazebo_gz/index.md index 719e773305..d93011de4c 100644 --- a/docs/ko/sim_gazebo_gz/index.md +++ b/docs/ko/sim_gazebo_gz/index.md @@ -20,6 +20,8 @@ See [Simulation](../simulation/index.md) for general information about simulator Gazebo Harmonic is installed by default on Ubuntu 22.04 as part of the normal [development environment setup](../dev_setup/dev_env_linux_ubuntu.md#simulation-and-nuttx-pixhawk-targets). +Gazebo versions Harmonic, Ionic, and Jetty are supported on Ubuntu 24.04. The latest installed Gazebo release is used by default. + :::info The PX4 installation scripts are based on the instructions: [Binary Installation on Ubuntu](https://gazebosim.org/docs/harmonic/install_ubuntu/) (gazebosim.org). ::: @@ -48,22 +50,23 @@ This runs both the PX4 SITL instance and the Gazebo client. The supported vehicles and `make` commands are listed below. Note that all gazebo make targets have the prefix `gz_`. -| Vehicle | 통신 | `PX4_SYS_AUTOSTART` | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------- | -| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | -| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | -| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | -| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | -| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | -| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | -| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | -| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | -| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | -| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | -| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_r1_rover` | 4009 | -| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 4012 | -| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | -| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| Vehicle | 통신 | `PX4_SYS_AUTOSTART` | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------------------- | +| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | +| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | +| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | +| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | +| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | +| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | +| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | +| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | +| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | +| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | +| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | +| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_rover_differential` | 50000 | +| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 51000 | +| [Mecanum Rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) | `make px4_sitl gz_rover_mecanum` | 52000 | All [vehicle models](../sim_gazebo_gz/vehicles.md) (and [worlds](#specify-world)) are included as a submodule from the [Gazebo Models Repository](../sim_gazebo_gz/gazebo_models.md) repository. @@ -316,33 +319,33 @@ Here are some examples of the different scenarios covered above. 1. **Start simulator + default world + spawn vehicle at default pose** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 2. **Start simulator + default world + spawn vehicle at custom pose (y=2m)** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 3. **Start simulator + default world + link to existing vehicle** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 + ``` 4. **Start simulator in standalone mode + connect to Gazebo instance running default world** - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` - In a separate terminal run: + In a separate terminal run: - ```sh - python /path/to/simulation-gazebo - ``` + ```sh + python /path/to/simulation-gazebo + ``` ## Adding New Worlds and Models @@ -358,38 +361,38 @@ To add a new model: 2. Define the default parameters for Gazebo in the airframe configuration file (this example is from [x500 quadcopter](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/4001_gz_x500)): - ```ini - PX4_SIMULATOR=${PX4_SIMULATOR:=gz} - PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} - PX4_SIM_MODEL=${PX4_SIM_MODEL:=} - ``` + ```ini + PX4_SIMULATOR=${PX4_SIMULATOR:=gz} + PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} + PX4_SIM_MODEL=${PX4_SIM_MODEL:=} + ``` - - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. + - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. - - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. + - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. - - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: + - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: - ```sh - PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 + ``` 3. Add CMake Target for the [airframe](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt). - - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. - - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` + - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. + - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` - You can of course also use both. + You can of course also use both. ### Adding a World To add a new world: 1. Add your world to the list of worlds found in the [`CMakeLists.txt` here](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/CMakeLists.txt). - This is required in order to allow `CMake` to generate correct targets. + This is required in order to allow `CMake` to generate correct targets. - - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. - - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` + - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. + - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` :::info As long as the world file and the model file are in the Gazebo search path (`GZ_SIM_RESOURCE_PATH`) it is not necessary to add them to the PX4 world and model directories. diff --git a/docs/ko/sim_gazebo_gz/plugins.md b/docs/ko/sim_gazebo_gz/plugins.md index 9723f44177..0f48c53db8 100644 --- a/docs/ko/sim_gazebo_gz/plugins.md +++ b/docs/ko/sim_gazebo_gz/plugins.md @@ -43,8 +43,8 @@ When developing new plugins: 1. **Follow the plugin architecture** - Implement desired interfaces. - You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. - The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). + You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. + The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). 2. **Register your plugin** - Add it to [server.config](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/server.config) for discovery. diff --git a/docs/ko/sim_gazebo_gz/tools_avl_automation.md b/docs/ko/sim_gazebo_gz/tools_avl_automation.md index 69f513013e..d25780226b 100644 --- a/docs/ko/sim_gazebo_gz/tools_avl_automation.md +++ b/docs/ko/sim_gazebo_gz/tools_avl_automation.md @@ -11,26 +11,26 @@ The results will then automatically be written into a provided plugin template t To setup the tool: 1. Download AVL 3.36 from . - The file for AVL version 3.36 can be found about halfway down the page. + The file for AVL version 3.36 can be found about halfway down the page. 2. After downloading, extract AVL and move it to the home directory using: - ```sh - sudo tar -xf avl3.36.tgz - mv ./Avl /home/ - ``` + ```sh + sudo tar -xf avl3.36.tgz + mv ./Avl /home/ + ``` 3. Follow the **index.md** found in `./Avl` to finish the setup process for AVL (this requires that you set up `plotlib` and `eispack` libraries). - We recommend using the `gfortran` compile option, which might further require that you to install `gfortran`. - On Ubuntu can be done by running: + We recommend using the `gfortran` compile option, which might further require that you to install `gfortran`. + On Ubuntu can be done by running: - ```sh - sudo apt update - sudo apt install gfortran - ``` + ```sh + sudo apt update + sudo apt install gfortran + ``` - When running the Makefile for AVL, you might encounter an `Error 1` message stating that there is a directory missing. - This does not prevent AVL from working for our purposes. + When running the Makefile for AVL, you might encounter an `Error 1` message stating that there is a directory missing. + This does not prevent AVL from working for our purposes. Once the process described in the AVL README is completed, AVL is ready to be used. No further set up is required on the side of the AVL or the tool. @@ -49,16 +49,16 @@ To run the tool for your plane: 2. Run the tool on your yml file: - ```sh - python input_avl.py .yml - ``` + ```sh + python input_avl.py .yml + ``` - Note that the `yaml` and `argparse` packages must be present in your Python environment. + Note that the `yaml` and `argparse` packages must be present in your Python environment. 3. The tool prompts for a range of vehicle specific parameters that are needed in order to specify the geometry and physical properties of the plane. - You can either: - - select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and just modify some physical properties, or - - define a completely custom model + You can either: + - select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and just modify some physical properties, or + - define a completely custom model Once the script has been executed, the generated `.avl`, `.sdf` and a plot of the proposed control surfaces can be found in `` directory. The sdf file is the generated Advanced Lift Drag Plugin that can be copied and pasted into a model.sdf file, which can then be run in Gazebo. diff --git a/docs/ko/sim_gazebo_gz/vehicles.md b/docs/ko/sim_gazebo_gz/vehicles.md index 5638f9b63f..6c93b94d49 100644 --- a/docs/ko/sim_gazebo_gz/vehicles.md +++ b/docs/ko/sim_gazebo_gz/vehicles.md @@ -185,7 +185,7 @@ make px4_sitl gz_tiltrotor [Differential Rover](../frames_rover/index.md#differential) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. ```sh -make px4_sitl gz_r1_rover +make px4_sitl gz_rover_differential ``` ![Differential Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_differential.png) @@ -199,3 +199,13 @@ make px4_sitl gz_rover_ackermann ``` ![Ackermann Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_ackermann.png) + +### Mecanum Rover + +[Mecanum Rover](../frames_rover/index.md#mecanum) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. + +```sh +make px4_sitl gz_rover_mecanum +``` + +![Mecanum Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_mecanum.png) diff --git a/docs/ko/sim_jmavsim/index.md b/docs/ko/sim_jmavsim/index.md index e64a540c29..5e1a543f4c 100644 --- a/docs/ko/sim_jmavsim/index.md +++ b/docs/ko/sim_jmavsim/index.md @@ -30,23 +30,23 @@ Follow the instructions below to install jMAVSim on macOS. To setup the environment for [jMAVSim](../sim_jmavsim/index.md) simulation: 1. Install a recent version of Java (e.g. Java 15). - You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): + You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): - ```sh - brew install --cask temurin - ``` + ```sh + brew install --cask temurin + ``` 2. Install jMAVSim: - ```sh - brew install px4-sim-jmavsim - ``` + ```sh + brew install px4-sim-jmavsim + ``` - :::warning - PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. + :::warning + PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. - For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. - You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). + For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. + You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). ::: diff --git a/docs/ko/sim_sih/index.md b/docs/ko/sim_sih/index.md index 181fc9904f..413302da84 100644 --- a/docs/ko/sim_sih/index.md +++ b/docs/ko/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH as SITL (without hardware) from PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Benefits @@ -71,24 +71,24 @@ To check that these are present on your flight controller: 3. Enter the following commands in the console: - ```sh - pwm_out_sim status - ``` + ```sh + pwm_out_sim status + ``` - ```sh - sensor_baro_sim status - ``` + ```sh + sensor_baro_sim status + ``` - ```sh - sensor_gps_sim status - ``` + ```sh + sensor_gps_sim status + ``` - ```sh - sensor_mag_sim status - ``` + ```sh + sensor_mag_sim status + ``` - ::: tip - Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). + ::: tip + Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). ::: @@ -141,12 +141,12 @@ To set up/start SIH: 1. Connect the flight controller to the desktop computer with a USB cable. 2. Open QGroundControl and wait for the flight controller too boot and connect. 3. Open [Vehicle Setup > Airframe](../config/airframe.md) then select the desired frame: - - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) - - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). - - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) - - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) - - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) - - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) + - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) + - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). + - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) + - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) + - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) + - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) The autopilot will then reboot. The `sih` module is started on reboot, and the vehicle should be displayed on the ground control station map. @@ -172,19 +172,19 @@ To display the simulated vehicle: 3. Start jMAVSim by calling the script **jmavsim_run.sh** from a terminal: - ```sh - ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o - ``` + ```sh + ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o + ``` - where the flags are: + where the flags are: - - `-q` to allow the communication to _QGroundControl_ (optional). - - `-d` to start the serial device `/dev/ttyACM0` on Linux. - On macOS this would be `/dev/tty.usbmodem1`. - - `-b` to set the serial baud rate to `2000000`. - - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). - - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. - If this flag is not present a quadrotor will be displayed by default. + - `-q` to allow the communication to _QGroundControl_ (optional). + - `-d` to start the serial device `/dev/ttyACM0` on Linux. + On macOS this would be `/dev/tty.usbmodem1`. + - `-b` to set the serial baud rate to `2000000`. + - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). + - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. + If this flag is not present a quadrotor will be displayed by default. 4. After few seconds, _QGroundControl_ can be opened again. @@ -201,41 +201,41 @@ To run SIH as SITL: 1. Install the [PX4 Development toolchain](../dev_setup/dev_env.md). 2. Run the appropriate make command for each vehicle type (at the root of the PX4-Autopilot repository): - - Quadcopter + - Quadcopter - ```sh - make px4_sitl sihsim_quadx - ``` + ```sh + make px4_sitl sihsim_quadx + ``` - - Hexacopter + - Hexacopter - ```sh - make px4_sitl sihsim_hex - ``` + ```sh + make px4_sitl sihsim_hex + ``` - - Fixed-wing (plane) + - Fixed-wing (plane) - ```sh - make px4_sitl sihsim_airplane - ``` + ```sh + make px4_sitl sihsim_airplane + ``` - - XVert VTOL tailsitter + - XVert VTOL tailsitter - ```sh - make px4_sitl sihsim_xvert - ``` + ```sh + make px4_sitl sihsim_xvert + ``` - - 표준 VTOL + - 표준 VTOL - ```sh - make px4_sitl sihsim_standard_vtol - ``` + ```sh + make px4_sitl sihsim_standard_vtol + ``` - - Ackermann Rover + - Ackermann Rover - ```sh - make px4_sitl sihsim_rover_ackermann - ``` + ```sh + make px4_sitl sihsim_rover_ackermann + ``` ### Change Simulation Speed @@ -328,6 +328,44 @@ For SIH as SITL (no FC): For specific examples see the `_sihsim_` airframes in [ROMFS/px4fmu_common/init.d-posix/airframes](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/) (SIH as SITL) and [ROMFS/px4fmu_common/init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) (SIH on FC). +## Controlling Actuators in SIH + +:::warning +If you want to control throttling actuators in SIH, make sure to remove propellers for safety. +::: + +In some scenarios, it may be useful to control an actuator while running SIH. For example, you might want to verify that winches or grippers are functioning correctly by checking the servo responses. + +To enable actuator control in SIH: + +1. Configure PWM parameters in the airframe file: + +Ensure your airframe file includes the necessary parameters to map PWM outputs to the correct channels. + +For example, if a servo is connected to MAIN 3 and you want to map it to AUX1 on your RC, use the following command: + +`param set-default PWM_MAIN_FUNC3 407` + +You can find a full list of available values for `PWM_MAIN_FUNCn` [here](../advanced_config/parameter_reference.md#PWM_MAIN_FUNC1). In this case, `407` maps the MAIN 3 output to AUX1 on the RC. + +Alternatively, you can use the [`PWM_AUX_FUNCn`](../advanced_config/parameter_reference.md#PWM_AUX_FUNC1) parameters. + +You may also configure the output as desired: + +- Disarmed PWM: ([`PWM_MAIN_DISn`](../advanced_config/parameter_reference.md#PWM_MAIN_DIS1) / [`PWM_AUX_DIS1`](../advanced_config/parameter_reference.md#PWM_AUX_DIS1)) +- Minimum PWM ([`PWM_MAIN_MINn`](../advanced_config/parameter_reference.md#PWM_MAIN_MIN1) / [`PWM_AUX_MINn`](../advanced_config/parameter_reference.md#PWM_AUX_MIN1)) +- Maximum PWM ([`PWM_MAIN_MAXn`](../advanced_config/parameter_reference.md#PWM_MAIN_MAX1) / [`PWM_AUX_MAXn`](../advanced_config/parameter_reference.md#PWM_AUX_MAX1)) + +2. Manually start the PWM output driver + +For safety, the PWM driver is not started automatically in SIH. To enable it, run the following command in the MAVLink shell: + +`pwm_out start` + +And to disable it again: + +`pwm_out stop` + ## Dynamic Models The dynamic models for the various vehicles are: diff --git a/docs/ko/simulation/index.md b/docs/ko/simulation/index.md index 0ad31c3091..aee31288f8 100644 --- a/docs/ko/simulation/index.md +++ b/docs/ko/simulation/index.md @@ -217,20 +217,20 @@ The simulated camera is a gazebo classic plugin that implements the [MAVLink Cam PX4 connects/integrates with this camera in _exactly the same way_ as it would with any other MAVLink camera: 1. [TRIG_INTERFACE](../advanced_config/parameter_reference.md#TRIG_INTERFACE) must be set to `3` to configure the camera trigger driver for use with a MAVLink camera - :::tip - In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. - For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). + :::tip + In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. + For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). ::: 2. PX4는 GCS와 (시뮬레이터) MAVLink 카메라 사이의 모든 카메라 명령을 전달하여야 합니다. - You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. + You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. - ```sh - mavlink start -u 14558 -o 14530 -r 4000 -f -m camera - ``` + ```sh + mavlink start -u 14558 -o 14530 -r 4000 -f -m camera + ``` - ::: info - More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. + ::: info + More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. ::: diff --git a/docs/ko/smart_batteries/rotoye_batmon.md b/docs/ko/smart_batteries/rotoye_batmon.md index 06f7e5cd8f..896ef46e27 100644 --- a/docs/ko/smart_batteries/rotoye_batmon.md +++ b/docs/ko/smart_batteries/rotoye_batmon.md @@ -3,11 +3,6 @@ [Rotoye Batmon](https://rotoye.com/batmon/) is a kit for adding smart battery functionality to off-the-shelf Lithium-Ion and LiPo batteries. 독립형 장치로 또는 공장에서 조립된 스마트 배터리의 일부로 구입할 수 있습니다. -:::info -At time of writing you can only use Batmon by [building a custom branch of PX4](#build-px4-firmware). -Support in the codeline is pending [PR approval](https://github.com/PX4/PX4-Autopilot/pull/16723). -::: - ![Rotoye Batmon Board](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye.jpg) ![Pre-assembled Rotoye smart battery](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye-pack.jpg) diff --git a/docs/ko/telemetry/crsf_telemetry.md b/docs/ko/telemetry/crsf_telemetry.md index b34c670497..ee024e976d 100644 --- a/docs/ko/telemetry/crsf_telemetry.md +++ b/docs/ko/telemetry/crsf_telemetry.md @@ -77,36 +77,36 @@ To use this feature you must build and upload custom firmware that includes [crs 1. [Setup a development environment](../dev_setup/dev_env.md) for building PX4. - As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. + As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. 2. Open a terminal and `cd` into the `PX4-Autopilot` directory. - ```sh - cd PX4-Autopilot - ``` + ```sh + cd PX4-Autopilot + ``` 3. Launch the [PX4 board config tool (`menuconfig`)](../hardware/porting_guide_config.md#px4-menuconfig-setup) for your `make` target using the `boardconfig` option (here the target is the [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) flight controller): - ```sh - make ark_fmu-v6x_default boardconfig - ``` + ```sh + make ark_fmu-v6x_default boardconfig + ``` 4. In the PX4 board config tool: - - Disable the default `rc_input` module - 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. - 2. Use the enter key to remove the `*` from `rc_input` checkbox. - - Enable the `crsf_rc` module - 1. Scroll to highlight the `RC` submenu, then press enter to open it. - 2. Scroll to highlight `crsf_rc` and press enter to enable it. + - Disable the default `rc_input` module + 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. + 2. Use the enter key to remove the `*` from `rc_input` checkbox. + - Enable the `crsf_rc` module + 1. Scroll to highlight the `RC` submenu, then press enter to open it. + 2. Scroll to highlight `crsf_rc` and press enter to enable it. - Save and exit the PX4 board config tool. + Save and exit the PX4 board config tool. 5. [Build the PX4 source code](../dev_setup/building_px4.md) with your changes (again assuming you are using ARKV6X): - ```sh - make ark_fmu-v6x_default - ``` + ```sh + make ark_fmu-v6x_default + ``` This will build your custom firmware, which must now be uploaded to your flight controller. @@ -128,11 +128,11 @@ Alternatively you can use QGroundControl to install the firmware, as described i 1. [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) — Set to the port that is connected to the CRSF receiver (such as `TELEM1`). - This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. - Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. - For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. - 포트 전송속도는 드라이버에 의해 설정되므로, 추가로 설정하지 않아도 됩니다. + 포트 전송속도는 드라이버에 의해 설정되므로, 추가로 설정하지 않아도 됩니다. 2. [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) — Enable to activate Crossfire telemetry. diff --git a/docs/ko/telemetry/jfi_telemetry.md b/docs/ko/telemetry/jfi_telemetry.md index 9fbd07f31d..4f7847e4a8 100644 --- a/docs/ko/telemetry/jfi_telemetry.md +++ b/docs/ko/telemetry/jfi_telemetry.md @@ -111,9 +111,9 @@ However if you change the baud rate from 57600 you will need to create and use a 1. Disable SiK Radio in QGC (**Application Settings → General → AutoConnect**). 2. Create a new link configuration: - - Go to **Application Settings → Comms Links**. - - Click **Add**. - - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. + - Go to **Application Settings → Comms Links**. + - Click **Add**. + - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. 3. Select **Connect** to connect with the new configuration. ## J.Fi Configuration diff --git a/docs/ko/telemetry/telemetry_wifi.md b/docs/ko/telemetry/telemetry_wifi.md index a1dbdc3693..41ec3d3827 100644 --- a/docs/ko/telemetry/telemetry_wifi.md +++ b/docs/ko/telemetry/telemetry_wifi.md @@ -1,6 +1,6 @@ # WiFi 텔레메트리 라디오 -WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS.\ +WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS. WiFi typically offers shorter range than a normal telemetry radio, but supports higher data rates, and makes it easier to support FPV/video feeds. 일반적으로 차량용 라디오 장치 하나만 필요합니다 (지상국에 이미 WiFi가 있다고 가정). diff --git a/docs/ko/test_and_ci/fuzz_tests.md b/docs/ko/test_and_ci/fuzz_tests.md index 5afba73dd8..d6f87791bb 100644 --- a/docs/ko/test_and_ci/fuzz_tests.md +++ b/docs/ko/test_and_ci/fuzz_tests.md @@ -15,14 +15,14 @@ To write a fuzz test: 1. Start by writing a "normal" [functional test](../test_and_ci/unit_tests.md#functional-test). 2. Make sure the file name contains `fuzz` (lower case). - For example `my_driver_fuzz_tests.cpp`. + For example `my_driver_fuzz_tests.cpp`. 3. Add one or more fuzz tests to the file. - 예: + 예: ```cpp #include #include - + void myDriverNeverCrashes(const std::string& s) { MyDriver driver; driver.handleInput(s); diff --git a/docs/ko/test_and_ci/index.md b/docs/ko/test_and_ci/index.md index bfe2a5af38..88754b19d7 100644 --- a/docs/ko/test_and_ci/index.md +++ b/docs/ko/test_and_ci/index.md @@ -9,8 +9,8 @@ Test topics include: - [Unit Tests](../test_and_ci/unit_tests.md) - [Continuous Integration (CI)](../test_and_ci/continous_integration.md) - [Integration Testing](../test_and_ci/integration_testing.md) - - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) - - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) - - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) + - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) + - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) + - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) - [Docker](../test_and_ci/docker.md) - [Maintenance](../test_and_ci/maintenance.md) diff --git a/docs/ko/test_and_ci/integration_testing_ros1_mavros.md b/docs/ko/test_and_ci/integration_testing_ros1_mavros.md index 1097c246fb..02882687a5 100644 --- a/docs/ko/test_and_ci/integration_testing_ros1_mavros.md +++ b/docs/ko/test_and_ci/integration_testing_ros1_mavros.md @@ -65,73 +65,73 @@ To write a new test: 1. Create a new test script by copying the empty test skeleton below: - ```python - #!/usr/bin/env python - # [... LICENSE ...] - - # - # @author Example Author - # - PKG = 'px4' - - import unittest - import rospy - import rosbag - - from sensor_msgs.msg import NavSatFix - - class MavrosNewTest(unittest.TestCase): - """ - Test description - """ - - def setUp(self): - rospy.init_node('test_node', anonymous=True) - rospy.wait_for_service('mavros/cmd/arming', 30) - - rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) - self.rate = rospy.Rate(10) # 10hz - self.has_global_pos = False - - def tearDown(self): - pass - - # - # General callback functions used in tests - # - def global_position_callback(self, data): - self.has_global_pos = True - - def test_method(self): - """Test method description""" - - # FIXME: hack to wait for simulation to be ready - while not self.has_global_pos: - self.rate.sleep() - - # TODO: execute test - - if __name__ == '__main__': - import rostest - rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) - ``` + ```python + #!/usr/bin/env python + # [... LICENSE ...] + + # + # @author Example Author + # + PKG = 'px4' + + import unittest + import rospy + import rosbag + + from sensor_msgs.msg import NavSatFix + + class MavrosNewTest(unittest.TestCase): + """ + Test description + """ + + def setUp(self): + rospy.init_node('test_node', anonymous=True) + rospy.wait_for_service('mavros/cmd/arming', 30) + + rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) + self.rate = rospy.Rate(10) # 10hz + self.has_global_pos = False + + def tearDown(self): + pass + + # + # General callback functions used in tests + # + def global_position_callback(self, data): + self.has_global_pos = True + + def test_method(self): + """Test method description""" + + # FIXME: hack to wait for simulation to be ready + while not self.has_global_pos: + self.rate.sleep() + + # TODO: execute test + + if __name__ == '__main__': + import rostest + rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) + ``` 2. Run the new test only - Start the simulator: - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - roslaunch launch/mavros_posix_sitl.launch - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + roslaunch launch/mavros_posix_sitl.launch + ``` - Run test (in a new shell): - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - rosrun px4 mavros_new_test.py - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + rosrun px4 mavros_new_test.py + ``` 3. Add new test node to a launch file - In `test/` create a new `.test` ROS launch file. @@ -145,9 +145,9 @@ To write a new test: 예: - ```sh - tests_: rostest - @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test - ``` + ```sh + tests_: rostest + @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test + ``` Run the tests as described above. diff --git a/docs/ko/test_and_ci/test_flights.md b/docs/ko/test_and_ci/test_flights.md index 062e7443eb..b0c65c3a6d 100644 --- a/docs/ko/test_and_ci/test_flights.md +++ b/docs/ko/test_and_ci/test_flights.md @@ -28,3 +28,7 @@ These are run by the test team as part of release testing, and for more signific - [MC_04 - Failsafe Testing](../test_cards/mc_04_failsafe_testing.md) - [MC_05 - Indoor Flight (Manual Modes)](../test_cards/mc_05_indoor_flight_manual_modes.md) - [MC_06 - Indoor Flight (Optical Flow)](../test_cards/mc_06_optical_flow.md) +- [MC_07 - Optical Flow Low Mount](../test_cards/mc_07_optical_flow_low_mount.md) +- [MC_08 - DSHOT ESC](../test_cards/mc_08_dshot.md) +- [MC_09 - VIO (Visual-Inertial Odometry)](../test_cards/mc_09_vio.md) +- [MC_10 - Optical Flow / GPS Mixed](../test_cards/mc_10_optical_flow_gps_mixed.md) diff --git a/docs/ko/test_and_ci/unit_tests.md b/docs/ko/test_and_ci/unit_tests.md index a4eb12d9fd..77a39b777b 100644 --- a/docs/ko/test_and_ci/unit_tests.md +++ b/docs/ko/test_and_ci/unit_tests.md @@ -126,34 +126,34 @@ It can be run directly in a debugger, however be careful to only run one test pe 10. Within [tests_main.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.h) define the new test: - ```cpp - extern int test_[description](int argc, char *argv[]); - ``` + ```cpp + extern int test_[description](int argc, char *argv[]); + ``` 11. Within [tests_main.c](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.c) add description name, test function and option: - ```cpp - ... - } tests[] = { - {... - {"[description]", test_[description], OPTION}, - ... - } - ``` + ```cpp + ... + } tests[] = { + {... + {"[description]", test_[description], OPTION}, + ... + } + ``` - `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: + `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: - ```sh - pxh> tests all - ``` + ```sh + pxh> tests all + ``` - 또는 + 또는 - ```sh - pxh> tests jig - ``` + ```sh + pxh> tests jig + ``` - If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. + If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. 12. Add the test `test_[description].cpp` to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/CMakeLists.txt). diff --git a/docs/ko/test_cards/mc_04_failsafe_testing.md b/docs/ko/test_cards/mc_04_failsafe_testing.md index 4ee46e5f3b..81915c1e58 100644 --- a/docs/ko/test_cards/mc_04_failsafe_testing.md +++ b/docs/ko/test_cards/mc_04_failsafe_testing.md @@ -9,10 +9,10 @@ Test RC loss, data link loss, and low battery failsafes. - Verify RC Loss action is Return to Land - Verify Data Link Loss action is Return to Land and the timeout is 10 seconds - Verify Battery failsafe - - Action is Return to Land - - Battery Warn Level is 25% - - Battery Failsafe Level is 20% - - Battery Emergency Level is 15% + - Action is Return to Land + - Battery Warn Level is 25% + - Battery Failsafe Level is 20% + - Battery Emergency Level is 15% ## Flight Tests diff --git a/docs/ko/test_cards/mc_06_optical_flow.md b/docs/ko/test_cards/mc_06_optical_flow.md index 3cd59ac133..9378bf2e4d 100644 --- a/docs/ko/test_cards/mc_06_optical_flow.md +++ b/docs/ko/test_cards/mc_06_optical_flow.md @@ -2,17 +2,23 @@ ## Objective -To test that optical flow / external vision work as expected +Test that optical flow works as expected ## Preflight -Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation ([setup information here](../sensor/optical_flow.md)) -Ensure that the drone can go into Altitude / Position flight mode while still on the ground +Ensure there are no other sources of positioning besides optical flow: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into Altitude / Position mode while still on the ground ## Flight Tests -❏ Altitude flight mode +❏ [Altitude mode](../flight_modes_mc/altitude.md)     ❏ Vertical position should hold current value with stick centered @@ -20,7 +26,7 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Throttle response set to climb/descent rate -❏ Position flight mode +❏ [Position mode](../flight_modes_mc/position.md)     ❏ Horizontal position should hold current value with stick centered @@ -30,6 +36,16 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates +❏ Varying height terrain + +    ❏ Put boxes on the ground to create varying heights in terrain + +    ❏ Take off in position mode and fly over the boxes such that the downward facing rangefinder varies in value + +    ❏ Do a few passes with varying amounts of time over the boxes (1-30 seconds if possible) + +    ❏ Drone should not raise in height when flying over boxes + ## 착륙 ❏ Land in either Position or Altitude mode with the throttle below 40% @@ -39,5 +55,8 @@ Ensure that the drone can go into Altitude / Position flight mode while still on ## 예상 결과 - 추력을 올릴 때 서서히 이륙한다 +- Drone should hold altitude in Altitude mode without wandering (over surface with many features) +- Drone should hold position within 1 meter in Position mode without pilot moving sticks - 위에 언급한 어떤 비행 모드에서도 떨림이 나타나서는 안됨 +- Drone should not raise in height when flying over boxes - 지면에 착륙시, 콥터가 지면에서 튀면 안됨 diff --git a/docs/ko/test_cards/mc_07_optical_flow_low_mount.md b/docs/ko/test_cards/mc_07_optical_flow_low_mount.md new file mode 100644 index 0000000000..5ac887e804 --- /dev/null +++ b/docs/ko/test_cards/mc_07_optical_flow_low_mount.md @@ -0,0 +1,45 @@ +# Test MC_07 - Optical Flow Low Sensor + +## Objective + +Test that optical flow works as expected with a low mounted optical flow sensor + +## Preflight + +Ensure that the drone's optical flow sensor is mounted more than an inch off of the ground + +Ensure that [MPC_THR_MIN](../advanced_config/parameter_reference.md#MPC_THR_MIN) is tuned correctly for landing + +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +([Setup Information here](../sensor/optical_flow.md)) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into [Position mode](../flight_modes_mc/position.md) while still on the ground + +## Flight Tests + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 착륙 + +❏ Land in Position mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 예상 결과 + +- 추력을 올릴 때 서서히 이륙한다 +- Drone should stay in Position mode, NOT fall into [altitude](../flight_modes_mc/altitude.md) mode diff --git a/docs/ko/test_cards/mc_07_vio.md b/docs/ko/test_cards/mc_07_vio.md new file mode 100644 index 0000000000..8d338f6883 --- /dev/null +++ b/docs/ko/test_cards/mc_07_vio.md @@ -0,0 +1,52 @@ +# Test MC_07 - VIO (Visual-Inertial Odometry) + +## Objective + +To test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into Altitude / Position flight mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ Altitude flight mode + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ Position flight mode + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 착륙 + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 예상 결과 + +- 추력을 올릴 때 서서히 이륙한다 +- Drone should hold altitude in Altitude Flight mode without wandering +- Drone should hold position within 1 meter in Position Flight mode without pilot moving sticks +- 위에 언급한 어떤 비행 모드에서도 떨림이 나타나서는 안됨 +- 지면에 착륙시, 콥터가 지면에서 튀면 안됨 diff --git a/docs/ko/test_cards/mc_08_dshot.md b/docs/ko/test_cards/mc_08_dshot.md new file mode 100644 index 0000000000..0df821802b --- /dev/null +++ b/docs/ko/test_cards/mc_08_dshot.md @@ -0,0 +1,46 @@ +# Test MC_08 - DSHOT ESC + +## Objective + +Regression test for DSHOT working with PX4 + +## Preflight + +- Ensure vehicle is using a DSHOT ESC +- Parameter [DSHOT_BIDIR_EN](../advanced_config/parameter_reference.md#DSHOT_BIDIR_EN) is enabled +- Parameter [DSHOT_TEL_CFG](../advanced_config/parameter_reference.md#DSHOT_TEL_CFG) is configured (if ESC supports telemetry) +- Parameter [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) has Debug (`5`) checked + +## Flight Tests + +❏ [Stabilized mode](../flight_modes_mc/manual_stabilized.md) + +    ❏ Takeoff in stabilized mode to ensure correct motor spin + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response 1:1 + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 착륙 + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 예상 결과 + +- Download flight logs +- Load into Data Plot Juggler +- Ensure data is logged for `esc_status`/`esc.0x`/`esc_rpm` + + ![Reference frames](../../assets/test_cards/dshot_log_output.png) diff --git a/docs/ko/test_cards/mc_09_vio.md b/docs/ko/test_cards/mc_09_vio.md new file mode 100644 index 0000000000..966073fafd --- /dev/null +++ b/docs/ko/test_cards/mc_09_vio.md @@ -0,0 +1,52 @@ +# Test MC_09 - VIO (Visual-Inertial Odometry) + +## Objective + +Test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 착륙 + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 예상 결과 + +- 추력을 올릴 때 서서히 이륙한다 +- Drone should hold altitude in Altitude mode without wandering +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- 위에 언급한 어떤 비행 모드에서도 떨림이 나타나서는 안됨 +- 지면에 착륙시, 콥터가 지면에서 튀면 안됨 diff --git a/docs/ko/test_cards/mc_10_optical_flow_gps_mixed.md b/docs/ko/test_cards/mc_10_optical_flow_gps_mixed.md new file mode 100644 index 0000000000..0f53829de9 --- /dev/null +++ b/docs/ko/test_cards/mc_10_optical_flow_gps_mixed.md @@ -0,0 +1,74 @@ +# Test MC_10 - Optical Flow / GPS Mixed + +## Objective + +Test that optical flow mixed with GPS works as expected + +## Preflight + +[Setup optical flow and GPS](../sensor/optical_flow.md) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `7` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `1` +- [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF): `1` (GPS) + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +❏ GPS Cutout + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Open QGC and navigate to MAVLink Console + +    ❏ Type `gps off` to disable GPS + +    ❏ Drone should maintain position hold via optical flow + +❏ GPS Degredation + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Fly under a metal surface (or other GPS blocking structure) + +    ❏ Ensure drone does not lose position hold or start drifting + +    ❏ Fly out of metal structure to regain GPS + +❏ GPS Acquisition + +    ❏ Takeoff in position mode in non-GPS environment + +    ❏ Fly into a GPS rich environment (outdoors) + +    ❏ Ensure drone acquires GPS position + +## 예상 결과 + +- 추력을 올릴 때 서서히 이륙한다 +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- Drone should hold position in GPS rich environment as well as non-GPS environment +- 위에 언급한 어떤 비행 모드에서도 떨림이 나타나서는 안됨 diff --git a/docs/ko/uart/user_configurable_serial_driver.md b/docs/ko/uart/user_configurable_serial_driver.md index ec6b2c2370..3a5b9b65cf 100644 --- a/docs/ko/uart/user_configurable_serial_driver.md +++ b/docs/ko/uart/user_configurable_serial_driver.md @@ -26,33 +26,33 @@ 1. Create a YAML module configuration file: - - Add a new file in the driver's source directory named **module.yaml** - - Insert the following text and adjust as needed: + - Add a new file in the driver's source directory named **module.yaml** + - Insert the following text and adjust as needed: - ```cmake - module_name: uLanding Radar - serial_config: - - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} - port_config_param: - name: SENS_ULAND_CFG - group: Sensors - ``` + ```cmake + module_name: uLanding Radar + serial_config: + - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} + port_config_param: + name: SENS_ULAND_CFG + group: Sensors + ``` - ::: info - The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. - This is also used to validate all configuration files in CI. + ::: info + The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. + This is also used to validate all configuration files in CI. ::: 2. Add the module configuration to the **CMakeLists.txt** file for the driver module: - ```cmake - px4_add_module( - MODULE drivers__ulanding - MAIN ulanding_radar - SRCS - ulanding.cpp - MODULE_CONFIG - module.yaml - ) - ``` + ```cmake + px4_add_module( + MODULE drivers__ulanding + MAIN ulanding_radar + SRCS + ulanding.cpp + MODULE_CONFIG + module.yaml + ) + ``` diff --git a/docs/ko/uorb/uorb_documentation.md b/docs/ko/uorb/uorb_documentation.md new file mode 100644 index 0000000000..d056d48860 --- /dev/null +++ b/docs/ko/uorb/uorb_documentation.md @@ -0,0 +1,170 @@ +# uORB Documentation Standard + +This topic demonstrates and explains how to document uORB messages. + +:::info +At time of writing many topics have not been updated. +::: + +## 개요 + +The [AirspeedValidated](../msg_docs/AirspeedValidated.md) message shown below is a good example of a uORB topic that has been documented to the current standard. + +```py +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + +uint32 MESSAGE_VERSION = 1 + +uint64 timestamp # [us] Time since system start + +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) + +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed + +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch +``` + +The main things to note are: + +- Documentation is added using formatted uORB comments. + Any text on a line after the `#` character is a comment, except for lines that start with the text `# TOPIC` (which indicates a multi-topic message). +- The message starts with a comment block consisting of short description (mandatory), followed by a longer description and then a space. +- Field and constants almost all have comments. + The comments are added on the same line as the field/constant, separated by one space. +- Fields: + - Comments are all on the same line as the field (extra lines become internal comments). + - Comments start with metadata, such as the units (`[m/s]`, `[rad/s]`) or allowed values (`[@enum SOURCE]`), and can also list invalid values (`[@invalid NaN]`) and allowed ranges (`[@range min, max]`). + - Units are required except for boolean fields or for fields with an enum value. + `[-]` is used to indicate unitless fields. + - Comments follow the metadata after a space. + The line should not be terminated in a full stop. +- Constants: + - Don't have metadata: the description follows the comment marker after one space. + - Some constants, such as `MESSAGE_VERSION`, don't need documentation because they are standardized. + - Constants with the same name prefix are grouped together as enums after the associated field. + +The following sections expand on the allowed formats. + +## Message Description + +Every message should start with a comment block that describes the message: + +```py +# Short description (mandatory) +# +# Longer description for the message if needed. +# Can be multiline, and should have punctuation. +# Should be followed by an empty line. +``` + +This consists of a mandatory short description, optionally followed by an empty comment line, and then a longer description. + +Short description (mandatory): + +- A succinct explanation for the purpose of the message. +- Usually just one line without a terminating full stop. +- Minimally it may just mirror the message name. +- For example, [`AirspeedValidated`](../msg_docs/AirspeedValidated.md) above has the short description `Validated airspeed`. + +Long description (Optional): + +- Additional context required to understand how the message is used. +- In particular this should be anything that can't be inferred from the name, fields or constants, such as the publishers and expected consumers. + It might also cover whether the message is only used for a particular frame type or mode. +- The message is often multiline and contains punctuation. +- May include comment lines that are empty, in order to indicate paragraphs. + +Both short and long descriptions may be multi-line. +Single line descriptions should not include a terminating full stop, but multiline comments should do so. + +The message description block ends at the first non-comment line, which should be an empty line, but might be a field or constant. +Any subsequent comment lines are considered "internal comments". + +### Fields + +A typical field comment looks like this: + +```py +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +``` + +Field comments must all be on the same line as the field, and consist of optional metadata followed by a description: + +- `metadata` (Optional) + - Information about the field units and allowed values: + - `[]` + - The unit of measurement inside square brackets (note, no `@` delineator indicates a unit), such as `[m]` for metres. + - Allowed units include: `m`, `m/s`, `m/s^2`, `rad`, `rad/s`, `rpm`, `V`, `A`, `mA`, `mAh`, `W`, `dBm`, `s`, `ms`, `us`, `Ohm`, `MB`, `Kb/s`, `degC`, `Pa`. + - Units are required unless clearly invalid, such as when the field is a boolean, or is an enum value. + - Unitless values should be specified as `[-]`. + Note though that units are not required for boolean fields or enum fields. + - `[@enum ]` + - The `enum_name` gives the prefix of constant values in the message that can be assigned to the field. + Note that enums in uORB are just a naming convention: they are not explicitly declared. + Multiple enum names allowed for a field indicates a possible error in the field design. + - `[@range , ]` + - The allowed range of the field, specified as a `lower_value` and/or an `upper_value`. + Either value can be omitted to indicate an unbounded upper or lower value. + For example `[@range 0, 3]`, `[@range 5.3, ]`, `[@range , 3]`. + - `[@invalid ]` + - The `value` to set the field to indicate that the field doesn't contain valid data, such as `[@invalid NaN]`. + The `description` is optional, and might be used to indicate the conditions under which data is invalid. + - `[@frame ]` + - The `frame` in which the field is set, such as `[@frame NED]` or `[@frame Body]`. +- `description` + - A concise description of the purpose of the field, and including any important information that can't be inferred from the name! + Use a capital first letter, and omit the full stop if the description is a single sentence. + Multiple sentences may also omit the final full stop. + +### Constants + +Constants follow the documentation conventions as fields except they only have a description (no metadata). +Documentation for a constant might look like this: + +```py +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +``` + +Constants are often grouped together following a field as enum values. +Note below how the prefix `SOURCE` for the values is specified as an enum against the _field_. + +```py +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +... +``` + +A small number of constants have a standardised meaning and do not require documentation. +These are: + +- `ORB_QUEUE_LENGTH` +- `MESSAGE_VERSION` + +### `# TOPICS` + +The prefix `# TOPICS` is used to indicate topic names for multi-topic messages. +For example, the [VehicleGlobalPosition.msg](../msg_docs/VehicleGlobalPosition.md) message definition is used to define the topic ids as shown: + +```text +# TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position +# TOPICS estimator_global_position +# TOPICS aux_global_position +``` + +At time of writing there is no format for documenting these. diff --git a/docs/ko/vtx/index.md b/docs/ko/vtx/index.md new file mode 100644 index 0000000000..19f320905b --- /dev/null +++ b/docs/ko/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## 시작하기 + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Parameters: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Configuration Parameters + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). diff --git a/docs/package-lock.json b/docs/package-lock.json deleted file mode 100644 index 3313510d76..0000000000 --- a/docs/package-lock.json +++ /dev/null @@ -1,3291 +0,0 @@ -{ - "name": "px4_user_guide", - "version": "1.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "px4_user_guide", - "version": "1.0.1", - "license": "CC-BY-4.0", - "dependencies": { - "@red-asuka/vitepress-plugin-tabs": "^0.0.3", - "lite-youtube-embed": "^0.3.3", - "markdown-it-mathjax3": "^4.3.2", - "medium-zoom": "^1.1.0", - "open-editor": "^5.0.0", - "vitepress": "^1.6.3", - "vue3-tabs-component": "^1.3.7" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", - "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", - "@algolia/autocomplete-shared": "1.17.7" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", - "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", - "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", - "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.32.0.tgz", - "integrity": "sha512-HG/6Eib6DnJYm/B2ijWFXr4txca/YOuA4K7AsEU0JBrOZSB+RU7oeDyNBPi3c0v0UDDqlkBqM3vBU/auwZlglA==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.32.0.tgz", - "integrity": "sha512-8Y9MLU72WFQOW3HArYv16+Wvm6eGmsqbxxM1qxtm0hvSASJbxCm+zQAZe5stqysTlcWo4BJ82KEH1PfgHbJAmQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.32.0.tgz", - "integrity": "sha512-w8L+rgyXMCPBKmEdOT+RfgMrF0mT6HK60vPYWLz8DBs/P7yFdGo7urn99XCJvVLMSKXrIbZ2FMZ/i50nZTXnuQ==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.32.0.tgz", - "integrity": "sha512-AdWfynhUeX7jz/LTiFU3wwzJembTbdLkQIOLs4n7PyBuxZ3jz4azV1CWbIP8AjUOFmul6uXbmYza+KqyS5CzOA==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.32.0.tgz", - "integrity": "sha512-bTupJY4xzGZYI4cEQcPlSjjIEzMvv80h7zXGrXY1Y0KC/n/SLiMv84v7Uy+B6AG1Kiy9FQm2ADChBLo1uEhGtQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.32.0.tgz", - "integrity": "sha512-if+YTJw1G3nDKL2omSBjQltCHUQzbaHADkcPQrGFnIGhVyHU3Dzq4g46uEv8mrL5sxL8FjiS9LvekeUlL2NRqw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.32.0.tgz", - "integrity": "sha512-kmK5nVkKb4DSUgwbveMKe4X3xHdMsPsOVJeEzBvFJ+oS7CkBPmpfHAEq+CcmiPJs20YMv6yVtUT9yPWL5WgAhg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.32.0.tgz", - "integrity": "sha512-PZTqjJbx+fmPuT2ud1n4vYDSF1yrT//vOGI9HNYKNA0PM0xGUBWigf5gRivHsXa3oBnUlTyHV9j7Kqx5BHbVHQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.32.0.tgz", - "integrity": "sha512-kYYoOGjvNQAmHDS1v5sBj+0uEL9RzYqH/TAdq8wmcV+/22weKt/fjh+6LfiqkS1SCZFYYrwGnirrUhUM36lBIQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.32.0.tgz", - "integrity": "sha512-jyIBLdskjPAL7T1g57UMfUNx+PzvYbxKslwRUKBrBA6sNEsYCFdxJAtZSLUMmw6MC98RDt4ksmEl5zVMT5bsuw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.32.0.tgz", - "integrity": "sha512-eDp14z92Gt6JlFgiexImcWWH+Lk07s/FtxcoDaGrE4UVBgpwqOO6AfQM6dXh1pvHxlDFbMJihHc/vj3gBhPjqQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.32.0.tgz", - "integrity": "sha512-rnWVglh/K75hnaLbwSc2t7gCkbq1ldbPgeIKDUiEJxZ4mlguFgcltWjzpDQ/t1LQgxk9HdIFcQfM17Hid3aQ6Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.32.0.tgz", - "integrity": "sha512-LbzQ04+VLkzXY4LuOzgyjqEv/46Gwrk55PldaglMJ4i4eDXSRXGKkwJpXFwsoU+c1HMQlHIyjJBhrfsfdyRmyQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", - "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", - "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", - "license": "MIT" - }, - "node_modules/@docsearch/js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", - "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "3.8.2", - "preact": "^10.0.0" - } - }, - "node_modules/@docsearch/react": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", - "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-core": "1.17.7", - "@algolia/autocomplete-preset-algolia": "1.17.7", - "@docsearch/css": "3.8.2", - "algoliasearch": "^5.14.2" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@iconify-json/simple-icons": { - "version": "1.2.42", - "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.42.tgz", - "integrity": "sha512-G/EED0hUV1wMNUsWaFdQYLibm6SO7rP2GZP1+CvhszB5WAFYYibD3zoWp3X96xSIWpYQFvccvE17ewpd0Q1hWQ==", - "license": "CC0-1.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", - "license": "MIT" - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@red-asuka/vitepress-plugin-tabs": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@red-asuka/vitepress-plugin-tabs/-/vitepress-plugin-tabs-0.0.3.tgz", - "integrity": "sha512-YZX7lBzoL8rgNRahk85XmXtOYfX9P8RFtHpT33K2LClrbYF1N2J1ds5iKK1nQ9e5m9Wt4shC6Bk/rGwCxhHPHg==", - "license": "MIT", - "dependencies": { - "markdown-it": "^13.0.1", - "markdown-it-container": "^3.0.0" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.2.tgz", - "integrity": "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.2.tgz", - "integrity": "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.2.tgz", - "integrity": "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.2.tgz", - "integrity": "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.2.tgz", - "integrity": "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.2.tgz", - "integrity": "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.2.tgz", - "integrity": "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.2.tgz", - "integrity": "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.2.tgz", - "integrity": "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.2.tgz", - "integrity": "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.2.tgz", - "integrity": "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.2.tgz", - "integrity": "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.2.tgz", - "integrity": "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.2.tgz", - "integrity": "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.2.tgz", - "integrity": "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.2.tgz", - "integrity": "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.2.tgz", - "integrity": "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.2.tgz", - "integrity": "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.2.tgz", - "integrity": "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.2.tgz", - "integrity": "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "license": "MIT" - }, - "node_modules/@shikijs/core": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", - "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", - "license": "MIT", - "dependencies": { - "@shikijs/engine-javascript": "2.5.0", - "@shikijs/engine-oniguruma": "2.5.0", - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.4" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", - "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^3.1.0" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", - "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", - "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", - "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/transformers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", - "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "2.5.0", - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", - "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "license": "MIT" - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT" - }, - "node_modules/@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", - "license": "MIT", - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", - "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", - "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.17.tgz", - "integrity": "sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.27.5", - "@vue/shared": "3.5.17", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-core/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz", - "integrity": "sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==", - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.17", - "@vue/shared": "3.5.17" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz", - "integrity": "sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.27.5", - "@vue/compiler-core": "3.5.17", - "@vue/compiler-dom": "3.5.17", - "@vue/compiler-ssr": "3.5.17", - "@vue/shared": "3.5.17", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.17", - "postcss": "^8.5.6", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz", - "integrity": "sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.17", - "@vue/shared": "3.5.17" - } - }, - "node_modules/@vue/devtools-api": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz", - "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==", - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^7.7.7" - } - }, - "node_modules/@vue/devtools-kit": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", - "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^7.7.7", - "birpc": "^2.3.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/@vue/devtools-shared": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", - "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.17.tgz", - "integrity": "sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.17" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.17.tgz", - "integrity": "sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.17", - "@vue/shared": "3.5.17" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz", - "integrity": "sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.17", - "@vue/runtime-core": "3.5.17", - "@vue/shared": "3.5.17", - "csstype": "^3.1.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.17.tgz", - "integrity": "sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.17", - "@vue/shared": "3.5.17" - }, - "peerDependencies": { - "vue": "3.5.17" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.17.tgz", - "integrity": "sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==", - "license": "MIT" - }, - "node_modules/@vueuse/core": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", - "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.21", - "@vueuse/metadata": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/integrations": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", - "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", - "license": "MIT", - "dependencies": { - "@vueuse/core": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "async-validator": "^4", - "axios": "^1", - "change-case": "^5", - "drauu": "^0.4", - "focus-trap": "^7", - "fuse.js": "^7", - "idb-keyval": "^6", - "jwt-decode": "^4", - "nprogress": "^0.2", - "qrcode": "^1.5", - "sortablejs": "^1", - "universal-cookie": "^7" - }, - "peerDependenciesMeta": { - "async-validator": { - "optional": true - }, - "axios": { - "optional": true - }, - "change-case": { - "optional": true - }, - "drauu": { - "optional": true - }, - "focus-trap": { - "optional": true - }, - "fuse.js": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "jwt-decode": { - "optional": true - }, - "nprogress": { - "optional": true - }, - "qrcode": { - "optional": true - }, - "sortablejs": { - "optional": true - }, - "universal-cookie": { - "optional": true - } - } - }, - "node_modules/@vueuse/metadata": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", - "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", - "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", - "license": "MIT", - "dependencies": { - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", - "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", - "license": "MIT", - "engines": { - "node": ">=14.6" - } - }, - "node_modules/algoliasearch": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.32.0.tgz", - "integrity": "sha512-84xBncKNPBK8Ae89F65+SyVcOihrIbm/3N7to+GpRBHEUXGjA3ydWTMpcRW6jmFzkBQ/eqYy/y+J+NBpJWYjBg==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.32.0", - "@algolia/client-analytics": "5.32.0", - "@algolia/client-common": "5.32.0", - "@algolia/client-insights": "5.32.0", - "@algolia/client-personalization": "5.32.0", - "@algolia/client-query-suggestions": "5.32.0", - "@algolia/client-search": "5.32.0", - "@algolia/ingestion": "1.32.0", - "@algolia/monitoring": "1.32.0", - "@algolia/recommend": "5.32.0", - "@algolia/requester-browser-xhr": "5.32.0", - "@algolia/requester-fetch": "5.32.0", - "@algolia/requester-node-http": "5.32.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/birpc": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.4.0.tgz", - "integrity": "sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.10", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", - "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^1.5.0", - "dom-serializer": "^1.3.2", - "domhandler": "^4.2.0", - "htmlparser2": "^6.1.0", - "parse5": "^6.0.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", - "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", - "license": "BSD-2-Clause", - "dependencies": { - "css-select": "^4.3.0", - "css-what": "^6.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.3.1", - "domutils": "^2.8.0" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/copy-anything": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", - "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", - "license": "MIT", - "dependencies": { - "is-what": "^4.1.8" - }, - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/emoji-regex-xs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", - "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", - "license": "MIT" - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-editor": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-1.1.0.tgz", - "integrity": "sha512-7AXskzN6T7Q9TFcKAGJprUbpQa4i1VsAetO9rdBqbGMGlragTziBgWt4pVYJMBWHQlLoX0buy6WFikzPH4Qjpw==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escape-goat": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", - "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/execa": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", - "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.1", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.2.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/focus-trap": { - "version": "7.6.5", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.5.tgz", - "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==", - "license": "MIT", - "dependencies": { - "tabbable": "^6.2.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "license": "MIT" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-what": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", - "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", - "license": "MIT", - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/juice": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/juice/-/juice-8.1.0.tgz", - "integrity": "sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==", - "license": "MIT", - "dependencies": { - "cheerio": "1.0.0-rc.10", - "commander": "^6.1.0", - "mensch": "^0.3.4", - "slick": "^1.12.2", - "web-resource-inliner": "^6.0.1" - }, - "bin": { - "juice": "bin/juice" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/line-column-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/line-column-path/-/line-column-path-3.0.0.tgz", - "integrity": "sha512-Atocnm7Wr9nuvAn97yEPQa3pcQI5eLQGBz+m6iTb+CVw+IOzYB9MrYK7jI7BfC9ISnT4Fu0eiwhAScV//rp4Hw==", - "license": "MIT", - "dependencies": { - "type-fest": "^2.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", - "license": "MIT", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/lite-youtube-embed": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lite-youtube-embed/-/lite-youtube-embed-0.3.3.tgz", - "integrity": "sha512-gFfVVnj6NRjxVfJKo3qoLtpi0v5mn3AcR4eKD45wrxQuxzveFJUb+7Cr6uV6n+DjO8X3p0UzPPquhGt0H/y+NA==", - "license": "Apache-2.0" - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", - "license": "MIT" - }, - "node_modules/markdown-it": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", - "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it-container": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-3.0.0.tgz", - "integrity": "sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==", - "license": "MIT" - }, - "node_modules/markdown-it-mathjax3": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz", - "integrity": "sha512-TX3GW5NjmupgFtMJGRauioMbbkGsOXAAt1DZ/rzzYmTHqzkO1rNAdiMD4NiruurToPApn2kYy76x02QN26qr2w==", - "license": "MIT", - "dependencies": { - "juice": "^8.0.0", - "mathjax-full": "^3.2.0" - } - }, - "node_modules/mathjax-full": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz", - "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==", - "license": "Apache-2.0", - "dependencies": { - "esm": "^3.2.25", - "mhchemparser": "^4.1.0", - "mj-context-menu": "^0.6.1", - "speech-rule-engine": "^4.0.6" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "license": "MIT" - }, - "node_modules/medium-zoom": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", - "integrity": "sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==", - "license": "MIT" - }, - "node_modules/mensch": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", - "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", - "license": "MIT" - }, - "node_modules/mhchemparser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz", - "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==", - "license": "Apache-2.0" - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/minisearch": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.2.tgz", - "integrity": "sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==", - "license": "MIT" - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT" - }, - "node_modules/mj-context-menu": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz", - "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==", - "license": "Apache-2.0" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/oniguruma-to-es": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", - "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", - "license": "MIT", - "dependencies": { - "emoji-regex-xs": "^1.0.0", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/open": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", - "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", - "license": "MIT", - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open-editor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/open-editor/-/open-editor-5.1.0.tgz", - "integrity": "sha512-KkNqM6FdoegD6WhY2YXmWcovOux45NV+zBped2+G3+V74zkDPkIl4cqh6hte2zNDojtwO2nBOV8U+sgziWfPrg==", - "license": "MIT", - "dependencies": { - "env-editor": "^1.1.0", - "execa": "^9.3.0", - "line-column-path": "^3.0.0", - "open": "^10.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "license": "MIT" - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "license": "MIT", - "dependencies": { - "parse5": "^6.0.1" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/preact": { - "version": "10.26.9", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz", - "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, - "node_modules/pretty-ms": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", - "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", - "license": "MIT", - "dependencies": { - "parse-ms": "^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", - "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "license": "MIT" - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.2.tgz", - "integrity": "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.44.2", - "@rollup/rollup-android-arm64": "4.44.2", - "@rollup/rollup-darwin-arm64": "4.44.2", - "@rollup/rollup-darwin-x64": "4.44.2", - "@rollup/rollup-freebsd-arm64": "4.44.2", - "@rollup/rollup-freebsd-x64": "4.44.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", - "@rollup/rollup-linux-arm-musleabihf": "4.44.2", - "@rollup/rollup-linux-arm64-gnu": "4.44.2", - "@rollup/rollup-linux-arm64-musl": "4.44.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", - "@rollup/rollup-linux-riscv64-gnu": "4.44.2", - "@rollup/rollup-linux-riscv64-musl": "4.44.2", - "@rollup/rollup-linux-s390x-gnu": "4.44.2", - "@rollup/rollup-linux-x64-gnu": "4.44.2", - "@rollup/rollup-linux-x64-musl": "4.44.2", - "@rollup/rollup-win32-arm64-msvc": "4.44.2", - "@rollup/rollup-win32-ia32-msvc": "4.44.2", - "@rollup/rollup-win32-x64-msvc": "4.44.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-applescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "license": "MIT", - "peer": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shiki": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", - "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "2.5.0", - "@shikijs/engine-javascript": "2.5.0", - "@shikijs/engine-oniguruma": "2.5.0", - "@shikijs/langs": "2.5.0", - "@shikijs/themes": "2.5.0", - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slick": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", - "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", - "license": "MIT (http://mootools.net/license.txt)", - "engines": { - "node": "*" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/speakingurl": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", - "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/speech-rule-engine": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.1.2.tgz", - "integrity": "sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==", - "license": "Apache-2.0", - "dependencies": { - "@xmldom/xmldom": "0.9.8", - "commander": "13.1.0", - "wicked-good-xpath": "1.3.0" - }, - "bin": { - "sre": "bin/sre" - } - }, - "node_modules/speech-rule-engine/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/superjson": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", - "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", - "license": "MIT", - "dependencies": { - "copy-anything": "^3.0.2" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", - "license": "MIT" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "license": "MIT" - }, - "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/valid-data-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", - "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "5.4.19", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", - "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitepress": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.3.tgz", - "integrity": "sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==", - "license": "MIT", - "dependencies": { - "@docsearch/css": "3.8.2", - "@docsearch/js": "3.8.2", - "@iconify-json/simple-icons": "^1.2.21", - "@shikijs/core": "^2.1.0", - "@shikijs/transformers": "^2.1.0", - "@shikijs/types": "^2.1.0", - "@types/markdown-it": "^14.1.2", - "@vitejs/plugin-vue": "^5.2.1", - "@vue/devtools-api": "^7.7.0", - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.4.0", - "@vueuse/integrations": "^12.4.0", - "focus-trap": "^7.6.4", - "mark.js": "8.11.1", - "minisearch": "^7.1.1", - "shiki": "^2.1.0", - "vite": "^5.4.14", - "vue": "^3.5.13" - }, - "bin": { - "vitepress": "bin/vitepress.js" - }, - "peerDependencies": { - "markdown-it-mathjax3": "^4", - "postcss": "^8" - }, - "peerDependenciesMeta": { - "markdown-it-mathjax3": { - "optional": true - }, - "postcss": { - "optional": true - } - } - }, - "node_modules/vue": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.17.tgz", - "integrity": "sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.17", - "@vue/compiler-sfc": "3.5.17", - "@vue/runtime-dom": "3.5.17", - "@vue/server-renderer": "3.5.17", - "@vue/shared": "3.5.17" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vue3-tabs-component": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/vue3-tabs-component/-/vue3-tabs-component-1.3.7.tgz", - "integrity": "sha512-nitYlPlTrKCW8msQS1HdtajYNRAfZsSP+2wQQymJDGDCK3um62mXP4oKUgAF5pRe6md86LMRQud7Ic3zmu7Zpg==", - "license": "MIT", - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/web-resource-inliner": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz", - "integrity": "sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==", - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "escape-goat": "^3.0.0", - "htmlparser2": "^5.0.0", - "mime": "^2.4.6", - "node-fetch": "^2.6.0", - "valid-data-url": "^3.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web-resource-inliner/node_modules/domhandler": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", - "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.0.1" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/web-resource-inliner/node_modules/htmlparser2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz", - "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^3.3.0", - "domutils": "^2.4.2", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/fb55/htmlparser2?sponsor=1" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wicked-good-xpath": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", - "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==", - "license": "MIT" - }, - "node_modules/yoctocolors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", - "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/docs/package.json b/docs/package.json index 0b836998bc..b95faf493e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -23,5 +23,8 @@ "open-editor": "^5.0.0", "vitepress": "^1.6.3", "vue3-tabs-component": "^1.3.7" + }, + "devDependencies": { + "prettier": "^3.2.0" } } diff --git a/docs/public/config/failsafe/index.js b/docs/public/config/failsafe/index.js index 58904fd091..d013fbdc67 100644 --- a/docs/public/config/failsafe/index.js +++ b/docs/public/config/failsafe/index.js @@ -1 +1 @@ -var Module=typeof Module!="undefined"?Module:{};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["v"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("index.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["u"];updateMemoryViews();wasmTable=wasmExports["A"];assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>abort("");var AsciiToString=ptr=>{var str="";while(1){var ch=HEAPU8[ptr++];if(!ch)return str;str+=String.fromCharCode(ch)}};var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var BindingError=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};var throwBindingError=message=>{throw new BindingError(message)};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){return sharedRegisterType(rawType,registeredInstance,options)}var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];case 8:return signed?pointer=>HEAP64[pointer>>3]:pointer=>HEAPU64[pointer>>3];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{name=AsciiToString(name);const isUnsignedType=minRange===0n;let fromWireType=value=>value;if(isUnsignedType){const bitSize=size*8;fromWireType=value=>BigInt.asUintN(bitSize,value);maxRange=fromWireType(maxRange)}registerType(primitiveType,{name,fromWireType,toWireType:(destructors,value)=>{if(typeof value=="number"){value=BigInt(value)}return value},argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,!isUnsignedType),destructorFunction:null})};var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=AsciiToString(name);registerType(rawType,{name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},argPackAdvance:GenericWireTypeSize,readValueFromPointer:function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var shallowCopyInternalPointer=o=>({count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType});var throwInstanceAlreadyDeleted=obj=>{function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")};var finalizationRegistry=false;var detachFinalizer=handle=>{};var runDestructor=$$=>{if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}};var releaseClassHandle=$$=>{$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}};var attachFinalizer=handle=>{if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};var deletionQueue=[];var flushPendingDeletes=()=>{while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}};var delayFunction;var init_ClassHandle=()=>{let proto=ClassHandle.prototype;Object.assign(proto,{isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;other.$$=other.$$;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right},clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}},delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}},isDeleted(){return!this.$$.ptr},deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}});const symbolDispose=Symbol.dispose;if(symbolDispose){proto[symbolDispose]=proto["delete"]}};function ClassHandle(){}var createNamedFunction=(name,func)=>Object.defineProperty(func,"name",{value:name});var registeredPointers={};var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module[name].overloadTable.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}var upcastPointer=(ptr,ptrClass,desiredClass)=>{while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr};var embindRepr=v=>{if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}};function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle||!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(()=>clonedHandle["delete"]()));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var downcastPointer=(ptr,ptrClass,desiredClass)=>{if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)};var registeredInstances={};var getBasestPointer=(class_,ptr)=>{if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr};var getInheritedInstance=(class_,ptr)=>{ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]};var InternalError=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};var throwInternalError=message=>{throw new InternalError(message)};var makeClassHandle=(prototype,record)=>{if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record,writable:true}}))};function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var init_RegisteredPointer=()=>{Object.assign(RegisteredPointer.prototype,{getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr},destructor(ptr){this.rawDestructor?.(ptr)},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,fromWireType:RegisteredPointer_fromWireType})};function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistent public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var embind__requireFunction=(signature,rawFunction,isAsync=false)=>{signature=AsciiToString(signature);function makeDynCaller(){var rtn=getWasmTableEntry(rawFunction);return rtn}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};class UnboundTypeError extends Error{}var getTypeName=type=>{var ptr=___getTypeName(type);var rv=AsciiToString(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(type=>typeDependencies[type]=dependentTypes);function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};var __embind_register_class=(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor)=>{name=AsciiToString(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);upcast&&=embind__requireFunction(upcastSignature,upcast);downcast&&=embind__requireFunction(downcastSignature,downcast);rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],base=>{base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(name,function(...args){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError(`Use 'new' to construct ${name}`)}if(undefined===registeredClass.constructor_body){throw new BindingError(`${name} has no accessible constructor`)}var body=registeredClass.constructor_body[args.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,args)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){registeredClass.baseClass.__derivedClasses??=[];registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function usesDestructorStack(argTypes){for(var i=1;i{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex===-1)return signature;return signature.slice(0,argsIndex)};var __embind_register_class_function=(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync,isNonnullReturn)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=AsciiToString(methodName);methodName=getFunctionName(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker,isAsync);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})};var validateThis=(this_,classType,humanName)=>{if(!(this_ instanceof Object)){throwBindingError(`${humanName} with invalid "this": ${this_}`)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(`${humanName} incompatible with "this" of type ${this_.constructor.name}`)}if(!this_.$$.ptr){throwBindingError(`cannot call emscripten binding method ${humanName} on deleted object`)}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)};var __embind_register_class_property=(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{fieldName=AsciiToString(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],classType=>{classType=classType[0];var humanName=`${classType.name}.${fieldName}`;var desc={get(){throwUnboundTypeError(`Cannot access ${humanName} due to unbound types`,[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=()=>throwUnboundTypeError(`Cannot access ${humanName} due to unbound types`,[getterReturnType,setterArgumentType])}else{desc.set=v=>throwBindingError(humanName+" is a read-only property")}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],types=>{var getterReturnType=types[0];var desc={get(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})};var emval_freelist=[];var emval_handles=[0,1,,1,null,1,true,1,false,1];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){emval_handles[handle]=undefined;emval_freelist.push(handle)}};var Emval={toValue:handle=>{if(!handle){throwBindingError(`Cannot use deleted val. handle = ${handle}`)}return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};var EmValType={name:"emscripten::val",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=AsciiToString(name);registerType(rawType,{name,fromWireType:value=>value,toWireType:(destructors,value)=>value,argPackAdvance:GenericWireTypeSize,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync,isNonnullReturn)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=AsciiToString(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker,isAsync);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=AsciiToString(name);const isUnsignedType=minRange===0;let fromWireType=value=>value;if(isUnsignedType){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift;maxRange=fromWireType(maxRange)}registerType(primitiveType,{name,fromWireType,toWireType:(destructors,value)=>value,argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=AsciiToString(name);registerType(rawType,{name,fromWireType:decodeMemoryView,argPackAdvance:GenericWireTypeSize,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var __embind_register_std_string=(rawType,name)=>{name=AsciiToString(name);var stdStringIsUTF8=true;registerType(rawType,{name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(valueIsOfTypeString){if(stdStringIsUTF8){stringToUTF8(value,ptr,length+1)}else{for(var i=0;i255){_free(base);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}}else{HEAPU8.set(value,ptr)}if(destructors!==null){destructors.push(_free,base)}return base},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):undefined;var UTF16ToString=(ptr,maxBytesToRead)=>{var idx=ptr>>1;var maxIdx=idx+maxBytesToRead/2;var endIdx=idx;while(!(endIdx>=maxIdx)&&HEAPU16[endIdx])++endIdx;if(endIdx-idx>16&&UTF16Decoder)return UTF16Decoder.decode(HEAPU16.subarray(idx,endIdx));var str="";for(var i=idx;!(i>=maxIdx);++i){var codeUnit=HEAPU16[i];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var str="";for(var i=0;!(i>=maxBytesToRead/4);i++){var utf32=HEAP32[ptr+i*4>>2];if(!utf32)break;str+=String.fromCodePoint(utf32)}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i65535){i++}HEAP32[outPtr>>2]=codePoint;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i65535){i++}len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=AsciiToString(name);var decodeString,encodeString,readCharAt,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;readCharAt=pointer=>HEAPU16[pointer>>1]}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;readCharAt=pointer=>HEAPU32[pointer>>2]}registerType(rawType,{name,fromWireType:value=>{var length=HEAPU32[value>>2];var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||readCharAt(currentBytePtr)==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_void=(rawType,name)=>{name=AsciiToString(name);registerType(rawType,{isVoid:true,name,argPackAdvance:0,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var _emscripten_date_now=()=>Date.now();var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var printCharBuffers=[null,[],[]];var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer));buffer.length=0}else{buffer.push(curr)}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0};init_ClassHandle();init_RegisteredPointer();{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}var _param_get,_param_set_used,__Znwm,__ZdlPvm,_malloc,__ZNSt12length_errorD1Ev,___cxa_allocate_exception,__ZNSt20bad_array_new_lengthD1Ev,__ZNSt20bad_array_new_lengthC1Ev,__ZNSt12out_of_rangeD1Ev,___cxa_pure_virtual,___getTypeName,__ZNSt9exceptionD2Ev,__emscripten_memcpy_bulkmem,_emscripten_stack_get_end,_emscripten_stack_get_base,_free,_emscripten_stack_init,_emscripten_stack_set_limits,_emscripten_stack_get_free,__ZSt15get_new_handlerv,__Znam,__ZdlPv,__ZdaPv,__ZdaPvm,__ZnwmSt11align_val_t,__ZnamSt11align_val_t,__ZdlPvSt11align_val_t,__ZdlPvmSt11align_val_t,__ZdaPvSt11align_val_t,__ZdaPvmSt11align_val_t,__ZSt14set_unexpectedPFvvE,__ZSt13set_terminatePFvvE,__ZSt15set_new_handlerPFvvE,__ZSt14get_unexpectedv,__ZSt10unexpectedv,__ZSt13get_terminatev,__ZSt9terminatev,___cxa_current_primary_exception,___cxa_rethrow_primary_exception,___cxa_uncaught_exception,___cxa_uncaught_exceptions,___cxa_free_exception,___cxa_init_primary_exception,___cxa_deleted_virtual,___dynamic_cast,__ZNSt9type_infoD2Ev,__ZNSt9exceptionD0Ev,__ZNSt9exceptionD1Ev,__ZNKSt9exception4whatEv,__ZNSt13bad_exceptionD0Ev,__ZNSt13bad_exceptionD1Ev,__ZNKSt13bad_exception4whatEv,__ZNSt9bad_allocC2Ev,__ZNSt9bad_allocD0Ev,__ZNSt9bad_allocD1Ev,__ZNKSt9bad_alloc4whatEv,__ZNSt20bad_array_new_lengthC2Ev,__ZNSt20bad_array_new_lengthD0Ev,__ZNKSt20bad_array_new_length4whatEv,__ZNSt13bad_exceptionD2Ev,__ZNSt9bad_allocC1Ev,__ZNSt9bad_allocD2Ev,__ZNSt20bad_array_new_lengthD2Ev,__ZNSt11logic_errorD2Ev,__ZNSt11logic_errorD0Ev,__ZNSt11logic_errorD1Ev,__ZNKSt11logic_error4whatEv,__ZNSt13runtime_errorD2Ev,__ZNSt13runtime_errorD0Ev,__ZNSt13runtime_errorD1Ev,__ZNKSt13runtime_error4whatEv,__ZNSt12domain_errorD0Ev,__ZNSt12domain_errorD1Ev,__ZNSt16invalid_argumentD0Ev,__ZNSt16invalid_argumentD1Ev,__ZNSt12length_errorD0Ev,__ZNSt12out_of_rangeD0Ev,__ZNSt11range_errorD0Ev,__ZNSt11range_errorD1Ev,__ZNSt14overflow_errorD0Ev,__ZNSt14overflow_errorD1Ev,__ZNSt15underflow_errorD0Ev,__ZNSt15underflow_errorD1Ev,__ZNSt12domain_errorD2Ev,__ZNSt16invalid_argumentD2Ev,__ZNSt12length_errorD2Ev,__ZNSt12out_of_rangeD2Ev,__ZNSt11range_errorD2Ev,__ZNSt14overflow_errorD2Ev,__ZNSt15underflow_errorD2Ev,__ZNSt9type_infoD0Ev,__ZNSt9type_infoD1Ev,__ZNSt8bad_castC2Ev,__ZNSt8bad_castD2Ev,__ZNSt8bad_castD0Ev,__ZNSt8bad_castD1Ev,__ZNKSt8bad_cast4whatEv,__ZNSt10bad_typeidC2Ev,__ZNSt10bad_typeidD2Ev,__ZNSt10bad_typeidD0Ev,__ZNSt10bad_typeidD1Ev,__ZNKSt10bad_typeid4whatEv,__ZNSt8bad_castC1Ev,__ZNSt10bad_typeidC1Ev;function assignWasmExports(wasmExports){Module["_param_get"]=_param_get=wasmExports["w"];Module["_param_set_used"]=_param_set_used=wasmExports["x"];Module["__Znwm"]=__Znwm=wasmExports["y"];Module["__ZdlPvm"]=__ZdlPvm=wasmExports["z"];_malloc=wasmExports["B"];Module["__ZNSt12length_errorD1Ev"]=__ZNSt12length_errorD1Ev=wasmExports["C"];Module["___cxa_allocate_exception"]=___cxa_allocate_exception=wasmExports["D"];Module["__ZNSt20bad_array_new_lengthD1Ev"]=__ZNSt20bad_array_new_lengthD1Ev=wasmExports["E"];Module["__ZNSt20bad_array_new_lengthC1Ev"]=__ZNSt20bad_array_new_lengthC1Ev=wasmExports["F"];Module["__ZNSt12out_of_rangeD1Ev"]=__ZNSt12out_of_rangeD1Ev=wasmExports["G"];Module["___cxa_pure_virtual"]=___cxa_pure_virtual=wasmExports["H"];___getTypeName=wasmExports["I"];Module["__ZNSt9exceptionD2Ev"]=__ZNSt9exceptionD2Ev=wasmExports["J"];Module["__emscripten_memcpy_bulkmem"]=__emscripten_memcpy_bulkmem=wasmExports["K"];Module["_emscripten_stack_get_end"]=_emscripten_stack_get_end=wasmExports["L"];Module["_emscripten_stack_get_base"]=_emscripten_stack_get_base=wasmExports["M"];_free=wasmExports["N"];Module["_emscripten_stack_init"]=_emscripten_stack_init=wasmExports["O"];Module["_emscripten_stack_set_limits"]=_emscripten_stack_set_limits=wasmExports["P"];Module["_emscripten_stack_get_free"]=_emscripten_stack_get_free=wasmExports["Q"];Module["__ZSt15get_new_handlerv"]=__ZSt15get_new_handlerv=wasmExports["R"];Module["__Znam"]=__Znam=wasmExports["S"];Module["__ZdlPv"]=__ZdlPv=wasmExports["T"];Module["__ZdaPv"]=__ZdaPv=wasmExports["U"];Module["__ZdaPvm"]=__ZdaPvm=wasmExports["V"];Module["__ZnwmSt11align_val_t"]=__ZnwmSt11align_val_t=wasmExports["W"];Module["__ZnamSt11align_val_t"]=__ZnamSt11align_val_t=wasmExports["X"];Module["__ZdlPvSt11align_val_t"]=__ZdlPvSt11align_val_t=wasmExports["Y"];Module["__ZdlPvmSt11align_val_t"]=__ZdlPvmSt11align_val_t=wasmExports["Z"];Module["__ZdaPvSt11align_val_t"]=__ZdaPvSt11align_val_t=wasmExports["_"];Module["__ZdaPvmSt11align_val_t"]=__ZdaPvmSt11align_val_t=wasmExports["$"];Module["__ZSt14set_unexpectedPFvvE"]=__ZSt14set_unexpectedPFvvE=wasmExports["aa"];Module["__ZSt13set_terminatePFvvE"]=__ZSt13set_terminatePFvvE=wasmExports["ba"];Module["__ZSt15set_new_handlerPFvvE"]=__ZSt15set_new_handlerPFvvE=wasmExports["ca"];Module["__ZSt14get_unexpectedv"]=__ZSt14get_unexpectedv=wasmExports["da"];Module["__ZSt10unexpectedv"]=__ZSt10unexpectedv=wasmExports["ea"];Module["__ZSt13get_terminatev"]=__ZSt13get_terminatev=wasmExports["fa"];Module["__ZSt9terminatev"]=__ZSt9terminatev=wasmExports["ga"];Module["___cxa_current_primary_exception"]=___cxa_current_primary_exception=wasmExports["ha"];Module["___cxa_rethrow_primary_exception"]=___cxa_rethrow_primary_exception=wasmExports["ia"];Module["___cxa_uncaught_exception"]=___cxa_uncaught_exception=wasmExports["ja"];Module["___cxa_uncaught_exceptions"]=___cxa_uncaught_exceptions=wasmExports["ka"];Module["___cxa_free_exception"]=___cxa_free_exception=wasmExports["la"];Module["___cxa_init_primary_exception"]=___cxa_init_primary_exception=wasmExports["ma"];Module["___cxa_deleted_virtual"]=___cxa_deleted_virtual=wasmExports["na"];Module["___dynamic_cast"]=___dynamic_cast=wasmExports["oa"];Module["__ZNSt9type_infoD2Ev"]=__ZNSt9type_infoD2Ev=wasmExports["pa"];Module["__ZNSt9exceptionD0Ev"]=__ZNSt9exceptionD0Ev=wasmExports["qa"];Module["__ZNSt9exceptionD1Ev"]=__ZNSt9exceptionD1Ev=wasmExports["ra"];Module["__ZNKSt9exception4whatEv"]=__ZNKSt9exception4whatEv=wasmExports["sa"];Module["__ZNSt13bad_exceptionD0Ev"]=__ZNSt13bad_exceptionD0Ev=wasmExports["ta"];Module["__ZNSt13bad_exceptionD1Ev"]=__ZNSt13bad_exceptionD1Ev=wasmExports["ua"];Module["__ZNKSt13bad_exception4whatEv"]=__ZNKSt13bad_exception4whatEv=wasmExports["va"];Module["__ZNSt9bad_allocC2Ev"]=__ZNSt9bad_allocC2Ev=wasmExports["wa"];Module["__ZNSt9bad_allocD0Ev"]=__ZNSt9bad_allocD0Ev=wasmExports["xa"];Module["__ZNSt9bad_allocD1Ev"]=__ZNSt9bad_allocD1Ev=wasmExports["ya"];Module["__ZNKSt9bad_alloc4whatEv"]=__ZNKSt9bad_alloc4whatEv=wasmExports["za"];Module["__ZNSt20bad_array_new_lengthC2Ev"]=__ZNSt20bad_array_new_lengthC2Ev=wasmExports["Aa"];Module["__ZNSt20bad_array_new_lengthD0Ev"]=__ZNSt20bad_array_new_lengthD0Ev=wasmExports["Ba"];Module["__ZNKSt20bad_array_new_length4whatEv"]=__ZNKSt20bad_array_new_length4whatEv=wasmExports["Ca"];Module["__ZNSt13bad_exceptionD2Ev"]=__ZNSt13bad_exceptionD2Ev=wasmExports["Da"];Module["__ZNSt9bad_allocC1Ev"]=__ZNSt9bad_allocC1Ev=wasmExports["Ea"];Module["__ZNSt9bad_allocD2Ev"]=__ZNSt9bad_allocD2Ev=wasmExports["Fa"];Module["__ZNSt20bad_array_new_lengthD2Ev"]=__ZNSt20bad_array_new_lengthD2Ev=wasmExports["Ga"];Module["__ZNSt11logic_errorD2Ev"]=__ZNSt11logic_errorD2Ev=wasmExports["Ha"];Module["__ZNSt11logic_errorD0Ev"]=__ZNSt11logic_errorD0Ev=wasmExports["Ia"];Module["__ZNSt11logic_errorD1Ev"]=__ZNSt11logic_errorD1Ev=wasmExports["Ja"];Module["__ZNKSt11logic_error4whatEv"]=__ZNKSt11logic_error4whatEv=wasmExports["Ka"];Module["__ZNSt13runtime_errorD2Ev"]=__ZNSt13runtime_errorD2Ev=wasmExports["La"];Module["__ZNSt13runtime_errorD0Ev"]=__ZNSt13runtime_errorD0Ev=wasmExports["Ma"];Module["__ZNSt13runtime_errorD1Ev"]=__ZNSt13runtime_errorD1Ev=wasmExports["Na"];Module["__ZNKSt13runtime_error4whatEv"]=__ZNKSt13runtime_error4whatEv=wasmExports["Oa"];Module["__ZNSt12domain_errorD0Ev"]=__ZNSt12domain_errorD0Ev=wasmExports["Pa"];Module["__ZNSt12domain_errorD1Ev"]=__ZNSt12domain_errorD1Ev=wasmExports["Qa"];Module["__ZNSt16invalid_argumentD0Ev"]=__ZNSt16invalid_argumentD0Ev=wasmExports["Ra"];Module["__ZNSt16invalid_argumentD1Ev"]=__ZNSt16invalid_argumentD1Ev=wasmExports["Sa"];Module["__ZNSt12length_errorD0Ev"]=__ZNSt12length_errorD0Ev=wasmExports["Ta"];Module["__ZNSt12out_of_rangeD0Ev"]=__ZNSt12out_of_rangeD0Ev=wasmExports["Ua"];Module["__ZNSt11range_errorD0Ev"]=__ZNSt11range_errorD0Ev=wasmExports["Va"];Module["__ZNSt11range_errorD1Ev"]=__ZNSt11range_errorD1Ev=wasmExports["Wa"];Module["__ZNSt14overflow_errorD0Ev"]=__ZNSt14overflow_errorD0Ev=wasmExports["Xa"];Module["__ZNSt14overflow_errorD1Ev"]=__ZNSt14overflow_errorD1Ev=wasmExports["Ya"];Module["__ZNSt15underflow_errorD0Ev"]=__ZNSt15underflow_errorD0Ev=wasmExports["Za"];Module["__ZNSt15underflow_errorD1Ev"]=__ZNSt15underflow_errorD1Ev=wasmExports["_a"];Module["__ZNSt12domain_errorD2Ev"]=__ZNSt12domain_errorD2Ev=wasmExports["$a"];Module["__ZNSt16invalid_argumentD2Ev"]=__ZNSt16invalid_argumentD2Ev=wasmExports["ab"];Module["__ZNSt12length_errorD2Ev"]=__ZNSt12length_errorD2Ev=wasmExports["bb"];Module["__ZNSt12out_of_rangeD2Ev"]=__ZNSt12out_of_rangeD2Ev=wasmExports["cb"];Module["__ZNSt11range_errorD2Ev"]=__ZNSt11range_errorD2Ev=wasmExports["db"];Module["__ZNSt14overflow_errorD2Ev"]=__ZNSt14overflow_errorD2Ev=wasmExports["eb"];Module["__ZNSt15underflow_errorD2Ev"]=__ZNSt15underflow_errorD2Ev=wasmExports["fb"];Module["__ZNSt9type_infoD0Ev"]=__ZNSt9type_infoD0Ev=wasmExports["gb"];Module["__ZNSt9type_infoD1Ev"]=__ZNSt9type_infoD1Ev=wasmExports["hb"];Module["__ZNSt8bad_castC2Ev"]=__ZNSt8bad_castC2Ev=wasmExports["ib"];Module["__ZNSt8bad_castD2Ev"]=__ZNSt8bad_castD2Ev=wasmExports["jb"];Module["__ZNSt8bad_castD0Ev"]=__ZNSt8bad_castD0Ev=wasmExports["kb"];Module["__ZNSt8bad_castD1Ev"]=__ZNSt8bad_castD1Ev=wasmExports["lb"];Module["__ZNKSt8bad_cast4whatEv"]=__ZNKSt8bad_cast4whatEv=wasmExports["mb"];Module["__ZNSt10bad_typeidC2Ev"]=__ZNSt10bad_typeidC2Ev=wasmExports["nb"];Module["__ZNSt10bad_typeidD2Ev"]=__ZNSt10bad_typeidD2Ev=wasmExports["ob"];Module["__ZNSt10bad_typeidD0Ev"]=__ZNSt10bad_typeidD0Ev=wasmExports["pb"];Module["__ZNSt10bad_typeidD1Ev"]=__ZNSt10bad_typeidD1Ev=wasmExports["qb"];Module["__ZNKSt10bad_typeid4whatEv"]=__ZNKSt10bad_typeid4whatEv=wasmExports["rb"];Module["__ZNSt8bad_castC1Ev"]=__ZNSt8bad_castC1Ev=wasmExports["sb"];Module["__ZNSt10bad_typeidC1Ev"]=__ZNSt10bad_typeidC1Ev=wasmExports["tb"]}var __ZTIPK16failsafe_flags_s=Module["__ZTIPK16failsafe_flags_s"]=47432;var __ZTIP16failsafe_flags_s=Module["__ZTIP16failsafe_flags_s"]=47416;var __ZTI16failsafe_flags_s=Module["__ZTI16failsafe_flags_s"]=47408;var __ZTIb=Module["__ZTIb"]=30292;var __ZTIh=Module["__ZTIh"]=30448;var __ZTIPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTIPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=47580;var __ZTIPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTIPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=47564;var __ZTINSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTINSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=47512;var __ZTISt12length_error=Module["__ZTISt12length_error"]=32392;var __ZTVSt12length_error=Module["__ZTVSt12length_error"]=32372;var __ZTISt20bad_array_new_length=Module["__ZTISt20bad_array_new_length"]=32156;var __ZTINSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE=Module["__ZTINSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"]=47500;var __ZTISt12out_of_range=Module["__ZTISt12out_of_range"]=32444;var __ZTVSt12out_of_range=Module["__ZTVSt12out_of_range"]=32424;var __ZTVN10__cxxabiv120__si_class_type_infoE=Module["__ZTVN10__cxxabiv120__si_class_type_infoE"]=31724;var __ZTVN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTVN10__cxxabiv121__vmi_class_type_infoE"]=31816;var __ZTVN10__cxxabiv117__class_type_infoE=Module["__ZTVN10__cxxabiv117__class_type_infoE"]=31684;var __ZTS16failsafe_flags_s=Module["__ZTS16failsafe_flags_s"]=28034;var __ZTVN10__cxxabiv119__pointer_type_infoE=Module["__ZTVN10__cxxabiv119__pointer_type_infoE"]=31936;var __ZTSP16failsafe_flags_s=Module["__ZTSP16failsafe_flags_s"]=28053;var __ZTSPK16failsafe_flags_s=Module["__ZTSPK16failsafe_flags_s"]=28073;var __ZTIi=Module["__ZTIi"]=30656;var __ZTSNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE=Module["__ZTSNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"]=28122;var __ZTSNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=28189;var __ZTIv=Module["__ZTIv"]=30184;var __ZTIf=Module["__ZTIf"]=31128;var __ZTSPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=28287;var __ZTSPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=28374;var __ZTIm=Module["__ZTIm"]=30812;var __ZTIN10emscripten3valE=Module["__ZTIN10emscripten3valE"]=47652;var __ZTSN10emscripten3valE=Module["__ZTSN10emscripten3valE"]=28477;var __ZTIc=Module["__ZTIc"]=30396;var __ZTIa=Module["__ZTIa"]=30500;var __ZTIs=Module["__ZTIs"]=30552;var __ZTIt=Module["__ZTIt"]=30604;var __ZTIj=Module["__ZTIj"]=30708;var __ZTIl=Module["__ZTIl"]=30760;var __ZTIx=Module["__ZTIx"]=30864;var __ZTIy=Module["__ZTIy"]=30916;var __ZTId=Module["__ZTId"]=31180;var __ZTINSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE=Module["__ZTINSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE"]=28532;var __ZTINSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE=Module["__ZTINSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE"]=28604;var __ZTINSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE=Module["__ZTINSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE"]=28680;var __ZTIN10emscripten11memory_viewIcEE=Module["__ZTIN10emscripten11memory_viewIcEE"]=28756;var __ZTIN10emscripten11memory_viewIaEE=Module["__ZTIN10emscripten11memory_viewIaEE"]=28796;var __ZTIN10emscripten11memory_viewIhEE=Module["__ZTIN10emscripten11memory_viewIhEE"]=28836;var __ZTIN10emscripten11memory_viewIsEE=Module["__ZTIN10emscripten11memory_viewIsEE"]=28876;var __ZTIN10emscripten11memory_viewItEE=Module["__ZTIN10emscripten11memory_viewItEE"]=28916;var __ZTIN10emscripten11memory_viewIiEE=Module["__ZTIN10emscripten11memory_viewIiEE"]=28956;var __ZTIN10emscripten11memory_viewIjEE=Module["__ZTIN10emscripten11memory_viewIjEE"]=28996;var __ZTIN10emscripten11memory_viewIlEE=Module["__ZTIN10emscripten11memory_viewIlEE"]=29036;var __ZTIN10emscripten11memory_viewImEE=Module["__ZTIN10emscripten11memory_viewImEE"]=29076;var __ZTIN10emscripten11memory_viewIxEE=Module["__ZTIN10emscripten11memory_viewIxEE"]=29116;var __ZTIN10emscripten11memory_viewIyEE=Module["__ZTIN10emscripten11memory_viewIyEE"]=29156;var __ZTIN10emscripten11memory_viewIfEE=Module["__ZTIN10emscripten11memory_viewIfEE"]=29196;var __ZTIN10emscripten11memory_viewIdEE=Module["__ZTIN10emscripten11memory_viewIdEE"]=29236;var __ZTSNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE=Module["__ZTSNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE"]=28540;var __ZTSNSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE=Module["__ZTSNSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE"]=28612;var __ZTSNSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE=Module["__ZTSNSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE"]=28688;var __ZTSN10emscripten11memory_viewIcEE=Module["__ZTSN10emscripten11memory_viewIcEE"]=28764;var __ZTSN10emscripten11memory_viewIaEE=Module["__ZTSN10emscripten11memory_viewIaEE"]=28804;var __ZTSN10emscripten11memory_viewIhEE=Module["__ZTSN10emscripten11memory_viewIhEE"]=28844;var __ZTSN10emscripten11memory_viewIsEE=Module["__ZTSN10emscripten11memory_viewIsEE"]=28884;var __ZTSN10emscripten11memory_viewItEE=Module["__ZTSN10emscripten11memory_viewItEE"]=28924;var __ZTSN10emscripten11memory_viewIiEE=Module["__ZTSN10emscripten11memory_viewIiEE"]=28964;var __ZTSN10emscripten11memory_viewIjEE=Module["__ZTSN10emscripten11memory_viewIjEE"]=29004;var __ZTSN10emscripten11memory_viewIlEE=Module["__ZTSN10emscripten11memory_viewIlEE"]=29044;var __ZTSN10emscripten11memory_viewImEE=Module["__ZTSN10emscripten11memory_viewImEE"]=29084;var __ZTSN10emscripten11memory_viewIxEE=Module["__ZTSN10emscripten11memory_viewIxEE"]=29124;var __ZTSN10emscripten11memory_viewIyEE=Module["__ZTSN10emscripten11memory_viewIyEE"]=29164;var __ZTSN10emscripten11memory_viewIfEE=Module["__ZTSN10emscripten11memory_viewIfEE"]=29204;var __ZTSN10emscripten11memory_viewIdEE=Module["__ZTSN10emscripten11memory_viewIdEE"]=29244;var __ZTVSt11logic_error=Module["__ZTVSt11logic_error"]=32196;var __ZTVSt9exception=Module["__ZTVSt9exception"]=32032;var __ZTVSt13runtime_error=Module["__ZTVSt13runtime_error"]=32216;var __ZTISt9exception=Module["__ZTISt9exception"]=32052;var ___cxa_unexpected_handler=Module["___cxa_unexpected_handler"]=47880;var ___cxa_terminate_handler=Module["___cxa_terminate_handler"]=47876;var ___cxa_new_handler=Module["___cxa_new_handler"]=50124;var __ZTIN10__cxxabiv116__shim_type_infoE=Module["__ZTIN10__cxxabiv116__shim_type_infoE"]=29760;var __ZTIN10__cxxabiv117__class_type_infoE=Module["__ZTIN10__cxxabiv117__class_type_infoE"]=29808;var __ZTIN10__cxxabiv117__pbase_type_infoE=Module["__ZTIN10__cxxabiv117__pbase_type_infoE"]=29856;var __ZTIDn=Module["__ZTIDn"]=30236;var __ZTIN10__cxxabiv119__pointer_type_infoE=Module["__ZTIN10__cxxabiv119__pointer_type_infoE"]=29904;var __ZTIN10__cxxabiv120__function_type_infoE=Module["__ZTIN10__cxxabiv120__function_type_infoE"]=29952;var __ZTIN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTIN10__cxxabiv129__pointer_to_member_type_infoE"]=30004;var __ZTISt9type_info=Module["__ZTISt9type_info"]=32716;var __ZTSN10__cxxabiv116__shim_type_infoE=Module["__ZTSN10__cxxabiv116__shim_type_infoE"]=29772;var __ZTSN10__cxxabiv117__class_type_infoE=Module["__ZTSN10__cxxabiv117__class_type_infoE"]=29820;var __ZTSN10__cxxabiv117__pbase_type_infoE=Module["__ZTSN10__cxxabiv117__pbase_type_infoE"]=29868;var __ZTSN10__cxxabiv119__pointer_type_infoE=Module["__ZTSN10__cxxabiv119__pointer_type_infoE"]=29916;var __ZTSN10__cxxabiv120__function_type_infoE=Module["__ZTSN10__cxxabiv120__function_type_infoE"]=29964;var __ZTSN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTSN10__cxxabiv129__pointer_to_member_type_infoE"]=30016;var __ZTVN10__cxxabiv116__shim_type_infoE=Module["__ZTVN10__cxxabiv116__shim_type_infoE"]=30076;var __ZTVN10__cxxabiv123__fundamental_type_infoE=Module["__ZTVN10__cxxabiv123__fundamental_type_infoE"]=30104;var __ZTIN10__cxxabiv123__fundamental_type_infoE=Module["__ZTIN10__cxxabiv123__fundamental_type_infoE"]=30132;var __ZTSN10__cxxabiv123__fundamental_type_infoE=Module["__ZTSN10__cxxabiv123__fundamental_type_infoE"]=30144;var __ZTSv=Module["__ZTSv"]=30192;var __ZTIPv=Module["__ZTIPv"]=30196;var __ZTSPv=Module["__ZTSPv"]=30212;var __ZTIPKv=Module["__ZTIPKv"]=30216;var __ZTSPKv=Module["__ZTSPKv"]=30232;var __ZTSDn=Module["__ZTSDn"]=30244;var __ZTIPDn=Module["__ZTIPDn"]=30248;var __ZTSPDn=Module["__ZTSPDn"]=30264;var __ZTIPKDn=Module["__ZTIPKDn"]=30268;var __ZTSPKDn=Module["__ZTSPKDn"]=30284;var __ZTSb=Module["__ZTSb"]=30300;var __ZTIPb=Module["__ZTIPb"]=30304;var __ZTSPb=Module["__ZTSPb"]=30320;var __ZTIPKb=Module["__ZTIPKb"]=30324;var __ZTSPKb=Module["__ZTSPKb"]=30340;var __ZTIw=Module["__ZTIw"]=30344;var __ZTSw=Module["__ZTSw"]=30352;var __ZTIPw=Module["__ZTIPw"]=30356;var __ZTSPw=Module["__ZTSPw"]=30372;var __ZTIPKw=Module["__ZTIPKw"]=30376;var __ZTSPKw=Module["__ZTSPKw"]=30392;var __ZTSc=Module["__ZTSc"]=30404;var __ZTIPc=Module["__ZTIPc"]=30408;var __ZTSPc=Module["__ZTSPc"]=30424;var __ZTIPKc=Module["__ZTIPKc"]=30428;var __ZTSPKc=Module["__ZTSPKc"]=30444;var __ZTSh=Module["__ZTSh"]=30456;var __ZTIPh=Module["__ZTIPh"]=30460;var __ZTSPh=Module["__ZTSPh"]=30476;var __ZTIPKh=Module["__ZTIPKh"]=30480;var __ZTSPKh=Module["__ZTSPKh"]=30496;var __ZTSa=Module["__ZTSa"]=30508;var __ZTIPa=Module["__ZTIPa"]=30512;var __ZTSPa=Module["__ZTSPa"]=30528;var __ZTIPKa=Module["__ZTIPKa"]=30532;var __ZTSPKa=Module["__ZTSPKa"]=30548;var __ZTSs=Module["__ZTSs"]=30560;var __ZTIPs=Module["__ZTIPs"]=30564;var __ZTSPs=Module["__ZTSPs"]=30580;var __ZTIPKs=Module["__ZTIPKs"]=30584;var __ZTSPKs=Module["__ZTSPKs"]=30600;var __ZTSt=Module["__ZTSt"]=30612;var __ZTIPt=Module["__ZTIPt"]=30616;var __ZTSPt=Module["__ZTSPt"]=30632;var __ZTIPKt=Module["__ZTIPKt"]=30636;var __ZTSPKt=Module["__ZTSPKt"]=30652;var __ZTSi=Module["__ZTSi"]=30664;var __ZTIPi=Module["__ZTIPi"]=30668;var __ZTSPi=Module["__ZTSPi"]=30684;var __ZTIPKi=Module["__ZTIPKi"]=30688;var __ZTSPKi=Module["__ZTSPKi"]=30704;var __ZTSj=Module["__ZTSj"]=30716;var __ZTIPj=Module["__ZTIPj"]=30720;var __ZTSPj=Module["__ZTSPj"]=30736;var __ZTIPKj=Module["__ZTIPKj"]=30740;var __ZTSPKj=Module["__ZTSPKj"]=30756;var __ZTSl=Module["__ZTSl"]=30768;var __ZTIPl=Module["__ZTIPl"]=30772;var __ZTSPl=Module["__ZTSPl"]=30788;var __ZTIPKl=Module["__ZTIPKl"]=30792;var __ZTSPKl=Module["__ZTSPKl"]=30808;var __ZTSm=Module["__ZTSm"]=30820;var __ZTIPm=Module["__ZTIPm"]=30824;var __ZTSPm=Module["__ZTSPm"]=30840;var __ZTIPKm=Module["__ZTIPKm"]=30844;var __ZTSPKm=Module["__ZTSPKm"]=30860;var __ZTSx=Module["__ZTSx"]=30872;var __ZTIPx=Module["__ZTIPx"]=30876;var __ZTSPx=Module["__ZTSPx"]=30892;var __ZTIPKx=Module["__ZTIPKx"]=30896;var __ZTSPKx=Module["__ZTSPKx"]=30912;var __ZTSy=Module["__ZTSy"]=30924;var __ZTIPy=Module["__ZTIPy"]=30928;var __ZTSPy=Module["__ZTSPy"]=30944;var __ZTIPKy=Module["__ZTIPKy"]=30948;var __ZTSPKy=Module["__ZTSPKy"]=30964;var __ZTIn=Module["__ZTIn"]=30968;var __ZTSn=Module["__ZTSn"]=30976;var __ZTIPn=Module["__ZTIPn"]=30980;var __ZTSPn=Module["__ZTSPn"]=30996;var __ZTIPKn=Module["__ZTIPKn"]=31e3;var __ZTSPKn=Module["__ZTSPKn"]=31016;var __ZTIo=Module["__ZTIo"]=31020;var __ZTSo=Module["__ZTSo"]=31028;var __ZTIPo=Module["__ZTIPo"]=31032;var __ZTSPo=Module["__ZTSPo"]=31048;var __ZTIPKo=Module["__ZTIPKo"]=31052;var __ZTSPKo=Module["__ZTSPKo"]=31068;var __ZTIDh=Module["__ZTIDh"]=31072;var __ZTSDh=Module["__ZTSDh"]=31080;var __ZTIPDh=Module["__ZTIPDh"]=31084;var __ZTSPDh=Module["__ZTSPDh"]=31100;var __ZTIPKDh=Module["__ZTIPKDh"]=31104;var __ZTSPKDh=Module["__ZTSPKDh"]=31120;var __ZTSf=Module["__ZTSf"]=31136;var __ZTIPf=Module["__ZTIPf"]=31140;var __ZTSPf=Module["__ZTSPf"]=31156;var __ZTIPKf=Module["__ZTIPKf"]=31160;var __ZTSPKf=Module["__ZTSPKf"]=31176;var __ZTSd=Module["__ZTSd"]=31188;var __ZTIPd=Module["__ZTIPd"]=31192;var __ZTSPd=Module["__ZTSPd"]=31208;var __ZTIPKd=Module["__ZTIPKd"]=31212;var __ZTSPKd=Module["__ZTSPKd"]=31228;var __ZTIe=Module["__ZTIe"]=31232;var __ZTSe=Module["__ZTSe"]=31240;var __ZTIPe=Module["__ZTIPe"]=31244;var __ZTSPe=Module["__ZTSPe"]=31260;var __ZTIPKe=Module["__ZTIPKe"]=31264;var __ZTSPKe=Module["__ZTSPKe"]=31280;var __ZTIg=Module["__ZTIg"]=31284;var __ZTSg=Module["__ZTSg"]=31292;var __ZTIPg=Module["__ZTIPg"]=31296;var __ZTSPg=Module["__ZTSPg"]=31312;var __ZTIPKg=Module["__ZTIPKg"]=31316;var __ZTSPKg=Module["__ZTSPKg"]=31332;var __ZTIDu=Module["__ZTIDu"]=31336;var __ZTSDu=Module["__ZTSDu"]=31344;var __ZTIPDu=Module["__ZTIPDu"]=31348;var __ZTSPDu=Module["__ZTSPDu"]=31364;var __ZTIPKDu=Module["__ZTIPKDu"]=31368;var __ZTSPKDu=Module["__ZTSPKDu"]=31384;var __ZTIDs=Module["__ZTIDs"]=31392;var __ZTSDs=Module["__ZTSDs"]=31400;var __ZTIPDs=Module["__ZTIPDs"]=31404;var __ZTSPDs=Module["__ZTSPDs"]=31420;var __ZTIPKDs=Module["__ZTIPKDs"]=31424;var __ZTSPKDs=Module["__ZTSPKDs"]=31440;var __ZTIDi=Module["__ZTIDi"]=31448;var __ZTSDi=Module["__ZTSDi"]=31456;var __ZTIPDi=Module["__ZTIPDi"]=31460;var __ZTSPDi=Module["__ZTSPDi"]=31476;var __ZTIPKDi=Module["__ZTIPKDi"]=31480;var __ZTSPKDi=Module["__ZTSPKDi"]=31496;var __ZTVN10__cxxabiv117__array_type_infoE=Module["__ZTVN10__cxxabiv117__array_type_infoE"]=31504;var __ZTIN10__cxxabiv117__array_type_infoE=Module["__ZTIN10__cxxabiv117__array_type_infoE"]=31532;var __ZTSN10__cxxabiv117__array_type_infoE=Module["__ZTSN10__cxxabiv117__array_type_infoE"]=31544;var __ZTVN10__cxxabiv120__function_type_infoE=Module["__ZTVN10__cxxabiv120__function_type_infoE"]=31580;var __ZTVN10__cxxabiv116__enum_type_infoE=Module["__ZTVN10__cxxabiv116__enum_type_infoE"]=31608;var __ZTIN10__cxxabiv116__enum_type_infoE=Module["__ZTIN10__cxxabiv116__enum_type_infoE"]=31636;var __ZTSN10__cxxabiv116__enum_type_infoE=Module["__ZTSN10__cxxabiv116__enum_type_infoE"]=31648;var __ZTIN10__cxxabiv120__si_class_type_infoE=Module["__ZTIN10__cxxabiv120__si_class_type_infoE"]=31764;var __ZTSN10__cxxabiv120__si_class_type_infoE=Module["__ZTSN10__cxxabiv120__si_class_type_infoE"]=31776;var __ZTIN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTIN10__cxxabiv121__vmi_class_type_infoE"]=31856;var __ZTSN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTSN10__cxxabiv121__vmi_class_type_infoE"]=31868;var __ZTVN10__cxxabiv117__pbase_type_infoE=Module["__ZTVN10__cxxabiv117__pbase_type_infoE"]=31908;var __ZTVN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTVN10__cxxabiv129__pointer_to_member_type_infoE"]=31964;var __ZTVSt9bad_alloc=Module["__ZTVSt9bad_alloc"]=31992;var __ZTVSt20bad_array_new_length=Module["__ZTVSt20bad_array_new_length"]=32012;var __ZTISt9bad_alloc=Module["__ZTISt9bad_alloc"]=32128;var __ZTSSt9exception=Module["__ZTSSt9exception"]=32060;var __ZTVSt13bad_exception=Module["__ZTVSt13bad_exception"]=32076;var __ZTISt13bad_exception=Module["__ZTISt13bad_exception"]=32096;var __ZTSSt13bad_exception=Module["__ZTSSt13bad_exception"]=32108;var __ZTSSt9bad_alloc=Module["__ZTSSt9bad_alloc"]=32140;var __ZTSSt20bad_array_new_length=Module["__ZTSSt20bad_array_new_length"]=32168;var __ZTISt11logic_error=Module["__ZTISt11logic_error"]=32288;var __ZTISt13runtime_error=Module["__ZTISt13runtime_error"]=32524;var __ZTVSt12domain_error=Module["__ZTVSt12domain_error"]=32236;var __ZTISt12domain_error=Module["__ZTISt12domain_error"]=32256;var __ZTSSt12domain_error=Module["__ZTSSt12domain_error"]=32268;var __ZTSSt11logic_error=Module["__ZTSSt11logic_error"]=32300;var __ZTVSt16invalid_argument=Module["__ZTVSt16invalid_argument"]=32316;var __ZTISt16invalid_argument=Module["__ZTISt16invalid_argument"]=32336;var __ZTSSt16invalid_argument=Module["__ZTSSt16invalid_argument"]=32348;var __ZTSSt12length_error=Module["__ZTSSt12length_error"]=32404;var __ZTSSt12out_of_range=Module["__ZTSSt12out_of_range"]=32456;var __ZTVSt11range_error=Module["__ZTVSt11range_error"]=32476;var __ZTISt11range_error=Module["__ZTISt11range_error"]=32496;var __ZTSSt11range_error=Module["__ZTSSt11range_error"]=32508;var __ZTSSt13runtime_error=Module["__ZTSSt13runtime_error"]=32536;var __ZTVSt14overflow_error=Module["__ZTVSt14overflow_error"]=32556;var __ZTISt14overflow_error=Module["__ZTISt14overflow_error"]=32576;var __ZTSSt14overflow_error=Module["__ZTSSt14overflow_error"]=32588;var __ZTVSt15underflow_error=Module["__ZTVSt15underflow_error"]=32608;var __ZTISt15underflow_error=Module["__ZTISt15underflow_error"]=32628;var __ZTSSt15underflow_error=Module["__ZTSSt15underflow_error"]=32640;var __ZTVSt8bad_cast=Module["__ZTVSt8bad_cast"]=32660;var __ZTVSt10bad_typeid=Module["__ZTVSt10bad_typeid"]=32680;var __ZTISt8bad_cast=Module["__ZTISt8bad_cast"]=32740;var __ZTISt10bad_typeid=Module["__ZTISt10bad_typeid"]=32764;var __ZTVSt9type_info=Module["__ZTVSt9type_info"]=32700;var __ZTSSt9type_info=Module["__ZTSSt9type_info"]=32724;var __ZTSSt8bad_cast=Module["__ZTSSt8bad_cast"]=32752;var __ZTSSt10bad_typeid=Module["__ZTSSt10bad_typeid"]=32776;var wasmImports={f:___cxa_throw,p:__abort_js,k:__embind_register_bigint,m:__embind_register_bool,l:__embind_register_class,h:__embind_register_class_constructor,e:__embind_register_class_function,a:__embind_register_class_property,r:__embind_register_emval,j:__embind_register_float,c:__embind_register_function,d:__embind_register_integer,b:__embind_register_memory_view,s:__embind_register_std_string,g:__embind_register_std_wstring,n:__embind_register_void,o:__emval_take_value,t:_emscripten_date_now,q:_emscripten_resize_heap,i:_fd_write};var wasmExports;createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run(); +var Module=typeof Module!="undefined"?Module:{};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){}var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);var ret=fs.readFileSync(filename);return ret};readAsync=(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return new Promise((resolve,reject)=>{fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)reject(err);else resolve(binary?data.buffer:data)})})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}process.on("uncaughtException",ex=>{if(ex!=="unwind"&&!(ex instanceof ExitStatus)&&!(ex.context instanceof ExitStatus)){throw ex}});quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=url=>{if(isFileURI(url)){return new Promise((reject,resolve)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response)}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}return fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))})}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function findWasmBinary(){var f="index.wasm";if(!isDataURI(f)){return locateFile(f)}return f}var wasmBinaryFile;function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary){return readAsync(binaryFile).then(response=>new Uint8Array(response),()=>getBinarySync(binaryFile))}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{a:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["w"];updateMemoryViews();wasmTable=wasmExports["C"];addOnInit(wasmExports["x"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);return false}}if(!wasmBinaryFile)wasmBinaryFile=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult);return{}}function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var noExitRuntime=Module["noExitRuntime"]||true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}get_exception_ptr(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>{abort("")};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var BindingError;var throwBindingError=message=>{throw new BindingError(message)};var InternalError;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},argPackAdvance:GenericWireTypeSize,readValueFromPointer:function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var shallowCopyInternalPointer=o=>({count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType});var throwInstanceAlreadyDeleted=obj=>{function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")};var finalizationRegistry=false;var detachFinalizer=handle=>{};var runDestructor=$$=>{if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}};var releaseClassHandle=$$=>{$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}};var downcastPointer=(ptr,ptrClass,desiredClass)=>{if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)};var registeredPointers={};var getInheritedInstanceCount=()=>Object.keys(registeredInstances).length;var getLiveInheritedInstances=()=>{var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv};var deletionQueue=[];var flushPendingDeletes=()=>{while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}};var delayFunction;var setDelayFunction=fn=>{delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}};var init_embind=()=>{Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction};var registeredInstances={};var getBasestPointer=(class_,ptr)=>{if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr};var getInheritedInstance=(class_,ptr)=>{ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]};var makeClassHandle=(prototype,record)=>{if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record,writable:true}}))};function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=handle=>{if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};var init_ClassHandle=()=>{Object.assign(ClassHandle.prototype,{isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;other.$$=other.$$;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right},clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}},delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}},isDeleted(){return!this.$$.ptr},deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}})};function ClassHandle(){}var createNamedFunction=(name,body)=>Object.defineProperty(body,"name",{value:name});var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}var upcastPointer=(ptr,ptrClass,desiredClass)=>{while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr};function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle||!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(()=>clonedHandle["delete"]()));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var init_RegisteredPointer=()=>{Object.assign(RegisteredPointer.prototype,{getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr},destructor(ptr){this.rawDestructor?.(ptr)},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,fromWireType:RegisteredPointer_fromWireType})};function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistent public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{sig=sig.replace(/p/g,"i");var f=Module["dynCall_"+sig];return f(ptr,...args)};var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var dynCall=(sig,ptr,args=[])=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr)(...args);return rtn};var getDynCaller=(sig,ptr)=>(...args)=>dynCall(sig,ptr,args);var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var __embind_register_class=(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor)=>{name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);upcast&&=embind__requireFunction(upcastSignature,upcast);downcast&&=embind__requireFunction(downcastSignature,downcast);rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],base=>{base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(name,function(...args){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[args.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,args)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){registeredClass.baseClass.__derivedClasses??=[];registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function usesDestructorStack(argTypes){for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex!==-1){return signature.substr(0,argsIndex)}else{return signature}};var __embind_register_class_function=(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);methodName=getFunctionName(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})};var validateThis=(this_,classType,humanName)=>{if(!(this_ instanceof Object)){throwBindingError(`${humanName} with invalid "this": ${this_}`)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(`${humanName} incompatible with "this" of type ${this_.constructor.name}`)}if(!this_.$$.ptr){throwBindingError(`cannot call emscripten binding method ${humanName} on deleted object`)}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)};var __embind_register_class_property=(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],classType=>{classType=classType[0];var humanName=`${classType.name}.${fieldName}`;var desc={get(){throwUnboundTypeError(`Cannot access ${humanName} due to unbound types`,[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=()=>throwUnboundTypeError(`Cannot access ${humanName} due to unbound types`,[getterReturnType,setterArgumentType])}else{desc.set=v=>throwBindingError(humanName+" is a read-only property")}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],types=>{var getterReturnType=types[0];var desc={get(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})};var emval_freelist=[];var emval_handles=[];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){emval_handles[handle]=undefined;emval_freelist.push(handle)}};var count_emval_handles=()=>emval_handles.length/2-5-emval_freelist.length;var init_emval=()=>{emval_handles.push(0,1,undefined,1,null,1,true,1,false,1);Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};var EmValType={name:"emscripten::val",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var embindRepr=v=>{if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:value=>value,toWireType:(destructors,value)=>value,argPackAdvance:GenericWireTypeSize,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,fromWireType:fromWireType,toWireType:toWireType,argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:decodeMemoryView,argPackAdvance:GenericWireTypeSize,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var __embind_register_optional=(rawOptionalType,rawType)=>{__embind_register_emval(rawOptionalType)};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,readCharAt,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;readCharAt=pointer=>HEAPU16[pointer>>1]}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;readCharAt=pointer=>HEAPU32[pointer>>2]}registerType(rawType,{name:name,fromWireType:value=>{var length=HEAPU32[value>>2];var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||readCharAt(currentBytePtr)==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,argPackAdvance:0,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var __emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var _emscripten_date_now=()=>Date.now();var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var printCharBuffers=[null,[],[]];var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var wasmImports={f:___cxa_throw,q:__abort_js,p:__embind_register_bigint,u:__embind_register_bool,l:__embind_register_class,h:__embind_register_class_constructor,e:__embind_register_class_function,a:__embind_register_class_property,t:__embind_register_emval,k:__embind_register_float,c:__embind_register_function,d:__embind_register_integer,b:__embind_register_memory_view,o:__embind_register_optional,j:__embind_register_std_string,g:__embind_register_std_wstring,m:__embind_register_void,s:__emscripten_memcpy_js,n:__emval_take_value,v:_emscripten_date_now,r:_emscripten_resize_heap,i:_fd_write};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["x"])();var _param_get=Module["_param_get"]=(a0,a1)=>(_param_get=Module["_param_get"]=wasmExports["y"])(a0,a1);var _param_set_used=Module["_param_set_used"]=a0=>(_param_set_used=Module["_param_set_used"]=wasmExports["z"])(a0);var __Znwm=Module["__Znwm"]=a0=>(__Znwm=Module["__Znwm"]=wasmExports["A"])(a0);var __ZdlPvm=Module["__ZdlPvm"]=(a0,a1)=>(__ZdlPvm=Module["__ZdlPvm"]=wasmExports["B"])(a0,a1);var _malloc=a0=>(_malloc=wasmExports["D"])(a0);var __ZNSt12length_errorD1Ev=Module["__ZNSt12length_errorD1Ev"]=a0=>(__ZNSt12length_errorD1Ev=Module["__ZNSt12length_errorD1Ev"]=wasmExports["E"])(a0);var ___cxa_allocate_exception=Module["___cxa_allocate_exception"]=a0=>(___cxa_allocate_exception=Module["___cxa_allocate_exception"]=wasmExports["F"])(a0);var __ZNSt20bad_array_new_lengthD1Ev=Module["__ZNSt20bad_array_new_lengthD1Ev"]=a0=>(__ZNSt20bad_array_new_lengthD1Ev=Module["__ZNSt20bad_array_new_lengthD1Ev"]=wasmExports["G"])(a0);var __ZNSt20bad_array_new_lengthC1Ev=Module["__ZNSt20bad_array_new_lengthC1Ev"]=a0=>(__ZNSt20bad_array_new_lengthC1Ev=Module["__ZNSt20bad_array_new_lengthC1Ev"]=wasmExports["H"])(a0);var __ZNSt12out_of_rangeD1Ev=Module["__ZNSt12out_of_rangeD1Ev"]=a0=>(__ZNSt12out_of_rangeD1Ev=Module["__ZNSt12out_of_rangeD1Ev"]=wasmExports["I"])(a0);var ___cxa_pure_virtual=Module["___cxa_pure_virtual"]=()=>(___cxa_pure_virtual=Module["___cxa_pure_virtual"]=wasmExports["J"])();var ___getTypeName=a0=>(___getTypeName=wasmExports["K"])(a0);var __ZNSt9exceptionD2Ev=Module["__ZNSt9exceptionD2Ev"]=a0=>(__ZNSt9exceptionD2Ev=Module["__ZNSt9exceptionD2Ev"]=wasmExports["L"])(a0);var _free=a0=>(_free=wasmExports["M"])(a0);var _getTempRet0=Module["_getTempRet0"]=()=>(_getTempRet0=Module["_getTempRet0"]=wasmExports["N"])();var _setTempRet0=Module["_setTempRet0"]=a0=>(_setTempRet0=Module["_setTempRet0"]=wasmExports["O"])(a0);var __ZSt15get_new_handlerv=Module["__ZSt15get_new_handlerv"]=()=>(__ZSt15get_new_handlerv=Module["__ZSt15get_new_handlerv"]=wasmExports["P"])();var __Znam=Module["__Znam"]=a0=>(__Znam=Module["__Znam"]=wasmExports["Q"])(a0);var __ZdlPv=Module["__ZdlPv"]=a0=>(__ZdlPv=Module["__ZdlPv"]=wasmExports["R"])(a0);var __ZdaPv=Module["__ZdaPv"]=a0=>(__ZdaPv=Module["__ZdaPv"]=wasmExports["S"])(a0);var __ZdaPvm=Module["__ZdaPvm"]=(a0,a1)=>(__ZdaPvm=Module["__ZdaPvm"]=wasmExports["T"])(a0,a1);var __ZnwmSt11align_val_t=Module["__ZnwmSt11align_val_t"]=(a0,a1)=>(__ZnwmSt11align_val_t=Module["__ZnwmSt11align_val_t"]=wasmExports["U"])(a0,a1);var __ZnamSt11align_val_t=Module["__ZnamSt11align_val_t"]=(a0,a1)=>(__ZnamSt11align_val_t=Module["__ZnamSt11align_val_t"]=wasmExports["V"])(a0,a1);var __ZdlPvSt11align_val_t=Module["__ZdlPvSt11align_val_t"]=(a0,a1)=>(__ZdlPvSt11align_val_t=Module["__ZdlPvSt11align_val_t"]=wasmExports["W"])(a0,a1);var __ZdlPvmSt11align_val_t=Module["__ZdlPvmSt11align_val_t"]=(a0,a1,a2)=>(__ZdlPvmSt11align_val_t=Module["__ZdlPvmSt11align_val_t"]=wasmExports["X"])(a0,a1,a2);var __ZdaPvSt11align_val_t=Module["__ZdaPvSt11align_val_t"]=(a0,a1)=>(__ZdaPvSt11align_val_t=Module["__ZdaPvSt11align_val_t"]=wasmExports["Y"])(a0,a1);var __ZdaPvmSt11align_val_t=Module["__ZdaPvmSt11align_val_t"]=(a0,a1,a2)=>(__ZdaPvmSt11align_val_t=Module["__ZdaPvmSt11align_val_t"]=wasmExports["Z"])(a0,a1,a2);var __ZSt14set_unexpectedPFvvE=Module["__ZSt14set_unexpectedPFvvE"]=a0=>(__ZSt14set_unexpectedPFvvE=Module["__ZSt14set_unexpectedPFvvE"]=wasmExports["_"])(a0);var __ZSt13set_terminatePFvvE=Module["__ZSt13set_terminatePFvvE"]=a0=>(__ZSt13set_terminatePFvvE=Module["__ZSt13set_terminatePFvvE"]=wasmExports["$"])(a0);var __ZSt15set_new_handlerPFvvE=Module["__ZSt15set_new_handlerPFvvE"]=a0=>(__ZSt15set_new_handlerPFvvE=Module["__ZSt15set_new_handlerPFvvE"]=wasmExports["aa"])(a0);var __ZSt14get_unexpectedv=Module["__ZSt14get_unexpectedv"]=()=>(__ZSt14get_unexpectedv=Module["__ZSt14get_unexpectedv"]=wasmExports["ba"])();var __ZSt10unexpectedv=Module["__ZSt10unexpectedv"]=()=>(__ZSt10unexpectedv=Module["__ZSt10unexpectedv"]=wasmExports["ca"])();var __ZSt13get_terminatev=Module["__ZSt13get_terminatev"]=()=>(__ZSt13get_terminatev=Module["__ZSt13get_terminatev"]=wasmExports["da"])();var __ZSt9terminatev=Module["__ZSt9terminatev"]=()=>(__ZSt9terminatev=Module["__ZSt9terminatev"]=wasmExports["ea"])();var ___cxa_current_primary_exception=Module["___cxa_current_primary_exception"]=()=>(___cxa_current_primary_exception=Module["___cxa_current_primary_exception"]=wasmExports["fa"])();var ___cxa_rethrow_primary_exception=Module["___cxa_rethrow_primary_exception"]=a0=>(___cxa_rethrow_primary_exception=Module["___cxa_rethrow_primary_exception"]=wasmExports["ga"])(a0);var ___cxa_uncaught_exception=Module["___cxa_uncaught_exception"]=()=>(___cxa_uncaught_exception=Module["___cxa_uncaught_exception"]=wasmExports["ha"])();var ___cxa_uncaught_exceptions=Module["___cxa_uncaught_exceptions"]=()=>(___cxa_uncaught_exceptions=Module["___cxa_uncaught_exceptions"]=wasmExports["ia"])();var ___cxa_free_exception=Module["___cxa_free_exception"]=a0=>(___cxa_free_exception=Module["___cxa_free_exception"]=wasmExports["ja"])(a0);var ___cxa_init_primary_exception=Module["___cxa_init_primary_exception"]=(a0,a1,a2)=>(___cxa_init_primary_exception=Module["___cxa_init_primary_exception"]=wasmExports["ka"])(a0,a1,a2);var ___cxa_deleted_virtual=Module["___cxa_deleted_virtual"]=()=>(___cxa_deleted_virtual=Module["___cxa_deleted_virtual"]=wasmExports["la"])();var ___dynamic_cast=Module["___dynamic_cast"]=(a0,a1,a2,a3)=>(___dynamic_cast=Module["___dynamic_cast"]=wasmExports["ma"])(a0,a1,a2,a3);var __ZNSt9type_infoD2Ev=Module["__ZNSt9type_infoD2Ev"]=a0=>(__ZNSt9type_infoD2Ev=Module["__ZNSt9type_infoD2Ev"]=wasmExports["na"])(a0);var ___cxa_is_pointer_type=a0=>(___cxa_is_pointer_type=wasmExports["oa"])(a0);var __ZNSt9exceptionD0Ev=Module["__ZNSt9exceptionD0Ev"]=a0=>(__ZNSt9exceptionD0Ev=Module["__ZNSt9exceptionD0Ev"]=wasmExports["pa"])(a0);var __ZNSt9exceptionD1Ev=Module["__ZNSt9exceptionD1Ev"]=a0=>(__ZNSt9exceptionD1Ev=Module["__ZNSt9exceptionD1Ev"]=wasmExports["qa"])(a0);var __ZNKSt9exception4whatEv=Module["__ZNKSt9exception4whatEv"]=a0=>(__ZNKSt9exception4whatEv=Module["__ZNKSt9exception4whatEv"]=wasmExports["ra"])(a0);var __ZNSt13bad_exceptionD0Ev=Module["__ZNSt13bad_exceptionD0Ev"]=a0=>(__ZNSt13bad_exceptionD0Ev=Module["__ZNSt13bad_exceptionD0Ev"]=wasmExports["sa"])(a0);var __ZNSt13bad_exceptionD1Ev=Module["__ZNSt13bad_exceptionD1Ev"]=a0=>(__ZNSt13bad_exceptionD1Ev=Module["__ZNSt13bad_exceptionD1Ev"]=wasmExports["ta"])(a0);var __ZNKSt13bad_exception4whatEv=Module["__ZNKSt13bad_exception4whatEv"]=a0=>(__ZNKSt13bad_exception4whatEv=Module["__ZNKSt13bad_exception4whatEv"]=wasmExports["ua"])(a0);var __ZNSt9bad_allocC2Ev=Module["__ZNSt9bad_allocC2Ev"]=a0=>(__ZNSt9bad_allocC2Ev=Module["__ZNSt9bad_allocC2Ev"]=wasmExports["va"])(a0);var __ZNSt9bad_allocD0Ev=Module["__ZNSt9bad_allocD0Ev"]=a0=>(__ZNSt9bad_allocD0Ev=Module["__ZNSt9bad_allocD0Ev"]=wasmExports["wa"])(a0);var __ZNSt9bad_allocD1Ev=Module["__ZNSt9bad_allocD1Ev"]=a0=>(__ZNSt9bad_allocD1Ev=Module["__ZNSt9bad_allocD1Ev"]=wasmExports["xa"])(a0);var __ZNKSt9bad_alloc4whatEv=Module["__ZNKSt9bad_alloc4whatEv"]=a0=>(__ZNKSt9bad_alloc4whatEv=Module["__ZNKSt9bad_alloc4whatEv"]=wasmExports["ya"])(a0);var __ZNSt20bad_array_new_lengthC2Ev=Module["__ZNSt20bad_array_new_lengthC2Ev"]=a0=>(__ZNSt20bad_array_new_lengthC2Ev=Module["__ZNSt20bad_array_new_lengthC2Ev"]=wasmExports["za"])(a0);var __ZNSt20bad_array_new_lengthD0Ev=Module["__ZNSt20bad_array_new_lengthD0Ev"]=a0=>(__ZNSt20bad_array_new_lengthD0Ev=Module["__ZNSt20bad_array_new_lengthD0Ev"]=wasmExports["Aa"])(a0);var __ZNKSt20bad_array_new_length4whatEv=Module["__ZNKSt20bad_array_new_length4whatEv"]=a0=>(__ZNKSt20bad_array_new_length4whatEv=Module["__ZNKSt20bad_array_new_length4whatEv"]=wasmExports["Ba"])(a0);var __ZNSt13bad_exceptionD2Ev=Module["__ZNSt13bad_exceptionD2Ev"]=a0=>(__ZNSt13bad_exceptionD2Ev=Module["__ZNSt13bad_exceptionD2Ev"]=wasmExports["Ca"])(a0);var __ZNSt9bad_allocC1Ev=Module["__ZNSt9bad_allocC1Ev"]=a0=>(__ZNSt9bad_allocC1Ev=Module["__ZNSt9bad_allocC1Ev"]=wasmExports["Da"])(a0);var __ZNSt9bad_allocD2Ev=Module["__ZNSt9bad_allocD2Ev"]=a0=>(__ZNSt9bad_allocD2Ev=Module["__ZNSt9bad_allocD2Ev"]=wasmExports["Ea"])(a0);var __ZNSt20bad_array_new_lengthD2Ev=Module["__ZNSt20bad_array_new_lengthD2Ev"]=a0=>(__ZNSt20bad_array_new_lengthD2Ev=Module["__ZNSt20bad_array_new_lengthD2Ev"]=wasmExports["Fa"])(a0);var __ZNSt11logic_errorD2Ev=Module["__ZNSt11logic_errorD2Ev"]=a0=>(__ZNSt11logic_errorD2Ev=Module["__ZNSt11logic_errorD2Ev"]=wasmExports["Ga"])(a0);var __ZNSt11logic_errorD0Ev=Module["__ZNSt11logic_errorD0Ev"]=a0=>(__ZNSt11logic_errorD0Ev=Module["__ZNSt11logic_errorD0Ev"]=wasmExports["Ha"])(a0);var __ZNSt11logic_errorD1Ev=Module["__ZNSt11logic_errorD1Ev"]=a0=>(__ZNSt11logic_errorD1Ev=Module["__ZNSt11logic_errorD1Ev"]=wasmExports["Ia"])(a0);var __ZNKSt11logic_error4whatEv=Module["__ZNKSt11logic_error4whatEv"]=a0=>(__ZNKSt11logic_error4whatEv=Module["__ZNKSt11logic_error4whatEv"]=wasmExports["Ja"])(a0);var __ZNSt13runtime_errorD2Ev=Module["__ZNSt13runtime_errorD2Ev"]=a0=>(__ZNSt13runtime_errorD2Ev=Module["__ZNSt13runtime_errorD2Ev"]=wasmExports["Ka"])(a0);var __ZNSt13runtime_errorD0Ev=Module["__ZNSt13runtime_errorD0Ev"]=a0=>(__ZNSt13runtime_errorD0Ev=Module["__ZNSt13runtime_errorD0Ev"]=wasmExports["La"])(a0);var __ZNSt13runtime_errorD1Ev=Module["__ZNSt13runtime_errorD1Ev"]=a0=>(__ZNSt13runtime_errorD1Ev=Module["__ZNSt13runtime_errorD1Ev"]=wasmExports["Ma"])(a0);var __ZNKSt13runtime_error4whatEv=Module["__ZNKSt13runtime_error4whatEv"]=a0=>(__ZNKSt13runtime_error4whatEv=Module["__ZNKSt13runtime_error4whatEv"]=wasmExports["Na"])(a0);var __ZNSt12domain_errorD0Ev=Module["__ZNSt12domain_errorD0Ev"]=a0=>(__ZNSt12domain_errorD0Ev=Module["__ZNSt12domain_errorD0Ev"]=wasmExports["Oa"])(a0);var __ZNSt12domain_errorD1Ev=Module["__ZNSt12domain_errorD1Ev"]=a0=>(__ZNSt12domain_errorD1Ev=Module["__ZNSt12domain_errorD1Ev"]=wasmExports["Pa"])(a0);var __ZNSt16invalid_argumentD0Ev=Module["__ZNSt16invalid_argumentD0Ev"]=a0=>(__ZNSt16invalid_argumentD0Ev=Module["__ZNSt16invalid_argumentD0Ev"]=wasmExports["Qa"])(a0);var __ZNSt16invalid_argumentD1Ev=Module["__ZNSt16invalid_argumentD1Ev"]=a0=>(__ZNSt16invalid_argumentD1Ev=Module["__ZNSt16invalid_argumentD1Ev"]=wasmExports["Ra"])(a0);var __ZNSt12length_errorD0Ev=Module["__ZNSt12length_errorD0Ev"]=a0=>(__ZNSt12length_errorD0Ev=Module["__ZNSt12length_errorD0Ev"]=wasmExports["Sa"])(a0);var __ZNSt12out_of_rangeD0Ev=Module["__ZNSt12out_of_rangeD0Ev"]=a0=>(__ZNSt12out_of_rangeD0Ev=Module["__ZNSt12out_of_rangeD0Ev"]=wasmExports["Ta"])(a0);var __ZNSt11range_errorD0Ev=Module["__ZNSt11range_errorD0Ev"]=a0=>(__ZNSt11range_errorD0Ev=Module["__ZNSt11range_errorD0Ev"]=wasmExports["Ua"])(a0);var __ZNSt11range_errorD1Ev=Module["__ZNSt11range_errorD1Ev"]=a0=>(__ZNSt11range_errorD1Ev=Module["__ZNSt11range_errorD1Ev"]=wasmExports["Va"])(a0);var __ZNSt14overflow_errorD0Ev=Module["__ZNSt14overflow_errorD0Ev"]=a0=>(__ZNSt14overflow_errorD0Ev=Module["__ZNSt14overflow_errorD0Ev"]=wasmExports["Wa"])(a0);var __ZNSt14overflow_errorD1Ev=Module["__ZNSt14overflow_errorD1Ev"]=a0=>(__ZNSt14overflow_errorD1Ev=Module["__ZNSt14overflow_errorD1Ev"]=wasmExports["Xa"])(a0);var __ZNSt15underflow_errorD0Ev=Module["__ZNSt15underflow_errorD0Ev"]=a0=>(__ZNSt15underflow_errorD0Ev=Module["__ZNSt15underflow_errorD0Ev"]=wasmExports["Ya"])(a0);var __ZNSt15underflow_errorD1Ev=Module["__ZNSt15underflow_errorD1Ev"]=a0=>(__ZNSt15underflow_errorD1Ev=Module["__ZNSt15underflow_errorD1Ev"]=wasmExports["Za"])(a0);var __ZNSt12domain_errorD2Ev=Module["__ZNSt12domain_errorD2Ev"]=a0=>(__ZNSt12domain_errorD2Ev=Module["__ZNSt12domain_errorD2Ev"]=wasmExports["_a"])(a0);var __ZNSt16invalid_argumentD2Ev=Module["__ZNSt16invalid_argumentD2Ev"]=a0=>(__ZNSt16invalid_argumentD2Ev=Module["__ZNSt16invalid_argumentD2Ev"]=wasmExports["$a"])(a0);var __ZNSt12length_errorD2Ev=Module["__ZNSt12length_errorD2Ev"]=a0=>(__ZNSt12length_errorD2Ev=Module["__ZNSt12length_errorD2Ev"]=wasmExports["ab"])(a0);var __ZNSt12out_of_rangeD2Ev=Module["__ZNSt12out_of_rangeD2Ev"]=a0=>(__ZNSt12out_of_rangeD2Ev=Module["__ZNSt12out_of_rangeD2Ev"]=wasmExports["bb"])(a0);var __ZNSt11range_errorD2Ev=Module["__ZNSt11range_errorD2Ev"]=a0=>(__ZNSt11range_errorD2Ev=Module["__ZNSt11range_errorD2Ev"]=wasmExports["cb"])(a0);var __ZNSt14overflow_errorD2Ev=Module["__ZNSt14overflow_errorD2Ev"]=a0=>(__ZNSt14overflow_errorD2Ev=Module["__ZNSt14overflow_errorD2Ev"]=wasmExports["db"])(a0);var __ZNSt15underflow_errorD2Ev=Module["__ZNSt15underflow_errorD2Ev"]=a0=>(__ZNSt15underflow_errorD2Ev=Module["__ZNSt15underflow_errorD2Ev"]=wasmExports["eb"])(a0);var __ZNSt9type_infoD0Ev=Module["__ZNSt9type_infoD0Ev"]=a0=>(__ZNSt9type_infoD0Ev=Module["__ZNSt9type_infoD0Ev"]=wasmExports["fb"])(a0);var __ZNSt9type_infoD1Ev=Module["__ZNSt9type_infoD1Ev"]=a0=>(__ZNSt9type_infoD1Ev=Module["__ZNSt9type_infoD1Ev"]=wasmExports["gb"])(a0);var __ZNSt8bad_castC2Ev=Module["__ZNSt8bad_castC2Ev"]=a0=>(__ZNSt8bad_castC2Ev=Module["__ZNSt8bad_castC2Ev"]=wasmExports["hb"])(a0);var __ZNSt8bad_castD2Ev=Module["__ZNSt8bad_castD2Ev"]=a0=>(__ZNSt8bad_castD2Ev=Module["__ZNSt8bad_castD2Ev"]=wasmExports["ib"])(a0);var __ZNSt8bad_castD0Ev=Module["__ZNSt8bad_castD0Ev"]=a0=>(__ZNSt8bad_castD0Ev=Module["__ZNSt8bad_castD0Ev"]=wasmExports["jb"])(a0);var __ZNSt8bad_castD1Ev=Module["__ZNSt8bad_castD1Ev"]=a0=>(__ZNSt8bad_castD1Ev=Module["__ZNSt8bad_castD1Ev"]=wasmExports["kb"])(a0);var __ZNKSt8bad_cast4whatEv=Module["__ZNKSt8bad_cast4whatEv"]=a0=>(__ZNKSt8bad_cast4whatEv=Module["__ZNKSt8bad_cast4whatEv"]=wasmExports["lb"])(a0);var __ZNSt10bad_typeidC2Ev=Module["__ZNSt10bad_typeidC2Ev"]=a0=>(__ZNSt10bad_typeidC2Ev=Module["__ZNSt10bad_typeidC2Ev"]=wasmExports["mb"])(a0);var __ZNSt10bad_typeidD2Ev=Module["__ZNSt10bad_typeidD2Ev"]=a0=>(__ZNSt10bad_typeidD2Ev=Module["__ZNSt10bad_typeidD2Ev"]=wasmExports["nb"])(a0);var __ZNSt10bad_typeidD0Ev=Module["__ZNSt10bad_typeidD0Ev"]=a0=>(__ZNSt10bad_typeidD0Ev=Module["__ZNSt10bad_typeidD0Ev"]=wasmExports["ob"])(a0);var __ZNSt10bad_typeidD1Ev=Module["__ZNSt10bad_typeidD1Ev"]=a0=>(__ZNSt10bad_typeidD1Ev=Module["__ZNSt10bad_typeidD1Ev"]=wasmExports["pb"])(a0);var __ZNKSt10bad_typeid4whatEv=Module["__ZNKSt10bad_typeid4whatEv"]=a0=>(__ZNKSt10bad_typeid4whatEv=Module["__ZNKSt10bad_typeid4whatEv"]=wasmExports["qb"])(a0);var __ZNSt8bad_castC1Ev=Module["__ZNSt8bad_castC1Ev"]=a0=>(__ZNSt8bad_castC1Ev=Module["__ZNSt8bad_castC1Ev"]=wasmExports["rb"])(a0);var __ZNSt10bad_typeidC1Ev=Module["__ZNSt10bad_typeidC1Ev"]=a0=>(__ZNSt10bad_typeidC1Ev=Module["__ZNSt10bad_typeidC1Ev"]=wasmExports["sb"])(a0);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["tb"])(a0,a1,a2,a3,a4);var __ZTIPK16failsafe_flags_s=Module["__ZTIPK16failsafe_flags_s"]=48448;var __ZTIP16failsafe_flags_s=Module["__ZTIP16failsafe_flags_s"]=48432;var __ZTI16failsafe_flags_s=Module["__ZTI16failsafe_flags_s"]=48424;var __ZTIb=Module["__ZTIb"]=31256;var __ZTIh=Module["__ZTIh"]=31412;var __ZTINSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE=Module["__ZTINSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"]=48524;var __ZTINSt3__28optionalINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEE=Module["__ZTINSt3__28optionalINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEE"]=48672;var __ZTIPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTIPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=48728;var __ZTIPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTIPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=48712;var __ZTINSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTINSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=48536;var __ZTISt12length_error=Module["__ZTISt12length_error"]=33372;var __ZTVSt12length_error=Module["__ZTVSt12length_error"]=33332;var __ZTISt20bad_array_new_length=Module["__ZTISt20bad_array_new_length"]=33144;var __ZTISt12out_of_range=Module["__ZTISt12out_of_range"]=33424;var __ZTVSt12out_of_range=Module["__ZTVSt12out_of_range"]=33384;var __ZTVN10__cxxabiv117__class_type_infoE=Module["__ZTVN10__cxxabiv117__class_type_infoE"]=32644;var __ZTVN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTVN10__cxxabiv121__vmi_class_type_infoE"]=32776;var __ZTVN10__cxxabiv120__si_class_type_infoE=Module["__ZTVN10__cxxabiv120__si_class_type_infoE"]=32684;var __ZTS16failsafe_flags_s=Module["__ZTS16failsafe_flags_s"]=28163;var __ZTSP16failsafe_flags_s=Module["__ZTSP16failsafe_flags_s"]=28182;var __ZTVN10__cxxabiv119__pointer_type_infoE=Module["__ZTVN10__cxxabiv119__pointer_type_infoE"]=32896;var __ZTSPK16failsafe_flags_s=Module["__ZTSPK16failsafe_flags_s"]=28202;var __ZTIi=Module["__ZTIi"]=31620;var __ZTSNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE=Module["__ZTSNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"]=28251;var __ZTSNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=28318;var __ZTIv=Module["__ZTIv"]=31148;var __ZTIf=Module["__ZTIf"]=32092;var __ZTSNSt3__28optionalINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEE=Module["__ZTSNSt3__28optionalINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEE"]=28416;var __ZTSNSt3__227__optional_move_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__227__optional_move_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28494;var __ZTSNSt3__227__optional_copy_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__227__optional_copy_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28596;var __ZTSNSt3__220__optional_move_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__220__optional_move_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28698;var __ZTSNSt3__220__optional_copy_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__220__optional_copy_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28793;var __ZTSNSt3__223__optional_storage_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__223__optional_storage_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28888;var __ZTSNSt3__224__optional_destruct_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTSNSt3__224__optional_destruct_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=28986;var __ZTINSt3__224__optional_destruct_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__224__optional_destruct_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48588;var __ZTINSt3__223__optional_storage_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__223__optional_storage_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48596;var __ZTINSt3__220__optional_copy_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__220__optional_copy_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48608;var __ZTINSt3__220__optional_move_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__220__optional_move_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48620;var __ZTINSt3__227__optional_copy_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__227__optional_copy_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48632;var __ZTINSt3__227__optional_move_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE=Module["__ZTINSt3__227__optional_move_assign_baseINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEELb0EEE"]=48644;var __ZTSNSt3__218__sfinae_ctor_baseILb1ELb1EEE=Module["__ZTSNSt3__218__sfinae_ctor_baseILb1ELb1EEE"]=29085;var __ZTINSt3__218__sfinae_ctor_baseILb1ELb1EEE=Module["__ZTINSt3__218__sfinae_ctor_baseILb1ELb1EEE"]=48656;var __ZTSNSt3__220__sfinae_assign_baseILb1ELb1EEE=Module["__ZTSNSt3__220__sfinae_assign_baseILb1ELb1EEE"]=29124;var __ZTINSt3__220__sfinae_assign_baseILb1ELb1EEE=Module["__ZTINSt3__220__sfinae_assign_baseILb1ELb1EEE"]=48664;var __ZTSPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSPNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=29165;var __ZTSPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE=Module["__ZTSPKNSt3__26vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS4_IS6_EEEE"]=29252;var __ZTIm=Module["__ZTIm"]=31776;var __ZTIc=Module["__ZTIc"]=31360;var __ZTIa=Module["__ZTIa"]=31464;var __ZTIs=Module["__ZTIs"]=31516;var __ZTIt=Module["__ZTIt"]=31568;var __ZTIj=Module["__ZTIj"]=31672;var __ZTIl=Module["__ZTIl"]=31724;var __ZTIx=Module["__ZTIx"]=31828;var __ZTIy=Module["__ZTIy"]=31880;var __ZTId=Module["__ZTId"]=32144;var __ZTINSt3__212basic_stringIhNS_11char_traitsIhEENS_9allocatorIhEEEE=Module["__ZTINSt3__212basic_stringIhNS_11char_traitsIhEENS_9allocatorIhEEEE"]=29456;var __ZTINSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE=Module["__ZTINSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE"]=29528;var __ZTINSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE=Module["__ZTINSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE"]=29604;var __ZTINSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE=Module["__ZTINSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE"]=29680;var __ZTSNSt3__212basic_stringIhNS_11char_traitsIhEENS_9allocatorIhEEEE=Module["__ZTSNSt3__212basic_stringIhNS_11char_traitsIhEENS_9allocatorIhEEEE"]=29392;var __ZTSNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE=Module["__ZTSNSt3__212basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE"]=29464;var __ZTSNSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE=Module["__ZTSNSt3__212basic_stringIDsNS_11char_traitsIDsEENS_9allocatorIDsEEEE"]=29536;var __ZTSNSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE=Module["__ZTSNSt3__212basic_stringIDiNS_11char_traitsIDiEENS_9allocatorIDiEEEE"]=29612;var __ZTVSt11logic_error=Module["__ZTVSt11logic_error"]=33156;var __ZTVSt9exception=Module["__ZTVSt9exception"]=32992;var __ZTVSt13runtime_error=Module["__ZTVSt13runtime_error"]=33176;var __ZTISt9exception=Module["__ZTISt9exception"]=33028;var ___cxa_unexpected_handler=Module["___cxa_unexpected_handler"]=49032;var ___cxa_terminate_handler=Module["___cxa_terminate_handler"]=49028;var ___cxa_new_handler=Module["___cxa_new_handler"]=51276;var __ZTIN10__cxxabiv116__shim_type_infoE=Module["__ZTIN10__cxxabiv116__shim_type_infoE"]=30756;var __ZTIN10__cxxabiv117__class_type_infoE=Module["__ZTIN10__cxxabiv117__class_type_infoE"]=30804;var __ZTIN10__cxxabiv117__pbase_type_infoE=Module["__ZTIN10__cxxabiv117__pbase_type_infoE"]=30852;var __ZTIDn=Module["__ZTIDn"]=31200;var __ZTIN10__cxxabiv119__pointer_type_infoE=Module["__ZTIN10__cxxabiv119__pointer_type_infoE"]=30900;var __ZTIN10__cxxabiv120__function_type_infoE=Module["__ZTIN10__cxxabiv120__function_type_infoE"]=30952;var __ZTIN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTIN10__cxxabiv129__pointer_to_member_type_infoE"]=31012;var __ZTSN10__cxxabiv116__shim_type_infoE=Module["__ZTSN10__cxxabiv116__shim_type_infoE"]=30720;var __ZTISt9type_info=Module["__ZTISt9type_info"]=33692;var __ZTSN10__cxxabiv117__class_type_infoE=Module["__ZTSN10__cxxabiv117__class_type_infoE"]=30768;var __ZTSN10__cxxabiv117__pbase_type_infoE=Module["__ZTSN10__cxxabiv117__pbase_type_infoE"]=30816;var __ZTSN10__cxxabiv119__pointer_type_infoE=Module["__ZTSN10__cxxabiv119__pointer_type_infoE"]=30864;var __ZTSN10__cxxabiv120__function_type_infoE=Module["__ZTSN10__cxxabiv120__function_type_infoE"]=30912;var __ZTSN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTSN10__cxxabiv129__pointer_to_member_type_infoE"]=30964;var __ZTVN10__cxxabiv116__shim_type_infoE=Module["__ZTVN10__cxxabiv116__shim_type_infoE"]=31036;var __ZTVN10__cxxabiv123__fundamental_type_infoE=Module["__ZTVN10__cxxabiv123__fundamental_type_infoE"]=31064;var __ZTIN10__cxxabiv123__fundamental_type_infoE=Module["__ZTIN10__cxxabiv123__fundamental_type_infoE"]=31132;var __ZTSN10__cxxabiv123__fundamental_type_infoE=Module["__ZTSN10__cxxabiv123__fundamental_type_infoE"]=31092;var __ZTSv=Module["__ZTSv"]=31144;var __ZTSPv=Module["__ZTSPv"]=31156;var __ZTIPv=Module["__ZTIPv"]=31160;var __ZTSPKv=Module["__ZTSPKv"]=31176;var __ZTIPKv=Module["__ZTIPKv"]=31180;var __ZTSDn=Module["__ZTSDn"]=31196;var __ZTSPDn=Module["__ZTSPDn"]=31208;var __ZTIPDn=Module["__ZTIPDn"]=31212;var __ZTSPKDn=Module["__ZTSPKDn"]=31228;var __ZTIPKDn=Module["__ZTIPKDn"]=31236;var __ZTSb=Module["__ZTSb"]=31252;var __ZTSPb=Module["__ZTSPb"]=31264;var __ZTIPb=Module["__ZTIPb"]=31268;var __ZTSPKb=Module["__ZTSPKb"]=31284;var __ZTIPKb=Module["__ZTIPKb"]=31288;var __ZTSw=Module["__ZTSw"]=31304;var __ZTIw=Module["__ZTIw"]=31308;var __ZTSPw=Module["__ZTSPw"]=31316;var __ZTIPw=Module["__ZTIPw"]=31320;var __ZTSPKw=Module["__ZTSPKw"]=31336;var __ZTIPKw=Module["__ZTIPKw"]=31340;var __ZTSc=Module["__ZTSc"]=31356;var __ZTSPc=Module["__ZTSPc"]=31368;var __ZTIPc=Module["__ZTIPc"]=31372;var __ZTSPKc=Module["__ZTSPKc"]=31388;var __ZTIPKc=Module["__ZTIPKc"]=31392;var __ZTSh=Module["__ZTSh"]=31408;var __ZTSPh=Module["__ZTSPh"]=31420;var __ZTIPh=Module["__ZTIPh"]=31424;var __ZTSPKh=Module["__ZTSPKh"]=31440;var __ZTIPKh=Module["__ZTIPKh"]=31444;var __ZTSa=Module["__ZTSa"]=31460;var __ZTSPa=Module["__ZTSPa"]=31472;var __ZTIPa=Module["__ZTIPa"]=31476;var __ZTSPKa=Module["__ZTSPKa"]=31492;var __ZTIPKa=Module["__ZTIPKa"]=31496;var __ZTSs=Module["__ZTSs"]=31512;var __ZTSPs=Module["__ZTSPs"]=31524;var __ZTIPs=Module["__ZTIPs"]=31528;var __ZTSPKs=Module["__ZTSPKs"]=31544;var __ZTIPKs=Module["__ZTIPKs"]=31548;var __ZTSt=Module["__ZTSt"]=31564;var __ZTSPt=Module["__ZTSPt"]=31576;var __ZTIPt=Module["__ZTIPt"]=31580;var __ZTSPKt=Module["__ZTSPKt"]=31596;var __ZTIPKt=Module["__ZTIPKt"]=31600;var __ZTSi=Module["__ZTSi"]=31616;var __ZTSPi=Module["__ZTSPi"]=31628;var __ZTIPi=Module["__ZTIPi"]=31632;var __ZTSPKi=Module["__ZTSPKi"]=31648;var __ZTIPKi=Module["__ZTIPKi"]=31652;var __ZTSj=Module["__ZTSj"]=31668;var __ZTSPj=Module["__ZTSPj"]=31680;var __ZTIPj=Module["__ZTIPj"]=31684;var __ZTSPKj=Module["__ZTSPKj"]=31700;var __ZTIPKj=Module["__ZTIPKj"]=31704;var __ZTSl=Module["__ZTSl"]=31720;var __ZTSPl=Module["__ZTSPl"]=31732;var __ZTIPl=Module["__ZTIPl"]=31736;var __ZTSPKl=Module["__ZTSPKl"]=31752;var __ZTIPKl=Module["__ZTIPKl"]=31756;var __ZTSm=Module["__ZTSm"]=31772;var __ZTSPm=Module["__ZTSPm"]=31784;var __ZTIPm=Module["__ZTIPm"]=31788;var __ZTSPKm=Module["__ZTSPKm"]=31804;var __ZTIPKm=Module["__ZTIPKm"]=31808;var __ZTSx=Module["__ZTSx"]=31824;var __ZTSPx=Module["__ZTSPx"]=31836;var __ZTIPx=Module["__ZTIPx"]=31840;var __ZTSPKx=Module["__ZTSPKx"]=31856;var __ZTIPKx=Module["__ZTIPKx"]=31860;var __ZTSy=Module["__ZTSy"]=31876;var __ZTSPy=Module["__ZTSPy"]=31888;var __ZTIPy=Module["__ZTIPy"]=31892;var __ZTSPKy=Module["__ZTSPKy"]=31908;var __ZTIPKy=Module["__ZTIPKy"]=31912;var __ZTSn=Module["__ZTSn"]=31928;var __ZTIn=Module["__ZTIn"]=31932;var __ZTSPn=Module["__ZTSPn"]=31940;var __ZTIPn=Module["__ZTIPn"]=31944;var __ZTSPKn=Module["__ZTSPKn"]=31960;var __ZTIPKn=Module["__ZTIPKn"]=31964;var __ZTSo=Module["__ZTSo"]=31980;var __ZTIo=Module["__ZTIo"]=31984;var __ZTSPo=Module["__ZTSPo"]=31992;var __ZTIPo=Module["__ZTIPo"]=31996;var __ZTSPKo=Module["__ZTSPKo"]=32012;var __ZTIPKo=Module["__ZTIPKo"]=32016;var __ZTSDh=Module["__ZTSDh"]=32032;var __ZTIDh=Module["__ZTIDh"]=32036;var __ZTSPDh=Module["__ZTSPDh"]=32044;var __ZTIPDh=Module["__ZTIPDh"]=32048;var __ZTSPKDh=Module["__ZTSPKDh"]=32064;var __ZTIPKDh=Module["__ZTIPKDh"]=32072;var __ZTSf=Module["__ZTSf"]=32088;var __ZTSPf=Module["__ZTSPf"]=32100;var __ZTIPf=Module["__ZTIPf"]=32104;var __ZTSPKf=Module["__ZTSPKf"]=32120;var __ZTIPKf=Module["__ZTIPKf"]=32124;var __ZTSd=Module["__ZTSd"]=32140;var __ZTSPd=Module["__ZTSPd"]=32152;var __ZTIPd=Module["__ZTIPd"]=32156;var __ZTSPKd=Module["__ZTSPKd"]=32172;var __ZTIPKd=Module["__ZTIPKd"]=32176;var __ZTSe=Module["__ZTSe"]=32192;var __ZTIe=Module["__ZTIe"]=32196;var __ZTSPe=Module["__ZTSPe"]=32204;var __ZTIPe=Module["__ZTIPe"]=32208;var __ZTSPKe=Module["__ZTSPKe"]=32224;var __ZTIPKe=Module["__ZTIPKe"]=32228;var __ZTSg=Module["__ZTSg"]=32244;var __ZTIg=Module["__ZTIg"]=32248;var __ZTSPg=Module["__ZTSPg"]=32256;var __ZTIPg=Module["__ZTIPg"]=32260;var __ZTSPKg=Module["__ZTSPKg"]=32276;var __ZTIPKg=Module["__ZTIPKg"]=32280;var __ZTSDu=Module["__ZTSDu"]=32296;var __ZTIDu=Module["__ZTIDu"]=32300;var __ZTSPDu=Module["__ZTSPDu"]=32308;var __ZTIPDu=Module["__ZTIPDu"]=32312;var __ZTSPKDu=Module["__ZTSPKDu"]=32328;var __ZTIPKDu=Module["__ZTIPKDu"]=32336;var __ZTSDs=Module["__ZTSDs"]=32352;var __ZTIDs=Module["__ZTIDs"]=32356;var __ZTSPDs=Module["__ZTSPDs"]=32364;var __ZTIPDs=Module["__ZTIPDs"]=32368;var __ZTSPKDs=Module["__ZTSPKDs"]=32384;var __ZTIPKDs=Module["__ZTIPKDs"]=32392;var __ZTSDi=Module["__ZTSDi"]=32408;var __ZTIDi=Module["__ZTIDi"]=32412;var __ZTSPDi=Module["__ZTSPDi"]=32420;var __ZTIPDi=Module["__ZTIPDi"]=32424;var __ZTSPKDi=Module["__ZTSPKDi"]=32440;var __ZTIPKDi=Module["__ZTIPKDi"]=32448;var __ZTVN10__cxxabiv117__array_type_infoE=Module["__ZTVN10__cxxabiv117__array_type_infoE"]=32464;var __ZTIN10__cxxabiv117__array_type_infoE=Module["__ZTIN10__cxxabiv117__array_type_infoE"]=32528;var __ZTSN10__cxxabiv117__array_type_infoE=Module["__ZTSN10__cxxabiv117__array_type_infoE"]=32492;var __ZTVN10__cxxabiv120__function_type_infoE=Module["__ZTVN10__cxxabiv120__function_type_infoE"]=32540;var __ZTVN10__cxxabiv116__enum_type_infoE=Module["__ZTVN10__cxxabiv116__enum_type_infoE"]=32568;var __ZTIN10__cxxabiv116__enum_type_infoE=Module["__ZTIN10__cxxabiv116__enum_type_infoE"]=32632;var __ZTSN10__cxxabiv116__enum_type_infoE=Module["__ZTSN10__cxxabiv116__enum_type_infoE"]=32596;var __ZTIN10__cxxabiv120__si_class_type_infoE=Module["__ZTIN10__cxxabiv120__si_class_type_infoE"]=32764;var __ZTSN10__cxxabiv120__si_class_type_infoE=Module["__ZTSN10__cxxabiv120__si_class_type_infoE"]=32724;var __ZTIN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTIN10__cxxabiv121__vmi_class_type_infoE"]=32856;var __ZTSN10__cxxabiv121__vmi_class_type_infoE=Module["__ZTSN10__cxxabiv121__vmi_class_type_infoE"]=32816;var __ZTVN10__cxxabiv117__pbase_type_infoE=Module["__ZTVN10__cxxabiv117__pbase_type_infoE"]=32868;var __ZTVN10__cxxabiv129__pointer_to_member_type_infoE=Module["__ZTVN10__cxxabiv129__pointer_to_member_type_infoE"]=32924;var __ZTVSt9bad_alloc=Module["__ZTVSt9bad_alloc"]=32952;var __ZTVSt20bad_array_new_length=Module["__ZTVSt20bad_array_new_length"]=32972;var __ZTISt9bad_alloc=Module["__ZTISt9bad_alloc"]=33104;var __ZTSSt9exception=Module["__ZTSSt9exception"]=33012;var __ZTVSt13bad_exception=Module["__ZTVSt13bad_exception"]=33036;var __ZTISt13bad_exception=Module["__ZTISt13bad_exception"]=33076;var __ZTSSt13bad_exception=Module["__ZTSSt13bad_exception"]=33056;var __ZTSSt9bad_alloc=Module["__ZTSSt9bad_alloc"]=33088;var __ZTSSt20bad_array_new_length=Module["__ZTSSt20bad_array_new_length"]=33116;var __ZTISt11logic_error=Module["__ZTISt11logic_error"]=33252;var __ZTISt13runtime_error=Module["__ZTISt13runtime_error"]=33492;var __ZTVSt12domain_error=Module["__ZTVSt12domain_error"]=33196;var __ZTISt12domain_error=Module["__ZTISt12domain_error"]=33264;var __ZTSSt12domain_error=Module["__ZTSSt12domain_error"]=33216;var __ZTSSt11logic_error=Module["__ZTSSt11logic_error"]=33233;var __ZTVSt16invalid_argument=Module["__ZTVSt16invalid_argument"]=33276;var __ZTISt16invalid_argument=Module["__ZTISt16invalid_argument"]=33320;var __ZTSSt16invalid_argument=Module["__ZTSSt16invalid_argument"]=33296;var __ZTSSt12length_error=Module["__ZTSSt12length_error"]=33352;var __ZTSSt12out_of_range=Module["__ZTSSt12out_of_range"]=33404;var __ZTVSt11range_error=Module["__ZTVSt11range_error"]=33436;var __ZTISt11range_error=Module["__ZTISt11range_error"]=33504;var __ZTSSt11range_error=Module["__ZTSSt11range_error"]=33456;var __ZTSSt13runtime_error=Module["__ZTSSt13runtime_error"]=33472;var __ZTVSt14overflow_error=Module["__ZTVSt14overflow_error"]=33516;var __ZTISt14overflow_error=Module["__ZTISt14overflow_error"]=33556;var __ZTSSt14overflow_error=Module["__ZTSSt14overflow_error"]=33536;var __ZTVSt15underflow_error=Module["__ZTVSt15underflow_error"]=33568;var __ZTISt15underflow_error=Module["__ZTISt15underflow_error"]=33608;var __ZTSSt15underflow_error=Module["__ZTSSt15underflow_error"]=33588;var __ZTVSt8bad_cast=Module["__ZTVSt8bad_cast"]=33620;var __ZTVSt10bad_typeid=Module["__ZTVSt10bad_typeid"]=33640;var __ZTISt8bad_cast=Module["__ZTISt8bad_cast"]=33712;var __ZTISt10bad_typeid=Module["__ZTISt10bad_typeid"]=33740;var __ZTVSt9type_info=Module["__ZTVSt9type_info"]=33660;var __ZTSSt9type_info=Module["__ZTSSt9type_info"]=33676;var __ZTSSt8bad_cast=Module["__ZTSSt8bad_cast"]=33700;var __ZTSSt10bad_typeid=Module["__ZTSSt10bad_typeid"]=33724;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); diff --git a/docs/public/config/failsafe/index.wasm b/docs/public/config/failsafe/index.wasm index c76c7dbd37..f80b40753d 100644 Binary files a/docs/public/config/failsafe/index.wasm and b/docs/public/config/failsafe/index.wasm differ diff --git a/docs/public/config/failsafe/parameters.json b/docs/public/config/failsafe/parameters.json index 4bf9a32275..b0fefe7e3c 100644 --- a/docs/public/config/failsafe/parameters.json +++ b/docs/public/config/failsafe/parameters.json @@ -1 +1 @@ -{"parameters": [{"category": "Standard", "default": 75, "group": "UAVCAN Motor Parameters", "longDesc": "Speed controller bandwidth, in Hz. Higher values result in faster speed and current rise times, but may result in overshoot and higher current consumption. For fixed-wing aircraft, this value should be less than 50 Hz; for multirotors, values up to 100 Hz may provide improvements in responsiveness.", "max": 250, "min": 10, "name": "ctl_bw", "shortDesc": "Speed controller bandwidth", "type": "Int32", "units": "Hz"}, {"category": "Standard", "default": 1, "group": "UAVCAN Motor Parameters", "longDesc": "Motor spin direction as detected during initial enumeration. Use 0 or 1 to reverse direction.", "max": 1, "min": 0, "name": "ctl_dir", "shortDesc": "Reverse direction", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "UAVCAN Motor Parameters", "longDesc": "Speed (RPM) controller gain. Determines controller\n aggressiveness; units are amp-seconds per radian. Systems with\n higher rotational inertia (large props) will need gain increased;\n systems with low rotational inertia (small props) may need gain\n decreased. Higher values result in faster response, but may result\n in oscillation and excessive overshoot. Lower values result in a\n slower, smoother response.", "max": 1.0, "min": 0.0, "name": "ctl_gain", "shortDesc": "Speed (RPM) controller gain", "type": "Float", "units": "C/rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 3.5, "group": "UAVCAN Motor Parameters", "longDesc": "Idle speed (e Hz)", "max": 100.0, "min": 0.0, "name": "ctl_hz_idle", "shortDesc": "Idle speed (e Hz)", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 25, "group": "UAVCAN Motor Parameters", "longDesc": "Spin-up rate (e Hz/s)", "max": 1000, "min": 5, "name": "ctl_start_rate", "shortDesc": "Spin-up rate (e Hz/s)", "type": "Int32", "units": "1/s^2"}, {"category": "Standard", "default": 0, "group": "UAVCAN Motor Parameters", "longDesc": "Index of this ESC in throttle command messages.", "max": 15, "min": 0, "name": "esc_index", "shortDesc": "Index of this ESC in throttle command messages.", "type": "Int32"}, {"category": "Standard", "default": 20034, "group": "UAVCAN Motor Parameters", "longDesc": "Extended status ID", "max": 1000000, "min": 1, "name": "id_ext_status", "shortDesc": "Extended status ID", "type": "Int32"}, {"category": "Standard", "default": 50000, "group": "UAVCAN Motor Parameters", "longDesc": "Extended status interval (\u00b5s)", "max": 1000000, "min": 0, "name": "int_ext_status", "shortDesc": "Extended status interval (\u00b5s)", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 50000, "group": "UAVCAN Motor Parameters", "longDesc": "ESC status interval (\u00b5s)", "max": 1000000, "name": "int_status", "shortDesc": "ESC status interval (\u00b5s)", "type": "Int32", "units": "us"}, {"category": "Standard", "decimalPlaces": 3, "default": 12.0, "group": "UAVCAN Motor Parameters", "longDesc": "Motor current limit in amps. This determines the maximum\n current controller setpoint, as well as the maximum allowable\n current setpoint slew rate. This value should generally be set to\n the continuous current rating listed in the motor\u2019s specification\n sheet, or set equal to the motor\u2019s specified continuous power\n divided by the motor voltage limit.", "max": 80.0, "min": 1.0, "name": "mot_i_max", "shortDesc": "Motor current limit in amps", "type": "Float", "units": "A"}, {"category": "Standard", "default": 2300, "group": "UAVCAN Motor Parameters", "longDesc": "Motor Kv in RPM per volt. This can be taken from the motor\u2019s\n specification sheet; accuracy will help control performance but\n some deviation from the specified value is acceptable.", "max": 4000, "min": 0, "name": "mot_kv", "shortDesc": "Motor Kv in RPM per volt", "type": "Int32", "units": "rpm/V"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "UAVCAN Motor Parameters", "longDesc": "READ ONLY: Motor inductance in henries. This is measured on start-up.", "name": "mot_ls", "shortDesc": "READ ONLY: Motor inductance in henries.", "type": "Float", "units": "H"}, {"category": "Standard", "default": 14, "group": "UAVCAN Motor Parameters", "longDesc": "Number of motor poles. Used to convert mechanical speeds to\n electrical speeds. This number should be taken from the motor\u2019s\n specification sheet.", "max": 40, "min": 2, "name": "mot_num_poles", "shortDesc": "Number of motor poles.", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "UAVCAN Motor Parameters", "longDesc": "READ ONLY: Motor resistance in ohms. This is measured on start-up. When\n tuning a new motor, check that this value is approximately equal\n to the value shown in the motor\u2019s specification sheet.", "name": "mot_rs", "shortDesc": "READ ONLY: Motor resistance in ohms", "type": "Float", "units": "Ohm"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "UAVCAN Motor Parameters", "longDesc": "Acceleration limit (V)", "max": 1.0, "min": 0.01, "name": "mot_v_accel", "shortDesc": "Acceleration limit (V)", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 3, "default": 14.8, "group": "UAVCAN Motor Parameters", "longDesc": "Motor voltage limit in volts. The current controller\u2019s\n commanded voltage will never exceed this value. Note that this may\n safely be above the nominal voltage of the motor; to determine the\n actual motor voltage limit, divide the motor\u2019s rated power by the\n motor current limit.", "min": 0.0, "name": "mot_v_max", "shortDesc": "Motor voltage limit in volts", "type": "Float", "units": "V"}, {"category": "Standard", "default": 2, "group": "UAVCAN GNSS", "longDesc": "Dynamic model used in the GNSS positioning engine. 0 \u2013\n Automotive, 1 \u2013 Sea, 2 \u2013 Airborne.\n ", "max": 2, "min": 0, "name": "gnss.dyn_model", "shortDesc": "GNSS dynamic model", "type": "Int32", "values": [{"description": "Automotive", "value": 0}, {"description": "Sea", "value": 1}, {"description": "Airborne", "value": 2}]}, {"category": "Standard", "default": 1, "group": "UAVCAN GNSS", "longDesc": "Broadcast the old (deprecated) GNSS fix message\n uavcan.equipment.gnss.Fix alongside the new alternative\n uavcan.equipment.gnss.Fix2. It is recommended to\n disable this feature to reduce the CAN bus traffic.\n ", "max": 1, "min": 0, "name": "gnss.old_fix_msg", "shortDesc": "Broadcast old GNSS fix message", "type": "Int32", "values": [{"description": "Fix2", "value": 0}, {"description": "Fix and Fix2", "value": 1}]}, {"category": "Standard", "default": 0, "group": "UAVCAN GNSS", "longDesc": "Set the device health to Warning if the dimensionality of\n the GNSS solution is less than this value. 3 for the full (3D)\n solution, 2 for planar (2D) solution, 1 for time-only solution,\n 0 disables the feature.\n ", "max": 3, "min": 0, "name": "gnss.warn_dimens", "shortDesc": "device health warning", "type": "Int32", "values": [{"description": "disables the feature", "value": 0}, {"description": "time-only solution", "value": 1}, {"description": "planar (2D) solution", "value": 2}, {"description": "full (3D) solution", "value": 3}]}, {"category": "Standard", "default": 0, "group": "UAVCAN GNSS", "longDesc": "Set the device health to Warning if the number of satellites\n used in the GNSS solution is below this threshold. Zero\n disables the feature\n ", "name": "gnss.warn_sats", "shortDesc": "", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "UAVCAN GNSS", "longDesc": "Set the device health to Warning if the number of satellites\n used in the GNSS solution is below this threshold. Zero\n disables the feature\n ", "max": 1000000, "min": 0, "name": "uavcan.pubp-pres", "shortDesc": "", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets first 4 characters of a total of 8. Valid characters are A-Z, 0-9, \" \". Example \"PX4 \" -> 1347957792\nFor CALLSIGN shorter than 8 characters use the null terminator at the end '\\0'.", "name": "ADSB_CALLSIGN_1", "rebootRequired": true, "shortDesc": "First 4 characters of CALLSIGN", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets second 4 characters of a total of 8. Valid characters are A-Z, 0-9, \" \" only. Example \"TEST\" -> 1413829460\nFor CALLSIGN shorter than 8 characters use the null terminator at the end '\\0'.", "name": "ADSB_CALLSIGN_2", "rebootRequired": true, "shortDesc": "Second 4 characters of CALLSIGN", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets the vehicle emergency state", "max": 6, "min": 0, "name": "ADSB_EMERGC", "rebootRequired": true, "shortDesc": "ADSB-Out Emergency State", "type": "Int32", "values": [{"description": "NoEmergency", "value": 0}, {"description": "General", "value": 1}, {"description": "Medical", "value": 2}, {"description": "LowFuel", "value": 3}, {"description": "NoCommunications", "value": 4}, {"description": "Interference", "value": 5}, {"description": "Downed", "value": 6}]}, {"category": "Standard", "default": 14, "group": "ADSB", "longDesc": "Configure the emitter type of the vehicle.", "max": 15, "min": 0, "name": "ADSB_EMIT_TYPE", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Emitter Type", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "Light", "value": 1}, {"description": "Small", "value": 2}, {"description": "Large", "value": 3}, {"description": "HighVortex", "value": 4}, {"description": "Heavy", "value": 5}, {"description": "Performance", "value": 6}, {"description": "Rotorcraft", "value": 7}, {"description": "RESERVED", "value": 8}, {"description": "Glider", "value": 9}, {"description": "LightAir", "value": 10}, {"description": "Parachute", "value": 11}, {"description": "UltraLight", "value": 12}, {"description": "RESERVED", "value": 13}, {"description": "UAV", "value": 14}, {"description": "Space", "value": 15}, {"description": "RESERVED", "value": 16}, {"description": "EmergencySurf", "value": 17}, {"description": "ServiceSurf", "value": 18}, {"description": "PointObstacle", "value": 19}]}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets GPS lataral offset encoding", "max": 7, "min": 0, "name": "ADSB_GPS_OFF_LAT", "rebootRequired": true, "shortDesc": "ADSB-Out GPS Offset lat", "type": "Int32", "values": [{"description": "NoData", "value": 0}, {"description": "LatLeft2M", "value": 1}, {"description": "LatLeft4M", "value": 2}, {"description": "LatLeft6M", "value": 3}, {"description": "LatRight0M", "value": 4}, {"description": "LatRight2M", "value": 5}, {"description": "LatRight4M", "value": 6}, {"description": "LatRight6M", "value": 7}]}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets GPS longitudinal offset encoding", "max": 1, "min": 0, "name": "ADSB_GPS_OFF_LON", "rebootRequired": true, "shortDesc": "ADSB-Out GPS Offset lon", "type": "Int32", "values": [{"description": "NoData", "value": 0}, {"description": "AppliedBySensor", "value": 1}]}, {"category": "Standard", "default": 1194684, "group": "ADSB", "longDesc": "Defines the ICAO ID of the vehicle", "max": 16777215, "min": -1, "name": "ADSB_ICAO_ID", "rebootRequired": true, "shortDesc": "ADSB-Out ICAO configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "This vehicle is always tracked. Use 0 to disable.", "max": 16777215, "min": 0, "name": "ADSB_ICAO_SPECL", "rebootRequired": true, "shortDesc": "ADSB-In Special ICAO configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Enable Identification of Position feature", "name": "ADSB_IDENT", "rebootRequired": true, "shortDesc": "ADSB-Out Ident Configuration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "ADSB", "longDesc": "Report the length and width of the vehicle in meters. In most cases, use '1' for the smallest vehicle size.", "max": 15, "min": 0, "name": "ADSB_LEN_WIDTH", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Size Configuration", "type": "Int32", "values": [{"description": "SizeUnknown", "value": 0}, {"description": "Len15_Wid23", "value": 1}, {"description": "Len25_Wid28", "value": 2}, {"description": "Len25_Wid34", "value": 3}, {"description": "Len35_Wid33", "value": 4}, {"description": "Len35_Wid38", "value": 5}, {"description": "Len45_Wid39", "value": 6}, {"description": "Len45_Wid45", "value": 7}, {"description": "Len55_Wid45", "value": 8}, {"description": "Len55_Wid52", "value": 9}, {"description": "Len65_Wid59", "value": 10}, {"description": "Len65_Wid67", "value": 11}, {"description": "Len75_Wid72", "value": 12}, {"description": "Len75_Wid80", "value": 13}, {"description": "Len85_Wid80", "value": 14}, {"description": "Len85_Wid90", "value": 15}]}, {"category": "Standard", "default": 25, "group": "ADSB", "longDesc": "Change number of targets to track", "max": 50, "min": 0, "name": "ADSB_LIST_MAX", "rebootRequired": true, "shortDesc": "ADSB-In Vehicle List Size", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Informs ADSB vehicles of this vehicle's max speed capability", "max": 6, "min": 0, "name": "ADSB_MAX_SPEED", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Max Speed", "type": "Int32", "values": [{"description": "UnknownMaxSpeed", "value": 0}, {"description": "75Kts", "value": 1}, {"description": "150Kts", "value": 2}, {"description": "300Kts", "value": 3}, {"description": "600Kts", "value": 4}, {"description": "1200Kts", "value": 5}, {"description": "Over1200Kts", "value": 6}]}, {"category": "Standard", "default": 1200, "group": "ADSB", "longDesc": "This parameter defines the squawk code. Value should be between 0000 and 7777.", "max": 7777, "min": 0, "name": "ADSB_SQUAWK", "rebootRequired": true, "shortDesc": "ADSB-Out squawk code configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 1.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC1", "shortDesc": "SIM Channel 1 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 10.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC10", "shortDesc": "SIM Channel 10 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 11.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC11", "shortDesc": "SIM Channel 11 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 12.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC12", "shortDesc": "SIM Channel 12 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 13.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC13", "shortDesc": "SIM Channel 13 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 14.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC14", "shortDesc": "SIM Channel 14 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 15.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC15", "shortDesc": "SIM Channel 15 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 16.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC16", "shortDesc": "SIM Channel 16 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 2.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC2", "shortDesc": "SIM Channel 2 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 3.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC3", "shortDesc": "SIM Channel 3 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 4.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC4", "shortDesc": "SIM Channel 4 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 5.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC5", "shortDesc": "SIM Channel 5 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 6.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC6", "shortDesc": "SIM Channel 6 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 7.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC7", "shortDesc": "SIM Channel 7 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 8.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC8", "shortDesc": "SIM Channel 8 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 9.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC9", "shortDesc": "SIM Channel 9 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"bitmask": [{"description": "SIM Channel 1", "index": 0}, {"description": "SIM Channel 2", "index": 1}, {"description": "SIM Channel 3", "index": 2}, {"description": "SIM Channel 4", "index": 3}, {"description": "SIM Channel 5", "index": 4}, {"description": "SIM Channel 6", "index": 5}, {"description": "SIM Channel 7", "index": 6}, {"description": "SIM Channel 8", "index": 7}, {"description": "SIM Channel 9", "index": 8}, {"description": "SIM Channel 10", "index": 9}, {"description": "SIM Channel 11", "index": 10}, {"description": "SIM Channel 12", "index": 11}, {"description": "SIM Channel 13", "index": 12}, {"description": "SIM Channel 14", "index": 13}, {"description": "SIM Channel 15", "index": 14}, {"description": "SIM Channel 16", "index": 15}], "category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Allows to reverse the output range for each channel.\nNote: this is only useful for servos.", "max": 65535, "min": 0, "name": "PWM_MAIN_REV", "shortDesc": "Reverse Output Range for SIM", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "Airspeed Validator", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "max": 5, "min": 1, "name": "ASPD_BETA_GATE", "shortDesc": "Gate size for sideslip angle fusion", "type": "Int32", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Airspeed Validator", "longDesc": "Sideslip measurement noise of the internal wind estimator(s) of the airspeed selector.", "max": 1.0, "min": 0.0, "name": "ASPD_BETA_NOISE", "shortDesc": "Wind estimator sideslip measurement noise", "type": "Float", "units": "rad"}, {"bitmask": [{"description": "Only data missing check (triggers if more than 1s no data)", "index": 0}, {"description": "Data stuck (triggers if data is exactly constant for 2s in FW mode)", "index": 1}, {"description": "Innovation check (see ASPD_FS_INNOV)", "index": 2}, {"description": "Load factor check (triggers if measurement is below stall speed)", "index": 3}, {"description": "First principle check (airspeed change vs. throttle and pitch)", "index": 4}], "category": "Standard", "default": 7, "group": "Airspeed Validator", "longDesc": "Controls which checks are run to check airspeed data for validity. Only applied if ASPD_PRIMARY > 0.", "max": 31, "min": 0, "name": "ASPD_DO_CHECKS", "shortDesc": "Enable checks on airspeed sensors", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Airspeed Validator", "name": "ASPD_FALLBACK", "shortDesc": "Fallback options", "type": "Int32", "values": [{"description": "Fallback only to other airspeed sensors", "value": 0}, {"description": "Fallback to groundspeed-minus-windspeed airspeed estimation", "value": 1}, {"description": "Fallback to thrust based airspeed estimation", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Airspeed Validator", "longDesc": "Window for comparing airspeed change to throttle and pitch change.\nTriggers when the airspeed change within this window is negative while throttle increases\nand the vehicle pitches down.\nIs meant to catch degrading airspeed blockages as can happen when flying through icing conditions.\nRelies on FW_THR_TRIM being set accurately.", "min": 0.0, "name": "ASPD_FP_T_WINDOW", "shortDesc": "First principle airspeed check time window", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Airspeed Validator", "longDesc": "This specifies the minimum airspeed innovation required to trigger a failsafe. Larger values make the check less sensitive,\nsmaller values make it more sensitive. Large innovations indicate an inconsistency between predicted (groundspeed - windspeeed)\nand measured airspeed.\nThe time required to detect a fault when the threshold is exceeded depends on the size of the exceedance and is controlled by the ASPD_FS_INTEG parameter.", "max": 10.0, "min": 0.5, "name": "ASPD_FS_INNOV", "shortDesc": "Airspeed failure innovation threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Airspeed Validator", "longDesc": "This sets the time integral of airspeed innovation exceedance above ASPD_FS_INNOV required to trigger a failsafe.\nLarger values make the check less sensitive, smaller positive values make it more sensitive.", "max": 50.0, "min": 0.0, "name": "ASPD_FS_INTEG", "shortDesc": "Airspeed failure innovation integral threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Airspeed Validator", "longDesc": "Delay before switching back to using airspeed sensor if checks indicate sensor is good.\nSet to a negative value to disable the re-enabling in flight.", "min": -1.0, "name": "ASPD_FS_T_START", "shortDesc": "Airspeed failsafe start delay", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Airspeed Validator", "longDesc": "Delay before stopping use of airspeed sensor if checks indicate sensor is bad.", "min": 0.0, "name": "ASPD_FS_T_STOP", "shortDesc": "Airspeed failsafe stop delay", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Airspeed Validator", "name": "ASPD_PRIMARY", "rebootRequired": true, "shortDesc": "Index or primary airspeed measurement source", "type": "Int32", "values": [{"description": "Groundspeed minus windspeed", "value": 0}, {"description": "First airspeed sensor", "value": 1}, {"description": "Second airspeed sensor", "value": 2}, {"description": "Third airspeed sensor", "value": 3}, {"description": "Thrust based airspeed", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the first airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_1", "rebootRequired": true, "shortDesc": "Scale of airspeed sensor 1", "type": "Float", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the second airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_2", "rebootRequired": true, "shortDesc": "Scale of airspeed sensor 2", "type": "Float", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the third airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_3", "rebootRequired": true, "shortDesc": "Scale of airspeed sensor 3", "type": "Float", "volatile": true}, {"category": "Standard", "default": 2, "group": "Airspeed Validator", "name": "ASPD_SCALE_APPLY", "shortDesc": "Controls when to apply the new estimated airspeed scale(s)", "type": "Int32", "values": [{"description": "Do not automatically apply the estimated scale", "value": 0}, {"description": "Apply the estimated scale after disarm", "value": 1}, {"description": "Apply the estimated scale in air", "value": 2}]}, {"category": "Standard", "decimalPlaces": 5, "default": 0.0001, "group": "Airspeed Validator", "longDesc": "Airspeed scale process noise of the internal wind estimator(s) of the airspeed selector.\nWhen unaided, the scale uncertainty (1-sigma, unitless) increases by this amount every second.", "max": 0.1, "min": 0.0, "name": "ASPD_SCALE_NSD", "shortDesc": "Wind estimator true airspeed scale process noise spectral density", "type": "Float", "units": "1/s/sqrt(Hz)"}, {"category": "Standard", "default": 4, "group": "Airspeed Validator", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "max": 5, "min": 1, "name": "ASPD_TAS_GATE", "shortDesc": "Gate size for true airspeed fusion", "type": "Int32", "units": "SD"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.4, "group": "Airspeed Validator", "longDesc": "True airspeed measurement noise of the internal wind estimator(s) of the airspeed selector.", "max": 4.0, "min": 0.0, "name": "ASPD_TAS_NOISE", "shortDesc": "Wind estimator true airspeed measurement noise", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.55, "group": "Airspeed Validator", "longDesc": "The synthetic airspeed estimate (from groundspeed and heading) will be declared valid\nas soon and as long the horizontal wind uncertainty is below this value.", "max": 5.0, "min": 0.001, "name": "ASPD_WERR_THR", "shortDesc": "Horizontal wind uncertainty threshold for synthetic airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Airspeed Validator", "longDesc": "Wind process noise of the internal wind estimator(s) of the airspeed selector.\nWhen unaided, the wind estimate uncertainty (1-sigma, in m/s) increases by this amount every second.", "max": 1.0, "min": 0.0, "name": "ASPD_WIND_NSD", "shortDesc": "Wind estimator wind process noise spectral density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "name": "ATT_ACC_COMP", "shortDesc": "Acceleration compensation based on GPS velocity", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Attitude Q estimator", "max": 2.0, "min": 0.0, "name": "ATT_BIAS_MAX", "shortDesc": "Gyro bias limit", "type": "Float", "units": "rad/s"}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "longDesc": "Enable standalone quaternion based attitude estimator.", "name": "ATT_EN", "shortDesc": "standalone attitude estimator enable (unsupported)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "longDesc": "Set to 1 to use heading estimate from vision.\nSet to 2 to use heading from motion capture.", "max": 2, "min": 0, "name": "ATT_EXT_HDG_M", "shortDesc": "External heading usage mode (from Motion capture/Vision)", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Vision", "value": 1}, {"description": "Motion Capture", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Attitude Q estimator", "longDesc": "This parameter is not used in normal operation,\nas the declination is looked up based on the\nGPS coordinates of the vehicle.", "name": "ATT_MAG_DECL", "shortDesc": "Magnetic declination, in degrees", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 1, "group": "Attitude Q estimator", "name": "ATT_MAG_DECL_A", "shortDesc": "Automatic GPS based declination compensation", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_ACC", "shortDesc": "Complimentary filter accelerometer weight", "type": "Float"}, {"category": "Standard", "default": 0.1, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_EXT_HDG", "shortDesc": "Complimentary filter external heading weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_GYRO_BIAS", "shortDesc": "Complimentary filter gyroscope bias weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Attitude Q estimator", "longDesc": "Set to 0 to avoid using the magnetometer.", "max": 1.0, "min": 0.0, "name": "ATT_W_MAG", "shortDesc": "Complimentary filter magnetometer weight", "type": "Float"}, {"category": "Standard", "default": 2, "group": "Autotune", "longDesc": "After the auto-tuning sequence is completed,\na new set of gains is available and can be applied\nimmediately or after landing.", "name": "FW_AT_APPLY", "shortDesc": "Controls when to apply the new gains", "type": "Int32", "values": [{"description": "Do not apply the new gains (logging only)", "value": 0}, {"description": "Apply the new gains after disarm", "value": 1}, {"description": "Apply the new gains in air", "value": 2}]}, {"bitmask": [{"description": "roll", "index": 0}, {"description": "pitch", "index": 1}, {"description": "yaw", "index": 2}], "category": "Standard", "default": 3, "group": "Autotune", "longDesc": "Defines which axes will be tuned during the auto-tuning sequence\nSet bits in the following positions to enable:\n0 : Roll\n1 : Pitch\n2 : Yaw", "max": 7, "min": 1, "name": "FW_AT_AXES", "shortDesc": "Tuning axes selection", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Autotune", "longDesc": "Defines which RC_MAP_AUXn parameter maps the RC channel used to enable/disable auto tuning.", "max": 6, "min": 0, "name": "FW_AT_MAN_AUX", "shortDesc": "Enable/disable auto tuning using an RC AUX input", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Aux1", "value": 1}, {"description": "Aux2", "value": 2}, {"description": "Aux3", "value": 3}, {"description": "Aux4", "value": 4}, {"description": "Aux5", "value": 5}, {"description": "Aux6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Autotune", "longDesc": "WARNING: this will inject steps to the rate controller\nand can be dangerous. Only activate if you know what you\nare doing, and in a safe environment.\nAny motion of the remote stick will abort the signal\ninjection and reset this parameter\nBest is to perform the identification in position or\nhold mode.\nIncrease the amplitude of the injected signal using\nFW_AT_SYSID_AMP for more signal/noise ratio", "name": "FW_AT_START", "shortDesc": "Start the autotuning sequence", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Autotune", "longDesc": "This parameter scales the signal sent to the\nrate controller during system identification.", "max": 6.0, "min": 0.1, "name": "FW_AT_SYSID_AMP", "shortDesc": "Amplitude of the injected signal", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Autotune", "longDesc": "Can be set lower or higher than the end frequency", "max": 30.0, "min": 0.1, "name": "FW_AT_SYSID_F0", "shortDesc": "Start frequency of the injected signal", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Autotune", "longDesc": "Can be set lower or higher than the start frequency", "max": 30.0, "min": 0.1, "name": "FW_AT_SYSID_F1", "shortDesc": "End frequency of the injected signal", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 0, "default": 10.0, "group": "Autotune", "longDesc": "Duration of the input signal sent on each axis during system identification", "max": 120.0, "min": 5.0, "name": "FW_AT_SYSID_TIME", "shortDesc": "Maneuver time for each axis", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Autotune", "longDesc": "Type of signal used during system identification to excite the system.", "name": "FW_AT_SYSID_TYPE", "shortDesc": "Input signal type", "type": "Int32", "values": [{"description": "Step", "value": 0}, {"description": "Linear sine sweep", "value": 1}, {"description": "Logarithmic sine sweep", "value": 2}]}, {"category": "Standard", "default": 1, "group": "Autotune", "longDesc": "After the auto-tuning sequence is completed,\na new set of gains is available and can be applied\nimmediately or after landing.\nWARNING Applying the gains in air is dangerous as there is no\nguarantee that those new gains will be able to stabilize\nthe drone properly.", "name": "MC_AT_APPLY", "shortDesc": "Controls when to apply the new gains", "type": "Int32", "values": [{"description": "Do not apply the new gains (logging only)", "value": 0}, {"description": "Apply the new gains after disarm", "value": 1}, {"description": "WARNING Apply the new gains in air", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Autotune", "name": "MC_AT_EN", "shortDesc": "Multicopter autotune module enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.14, "group": "Autotune", "max": 0.5, "min": 0.01, "name": "MC_AT_RISE_TIME", "shortDesc": "Desired angular rate closed-loop rise time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Autotune", "longDesc": "WARNING: this will inject steps to the rate controller\nand can be dangerous. Only activate if you know what you\nare doing, and in a safe environment.\nAny motion of the remote stick will abort the signal\ninjection and reset this parameter\nBest is to perform the identification in position or\nhold mode.\nIncrease the amplitude of the injected signal using\nMC_AT_SYSID_AMP for more signal/noise ratio", "name": "MC_AT_START", "shortDesc": "Start the autotuning sequence", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.7, "group": "Autotune", "max": 6.0, "min": 0.1, "name": "MC_AT_SYSID_AMP", "shortDesc": "Amplitude of the injected signal", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 1 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT1_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 1 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT1_N_CELLS", "shortDesc": "Number of cells for battery 1", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT1_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 1", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module'\nmeans that measurements are expected to come from a power module. If the value is set to\n'External' then the system expects to receive mavlink battery status messages.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current.", "name": "BAT1_SOURCE", "rebootRequired": true, "shortDesc": "Battery 1 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT1_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT1_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 2 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT2_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 2 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT2_N_CELLS", "shortDesc": "Number of cells for battery 2", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT2_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 2", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": -1, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module'\nmeans that measurements are expected to come from a power module. If the value is set to\n'External' then the system expects to receive mavlink battery status messages.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current.", "name": "BAT2_SOURCE", "rebootRequired": true, "shortDesc": "Battery 2 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT2_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT2_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 3 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT3_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 3 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT3_N_CELLS", "shortDesc": "Number of cells for battery 3", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT3_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 3", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": -1, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module'\nmeans that measurements are expected to come from a power module. If the value is set to\n'External' then the system expects to receive mavlink battery status messages.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current.", "name": "BAT3_SOURCE", "rebootRequired": true, "shortDesc": "Battery 3 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT3_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT3_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 15.0, "group": "Battery Calibration", "increment": 0.1, "longDesc": "This value is used to initialize the in-flight average current estimation,\nwhich in turn is used for estimating remaining flight time and RTL triggering.", "max": 500.0, "min": 0.0, "name": "BAT_AVRG_CURRENT", "shortDesc": "Expected battery current in flight", "type": "Float", "units": "A"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.07, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as critically low.\nThis has to be lower than the low threshold. This threshold commonly\nwill trigger RTL.", "max": 0.5, "min": 0.05, "name": "BAT_CRIT_THR", "shortDesc": "Critical threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as dangerously low.\nThis has to be lower than the critical threshold. This threshold commonly\nwill trigger landing.", "max": 0.5, "min": 0.03, "name": "BAT_EMERGEN_THR", "shortDesc": "Emergency threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as low.\nThis has to be higher than the critical threshold.", "max": 0.5, "min": 0.12, "name": "BAT_LOW_THR", "shortDesc": "Low threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Camera trigger", "longDesc": "This parameter sets the time the trigger needs to pulled high or low.", "max": 3000.0, "min": 0.1, "name": "TRIG_ACT_TIME", "rebootRequired": true, "shortDesc": "Camera trigger activation time", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "Camera trigger", "increment": 1.0, "longDesc": "Sets the distance at which to trigger the camera.", "min": 0.0, "name": "TRIG_DISTANCE", "rebootRequired": true, "shortDesc": "Camera trigger distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 4, "group": "Camera trigger", "longDesc": "Selects the trigger interface", "name": "TRIG_INTERFACE", "rebootRequired": true, "shortDesc": "Camera trigger Interface", "type": "Int32", "values": [{"description": "GPIO", "value": 1}, {"description": "Seagull MAP2 (over PWM)", "value": 2}, {"description": "MAVLink (Camera Protocol v1)", "value": 3}, {"description": "Generic PWM (IR trigger, servo)", "value": 4}]}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Camera trigger", "longDesc": "This parameter sets the time between two consecutive trigger events", "max": 10000.0, "min": 4.0, "name": "TRIG_INTERVAL", "rebootRequired": true, "shortDesc": "Camera trigger interval", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Camera trigger", "longDesc": "This parameter sets the minimum time between two consecutive trigger events\nthe specific camera setup is supporting.", "max": 10000.0, "min": 1.0, "name": "TRIG_MIN_INTERVA", "rebootRequired": true, "shortDesc": "Minimum camera trigger interval", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "Camera trigger", "max": 4, "min": 0, "name": "TRIG_MODE", "rebootRequired": true, "shortDesc": "Camera trigger mode", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Time based, on command", "value": 1}, {"description": "Time based, always on", "value": 2}, {"description": "Distance based, always on", "value": 3}, {"description": "Distance based, on command (Survey mode)", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Camera trigger", "longDesc": "This parameter sets the polarity of the trigger (0 = active low, 1 = active high )", "max": 1, "min": 0, "name": "TRIG_POLARITY", "rebootRequired": true, "shortDesc": "Camera trigger polarity", "type": "Int32", "values": [{"description": "Active low", "value": 0}, {"description": "Active high", "value": 1}]}, {"category": "Standard", "default": 1500, "group": "Camera trigger", "max": 2000, "min": 1000, "name": "TRIG_PWM_NEUTRAL", "rebootRequired": true, "shortDesc": "PWM neutral output on trigger pin", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 1900, "group": "Camera trigger", "max": 2000, "min": 1000, "name": "TRIG_PWM_SHOOT", "rebootRequired": true, "shortDesc": "PWM output to trigger shot", "type": "Int32", "units": "us"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 782097 will disable the buzzer audio notification.\nSetting this parameter to 782090 will disable the startup tune, while keeping\nall others enabled.", "max": 782097, "min": 0, "name": "CBRK_BUZZER", "rebootRequired": true, "shortDesc": "Circuit breaker for disabling buzzer", "type": "Int32"}, {"category": "Developer", "default": 121212, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 121212 will disable the flight termination action if triggered\nby the FailureDetector logic or if FMU is lost.\nThis circuit breaker does not affect the RC loss, data link loss, geofence,\nand takeoff failure detection safety logic.", "max": 121212, "min": 0, "name": "CBRK_FLIGHTTERM", "rebootRequired": true, "shortDesc": "Circuit breaker for flight termination", "type": "Int32"}, {"category": "Developer", "default": 22027, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 22027 will disable IO safety.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 22027, "min": 0, "name": "CBRK_IO_SAFETY", "shortDesc": "Circuit breaker for IO safety", "type": "Int32"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 894281 will disable the power valid\nchecks in the commander.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 894281, "min": 0, "name": "CBRK_SUPPLY_CHK", "shortDesc": "Circuit breaker for power supply check", "type": "Int32"}, {"category": "Developer", "default": 197848, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 197848 will disable the USB connected\nchecks in the commander, setting it to 0 keeps them enabled (recommended).\nWe are generally recommending to not fly with the USB link\nconnected and production vehicles should set this parameter to\nzero to prevent users from flying USB powered. However, for R&D purposes\nit has proven over the years to work just fine.", "max": 197848, "min": 0, "name": "CBRK_USB_CHK", "shortDesc": "Circuit breaker for USB link check", "type": "Int32"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 159753 will enable arming in fixed-wing\nmode for VTOLs.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 159753, "min": 0, "name": "CBRK_VTOLARMING", "shortDesc": "Circuit breaker for arming in fixed-wing mode check", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Note: actuator failure needs to be enabled and configured via FD_ACT_*\nparameters.", "max": 3, "min": 0, "name": "COM_ACT_FAIL_ACT", "shortDesc": "Set the actuator failure failsafe mode", "type": "Int32", "values": [{"description": "Warning only", "value": 0}, {"description": "Hold mode", "value": 1}, {"description": "Land mode", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Terminate", "value": 4}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Set 0 to prevent accidental use of the vehicle e.g. for safety or maintenance reasons.", "name": "COM_ARMABLE", "shortDesc": "Flag to allow arming", "type": "Int32", "values": [{"description": "Disallow arming", "value": 0}, {"description": "Allow arming", "value": 1}]}, {"category": "Standard", "default": 10, "group": "Commander", "longDesc": "Used if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_ID", "shortDesc": "Arm authorizer system id", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Methods:\n- one arm: request authorization and arm when authorization is received\n- two step arm: 1st arm command request an authorization and\n2nd arm command arm the drone if authorized\nUsed if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_MET", "shortDesc": "Arm authorization method", "type": "Int32", "values": [{"description": "one arm", "value": 0}, {"description": "two step arm", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "By default off. The default allows to arm the vehicle without a arm authorization.", "name": "COM_ARM_AUTH_REQ", "shortDesc": "Require arm authorization to arm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "increment": 0.1, "longDesc": "Timeout for authorizer answer.\nUsed if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_TO", "shortDesc": "Arm authorization timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Commander", "increment": 0.01, "longDesc": "Threshold for battery percentage below arming is prohibited.\nA negative value means BAT_CRIT_THR is the threshold.", "max": 0.9, "min": -1.0, "name": "COM_ARM_BAT_MIN", "shortDesc": "Minimum battery level for arming", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "If this parameter is set, the system will check ESC's online status and failures.\nThis param is specific for ESCs reporting status. It shall be used only if ESCs support telemetry.", "name": "COM_ARM_CHK_ESCS", "shortDesc": "Enable checks on ESCs that report telemetry", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This check detects if there are hardfault files present on the\nSD card. If so, and the parameter is enabled, arming is prevented.", "name": "COM_ARM_HFLT_CHK", "shortDesc": "Enable FMU SD card hardfault detection check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "Commander", "increment": 0.05, "max": 1.0, "min": 0.1, "name": "COM_ARM_IMU_ACC", "shortDesc": "Maximum accelerometer inconsistency between IMU units that will allow arming", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Commander", "increment": 0.01, "max": 0.3, "min": 0.02, "name": "COM_ARM_IMU_GYR", "shortDesc": "Maximum rate gyro inconsistency between IMU units that will allow arming", "type": "Float", "units": "rad/s"}, {"category": "Standard", "default": 60, "group": "Commander", "longDesc": "Set -1 to disable the check.", "max": 180, "min": 3, "name": "COM_ARM_MAG_ANG", "shortDesc": "Maximum magnetic field inconsistency between units that will allow arming", "type": "Int32", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Commander", "longDesc": "Check if the estimator detects a strong magnetic\ndisturbance (check enabled by EKF2_MAG_CHECK)", "name": "COM_ARM_MAG_STR", "shortDesc": "Enable mag strength preflight check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Deny arming", "value": 1}, {"description": "Warning only", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The default allows to arm the vehicle without a valid mission.", "name": "COM_ARM_MIS_REQ", "shortDesc": "Require valid mission to arm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "This check detects if the Open Drone ID system is missing.\nDepending on the value of the parameter, the check can be\ndisabled, warn only or deny arming.", "name": "COM_ARM_ODID", "shortDesc": "Enable Drone ID system detection and health check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warning only", "value": 1}, {"description": "Enforce Open Drone ID system presence", "value": 2}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This check detects if the FMU SD card is missing.\nDepending on the value of the parameter, the check can be\ndisabled, warn only or deny arming.", "name": "COM_ARM_SDCARD", "shortDesc": "Enable FMU SD card detection check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warning only", "value": 1}, {"description": "Enforce SD card presence", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "0: Arming/disarming triggers on switch transition.\n1: Arming/disarming triggers when holding the momentary button down\nfor COM_RC_ARM_HYST like the stick gesture.", "name": "COM_ARM_SWISBTN", "shortDesc": "Arm switch is a momentary button", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Measures taken when a check defined by EKF2_GPS_CHECK is failing.", "name": "COM_ARM_WO_GPS", "shortDesc": "GPS preflight check", "type": "Int32", "values": [{"description": "Deny arming", "value": 0}, {"description": "Warning only", "value": 1}, {"description": "Disabled", "value": 2}]}, {"category": "Standard", "default": 95.0, "group": "Commander", "increment": 1.0, "longDesc": "The check fails if the CPU load is above this threshold for 2s.\nA negative value disables the check.", "max": 100.0, "min": -1.0, "name": "COM_CPU_MAX", "shortDesc": "Maximum allowed CPU load to still arm", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Commander", "increment": 0.1, "longDesc": "A non-zero, positive value specifies the time-out period in seconds after which the vehicle will be\nautomatically disarmed in case a landing situation has been detected during this period.\nA zero or negative value means that automatic disarming triggered by landing detection is disabled.", "name": "COM_DISARM_LAND", "shortDesc": "Time-out for auto disarm after landing", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "0: Disallow disarming when not landed\n1: Allow disarming in multicopter flight in modes where\nthe thrust is directly controlled by thr throttle stick\ne.g. Stabilized, Acro", "name": "COM_DISARM_MAN", "shortDesc": "Allow disarming via switch/stick/button on multicopters in manual thrust modes", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Commander", "increment": 0.1, "longDesc": "A non-zero, positive value specifies the time in seconds, within which the\nvehicle is expected to take off after arming. In case the vehicle didn't takeoff\nwithin the timeout it disarms again.\nA negative value disables autmoatic disarming triggered by a pre-takeoff timeout.", "name": "COM_DISARM_PRFLT", "shortDesc": "Time-out for auto disarm if not taking off", "type": "Float", "units": "s"}, {"bitmask": [{"description": "Mission", "index": 0}, {"description": "Hold", "index": 1}, {"description": "Offboard", "index": 2}], "category": "Standard", "default": 0, "group": "Commander", "longDesc": "Specify modes in which datalink loss is ignored and the failsafe action not triggered.", "max": 7, "min": 0, "name": "COM_DLL_EXCEPT", "shortDesc": "Datalink loss exceptions", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10, "group": "Commander", "increment": 1, "longDesc": "After this amount of seconds without datalink, the GCS connection lost mode triggers", "max": 300, "min": 5, "name": "COM_DL_LOSS_T", "shortDesc": "GCS connection loss time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "longDesc": "Before entering failsafe (RTL, Land, Hold), wait COM_FAIL_ACT_T seconds in Hold mode\nfor the user to realize.\nDuring that time the user cannot take over control via the stick override feature (see COM_RC_OVERRIDE).\nAfterwards the configured failsafe action is triggered and the user may use stick override.\nA zero value disables the delay and the user cannot take over via stick movements (switching modes is still allowed).", "max": 25.0, "min": 0.0, "name": "COM_FAIL_ACT_T", "shortDesc": "Delay between failsafe condition triggered and failsafe reaction", "type": "Float", "units": "s"}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This number is incremented automatically after every flight on\ndisarming in order to remember the next flight UUID.\nThe first flight is 0.", "min": 0, "name": "COM_FLIGHT_UUID", "shortDesc": "Next flight UUID", "type": "Int32", "volatile": true}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE1", "shortDesc": "Mode slot 1", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE2", "shortDesc": "Mode slot 2", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE3", "shortDesc": "Mode slot 3", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE4", "shortDesc": "Mode slot 4", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE5", "shortDesc": "Mode slot 5", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE6", "shortDesc": "Mode slot 6", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": 3, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when the remaining flight time is below\nthe estimated time it takes to reach the RTL destination.", "name": "COM_FLTT_LOW_ACT", "shortDesc": "Remaining flight time low failsafe", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Return", "value": 3}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Describes the intended use of the vehicle.\nCan be used by ground control software or log post processing.\nThis param does not influence the behavior within the firmware. This means for example the control logic is independent of the setting of this param (but depends on other params).", "name": "COM_FLT_PROFILE", "shortDesc": "User Flight Profile", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Pro User", "value": 100}, {"description": "Flight Tester", "value": 200}, {"description": "Developer", "value": 300}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "The vehicle aborts the current operation and returns to launch when\nthe time since takeoff is above this value. It is not possible to resume the\nmission or switch to any auto mode other than RTL or Land. Taking over in any manual\nmode is still possible.\nStarting from 90% of the maximum flight time, a warning message will be sent\nevery 1 minute with the remaining time until automatic RTL.\nSet to -1 to disable.", "min": -1, "name": "COM_FLT_TIME_MAX", "shortDesc": "Maximum allowed flight time", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Force safety when the vehicle disarms", "name": "COM_FORCE_SAFETY", "shortDesc": "Enable force safety", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 120, "group": "Commander", "longDesc": "After this amount of seconds without datalink the data link lost mode triggers", "max": 3600, "min": 60, "name": "COM_HLDL_LOSS_T", "shortDesc": "High Latency Datalink loss time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "After a data link loss: after this number of seconds with a healthy datalink the 'datalink loss'\nflag is set back to false", "max": 60, "min": 0, "name": "COM_HLDL_REG_T", "shortDesc": "High Latency Datalink regain time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Set home position automatically if possible.\nDuring missions, the latitude/longitude of the home position is locked and will not reset during intermediate landings.\nIt will only update once the mission is complete or landed outside of a mission.\nHowever, the altitude is still being adjusted to correct for GNSS vertical drift in the first 2 minutes after takeoff.", "name": "COM_HOME_EN", "rebootRequired": true, "shortDesc": "Home position enabled", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "If set to true, the autopilot is allowed to set its home position after takeoff\nThe true home position is back-computed if a local position is estimate if available.\nIf no local position is available, home is set to the current position.", "name": "COM_HOME_IN_AIR", "shortDesc": "Allows setting the home position after takeoff", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when an imbalanced propeller is detected by the failure detector.\nSee also FD_IMB_PROP_THR to set the failure threshold.", "name": "COM_IMB_PROP_ACT", "shortDesc": "Imbalanced propeller failsafe mode", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Warning", "value": 0}, {"description": "Return", "value": 1}, {"description": "Land", "value": 2}]}, {"category": "Standard", "default": 5.0, "group": "Commander", "increment": 0.1, "max": 30.0, "min": 0.0, "name": "COM_KILL_DISARM", "shortDesc": "Timeout value for disarming when kill switch is engaged", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 3.0, "group": "Commander", "longDesc": "A non-zero, positive value specifies the timeframe in seconds within failure detector is allowed to disarm the vehicle\nif attitude exceeds the limits defined in FD_FAIL_P and FD_FAIL_R.\nThe check is not executed for flight modes that do support acrobatic maneuvers, e.g: Acro (MC/FW) and Manual (FW).\nA zero or negative value means that the check is disabled.", "max": 5.0, "min": -1.0, "name": "COM_LKDOWN_TKO", "shortDesc": "Timeout for detecting a failure after takeoff", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Action the system takes at critical battery. See also BAT_CRIT_THR and BAT_EMERGEN_THR\nfor definition of battery states.", "name": "COM_LOW_BAT_ACT", "shortDesc": "Battery failsafe mode", "type": "Int32", "values": [{"description": "Warning", "value": 0}, {"description": "Land mode", "value": 2}, {"description": "Return at critical level, land at emergency level", "value": 3}]}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE0_HASH", "shortDesc": "External mode identifier 0", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE1_HASH", "shortDesc": "External mode identifier 1", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE2_HASH", "shortDesc": "External mode identifier 2", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE3_HASH", "shortDesc": "External mode identifier 3", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE4_HASH", "shortDesc": "External mode identifier 4", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE5_HASH", "shortDesc": "External mode identifier 5", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE6_HASH", "shortDesc": "External mode identifier 6", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE7_HASH", "shortDesc": "External mode identifier 7", "type": "Int32", "volatile": true}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "By default disabled for safety reasons", "name": "COM_MODE_ARM_CHK", "shortDesc": "Allow external mode registration while armed", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "If set, enables the actuator test interface via MAVLink (ACTUATOR_TEST), that\nallows spinning the motors and moving the servos for testing purposes.", "name": "COM_MOT_TEST_EN", "shortDesc": "Enable Actuator Testing", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 5.0, "group": "Commander", "increment": 0.01, "max": 60.0, "min": 0.0, "name": "COM_OBC_LOSS_T", "shortDesc": "Time-out to wait when onboard computer connection is lost before warning about loss connection", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The offboard loss failsafe will only be entered after a timeout,\nset by COM_OF_LOSS_T in seconds.", "name": "COM_OBL_RC_ACT", "shortDesc": "Set offboard loss failsafe mode", "type": "Int32", "values": [{"description": "Position mode", "value": 0}, {"description": "Altitude mode", "value": 1}, {"description": "Stabilized", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Land mode", "value": 4}, {"description": "Hold mode", "value": 5}, {"description": "Terminate", "value": 6}, {"description": "Disarm", "value": 7}]}, {"category": "Standard", "default": 1.0, "group": "Commander", "increment": 0.01, "longDesc": "See COM_OBL_RC_ACT to configure action.", "max": 60.0, "min": 0.0, "name": "COM_OF_LOSS_T", "shortDesc": "Time-out to wait when offboard connection is lost before triggering offboard lost action", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "name": "COM_PARACHUTE", "shortDesc": "Expect and require a healthy MAVLink parachute system", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "This sets the flight mode that will be used if navigation accuracy is no longer adequate for position control in manual Position mode.", "name": "COM_POSCTL_NAVL", "shortDesc": "Position mode navigation loss response", "type": "Int32", "values": [{"description": "Altitude mode", "value": 0}, {"description": "Land mode (descend)", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "longDesc": "This is the horizontal position error (EPH) threshold that will trigger a failsafe.\nIf the previous position error was below this threshold, there is an additional\nfactor of 2.5 applied (threshold for invalidation 2.5 times the one for validation).\nOnly used for multicopters and VTOLs in hover mode.\nIndependent from estimator positioning data timeout threshold (see EKF2_NOAID_TOUT).\nSet to -1 to disable.", "max": 400.0, "min": -1.0, "name": "COM_POS_FS_EPH", "shortDesc": "Horizontal position error threshold for hovering systems", "type": "Float", "units": "m"}, {"category": "Standard", "default": 3, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when the estimated position has an accuracy below the specified threshold.\nSee COM_POS_LOW_EPH to set the failsafe threshold.\nThe failsafe action is only executed if the vehicle is in auto mission or auto loiter mode,\notherwise it is only a warning.", "name": "COM_POS_LOW_ACT", "shortDesc": "Low position accuracy action", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold", "value": 2}, {"description": "Return", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land", "value": 5}]}, {"category": "Standard", "default": -1.0, "group": "Commander", "longDesc": "This triggers the action specified in COM_POS_LOW_ACT if the estimated position accuracy is below this threshold.\nLocal position has to be still declared valid, which requires some kind of velocity aiding or large dead-reckoning time (EKF2_NOAID_TOUT),\nand a high failsafe threshold (COM_POS_FS_EPH).\nSet to -1 to disable.", "max": 1000.0, "min": -1.0, "name": "COM_POS_LOW_EPH", "shortDesc": "Low position accuracy failsafe threshold", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This configures a check to verify the expected number of 5V rail power supplies are present. By default only one is expected.\nNote: CBRK_SUPPLY_CHK disables all power checks including this one.", "max": 4, "min": 0, "name": "COM_POWER_COUNT", "shortDesc": "Required number of redundant power modules", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Condition to enter the prearmed state, an intermediate state between disarmed and armed\nin which non-throttling actuators are active.", "name": "COM_PREARM_MODE", "shortDesc": "Condition to enter prearmed mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Safety button", "value": 1}, {"description": "Always", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "name": "COM_QC_ACT", "shortDesc": "Set action after a quadchute", "type": "Int32", "values": [{"description": "Warning only", "value": -1}, {"description": "Return mode", "value": 0}, {"description": "Land mode", "value": 1}, {"description": "Hold mode", "value": 2}]}, {"category": "Standard", "default": 95.0, "group": "Commander", "increment": 1.0, "longDesc": "The check fails if the RAM usage is above this threshold.\nA negative value disables the check.", "max": 100.0, "min": -1.0, "name": "COM_RAM_MAX", "shortDesc": "Maximum allowed RAM usage to pass checks", "type": "Float", "units": "%"}, {"bitmask": [{"description": "Mission", "index": 0}, {"description": "Hold", "index": 1}, {"description": "Offboard", "index": 2}], "category": "Standard", "default": 0, "group": "Commander", "longDesc": "Specify modes in which RC loss is ignored and the failsafe action not triggered.", "max": 7, "min": 0, "name": "COM_RCL_EXCEPT", "shortDesc": "RC loss exceptions", "type": "Int32"}, {"category": "Standard", "default": 1000, "group": "Commander", "longDesc": "The default value of 1000 requires the stick to be held in the arm or disarm position for 1 second.", "max": 1500, "min": 100, "name": "COM_RC_ARM_HYST", "shortDesc": "RC input arm/disarm command duration", "type": "Int32", "units": "ms"}, {"category": "Standard", "default": 3, "group": "Commander", "longDesc": "A value of 0 enables RC transmitter control (only). A valid RC transmitter calibration is required.\nA value of 1 allows joystick control only. RC input handling and the associated checks are disabled.\nA value of 2 allows either RC Transmitter or Joystick input. The first valid input is used, will fallback to other sources if the input stream becomes invalid.\nA value of 3 allows either input from RC or joystick. The first available source is selected and used until reboot.\nA value of 4 ignores any stick input.", "max": 4, "min": 0, "name": "COM_RC_IN_MODE", "shortDesc": "RC control input mode", "type": "Int32", "values": [{"description": "RC Transmitter only", "value": 0}, {"description": "Joystick only", "value": 1}, {"description": "RC and Joystick with fallback", "value": 2}, {"description": "RC or Joystick keep first", "value": 3}, {"description": "Stick input disabled", "value": 4}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Commander", "increment": 0.1, "longDesc": "The time in seconds without a new setpoint from RC or Joystick, after which the connection is considered lost.\nThis must be kept short as the vehicle will use the last supplied setpoint until the timeout triggers.\nEnsure the value is not set lower than the update interval of the RC or Joystick.", "max": 35.0, "min": 0.0, "name": "COM_RC_LOSS_T", "shortDesc": "Manual control loss timeout", "type": "Float", "units": "s"}, {"bitmask": [{"description": "Enable override during auto modes (except for in critical battery reaction)", "index": 0}, {"description": "Enable override during offboard mode", "index": 1}], "category": "Standard", "default": 1, "group": "Commander", "longDesc": "When RC stick override is enabled, moving the RC sticks more than COM_RC_STICK_OV\nimmediately gives control back to the pilot by switching to Position mode and\nif position is unavailable Altitude mode.\nNote: Only has an effect on multicopters, and VTOLs in multicopter mode.", "max": 3, "min": 0, "name": "COM_RC_OVERRIDE", "shortDesc": "Enable RC stick override of auto and/or offboard modes", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 0, "default": 30.0, "group": "Commander", "increment": 0.05, "longDesc": "If COM_RC_OVERRIDE is enabled and the joystick input is moved more than this threshold\nthe autopilot the pilot takes over control.", "max": 80.0, "min": 5.0, "name": "COM_RC_STICK_OV", "shortDesc": "RC stick override threshold", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "increment": 0.1, "longDesc": "The minimal time from arming the motors until moving the vehicle is possible is COM_SPOOLUP_TIME seconds.\nGoal:\n- Motors and propellers spool up to idle speed before getting commanded to spin faster\n- Timeout for ESCs and smart batteries to successfulyy do failure checks\ne.g. for stuck rotors before the vehicle is off the ground", "max": 30.0, "min": 0.0, "name": "COM_SPOOLUP_TIME", "shortDesc": "Enforced delay between arming and further navigation", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The mode transition after TAKEOFF has completed successfully.", "name": "COM_TAKEOFF_ACT", "shortDesc": "Action after TAKEOFF has been accepted", "type": "Int32", "values": [{"description": "Hold", "value": 0}, {"description": "Mission (if valid)", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Allows to start the vehicle by throwing it into the air.", "name": "COM_THROW_EN", "shortDesc": "Enable throw-start", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "increment": 0.1, "longDesc": "When the throw launch is enabled, the drone will only allow motors to spin after this speed\nis exceeded before detecting the freefall. This is a safety feature to ensure the drone does\nnot turn on after accidental drop or a rapid movement before the throw.\nSet to 0 to disable.", "min": 0.0, "name": "COM_THROW_SPEED", "shortDesc": "Minimum speed for the throw start", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "longDesc": "This is the horizontal velocity error (EVH) threshold that will trigger a failsafe.\nThe default is appropriate for a multicopter. Can be increased for a fixed-wing.\nIf the previous velocity error was below this threshold, there is an additional\nfactor of 2.5 applied (threshold for invalidation 2.5 times the one for validation).", "min": 0.0, "name": "COM_VEL_FS_EVH", "shortDesc": "Horizontal velocity error threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Commander", "increment": 0.1, "longDesc": "Wind speed threshold above which an automatic failsafe action is triggered.\nFailsafe action can be specified with COM_WIND_MAX_ACT.", "min": -1.0, "name": "COM_WIND_MAX", "shortDesc": "High wind speed failsafe threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when a wind speed above the specified threshold is detected.\nSee COM_WIND_MAX to set the failsafe threshold.\nIf enabled, it is not possible to resume the mission or switch to any auto mode other than\nRTL or Land if this threshold is exceeded. Taking over in any manual\nmode is still possible.", "name": "COM_WIND_MAX_ACT", "shortDesc": "High wind failsafe mode", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold", "value": 2}, {"description": "Return", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Commander", "increment": 0.1, "longDesc": "A warning is triggered if the currently estimated wind speed is above this value.\nWarning is sent periodically (every 1 minute).\nSet to -1 to disable.", "min": -1.0, "name": "COM_WIND_WARN", "shortDesc": "Wind speed warning threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The GCS connection loss failsafe will only be entered after a timeout,\nset by COM_DL_LOSS_T in seconds. Once the timeout occurs the selected\naction will be executed.", "max": 6, "min": 0, "name": "NAV_DLL_ACT", "shortDesc": "Set GCS connection loss failsafe mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Hold mode", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Terminate", "value": 5}, {"description": "Disarm", "value": 6}]}, {"category": "Standard", "default": 2, "group": "Commander", "longDesc": "The RC loss failsafe will only be entered after a timeout,\nset by COM_RC_LOSS_T in seconds. If RC input checks have been disabled\nby setting the COM_RC_IN_MODE param it will not be triggered.", "max": 6, "min": 1, "name": "NAV_RCL_ACT", "shortDesc": "Set RC loss failsafe mode", "type": "Int32", "values": [{"description": "Hold mode", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Terminate", "value": 5}, {"description": "Disarm", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "max": 0.5, "min": 0.0, "name": "EKF2_ABIAS_INIT", "rebootRequired": true, "shortDesc": "1-sigma IMU accelerometer switch-on bias", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "EKF2", "longDesc": "If the magnitude of the IMU accelerometer vector exceeds this value, the EKF accel bias state estimation will be inhibited. This reduces the adverse effect of high manoeuvre accelerations and IMU nonlinerity and scale factor errors on the accel bias estimates.", "max": 200.0, "min": 20.0, "name": "EKF2_ABL_ACCLIM", "shortDesc": "Maximum IMU accel magnitude that allows IMU bias learning", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "If the magnitude of the IMU angular rate vector exceeds this value, the EKF accel bias state estimation will be inhibited. This reduces the adverse effect of rapid rotation rates and associated errors on the accel bias estimates.", "max": 20.0, "min": 2.0, "name": "EKF2_ABL_GYRLIM", "shortDesc": "Maximum IMU gyro angular rate magnitude that allows IMU bias learning", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "EKF2", "longDesc": "The ekf accel bias states will be limited to within a range equivalent to +- of this value.", "max": 0.8, "min": 0.0, "name": "EKF2_ABL_LIM", "shortDesc": "Accelerometer bias learning limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "The vector magnitude of angular rate and acceleration used to check if learning should be inhibited has a peak hold filter applied to it with an exponential decay. This parameter controls the time constant of the decay.", "max": 1.0, "min": 0.1, "name": "EKF2_ABL_TAU", "shortDesc": "Accel bias learning inhibit time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.003, "group": "EKF2", "max": 0.01, "min": 0.0, "name": "EKF2_ACC_B_NOISE", "shortDesc": "Process noise for IMU accelerometer bias prediction", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.35, "group": "EKF2", "max": 1.0, "min": 0.01, "name": "EKF2_ACC_NOISE", "shortDesc": "Accelerometer noise for covariance prediction", "type": "Float", "units": "m/s^2"}, {"bitmask": [{"description": "Horizontal position", "index": 0}, {"description": "Vertical position", "index": 1}], "category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Horizontal position fusion 1 : Vertical position fusion", "max": 3, "min": 0, "name": "EKF2_AGP_CTRL", "shortDesc": "Aux global position (AGP) sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_AGP_DELAY", "rebootRequired": true, "shortDesc": "Aux global position estimator delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_AGP_GATE", "shortDesc": "Gate size for aux global position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.9, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_AGP_NOISE", "shortDesc": "Measurement noise for aux global position measurements", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "EKF2", "max": 0.5, "min": 0.0, "name": "EKF2_ANGERR_INIT", "rebootRequired": true, "shortDesc": "1-sigma tilt angle uncertainty after gravity vector alignment", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "longDesc": "Airspeed data is fused for wind estimation if above this threshold. Set to 0 to disable airspeed fusion. For reliable wind estimation both sideslip (see EKF2_FUSE_BETA) and airspeed fusion should be enabled. Only applies to fixed-wing vehicles (or VTOLs in fixed-wing mode).", "min": 0.0, "name": "EKF2_ARSP_THR", "shortDesc": "Airspeed fusion threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "max": 50.0, "min": 5.0, "name": "EKF2_ASPD_MAX", "shortDesc": "Maximum airspeed used for baro static pressure compensation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_ASP_DELAY", "rebootRequired": true, "shortDesc": "Airspeed measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_AVEL_DELAY", "rebootRequired": true, "shortDesc": "Auxiliary Velocity Estimate delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "If this parameter is enabled then the estimator will make use of the barometric height measurements to estimate its height in addition to other height sources (if activated).", "name": "EKF2_BARO_CTRL", "shortDesc": "Barometric sensor height aiding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_BARO_DELAY", "rebootRequired": true, "shortDesc": "Barometer measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_BARO_GATE", "shortDesc": "Gate size for barometric and GPS height fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.5, "group": "EKF2", "max": 15.0, "min": 0.01, "name": "EKF2_BARO_NOISE", "shortDesc": "Measurement noise for barometric altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by bluff body drag along the forward/reverse axis when flying a multi-copter which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed squared. The predicted drag from the rotors is specified separately by the EKF2_MCOEF parameter. Set this parameter to zero to turn off the bluff body drag model for this axis.", "max": 200.0, "min": 0.0, "name": "EKF2_BCOEF_X", "shortDesc": "X-axis ballistic coefficient used for multi-rotor wind estimation", "type": "Float", "units": "kg/m^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by bluff body drag along the right/left axis when flying a multi-copter, which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed squared. The predicted drag from the rotors is specified separately by the EKF2_MCOEF parameter. Set this parameter to zero to turn off the bluff body drag model for this axis.", "max": 200.0, "min": 0.0, "name": "EKF2_BCOEF_Y", "shortDesc": "Y-axis ballistic coefficient used for multi-rotor wind estimation", "type": "Float", "units": "kg/m^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_BETA_GATE", "shortDesc": "Gate size for synthetic sideslip fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 1.0, "min": 0.1, "name": "EKF2_BETA_NOISE", "shortDesc": "Noise for synthetic sideslip fusion", "type": "Float", "units": "m/s"}, {"bitmask": [{"description": "use geo_lookup declination", "index": 0}, {"description": "save EKF2_MAG_DECL on disarm", "index": 1}], "category": "Standard", "default": 3, "group": "EKF2", "longDesc": "Set bits in the following positions to enable functions. 0 : Set to true to use the declination from the geo_lookup library when the GPS position becomes available, set to false to always use the EKF2_MAG_DECL value. 1 : Set to true to save the EKF2_MAG_DECL parameter to the value returned by the EKF when the vehicle disarms.", "max": 3, "min": 0, "name": "EKF2_DECL_TYPE", "rebootRequired": true, "shortDesc": "Integer bitmask controlling handling of magnetic declination", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 200.0, "group": "EKF2", "longDesc": "Defines the delay between the current time and the delayed-time horizon. This value should be at least as large as the largest EKF2_XXX_DELAY parameter.", "max": 1000.0, "min": 0.0, "name": "EKF2_DELAY_MAX", "rebootRequired": true, "shortDesc": "Maximum delay of all the aiding sensors", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Activate wind speed estimation using specific-force measurements and a drag model defined by EKF2_BCOEF_[XY] and EKF2_MCOEF. Only use on vehicles that have their thrust aligned with the Z axis and no thrust in the XY plane.", "name": "EKF2_DRAG_CTRL", "shortDesc": "Multirotor wind estimation selection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 2.5, "group": "EKF2", "longDesc": "Used by the multi-rotor specific drag force model. Increasing this makes the multi-rotor wind estimates adjust more slowly.", "max": 10.0, "min": 0.5, "name": "EKF2_DRAG_NOISE", "shortDesc": "Specific drag force observation noise variance", "type": "Float", "units": "(m/s^2)^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.4, "group": "EKF2", "max": 5.0, "min": 0.5, "name": "EKF2_EAS_NOISE", "shortDesc": "Measurement noise for airspeed fusion", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "EKF2", "name": "EKF2_EN", "shortDesc": "EKF2 enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.05, "name": "EKF2_EVA_NOISE", "shortDesc": "Measurement noise for vision angle measurements", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_EVP_GATE", "shortDesc": "Gate size for vision position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_EVP_NOISE", "shortDesc": "Measurement noise for vision position measurements", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_EVV_GATE", "shortDesc": "Gate size for vision velocity estimate fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_EVV_NOISE", "shortDesc": "Measurement noise for vision velocity measurements", "type": "Float", "units": "m/s"}, {"bitmask": [{"description": "Horizontal position", "index": 0}, {"description": "Vertical position", "index": 1}, {"description": "3D velocity", "index": 2}, {"description": "Yaw", "index": 3}], "category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Horizontal position fusion 1 : Vertical position fusion 2 : 3D velocity fusion 3 : Yaw", "max": 15, "min": 0, "name": "EKF2_EV_CTRL", "shortDesc": "External vision (EV) sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_EV_DELAY", "rebootRequired": true, "shortDesc": "Vision Position Estimator delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "If set to 0 (default) the measurement noise is taken from the vision message and the EV noise parameters are used as a lower bound. If set to 1 the observation noise is set from the parameters directly,", "name": "EKF2_EV_NOISE_MD", "shortDesc": "External vision (EV) noise mode", "type": "Int32", "values": [{"description": "EV reported variance (parameter lower bound)", "value": 0}, {"description": "EV noise parameters", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_X", "shortDesc": "X position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_Y", "shortDesc": "Y position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_Z", "shortDesc": "Z position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0, "group": "EKF2", "longDesc": "External vision will only be started and fused if the quality metric is above this threshold. The quality metric is a completely optional field provided by some VIO systems.", "max": 100, "min": 0, "name": "EKF2_EV_QMIN", "shortDesc": "External vision (EV) minimum quality (optional)", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "For reliable wind estimation both sideslip and airspeed fusion (see EKF2_ARSP_THR) should be enabled. Only applies to vehicles in fixed-wing mode or with airspeed fusion active. Note: side slip fusion is currently not supported for tailsitters.", "name": "EKF2_FUSE_BETA", "shortDesc": "Enable synthetic sideslip fusion", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "max": 0.2, "min": 0.0, "name": "EKF2_GBIAS_INIT", "rebootRequired": true, "shortDesc": "1-sigma IMU gyro switch-on bias", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "EKF2", "longDesc": "Sets the value of deadzone applied to negative baro innovations. Deadzone is enabled when EKF2_GND_EFF_DZ > 0.", "max": 10.0, "min": 0.0, "name": "EKF2_GND_EFF_DZ", "shortDesc": "Baro deadzone range for height fusion", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "EKF2", "longDesc": "Sets the maximum distance to the ground level where negative baro innovations are expected.", "max": 5.0, "min": 0.0, "name": "EKF2_GND_MAX_HGT", "shortDesc": "Height above ground level for ground effect zone", "type": "Float", "units": "m"}, {"bitmask": [{"description": "Sat count (EKF2_REQ_NSATS)", "index": 0}, {"description": "PDOP (EKF2_REQ_PDOP)", "index": 1}, {"description": "EPH (EKF2_REQ_EPH)", "index": 2}, {"description": "EPV (EKF2_REQ_EPV)", "index": 3}, {"description": "Speed accuracy (EKF2_REQ_SACC)", "index": 4}, {"description": "Horizontal position drift (EKF2_REQ_HDRIFT)", "index": 5}, {"description": "Vertical position drift (EKF2_REQ_VDRIFT)", "index": 6}, {"description": "Horizontal speed offset (EKF2_REQ_HDRIFT)", "index": 7}, {"description": "Vertical speed offset (EKF2_REQ_VDRIFT)", "index": 8}, {"description": "Spoofing", "index": 9}], "category": "Standard", "default": 1023, "group": "EKF2", "longDesc": "Each threshold value is defined by the parameter indicated next to the check. Drift and offset checks only run when the vehicle is on ground and stationary.", "max": 1023, "min": 0, "name": "EKF2_GPS_CHECK", "shortDesc": "Integer bitmask controlling GPS checks", "type": "Int32"}, {"bitmask": [{"description": "Lon/lat", "index": 0}, {"description": "Altitude", "index": 1}, {"description": "3D velocity", "index": 2}, {"description": "Dual antenna heading", "index": 3}], "category": "Standard", "default": 7, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Longitude and latitude fusion 1 : Altitude fusion 2 : 3D velocity fusion 3 : Dual antenna heading fusion", "max": 15, "min": 0, "name": "EKF2_GPS_CTRL", "shortDesc": "GNSS sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 110.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_GPS_DELAY", "rebootRequired": true, "shortDesc": "GPS measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward (roll) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_X", "shortDesc": "X position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Right (pitch) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_Y", "shortDesc": "Y position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Down (yaw) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_Z", "shortDesc": "Z position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_GPS_P_GATE", "shortDesc": "Gate size for GNSS position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "max": 10.0, "min": 0.01, "name": "EKF2_GPS_P_NOISE", "shortDesc": "Measurement noise for GNSS position", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_GPS_V_GATE", "shortDesc": "Gate size for GNSS velocity fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 5.0, "min": 0.01, "name": "EKF2_GPS_V_NOISE", "shortDesc": "Measurement noise for GNSS velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 360.0, "min": 0.0, "name": "EKF2_GPS_YAW_OFF", "shortDesc": "Heading/Yaw offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "EKF2", "max": 10.0, "min": 0.1, "name": "EKF2_GRAV_NOISE", "shortDesc": "Accelerometer measurement noise for gravity based observations", "type": "Float", "units": "g0"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "EKF2", "longDesc": "If no airspeed measurements are available, the EKF-GSF AHRS calculation will assume this value of true airspeed when compensating for centripetal acceleration during turns. Set to zero to disable centripetal acceleration compensation during fixed wing flight modes.", "max": 100.0, "min": 0.0, "name": "EKF2_GSF_TAS", "shortDesc": "Default value of true airspeed used in EKF-GSF AHRS calculation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "EKF2", "longDesc": "The ekf gyro bias states will be limited to within a range equivalent to +- of this value.", "max": 0.4, "min": 0.0, "name": "EKF2_GYR_B_LIM", "shortDesc": "Gyro bias learning limit", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.001, "group": "EKF2", "max": 0.01, "min": 0.0, "name": "EKF2_GYR_B_NOISE", "shortDesc": "Process noise for IMU rate gyro bias prediction", "type": "Float", "units": "rad/s^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.015, "group": "EKF2", "max": 0.1, "min": 0.0001, "name": "EKF2_GYR_NOISE", "shortDesc": "Rate gyro noise for covariance prediction", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.6, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_HDG_GATE", "shortDesc": "Gate size for heading fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 1.0, "min": 0.01, "name": "EKF2_HEAD_NOISE", "shortDesc": "Measurement noise for magnetic heading fusion", "type": "Float", "units": "rad"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "When multiple height sources are enabled at the same time, the height estimate will always converge towards the reference height source selected by this parameter. The range sensor and vision options should only be used when for operation over a flat surface as the local NED origin will move up and down with ground level. If GPS is set as reference but altitude fusion is disabled in EKF2_GPS_CTRL, the GPS altitude is still used to initiaize the bias of the other height sensors.", "name": "EKF2_HGT_REF", "rebootRequired": true, "shortDesc": "Determines the reference source of height data used by the EKF", "type": "Int32", "values": [{"description": "Barometric pressure", "value": 0}, {"description": "GPS", "value": 1}, {"description": "Range sensor", "value": 2}, {"description": "Vision", "value": 3}]}, {"bitmask": [{"description": "Gyro Bias", "index": 0}, {"description": "Accel Bias", "index": 1}, {"description": "Gravity vector fusion", "index": 2}], "category": "Standard", "default": 7, "group": "EKF2", "max": 7, "min": 0, "name": "EKF2_IMU_CTRL", "shortDesc": "IMU control", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_X", "shortDesc": "X position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_Y", "shortDesc": "Y position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_Z", "shortDesc": "Z position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "EKF2", "name": "EKF2_LOG_VERBOSE", "shortDesc": "Verbose logging", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "The heading is assumed to be observable when the body acceleration is greater than this parameter when a global position/velocity aiding source is active.", "max": 5.0, "min": 0.0, "name": "EKF2_MAG_ACCLIM", "shortDesc": "Horizontal acceleration threshold used for heading observability check", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.0001, "group": "EKF2", "max": 0.1, "min": 0.0, "name": "EKF2_MAG_B_NOISE", "shortDesc": "Process noise for body magnetic field prediction", "type": "Float", "units": "gauss/s"}, {"bitmask": [{"description": "Strength (EKF2_MAG_CHK_STR)", "index": 0}, {"description": "Inclination (EKF2_MAG_CHK_INC)", "index": 1}, {"description": "Wait for WMM", "index": 2}], "category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Bitmask to set which check is used to decide whether the magnetometer data is valid. If GNSS data is received, the magnetic field is compared to a World Magnetic Model (WMM), otherwise an average value is used. This check is useful to reject occasional hard iron disturbance. Set bits to 1 to enable checks. Checks enabled by the following bit positions 0 : Magnetic field strength. Set tolerance using EKF2_MAG_CHK_STR 1 : Magnetic field inclination. Set tolerance using EKF2_MAG_CHK_INC 2 : Wait for GNSS to find the theoretical strength and inclination using the WMM", "max": 7, "min": 0, "name": "EKF2_MAG_CHECK", "shortDesc": "Magnetic field strength test selection", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "longDesc": "Maximum allowed deviation from the expected magnetic field inclination to pass the check.", "max": 90.0, "min": 0.0, "name": "EKF2_MAG_CHK_INC", "shortDesc": "Magnetic field inclination check tolerance", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "longDesc": "Maximum allowed deviation from the expected magnetic field strength to pass the check.", "max": 1.0, "min": 0.0, "name": "EKF2_MAG_CHK_STR", "shortDesc": "Magnetic field strength check tolerance", "type": "Float", "units": "gauss"}, {"category": "System", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "name": "EKF2_MAG_DECL", "shortDesc": "Magnetic declination", "type": "Float", "units": "deg", "volatile": true}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_MAG_DELAY", "rebootRequired": true, "shortDesc": "Magnetometer measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.001, "group": "EKF2", "max": 0.1, "min": 0.0, "name": "EKF2_MAG_E_NOISE", "shortDesc": "Process noise for earth magnetic field prediction", "type": "Float", "units": "gauss/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_MAG_GATE", "shortDesc": "Gate size for magnetometer XYZ component fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "EKF2", "max": 1.0, "min": 0.001, "name": "EKF2_MAG_NOISE", "shortDesc": "Measurement noise for magnetometer 3-axis fusion", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Integer controlling the type of magnetometer fusion used - magnetic heading or 3-component vector. The fusion of magnetometer data as a three component vector enables vehicle body fixed hard iron errors to be learned, but requires a stable earth field. If set to 'Automatic' magnetic heading fusion is used when on-ground and 3-axis magnetic field fusion in-flight. If set to 'Magnetic heading' magnetic heading fusion is used at all times. If set to 'None' the magnetometer will not be used under any circumstance. If no external source of yaw is available, it is possible to use post-takeoff horizontal movement combined with GNSS velocity measurements to align the yaw angle. If set to 'Init' the magnetometer is only used to initalize the heading.", "name": "EKF2_MAG_TYPE", "rebootRequired": true, "shortDesc": "Type of magnetometer fusion", "type": "Int32", "values": [{"description": "Automatic", "value": 0}, {"description": "Magnetic heading", "value": 1}, {"description": "None", "value": 5}, {"description": "Init", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by the propellers when flying a multi-copter, which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed not speed squared and is produced because some of the air velocity normal to the propeller axis of rotation is lost when passing through the rotor disc. This changes the momentum of the flow which creates a drag reaction force. When comparing un-ducted propellers of the same diameter, the effect is roughly proportional to the area of the propeller blades when viewed side on and changes with propeller selection. Momentum drag is significantly higher for ducted rotors. To account for the drag produced by the body which scales with speed squared, see documentation for the EKF2_BCOEF_X and EKF2_BCOEF_Y parameters. Set this parameter to zero to turn off the momentum drag model for both axis.", "max": 1.0, "min": 0.0, "name": "EKF2_MCOEF", "shortDesc": "Propeller momentum drag coefficient for multi-rotor wind estimation", "type": "Float", "units": "1/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "If the vehicle is on ground, is not moving as determined by the motion test and the range finder is returning invalid or no data, then an assumed range value of EKF2_MIN_RNG will be used by the terrain estimator so that a terrain height estimate is available at the start of flight in situations where the range finder may be inside its minimum measurements distance when on ground.", "min": 0.01, "name": "EKF2_MIN_RNG", "shortDesc": "Expected range finder reading when on ground", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Maximum number of IMUs to use for Multi-EKF. Set 0 to disable. Requires SENS_IMU_MODE 0.", "max": 4, "min": 0, "name": "EKF2_MULTI_IMU", "rebootRequired": true, "shortDesc": "Multi-EKF IMUs", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Maximum number of magnetometers to use for Multi-EKF. Set 0 to disable. Requires SENS_MAG_MODE 0.", "max": 4, "min": 0, "name": "EKF2_MULTI_MAG", "rebootRequired": true, "shortDesc": "Multi-EKF Magnetometers", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "EKF2", "max": 50.0, "min": 0.5, "name": "EKF2_NOAID_NOISE", "shortDesc": "Measurement noise for non-aiding position hold", "type": "Float", "units": "m"}, {"category": "Standard", "default": 5000000, "group": "EKF2", "longDesc": "Maximum lapsed time from last fusion of measurements that constrain velocity drift before the EKF will report the horizontal nav solution as invalid", "max": 10000000, "min": 500000, "name": "EKF2_NOAID_TOUT", "shortDesc": "Maximum inertial dead-reckoning time", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Enable optical flow fusion.", "name": "EKF2_OF_CTRL", "shortDesc": "Optical flow aiding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "longDesc": "Assumes measurement is timestamped at trailing edge of integration period", "max": 300.0, "min": 0.0, "name": "EKF2_OF_DELAY", "rebootRequired": true, "shortDesc": "Optical flow measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_OF_GATE", "shortDesc": "Gate size for optical flow fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Auto: use gyro from optical flow message if available, internal gyro otherwise. Internal: always use internal gyro", "name": "EKF2_OF_GYR_SRC", "shortDesc": "Optical flow angular rate compensation source", "type": "Int32", "values": [{"description": "Auto", "value": 0}, {"description": "Internal", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "Measurement noise for the optical flow sensor when it's reported quality metric is at the minimum", "min": 0.05, "name": "EKF2_OF_N_MAX", "shortDesc": "Optical flow maximum noise", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "EKF2", "longDesc": "Measurement noise for the optical flow sensor when it's reported quality metric is at the maximum", "min": 0.05, "name": "EKF2_OF_N_MIN", "shortDesc": "Optical flow minimum noise", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_X", "shortDesc": "X position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_Y", "shortDesc": "Y position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_Z", "shortDesc": "Z position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Optical Flow data will only be used in air if the sensor reports a quality metric >= EKF2_OF_QMIN", "max": 255, "min": 0, "name": "EKF2_OF_QMIN", "shortDesc": "In air optical flow minimum quality", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Optical Flow data will only be used on the ground if the sensor reports a quality metric >= EKF2_OF_QMIN_GND", "max": 255, "min": 0, "name": "EKF2_OF_QMIN_GND", "shortDesc": "On ground optical flow minimum quality", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a negative wind relative velocity along the X body axis. If the baro height estimate rises during backwards flight, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_XN", "shortDesc": "Static pressure position error coefficient for the negative X axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a positive wind relative velocity along the X body axis. If the baro height estimate rises during forward flight, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_XP", "shortDesc": "Static pressure position error coefficient for the positive X axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the negative Y (LH) body axis. If the baro height estimate rises during sideways flight to the left, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_YN", "shortDesc": "Pressure position error coefficient for the negative Y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the positive Y (RH) body axis. If the baro height estimate rises during sideways flight to the right, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_YP", "shortDesc": "Pressure position error coefficient for the positive Y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the Z body axis.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_Z", "shortDesc": "Static pressure position error coefficient for the Z axis", "type": "Float"}, {"category": "Standard", "default": 10000, "group": "EKF2", "longDesc": "EKF prediction period in microseconds. This should ideally be an integer multiple of the IMU time delta. Actual filter update will be an integer multiple of IMU update.", "max": 20000, "min": 1000, "name": "EKF2_PREDICT_US", "shortDesc": "EKF prediction period", "type": "Int32", "units": "us"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "max": 100.0, "min": 2.0, "name": "EKF2_REQ_EPH", "shortDesc": "Required EPH to use GPS", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 100.0, "min": 2.0, "name": "EKF2_REQ_EPV", "shortDesc": "Required EPV to use GPS", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "EKF2", "longDesc": "Minimum continuous period without GPS failure required to mark a healthy GPS status. It can be reduced to speed up initialization, but it's recommended to keep this unchanged for a vehicle.", "min": 0.1, "name": "EKF2_REQ_GPS_H", "rebootRequired": true, "shortDesc": "Required GPS health time on startup", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "max": 1.0, "min": 0.1, "name": "EKF2_REQ_HDRIFT", "shortDesc": "Maximum horizontal drift speed to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 6, "group": "EKF2", "max": 12, "min": 4, "name": "EKF2_REQ_NSATS", "shortDesc": "Required satellite count to use GPS", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "EKF2", "max": 5.0, "min": 1.5, "name": "EKF2_REQ_PDOP", "shortDesc": "Maximum PDOP to use GPS", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "max": 5.0, "min": 0.5, "name": "EKF2_REQ_SACC", "shortDesc": "Required speed accuracy to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "max": 1.5, "min": 0.1, "name": "EKF2_REQ_VDRIFT", "shortDesc": "Maximum vertical drift speed to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 5.0, "group": "EKF2", "longDesc": "If the vehicle absolute altitude exceeds this value then the estimator will not fuse range measurements to estimate its height. This only applies when conditional range aid mode is activated (EKF2_RNG_CTRL = 1).", "max": 10.0, "min": 1.0, "name": "EKF2_RNG_A_HMAX", "shortDesc": "Maximum height above ground allowed for conditional range aid mode", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "A lower value means HAGL needs to be more stable in order to use range finder for height estimation in range aid mode", "max": 5.0, "min": 0.1, "name": "EKF2_RNG_A_IGATE", "shortDesc": "Gate size used for innovation consistency checks for range aid fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "If the vehicle horizontal speed exceeds this value then the estimator will not fuse range measurements to estimate its height. This only applies when conditional range aid mode is activated (EKF2_RNG_CTRL = 1).", "max": 2.0, "min": 0.1, "name": "EKF2_RNG_A_VMAX", "shortDesc": "Maximum horizontal velocity allowed for conditional range aid mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "WARNING: Range finder measurements are less reliable and can experience unexpected errors. For these reasons, if accurate control of height relative to ground is required, it is recommended to use the MPC_ALT_MODE parameter instead, unless baro errors are severe enough to cause problems with landing and takeoff. If this parameter is enabled then the estimator will make use of the range finder measurements to estimate its height in addition to other height sources (if activated). Range sensor aiding can be enabled (i.e.: always use) or set in \"conditional\" mode. Conditional mode: This enables the range finder to be used during low speed (< EKF2_RNG_A_VMAX) and low altitude (< EKF2_RNG_A_HMAX) operation, eg takeoff and landing, where baro interference from rotor wash is excessive and can corrupt EKF state estimates. It is intended to be used where a vertical takeoff and landing is performed, and horizontal flight does not occur until above EKF2_RNG_A_HMAX.", "name": "EKF2_RNG_CTRL", "shortDesc": "Range sensor height aiding", "type": "Int32", "values": [{"description": "Disable range fusion", "value": 0}, {"description": "Enabled (conditional mode)", "value": 1}, {"description": "Enabled", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_RNG_DELAY", "rebootRequired": true, "shortDesc": "Range finder measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Limit for fog detection. If the range finder measures a distance greater than this value, the measurement is considered to not be blocked by fog or rain. If there's a jump from larger than RNG_FOG to smaller than EKF2_RNG_FOG, the measurement may gets rejected. 0 - disabled", "max": 20.0, "min": 0.0, "name": "EKF2_RNG_FOG", "shortDesc": "Maximum distance at which the range finder could detect fog (m)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_RNG_GATE", "shortDesc": "Gate size for range finder fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "To be used, the time derivative of the distance sensor measurements projected on the vertical axis needs to be statistically consistent with the estimated vertical velocity of the drone. Decrease this value to make the filter more robust against range finder faulty data (stuck, reflections, ...). Note: tune the range finder noise parameters (EKF2_RNG_NOISE and EKF2_RNG_SFE) before tuning this gate.", "max": 5.0, "min": 0.1, "name": "EKF2_RNG_K_GATE", "shortDesc": "Gate size used for range finder kinematic consistency check", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "min": 0.01, "name": "EKF2_RNG_NOISE", "shortDesc": "Measurement noise for range finder fusion", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "max": 0.75, "min": -0.75, "name": "EKF2_RNG_PITCH", "shortDesc": "Range sensor pitch offset", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_X", "shortDesc": "X position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_Y", "shortDesc": "Y position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_Z", "shortDesc": "Z position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "Minimum duration during which the reported range finder signal quality needs to be non-zero in order to be declared valid (s)", "max": 5.0, "min": 0.1, "name": "EKF2_RNG_QLTY_T", "shortDesc": "Minumum range validity period", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0.05, "group": "EKF2", "longDesc": "Specifies the increase in range finder noise with range.", "max": 0.2, "min": 0.0, "name": "EKF2_RNG_SFE", "shortDesc": "Range finder range dependent noise scaler", "type": "Float", "units": "m/m"}, {"category": "Standard", "default": 0.2, "group": "EKF2", "longDesc": "EKF2 instances have to be better than the selected by at least this amount before their relative score can be reduced.", "name": "EKF2_SEL_ERR_RED", "shortDesc": "Selector error reduce threshold", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "EKF2 selector acceleration error threshold for comparing accelerometers. Acceleration vector differences larger than this will result in accumulated velocity error.", "name": "EKF2_SEL_IMU_ACC", "shortDesc": "Selector acceleration threshold", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "default": 15.0, "group": "EKF2", "longDesc": "EKF2 selector maximum accumulated angular error threshold for comparing gyros. Accumulated angular error larger than this will result in the sensor being declared faulty.", "name": "EKF2_SEL_IMU_ANG", "shortDesc": "Selector angular threshold", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 7.0, "group": "EKF2", "longDesc": "EKF2 selector angular rate error threshold for comparing gyros. Angular rate vector differences larger than this will result in accumulated angular error.", "name": "EKF2_SEL_IMU_RAT", "shortDesc": "Selector angular rate threshold", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 2.0, "group": "EKF2", "longDesc": "EKF2 selector maximum accumulated velocity threshold for comparing accelerometers. Accumulated velocity error larger than this will result in the sensor being declared faulty.", "name": "EKF2_SEL_IMU_VEL", "shortDesc": "Selector angular threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Use for vehicles where the measured body Z magnetic field is subject to strong magnetic interference. For magnetic heading fusion the magnetometer Z measurement will be replaced by a synthetic value calculated using the knowledge of the 3D magnetic field vector at the location of the drone. Therefore, this parameter will only have an effect if the global position of the drone is known. For 3D mag fusion the magnetometer Z measurement will simply be ignored instead of fusing the synthetic value.", "name": "EKF2_SYNT_MAG_Z", "shortDesc": "Enable synthetic magnetometer Z component measurement", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_TAS_GATE", "shortDesc": "Gate size for TAS fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "EKF2", "longDesc": "Controls how tightly the output track the EKF states", "max": 1.0, "min": 0.1, "name": "EKF2_TAU_POS", "shortDesc": "Output predictor position time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "EKF2", "max": 1.0, "name": "EKF2_TAU_VEL", "shortDesc": "Time constant of the velocity output prediction and smoothing filter", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "min": 0.0, "name": "EKF2_TERR_GRAD", "shortDesc": "Magnitude of terrain gradient", "type": "Float", "units": "m/m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "min": 0.5, "name": "EKF2_TERR_NOISE", "shortDesc": "Terrain altitude process noise", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "max": 299792458.0, "name": "EKF2_VEL_LIM", "shortDesc": "Velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "EKF2", "longDesc": "When unaided, the wind estimate uncertainty (1-sigma, in m/s) increases by this amount every second.", "max": 1.0, "min": 0.0, "name": "EKF2_WIND_NSD", "shortDesc": "Process noise spectral density for wind velocity prediction", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "default": 0, "group": "Events", "longDesc": "Enable/disable event task for RC Loss. When enabled, an alarm tune will be\nplayed via buzzer or ESCs, if supported. The alarm will sound after a disarm,\nif the vehicle was previously armed and only if the vehicle had RC signal at\nsome point. Particularly useful for locating crashed drones without a GPS\nsensor.", "name": "EV_TSK_RC_LOSS", "rebootRequired": true, "shortDesc": "RC Loss Alarm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Events", "longDesc": "Enable/disable event task for displaying the vehicle status using arm-mounted\nLEDs. When enabled and if the vehicle supports it, LEDs will flash\nindicating various vehicle status changes. Currently PX4 has not implemented\nany specific status events.\n-", "name": "EV_TSK_STAT_DIS", "rebootRequired": true, "shortDesc": "Status Display", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "Applies to both directions in all manual modes with attitude stabilization but without altitude control", "max": 90.0, "min": 0.0, "name": "FW_MAN_P_MAX", "shortDesc": "Maximum manual pitch angle", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 45.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "Applies to both directions in all manual modes with attitude stabilization", "max": 90.0, "min": 0.0, "name": "FW_MAN_R_MAX", "shortDesc": "Maximum manual roll angle", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "This is the maximally added yaw rate setpoint from the yaw stick in any attitude controlled flight mode.\nIt is added to the yaw rate setpoint generated by the controller for turn coordination.", "min": 0.0, "name": "FW_MAN_YR_MAX", "shortDesc": "Maximum manually added yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "An airframe specific offset of the pitch setpoint in degrees, the value is\nadded to the pitch setpoint and should correspond to the pitch at\ntypical cruise speed of the airframe.", "max": 90.0, "min": -90.0, "name": "FW_PSP_OFF", "shortDesc": "Pitch setpoint offset (pitch at level flight)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 60.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_P_RMAX_NEG", "shortDesc": "Maximum negative / down pitch rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 60.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_P_RMAX_POS", "shortDesc": "Maximum positive / up pitch rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "longDesc": "This defines the latency between a pitch step input and the achieved setpoint\n(inverse to a P gain). Smaller systems may require smaller values.", "max": 1.0, "min": 0.2, "name": "FW_P_TC", "shortDesc": "Attitude pitch time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 70.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_R_RMAX", "shortDesc": "Maximum roll rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "longDesc": "This defines the latency between a roll step input and the achieved setpoint\n(inverse to a P gain). Smaller systems may require smaller values.", "max": 1.0, "min": 0.2, "name": "FW_R_TC", "shortDesc": "Attitude Roll Time Constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Attitude Control", "increment": 0.05, "max": 10.0, "min": 0.0, "name": "FW_WR_FF", "shortDesc": "Wheel steering rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "FW Attitude Control", "increment": 0.005, "longDesc": "This gain defines how much control response will result out of a steady\nstate error. It trims any constant error.", "max": 10.0, "min": 0.0, "name": "FW_WR_I", "shortDesc": "Wheel steering rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_WR_IMAX", "shortDesc": "Wheel steering rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "FW Attitude Control", "increment": 0.005, "longDesc": "This defines how much the wheel steering input will be commanded depending on the\ncurrent body angular rate error.", "max": 10.0, "min": 0.0, "name": "FW_WR_P", "shortDesc": "Wheel steering rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 0, "group": "FW Attitude Control", "longDesc": "Only enabled during automatic runway takeoff and landing.\nIn all manual modes the wheel is directly controlled with yaw stick.", "name": "FW_W_EN", "shortDesc": "Enable wheel steering controller", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "This limits the maximum wheel steering rate the controller will output (in degrees per\nsecond).", "max": 90.0, "min": 0.0, "name": "FW_W_RMAX", "shortDesc": "Maximum wheel steering rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 50.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_Y_RMAX", "shortDesc": "Maximum yaw rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Auto Landing", "increment": 0.01, "longDesc": "Sets a fraction of full flaps during landing.\nAlso applies to flaperons if enabled in the mixer/allocation.", "max": 1.0, "min": 0.0, "name": "FW_FLAPS_LND_SCL", "shortDesc": "Flaps setting during landing", "type": "Float", "units": "norm"}, {"bitmask": [{"description": "Abort if terrain is not found (only applies to mission landings)", "index": 0}, {"description": "Abort if terrain times out (after a first successful measurement)", "index": 1}], "category": "Standard", "default": 3, "group": "FW Auto Landing", "longDesc": "Terrain estimation:\nbit 0: Abort if terrain is not found\nbit 1: Abort if terrain times out (after a first successful measurement)\nThe last estimate is always used as ground, whether the last valid measurement or the land waypoint, depending on the\nselected abort criteria, until an abort condition is entered. If FW_LND_USETER == 0, these bits are ignored.\nTODO: Extend automatic abort conditions\ne.g. glide slope tracking error (horizontal and vertical)", "max": 3, "min": 0, "name": "FW_LND_ABORT", "shortDesc": "Bit mask to set the automatic landing abort conditions", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "The calibrated airspeed setpoint during landing.\nIf set <= 0, landing airspeed = FW_AIRSPD_MIN by default.", "min": -1.0, "name": "FW_LND_AIRSPD", "shortDesc": "Landing airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Typically the desired landing slope angle when landing configuration (flaps, airspeed) is enabled.\nSet this value within the vehicle's performance limits.", "max": 45.0, "min": 1.0, "name": "FW_LND_ANG", "shortDesc": "Maximum landing slope angle", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "FW Auto Landing", "longDesc": "Allows to deploy the landing configuration (flaps, landing airspeed, etc.) already in\nthe loiter-down waypoint before the final approach.\nOtherwise is enabled only in the final approach.", "name": "FW_LND_EARLYCFG", "shortDesc": "Early landing configuration deployment", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "NOTE: max(FW_LND_FLALT, FW_LND_FL_TIME * |z-velocity|) is taken as the flare altitude", "min": 0.0, "name": "FW_LND_FLALT", "shortDesc": "Landing flare altitude (relative to landing altitude)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Maximum pitch during landing flare.", "max": 45.0, "min": 0.0, "name": "FW_LND_FL_PMAX", "shortDesc": "Flare, maximum pitch", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Minimum pitch during landing flare.", "max": 15.0, "min": -5.0, "name": "FW_LND_FL_PMIN", "shortDesc": "Flare, minimum pitch", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "TECS will attempt to control the aircraft to this sink rate via pitch angle (throttle killed during flare)", "max": 2.0, "min": 0.0, "name": "FW_LND_FL_SINK", "shortDesc": "Landing flare sink rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "Multiplied by the descent rate to calculate a dynamic altitude at which\nto trigger the flare.\nNOTE: max(FW_LND_FLALT, FW_LND_FL_TIME * descent rate) is taken as the flare altitude", "max": 5.0, "min": 0.1, "name": "FW_LND_FL_TIME", "shortDesc": "Landing flare time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 2, "group": "FW Auto Landing", "longDesc": "Approach angle nudging: shifts the touchdown point laterally while keeping the approach entrance point constant\nApproach path nudging: shifts the touchdown point laterally along with the entire approach path\nThis is useful for manually adjusting the landing point in real time when map or GNSS errors cause an offset from the\ndesired landing vector. Nudging is done with yaw stick, constrained to FW_LND_TD_OFF (in meters) and the direction is\nrelative to the vehicle heading (stick deflection to the right = land point moves to the right as seen by the vehicle).", "max": 2, "min": 0, "name": "FW_LND_NUDGE", "shortDesc": "Landing touchdown nudging option", "type": "Int32", "values": [{"description": "Disable nudging", "value": 0}, {"description": "Nudge approach angle", "value": 1}, {"description": "Nudge approach path", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "FW Auto Landing", "increment": 1.0, "max": 10.0, "min": 0.0, "name": "FW_LND_TD_OFF", "shortDesc": "Maximum lateral position offset for the touchdown point", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "This is the time after the start of flaring that we expect the vehicle to touch the runway.\nAt this time, a 0.5s clamp down ramp will engage, constraining the pitch setpoint to RWTO_PSP.\nIf enabled, ensure that RWTO_PSP is configured appropriately for full gear contact on ground roll.\nSet to -1.0 to disable touchdown clamping. E.g. it may not be desirable to clamp on belly landings.\nThe touchdown time will be constrained to be greater than or equal to the flare time (FW_LND_FL_TIME).", "max": 5.0, "min": -1.0, "name": "FW_LND_TD_TIME", "shortDesc": "Landing touchdown time (since flare start)", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "The TECS altitude time constant (FW_T_ALT_TC) is multiplied by this value.", "max": 1.0, "min": 0.2, "name": "FW_LND_THRTC_SC", "shortDesc": "Altitude time constant factor for landing and low-height flight", "type": "Float", "units": ""}, {"category": "Standard", "default": 1, "group": "FW Auto Landing", "longDesc": "This is critical for detecting when to flare, and should be enabled if possible.\nIf enabled and no measurement is found within a given timeout, the landing waypoint altitude will be used OR the landing\nwill be aborted, depending on the criteria set in FW_LND_ABORT.\nIf disabled, FW_LND_ABORT terrain based criteria are ignored.", "max": 2, "min": 0, "name": "FW_LND_USETER", "shortDesc": "Use terrain estimation during landing", "type": "Int32", "values": [{"description": "Disable the terrain estimate", "value": 0}, {"description": "Use the terrain estimate to trigger the flare (only)", "value": 1}, {"description": "Calculate landing glide slope relative to the terrain estimate", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Auto Landing", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "FW_SPOILERS_LND", "shortDesc": "Spoiler landing setting", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Auto Takeoff", "increment": 0.01, "longDesc": "Sets a fraction of full flaps during take-off.\nAlso applies to flaperons if enabled in the mixer/allocation.", "max": 1.0, "min": 0.0, "name": "FW_FLAPS_TO_SCL", "shortDesc": "Flaps setting during take-off", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "FW Auto Takeoff", "increment": 0.05, "longDesc": "Launch is detected when acceleration in body forward direction is above FW_LAUN_AC_THLD for FW_LAUN_AC_T seconds.", "max": 5.0, "min": 0.0, "name": "FW_LAUN_AC_T", "shortDesc": "Trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Auto Takeoff", "increment": 0.5, "longDesc": "Launch is detected when acceleration in body forward direction is above FW_LAUN_AC_THLD for FW_LAUN_AC_T seconds.", "min": 0.0, "name": "FW_LAUN_AC_THLD", "shortDesc": "Trigger acceleration threshold", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "default": 0, "group": "FW Auto Takeoff", "longDesc": "Enables automatic launch detection based on measured acceleration. Use for hand- or catapult-launched vehicles.\nNot compatible with runway takeoff.", "name": "FW_LAUN_DETCN_ON", "shortDesc": "Fixed-wing launch detection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Auto Takeoff", "increment": 0.5, "longDesc": "Start the motor(s) this amount of seconds after launch is detected.", "max": 10.0, "min": 0.0, "name": "FW_LAUN_MOT_DEL", "shortDesc": "Motor delay", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Takeoff", "increment": 0.1, "longDesc": "The calibrated airspeed setpoint during the takeoff climbout.\nIf set <= 0, FW_AIRSPD_MIN will be set by default.", "min": -1.0, "name": "FW_TKO_AIRSPD", "shortDesc": "Takeoff Airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW Auto Takeoff", "increment": 0.5, "max": 80.0, "min": -5.0, "name": "FW_TKO_PITCH_MIN", "shortDesc": "Minimum pitch during takeoff", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 30, "group": "FW General", "longDesc": "The time the system should do open loop loiter and wait for GPS recovery\nbefore it starts descending. Set to 0 to disable. Roll angle is set to FW_GPSF_R.\nDoes only apply for fixed-wing vehicles or VTOLs with NAV_FORCE_VT set to 0.", "min": 0, "name": "FW_GPSF_LT", "shortDesc": "GPS failure loiter time", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW General", "increment": 0.5, "longDesc": "Roll angle in GPS failure loiter mode.", "max": 60.0, "min": 0.0, "name": "FW_GPSF_R", "shortDesc": "GPS failure fixed roll angle", "type": "Float", "units": "deg"}, {"bitmask": [{"description": "Alternative stick configuration (height rate on throttle stick, airspeed on pitch stick)", "index": 0}, {"description": "Enable airspeed setpoint via sticks in altitude and position flight mode", "index": 1}], "category": "Standard", "default": 2, "group": "FW General", "longDesc": "Applies in manual Position and Altitude flight modes.", "max": 3, "min": 0, "name": "FW_POS_STK_CONF", "shortDesc": "Custom stick configuration", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 80.0, "min": 0.0, "name": "FW_P_LIM_MAX", "shortDesc": "Maximum pitch angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -30.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 0.0, "min": -60.0, "name": "FW_P_LIM_MIN", "shortDesc": "Minimum pitch angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 50.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 75.0, "min": 35.0, "name": "FW_R_LIM", "shortDesc": "Maximum roll angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW General", "increment": 0.01, "longDesc": "This is the minimum throttle while on the ground (\"landed\") in auto modes.", "max": 1.0, "min": 0.0, "name": "FW_THR_IDLE", "shortDesc": "Idle throttle", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW General", "increment": 0.01, "longDesc": "Applies in any altitude controlled flight mode.\nShould be set accordingly to achieve FW_T_CLMB_MAX.", "max": 1.0, "min": 0.0, "name": "FW_THR_MAX", "shortDesc": "Throttle limit max", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW General", "increment": 0.01, "longDesc": "Applies in any altitude controlled flight mode.\nUsually set to 0 but can be increased to prevent the motor from stopping when\ndescending, which can increase achievable descent rates.", "max": 1.0, "min": 0.0, "name": "FW_THR_MIN", "shortDesc": "Throttle limit min", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "FW General", "increment": 0.01, "longDesc": "In auto modes: default climb rate output by controller to achieve altitude setpoints.\nIn manual modes: maximum climb rate setpoint.", "min": 0.1, "name": "FW_T_CLMB_R_SP", "shortDesc": "Default target climbrate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "FW General", "increment": 0.01, "longDesc": "In auto modes: default sink rate output by controller to achieve altitude setpoints.\nIn manual modes: maximum sink rate setpoint.", "min": 0.1, "name": "FW_T_SINK_R_SP", "shortDesc": "Default target sinkrate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW General", "increment": 1.0, "longDesc": "Adjusts the amount of weighting that the pitch control\napplies to speed vs height errors.\n0 -> control height only\n2 -> control speed only (gliders)", "max": 2.0, "min": 0.0, "name": "FW_T_SPDWEIGHT", "shortDesc": "Speed <--> Altitude weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "FW General", "increment": 1.0, "longDesc": "This is used to constrain a minimum altitude below which we keep wings level to avoid wing tip strike. It's safer\nto give a slight margin here (> 0m)", "min": 0.0, "name": "FW_WING_HEIGHT", "shortDesc": "Height (AGL) of the wings when the aircraft is on the ground", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "FW General", "increment": 0.1, "longDesc": "This is used for limiting the roll setpoint near the ground. (if multiple wings, take the longest span)", "min": 0.1, "name": "FW_WING_SPAN", "shortDesc": "The aircraft's wing span (length from tip to tip)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "FW Lateral Control", "increment": 1.0, "longDesc": "Maximum change in roll angle setpoint per second.\nApplied in all Auto modes, plus manual Position & Altitude modes.", "min": 0.0, "name": "FW_PN_R_SLEW_MAX", "shortDesc": "Path navigation roll slew rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "The controller will increase the commanded airspeed to maintain\nthis minimum groundspeed to the next waypoint.", "max": 40.0, "min": 0.0, "name": "FW_GND_SPD_MIN", "shortDesc": "Minimum groundspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "Maximum slew rate for the commanded throttle", "max": 1.0, "min": 0.0, "name": "FW_THR_SLEW_MAX", "shortDesc": "Throttle max slew rate", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "min": 2.0, "name": "FW_T_ALT_TC", "shortDesc": "Altitude error time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Longitudinal Control", "longDesc": "Minimum altitude error needed to descend with max airspeed and minimal throttle.\nA negative value disables fast descend.", "min": -1.0, "name": "FW_T_F_ALT_ERR", "shortDesc": "Fast descend: minimum altitude error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "FW Longitudinal Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_T_HRATE_FF", "shortDesc": "Height rate feed forward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Longitudinal Control", "increment": 0.05, "longDesc": "Increase it to trim out speed and height offsets faster,\nwith the downside of possible overshoots and oscillations.", "max": 2.0, "min": 0.0, "name": "FW_T_I_GAIN_PIT", "shortDesc": "Integrator gain pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Longitudinal Control", "increment": 0.1, "max": 2.0, "min": 0.0, "name": "FW_T_PTCH_DAMP", "shortDesc": "Pitch damping gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "Is used to compensate for the additional drag created by turning.\nIncrease this gain if the aircraft initially loses energy in turns\nand reduce if the aircraft initially gains energy in turns.", "max": 20.0, "min": 0.0, "name": "FW_T_RLL2THR", "shortDesc": "Roll -> Throttle feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Longitudinal Control", "increment": 0.01, "max": 3.0, "min": 0.5, "name": "FW_T_SEB_R_FF", "shortDesc": "Specific total energy balance rate feedforward gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "max": 15.0, "min": 1.0, "name": "FW_T_SINK_MAX", "shortDesc": "Maximum descent rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "For the airspeed filter in TECS.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_DEV_STD", "shortDesc": "Airspeed rate measurement standard deviation", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "This is defining the noise in the airspeed rate for the constant airspeed rate model\nof the TECS airspeed filter.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_PRC_STD", "shortDesc": "Process noise standard deviation for the airspeed rate", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.07, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "For the airspeed filter in TECS.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_STD", "shortDesc": "Airspeed measurement standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "This filter is applied to the specific total energy rate used for throttle damping.", "max": 2.0, "min": 0.0, "name": "FW_T_STE_R_TC", "shortDesc": "Specific total energy rate first order filter time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "min": 2.0, "name": "FW_T_TAS_TC", "shortDesc": "True airspeed error time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "This is the damping gain for the throttle demand loop.", "max": 1.0, "min": 0.0, "name": "FW_T_THR_DAMPING", "shortDesc": "Throttle damping factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.02, "group": "FW Longitudinal Control", "increment": 0.005, "longDesc": "Increase it to trim out speed and height offsets faster,\nwith the downside of possible overshoots and oscillations.", "max": 1.0, "min": 0.0, "name": "FW_T_THR_INTEG", "shortDesc": "Integrator gain throttle", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Longitudinal Control", "increment": 1.0, "longDesc": "Height above ground threshold below which tighter altitude\ntracking gets enabled (see FW_LND_THRTC_SC). Below this height, TECS smoothly\n(1 sec / sec) transitions the altitude tracking time constant from FW_T_ALT_TC\nto FW_LND_THRTC_SC*FW_T_ALT_TC.\n-1 to disable.", "min": -1.0, "name": "FW_T_THR_LOW_HGT", "shortDesc": "Low-height threshold for tighter altitude tracking", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 7.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "This is the maximum vertical acceleration\neither up or down that the controller will use to correct speed\nor height errors.", "max": 10.0, "min": 1.0, "name": "FW_T_VERT_ACC", "shortDesc": "Maximum vertical acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "Multiplying this factor with the current absolute wind estimate gives the airspeed offset\nadded to the minimum airspeed setpoint limit. This helps to make the\nsystem more robust against disturbances (turbulence) in high wind.", "min": 0.0, "name": "FW_WIND_ARSP_SC", "shortDesc": "Wind-based airspeed scaling factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "FW NPFG Control", "increment": 0.01, "longDesc": "Damping ratio of NPFG control law.", "max": 1.0, "min": 0.1, "name": "NPFG_DAMPING", "shortDesc": "NPFG damping ratio", "type": "Float"}, {"category": "Standard", "default": 1, "group": "FW NPFG Control", "longDesc": "Avoids limit cycling from a too aggressively tuned period/damping combination.\nIf false, also disables upper bound NPFG_PERIOD_UB.", "name": "NPFG_LB_PERIOD", "shortDesc": "Enable automatic lower bound on the NPFG period", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW NPFG Control", "increment": 0.1, "longDesc": "Period of NPFG control law.", "max": 100.0, "min": 1.0, "name": "NPFG_PERIOD", "shortDesc": "NPFG period", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "FW NPFG Control", "increment": 0.1, "longDesc": "Multiplied by period for conservative minimum period bounding (when period lower\nbounding is enabled). 1.0 bounds at marginal stability.", "max": 10.0, "min": 1.0, "name": "NPFG_PERIOD_SF", "shortDesc": "Period safety factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW NPFG Control", "increment": 0.05, "longDesc": "Time constant of roll controller command / response, modeled as first order delay.\nUsed to determine lower period bound. Setting zero disables automatic period bounding.", "max": 2.0, "min": 0.0, "name": "NPFG_ROLL_TC", "shortDesc": "Roll time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.32, "group": "FW NPFG Control", "increment": 0.01, "longDesc": "Multiplied by the track error boundary to determine when the aircraft switches\nto the next waypoint and/or path segment. Should be less than 1.", "max": 1.0, "min": 0.1, "name": "NPFG_SW_DST_MLT", "shortDesc": "NPFG switch distance multiplier", "type": "Float"}, {"category": "Standard", "default": 1, "group": "FW NPFG Control", "longDesc": "Adapts period to maintain track keeping in variable winds and path curvature.", "name": "NPFG_UB_PERIOD", "shortDesc": "Enable automatic upper bound on the NPFG period", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Factor applied to the minimum and stall airspeed when flaps are fully deployed.", "max": 1.0, "min": 0.5, "name": "FW_AIRSPD_FLP_SC", "shortDesc": "Airspeed scale with full flaps", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The maximal airspeed (calibrated airspeed) the user is able to command.", "min": 0.5, "name": "FW_AIRSPD_MAX", "shortDesc": "Maximum Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The minimal airspeed (calibrated airspeed) the user is able to command.\nFurther, if the airspeed falls below this value, the TECS controller will try to\nincrease airspeed more aggressively.\nHas to be set according to the vehicle's stall speed (which should be set in FW_AIRSPD_STALL),\nwith some margin between the stall speed and minimum airspeed.\nThis value corresponds to the desired minimum speed with the default load factor (level flight, default weight),\nand is automatically adpated to the current load factor (calculated from roll setpoint and WEIGHT_GROSS/WEIGHT_BASE).", "min": 0.5, "name": "FW_AIRSPD_MIN", "shortDesc": "Minimum Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 7.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The stall airspeed (calibrated airspeed) of the vehicle.\nIt is used for airspeed sensor failure detection and for the control\nsurface scaling airspeed limits.", "min": 0.5, "name": "FW_AIRSPD_STALL", "shortDesc": "Stall Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The trim CAS (calibrated airspeed) of the vehicle. If an airspeed controller is active,\nthis is the default airspeed setpoint that the controller will try to achieve.\nThis value corresponds to the trim airspeed with the default load factor (level flight, default weight).", "min": 0.5, "name": "FW_AIRSPD_TRIM", "shortDesc": "Trim (Cruise) Airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Performance", "increment": 1.0, "longDesc": "Altitude in standard atmosphere at which the vehicle in normal configuration (WEIGHT_BASE) is still able to achieve a maximum climb rate of\n0.5m/s at maximum throttle (FW_THR_MAX). Used to compensate for air density in FW_T_CLMB_MAX.\nSet negative to disable.", "min": -1.0, "name": "FW_SERVICE_CEIL", "shortDesc": "Service ceiling", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at maximum airspeed FW_AIRSPD_MAX\nSet to 0 to disable mapping of airspeed to trim throttle.", "max": 1.0, "min": 0.0, "name": "FW_THR_ASPD_MAX", "shortDesc": "Throttle at max airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at minimum airspeed FW_AIRSPD_MIN\nSet to 0 to disable mapping of airspeed to trim throttle below FW_AIRSPD_TRIM.", "max": 1.0, "min": 0.0, "name": "FW_THR_ASPD_MIN", "shortDesc": "Throttle at min airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at FW_AIRSPD_TRIM", "max": 1.0, "min": 0.0, "name": "FW_THR_TRIM", "shortDesc": "Trim throttle", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the maximum calibrated climb rate that the aircraft can achieve with\nthe throttle set to FW_THR_MAX and the airspeed set to the\ntrim value. For electric aircraft make sure this number can be\nachieved towards the end of flight when the battery voltage has reduced.", "min": 1.0, "name": "FW_T_CLMB_MAX", "shortDesc": "Maximum climb rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the minimum calibrated sink rate of the aircraft with the throttle\nset to THR_MIN and flown at the same airspeed as used\nto measure FW_T_CLMB_MAX.", "min": 1.0, "name": "FW_T_SINK_MIN", "shortDesc": "Minimum descent rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the weight of the vehicle at which it's performance limits were derived. A zero or negative value\ndisables trim throttle and minimum airspeed compensation based on weight.", "name": "WEIGHT_BASE", "shortDesc": "Vehicle base weight", "type": "Float", "units": "kg"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Performance", "increment": 0.1, "longDesc": "This is the actual weight of the vehicle at any time. This value will differ from WEIGHT_BASE in case weight was added\nor removed from the base weight. Examples are the addition of payloads or larger batteries. A zero or negative value\ndisables trim throttle and minimum airspeed compensation based on weight.", "name": "WEIGHT_GROSS", "shortDesc": "Vehicle gross weight", "type": "Float", "units": "kg"}, {"category": "Standard", "default": 90.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_X_MAX", "shortDesc": "Acro body roll max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "If this parameter is set to 1, the yaw rate controller is enabled in Fixed-wing Acro mode.\nOtherwise the pilot commands directly the yaw actuator.\nIt is disabled by default because an active yaw rate controller will fight against the\nnatural turn coordination of the plane.", "name": "FW_ACRO_YAW_EN", "shortDesc": "Enable yaw rate controller in Acro", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 90.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_Y_MAX", "shortDesc": "Acro body pitch max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 45.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_Z_MAX", "shortDesc": "Acro body yaw max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 1, "group": "FW Rate Control", "longDesc": "This enables a logic that automatically adjusts the output of the rate controller to take\ninto account the real torque produced by an aerodynamic control surface given\nthe current deviation from the trim airspeed (FW_AIRSPD_TRIM).\nEnable when using aerodynamic control surfaces (e.g.: plane)\nDisable when using rotor wings (e.g.: autogyro)", "name": "FW_ARSP_SCALE_EN", "shortDesc": "Enable airspeed scaling", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "This compensates for voltage drop of the battery over time by attempting to\nnormalize performance across the operating range of the battery.", "name": "FW_BAT_SCALE_EN", "shortDesc": "Enable throttle scale by battery level", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_PITCH when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_P_VMAX", "shortDesc": "Pitch trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_PITCH when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_P_VMIN", "shortDesc": "Pitch trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_ROLL when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_R_VMAX", "shortDesc": "Roll trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_ROLL when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_R_VMIN", "shortDesc": "Roll trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_YAW when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_Y_VMAX", "shortDesc": "Yaw trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_YAW when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_Y_VMIN", "shortDesc": "Yaw trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired pitch actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "min": 0.0, "name": "FW_MAN_P_SC", "shortDesc": "Manual pitch scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired roll actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "max": 1.0, "min": 0.0, "name": "FW_MAN_R_SC", "shortDesc": "Manual roll scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired yaw actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "min": 0.0, "name": "FW_MAN_Y_SC", "shortDesc": "Manual yaw scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "longDesc": "Pitch rate differential gain.", "max": 10.0, "min": 0.0, "name": "FW_PR_D", "shortDesc": "Pitch rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output", "max": 10.0, "min": 0.0, "name": "FW_PR_FF", "shortDesc": "Pitch rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_PR_I", "shortDesc": "Pitch rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_PR_IMAX", "shortDesc": "Pitch rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.08, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_PR_P", "shortDesc": "Pitch rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This gain can be used to counteract the \"adverse yaw\" effect for fixed wings.\nWhen the plane enters a roll it will tend to yaw the nose out of the turn.\nThis gain enables the use of a yaw actuator to counteract this effect.", "min": 0.0, "name": "FW_RLL_TO_YAW_FF", "shortDesc": "Roll control to yaw control feedforward gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_RR_D", "shortDesc": "Roll rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output.", "max": 10.0, "min": 0.0, "name": "FW_RR_FF", "shortDesc": "Roll rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Rate Control", "increment": 0.01, "max": 10.0, "min": 0.0, "name": "FW_RR_I", "shortDesc": "Roll rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_RR_IMAX", "shortDesc": "Roll integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_RR_P", "shortDesc": "Roll rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "Chose source for manual setting of spoilers in manual flight modes.", "name": "FW_SPOILERS_MAN", "shortDesc": "Spoiler input in manual flight", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Flaps channel", "value": 1}, {"description": "Aux1", "value": 2}]}, {"category": "Standard", "default": 1, "group": "FW Rate Control", "longDesc": "If set to 1, the airspeed measurement data, if valid, is used in the following controllers:\n- Rate controller: output scaling\n- Attitude controller: coordinated turn controller\n- Position controller: airspeed setpoint tracking, takeoff logic\n- VTOL: transition logic", "name": "FW_USE_AIRSPD", "shortDesc": "Use airspeed for control", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_YR_D", "shortDesc": "Yaw rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output", "max": 10.0, "min": 0.0, "name": "FW_YR_FF", "shortDesc": "Yaw rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.1, "group": "FW Rate Control", "increment": 0.5, "max": 10.0, "min": 0.0, "name": "FW_YR_I", "shortDesc": "Yaw rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_YR_IMAX", "shortDesc": "Yaw rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_YR_P", "shortDesc": "Yaw rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 1, "group": "Failure Detector", "longDesc": "If enabled, failure detector will verify that for motors, a minimum amount of ESC current per throttle\nlevel is being consumed.\nOtherwise this indicates an motor failure.", "name": "FD_ACT_EN", "rebootRequired": true, "shortDesc": "Enable Actuator Failure check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Failure Detector", "increment": 1.0, "longDesc": "Motor failure triggers only below this current value", "max": 50.0, "min": 0.0, "name": "FD_ACT_MOT_C2T", "shortDesc": "Motor Failure Current/Throttle Threshold", "type": "Float", "units": "A/%"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Failure Detector", "increment": 0.01, "longDesc": "Motor failure triggers only above this throttle value.", "max": 1.0, "min": 0.0, "name": "FD_ACT_MOT_THR", "shortDesc": "Motor Failure Throttle Threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 100, "group": "Failure Detector", "increment": 100, "longDesc": "Motor failure triggers only if the throttle threshold and the\ncurrent to throttle threshold are violated for this time.", "max": 10000, "min": 10, "name": "FD_ACT_MOT_TOUT", "shortDesc": "Motor Failure Time Threshold", "type": "Int32", "units": "ms"}, {"category": "Standard", "default": 1, "group": "Failure Detector", "longDesc": "If enabled, failure detector will verify that all the ESCs have successfully armed when the vehicle has transitioned to the armed state.\nTimeout for receiving an acknowledgement from the ESCs is 0.3s, if no feedback is received the failure detector will auto disarm the vehicle.", "name": "FD_ESCS_EN", "shortDesc": "Enable checks on ESCs that report their arming state", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Failure Detector", "longDesc": "Enabled on either AUX5 or MAIN5 depending on board.\nExternal ATS is required by ASTM F3322-18.", "name": "FD_EXT_ATS_EN", "rebootRequired": true, "shortDesc": "Enable PWM input on for engaging failsafe from an external automatic trigger system (ATS)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1900, "group": "Failure Detector", "longDesc": "External ATS is required by ASTM F3322-18.", "name": "FD_EXT_ATS_TRIG", "shortDesc": "The PWM threshold from external automatic trigger system for engaging failsafe", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 60, "group": "Failure Detector", "longDesc": "Maximum pitch angle before FailureDetector triggers the attitude_failure flag.\nThe flag triggers flight termination (if @CBRK_FLIGHTTERM = 0),\nwhich sets outputs to their failsafe values.\nOn takeoff the flag triggers lockdown (irrespective of @CBRK_FLIGHTTERM),\nwhich disarms motors but does not set outputs to failsafe values.\nSetting this parameter to 0 disables the check", "max": 180, "min": 0, "name": "FD_FAIL_P", "shortDesc": "FailureDetector Max Pitch", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Failure Detector", "longDesc": "Seconds (decimal) that pitch has to exceed FD_FAIL_P before being considered as a failure.", "max": 5.0, "min": 0.02, "name": "FD_FAIL_P_TTRI", "shortDesc": "Pitch failure trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 60, "group": "Failure Detector", "longDesc": "Maximum roll angle before FailureDetector triggers the attitude_failure flag.\nThe flag triggers flight termination (if @CBRK_FLIGHTTERM = 0),\nwhich sets outputs to their failsafe values.\nOn takeoff the flag triggers lockdown (irrespective of @CBRK_FLIGHTTERM),\nwhich disarms motors but does not set outputs to failsafe values.\nSetting this parameter to 0 disables the check", "max": 180, "min": 0, "name": "FD_FAIL_R", "shortDesc": "FailureDetector Max Roll", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Failure Detector", "longDesc": "Seconds (decimal) that roll has to exceed FD_FAIL_R before being considered as a failure.", "max": 5.0, "min": 0.02, "name": "FD_FAIL_R_TTRI", "shortDesc": "Roll failure trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 30, "group": "Failure Detector", "increment": 1, "longDesc": "Value at which the imbalanced propeller metric (based on horizontal and\nvertical acceleration variance) triggers a failure\nSetting this value to 0 disables the feature.", "max": 1000, "min": 0, "name": "FD_IMB_PROP_THR", "shortDesc": "Imbalanced propeller check threshold", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 1000.0, "group": "Flight Task Orbit", "increment": 0.5, "max": 10000.0, "min": 1.0, "name": "MC_ORBIT_RAD_MAX", "shortDesc": "Maximum radius of orbit", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Flight Task Orbit", "name": "MC_ORBIT_YAW_MOD", "shortDesc": "Yaw behaviour during orbit flight", "type": "Int32", "values": [{"description": "Front to Circle Center", "value": 0}, {"description": "Hold Initial Heading", "value": 1}, {"description": "Uncontrolled", "value": 2}, {"description": "Hold Front Tangent to Circle", "value": 3}, {"description": "RC Controlled", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Follow target", "longDesc": "Maintain altitude or track target's altitude. When maintaining the altitude,\nthe drone can crash into terrain when the target moves uphill. When tracking\nthe target's altitude, the follow altitude FLW_TGT_HT should be high enough\nto prevent terrain collisions due to GPS inaccuracies of the target.", "name": "FLW_TGT_ALT_M", "shortDesc": "Altitude control mode", "type": "Int32", "values": [{"description": "2D Tracking: Maintain constant altitude relative to home and track XY position only", "value": 0}, {"description": "2D + Terrain: Maintain constant altitude relative to terrain below and track XY position", "value": 1}, {"description": "3D Tracking: Track target's altitude (be aware that GPS altitude bias usually makes this useless)", "value": 2}]}, {"category": "Standard", "default": 8.0, "group": "Follow target", "longDesc": "The distance in meters to follow the target at", "min": 1.0, "name": "FLW_TGT_DST", "shortDesc": "Distance to follow target from", "type": "Float", "units": "m"}, {"category": "Standard", "default": 180.0, "group": "Follow target", "longDesc": "Angle to follow the target from. 0.0 Equals straight in front of the target's\ncourse (direction of motion) and the angle increases in clockwise direction,\nmeaning Right-side would be 90.0 degrees while Left-side is -90.0 degrees\nNote: When the user force sets the angle out of the min/max range, it will be\nwrapped (e.g. 480 -> 120) in the range to gracefully handle the out of range.", "max": 180.0, "min": -180.0, "name": "FLW_TGT_FA", "shortDesc": "Follow Angle setting in degrees", "type": "Float"}, {"category": "Standard", "default": 8.0, "group": "Follow target", "longDesc": "Following height above the target", "min": 8.0, "name": "FLW_TGT_HT", "shortDesc": "Follow target height", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Follow target", "longDesc": "This is the maximum tangential velocity the drone will circle around the target whenever\nan orbit angle setpoint changes. Higher value means more aggressive follow behavior.", "max": 20.0, "min": 0.0, "name": "FLW_TGT_MAX_VEL", "shortDesc": "Maximum tangential velocity setting for generating the follow orbit trajectory", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Follow target", "longDesc": "lower values increase the responsiveness to changing position, but also ignore less noise", "max": 1.0, "min": 0.0, "name": "FLW_TGT_RS", "shortDesc": "Responsiveness to target movement in Target Estimator", "type": "Float"}, {"bitmask": [{"description": "GPS (with QZSS)", "index": 0}, {"description": "SBAS", "index": 1}, {"description": "Galileo", "index": 2}, {"description": "BeiDou", "index": 3}, {"description": "GLONASS", "index": 4}, {"description": "NAVIC", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "longDesc": "This integer bitmask controls the set of GNSS systems used by the receiver. Check your\nreceiver's documentation on how many systems are supported to be used in parallel.\nCurrently this functionality is just implemented for u-blox receivers.\nWhen no bits are set, the receiver's default configuration should be used.\nSet bits true to enable:\n0 : Use GPS (with QZSS)\n1 : Use SBAS (multiple GPS augmentation systems)\n2 : Use Galileo\n3 : Use BeiDou\n4 : Use GLONASS\n5 : Use NAVIC", "max": 63, "min": 0, "name": "GPS_1_GNSS", "rebootRequired": true, "shortDesc": "GNSS Systems for Primary GPS (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "GPS", "longDesc": "Select the GPS protocol over serial.\nAuto-detection will probe all protocols, and thus is a bit slower.", "max": 7, "min": 0, "name": "GPS_1_PROTOCOL", "rebootRequired": true, "shortDesc": "Protocol for Main GPS", "type": "Int32", "values": [{"description": "Auto detect", "value": 0}, {"description": "u-blox", "value": 1}, {"description": "MTK", "value": 2}, {"description": "Ashtech / Trimble", "value": 3}, {"description": "Emlid Reach", "value": 4}, {"description": "Femtomes", "value": 5}, {"description": "NMEA (generic)", "value": 6}]}, {"bitmask": [{"description": "GPS (with QZSS)", "index": 0}, {"description": "SBAS", "index": 1}, {"description": "Galileo", "index": 2}, {"description": "BeiDou", "index": 3}, {"description": "GLONASS", "index": 4}, {"description": "NAVIC", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "longDesc": "This integer bitmask controls the set of GNSS systems used by the receiver. Check your\nreceiver's documentation on how many systems are supported to be used in parallel.\nCurrently this functionality is just implemented for u-blox receivers.\nWhen no bits are set, the receiver's default configuration should be used.\nSet bits true to enable:\n0 : Use GPS (with QZSS)\n1 : Use SBAS (multiple GPS augmentation systems)\n2 : Use Galileo\n3 : Use BeiDou\n4 : Use GLONASS\n5 : Use NAVIC", "max": 63, "min": 0, "name": "GPS_2_GNSS", "rebootRequired": true, "shortDesc": "GNSS Systems for Secondary GPS (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "GPS", "longDesc": "Select the GPS protocol over serial.\nAuto-detection will probe all protocols, and thus is a bit slower.", "max": 6, "min": 0, "name": "GPS_2_PROTOCOL", "rebootRequired": true, "shortDesc": "Protocol for Secondary GPS", "type": "Int32", "values": [{"description": "Auto detect", "value": 0}, {"description": "u-blox", "value": 1}, {"description": "MTK", "value": 2}, {"description": "Ashtech / Trimble", "value": 3}, {"description": "Emlid Reach", "value": 4}, {"description": "Femtomes", "value": 5}, {"description": "NMEA (generic)", "value": 6}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "If this is set to 1, all GPS communication data will be published via uORB,\nand written to the log file as gps_dump message.\nIf this is set to 2, the main GPS is configured to output RTCM data,\nwhich is then logged as gps_dump and can be used for PPK.", "max": 2, "min": 0, "name": "GPS_DUMP_COMM", "shortDesc": "Log GPS communication data", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Full communication", "value": 1}, {"description": "RTCM output (PPK)", "value": 2}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Enable publication of satellite info (ORB_ID(satellite_info)) if possible.\nNot available on MTK.", "name": "GPS_SAT_INFO", "rebootRequired": true, "shortDesc": "Enable sat info (if available)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 230400, "group": "GPS", "longDesc": "Select a baudrate for the F9P's UART2 port.\nIn GPS_UBX_MODE 1, 2, and 3, the F9P's UART2 port is configured to send/receive RTCM corrections.\nSet this to 57600 if you want to attach a telemetry radio on UART2.", "min": 0, "name": "GPS_UBX_BAUD2", "rebootRequired": true, "shortDesc": "u-blox F9P UART2 Baudrate", "type": "Int32", "units": "B/s"}, {"bitmask": [{"description": "Enable I2C input protocol UBX", "index": 0}, {"description": "Enable I2C input protocol NMEA", "index": 1}, {"description": "Enable I2C input protocol RTCM3X", "index": 2}, {"description": "Enable I2C output protocol UBX", "index": 3}, {"description": "Enable I2C output protocol NMEA", "index": 4}, {"description": "Enable I2C output protocol RTCM3X", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "max": 32, "min": 0, "name": "GPS_UBX_CFG_INTF", "rebootRequired": true, "shortDesc": "u-blox protocol configuration for interfaces", "type": "Int32"}, {"category": "Standard", "default": 7, "group": "GPS", "longDesc": "u-blox receivers support different dynamic platform models to adjust the navigation engine to\nthe expected application environment.", "max": 9, "min": 0, "name": "GPS_UBX_DYNMODEL", "rebootRequired": true, "shortDesc": "u-blox GPS dynamic platform model", "type": "Int32", "values": [{"description": "stationary", "value": 2}, {"description": "automotive", "value": 4}, {"description": "airborne with <1g acceleration", "value": 6}, {"description": "airborne with <2g acceleration", "value": 7}, {"description": "airborne with <4g acceleration", "value": 8}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Select the u-blox configuration setup. Most setups will use the default, including RTK and\ndual GPS without heading.\nIf rover has RTCM corrections from a static base (or other static correction source) coming in on UART2, then select Mode 5.\nThe Heading mode requires 2 F9P devices to be attached. The main GPS will act as rover and output\nheading information, whereas the secondary will act as moving base.\nModes 1 and 2 require each F9P UART1 to be connected to the Autopilot. In addition, UART2 on the\nF9P units are connected to each other.\nModes 3 and 4 only require UART1 on each F9P connected to the Autopilot or Can Node. UART RX DMA is required.\nRTK is still possible with this setup.", "max": 1, "min": 0, "name": "GPS_UBX_MODE", "rebootRequired": true, "shortDesc": "u-blox GPS Mode", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Heading (Rover With Moving Base UART1 Connected To Autopilot, UART2 Connected To Moving Base)", "value": 1}, {"description": "Moving Base (UART1 Connected To Autopilot, UART2 Connected To Rover)", "value": 2}, {"description": "Heading (Rover With Moving Base UART1 Connected to Autopilot Or Can Node At 921600)", "value": 3}, {"description": "Moving Base (Moving Base UART1 Connected to Autopilot Or Can Node At 921600)", "value": 4}, {"description": "Rover with Static Base on UART2 (similar to Default, except coming in on UART2)", "value": 5}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "GPS", "longDesc": "Heading offset angle for dual antenna GPS setups that support heading estimation.\nSet this to 0 if the antennas are parallel to the forward-facing direction\nof the vehicle and the rover (or Unicore primary) antenna is in front.\nThe offset angle increases clockwise.\nSet this to 90 if the rover (or Unicore primary, or Septentrio Mosaic Aux)\nantenna is placed on the right side of the vehicle and the moving base\nantenna is on the left side.\n(Note: the Unicore primary antenna is the one connected on the right as seen\nfrom the top).", "max": 360.0, "min": 0.0, "name": "GPS_YAW_OFFSET", "rebootRequired": true, "shortDesc": "Heading/Yaw offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Geofence", "longDesc": "Note: Setting this value to 4 enables flight termination,\nwhich will kill the vehicle on violation of the fence.", "max": 5, "min": 0, "name": "GF_ACTION", "shortDesc": "Geofence violation action", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold mode", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land mode", "value": 5}]}, {"category": "Standard", "default": 0.0, "group": "Geofence", "increment": 1.0, "longDesc": "Maximum horizontal distance in meters the vehicle can be from Home before triggering a geofence action.\nDisabled if 0.", "max": 10000.0, "min": 0.0, "name": "GF_MAX_HOR_DIST", "shortDesc": "Max horizontal distance from Home", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0.0, "group": "Geofence", "increment": 1.0, "longDesc": "Maximum vertical distance in meters the vehicle can be from Home before triggering a geofence action.\nDisabled if 0.", "max": 10000.0, "min": 0.0, "name": "GF_MAX_VER_DIST", "shortDesc": "Max vertical distance from Home", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geofence", "longDesc": "WARNING: This experimental feature may cause flyaways. Use at your own risk.\nPredict the motion of the vehicle and trigger the breach if it is determined that the current trajectory\nwould result in a breach happening before the vehicle can make evasive maneuvers.\nThe vehicle is then re-routed to a safe hold position (stop for multirotor, loiter for fixed wing).", "name": "GF_PREDICT", "shortDesc": "[EXPERIMENTAL] Use Pre-emptive geofence triggering", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Geofence", "longDesc": "Select which position source should be used. Selecting GPS instead of global position makes sure that there is\nno dependence on the position estimator\n0 = global position, 1 = GPS", "max": 1, "min": 0, "name": "GF_SOURCE", "shortDesc": "Geofence source", "type": "Int32", "values": [{"description": "GPOS", "value": 0}, {"description": "GPS", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines which mixer implementation to use.\nSome are generic, while others are specifically fit to a certain vehicle with a fixed set of actuators.\n'Custom' should only be used if noting else can be used.", "name": "CA_AIRFRAME", "shortDesc": "Airframe selection", "type": "Int32", "values": [{"description": "Multirotor", "value": 0}, {"description": "Fixed-wing", "value": 1}, {"description": "Standard VTOL", "value": 2}, {"description": "Tiltrotor VTOL", "value": 3}, {"description": "Tailsitter VTOL", "value": 4}, {"description": "Rover (Ackermann)", "value": 5}, {"description": "Rover (Differential)", "value": 6}, {"description": "Motors (6DOF)", "value": 7}, {"description": "Multirotor with Tilt", "value": 8}, {"description": "Custom", "value": 9}, {"description": "Helicopter (tail ESC)", "value": 10}, {"description": "Helicopter (tail Servo)", "value": 11}, {"description": "Helicopter (Coaxial)", "value": 12}, {"description": "Rover (Mecanum)", "value": 13}, {"description": "Spacecraft 2D", "value": 14}, {"description": "Spacecraft 3D", "value": 15}]}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "This is used to specify how to handle motor failures\nreported by failure detector.", "name": "CA_FAILURE_MODE", "shortDesc": "Motor failure handling mode", "type": "Int32", "values": [{"description": "Ignore", "value": 0}, {"description": "Remove first failed motor from effectiveness", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": -0.05, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 0 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C0", "shortDesc": "Collective pitch curve at position 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0725, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 1 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C1", "shortDesc": "Collective pitch curve at position 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 2 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C2", "shortDesc": "Collective pitch curve at position 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.325, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 3 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C3", "shortDesc": "Collective pitch curve at position 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.45, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 4 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C4", "shortDesc": "Collective pitch curve at position 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Same definition as the proportional gain but for integral.", "max": 10.0, "min": 0.0, "name": "CA_HELI_RPM_I", "shortDesc": "Integral gain for rpm control", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Ratio between rpm error devided by 1000 to how much normalized output gets added to correct for it.\nmotor_command = throttle_curve + CA_HELI_RPM_P * (rpm_setpoint - rpm_measurement) / 1000", "max": 10.0, "min": 0.0, "name": "CA_HELI_RPM_P", "shortDesc": "Proportional gain for rpm control", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": 1500.0, "group": "Geometry", "increment": 1.0, "longDesc": "Requires rpm feedback for the controller.", "max": 10000.0, "min": 100.0, "name": "CA_HELI_RPM_SP", "shortDesc": "Setpoint for main rotor rpm", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 0.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C0", "shortDesc": "Throttle curve at position 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 1.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C1", "shortDesc": "Throttle curve at position 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 2.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C2", "shortDesc": "Throttle curve at position 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 3.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C3", "shortDesc": "Throttle curve at position 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 4.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C4", "shortDesc": "Throttle curve at position 4", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Default configuration is for a clockwise turning main rotor and\npositive thrust of the tail rotor is expected to rotate the vehicle clockwise.\nSet this parameter to true if the tail rotor provides thrust in counter-clockwise direction\nwhich is mostly the case when the main rotor turns counter-clockwise.", "name": "CA_HELI_YAW_CCW", "shortDesc": "Main rotor turns counter-clockwise", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to specify which collective pitch command results in the least amount of rotor drag.\nThis is used to increase the accuracy of the yaw drag torque compensation based on collective pitch\nby aligning the lowest rotor drag with zero compensation.\nFor symmetric profile blades this is the command that results in exactly 0\u00b0 collective blade angle.\nFor lift profile blades this is typically a command resulting in slightly negative collective blade angle.\ntail_output += CA_HELI_YAW_CP_S * abs(collective_pitch - CA_HELI_YAW_CP_O)", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_CP_O", "shortDesc": "Offset for yaw compensation based on collective pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to add a proportional factor of the collective pitch command to the yaw command.\nA negative value is needed when positive thrust of the tail rotor rotates the vehicle opposite to the main rotor turn direction.\ntail_output += CA_HELI_YAW_CP_S * abs(collective_pitch - CA_HELI_YAW_CP_O)", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_CP_S", "shortDesc": "Scale for yaw compensation based on collective pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to add a proportional factor of the throttle command to the yaw command.\nA negative value is needed when positive thrust of the tail rotor rotates the vehicle opposite to the main rotor turn direction.\ntail_output += CA_HELI_YAW_TH_S * throttle", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_TH_S", "shortDesc": "Scale for yaw compensation based on throttle", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Used to linearize mechanical output of swashplate servos to avoid axis coupling and binding with 4 servo redundancy.\nThis requires a symmetric setup where the servo horn is exactly centered with a 0 command.\nSetting to zero disables feature.", "max": 75.0, "min": 0.0, "name": "CA_MAX_SVO_THROW", "shortDesc": "Throw angle of swashplate servo at maximum commands for linearization", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Geometry", "longDesc": "Selects the algorithm and desaturation method.\nIf set to Automatic, the selection is based on the airframe (CA_AIRFRAME).", "name": "CA_METHOD", "shortDesc": "Control allocation method", "type": "Int32", "values": [{"description": "Pseudo-inverse with output clipping", "value": 0}, {"description": "Pseudo-inverse with sequential desaturation technique", "value": 1}, {"description": "Automatic", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R0_SLEW", "shortDesc": "Motor 0 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R10_SLEW", "shortDesc": "Motor 10 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R11_SLEW", "shortDesc": "Motor 11 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R1_SLEW", "shortDesc": "Motor 1 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R2_SLEW", "shortDesc": "Motor 2 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R3_SLEW", "shortDesc": "Motor 3 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R4_SLEW", "shortDesc": "Motor 4 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R5_SLEW", "shortDesc": "Motor 5 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R6_SLEW", "shortDesc": "Motor 6 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R7_SLEW", "shortDesc": "Motor 7 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R8_SLEW", "shortDesc": "Motor 8 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R9_SLEW", "shortDesc": "Motor 9 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AX", "shortDesc": "Axis of rotor 0 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AY", "shortDesc": "Axis of rotor 0 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AZ", "shortDesc": "Axis of rotor 0 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR0_CT", "shortDesc": "Thrust coefficient of rotor 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR0_KM", "shortDesc": "Moment coefficient of rotor 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PX", "shortDesc": "Position of rotor 0 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PY", "shortDesc": "Position of rotor 0 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PZ", "shortDesc": "Position of rotor 0 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR0_TILT", "shortDesc": "Rotor 0 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AX", "shortDesc": "Axis of rotor 10 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AY", "shortDesc": "Axis of rotor 10 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AZ", "shortDesc": "Axis of rotor 10 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR10_CT", "shortDesc": "Thrust coefficient of rotor 10", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR10_KM", "shortDesc": "Moment coefficient of rotor 10", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PX", "shortDesc": "Position of rotor 10 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PY", "shortDesc": "Position of rotor 10 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PZ", "shortDesc": "Position of rotor 10 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR10_TILT", "shortDesc": "Rotor 10 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AX", "shortDesc": "Axis of rotor 11 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AY", "shortDesc": "Axis of rotor 11 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AZ", "shortDesc": "Axis of rotor 11 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR11_CT", "shortDesc": "Thrust coefficient of rotor 11", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR11_KM", "shortDesc": "Moment coefficient of rotor 11", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PX", "shortDesc": "Position of rotor 11 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PY", "shortDesc": "Position of rotor 11 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PZ", "shortDesc": "Position of rotor 11 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR11_TILT", "shortDesc": "Rotor 11 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AX", "shortDesc": "Axis of rotor 1 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AY", "shortDesc": "Axis of rotor 1 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AZ", "shortDesc": "Axis of rotor 1 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR1_CT", "shortDesc": "Thrust coefficient of rotor 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR1_KM", "shortDesc": "Moment coefficient of rotor 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PX", "shortDesc": "Position of rotor 1 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PY", "shortDesc": "Position of rotor 1 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PZ", "shortDesc": "Position of rotor 1 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR1_TILT", "shortDesc": "Rotor 1 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AX", "shortDesc": "Axis of rotor 2 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AY", "shortDesc": "Axis of rotor 2 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AZ", "shortDesc": "Axis of rotor 2 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR2_CT", "shortDesc": "Thrust coefficient of rotor 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR2_KM", "shortDesc": "Moment coefficient of rotor 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PX", "shortDesc": "Position of rotor 2 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PY", "shortDesc": "Position of rotor 2 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PZ", "shortDesc": "Position of rotor 2 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR2_TILT", "shortDesc": "Rotor 2 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AX", "shortDesc": "Axis of rotor 3 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AY", "shortDesc": "Axis of rotor 3 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AZ", "shortDesc": "Axis of rotor 3 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR3_CT", "shortDesc": "Thrust coefficient of rotor 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR3_KM", "shortDesc": "Moment coefficient of rotor 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PX", "shortDesc": "Position of rotor 3 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PY", "shortDesc": "Position of rotor 3 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PZ", "shortDesc": "Position of rotor 3 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR3_TILT", "shortDesc": "Rotor 3 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AX", "shortDesc": "Axis of rotor 4 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AY", "shortDesc": "Axis of rotor 4 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AZ", "shortDesc": "Axis of rotor 4 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR4_CT", "shortDesc": "Thrust coefficient of rotor 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR4_KM", "shortDesc": "Moment coefficient of rotor 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PX", "shortDesc": "Position of rotor 4 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PY", "shortDesc": "Position of rotor 4 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PZ", "shortDesc": "Position of rotor 4 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR4_TILT", "shortDesc": "Rotor 4 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AX", "shortDesc": "Axis of rotor 5 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AY", "shortDesc": "Axis of rotor 5 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AZ", "shortDesc": "Axis of rotor 5 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR5_CT", "shortDesc": "Thrust coefficient of rotor 5", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR5_KM", "shortDesc": "Moment coefficient of rotor 5", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PX", "shortDesc": "Position of rotor 5 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PY", "shortDesc": "Position of rotor 5 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PZ", "shortDesc": "Position of rotor 5 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR5_TILT", "shortDesc": "Rotor 5 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AX", "shortDesc": "Axis of rotor 6 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AY", "shortDesc": "Axis of rotor 6 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AZ", "shortDesc": "Axis of rotor 6 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR6_CT", "shortDesc": "Thrust coefficient of rotor 6", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR6_KM", "shortDesc": "Moment coefficient of rotor 6", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PX", "shortDesc": "Position of rotor 6 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PY", "shortDesc": "Position of rotor 6 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PZ", "shortDesc": "Position of rotor 6 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR6_TILT", "shortDesc": "Rotor 6 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AX", "shortDesc": "Axis of rotor 7 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AY", "shortDesc": "Axis of rotor 7 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AZ", "shortDesc": "Axis of rotor 7 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR7_CT", "shortDesc": "Thrust coefficient of rotor 7", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR7_KM", "shortDesc": "Moment coefficient of rotor 7", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PX", "shortDesc": "Position of rotor 7 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PY", "shortDesc": "Position of rotor 7 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PZ", "shortDesc": "Position of rotor 7 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR7_TILT", "shortDesc": "Rotor 7 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AX", "shortDesc": "Axis of rotor 8 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AY", "shortDesc": "Axis of rotor 8 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AZ", "shortDesc": "Axis of rotor 8 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR8_CT", "shortDesc": "Thrust coefficient of rotor 8", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR8_KM", "shortDesc": "Moment coefficient of rotor 8", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PX", "shortDesc": "Position of rotor 8 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PY", "shortDesc": "Position of rotor 8 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PZ", "shortDesc": "Position of rotor 8 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR8_TILT", "shortDesc": "Rotor 8 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AX", "shortDesc": "Axis of rotor 9 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AY", "shortDesc": "Axis of rotor 9 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AZ", "shortDesc": "Axis of rotor 9 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR9_CT", "shortDesc": "Thrust coefficient of rotor 9", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR9_KM", "shortDesc": "Moment coefficient of rotor 9", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PX", "shortDesc": "Position of rotor 9 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PY", "shortDesc": "Position of rotor 9 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PZ", "shortDesc": "Position of rotor 9 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR9_TILT", "shortDesc": "Rotor 9 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_ROTOR_COUNT", "shortDesc": "Total number of rotors", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}, {"description": "5", "value": 5}, {"description": "6", "value": 6}, {"description": "7", "value": 7}, {"description": "8", "value": 8}, {"description": "9", "value": 9}, {"description": "10", "value": 10}, {"description": "11", "value": 11}, {"description": "12", "value": 12}]}, {"bitmask": [{"description": "Motor 1", "index": 0}, {"description": "Motor 2", "index": 1}, {"description": "Motor 3", "index": 2}, {"description": "Motor 4", "index": 3}, {"description": "Motor 5", "index": 4}, {"description": "Motor 6", "index": 5}, {"description": "Motor 7", "index": 6}, {"description": "Motor 8", "index": 7}, {"description": "Motor 9", "index": 8}, {"description": "Motor 10", "index": 9}, {"description": "Motor 11", "index": 10}, {"description": "Motor 12", "index": 11}], "category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Configure motors to be bidirectional/reversible. Note that the output driver needs to support this as well.", "max": 4095, "min": 0, "name": "CA_R_REV", "shortDesc": "Bidirectional/Reversible motors", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG0", "shortDesc": "Angle for swash plate servo 0", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 140.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG1", "shortDesc": "Angle for swash plate servo 1", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 220.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG2", "shortDesc": "Angle for swash plate servo 2", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG3", "shortDesc": "Angle for swash plate servo 3", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L0", "shortDesc": "Arm length for swash plate servo 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L1", "shortDesc": "Arm length for swash plate servo 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L2", "shortDesc": "Arm length for swash plate servo 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L3", "shortDesc": "Arm length for swash plate servo 3", "type": "Float"}, {"category": "Standard", "default": 3, "group": "Geometry", "name": "CA_SP0_COUNT", "shortDesc": "Number of swash plates servos", "type": "Int32", "values": [{"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV0_SLEW", "shortDesc": "Servo 0 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV1_SLEW", "shortDesc": "Servo 1 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV2_SLEW", "shortDesc": "Servo 2 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV3_SLEW", "shortDesc": "Servo 3 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV4_SLEW", "shortDesc": "Servo 4 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV5_SLEW", "shortDesc": "Servo 5 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV6_SLEW", "shortDesc": "Servo 6 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV7_SLEW", "shortDesc": "Servo 7 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_FLAP", "shortDesc": "Control Surface 0 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_SPOIL", "shortDesc": "Control Surface 0 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_TRIM", "shortDesc": "Control Surface 0 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_P", "shortDesc": "Control Surface 0 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_R", "shortDesc": "Control Surface 0 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_Y", "shortDesc": "Control Surface 0 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS0_TYPE", "shortDesc": "Control Surface 0 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_FLAP", "shortDesc": "Control Surface 1 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_SPOIL", "shortDesc": "Control Surface 1 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_TRIM", "shortDesc": "Control Surface 1 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_P", "shortDesc": "Control Surface 1 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_R", "shortDesc": "Control Surface 1 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_Y", "shortDesc": "Control Surface 1 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS1_TYPE", "shortDesc": "Control Surface 1 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_FLAP", "shortDesc": "Control Surface 2 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_SPOIL", "shortDesc": "Control Surface 2 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_TRIM", "shortDesc": "Control Surface 2 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_P", "shortDesc": "Control Surface 2 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_R", "shortDesc": "Control Surface 2 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_Y", "shortDesc": "Control Surface 2 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS2_TYPE", "shortDesc": "Control Surface 2 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_FLAP", "shortDesc": "Control Surface 3 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_SPOIL", "shortDesc": "Control Surface 3 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_TRIM", "shortDesc": "Control Surface 3 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_P", "shortDesc": "Control Surface 3 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_R", "shortDesc": "Control Surface 3 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_Y", "shortDesc": "Control Surface 3 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS3_TYPE", "shortDesc": "Control Surface 3 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_FLAP", "shortDesc": "Control Surface 4 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_SPOIL", "shortDesc": "Control Surface 4 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_TRIM", "shortDesc": "Control Surface 4 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_P", "shortDesc": "Control Surface 4 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_R", "shortDesc": "Control Surface 4 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_Y", "shortDesc": "Control Surface 4 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS4_TYPE", "shortDesc": "Control Surface 4 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_FLAP", "shortDesc": "Control Surface 5 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_SPOIL", "shortDesc": "Control Surface 5 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_TRIM", "shortDesc": "Control Surface 5 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_P", "shortDesc": "Control Surface 5 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_R", "shortDesc": "Control Surface 5 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_Y", "shortDesc": "Control Surface 5 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS5_TYPE", "shortDesc": "Control Surface 5 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_FLAP", "shortDesc": "Control Surface 6 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_SPOIL", "shortDesc": "Control Surface 6 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_TRIM", "shortDesc": "Control Surface 6 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_P", "shortDesc": "Control Surface 6 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_R", "shortDesc": "Control Surface 6 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_Y", "shortDesc": "Control Surface 6 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS6_TYPE", "shortDesc": "Control Surface 6 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_FLAP", "shortDesc": "Control Surface 7 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_SPOIL", "shortDesc": "Control Surface 7 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_TRIM", "shortDesc": "Control Surface 7 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_P", "shortDesc": "Control Surface 7 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_R", "shortDesc": "Control Surface 7 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_Y", "shortDesc": "Control Surface 7 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS7_TYPE", "shortDesc": "Control Surface 7 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS_COUNT", "shortDesc": "Total number of Control Surfaces", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}, {"description": "5", "value": 5}, {"description": "6", "value": 6}, {"description": "7", "value": 7}, {"description": "8", "value": 8}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL0_CT", "shortDesc": "Tilt 0 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL0_MAXA", "shortDesc": "Tilt Servo 0 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL0_MINA", "shortDesc": "Tilt Servo 0 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL0_TD", "shortDesc": "Tilt Servo 0 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL1_CT", "shortDesc": "Tilt 1 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL1_MAXA", "shortDesc": "Tilt Servo 1 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL1_MINA", "shortDesc": "Tilt Servo 1 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL1_TD", "shortDesc": "Tilt Servo 1 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL2_CT", "shortDesc": "Tilt 2 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL2_MAXA", "shortDesc": "Tilt Servo 2 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL2_MINA", "shortDesc": "Tilt Servo 2 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL2_TD", "shortDesc": "Tilt Servo 2 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL3_CT", "shortDesc": "Tilt 3 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL3_MAXA", "shortDesc": "Tilt Servo 3 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL3_MINA", "shortDesc": "Tilt Servo 3 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL3_TD", "shortDesc": "Tilt Servo 3 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_TL_COUNT", "shortDesc": "Total number of Tilt Servos", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Hover Thrust Estimator", "longDesc": "Sets the number of standard deviations used\nby the innovation consistency test.", "max": 10.0, "min": 1.0, "name": "HTE_ACC_GATE", "shortDesc": "Gate size for acceleration fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Hover Thrust Estimator", "longDesc": "Sets the number of standard deviations used\nby the innovation consistency test.", "max": 1.0, "min": 0.0, "name": "HTE_HT_ERR_INIT", "shortDesc": "1-sigma initial hover thrust uncertainty", "type": "Float", "units": "normalized_thrust"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0036, "group": "Hover Thrust Estimator", "longDesc": "Reduce to make the hover thrust estimate\nmore stable, increase if the real hover thrust\nis expected to change quickly over time.", "max": 1.0, "min": 0.0001, "name": "HTE_HT_NOISE", "shortDesc": "Hover thrust process noise", "type": "Float", "units": "normalized_thrust/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Hover Thrust Estimator", "longDesc": "Defines the range of the hover thrust estimate around MPC_THR_HOVER.\nA value of 0.2 with MPC_THR_HOVER at 0.5 results in a range of [0.3, 0.7].\nSet to a large value if the vehicle operates in varying physical conditions that\naffect the required hover thrust strongly (e.g. differently sized payloads).", "max": 0.4, "min": 0.01, "name": "HTE_THR_RANGE", "shortDesc": "Max deviation from MPC_THR_HOVER", "type": "Float", "units": "normalized_thrust"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Hover Thrust Estimator", "longDesc": "Above this speed, the measurement noise is linearly increased\nto reduce the sensitivity of the estimator from biased measurement.\nSet to a low value on vehicles with large lifting surfaces.", "max": 20.0, "min": 1.0, "name": "HTE_VXY_THR", "shortDesc": "Horizontal velocity threshold for sensitivity reduction", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Hover Thrust Estimator", "longDesc": "Above this speed, the measurement noise is linearly increased\nto reduce the sensitivity of the estimator from biased measurement.\nSet to a low value on vehicles affected by air drag when climbing or descending.", "max": 10.0, "min": 1.0, "name": "HTE_VZ_THR", "shortDesc": "Vertical velocity threshold for sensitivity reduction", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.0, "group": "Land Detector", "longDesc": "Maximum airspeed allowed in the landed state", "max": 30.0, "min": 2.0, "name": "LNDFW_AIRSPD_MAX", "shortDesc": "Fixed-wing land detector: Max airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Land Detector", "longDesc": "Maximum allowed norm of the angular velocity in the landed state.\nOnly used if neither airspeed nor groundspeed can be used for landing detection.", "name": "LNDFW_ROT_MAX", "shortDesc": "Fixed-wing land detector: max rotational speed", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Land Detector", "longDesc": "Time the land conditions (speeds and acceleration) have to be satisfied to detect a landing.", "min": 0.1, "name": "LNDFW_TRIG_TIME", "rebootRequired": true, "shortDesc": "Fixed-wing land detection trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Land Detector", "longDesc": "Maximum horizontal velocity allowed in the landed state.\nA factor of 0.7 is applied in case of airspeed-less flying\n(either because no sensor is present or sensor data got invalid in flight).", "max": 20.0, "min": 0.5, "name": "LNDFW_VEL_XY_MAX", "shortDesc": "Fixed-wing land detector: Max horizontal velocity threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Land Detector", "longDesc": "Maximum vertical velocity allowed in the landed state.", "max": 20.0, "min": 0.1, "name": "LNDFW_VEL_Z_MAX", "shortDesc": "Fixed-wing land detector: Max vertiacal velocity threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 8.0, "group": "Land Detector", "longDesc": "Maximum horizontal (x,y body axes) acceleration allowed in the landed state", "max": 30.0, "min": 2.0, "name": "LNDFW_XYACC_MAX", "shortDesc": "Fixed-wing land detector: Max horizontal acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Land Detector", "longDesc": "The height above ground below which ground effect creates barometric altitude errors.\nA negative value indicates no ground effect.", "min": -1.0, "name": "LNDMC_ALT_GND", "shortDesc": "Ground effect altitude for multicopters", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Land Detector", "longDesc": "Maximum allowed norm of the angular velocity (roll, pitch) in the landed state.", "name": "LNDMC_ROT_MAX", "shortDesc": "Multicopter max rotational speed", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Land Detector", "longDesc": "Total time it takes to go through all three land detection stages:\nground contact, maybe landed, landed\nwhen all necessary conditions are constantly met.", "max": 10.0, "min": 0.1, "name": "LNDMC_TRIG_TIME", "shortDesc": "Multicopter land detection trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Land Detector", "longDesc": "Maximum horizontal velocity allowed in the landed state", "name": "LNDMC_XY_VEL_MAX", "shortDesc": "Multicopter max horizontal velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "Land Detector", "longDesc": "Vertical velocity threshold to detect landing.\nHas to be set lower than the expected minimal speed for landing,\nwhich is either MPC_LAND_SPEED or MPC_LAND_CRWL.\nThis is enforced by an automatic check.", "min": 0.0, "name": "LNDMC_Z_VEL_MAX", "shortDesc": "Multicopter vertical velocity threshold", "type": "Float", "units": "m/s"}, {"category": "System", "default": 0, "group": "Land Detector", "longDesc": "Total flight time of this autopilot. Higher 32 bits of the value.\nFlight time in microseconds = (LND_FLIGHT_T_HI << 32) | LND_FLIGHT_T_LO.", "min": 0, "name": "LND_FLIGHT_T_HI", "shortDesc": "Total flight time in microseconds", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Land Detector", "longDesc": "Total flight time of this autopilot. Lower 32 bits of the value.\nFlight time in microseconds = (LND_FLIGHT_T_HI << 32) | LND_FLIGHT_T_LO.", "min": 0, "name": "LND_FLIGHT_T_LO", "shortDesc": "Total flight time in microseconds", "type": "Int32", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Landing Target Estimator", "longDesc": "Variance of acceleration measurement used for landing target position prediction.\nHigher values results in tighter following of the measurements and more lenient outlier rejection", "min": 0.01, "name": "LTEST_ACC_UNC", "shortDesc": "Acceleration uncertainty", "type": "Float", "units": "(m/s^2)^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.005, "group": "Landing Target Estimator", "longDesc": "Variance of the landing target measurement from the driver.\nHigher values result in less aggressive following of the measurement and a smoother output as well as fewer rejected measurements.", "name": "LTEST_MEAS_UNC", "shortDesc": "Landing target measurement uncertainty", "type": "Float", "units": "tan(rad)^2"}, {"category": "Standard", "default": 0, "group": "Landing Target Estimator", "longDesc": "Configure the mode of the landing target. Depending on the mode, the landing target observations are used differently to aid position estimation.\nMode Moving: The landing target may be moving around while in the field of view of the vehicle. Landing target measurements are not used to aid positioning.\nMode Stationary: The landing target is stationary. Measured velocity w.r.t. the landing target is used to aid velocity estimation.", "max": 1, "min": 0, "name": "LTEST_MODE", "shortDesc": "Landing target mode", "type": "Int32", "values": [{"description": "Moving", "value": 0}, {"description": "Stationary", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Landing Target Estimator", "longDesc": "Initial variance of the relative landing target position in x and y direction", "min": 0.001, "name": "LTEST_POS_UNC_IN", "shortDesc": "Initial landing target position uncertainty", "type": "Float", "units": "m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Landing Target Estimator", "longDesc": "Landing target x measurements are scaled by this factor before being used", "min": 0.01, "name": "LTEST_SCALE_X", "shortDesc": "Scale factor for sensor measurements in sensor x axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Landing Target Estimator", "longDesc": "Landing target y measurements are scaled by this factor before being used", "min": 0.01, "name": "LTEST_SCALE_Y", "shortDesc": "Scale factor for sensor measurements in sensor y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_X", "rebootRequired": true, "shortDesc": "X Position of IRLOCK in body frame (forward)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_Y", "rebootRequired": true, "shortDesc": "Y Position of IRLOCK in body frame (right)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_Z", "rebootRequired": true, "shortDesc": "Z Position of IRLOCK in body frame (downward)", "type": "Float", "units": "m"}, {"category": "Standard", "default": 2, "group": "Landing Target Estimator", "longDesc": "Default orientation of Yaw 90\u00b0", "max": 40, "min": -1, "name": "LTEST_SENS_ROT", "rebootRequired": true, "shortDesc": "Rotation of IRLOCK sensor relative to airframe", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Landing Target Estimator", "longDesc": "Initial variance of the relative landing target velocity in x and y directions", "min": 0.001, "name": "LTEST_VEL_UNC_IN", "shortDesc": "Initial landing target velocity uncertainty", "type": "Float", "units": "(m/s)^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.012, "group": "Local Position Estimator", "longDesc": "Data sheet noise density = 150ug/sqrt(Hz) = 0.0015 m/s^2/sqrt(Hz)\nLarger than data sheet to account for tilt error.", "max": 2.0, "min": 1e-05, "name": "LPE_ACC_XY", "shortDesc": "Accelerometer xy noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.02, "group": "Local Position Estimator", "longDesc": "Data sheet noise density = 150ug/sqrt(Hz) = 0.0015 m/s^2/sqrt(Hz)", "max": 2.0, "min": 1e-05, "name": "LPE_ACC_Z", "shortDesc": "Accelerometer z noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Local Position Estimator", "max": 100.0, "min": 0.01, "name": "LPE_BAR_Z", "shortDesc": "Barometric presssure altitude z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Local Position Estimator", "name": "LPE_EN", "shortDesc": "Local position estimator enable (unsupported)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 3.0, "group": "Local Position Estimator", "max": 5.0, "min": 1.0, "name": "LPE_EPH_MAX", "shortDesc": "Max EPH allowed for GPS initialization", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 5.0, "group": "Local Position Estimator", "max": 5.0, "min": 1.0, "name": "LPE_EPV_MAX", "shortDesc": "Max EPV allowed for GPS initialization", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Local Position Estimator", "longDesc": "By initializing the estimator to the LPE_LAT/LON parameters when global information is unavailable", "max": 1, "min": 0, "name": "LPE_FAKE_ORIGIN", "shortDesc": "Enable publishing of a fake global position (e.g for AUTO missions using Optical Flow)", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.001, "group": "Local Position Estimator", "max": 2.0, "min": 0.0, "name": "LPE_FGYRO_HP", "shortDesc": "Flow gyro high pass filter cut off frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_FLW_OFF_Z", "shortDesc": "Optical flow z offset from center", "type": "Float", "units": "m"}, {"category": "Standard", "default": 150, "group": "Local Position Estimator", "max": 255, "min": 0, "name": "LPE_FLW_QMIN", "shortDesc": "Optical flow minimum quality threshold", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 7.0, "group": "Local Position Estimator", "max": 10.0, "min": 0.1, "name": "LPE_FLW_R", "shortDesc": "Optical flow rotation (roll/pitch) noise gain", "type": "Float", "units": "m/s/rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 7.0, "group": "Local Position Estimator", "max": 10.0, "min": 0.0, "name": "LPE_FLW_RR", "shortDesc": "Optical flow angular velocity noise gain", "type": "Float", "units": "m/rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.3, "group": "Local Position Estimator", "max": 10.0, "min": 0.1, "name": "LPE_FLW_SCALE", "shortDesc": "Optical flow scale", "type": "Float", "units": "m"}, {"bitmask": [{"description": "fuse GPS, requires GPS for alt. init", "index": 0}, {"description": "fuse optical flow", "index": 1}, {"description": "fuse vision position", "index": 2}, {"description": "fuse landing target", "index": 3}, {"description": "fuse land detector", "index": 4}, {"description": "pub agl as lpos down", "index": 5}, {"description": "flow gyro compensation", "index": 6}, {"description": "fuse baro", "index": 7}], "category": "Standard", "default": 145, "group": "Local Position Estimator", "longDesc": "Set bits in the following positions to enable:\n0 : Set to true to fuse GPS data if available, also requires GPS for altitude init\n1 : Set to true to fuse optical flow data if available\n2 : Set to true to fuse vision position\n3 : Set to true to enable landing target\n4 : Set to true to fuse land detector\n5 : Set to true to publish AGL as local position down component\n6 : Set to true to enable flow gyro compensation\n7 : Set to true to enable baro fusion\ndefault (145 - GPS, baro, land detector)", "max": 255, "min": 0, "name": "LPE_FUSION", "shortDesc": "Integer bitmask controlling data fusion", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.29, "group": "Local Position Estimator", "max": 0.4, "min": 0.0, "name": "LPE_GPS_DELAY", "shortDesc": "GPS delay compensaton", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Local Position Estimator", "longDesc": "EPV used if greater than this value.", "max": 2.0, "min": 0.01, "name": "LPE_GPS_VXY", "shortDesc": "GPS xy velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Local Position Estimator", "max": 2.0, "min": 0.01, "name": "LPE_GPS_VZ", "shortDesc": "GPS z velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Local Position Estimator", "max": 5.0, "min": 0.01, "name": "LPE_GPS_XY", "shortDesc": "Minimum GPS xy standard deviation, uses reported EPH if greater", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Local Position Estimator", "max": 200.0, "min": 0.01, "name": "LPE_GPS_Z", "shortDesc": "Minimum GPS z standard deviation, uses reported EPV if greater", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Local Position Estimator", "max": 10.0, "min": 0.01, "name": "LPE_LAND_VXY", "shortDesc": "Land detector xy velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Local Position Estimator", "max": 10.0, "min": 0.001, "name": "LPE_LAND_Z", "shortDesc": "Land detector z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 8, "default": 47.397742, "group": "Local Position Estimator", "max": 90.0, "min": -90.0, "name": "LPE_LAT", "shortDesc": "Local origin latitude for nav w/o GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_LDR_OFF_Z", "shortDesc": "Lidar z offset from center of vehicle +down", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_LDR_Z", "shortDesc": "Lidar z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 8, "default": 8.545594, "group": "Local Position Estimator", "max": 180.0, "min": -180.0, "name": "LPE_LON", "shortDesc": "Local origin longitude for nav w/o GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0001, "group": "Local Position Estimator", "max": 10.0, "min": 0.0, "name": "LPE_LT_COV", "shortDesc": "Minimum landing target standard covariance, uses reported covariance if greater", "type": "Float", "units": "m^2"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0, "name": "LPE_PN_B", "shortDesc": "Accel bias propagation noise density", "type": "Float", "units": "m/s^3/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Increase to trust measurements more.\nDecrease to trust model more.", "max": 1.0, "min": 0.0, "name": "LPE_PN_P", "shortDesc": "Position propagation noise density", "type": "Float", "units": "m/s/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0, "name": "LPE_PN_T", "shortDesc": "Terrain random walk noise density, hilly/outdoor (0.1), flat/Indoor (0.001)", "type": "Float", "units": "m/s/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Increase to trust measurements more.\nDecrease to trust model more.", "max": 1.0, "min": 0.0, "name": "LPE_PN_V", "shortDesc": "Velocity propagation noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_SNR_OFF_Z", "shortDesc": "Sonar z offset from center of vehicle +down", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_SNR_Z", "shortDesc": "Sonar z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Local Position Estimator", "longDesc": "Used to calculate increased terrain random walk nosie due to movement.", "max": 100.0, "min": 0.0, "name": "LPE_T_MAX_GRADE", "shortDesc": "Terrain maximum percent grade, hilly/outdoor (100 = 45 deg), flat/Indoor (0 = 0 deg)", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0001, "name": "LPE_VIC_P", "shortDesc": "Vicon position standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Set to zero to enable automatic compensation from measurement timestamps", "max": 0.1, "min": 0.0, "name": "LPE_VIS_DELAY", "shortDesc": "Vision delay compensation", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_VIS_XY", "shortDesc": "Vision xy standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "Local Position Estimator", "max": 100.0, "min": 0.01, "name": "LPE_VIS_Z", "shortDesc": "Vision z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.3, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_VXY_PUB", "shortDesc": "Required velocity xy standard deviation to publish position", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 5.0, "group": "Local Position Estimator", "max": 1000.0, "min": 5.0, "name": "LPE_X_LP", "shortDesc": "Cut frequency for state publication", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Local Position Estimator", "max": 5.0, "min": 0.3, "name": "LPE_Z_PUB", "shortDesc": "Required z standard deviation to publish altitude/ terrain", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_0_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 0", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_0_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 0", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_0_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 0", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 0, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_0_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 0", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_0_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 0", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_0_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 0", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1200, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_0_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 0", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 14550, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 0,\nselected remote port will be set and used in MAVLink instance 0.", "name": "MAV_0_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 0", "type": "Int32"}, {"category": "Standard", "default": 14556, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 0,\nselected udp port will be set and used in MAVLink instance 0.", "name": "MAV_0_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 0", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_1_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 1", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_1_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 1", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_1_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 1", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 1, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_1_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 1", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_1_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 1", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_1_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 1", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_1_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 1", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 1,\nselected remote port will be set and used in MAVLink instance 1.", "name": "MAV_1_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 1", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 1,\nselected udp port will be set and used in MAVLink instance 1.", "name": "MAV_1_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 1", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_2_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 2", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_2_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 2", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_2_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 2", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 2, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_2_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 2", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_2_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 2", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_2_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 2", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_2_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 2", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 2,\nselected remote port will be set and used in MAVLink instance 2.", "name": "MAV_2_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 2", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 2,\nselected udp port will be set and used in MAVLink instance 2.", "name": "MAV_2_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 2", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "max": 250, "min": 1, "name": "MAV_COMP_ID", "rebootRequired": true, "shortDesc": "MAVLink component ID", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If set to 1 incoming external setpoint messages will be directly forwarded\nto the controllers if in offboard control mode", "name": "MAV_FWDEXTSP", "shortDesc": "Forward external setpoint messages", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "Disabling the parameter hash check functionality will make the mavlink instance\nstream parameters continuously.", "name": "MAV_HASH_CHK_EN", "shortDesc": "Parameter hash check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "The mavlink heartbeat message will not be forwarded if this parameter is set to 'disabled'.\nThe main reason for disabling heartbeats to be forwarded is because they confuse dronekit.", "name": "MAV_HB_FORW_EN", "shortDesc": "Heartbeat message forwarding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "name": "MAV_PROTO_VER", "shortDesc": "MAVLink protocol version", "type": "Int32", "values": [{"description": "Default to 1, switch to 2 if GCS sends version 2", "value": 0}, {"description": "Always use version 1", "value": 1}, {"description": "Always use version 2", "value": 2}]}, {"category": "Standard", "default": 5, "group": "MAVLink", "longDesc": "If the connected radio stops reporting RADIO_STATUS for a certain time,\na warning is triggered and, if MAV_X_RADIO_CTL is enabled, the software-flow\ncontrol is reset.", "max": 250, "min": 1, "name": "MAV_RADIO_TOUT", "shortDesc": "Timeout in seconds for the RADIO_STATUS reports coming in", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "When non-zero the MAVLink app will attempt to configure the\nSiK radio to this ID and re-set the parameter to 0. If the value\nis negative it will reset the complete radio config to\nfactory defaults. Only applies if this mavlink instance is going through a SiK radio", "max": 240, "min": -1, "name": "MAV_SIK_RADIO_ID", "shortDesc": "MAVLink SiK Radio ID", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "max": 250, "min": 1, "name": "MAV_SYS_ID", "rebootRequired": true, "shortDesc": "MAVLink system ID", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "max": 22, "min": 0, "name": "MAV_TYPE", "shortDesc": "MAVLink airframe type", "type": "Int32", "values": [{"description": "Generic micro air vehicle", "value": 0}, {"description": "Fixed wing aircraft", "value": 1}, {"description": "Quadrotor", "value": 2}, {"description": "Coaxial helicopter", "value": 3}, {"description": "Normal helicopter with tail rotor", "value": 4}, {"description": "Airship, controlled", "value": 7}, {"description": "Free balloon, uncontrolled", "value": 8}, {"description": "Ground rover", "value": 10}, {"description": "Surface vessel, boat, ship", "value": 11}, {"description": "Submarine", "value": 12}, {"description": "Hexarotor", "value": 13}, {"description": "Octorotor", "value": 14}, {"description": "Tricopter", "value": 15}, {"description": "VTOL Two-rotor Tailsitter", "value": 19}, {"description": "VTOL Quad-rotor Tailsitter", "value": 20}, {"description": "VTOL Tiltrotor", "value": 21}, {"description": "VTOL Standard (separate fixed rotors for hover and cruise flight)", "value": 22}, {"description": "VTOL Tailsitter", "value": 23}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If set to 1 incoming HIL GPS messages are parsed.", "name": "MAV_USEHILGPS", "shortDesc": "Use/Accept HIL GPS message even if not in HIL mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Magnetometer Bias Estimator", "longDesc": "This enables continuous calibration of the magnetometers\nbefore takeoff using gyro data.", "name": "MBE_ENABLE", "rebootRequired": true, "shortDesc": "Enable online mag bias calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 18.0, "group": "Magnetometer Bias Estimator", "increment": 0.1, "longDesc": "Increase to make the estimator more responsive\nDecrease to make the estimator more robust to noise", "max": 100.0, "min": 0.1, "name": "MBE_LEARN_GAIN", "shortDesc": "Mag bias estimator learning gain", "type": "Float"}, {"category": "Standard", "default": 1, "group": "Manual Control", "longDesc": "This determines if moving the left stick to the lower right\narms and to the lower left disarms the vehicle.", "name": "MAN_ARM_GESTURE", "shortDesc": "Enable arm/disarm stick gesture", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Manual Control", "longDesc": "The timeout for holding the left stick to the lower left\nand the right stick to the lower right at the same time until the gesture\nkills the actuators one-way.\nA negative value disables the feature.", "max": 15.0, "min": -1.0, "name": "MAN_KILL_GEST_T", "shortDesc": "Trigger time for kill stick gesture", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Mission", "longDesc": "Ensure:\ngripper: NAV_CMD_DO_GRIPPER\nhas released before continuing mission.\nwinch: CMD_DO_WINCH\nhas delivered before continuing mission.\ngimbal: CMD_DO_GIMBAL_MANAGER_PITCHYAW\nhas reached the commanded orientation before beginning to take pictures.", "min": 0.0, "name": "MIS_COMMAND_TOUT", "shortDesc": "Timeout to allow the payload to execute the mission command", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10000.0, "group": "Mission", "increment": 100.0, "longDesc": "There will be a warning message if the current waypoint is more distant than MIS_DIST_1WP from Home.\nHas no effect on mission validity.\nSet a value of zero or less to disable.", "max": 100000.0, "min": -1.0, "name": "MIS_DIST_1WP", "shortDesc": "Maximal horizontal distance from Home to first waypoint", "type": "Float", "units": "m"}, {"category": "Standard", "default": 30, "group": "Mission", "longDesc": "Minimum altitude above landing point that the vehicle will climb to after an aborted landing.\nThen vehicle will loiter in this altitude until further command is received.\nOnly applies to fixed-wing vehicles.", "min": 0, "name": "MIS_LND_ABRT_ALT", "shortDesc": "Landing abort min altitude", "type": "Int32", "units": "m"}, {"category": "Standard", "default": 0, "group": "Mission", "longDesc": "If enabled, yaw commands will be sent to the mount and the vehicle will follow its heading towards the flight direction.\nIf disabled, the vehicle will yaw towards the ROI.", "max": 1, "min": 0, "name": "MIS_MNT_YAW_CTL", "shortDesc": "Enable yaw control of the mount. (Only affects multicopters and ROI mission items)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Enable", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "Mission", "increment": 0.5, "longDesc": "This is the relative altitude the system will take off to\nif not otherwise specified.", "min": 0.0, "name": "MIS_TAKEOFF_ALT", "shortDesc": "Default take-off altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Mission", "longDesc": "Specifies if a mission has to contain a takeoff and/or mission landing.\nValidity of configured takeoffs/landings is checked independently of the setting here.", "name": "MIS_TKO_LAND_REQ", "shortDesc": "Mission takeoff/landing required", "type": "Int32", "values": [{"description": "No requirements", "value": 0}, {"description": "Require a takeoff", "value": 1}, {"description": "Require a landing", "value": 2}, {"description": "Require a takeoff and a landing", "value": 3}, {"description": "Require both a takeoff and a landing, or neither", "value": 4}, {"description": "Same as previous when landed, in-air require landing only if no valid VTOL approach is present", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": 12.0, "group": "Mission", "increment": 1.0, "max": 90.0, "min": 0.0, "name": "MIS_YAW_ERR", "shortDesc": "Max yaw error in degrees needed for waypoint heading acceptance", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 1.0, "longDesc": "If set > 0 it will ignore the target heading for normal waypoint acceptance. If the\nwaypoint forces the heading the timeout will matter. For example on VTOL forwards transition.\nMainly useful for VTOLs that have less yaw authority and might not reach target\nyaw in wind. Disabled by default.", "max": 20.0, "min": -1.0, "name": "MIS_YAW_TMT", "shortDesc": "Time in seconds we wait on reaching target heading at a waypoint if it is forced", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Mission", "max": 4, "min": 0, "name": "MPC_YAW_MODE", "shortDesc": "Heading behavior in autonomous modes", "type": "Int32", "values": [{"description": "towards waypoint", "value": 0}, {"description": "towards home", "value": 1}, {"description": "away from home", "value": 2}, {"description": "along trajectory", "value": 3}, {"description": "towards waypoint (yaw first)", "value": 4}, {"description": "yaw fixed", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Mission", "increment": 0.5, "longDesc": "Default acceptance radius, overridden by acceptance radius of waypoint if set.\nFor fixed wing the npfg switch distance is used for horizontal acceptance.", "max": 200.0, "min": 0.05, "name": "NAV_ACC_RAD", "shortDesc": "Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Mission", "name": "NAV_FORCE_VT", "shortDesc": "Force VTOL mode takeoff and land", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Mission", "longDesc": "Altitude acceptance used for the last waypoint before a fixed-wing landing. This is usually smaller\nthan the standard vertical acceptance because close to the ground higher accuracy is required.", "max": 200.0, "min": 0.05, "name": "NAV_FW_ALTL_RAD", "shortDesc": "FW Altitude Acceptance Radius before a landing", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Mission", "increment": 0.5, "longDesc": "Acceptance radius for fixedwing altitude.", "max": 200.0, "min": 0.05, "name": "NAV_FW_ALT_RAD", "shortDesc": "FW Altitude Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 80.0, "group": "Mission", "increment": 0.5, "longDesc": "Default value of loiter radius in FW mode (e.g. for Loiter mode).", "max": 1000.0, "min": 25.0, "name": "NAV_LOITER_RAD", "shortDesc": "Loiter radius (FW only)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.8, "group": "Mission", "increment": 0.5, "longDesc": "Acceptance radius for multicopter altitude.", "max": 200.0, "min": 0.05, "name": "NAV_MC_ALT_RAD", "shortDesc": "MC Altitude Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 1.0, "longDesc": "Minimum height above ground the vehicle is allowed to descend to during Mission and RTL,\nexcluding landing commands.\nRequires a distance sensor to be set up.\nNote: only prevents the vehicle from descending further, but does not force it to climb.\nSet to a negative value to disable.", "min": -1.0, "name": "NAV_MIN_GND_DIST", "shortDesc": "Minimum height above ground during Mission and RTL", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 0.5, "longDesc": "This is the minimum altitude above Home the system will always obey in Loiter (Hold) mode if switched into this\nmode without specifying an altitude (e.g. through Loiter switch on RC).\nDoesn't affect Loiters that are part of Missions or that are entered through a reposition setpoint (\"Go to\").\nSet to a negative value to disable.", "min": -1.0, "name": "NAV_MIN_LTR_ALT", "shortDesc": "Minimum Loiter altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Mission", "longDesc": "Enabling this will allow the system to respond\nto transponder data from e.g. ADSB transponders", "name": "NAV_TRAFF_AVOID", "shortDesc": "Set traffic avoidance mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warn only", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Position Hold mode", "value": 4}]}, {"category": "Standard", "default": 500.0, "group": "Mission", "longDesc": "Defines a crosstrack horizontal distance", "min": 500.0, "name": "NAV_TRAFF_A_HOR", "shortDesc": "Set NAV TRAFFIC AVOID horizontal distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 500.0, "group": "Mission", "max": 500.0, "min": 10.0, "name": "NAV_TRAFF_A_VER", "shortDesc": "Set NAV TRAFFIC AVOID vertical distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 60, "group": "Mission", "longDesc": "Minimum acceptable time until collsion.\nAssumes constant speed over 3d distance.", "max": 900000000, "min": 1, "name": "NAV_TRAFF_COLL_T", "shortDesc": "Estimated time until collision", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Mixer Output", "longDesc": "The air-mode enables the mixer to increase the total thrust of the multirotor\nin order to keep attitude and rate control even at low and high throttle.\nThis function should be disabled during tuning as it will help the controller\nto diverge if the closed-loop is unstable (i.e. the vehicle is not tuned yet).\nEnabling air-mode for yaw requires the use of an arming switch.", "name": "MC_AIRMODE", "shortDesc": "Multicopter air-mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Roll/Pitch", "value": 1}, {"description": "Roll/Pitch/Yaw", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Mount", "longDesc": "Set to true for servo gimbal, false for passthrough.\nThis is required for a gimbal which is not capable of stabilizing itself\nand relies on the IMU's attitude estimation.", "max": 2, "min": 0, "name": "MNT_DO_STAB", "shortDesc": "Stabilize the mount", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Stabilize all axis", "value": 1}, {"description": "Stabilize yaw for absolute/lock mode.", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 90.0, "group": "Mount", "max": 90.0, "min": -90.0, "name": "MNT_LND_P_MAX", "shortDesc": "Pitch maximum when landed", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -90.0, "group": "Mount", "max": 90.0, "min": -90.0, "name": "MNT_LND_P_MIN", "shortDesc": "Pitch minimum when landed", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_PITCH", "shortDesc": "Auxiliary channel to control pitch (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_ROLL", "shortDesc": "Auxiliary channel to control roll (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_YAW", "shortDesc": "Auxiliary channel to control yaw (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 154, "group": "Mount", "longDesc": "If MNT_MODE_OUT is MAVLink protocol v2, mount configure/control commands will be sent with this component ID.", "name": "MNT_MAV_COMPID", "shortDesc": "Mavlink Component ID of the mount", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "Mount", "longDesc": "If MNT_MODE_OUT is MAVLink gimbal protocol v1, mount configure/control commands will be sent with this target ID.", "name": "MNT_MAV_SYSID", "shortDesc": "Mavlink System ID of the mount", "type": "Int32"}, {"category": "Standard", "default": -1, "group": "Mount", "longDesc": "This is the protocol used between the ground station and the autopilot.\nRecommended is Auto, RC only or MAVLink gimbal protocol v2.\nThe rest will be deprecated.", "max": 4, "min": -1, "name": "MNT_MODE_IN", "rebootRequired": true, "shortDesc": "Mount input mode", "type": "Int32", "values": [{"description": "DISABLED", "value": -1}, {"description": "Auto (RC and MAVLink gimbal protocol v2)", "value": 0}, {"description": "RC", "value": 1}, {"description": "MAVLINK_ROI (protocol v1, to be deprecated)", "value": 2}, {"description": "MAVLINK_DO_MOUNT (protocol v1, to be deprecated)", "value": 3}, {"description": "MAVlink gimbal protocol v2", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Mount", "longDesc": "This is the protocol used between the autopilot and a connected gimbal.\nRecommended is the MAVLink gimbal protocol v2 if the gimbal supports it.", "max": 2, "min": 0, "name": "MNT_MODE_OUT", "rebootRequired": true, "shortDesc": "Mount output mode", "type": "Int32", "values": [{"description": "AUX", "value": 0}, {"description": "MAVLink gimbal protocol v1", "value": 1}, {"description": "MAVLink gimbal protocol v2", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Mount", "max": 360.0, "min": -360.0, "name": "MNT_OFF_PITCH", "shortDesc": "Offset for pitch channel output in degrees", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Mount", "max": 360.0, "min": -360.0, "name": "MNT_OFF_ROLL", "shortDesc": "Offset for roll channel output in degrees", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Mount", "max": 360.0, "min": -360.0, "name": "MNT_OFF_YAW", "shortDesc": "Offset for yaw channel output in degrees", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 90.0, "group": "Mount", "max": 720.0, "min": 1.0, "name": "MNT_RANGE_PITCH", "shortDesc": "Range of pitch channel output in degrees (only in AUX output mode)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 90.0, "group": "Mount", "max": 720.0, "min": 1.0, "name": "MNT_RANGE_ROLL", "shortDesc": "Range of roll channel output in degrees (only in AUX output mode)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 360.0, "group": "Mount", "max": 720.0, "min": 1.0, "name": "MNT_RANGE_YAW", "shortDesc": "Range of yaw channel output in degrees (only in AUX output mode)", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 30.0, "group": "Mount", "longDesc": "Full stick input [-1..1] translats to [-pitch rate..pitch rate].", "max": 90.0, "min": 1.0, "name": "MNT_RATE_PITCH", "shortDesc": "Angular pitch rate for manual input in degrees/second", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 30.0, "group": "Mount", "longDesc": "Full stick input [-1..1] translats to [-yaw rate..yaw rate].", "max": 90.0, "min": 1.0, "name": "MNT_RATE_YAW", "shortDesc": "Angular yaw rate for manual input in degrees/second", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 1, "group": "Mount", "max": 1, "min": 0, "name": "MNT_RC_IN_MODE", "shortDesc": "Input mode for RC gimbal input", "type": "Int32", "values": [{"description": "Angle", "value": 0}, {"description": "Angular rate", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "Exponential factor for tuning the input curve shape.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MC_ACRO_EXPO", "shortDesc": "Acro mode roll, pitch expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "Exponential factor for tuning the input curve shape.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MC_ACRO_EXPO_Y", "shortDesc": "Acro mode yaw expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_P_MAX", "shortDesc": "Acro mode maximum pitch rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_R_MAX", "shortDesc": "Acro mode maximum roll rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "\"Superexponential\" factor for refining the input curve shape tuned using MC_ACRO_EXPO.\n0 Pure Expo function\n0.7 reasonable shape enhancement for intuitive stick feel\n0.95 very strong bent input curve only near maxima have effect", "max": 0.95, "min": 0.0, "name": "MC_ACRO_SUPEXPO", "shortDesc": "Acro mode roll, pitch super expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "\"Superexponential\" factor for refining the input curve shape tuned using MC_ACRO_EXPO_Y.\n0 Pure Expo function\n0.7 reasonable shape enhancement for intuitive stick feel\n0.95 very strong bent input curve only near maxima have effect", "max": 0.95, "min": 0.0, "name": "MC_ACRO_SUPEXPOY", "shortDesc": "Acro mode yaw super expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_Y_MAX", "shortDesc": "Acro mode maximum yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 220.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limit for pitch rate in manual and auto modes (except acro).\nHas effect for large rotations in autonomous mode, to avoid large control\noutput and mixer saturation.\nThis is not only limited by the vehicle's properties, but also by the maximum\nmeasurement rate of the gyro.", "max": 1800.0, "min": 0.0, "name": "MC_PITCHRATE_MAX", "shortDesc": "Max pitch rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Pitch proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 12.0, "min": 0.0, "name": "MC_PITCH_P", "shortDesc": "Pitch P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 220.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limit for roll rate in manual and auto modes (except acro).\nHas effect for large rotations in autonomous mode, to avoid large control\noutput and mixer saturation.\nThis is not only limited by the vehicle's properties, but also by the maximum\nmeasurement rate of the gyro.", "max": 1800.0, "min": 0.0, "name": "MC_ROLLRATE_MAX", "shortDesc": "Max roll rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Roll proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 12.0, "min": 0.0, "name": "MC_ROLL_P", "shortDesc": "Roll P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 200.0, "group": "Multicopter Attitude Control", "increment": 5.0, "max": 1800.0, "min": 0.0, "name": "MC_YAWRATE_MAX", "shortDesc": "Max yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.8, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Yaw proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 5.0, "min": 0.0, "name": "MC_YAW_P", "shortDesc": "Yaw P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "A fraction [0,1] deprioritizing yaw compared to roll and pitch in non-linear attitude control.\nDeprioritizing yaw is necessary because multicopters have much less control authority\nin yaw compared to the other axes and it makes sense because yaw is not critical for\nstable hovering or 3D navigation.\nFor yaw control tuning use MC_YAW_P. This ratio has no impact on the yaw gain.", "max": 1.0, "min": 0.0, "name": "MC_YAW_WEIGHT", "shortDesc": "Yaw weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": 20.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limits the acceleration of the yaw setpoint to avoid large\ncontrol output and mixer saturation.", "max": 360.0, "min": 5.0, "name": "MPC_YAWRAUTO_ACC", "shortDesc": "Maximum yaw acceleration in autonomous modes", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 0, "default": 60.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limits the rate of change of the yaw setpoint to avoid large\ncontrol output and mixer saturation.", "max": 360.0, "min": 5.0, "name": "MPC_YAWRAUTO_MAX", "shortDesc": "Maximum yaw rate in autonomous modes", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0.4, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "max": 1.0, "min": 0.0, "name": "CP_DELAY", "shortDesc": "Average delay of the range sensor message plus the tracking delay of the position controller in seconds", "type": "Float", "units": "s"}, {"category": "Standard", "default": -1.0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode. Collision avoidance is disabled by setting this parameter to a negative value", "max": 15.0, "min": -1.0, "name": "CP_DIST", "shortDesc": "Minimum distance the vehicle should keep to all obstacles", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "name": "CP_GO_NO_DATA", "shortDesc": "Boolean to allow moving into directions where there is no sensor data (outside FOV)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 30.0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "max": 90.0, "min": 0.0, "name": "CP_GUIDE_ANG", "shortDesc": "Angle left/right from the commanded setpoint by which the collision prevention algorithm can choose to change the setpoint direction", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Position Control", "longDesc": "Setting this parameter to 0 disables the filter", "max": 2.0, "min": 0.0, "name": "MC_MAN_TILT_TAU", "shortDesc": "Manual tilt input filter time constant", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Multicopter Position Control", "longDesc": "Set to decouple tilt from vertical acceleration.\nThis provides smoother flight but slightly worse tracking in position and auto modes.\nUnset if accurate position tracking during dynamic maneuvers is more important than a smooth flight.", "name": "MPC_ACC_DECOUPLE", "shortDesc": "Acceleration to tilt coupling", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 15.0, "min": 2.0, "name": "MPC_ACC_DOWN_MAX", "shortDesc": "Maximum downwards acceleration in climb rate controlled modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "When piloting manually, this parameter is only used in MPC_POS_MODE Acceleration based.", "max": 15.0, "min": 2.0, "name": "MPC_ACC_HOR", "shortDesc": "Acceleration for autonomous and for manual modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "MPC_POS_MODE\n1 just deceleration\n4 not used, use MPC_ACC_HOR instead", "max": 15.0, "min": 2.0, "name": "MPC_ACC_HOR_MAX", "shortDesc": "Maximum horizontal acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 15.0, "min": 2.0, "name": "MPC_ACC_UP_MAX", "shortDesc": "Maximum upwards acceleration in climb rate controlled modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "default": 2, "group": "Multicopter Position Control", "longDesc": "Control height\n0: relative earth frame origin which may drift due to sensors\n1: relative to ground (requires distance sensor) which changes with terrain variation.\nIt will revert to relative earth frame if the distance to ground estimate becomes invalid.\n2: relative to ground (requires distance sensor) when stationary\nand relative to earth frame when moving horizontally.\nThe speed threshold is MPC_HOLD_MAX_XY", "max": 2, "min": 0, "name": "MPC_ALT_MODE", "shortDesc": "Altitude reference mode", "type": "Int32", "values": [{"description": "Altitude following", "value": 0}, {"description": "Terrain following", "value": 1}, {"description": "Terrain hold", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Does not apply to manual throttle and direct attitude piloting by stick.", "max": 1.0, "min": 0.0, "name": "MPC_HOLD_DZ", "shortDesc": "Deadzone for sticks in manual piloted modes", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.8, "group": "Multicopter Position Control", "longDesc": "Only used with MPC_POS_MODE Direct velocity or MPC_ALT_MODE 2", "max": 3.0, "min": 0.0, "name": "MPC_HOLD_MAX_XY", "shortDesc": "Maximum horizontal velocity for which position hold is enabled (use 0 to disable check)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "Multicopter Position Control", "longDesc": "Only used with MPC_ALT_MODE 1", "max": 3.0, "min": 0.0, "name": "MPC_HOLD_MAX_Z", "shortDesc": "Maximum vertical velocity for which position hold is enabled (use 0 to disable check)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Limit the maximum jerk of the vehicle (how fast the acceleration can change).\nA lower value leads to smoother vehicle motions but also limited agility.", "max": 80.0, "min": 1.0, "name": "MPC_JERK_AUTO", "shortDesc": "Jerk limit in autonomous modes", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 0, "default": 8.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Limit the maximum jerk (acceleration change) of the vehicle.\nA lower value leads to smoother motions but limits agility.\nSetting this to the maximum value essentially disables the limit.\nOnly used with MPC_POS_MODE Acceleration based.", "max": 500.0, "min": 0.5, "name": "MPC_JERK_MAX", "shortDesc": "Maximum horizontal and vertical jerk in Position/Altitude mode", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Multicopter Position Control", "longDesc": "Below this altitude descending velocity gets limited to a value\nbetween \"MPC_Z_VEL_MAX_DN\" (or \"MPC_Z_V_AUTO_DN\") and \"MPC_LAND_SPEED\"\nValue needs to be higher than \"MPC_LAND_ALT2\"", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT1", "shortDesc": "Altitude for 1. step of slow landing (descend)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "longDesc": "Below this altitude descending velocity gets\nlimited to \"MPC_LAND_SPEED\"\nValue needs to be lower than \"MPC_LAND_ALT1\"", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT2", "shortDesc": "Altitude for 2. step of slow landing (landing)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Multicopter Position Control", "longDesc": "If a valid distance sensor measurement to the ground is available,\nlimit descending velocity to \"MPC_LAND_CRWL\" below this altitude.", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT3", "shortDesc": "Altitude for 3. step of slow landing", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.3, "group": "Multicopter Position Control", "longDesc": "Used below MPC_LAND_ALT3 if distance sensor data is availabe.", "min": 0.1, "name": "MPC_LAND_CRWL", "shortDesc": "Land crawl descend rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 1000.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "When nudging is enabled (see MPC_LAND_RC_HELP), this controls\nthe maximum allowed horizontal displacement from the original landing point.", "min": 0.0, "name": "MPC_LAND_RADIUS", "shortDesc": "User assisted landing radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Using stick input the vehicle can be moved horizontally and yawed.\nThe descend speed is amended:\nstick full up - 0\nstick centered - MPC_LAND_SPEED\nstick full down - 2 * MPC_LAND_SPEED\nManual override during auto modes has to be disabled to use this feature (see COM_RC_OVERRIDE).", "max": 1, "min": 0, "name": "MPC_LAND_RC_HELP", "shortDesc": "Enable nudging based on user input during autonomous land routine", "type": "Int32", "values": [{"description": "Nudging disabled", "value": 0}, {"description": "Nudging enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.7, "group": "Multicopter Position Control", "min": 0.6, "name": "MPC_LAND_SPEED", "shortDesc": "Landing descend rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "The value is mapped to the lowest throttle stick position in Stabilized mode.\nToo low collective thrust leads to loss of roll/pitch/yaw torque control authority.\nAirmode is used to keep torque authority with zero thrust (see MC_AIRMODE).", "max": 1.0, "min": 0.0, "name": "MPC_MANTHR_MIN", "shortDesc": "Minimum collective thrust in Stabilized mode", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 0, "default": 35.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 70.0, "min": 1.0, "name": "MPC_MAN_TILT_MAX", "shortDesc": "Maximal tilt angle in Stabilized or Altitude mode", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 150.0, "group": "Multicopter Position Control", "increment": 10.0, "max": 400.0, "min": 0.0, "name": "MPC_MAN_Y_MAX", "shortDesc": "Max manual yaw rate for Stabilized, Altitude, Position mode", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Not used in Stabilized mode\nSetting this parameter to 0 disables the filter", "max": 5.0, "min": 0.0, "name": "MPC_MAN_Y_TAU", "shortDesc": "Manual yaw rate input filter time constant", "type": "Float", "units": "s"}, {"category": "Standard", "default": 4, "group": "Multicopter Position Control", "longDesc": "The supported sub-modes are:\nDirect velocity:\nSticks directly map to velocity setpoints without smoothing.\nAlso applies to vertical direction and Altitude mode.\nUseful for velocity control tuning.\nAcceleration based:\nSticks map to acceleration and there's a virtual brake drag", "name": "MPC_POS_MODE", "shortDesc": "Position/Altitude mode variant", "type": "Int32", "values": [{"description": "Direct velocity", "value": 0}, {"description": "Acceleration based", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Defines how the throttle stick is mapped to collective thrust in Stabilized mode.\nRescale to hover thrust estimate:\nStick input is linearly rescaled, such that a centered throttle stick corresponds to the hover thrust estimator's output.\nNo rescale:\nDirectly map the stick 1:1 to the output.\nCan be useful with very low hover thrust which leads to much distortion and the upper half getting sensitive.\nRescale to hover thrust parameter:\nSimilar to rescaling to the hover thrust estimate, but it uses the hover thrust parameter value (see MPC_THR_HOVER) instead of estimated value.\nWith MPC_THR_HOVER 0.5 it's equivalent to No rescale.", "name": "MPC_THR_CURVE", "shortDesc": "Thrust curve mapping in Stabilized Mode", "type": "Int32", "values": [{"description": "Rescale to estimate", "value": 0}, {"description": "No rescale", "value": 1}, {"description": "Rescale to parameter", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Mapped to center throttle stick in Stabilized mode (see MPC_THR_CURVE).\nUsed for initialization of the hover thrust estimator (see MPC_USE_HTE).\nThe estimated hover thrust is used as base for zero vertical acceleration in altitude control.\nThe hover thrust is important for land detection to work correctly.", "max": 0.8, "min": 0.1, "name": "MPC_THR_HOVER", "shortDesc": "Vertical thrust required to hover", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Control", "increment": 0.05, "longDesc": "Limit allowed thrust e.g. for indoor test of overpowered vehicle.", "max": 1.0, "min": 0.0, "name": "MPC_THR_MAX", "shortDesc": "Maximum collective thrust in climb rate controlled modes", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.12, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Too low thrust leads to loss of roll/pitch/yaw torque control authority.\nWith airmode enabled this parameters can be set to 0\nwhile still keeping torque authority (see MC_AIRMODE).", "max": 0.5, "min": 0.05, "name": "MPC_THR_MIN", "shortDesc": "Minimum collective thrust in climb rate controlled modes", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Margin that is kept for horizontal control when higher priority vertical thrust is saturated.\nTo avoid completely starving horizontal control with high vertical error.", "max": 0.5, "min": 0.0, "name": "MPC_THR_XY_MARG", "shortDesc": "Horizontal thrust margin", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 0, "default": 45.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Absolute maximum for all velocity or acceleration controlled modes.\nAny higher value is truncated.", "max": 89.0, "min": 20.0, "name": "MPC_TILTMAX_AIR", "shortDesc": "Maximum tilt angle in air", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 12.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Tighter tilt limit during takeoff to avoid tip over.", "max": 89.0, "min": 5.0, "name": "MPC_TILTMAX_LND", "shortDesc": "Maximum tilt during inital takeoff ramp", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 3.0, "group": "Multicopter Position Control", "longDesc": "Increasing this value will make climb rate controlled takeoff slower.\nIf it's too slow the drone might scratch the ground and tip over.\nA time constant of 0 disables the ramp", "max": 5.0, "min": 0.0, "name": "MPC_TKO_RAMP_T", "shortDesc": "Smooth takeoff ramp time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.5, "group": "Multicopter Position Control", "max": 5.0, "min": 1.0, "name": "MPC_TKO_SPEED", "shortDesc": "Takeoff climb rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "Multicopter Position Control", "longDesc": "Disable to use the fixed parameter MPC_THR_HOVER instead of the hover thrust estimate in the position controller.\nThis parameter does not influence Stabilized mode throttle curve (see MPC_THR_CURVE).", "name": "MPC_USE_HTE", "shortDesc": "Use hover thrust estimate for altitude control", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VELD_LP", "shortDesc": "Velocity derivative low pass cutoff frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_LP", "shortDesc": "Velocity low pass cutoff frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Must be smaller than MPC_XY_VEL_MAX.\nThe maximum sideways and backward speed can be set differently\nusing MPC_VEL_MAN_SIDE and MPC_VEL_MAN_BACK, respectively.", "max": 20.0, "min": 3.0, "name": "MPC_VEL_MANUAL", "shortDesc": "Maximum horizontal velocity setpoint in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a negative value or larger than\nMPC_VEL_MANUAL then MPC_VEL_MANUAL is used.", "max": 20.0, "min": -1.0, "name": "MPC_VEL_MAN_BACK", "shortDesc": "Maximum backward velocity in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a negative value or larger than\nMPC_VEL_MANUAL then MPC_VEL_MANUAL is used.", "max": 20.0, "min": -1.0, "name": "MPC_VEL_MAN_SIDE", "shortDesc": "Maximum sideways velocity in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_NF_BW", "shortDesc": "Velocity notch filter bandwidth", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "The center frequency for the 2nd order notch filter on the velocity.\nA value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_NF_FRQ", "shortDesc": "Velocity notch filter frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 0, "default": 5.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "e.g. in Missions, RTL, Goto if the waypoint does not specify differently", "max": 20.0, "min": 3.0, "name": "MPC_XY_CRUISE", "shortDesc": "Default horizontal velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "The integration speed of the trajectory setpoint is linearly\nreduced with the horizontal position tracking error. When the\nerror is above this parameter, the integration of the\ntrajectory is stopped to wait for the drone.\nThis value can be adjusted depending on the tracking\ncapabilities of the vehicle.", "max": 10.0, "min": 0.1, "name": "MPC_XY_ERR_MAX", "shortDesc": "Maximum horizontal error allowed by the trajectory generator", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "The higher the value the less sensitivity the stick has around zero\nwhile still reaching the maximum value with full stick deflection.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MPC_XY_MAN_EXPO", "shortDesc": "Manual position control stick exponential curve sensitivity", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.95, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective velocity in m/s per m position error", "max": 2.0, "min": 0.0, "name": "MPC_XY_P", "shortDesc": "Proportional gain for horizontal position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Multicopter Position Control", "increment": 0.1, "max": 1.0, "min": 0.1, "name": "MPC_XY_TRAJ_P", "shortDesc": "Proportional gain for horizontal trajectory position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": -10.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a value greater than zero, other parameters are automatically set (such as\nMPC_XY_VEL_MAX or MPC_VEL_MANUAL).\nIf set to a negative value, the existing individual parameters are used.", "max": 20.0, "min": -20.0, "name": "MPC_XY_VEL_ALL", "shortDesc": "Overall Horizontal Velocity Limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s^2 velocity derivative", "max": 2.0, "min": 0.1, "name": "MPC_XY_VEL_D_ACC", "shortDesc": "Differential gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as correction acceleration in m/s^2 per m velocity integral\nAllows to eliminate steady state errors in disturbances like wind.", "max": 60.0, "min": 0.0, "name": "MPC_XY_VEL_I_ACC", "shortDesc": "Integral gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 12.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Absolute maximum for all velocity controlled modes.\nAny higher value is truncated.", "max": 20.0, "min": 0.0, "name": "MPC_XY_VEL_MAX", "shortDesc": "Maximum horizontal velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.8, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s velocity error", "max": 5.0, "min": 1.2, "name": "MPC_XY_VEL_P_ACC", "shortDesc": "Proportional gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "The higher the value the less sensitivity the stick has around zero\nwhile still reaching the maximum value with full stick deflection.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MPC_YAW_EXPO", "shortDesc": "Manual control stick yaw rotation exponential curve", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "The higher the value the less sensitivity the stick has around zero\nwhile still reaching the maximum value with full stick deflection.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MPC_Z_MAN_EXPO", "shortDesc": "Manual control stick vertical exponential curve", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective velocity in m/s per m position error", "max": 1.5, "min": 0.1, "name": "MPC_Z_P", "shortDesc": "Proportional gain for vertical position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": -3.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "If set to a value greater than zero, other parameters are automatically set (such as\nMPC_Z_VEL_MAX_UP or MPC_LAND_SPEED).\nIf set to a negative value, the existing individual parameters are used.", "max": 8.0, "min": -3.0, "name": "MPC_Z_VEL_ALL", "shortDesc": "Overall Vertical Velocity Limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s^2 velocity derivative", "max": 2.0, "min": 0.0, "name": "MPC_Z_VEL_D_ACC", "shortDesc": "Differential gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m velocity integral", "max": 3.0, "min": 0.2, "name": "MPC_Z_VEL_I_ACC", "shortDesc": "Integral gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Absolute maximum for all climb rate controlled modes.\nIn manually piloted modes full stick deflection commands this velocity.\nFor default autonomous velocity see MPC_Z_V_AUTO_UP", "max": 4.0, "min": 0.5, "name": "MPC_Z_VEL_MAX_DN", "shortDesc": "Maximum descent velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Absolute maximum for all climb rate controlled modes.\nIn manually piloted modes full stick deflection commands this velocity.\nFor default autonomous velocity see MPC_Z_V_AUTO_UP", "max": 8.0, "min": 0.5, "name": "MPC_Z_VEL_MAX_UP", "shortDesc": "Maximum ascent velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s velocity error", "max": 15.0, "min": 2.0, "name": "MPC_Z_VEL_P_ACC", "shortDesc": "Proportional gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "For manual modes and offboard, see MPC_Z_VEL_MAX_DN", "max": 4.0, "min": 0.5, "name": "MPC_Z_V_AUTO_DN", "shortDesc": "Descent velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "For manually controlled modes and offboard see MPC_Z_VEL_MAX_UP", "max": 8.0, "min": 0.5, "name": "MPC_Z_V_AUTO_UP", "shortDesc": "Ascent velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": -0.4, "group": "Multicopter Position Control", "increment": 0.05, "longDesc": "Changes the overall responsiveness of the vehicle.\nThe higher the value, the faster the vehicle will react.\nIf set to a value greater than zero, other parameters are automatically set (such as\nthe acceleration or jerk limits).\nIf set to a negative value, the existing individual parameters are used.", "max": 1.0, "min": -1.0, "name": "SYS_VEHICLE_RESP", "shortDesc": "Responsiveness", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "name": "WV_EN", "shortDesc": "Enable weathervane", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1.0, "group": "Multicopter Position Control", "max": 5.0, "min": 0.0, "name": "WV_ROLL_MIN", "shortDesc": "Minimum roll angle setpoint for weathervane controller to demand a yaw-rate", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 90.0, "group": "Multicopter Position Control", "max": 120.0, "min": 0.0, "name": "WV_YRATE_MAX", "shortDesc": "Maximum yawrate the weathervane controller is allowed to demand", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 0.1, "name": "MC_SLOW_DEF_HVEL", "shortDesc": "Default horizontal velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 0.1, "name": "MC_SLOW_DEF_VVEL", "shortDesc": "Default vertical velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 45.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 1.0, "name": "MC_SLOW_DEF_YAWR", "shortDesc": "Default yaw rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_HVEL", "shortDesc": "Manual input mapped to scale horizontal velocity in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_PTCH", "shortDesc": "RC_MAP_AUX{N} to allow for gimbal pitch rate control in position slow mode", "type": "Int32", "values": [{"description": "No pitch rate input", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_VVEL", "shortDesc": "Manual input mapped to scale vertical velocity in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_YAWR", "shortDesc": "Manual input mapped to scale yaw rate in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this velocity.", "min": 0.1, "name": "MC_SLOW_MIN_HVEL", "shortDesc": "Horizontal velocity lower limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this velocity.", "min": 0.1, "name": "MC_SLOW_MIN_VVEL", "shortDesc": "Vertical velocity lower limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 3.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this rate.", "min": 1.0, "name": "MC_SLOW_MIN_YAWR", "shortDesc": "Yaw rate lower limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0, "group": "Multicopter Rate Control", "longDesc": "This compensates for voltage drop of the battery over time by attempting to\nnormalize performance across the operating range of the battery. The copter\nshould constantly behave as if it was fully charged with reduced max acceleration\nat lower battery percentages. i.e. if hover is at 0.5 throttle at 100% battery,\nit will still be 0.5 at 60% battery.", "name": "MC_BAT_SCALE_EN", "shortDesc": "Battery power level scaler", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 4, "default": 0.003, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Pitch rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "min": 0.0, "name": "MC_PITCHRATE_D", "shortDesc": "Pitch rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_PITCHRATE_FF", "shortDesc": "Pitch rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_PITCHRATE_I", "shortDesc": "Pitch rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_PITCHRATE_K * (MC_PITCHRATE_P * error\n+ MC_PITCHRATE_I * error_integral\n+ MC_PITCHRATE_D * error_derivative)\nSet MC_PITCHRATE_P=1 to implement a PID in the ideal form.\nSet MC_PITCHRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.01, "name": "MC_PITCHRATE_K", "shortDesc": "Pitch rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.6, "min": 0.01, "name": "MC_PITCHRATE_P", "shortDesc": "Pitch rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large pitch moment trim changes.", "min": 0.0, "name": "MC_PR_INT_LIM", "shortDesc": "Pitch rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.003, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Roll rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "max": 0.01, "min": 0.0, "name": "MC_ROLLRATE_D", "shortDesc": "Roll rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_ROLLRATE_FF", "shortDesc": "Roll rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_ROLLRATE_I", "shortDesc": "Roll rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_ROLLRATE_K * (MC_ROLLRATE_P * error\n+ MC_ROLLRATE_I * error_integral\n+ MC_ROLLRATE_D * error_derivative)\nSet MC_ROLLRATE_P=1 to implement a PID in the ideal form.\nSet MC_ROLLRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.01, "name": "MC_ROLLRATE_K", "shortDesc": "Roll rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.5, "min": 0.01, "name": "MC_ROLLRATE_P", "shortDesc": "Roll rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large roll moment trim changes.", "min": 0.0, "name": "MC_RR_INT_LIM", "shortDesc": "Roll rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "min": 0.0, "name": "MC_YAWRATE_D", "shortDesc": "Yaw rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_YAWRATE_FF", "shortDesc": "Yaw rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_YAWRATE_I", "shortDesc": "Yaw rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_YAWRATE_K * (MC_YAWRATE_P * error\n+ MC_YAWRATE_I * error_integral\n+ MC_YAWRATE_D * error_derivative)\nSet MC_YAWRATE_P=1 to implement a PID in the ideal form.\nSet MC_YAWRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.0, "name": "MC_YAWRATE_K", "shortDesc": "Yaw rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.6, "min": 0.0, "name": "MC_YAWRATE_P", "shortDesc": "Yaw rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 2.0, "group": "Multicopter Rate Control", "longDesc": "Reduces vibrations by lowering high frequency torque caused by rotor acceleration.\n0 disables the filter", "max": 10.0, "min": 0.0, "name": "MC_YAW_TQ_CUTOFF", "shortDesc": "Low pass filter cutoff frequency for yaw torque setpoint", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large yaw moment trim changes.", "min": 0.0, "name": "MC_YR_INT_LIM", "shortDesc": "Yaw rate integrator limit", "type": "Float"}, {"category": "Standard", "default": 0, "group": "OSD", "longDesc": "Controls the vertical position of the crosshair display.\nResolution is limited by OSD to 15 discrete values. Negative\nvalues will display the crosshairs below the horizon", "max": 8, "min": -8, "name": "OSD_CH_HEIGHT", "shortDesc": "OSD Crosshairs Height", "type": "Int32"}, {"category": "Standard", "default": 500, "group": "OSD", "longDesc": "Amount of time in milliseconds to dwell at the beginning of the display, when scrolling.", "max": 10000, "min": 100, "name": "OSD_DWELL_TIME", "shortDesc": "OSD Dwell Time (ms)", "type": "Int32"}, {"category": "Standard", "default": 3, "group": "OSD", "longDesc": "Minimum security of log level to display on the OSD.", "name": "OSD_LOG_LEVEL", "shortDesc": "OSD Warning Level", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "OSD", "longDesc": "Forward RC stick input to VTX when disarmed", "max": 1, "min": 0, "name": "OSD_RC_STICK", "shortDesc": "OSD RC Stick commands", "type": "Int32"}, {"category": "Standard", "default": 125, "group": "OSD", "longDesc": "Scroll rate in milliseconds for OSD messages longer than available character width.\nThis is lower-bounded by the nominal loop rate of this module.", "max": 1000, "min": 100, "name": "OSD_SCROLL_RATE", "shortDesc": "OSD Scroll Rate (ms)", "type": "Int32"}, {"bitmask": [{"description": "CRAFT_NAME", "index": 0}, {"description": "DISARMED", "index": 1}, {"description": "GPS_LAT", "index": 2}, {"description": "GPS_LON", "index": 3}, {"description": "GPS_SATS", "index": 4}, {"description": "GPS_SPEED", "index": 5}, {"description": "HOME_DIST", "index": 6}, {"description": "HOME_DIR", "index": 7}, {"description": "MAIN_BATT_VOLTAGE", "index": 8}, {"description": "CURRENT_DRAW", "index": 9}, {"description": "MAH_DRAWN", "index": 10}, {"description": "RSSI_VALUE", "index": 11}, {"description": "ALTITUDE", "index": 12}, {"description": "NUMERICAL_VARIO", "index": 13}, {"description": "(unused) FLYMODE", "index": 14}, {"description": "(unused) ESC_TMP", "index": 15}, {"description": "(unused) PITCH_ANGLE", "index": 16}, {"description": "(unused) ROLL_ANGLE", "index": 17}, {"description": "CROSSHAIRS", "index": 18}, {"description": "AVG_CELL_VOLTAGE", "index": 19}, {"description": "(unused) HORIZON_SIDEBARS", "index": 20}, {"description": "POWER", "index": 21}], "category": "Standard", "default": 16383, "group": "OSD", "longDesc": "Configure / toggle support display options.", "max": 4194303, "min": 0, "name": "OSD_SYMBOLS", "shortDesc": "OSD Symbol Selection", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "PWM Outputs", "increment": 0.1, "longDesc": "Parameter used to model the nonlinear relationship between\nmotor control signal (e.g. PWM) and static thrust.\nThe model is: rel_thrust = factor * rel_signal^2 + (1-factor) * rel_signal,\nwhere rel_thrust is the normalized thrust between 0 and 1, and\nrel_signal is the relative motor control signal between 0 and 1.", "max": 1.0, "min": 0.0, "name": "THR_MDL_FAC", "shortDesc": "Thrust to motor control signal model parameter", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Payload Deliverer", "name": "PD_GRIPPER_EN", "rebootRequired": true, "shortDesc": "Enable Gripper actuation in Payload Deliverer", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 3.0, "group": "Payload Deliverer", "longDesc": "Maximum time Gripper will wait while the successful griper actuation isn't recognised.\nIf the gripper has no feedback sensor, it will simply wait for\nthis time before considering gripper actuation successful and publish a\n'VehicleCommandAck' signaling successful gripper action", "min": 0.0, "name": "PD_GRIPPER_TO", "shortDesc": "Timeout for successful gripper actuation acknowledgement", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Payload Deliverer", "max": 0, "min": -1, "name": "PD_GRIPPER_TYPE", "shortDesc": "Type of Gripper (Servo, etc.)", "type": "Int32", "values": [{"description": "Undefined", "value": -1}, {"description": "Servo", "value": 0}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Precision Land", "increment": 0.5, "longDesc": "Time after which the landing target is considered lost without any new measurements.", "max": 50.0, "min": 0.0, "name": "PLD_BTOUT", "shortDesc": "Landing Target Timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Precision Land", "increment": 0.1, "longDesc": "Allow final approach (without horizontal positioning) if losing landing target closer than this to the ground.", "max": 10.0, "min": 0.0, "name": "PLD_FAPPR_ALT", "shortDesc": "Final approach altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Precision Land", "increment": 0.1, "longDesc": "Start descending if closer above landing target than this.", "max": 10.0, "min": 0.0, "name": "PLD_HACC_RAD", "shortDesc": "Horizontal acceptance radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 3, "group": "Precision Land", "longDesc": "Maximum number of times to search for the landing target if it is lost during the precision landing.", "max": 100, "min": 0, "name": "PLD_MAX_SRCH", "shortDesc": "Maximum number of search attempts", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Precision Land", "increment": 0.1, "longDesc": "Altitude above home to which to climb when searching for the landing target.", "max": 100.0, "min": 0.0, "name": "PLD_SRCH_ALT", "shortDesc": "Search altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Precision Land", "increment": 0.1, "longDesc": "Time allowed to search for the landing target before falling back to normal landing.", "max": 100.0, "min": 0.0, "name": "PLD_SRCH_TOUT", "shortDesc": "Search timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Pure Pursuit", "increment": 0.01, "longDesc": "Lower value -> More aggressive controller (beware overshoot/oscillations)", "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_GAIN", "shortDesc": "Tuning parameter for the pure pursuit controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Pure Pursuit", "increment": 0.01, "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_MAX", "shortDesc": "Maximum lookahead distance for the pure pursuit controller", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Pure Pursuit", "increment": 0.01, "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_MIN", "shortDesc": "Minimum lookahead distance for the pure pursuit controller", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC10_DZ", "shortDesc": "RC channel 10 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC10_MAX", "shortDesc": "RC channel 10 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC10_MIN", "shortDesc": "RC channel 10 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC10_REV", "shortDesc": "RC channel 10 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC10_TRIM", "shortDesc": "RC channel 10 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC11_DZ", "shortDesc": "RC channel 11 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC11_MAX", "shortDesc": "RC channel 11 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC11_MIN", "shortDesc": "RC channel 11 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC11_REV", "shortDesc": "RC channel 11 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC11_TRIM", "shortDesc": "RC channel 11 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC12_DZ", "shortDesc": "RC channel 12 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC12_MAX", "shortDesc": "RC channel 12 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC12_MIN", "shortDesc": "RC channel 12 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC12_REV", "shortDesc": "RC channel 12 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC12_TRIM", "shortDesc": "RC channel 12 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC13_DZ", "shortDesc": "RC channel 13 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC13_MAX", "shortDesc": "RC channel 13 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC13_MIN", "shortDesc": "RC channel 13 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC13_REV", "shortDesc": "RC channel 13 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC13_TRIM", "shortDesc": "RC channel 13 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC14_DZ", "shortDesc": "RC channel 14 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC14_MAX", "shortDesc": "RC channel 14 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC14_MIN", "shortDesc": "RC channel 14 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC14_REV", "shortDesc": "RC channel 14 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC14_TRIM", "shortDesc": "RC channel 14 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC15_DZ", "shortDesc": "RC channel 15 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC15_MAX", "shortDesc": "RC channel 15 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC15_MIN", "shortDesc": "RC channel 15 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC15_REV", "shortDesc": "RC channel 15 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC15_TRIM", "shortDesc": "RC channel 15 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC16_DZ", "shortDesc": "RC channel 16 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC16_MAX", "shortDesc": "RC channel 16 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC16_MIN", "shortDesc": "RC channel 16 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC16_REV", "shortDesc": "RC channel 16 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC16_TRIM", "shortDesc": "RC channel 16 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC17_DZ", "shortDesc": "RC channel 17 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC17_MAX", "shortDesc": "RC channel 17 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC17_MIN", "shortDesc": "RC channel 17 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC17_REV", "shortDesc": "RC channel 17 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC17_TRIM", "shortDesc": "RC channel 17 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC18_DZ", "shortDesc": "RC channel 18 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC18_MAX", "shortDesc": "RC channel 18 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC18_MIN", "shortDesc": "RC channel 18 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC18_REV", "shortDesc": "RC channel 18 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC18_TRIM", "shortDesc": "RC channel 18 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC1_DZ", "shortDesc": "RC channel 1 dead zone", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for RC channel 1", "max": 2200.0, "min": 1500.0, "name": "RC1_MAX", "shortDesc": "RC channel 1 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for RC channel 1", "max": 1500.0, "min": 800.0, "name": "RC1_MIN", "shortDesc": "RC channel 1 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC1_REV", "shortDesc": "RC channel 1 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC1_TRIM", "shortDesc": "RC channel 1 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC2_DZ", "shortDesc": "RC channel 2 dead zone", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC2_MAX", "shortDesc": "RC channel 2 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC2_MIN", "shortDesc": "RC channel 2 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC2_REV", "shortDesc": "RC channel 2 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC2_TRIM", "shortDesc": "RC channel 2 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC3_DZ", "shortDesc": "RC channel 3 dead zone", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC3_MAX", "shortDesc": "RC channel 3 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC3_MIN", "shortDesc": "RC channel 3 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC3_REV", "shortDesc": "RC channel 3 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC3_TRIM", "shortDesc": "RC channel 3 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC4_DZ", "shortDesc": "RC channel 4 dead zone", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC4_MAX", "shortDesc": "RC channel 4 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC4_MIN", "shortDesc": "RC channel 4 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC4_REV", "shortDesc": "RC channel 4 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC4_TRIM", "shortDesc": "RC channel 4 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC5_DZ", "shortDesc": "RC channel 5 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC5_MAX", "shortDesc": "RC channel 5 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC5_MIN", "shortDesc": "RC channel 5 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC5_REV", "shortDesc": "RC channel 5 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC5_TRIM", "shortDesc": "RC channel 5 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC6_DZ", "shortDesc": "RC channel 6 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC6_MAX", "shortDesc": "RC channel 6 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC6_MIN", "shortDesc": "RC channel 6 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC6_REV", "shortDesc": "RC channel 6 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC6_TRIM", "shortDesc": "RC channel 6 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC7_DZ", "shortDesc": "RC channel 7 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC7_MAX", "shortDesc": "RC channel 7 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC7_MIN", "shortDesc": "RC channel 7 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC7_REV", "shortDesc": "RC channel 7 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC7_TRIM", "shortDesc": "RC channel 7 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 10.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC8_DZ", "shortDesc": "RC channel 8 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC8_MAX", "shortDesc": "RC channel 8 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC8_MIN", "shortDesc": "RC channel 8 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC8_REV", "shortDesc": "RC channel 8 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC8_TRIM", "shortDesc": "RC channel 8 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0.0, "group": "Radio Calibration", "longDesc": "The +- range of this value around the trim value will be considered as zero.", "max": 100.0, "min": 0.0, "name": "RC9_DZ", "shortDesc": "RC channel 9 dead zone", "type": "Float"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC9_MAX", "shortDesc": "RC channel 9 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC9_MIN", "shortDesc": "RC channel 9 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC9_REV", "shortDesc": "RC channel 9 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC9_TRIM", "shortDesc": "RC channel 9 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "This parameter is used by Ground Station software to save the number\nof channels which were used during RC calibration. It is only meant\nfor ground station use.", "max": 18, "min": 0, "name": "RC_CHAN_CNT", "shortDesc": "RC channel count", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Use RC_MAP_FAILSAFE to specify which channel is used to indicate RC loss via this threshold.\nBy default this is the throttle channel.\nSet to a PWM value slightly above the PWM value for the channel (e.g. throttle) in a failsafe event,\nbut below the minimum PWM value for the channel during normal operation.\nNote: The default value of 0 disables the feature (it is below the expected range).", "max": 2200, "min": 0, "name": "RC_FAILS_THR", "shortDesc": "Failsafe channel PWM threshold", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX1", "shortDesc": "AUX1 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX2", "shortDesc": "AUX2 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX3", "shortDesc": "AUX3 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX4", "shortDesc": "AUX4 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX5", "shortDesc": "AUX5 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX6", "shortDesc": "AUX6 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_ENG_MOT", "shortDesc": "RC channel to engage the main motor (for helicopters)", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Configures which RC channel is used by the receiver to indicate the signal was lost\n(on receivers that use output a fixed signal value to report lost signal).\nIf set to 0, the channel mapped to throttle is used.\nUse RC_FAILS_THR to set the threshold indicating lost signal. By default it's below\nthe expected range and hence disabled.", "max": 18, "min": 0, "name": "RC_MAP_FAILSAFE", "shortDesc": "Failsafe channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 1st parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM1", "shortDesc": "PARAM1 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 2nd parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM2", "shortDesc": "PARAM2 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 3th parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM3", "shortDesc": "PARAM3 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading pitch inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_PITCH", "shortDesc": "Pitch control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading roll inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_ROLL", "shortDesc": "Roll control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading throttle inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_THROTTLE", "shortDesc": "Throttle control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading yaw inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_YAW", "shortDesc": "Yaw control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "0: do not read RSSI from input channel\n1-18: read RSSI from specified input channel\nSpecify the range for RSSI input with RC_RSSI_PWM_MIN and RC_RSSI_PWM_MAX parameters.", "max": 18, "min": 0, "name": "RC_RSSI_PWM_CHAN", "shortDesc": "PWM input channel that provides RSSI", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 2000, "group": "Radio Calibration", "longDesc": "Only used if RC_RSSI_PWM_CHAN > 0", "max": 2000, "min": 0, "name": "RC_RSSI_PWM_MAX", "shortDesc": "Max input value for RSSI reading", "type": "Int32"}, {"category": "Standard", "default": 1000, "group": "Radio Calibration", "longDesc": "Only used if RC_RSSI_PWM_CHAN > 0", "max": 2000, "min": 0, "name": "RC_RSSI_PWM_MIN", "shortDesc": "Min input value for RSSI reading", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_PITCH", "shortDesc": "Pitch trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_ROLL", "shortDesc": "Roll trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_YAW", "shortDesc": "Yaw trim", "type": "Float"}, {"category": "Standard", "default": 0.75, "group": "Radio Switches", "longDesc": "0-1 indicate where in the full channel range the threshold sits\n0 : min\n1 : max\nsign indicates polarity of comparison\npositive : true when channel>th\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channel The rover starts to cut the corner earlier.", "max": 100.0, "min": 1.0, "name": "RA_ACC_RAD_GAIN", "shortDesc": "Tuning parameter for corner cutting", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Ackermann", "increment": 0.01, "longDesc": "The controller scales the acceptance radius based on the angle between\nthe previous, current and next waypoint.\nHigher value -> smoother trajectory at the cost of how close the rover gets\nto the waypoint (Set to -1 to disable corner cutting).", "max": 100.0, "min": -1.0, "name": "RA_ACC_RAD_MAX", "shortDesc": "Maximum acceptance radius for the waypoints", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Ackermann", "increment": 0.01, "max": 1.5708, "min": 0.0, "name": "RA_MAX_STR_ANG", "shortDesc": "Maximum steering angle", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Ackermann", "increment": 0.01, "longDesc": "Set to -1 to disable.", "max": 1000.0, "min": -1.0, "name": "RA_STR_RATE_LIM", "shortDesc": "Steering rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Ackermann", "increment": 0.001, "longDesc": "Distance from the front to the rear axle.", "max": 100.0, "min": 0.0, "name": "RA_WHEEL_BASE", "shortDesc": "Wheel base", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Attitude Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_P", "shortDesc": "Proportional gain for closed loop yaw controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.174533, "group": "Rover Differential", "increment": 0.01, "longDesc": "This threshold is used for the state machine to switch from driving to turning based on the\nerror between the desired and actual yaw. It is also used as the threshold whether the rover should come\nto a smooth stop at the next waypoint. This slow down effect is active if the angle between the\nline segments from prevWP-currWP and currWP-nextWP is smaller then 180 - RD_TRANS_DRV_TRN.", "max": 3.14159, "min": 0.001, "name": "RD_TRANS_DRV_TRN", "shortDesc": "Yaw error threshhold to switch from driving to spot turning", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0872665, "group": "Rover Differential", "increment": 0.01, "longDesc": "This threshold is used for the state machine to switch from turning to driving based on the\nerror between the desired and actual yaw.", "max": 3.14159, "min": 0.001, "name": "RD_TRANS_TRN_DRV", "shortDesc": "Yaw error threshhold to switch from spot turning to driving", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Differential", "increment": 0.001, "longDesc": "Distance from the center of the right wheel to the center of the left wheel.", "max": 100.0, "min": 0.0, "name": "RD_WHEEL_TRACK", "shortDesc": "Wheel track", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.17, "group": "Rover Mecanum", "increment": 0.01, "longDesc": "Threshold for the angle between the active cruise direction and the cruise direction given\nby the stick inputs.\nThis can be understood as a deadzone for the combined stick inputs for forward/backwards\nand lateral speed which defines a course direction.", "max": 3.14, "min": 0.0, "name": "RM_COURSE_CTL_TH", "shortDesc": "Threshold to update course control in manual position mode", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Mecanum", "increment": 0.001, "longDesc": "Distance from the center of the right wheel to the center of the left wheel.", "max": 100.0, "min": 0.0, "name": "RM_WHEEL_TRACK", "shortDesc": "Wheel track", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.75, "group": "Rover Position Control (Deprecated)", "increment": 0.05, "longDesc": "Damping factor for L1 control.", "max": 0.9, "min": 0.6, "name": "GND_L1_DAMPING", "shortDesc": "L1 damping", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Rover Position Control (Deprecated)", "increment": 0.1, "longDesc": "This is the distance at which the next waypoint is activated. This should be set\nto about 2-4x of GND_WHEEL_BASE and not smaller than one meter (due to GPS accuracy).", "max": 50.0, "min": 1.0, "name": "GND_L1_DIST", "shortDesc": "L1 distance", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Rover Position Control (Deprecated)", "increment": 0.5, "longDesc": "This is the L1 distance and defines the tracking\npoint ahead of the rover it's following.\nUse values around 2-5m for a 0.3m wheel base. Tuning instructions: Shorten\nslowly during tuning until response is sharp without oscillation.", "max": 50.0, "min": 0.5, "name": "GND_L1_PERIOD", "shortDesc": "L1 period", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 150.0, "group": "Rover Position Control (Deprecated)", "max": 400.0, "min": 0.0, "name": "GND_MAN_Y_MAX", "shortDesc": "Max manual yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.7854, "group": "Rover Position Control (Deprecated)", "increment": 0.01, "longDesc": "At a control output of 0, the steering wheels are at 0 radians.\nAt a control output of 1, the steering wheels are at GND_MAX_ANG radians.", "max": 3.14159, "min": 0.0, "name": "GND_MAX_ANG", "shortDesc": "Maximum turn angle for Ackerman steering", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.001, "group": "Rover Position Control (Deprecated)", "increment": 0.005, "longDesc": "This is the derivative gain for the speed closed loop controller", "max": 50.0, "min": 0.0, "name": "GND_SPEED_D", "shortDesc": "Speed proportional gain", "type": "Float", "units": "%m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 3.0, "group": "Rover Position Control (Deprecated)", "increment": 0.005, "longDesc": "This is the integral gain for the speed closed loop controller", "max": 50.0, "min": 0.0, "name": "GND_SPEED_I", "shortDesc": "Speed Integral gain", "type": "Float", "units": "%m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Rover Position Control (Deprecated)", "increment": 0.005, "longDesc": "This is the maxim value the integral can reach to prevent wind-up.", "max": 50.0, "min": 0.005, "name": "GND_SPEED_IMAX", "shortDesc": "Speed integral maximum value", "type": "Float", "units": "%m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Rover Position Control (Deprecated)", "increment": 0.5, "max": 40.0, "min": 0.0, "name": "GND_SPEED_MAX", "shortDesc": "Maximum ground speed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 2.0, "group": "Rover Position Control (Deprecated)", "increment": 0.005, "longDesc": "This is the proportional gain for the speed closed loop controller", "max": 50.0, "min": 0.005, "name": "GND_SPEED_P", "shortDesc": "Speed proportional gain", "type": "Float", "units": "%m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Rover Position Control (Deprecated)", "increment": 0.005, "longDesc": "This is a gain to map the speed control output to the throttle linearly.", "max": 50.0, "min": 0.005, "name": "GND_SPEED_THR_SC", "shortDesc": "Speed to throttle scaler", "type": "Float", "units": "%m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Rover Position Control (Deprecated)", "increment": 0.5, "max": 40.0, "min": 0.0, "name": "GND_SPEED_TRIM", "shortDesc": "Trim ground speed", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "Rover Position Control (Deprecated)", "longDesc": "This allows the user to choose between closed loop gps speed or open loop cruise throttle speed", "max": 1, "min": 0, "name": "GND_SP_CTRL_MODE", "shortDesc": "Control mode for speed", "type": "Int32", "values": [{"description": "open loop control", "value": 0}, {"description": "close the loop with gps speed", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Rover Position Control (Deprecated)", "increment": 0.01, "longDesc": "This is the throttle setting required to achieve the desired cruise speed.\n10% is ok for a traxxas stampede vxl with ESC set to training mode", "max": 1.0, "min": 0.0, "name": "GND_THR_CRUISE", "shortDesc": "Cruise throttle", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Rover Position Control (Deprecated)", "increment": 0.01, "longDesc": "This is the maximum throttle % that can be used by the controller.\nFor a Traxxas stampede vxl with the ESC set to training, 30 % is enough", "max": 1.0, "min": 0.0, "name": "GND_THR_MAX", "shortDesc": "Throttle limit max", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Position Control (Deprecated)", "increment": 0.01, "longDesc": "This is the minimum throttle % that can be used by the controller.\nSet to 0 for rover", "max": 1.0, "min": 0.0, "name": "GND_THR_MIN", "shortDesc": "Throttle limit min", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.31, "group": "Rover Position Control (Deprecated)", "increment": 0.01, "longDesc": "A value of 0.31 is typical for 1/10 RC cars.", "min": 0.0, "name": "GND_WHEEL_BASE", "shortDesc": "Distance from front axle to rear axle", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap how quickly the magnitude of yaw rate setpoints can increase.\nSet to -1 to disable.", "max": 10000.0, "min": -1.0, "name": "RO_YAW_ACCEL_LIM", "shortDesc": "Yaw acceleration limit", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap how quickly the magnitude of yaw rate setpoints can decrease.\nSet to -1 to disable.", "max": 10000.0, "min": -1.0, "name": "RO_YAW_DECEL_LIM", "shortDesc": "Yaw deceleration limit", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Multiplicative correction factor for the feedforward mapping of the yaw rate controller.\nIncrease this value (x > 1) if the measured yaw rate is lower than the setpoint, decrease (0 < x < 1) otherwise.\nNote: Tuning this is particularly useful for skid-steered rovers, or rovers with misaligned wheels/steering axes\nthat cause a lot of friction when turning.", "max": 10000.0, "min": 0.01, "name": "RO_YAW_RATE_CORR", "shortDesc": "Yaw rate correction factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_I", "shortDesc": "Integral gain for closed loop yaw rate controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap yaw rate setpoints and map controller inputs to yaw rate setpoints\nin Acro, Stabilized and Position mode.", "max": 10000.0, "min": 0.0, "name": "RO_YAW_RATE_LIM", "shortDesc": "Yaw rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_P", "shortDesc": "Proportional gain for closed loop yaw rate controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "The minimum threshold for the yaw rate measurement not to be interpreted as zero.", "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_TH", "shortDesc": "Yaw rate measurement threshold", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Percentage of stick input range that will be interpreted as zero around the stick centered value.", "max": 1.0, "min": 0.0, "name": "RO_YAW_STICK_DZ", "shortDesc": "Yaw stick deadzone", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nFor mecanum rovers this limit is used for longitudinal and lateral acceleration.", "max": 100.0, "min": -1.0, "name": "RO_ACCEL_LIM", "shortDesc": "Acceleration limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nNote that if it is disabled the rover will not slow down when approaching waypoints in auto modes.\nFor mecanum rovers this limit is used for longitudinal and lateral deceleration.", "max": 100.0, "min": -1.0, "name": "RO_DECEL_LIM", "shortDesc": "Deceleration limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nNote that if it is disabled the rover will not slow down when approaching waypoints in auto modes.\nFor mecanum rovers this limit is used for longitudinal and lateral jerk.", "max": 100.0, "min": -1.0, "name": "RO_JERK_LIM", "shortDesc": "Jerk limit", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Used to linearly map speeds [m/s] to throttle values [-1. 1].", "max": 100.0, "min": 0.0, "name": "RO_MAX_THR_SPEED", "shortDesc": "Speed the rover drives at maximum throttle", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.001, "max": 100.0, "min": 0.0, "name": "RO_SPEED_I", "shortDesc": "Integral gain for ground speed controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Used to cap speed setpoints and map controller inputs to speed setpoints in Position mode.", "max": 100.0, "min": -1.0, "name": "RO_SPEED_LIM", "shortDesc": "Speed limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_SPEED_P", "shortDesc": "Proportional gain for ground speed controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Reduced_speed = RO_MAX_THR_SPEED * (1 - normalized_course_error * RO_SPEED_RED)\nThe normalized course error is the angle between the current course and the bearing setpoint\ninterpolated from [0, 180] -> [0, 1].\nHigher value -> More speed reduction.\nNote: This is also used to calculate the speed at which the vehicle arrives at a waypoint in auto modes.\nSet to -1 to disable bearing error based speed reduction.", "max": 100.0, "min": -1.0, "name": "RO_SPEED_RED", "shortDesc": "Tuning parameter for the speed reduction based on the course error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nThe minimum threshold for the speed measurement not to be interpreted as zero.", "max": 100.0, "min": 0.0, "name": "RO_SPEED_TH", "shortDesc": "Speed measurement threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Runway Takeoff", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "RWTO_MAX_THR", "shortDesc": "Throttle during runway takeoff", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 1, "group": "Runway Takeoff", "longDesc": "This is useful when map, GNSS, or yaw errors on ground are misaligned with what the operator intends for takeoff course.\nParticularly useful for skinny runways or if the wheel servo is a bit off trim.", "name": "RWTO_NUDGE", "shortDesc": "Enable use of yaw stick for nudging the wheel during runway ground roll", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Runway Takeoff", "increment": 0.5, "longDesc": "A taildragger with steerable wheel might need to pitch up\na little to keep its wheel on the ground before airspeed\nto takeoff is reached.", "max": 20.0, "min": -10.0, "name": "RWTO_PSP", "shortDesc": "Pitch setpoint during taxi / before takeoff rotation airspeed is reached", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Runway Takeoff", "increment": 0.1, "max": 15.0, "min": 1.0, "name": "RWTO_RAMP_TIME", "shortDesc": "Throttle ramp up time for runway takeoff", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Runway Takeoff", "increment": 0.1, "longDesc": "The calibrated airspeed threshold during the takeoff ground roll when the plane should start rotating (pitching up).\nMust be less than the takeoff airspeed, will otherwise be capped at the takeoff airpeed (see FW_TKO_AIRSPD).\nIf set <= 0.0, defaults to 0.9 * takeoff airspeed (see FW_TKO_AIRSPD)", "min": -1.0, "name": "RWTO_ROT_AIRSPD", "shortDesc": "Takeoff rotation airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Runway Takeoff", "increment": 0.1, "longDesc": "This is the time desired to linearly ramp in takeoff pitch constraints during the takeoff rotation", "min": 0.1, "name": "RWTO_ROT_TIME", "shortDesc": "Takeoff rotation time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Runway Takeoff", "name": "RWTO_TKOFF", "shortDesc": "Runway takeoff with landing gear", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 2, "group": "SD Logging", "longDesc": "Selects the algorithm used for logfile encryption", "name": "SDLOG_ALGORITHM", "shortDesc": "Logfile Encryption algorithm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "XChaCha20", "value": 2}]}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "When enabled, logging will not start from boot if battery power is not detected\n(e.g. powered via USB on a test bench). This prevents extraneous flight logs from\nbeing created during bench testing.\nNote that this only applies to log-from-boot modes. This has no effect on arm-based\nmodes.", "name": "SDLOG_BOOT_BAT", "shortDesc": "Battery-only Logging", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "If there are more log directories than this value,\nthe system will delete the oldest directories during startup.\nIn addition, the system will delete old logs if there is not enough free space left.\nThe minimum amount is 300 MB.\nIf this is set to 0, old directories will only be removed if the free space falls below\nthe minimum.\nNote: this does not apply to mission log files.", "max": 1000, "min": 0, "name": "SDLOG_DIRS_MAX", "rebootRequired": true, "shortDesc": "Maximum number of log directories to keep", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "SD Logging", "longDesc": "If the logfile is encrypted using a symmetric key algorithm,\nthe used encryption key is generated at logging start and stored\non the sdcard RSA2048 encrypted using this key.", "max": 255, "min": 0, "name": "SDLOG_EXCH_KEY", "shortDesc": "Logfile Encryption key exchange key", "type": "Int32"}, {"category": "Standard", "default": 2, "group": "SD Logging", "longDesc": "Selects the key in keystore, used for encrypting the log. When using\na symmetric encryption algorithm, the key is generated at logging start\nand kept stored in this index. For symmetric algorithms, the key is\nvolatile and valid only for the duration of logging. The key is stored\nin encrypted format on the sdcard alongside the logfile, using an RSA2048\nkey defined by the SDLOG_EXCHANGE_KEY", "max": 255, "min": 0, "name": "SDLOG_KEY", "shortDesc": "Logfile Encryption key index", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "If enabled, a small additional \"mission\" log file will be written to the SD card.\nThe log contains just those messages that are useful for tasks like\ngenerating flight statistics and geotagging.\nThe different modes can be used to further reduce the logged data\n(and thus the log file size). For example, choose geotagging mode to\nonly log data required for geotagging.\nNote that the normal/full log is still created, and contains all\nthe data in the mission log (and more).", "name": "SDLOG_MISSION", "rebootRequired": true, "shortDesc": "Mission Log", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "All mission messages", "value": 1}, {"description": "Geotagging messages", "value": 2}]}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "Determines when to start and stop logging. By default, logging is started\nwhen arming the system, and stopped when disarming.", "name": "SDLOG_MODE", "rebootRequired": true, "shortDesc": "Logging Mode", "type": "Int32", "values": [{"description": "disabled", "value": -1}, {"description": "when armed until disarm (default)", "value": 0}, {"description": "from boot until disarm", "value": 1}, {"description": "from boot until shutdown", "value": 2}, {"description": "while manual input AUX1 >30%", "value": 3}, {"description": "from 1st armed until shutdown", "value": 4}]}, {"bitmask": [{"description": "Default set (general log analysis)", "index": 0}, {"description": "Estimator replay (EKF2)", "index": 1}, {"description": "Thermal calibration", "index": 2}, {"description": "System identification", "index": 3}, {"description": "High rate", "index": 4}, {"description": "Debug", "index": 5}, {"description": "Sensor comparison", "index": 6}, {"description": "Computer Vision and Avoidance", "index": 7}, {"description": "Raw FIFO high-rate IMU (Gyro)", "index": 8}, {"description": "Raw FIFO high-rate IMU (Accel)", "index": 9}, {"description": "Mavlink tunnel message logging", "index": 10}, {"description": "High rate sensors", "index": 11}], "category": "Standard", "default": 1, "group": "SD Logging", "longDesc": "This integer bitmask controls the set and rates of logged topics.\nThe default allows for general log analysis while keeping the\nlog file size reasonably small.\nEnabling multiple sets leads to higher bandwidth requirements and larger log\nfiles.\nSet bits true to enable:\n0 : Default set (used for general log analysis)\n1 : Full rate estimator (EKF2) replay topics\n2 : Topics for thermal calibration (high rate raw IMU and Baro sensor data)\n3 : Topics for system identification (high rate actuator control and IMU data)\n4 : Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators)\n5 : Debugging topics (debug_*.msg topics, for custom code)\n6 : Topics for sensor comparison (low rate raw IMU, Baro and magnetometer data)\n7 : Topics for computer vision and collision prevention\n8 : Raw FIFO high-rate IMU (Gyro)\n9 : Raw FIFO high-rate IMU (Accel)\n10: Logging of mavlink tunnel message (useful for payload communication debugging)", "max": 4095, "min": 0, "name": "SDLOG_PROFILE", "rebootRequired": true, "shortDesc": "Logging topic profile (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "the difference in hours and minutes from Coordinated\nUniversal Time (UTC) for a your place and date.\nfor example, In case of South Korea(UTC+09:00),\nUTC offset is 540 min (9*60)\nrefer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets", "max": 1000, "min": -1000, "name": "SDLOG_UTC_OFFSET", "shortDesc": "UTC offset (unit: min)", "type": "Int32", "units": "min"}, {"category": "Standard", "default": 1, "group": "SD Logging", "longDesc": "If set to 1, add an ID to the log, which uniquely identifies the vehicle", "name": "SDLOG_UUID", "shortDesc": "Log UUID", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 60.0, "group": "SITL", "increment": 1.0, "max": 86400.0, "min": 1.0, "name": "SIM_BAT_DRAIN", "shortDesc": "Simulator Battery drain interval", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "SITL", "longDesc": "Enable or disable the internal battery simulation. This is useful\nwhen the battery is simulated externally and interfaced with PX4\nthrough MAVLink for example.", "name": "SIM_BAT_ENABLE", "shortDesc": "Simulator Battery enabled", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 50.0, "group": "SITL", "increment": 0.1, "longDesc": "Can be used to alter the battery level during SITL- or HITL-simulation on the fly.\nParticularly useful for testing different low-battery behaviour.", "max": 100.0, "min": 0.0, "name": "SIM_BAT_MIN_PCT", "shortDesc": "Simulator Battery minimal percentage", "type": "Float", "units": "%"}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC0_ID", "shortDesc": "Accelerometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC0_PRIO", "shortDesc": "Accelerometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC0_ROT", "shortDesc": "Accelerometer 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_XOFF", "shortDesc": "Accelerometer 0 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_XSCALE", "shortDesc": "Accelerometer 0 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_YOFF", "shortDesc": "Accelerometer 0 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_YSCALE", "shortDesc": "Accelerometer 0 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_ZOFF", "shortDesc": "Accelerometer 0 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_ZSCALE", "shortDesc": "Accelerometer 0 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC1_ID", "shortDesc": "Accelerometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC1_PRIO", "shortDesc": "Accelerometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC1_ROT", "shortDesc": "Accelerometer 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_XOFF", "shortDesc": "Accelerometer 1 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_XSCALE", "shortDesc": "Accelerometer 1 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_YOFF", "shortDesc": "Accelerometer 1 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_YSCALE", "shortDesc": "Accelerometer 1 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_ZOFF", "shortDesc": "Accelerometer 1 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_ZSCALE", "shortDesc": "Accelerometer 1 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC2_ID", "shortDesc": "Accelerometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC2_PRIO", "shortDesc": "Accelerometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC2_ROT", "shortDesc": "Accelerometer 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_XOFF", "shortDesc": "Accelerometer 2 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_XSCALE", "shortDesc": "Accelerometer 2 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_YOFF", "shortDesc": "Accelerometer 2 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_YSCALE", "shortDesc": "Accelerometer 2 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_ZOFF", "shortDesc": "Accelerometer 2 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_ZSCALE", "shortDesc": "Accelerometer 2 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC3_ID", "shortDesc": "Accelerometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC3_PRIO", "shortDesc": "Accelerometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC3_ROT", "shortDesc": "Accelerometer 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_XOFF", "shortDesc": "Accelerometer 3 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_XSCALE", "shortDesc": "Accelerometer 3 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_YOFF", "shortDesc": "Accelerometer 3 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_YSCALE", "shortDesc": "Accelerometer 3 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_ZOFF", "shortDesc": "Accelerometer 3 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_ZSCALE", "shortDesc": "Accelerometer 3 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO0_ID", "shortDesc": "Barometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO0_OFF", "shortDesc": "Barometer 0 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO0_PRIO", "shortDesc": "Barometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO1_ID", "shortDesc": "Barometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO1_OFF", "shortDesc": "Barometer 1 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO1_PRIO", "shortDesc": "Barometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO2_ID", "shortDesc": "Barometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO2_OFF", "shortDesc": "Barometer 2 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO2_PRIO", "shortDesc": "Barometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO3_ID", "shortDesc": "Barometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO3_OFF", "shortDesc": "Barometer 3 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO3_PRIO", "shortDesc": "Barometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO0_ID", "shortDesc": "Gyroscope 0 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO0_PRIO", "shortDesc": "Gyroscope 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO0_ROT", "shortDesc": "Gyroscope 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_XOFF", "shortDesc": "Gyroscope 0 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_YOFF", "shortDesc": "Gyroscope 0 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_ZOFF", "shortDesc": "Gyroscope 0 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO1_ID", "shortDesc": "Gyroscope 1 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO1_PRIO", "shortDesc": "Gyroscope 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO1_ROT", "shortDesc": "Gyroscope 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_XOFF", "shortDesc": "Gyroscope 1 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_YOFF", "shortDesc": "Gyroscope 1 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_ZOFF", "shortDesc": "Gyroscope 1 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO2_ID", "shortDesc": "Gyroscope 2 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO2_PRIO", "shortDesc": "Gyroscope 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO2_ROT", "shortDesc": "Gyroscope 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_XOFF", "shortDesc": "Gyroscope 2 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_YOFF", "shortDesc": "Gyroscope 2 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_ZOFF", "shortDesc": "Gyroscope 2 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO3_ID", "shortDesc": "Gyroscope 3 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO3_PRIO", "shortDesc": "Gyroscope 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO3_ROT", "shortDesc": "Gyroscope 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_XOFF", "shortDesc": "Gyroscope 3 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_YOFF", "shortDesc": "Gyroscope 3 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_ZOFF", "shortDesc": "Gyroscope 3 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG0_ID", "shortDesc": "Magnetometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_PITCH", "shortDesc": "Magnetometer 0 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG0_PRIO", "shortDesc": "Magnetometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_ROLL", "shortDesc": "Magnetometer 0 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG0_ROLL, CAL_MAG0_PITCH and CAL_MAG0_YAW.", "max": 100, "min": -1, "name": "CAL_MAG0_ROT", "shortDesc": "Magnetometer 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_XCOMP", "shortDesc": "Magnetometer 0 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_XODIAG", "shortDesc": "Magnetometer 0 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_XOFF", "shortDesc": "Magnetometer 0 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_XSCALE", "shortDesc": "Magnetometer 0 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_YAW", "shortDesc": "Magnetometer 0 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_YCOMP", "shortDesc": "Magnetometer 0 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_YODIAG", "shortDesc": "Magnetometer 0 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_YOFF", "shortDesc": "Magnetometer 0 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_YSCALE", "shortDesc": "Magnetometer 0 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_ZCOMP", "shortDesc": "Magnetometer 0 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_ZODIAG", "shortDesc": "Magnetometer 0 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_ZOFF", "shortDesc": "Magnetometer 0 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_ZSCALE", "shortDesc": "Magnetometer 0 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG1_ID", "shortDesc": "Magnetometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_PITCH", "shortDesc": "Magnetometer 1 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG1_PRIO", "shortDesc": "Magnetometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_ROLL", "shortDesc": "Magnetometer 1 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG1_ROLL, CAL_MAG1_PITCH and CAL_MAG1_YAW.", "max": 100, "min": -1, "name": "CAL_MAG1_ROT", "shortDesc": "Magnetometer 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_XCOMP", "shortDesc": "Magnetometer 1 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_XODIAG", "shortDesc": "Magnetometer 1 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_XOFF", "shortDesc": "Magnetometer 1 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_XSCALE", "shortDesc": "Magnetometer 1 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_YAW", "shortDesc": "Magnetometer 1 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_YCOMP", "shortDesc": "Magnetometer 1 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_YODIAG", "shortDesc": "Magnetometer 1 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_YOFF", "shortDesc": "Magnetometer 1 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_YSCALE", "shortDesc": "Magnetometer 1 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_ZCOMP", "shortDesc": "Magnetometer 1 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_ZODIAG", "shortDesc": "Magnetometer 1 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_ZOFF", "shortDesc": "Magnetometer 1 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_ZSCALE", "shortDesc": "Magnetometer 1 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG2_ID", "shortDesc": "Magnetometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_PITCH", "shortDesc": "Magnetometer 2 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG2_PRIO", "shortDesc": "Magnetometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_ROLL", "shortDesc": "Magnetometer 2 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG2_ROLL, CAL_MAG2_PITCH and CAL_MAG2_YAW.", "max": 100, "min": -1, "name": "CAL_MAG2_ROT", "shortDesc": "Magnetometer 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_XCOMP", "shortDesc": "Magnetometer 2 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_XODIAG", "shortDesc": "Magnetometer 2 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_XOFF", "shortDesc": "Magnetometer 2 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_XSCALE", "shortDesc": "Magnetometer 2 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_YAW", "shortDesc": "Magnetometer 2 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_YCOMP", "shortDesc": "Magnetometer 2 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_YODIAG", "shortDesc": "Magnetometer 2 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_YOFF", "shortDesc": "Magnetometer 2 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_YSCALE", "shortDesc": "Magnetometer 2 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_ZCOMP", "shortDesc": "Magnetometer 2 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_ZODIAG", "shortDesc": "Magnetometer 2 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_ZOFF", "shortDesc": "Magnetometer 2 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_ZSCALE", "shortDesc": "Magnetometer 2 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG3_ID", "shortDesc": "Magnetometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_PITCH", "shortDesc": "Magnetometer 3 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG3_PRIO", "shortDesc": "Magnetometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_ROLL", "shortDesc": "Magnetometer 3 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG3_ROLL, CAL_MAG3_PITCH and CAL_MAG3_YAW.", "max": 100, "min": -1, "name": "CAL_MAG3_ROT", "shortDesc": "Magnetometer 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_XCOMP", "shortDesc": "Magnetometer 3 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_XODIAG", "shortDesc": "Magnetometer 3 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_XOFF", "shortDesc": "Magnetometer 3 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_XSCALE", "shortDesc": "Magnetometer 3 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_YAW", "shortDesc": "Magnetometer 3 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_YCOMP", "shortDesc": "Magnetometer 3 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_YODIAG", "shortDesc": "Magnetometer 3 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_YOFF", "shortDesc": "Magnetometer 3 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_YSCALE", "shortDesc": "Magnetometer 3 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_ZCOMP", "shortDesc": "Magnetometer 3 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_ZODIAG", "shortDesc": "Magnetometer 3 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_ZOFF", "shortDesc": "Magnetometer 3 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_ZSCALE", "shortDesc": "Magnetometer 3 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "name": "CAL_MAG_COMP_TYP", "shortDesc": "Type of magnetometer compensation", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Throttle-based compensation", "value": 1}, {"description": "Current-based compensation (battery_status instance 0)", "value": 2}, {"description": "Current-based compensation (battery_status instance 1)", "value": 3}]}, {"category": "Standard", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Pick the appropriate scaling from the datasheet.\nthis number defines the (linear) conversion from voltage\nto Pascal (pa). For the MPXV7002DP this is 1000.\nNOTE: If the sensor always registers zero, try switching\nthe static and dynamic tubes.", "name": "SENS_DPRES_ANSC", "shortDesc": "Differential pressure sensor analog scaling", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "The offset (zero-reading) in Pascal", "name": "SENS_DPRES_OFF", "shortDesc": "Differential pressure sensor offset", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Reverse the raw measurements of all differential pressure sensors.\nThis can be enabled if the sensors have static and dynamic ports swapped.", "name": "SENS_DPRES_REV", "shortDesc": "Reverse differential pressure sensor readings", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 100.0, "group": "Sensor Calibration", "increment": 0.1, "longDesc": "This parameter defines the maximum distance from ground at which the optical flow sensor operates reliably.\nThe height setpoint will be limited to be no greater than this value when the navigation system\nis completely reliant on optical flow data and the height above ground estimate is valid.\nThe sensor may be usable above this height, but accuracy will progressively degrade.", "max": 100.0, "min": 1.0, "name": "SENS_FLOW_MAXHGT", "shortDesc": "Maximum height above ground when reliant on optical flow", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 8.0, "group": "Sensor Calibration", "longDesc": "Optical flow data will not fused by the estimators if the magnitude of the flow rate exceeds this value and\ncontrol loops will be instructed to limit ground speed such that the flow rate produced by movement over ground\nis less than 50% of this value.", "min": 1.0, "name": "SENS_FLOW_MAXR", "shortDesc": "Magnitude of maximum angular flow rate reliably measurable by the optical flow sensor", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Sensor Calibration", "increment": 0.1, "longDesc": "This parameter defines the minimum distance from ground at which the optical flow sensor operates reliably.\nThe sensor may be usable below this height, but accuracy will progressively reduce to loss of focus.", "max": 1.0, "min": 0.0, "name": "SENS_FLOW_MINHGT", "shortDesc": "Minimum height above ground when reliant on optical flow", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "Model with Pitot\nCAL_AIR_TUBED_MM: Not used, 1.5 mm tubes assumed.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor.\nModel without Pitot (1.5 mm tubes)\nCAL_AIR_TUBED_MM: Not used, 1.5 mm tubes assumed.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor.\nTube Pressure Drop\nCAL_AIR_TUBED_MM: Diameter in mm of the pitot and tubes, must have the same diameter.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor and the static + dynamic port length of the pitot.", "name": "CAL_AIR_CMODEL", "shortDesc": "Airspeed sensor compensation model for the SDP3x", "type": "Int32", "values": [{"description": "Model with Pitot", "value": 0}, {"description": "Model without Pitot (1.5 mm tubes)", "value": 1}, {"description": "Tube Pressure Drop", "value": 2}]}, {"category": "Standard", "default": 1.5, "group": "Sensors", "max": 100.0, "min": 1.5, "name": "CAL_AIR_TUBED_MM", "shortDesc": "Airspeed sensor tube diameter. Only used for the Tube Pressure Drop Compensation", "type": "Float", "units": "mm"}, {"category": "Standard", "default": 0.2, "group": "Sensors", "longDesc": "See the CAL_AIR_CMODEL explanation on how this parameter should be set.", "max": 2.0, "min": 0.01, "name": "CAL_AIR_TUBELEN", "shortDesc": "Airspeed sensor tube length", "type": "Float", "units": "m"}, {"category": "Developer", "default": 63, "group": "Sensors", "longDesc": "Use SENS_MAG_SIDES instead", "name": "CAL_MAG_SIDES", "shortDesc": "For legacy QGC support only", "type": "Int32"}, {"category": "Standard", "default": 30.0, "group": "Sensors", "longDesc": "The cutoff frequency for the 2nd order butterworth filter on the primary accelerometer.\nThis only affects the signal sent to the controllers, not the estimators. 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_ACCEL_CUTOFF", "rebootRequired": true, "shortDesc": "Low pass filter cutoff frequency for accel", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The cutoff frequency for the 2nd order butterworth filter used on\nthe time derivative of the measured angular velocity, also known as\nthe D-term filter in the rate controller. The D-term uses the derivative of\nthe rate and thus is the most susceptible to noise. Therefore, using\na D-term filter allows to increase IMU_GYRO_CUTOFF, which\nleads to reduced control latency and permits to increase the P gains.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_DGYRO_CUTOFF", "rebootRequired": true, "shortDesc": "Cutoff frequency for angular acceleration (D-Term filter)", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 1, "group": "Sensors", "name": "IMU_GYRO_CAL_EN", "rebootRequired": true, "shortDesc": "IMU gyro auto calibration enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Sensors", "increment": 0.1, "longDesc": "The cutoff frequency for the 2nd order butterworth filter on the primary gyro.\nThis only affects the angular velocity sent to the controllers, not the estimators.\nIt applies also to the angular acceleration (D-Term filter), see IMU_DGYRO_CUTOFF.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_CUTOFF", "rebootRequired": true, "shortDesc": "Low pass filter cutoff frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "Sensors", "increment": 0.1, "longDesc": "Bandwidth per notch filter when using dynamic notch filtering with ESC RPM.", "max": 30.0, "min": 5.0, "name": "IMU_GYRO_DNF_BW", "shortDesc": "IMU gyro ESC notch filter bandwidth", "type": "Float", "units": "Hz"}, {"bitmask": [{"description": "ESC RPM", "index": 0}, {"description": "FFT", "index": 1}], "category": "Standard", "default": 0, "group": "Sensors", "longDesc": "Enable bank of dynamically updating notch filters.\nRequires ESC RPM feedback or onboard FFT (IMU_GYRO_FFT_EN).", "max": 3, "min": 0, "name": "IMU_GYRO_DNF_EN", "shortDesc": "IMU gyro dynamic notch filtering", "type": "Int32"}, {"category": "Standard", "default": 3, "group": "Sensors", "longDesc": "ESC RPM number of harmonics (multiples of RPM) for ESC RPM dynamic notch filtering.", "max": 7, "min": 1, "name": "IMU_GYRO_DNF_HMC", "shortDesc": "IMU gyro dynamic notch filter harmonics", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "Sensors", "increment": 0.1, "longDesc": "Minimum notch filter frequency in Hz.", "name": "IMU_GYRO_DNF_MIN", "shortDesc": "IMU gyro dynamic notch filter minimum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "Sensors", "name": "IMU_GYRO_FFT_EN", "rebootRequired": true, "shortDesc": "IMU gyro FFT enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 512, "group": "Sensors", "name": "IMU_GYRO_FFT_LEN", "rebootRequired": true, "shortDesc": "IMU gyro FFT length", "type": "Int32", "units": "Hz", "values": [{"description": "256", "value": 256}, {"description": "512", "value": 512}, {"description": "1024", "value": 1024}, {"description": "4096", "value": 4096}]}, {"category": "Standard", "default": 150.0, "group": "Sensors", "max": 1000.0, "min": 1.0, "name": "IMU_GYRO_FFT_MAX", "rebootRequired": true, "shortDesc": "IMU gyro FFT maximum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 30.0, "group": "Sensors", "max": 1000.0, "min": 1.0, "name": "IMU_GYRO_FFT_MIN", "rebootRequired": true, "shortDesc": "IMU gyro FFT minimum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 10.0, "group": "Sensors", "max": 30.0, "min": 1.0, "name": "IMU_GYRO_FFT_SNR", "shortDesc": "IMU gyro FFT SNR", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The frequency width of the stop band for the 2nd order notch filter on the primary gyro.\nSee \"IMU_GYRO_NF0_FRQ\" to activate the filter and to set the notch frequency.\nApplies to both angular velocity and angular acceleration sent to the controllers.", "max": 100.0, "min": 0.0, "name": "IMU_GYRO_NF0_BW", "rebootRequired": true, "shortDesc": "Notch filter bandwidth for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "increment": 0.1, "longDesc": "The center frequency for the 2nd order notch filter on the primary gyro.\nThis filter can be enabled to avoid feedback amplification of structural resonances at a specific frequency.\nThis only affects the signal sent to the controllers, not the estimators.\nApplies to both angular velocity and angular acceleration sent to the controllers.\nSee \"IMU_GYRO_NF0_BW\" to set the bandwidth of the filter.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_NF0_FRQ", "rebootRequired": true, "shortDesc": "Notch filter frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The frequency width of the stop band for the 2nd order notch filter on the primary gyro.\nSee \"IMU_GYRO_NF1_FRQ\" to activate the filter and to set the notch frequency.\nApplies to both angular velocity and angular acceleration sent to the controllers.", "max": 100.0, "min": 0.0, "name": "IMU_GYRO_NF1_BW", "rebootRequired": true, "shortDesc": "Notch filter 1 bandwidth for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "increment": 0.1, "longDesc": "The center frequency for the 2nd order notch filter on the primary gyro.\nThis filter can be enabled to avoid feedback amplification of structural resonances at a specific frequency.\nThis only affects the signal sent to the controllers, not the estimators.\nApplies to both angular velocity and angular acceleration sent to the controllers.\nSee \"IMU_GYRO_NF1_BW\" to set the bandwidth of the filter.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_NF1_FRQ", "rebootRequired": true, "shortDesc": "Notch filter 2 frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 400, "group": "Sensors", "longDesc": "The maximum rate the gyro control data (vehicle_angular_velocity) will be\nallowed to publish at. This is the loop rate for the rate controller and outputs.\nNote: sensor data is always read and filtered at the full raw rate (eg commonly 8 kHz) regardless of this setting.", "max": 2000, "min": 100, "name": "IMU_GYRO_RATEMAX", "rebootRequired": true, "shortDesc": "Gyro control data maximum publication rate (inner loop rate)", "type": "Int32", "units": "Hz", "values": [{"description": "100 Hz", "value": 100}, {"description": "250 Hz", "value": 250}, {"description": "400 Hz", "value": 400}, {"description": "800 Hz", "value": 800}, {"description": "1000 Hz", "value": 1000}, {"description": "2000 Hz", "value": 2000}]}, {"category": "Standard", "default": 200, "group": "Sensors", "longDesc": "The rate at which raw IMU data is integrated to produce delta angles and delta velocities.\nRecommended to set this to a multiple of the estimator update period (currently 10 ms for ekf2).", "max": 1000, "min": 100, "name": "IMU_INTEG_RATE", "rebootRequired": true, "shortDesc": "IMU integration rate", "type": "Int32", "units": "Hz", "values": [{"description": "100 Hz", "value": 100}, {"description": "200 Hz", "value": 200}, {"description": "250 Hz", "value": 250}, {"description": "400 Hz", "value": 400}]}, {"category": "Standard", "default": 1013.25, "group": "Sensors", "max": 1500.0, "min": 500.0, "name": "SENS_BARO_QNH", "shortDesc": "QNH for barometer", "type": "Float", "units": "hPa"}, {"category": "Standard", "default": 20.0, "group": "Sensors", "longDesc": "Barometric air data maximum publication rate. This is an upper bound,\nactual barometric data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_BARO_RATE", "shortDesc": "Baro max rate", "type": "Float", "units": "Hz"}, {"category": "System", "default": 0, "group": "Sensors", "longDesc": "Automatically calibrate barometer based on the GNSS height", "name": "SENS_BAR_AUTOCAL", "shortDesc": "Barometer auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "This parameter defines the rotation of the FMU board relative to the platform.", "max": 40, "min": -1, "name": "SENS_BOARD_ROT", "rebootRequired": true, "shortDesc": "Board rotation", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nThis parameter gets set during the \"level horizon\" calibration or can be\nset manually.", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_X_OFF", "shortDesc": "Board rotation X (roll) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nThis parameter gets set during the \"level horizon\" calibration or can be\nset manually.", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_Y_OFF", "shortDesc": "Board rotation Y (pitch) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nHas to be set manually (not set by any calibration).", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_Z_OFF", "shortDesc": "Board rotation Z (yaw) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_AGPSIM", "rebootRequired": true, "shortDesc": "Simulate Aux Global Position (AGP)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_ARSPDSIM", "rebootRequired": true, "shortDesc": "Enable simulated airspeed sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_BAROSIM", "rebootRequired": true, "shortDesc": "Enable simulated barometer sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_GPSSIM", "rebootRequired": true, "shortDesc": "Enable simulated GPS sinstance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_MAGSIM", "rebootRequired": true, "shortDesc": "Enable simulated magnetometer sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": -1, "group": "Sensors", "name": "SENS_EN_THERMAL", "shortDesc": "Thermal control of sensor temperature", "type": "Int32", "values": [{"description": "Thermal control unavailable", "value": -1}, {"description": "Thermal control off", "value": 0}, {"description": "Thermal control enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Probe for optional external I2C devices.", "name": "SENS_EXT_I2C_PRB", "shortDesc": "External I2C probe", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 70.0, "group": "Sensors", "longDesc": "Optical flow data maximum publication rate. This is an upper bound,\nactual optical flow data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_FLOW_RATE", "rebootRequired": true, "shortDesc": "Optical flow max rate", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "This parameter defines the yaw rotation of the optical flow relative to the vehicle body frame.\nZero rotation is defined as X on flow board pointing towards front of vehicle.", "name": "SENS_FLOW_ROT", "shortDesc": "Optical flow rotation", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Sensors", "max": 1.5, "min": 0.5, "name": "SENS_FLOW_SCALE", "shortDesc": "Optical flow scale factor", "type": "Float"}, {"bitmask": [{"description": "use speed accuracy", "index": 0}, {"description": "use hpos accuracy", "index": 1}, {"description": "use vpos accuracy", "index": 2}], "category": "Standard", "default": 7, "group": "Sensors", "longDesc": "Set bits in the following positions to set which GPS accuracy metrics will be used to calculate the blending weight. Set to zero to disable and always used first GPS instance.\n0 : Set to true to use speed accuracy\n1 : Set to true to use horizontal position accuracy\n2 : Set to true to use vertical position accuracy", "max": 7, "min": 0, "name": "SENS_GPS_MASK", "shortDesc": "Multi GPS Blending Control Mask", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "When no blending is active, this defines the preferred GPS receiver instance.\nThe GPS selection logic waits until the primary receiver is available to\nsend data to the EKF even if a secondary instance is already available.\nThe secondary instance is then only used if the primary one times out.\nTo have an equal priority of all the instances, set this parameter to -1 and\nthe best receiver will be used.\nThis parameter has no effect if blending is active.", "max": 1, "min": -1, "name": "SENS_GPS_PRIME", "shortDesc": "Multi GPS primary instance", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Sensors", "longDesc": "Sets the longest time constant that will be applied to the calculation of GPS position and height offsets used to correct data from multiple GPS data for steady state position differences.", "max": 100.0, "min": 1.0, "name": "SENS_GPS_TAU", "shortDesc": "Multi GPS Blending Time Constant", "type": "Float", "units": "s"}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Automatically initialize IMU (accel/gyro) calibration from bias estimates if available.", "name": "SENS_IMU_AUTOCAL", "shortDesc": "IMU auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Notify the user if the IMU is clipping", "name": "SENS_IMU_CLPNOTI", "shortDesc": "IMU notify clipping", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "name": "SENS_IMU_MODE", "rebootRequired": true, "shortDesc": "Sensors hub IMU mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Publish primary IMU selection", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "For systems with an external barometer, this should be set to false to make sure that the external is used.", "name": "SENS_INT_BARO_EN", "rebootRequired": true, "shortDesc": "Enable internal barometers", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Automatically initialize magnetometer calibration from bias estimate if available.", "name": "SENS_MAG_AUTOCAL", "shortDesc": "Magnetometer auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Sensors", "longDesc": "During calibration attempt to automatically determine the rotation of external magnetometers.", "name": "SENS_MAG_AUTOROT", "shortDesc": "Automatically set external rotations", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "name": "SENS_MAG_MODE", "rebootRequired": true, "shortDesc": "Sensors hub mag mode", "type": "Int32", "values": [{"description": "Publish all magnetometers", "value": 0}, {"description": "Publish primary magnetometer", "value": 1}]}, {"category": "Standard", "default": 15.0, "group": "Sensors", "longDesc": "Magnetometer data maximum publication rate. This is an upper bound,\nactual magnetometer data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_MAG_RATE", "rebootRequired": true, "shortDesc": "Magnetometer max rate", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 63, "group": "Sensors", "longDesc": "If set to two side calibration, only the offsets are estimated, the scale\ncalibration is left unchanged. Thus an initial six side calibration is\nrecommended.\nBits:\nORIENTATION_TAIL_DOWN = 1\nORIENTATION_NOSE_DOWN = 2\nORIENTATION_LEFT = 4\nORIENTATION_RIGHT = 8\nORIENTATION_UPSIDE_DOWN = 16\nORIENTATION_RIGHTSIDE_UP = 32", "max": 63, "min": 34, "name": "SENS_MAG_SIDES", "shortDesc": "Bitfield selecting mag sides for calibration", "type": "Int32", "values": [{"description": "Two side calibration", "value": 34}, {"description": "Three side calibration", "value": 38}, {"description": "Six side calibration", "value": 63}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SIM_ARSPD_FAIL", "rebootRequired": true, "shortDesc": "Dynamically simulate failure of airspeed sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 4, "default": 100.0, "group": "Simulation In Hardware", "increment": 0.01, "max": 1000.0, "min": 0.0, "name": "SIH_DISTSNSR_MAX", "shortDesc": "distance sensor maximum range", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.01, "max": 10.0, "min": 0.0, "name": "SIH_DISTSNSR_MIN", "shortDesc": "distance sensor minimum range", "type": "Float", "units": "m"}, {"category": "Standard", "default": -1.0, "group": "Simulation In Hardware", "longDesc": "Absolute value superior to 10000 will disable distance sensor", "name": "SIH_DISTSNSR_OVR", "shortDesc": "if >= 0 the distance sensor measures will be overridden by this value", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IXX", "shortDesc": "Vehicle inertia about X axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IXY", "shortDesc": "Vehicle cross term inertia xy", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IXZ", "shortDesc": "Vehicle cross term inertia xz", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IYY", "shortDesc": "Vehicle inertia about Y axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IYZ", "shortDesc": "Vehicle cross term inertia yz", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IZZ", "shortDesc": "Vehicle inertia about Z axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "Physical coefficient representing the friction with air particules.\nThe greater this value, the slower the quad will move.\nDrag force function of velocity: D=-KDV*V.\nThe maximum freefall velocity can be computed as V=10*MASS/KDV [m/s]", "min": 0.0, "name": "SIH_KDV", "shortDesc": "First order drag coefficient", "type": "Float", "units": "N/(m/s)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "Physical coefficient representing the friction with air particules during rotations.\nThe greater this value, the slower the quad will rotate.\nAerodynamic moment function of body rate: Ma=-KDW*W_B.\nThis value can be set to 0 if unknown.", "min": 0.0, "name": "SIH_KDW", "shortDesc": "First order angular damper coefficient", "type": "Float", "units": "Nm/(rad/s)"}, {"category": "Standard", "decimalPlaces": 2, "default": 489.4, "group": "Simulation In Hardware", "increment": 0.01, "longDesc": "This value represents the Above Mean Sea Level (AMSL) altitude where the simulation begins.\nIf using FlightGear as a visual animation,\nthis value can be tweaked such that the vehicle lies on the ground at takeoff.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 8848.0, "min": -420.0, "name": "SIH_LOC_H0", "shortDesc": "Initial AMSL ground altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 47.397742, "group": "Simulation In Hardware", "longDesc": "This value represents the North-South location on Earth where the simulation begins.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 90.0, "min": -90.0, "name": "SIH_LOC_LAT0", "shortDesc": "Initial geodetic latitude", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 8.545594, "group": "Simulation In Hardware", "longDesc": "This value represents the East-West location on Earth where the simulation begins.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 180.0, "min": -180.0, "name": "SIH_LOC_LON0", "shortDesc": "Initial geodetic longitude", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the arm length generating the pitching moment\nThis value can be measured with a ruler.\nThis corresponds to half the distance between the front and rear motors.", "min": 0.0, "name": "SIH_L_PITCH", "shortDesc": "Pitch arm length", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the arm length generating the rolling moment\nThis value can be measured with a ruler.\nThis corresponds to half the distance between the left and right motors.", "min": 0.0, "name": "SIH_L_ROLL", "shortDesc": "Roll arm length", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Simulation In Hardware", "increment": 0.1, "longDesc": "This value can be measured by weighting the quad on a scale.", "min": 0.0, "name": "SIH_MASS", "shortDesc": "Vehicle mass", "type": "Float", "units": "kg"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the maximum torque delivered by one propeller\nwhen the motor is running at full speed.\nThis value is usually about few percent of the maximum thrust force.", "min": 0.0, "name": "SIH_Q_MAX", "shortDesc": "Max propeller torque", "type": "Float", "units": "Nm"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "Simulation In Hardware", "increment": 0.5, "longDesc": "This is the maximum force delivered by one propeller\nwhen the motor is running at full speed.\nThis value is usually about 5 times the mass of the quadrotor.", "min": 0.0, "name": "SIH_T_MAX", "shortDesc": "Max propeller thrust force", "type": "Float", "units": "N"}, {"category": "Standard", "default": 0.05, "group": "Simulation In Hardware", "longDesc": "the time taken for the thruster to step from 0 to 100% should be about 4 times tau", "name": "SIH_T_TAU", "shortDesc": "thruster time constant tau", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Simulation In Hardware", "name": "SIH_VEHICLE_TYPE", "rebootRequired": true, "shortDesc": "Vehicle type", "type": "Int32", "values": [{"description": "Quadcopter", "value": 0}, {"description": "Fixed-Wing", "value": 1}, {"description": "Tailsitter", "value": 2}, {"description": "Standard VTOL", "value": 3}, {"description": "Hexacopter", "value": 4}]}, {"bitmask": [{"description": "Stuck", "index": 0}, {"description": "Drift", "index": 1}], "category": "Standard", "default": 0, "group": "Simulator", "longDesc": "Stuck: freeze the measurement to the current location\nDrift: add a linearly growing bias to the sensor data", "max": 3, "min": 0, "name": "SIM_AGP_FAIL", "shortDesc": "AGP failure mode", "type": "Int32"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_BARO_OFF_P", "shortDesc": "simulated barometer pressure offset", "type": "Float"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_BARO_OFF_T", "shortDesc": "simulated barometer temperature offset", "type": "Float", "units": "celcius"}, {"category": "Standard", "default": 10, "group": "Simulator", "max": 50, "min": 0, "name": "SIM_GPS_USED", "shortDesc": "simulated GPS number of satellites used", "type": "Int32"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_X", "shortDesc": "simulated magnetometer X offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_Y", "shortDesc": "simulated magnetometer Y offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_Z", "shortDesc": "simulated magnetometer Z offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "Set to 1 to reset parameters on next system startup (setting defaults).\nPlatform-specific values are used if available.\nRC* parameters are preserved.", "name": "SYS_AUTOCONFIG", "shortDesc": "Automatically configure default values", "type": "Int32", "values": [{"description": "Keep parameters", "value": 0}, {"description": "Reset parameters to airframe defaults", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "CHANGING THIS VALUE REQUIRES A RESTART. Defines the auto-start script used to bootstrap the system.", "max": 9999999, "min": 0, "name": "SYS_AUTOSTART", "rebootRequired": true, "shortDesc": "Auto-start script index", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled, update the bootloader on the next boot.\nWARNING: do not cut the power during an update process, otherwise you will\nhave to recover using some alternative method (e.g. JTAG).\nInstructions:\n- Insert an SD card\n- Enable this parameter\n- Reboot the board (plug the power or send a reboot command)\n- Wait until the board comes back up (or at least 2 minutes)\n- If it does not come back, check the file bootlog.txt on the SD card", "name": "SYS_BL_UPDATE", "rebootRequired": true, "shortDesc": "Bootloader update", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_ACCEL", "shortDesc": "Enable auto start of accelerometer thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_BARO", "shortDesc": "Enable auto start of barometer thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_GYRO", "shortDesc": "Enable auto start of rate gyro thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 24, "group": "System", "longDesc": "A temperature increase greater than this value is required during calibration.\nCalibration will complete for each sensor when the temperature increase above the starting temperature exceeds the value set by SYS_CAL_TDEL.\nIf the temperature rise is insufficient, the calibration will continue indefinitely and the board will need to be repowered to exit.", "min": 10, "name": "SYS_CAL_TDEL", "shortDesc": "Required temperature rise during thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 10, "group": "System", "longDesc": "Temperature calibration will not start if the temperature of any sensor is higher than the value set by SYS_CAL_TMAX.", "name": "SYS_CAL_TMAX", "shortDesc": "Maximum starting temperature for thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 5, "group": "System", "longDesc": "Temperature calibration for each sensor will ignore data if the temperature is lower than the value set by SYS_CAL_TMIN.", "name": "SYS_CAL_TMIN", "shortDesc": "Minimum starting temperature for thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If the board supports persistent storage (i.e., the KConfig variable DATAMAN_PERSISTENT_STORAGE is set),\nthe 'Default storage' backend uses a file on persistent storage. If not supported, this backend uses\nnon-persistent storage in RAM.", "name": "SYS_DM_BACKEND", "rebootRequired": true, "shortDesc": "Dataman storage backend", "type": "Int32", "values": [{"description": "Dataman disabled", "value": -1}, {"description": "Default storage", "value": 0}, {"description": "RAM storage", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled, future sensor calibrations will be stored to /fs/mtd_caldata.\nNote: this is only supported on boards with a separate calibration storage\n/fs/mtd_caldata.", "name": "SYS_FAC_CAL_MODE", "shortDesc": "Enable factory calibration mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "All sensors", "value": 1}, {"description": "All sensors except mag", "value": 2}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled allows MAVLink INJECT_FAILURE commands.\nWARNING: the failures can easily cause crashes and are to be used with caution!", "name": "SYS_FAILURE_EN", "shortDesc": "Enable failure injection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "Disable this if the board has no barometer, such as some of the Omnibus\nF4 SD variants.\nIf disabled, the preflight checks will not check for the presence of a\nbarometer.", "name": "SYS_HAS_BARO", "rebootRequired": true, "shortDesc": "Control if the vehicle has a barometer", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "Disable this if the system has no GPS.\nIf disabled, the sensors hub will not process sensor_gps,\nand GPS will not be available for the rest of the system.", "name": "SYS_HAS_GPS", "rebootRequired": true, "shortDesc": "Control if the vehicle has a GPS", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "0: System has no magnetometer, preflight checks should pass without one.\n1-N: Require the presence of N magnetometer sensors for check to pass.", "name": "SYS_HAS_MAG", "rebootRequired": true, "shortDesc": "Control if and how many magnetometers are expected", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "Set this to 0 if the board has no airspeed sensor.\nIf set to 0, the preflight checks will not check for the presence of an\nairspeed sensor.", "max": 1, "min": 0, "name": "SYS_HAS_NUM_ASPD", "shortDesc": "Control if the vehicle has an airspeed sensor", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "The preflight check will fail if fewer than this number of distance sensors with valid data is present.\nDisable the check with 0.", "max": 4, "min": 0, "name": "SYS_HAS_NUM_DIST", "shortDesc": "Number of distance sensors to check being available", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "The preflight check will fail if fewer than this number of optical flow sensors with valid data are present.", "max": 1, "min": 0, "name": "SYS_HAS_NUM_OF", "shortDesc": "Number of optical flow sensors required to be available", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "While enabled the system will boot in Hardware-In-The-Loop (HITL)\nor Simulation-In-Hardware (SIH) mode and not enable all sensors and checks.\nWhen disabled the same vehicle can be flown normally.\nSet to 'external HITL', if the system should perform as if it were a real\nvehicle (the only difference to a real system is then only the parameter\nvalue, which can be used for log analysis).", "name": "SYS_HITL", "rebootRequired": true, "shortDesc": "Enable HITL/SIH mode on next boot", "type": "Int32", "values": [{"description": "external HITL", "value": -1}, {"description": "HITL and SIH disabled", "value": 0}, {"description": "HITL enabled", "value": 1}, {"description": "SIH enabled", "value": 2}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "This is used internally only: an airframe configuration might set an expected\nparameter version value via PARAM_DEFAULTS_VER. This is checked on bootup\nagainst SYS_PARAM_VER, and if they do not match, parameters are reset and\nreloaded from the airframe configuration.", "min": 0, "name": "SYS_PARAM_VER", "shortDesc": "Parameter version", "type": "Int32"}, {"category": "Standard", "default": 1.0, "group": "System", "longDesc": "Set to 0 to disable, 1 for maximum brightness", "name": "SYS_RGB_MAXBRT", "shortDesc": "RGB Led brightness limit", "type": "Float", "units": "%"}, {"category": "Standard", "default": 1, "group": "System", "name": "SYS_STCK_EN", "shortDesc": "Enable stack checking", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 2, "group": "Testing", "name": "TEST_1", "shortDesc": "TEST_1", "type": "Int32"}, {"category": "Standard", "default": 4, "group": "Testing", "name": "TEST_2", "shortDesc": "TEST_2", "type": "Int32"}, {"category": "Standard", "default": 5.0, "group": "Testing", "name": "TEST_3", "shortDesc": "TEST_3", "type": "Float"}, {"category": "Standard", "default": 0.01, "group": "Testing", "name": "TEST_D", "shortDesc": "TEST_D", "type": "Float"}, {"category": "Standard", "default": 2.0, "group": "Testing", "name": "TEST_DEV", "shortDesc": "TEST_DEV", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_D_LP", "shortDesc": "TEST_D_LP", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_HP", "shortDesc": "TEST_HP", "type": "Float"}, {"category": "Standard", "default": 0.1, "group": "Testing", "name": "TEST_I", "shortDesc": "TEST_I", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_I_MAX", "shortDesc": "TEST_I_MAX", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_LP", "shortDesc": "TEST_LP", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_MAX", "shortDesc": "TEST_MAX", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_MEAN", "shortDesc": "TEST_MEAN", "type": "Float"}, {"category": "Standard", "default": -1.0, "group": "Testing", "name": "TEST_MIN", "shortDesc": "TEST_MIN", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "Testing", "name": "TEST_P", "shortDesc": "TEST_P", "type": "Float"}, {"category": "Standard", "default": 12345678, "group": "Testing", "name": "TEST_PARAMS", "shortDesc": "TEST_PARAMS", "type": "Int32"}, {"category": "Standard", "default": 16, "group": "Testing", "name": "TEST_RC2_X", "shortDesc": "TEST_RC2_X", "type": "Int32"}, {"category": "Standard", "default": 8, "group": "Testing", "name": "TEST_RC_X", "shortDesc": "TEST_RC_X", "type": "Int32"}, {"category": "Standard", "default": 0.5, "group": "Testing", "name": "TEST_TRIM", "shortDesc": "TEST_TRIM", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A0_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A0_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A0_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A1_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A1_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A1_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A2_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A2_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A2_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A3_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A3_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A3_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_A_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for accelerometer sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B0_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B0_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B0_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B0_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B1_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B1_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B1_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B1_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B2_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B2_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B2_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B2_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B3_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B3_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B3_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B3_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_B_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for barometric pressure sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G0_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G0_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G0_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G1_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G1_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G1_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G2_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G2_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G2_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G3_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G3_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G3_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_G_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for rate gyro sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M0_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M0_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M0_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M1_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M1_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M1_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M2_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M2_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M2_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M3_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M3_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M3_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_M_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for magnetometer sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0.0, "group": "UUV Attitude Control", "name": "UUV_DIRCT_PITCH", "shortDesc": "Direct pitch input", "type": "Float"}, {"category": "Standard", "default": 0.0, "group": "UUV Attitude Control", "name": "UUV_DIRCT_ROLL", "shortDesc": "Direct roll input", "type": "Float"}, {"category": "Standard", "default": 0.0, "group": "UUV Attitude Control", "name": "UUV_DIRCT_THRUST", "shortDesc": "Direct thrust input", "type": "Float"}, {"category": "Standard", "default": 0.0, "group": "UUV Attitude Control", "name": "UUV_DIRCT_YAW", "shortDesc": "Direct yaw input", "type": "Float"}, {"category": "Standard", "default": 0, "group": "UUV Attitude Control", "name": "UUV_INPUT_MODE", "shortDesc": "Select Input Mode", "type": "Int32", "values": [{"description": "use Attitude Setpoints", "value": 0}, {"description": "Direct Feedthrough", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "UUV Attitude Control", "name": "UUV_PITCH_D", "shortDesc": "Pitch differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_PITCH_P", "shortDesc": "Pitch proportional gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.5, "group": "UUV Attitude Control", "name": "UUV_ROLL_D", "shortDesc": "Roll differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_ROLL_P", "shortDesc": "Roll proportional gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "UUV Attitude Control", "name": "UUV_YAW_D", "shortDesc": "Yaw differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_YAW_P", "shortDesc": "Yawh proportional gain", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_X_D", "shortDesc": "Gain of D controller X", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_X_P", "shortDesc": "Gain of P controller X", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_Y_D", "shortDesc": "Gain of D controller Y", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_Y_P", "shortDesc": "Gain of P controller Y", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_Z_D", "shortDesc": "Gain of D controller Z", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_Z_P", "shortDesc": "Gain of P controller Z", "type": "Float"}, {"category": "Standard", "default": 1, "group": "UUV Position Control", "name": "UUV_STAB_MODE", "shortDesc": "Stabilization mode(1) or Position Control(0)", "type": "Int32", "values": [{"description": "Position Control", "value": 0}, {"description": "Stabilization Mode", "value": 1}]}, {"category": "Standard", "default": 2130706433, "group": "UXRCE-DDS Client", "longDesc": "If ethernet is enabled and is the selected configuration for uXRCE-DDS,\nthe selected Agent IP address will be set and used.\nDecimal dot notation is not supported. IP address must be provided\nin int32 format. For example, 192.168.1.2 is mapped to -1062731518;\n127.0.0.1 is mapped to 2130706433.", "name": "UXRCE_DDS_AG_IP", "rebootRequired": true, "shortDesc": "uXRCE-DDS Agent IP address", "type": "Int32"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "uXRCE-DDS domain ID", "name": "UXRCE_DDS_DOM_ID", "rebootRequired": true, "shortDesc": "uXRCE-DDS domain ID", "type": "Int32"}, {"category": "System", "default": 1, "group": "UXRCE-DDS Client", "longDesc": "uXRCE-DDS key, must be different from zero.\nIn a single agent - multi client configuration, each client\nmust have a unique session key.", "name": "UXRCE_DDS_KEY", "rebootRequired": true, "shortDesc": "uXRCE-DDS session key", "type": "Int32"}, {"category": "Standard", "default": 8888, "group": "UXRCE-DDS Client", "longDesc": "If ethernet is enabled and is the selected configuration for uXRCE-DDS,\nthe selected UDP port will be set and used.", "max": 65535, "min": 0, "name": "UXRCE_DDS_PRT", "rebootRequired": true, "shortDesc": "uXRCE-DDS UDP port", "type": "Int32"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "Set the participant configuration on the Agent's system.\n0: Use the default configuration.\n1: Restrict messages to localhost\n(use in combination with ROS_LOCALHOST_ONLY=1).\n2: Use a custom participant with the profile name \"px4_participant\".", "max": 2, "min": 0, "name": "UXRCE_DDS_PTCFG", "rebootRequired": true, "shortDesc": "uXRCE-DDS participant configuration", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Localhost-only", "value": 1}, {"description": "Custom participant", "value": 2}]}, {"category": "System", "default": -1, "group": "UXRCE-DDS Client", "longDesc": "Specifies after how many seconds without receiving data the DDS connection is reestablished.\nA value less than one disables the RX rate timeout.", "name": "UXRCE_DDS_RX_TO", "rebootRequired": true, "shortDesc": "RX rate timeout configuration", "type": "Int32", "units": "s"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "When enabled along with UXRCE_DDS_SYNCT, uxrce_dds_client will set the system clock using the agents UTC timestamp.", "name": "UXRCE_DDS_SYNCC", "rebootRequired": true, "shortDesc": "Enable uXRCE-DDS system clock synchronization", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "UXRCE-DDS Client", "longDesc": "When enabled, uxrce_dds_client will synchronize the timestamps of the incoming and outgoing messages measuring the offset between the Agent OS time and the PX4 time.", "name": "UXRCE_DDS_SYNCT", "rebootRequired": true, "shortDesc": "Enable uXRCE-DDS timestamp synchronization", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 3, "group": "UXRCE-DDS Client", "longDesc": "Specifies after how many seconds without sending data the DDS connection is reestablished.\nA value less than one disables the TX rate timeout.", "name": "UXRCE_DDS_TX_TO", "rebootRequired": true, "shortDesc": "TX rate timeout configuration", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 8.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Airspeed at which we can start blending both fw and mc controls. Set to 0 to disable.", "max": 30.0, "min": 0.0, "name": "VT_ARSP_BLEND", "shortDesc": "Transition blending airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Airspeed at which we can switch to fw mode", "max": 30.0, "min": 0.0, "name": "VT_ARSP_TRANS", "shortDesc": "Transition airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Time in seconds it takes to tilt form VT_TILT_FW to VT_TILT_MC.", "max": 10.0, "min": 0.1, "name": "VT_BT_TILT_DUR", "shortDesc": "Duration motor tilt up in backtransition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "VTOL Attitude Control", "increment": 0.05, "max": 0.3, "min": 0.0, "name": "VT_B_DEC_I", "shortDesc": "Backtransition deceleration setpoint to pitch I gain", "type": "Float", "units": "rad s/m"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Used to calculate back transition distance in an auto mode.\nFor standard vtol and tiltrotors a controller is used to track this value during the transition.", "max": 10.0, "min": 0.5, "name": "VT_B_DEC_MSS", "shortDesc": "Approximate deceleration during back transition", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Transition is also declared over if the groundspeed drops below MPC_XY_CRUISE.", "max": 20.0, "min": 0.1, "name": "VT_B_TRANS_DUR", "shortDesc": "Maximum duration of a back transition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "This sets the duration during which the MC motors ramp up to the commanded thrust during the back transition stage.", "max": 20.0, "min": 0.0, "name": "VT_B_TRANS_RAMP", "shortDesc": "Back transition MC motor ramp up time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "VTOL Attitude Control", "longDesc": "If set to 1 the control surfaces are locked at the disarmed value in multicopter mode.", "name": "VT_ELEV_MC_LOCK", "shortDesc": "Lock control surfaces in hover", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Prevents downforce from pitching the body down when facing wind.\nUses puller/pusher (standard VTOL), or forward-tilt (tiltrotor VTOL) to accelerate forward instead.\nOnly active if demanded pitch is below VT_PITCH_MIN.\nUse VT_FWD_THRUST_SC to tune it.\nDescend mode is treated as Landing too.\nOnly active (if enabled) in height-rate controlled modes.", "name": "VT_FWD_THRUST_EN", "shortDesc": "Use fixed-wing actuation in hover to accelerate forward", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled (except LANDING)", "value": 1}, {"description": "Enabled if above MPC_LAND_ALT1", "value": 2}, {"description": "Enabled if above MPC_LAND_ALT2", "value": 3}, {"description": "Enabled constantly", "value": 4}, {"description": "Enabled if above MPC_LAND_ALT1 (except LANDING)", "value": 5}, {"description": "Enabled if above MPC_LAND_ALT2 (except LANDING)", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Scale applied to the demanded pitch (below VT_PITCH_MIN) to get the fixed-wing forward actuation in hover mode.\nEnabled via VT_FWD_THRUST_EN.", "max": 5.0, "min": 0.0, "name": "VT_FWD_THRUST_SC", "shortDesc": "Fixed-wing actuation thrust scale in hover", "type": "Float"}, {"bitmask": [{"description": "Yaw", "index": 0}, {"description": "Roll", "index": 1}, {"description": "Pitch", "index": 2}], "category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Enable differential thrust seperately for roll, pitch, yaw in forward (fixed-wing) mode.\nThe effectiveness of differential thrust around the corresponding axis can be\ntuned by setting VT_FW_DIFTHR_S_R / VT_FW_DIFTHR_S_P / VT_FW_DIFTHR_S_Y.", "max": 7, "min": 0, "name": "VT_FW_DIFTHR_EN", "shortDesc": "Differential thrust in forwards flight", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_P", "shortDesc": "Pitch differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_R", "shortDesc": "Roll differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_Y", "shortDesc": "Yaw differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Minimum altitude for fixed-wing flight. When the vehicle is in fixed-wing mode\nand the altitude drops below this altitude (relative altitude above local origin),\nit will instantly switch back to MC mode and execute behavior defined in COM_QC_ACT.", "max": 200.0, "min": 0.0, "name": "VT_FW_MIN_ALT", "shortDesc": "Quad-chute altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "increment": 1, "longDesc": "Maximum height above the ground (if available, otherwise above\nHome if available, otherwise above the local origin) where triggering a quad-chute is possible.\nAt high altitudes there is a big risk to deplete the battery and therefore crash if quad-chuting there.", "min": 0, "name": "VT_FW_QC_HMAX", "shortDesc": "Quad-chute maximum height", "type": "Int32", "units": "m"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Absolute pitch threshold for quad-chute triggering in FW mode.\nAbove this the vehicle will transition back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 180, "min": 0, "name": "VT_FW_QC_P", "shortDesc": "Quad-chute max pitch threshold", "type": "Int32", "units": "deg"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Absolute roll threshold for quad-chute triggering in FW mode.\nAbove this the vehicle will transition back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 180, "min": 0, "name": "VT_FW_QC_R", "shortDesc": "Quad-chute max roll threshold", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Time in seconds used for a transition", "max": 20.0, "min": 0.1, "name": "VT_F_TRANS_DUR", "shortDesc": "Duration of a front transition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_F_TRANS_THR", "shortDesc": "Target throttle value for the transition to fixed-wing flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.0, "group": "VTOL Attitude Control", "increment": 0.5, "longDesc": "The duration of the front transition when there is no airspeed feedback available.\nWhen airspeed is used, transition timeout is declared if airspeed does not\nreach VT_ARSP_BLEND after this time.", "max": 30.0, "min": 1.0, "name": "VT_F_TR_OL_TM", "shortDesc": "Airspeed-less front transition time (open loop)", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": -5.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Overrides VT_PITCH_MIN when the vehicle is in LAND mode (hovering).\nDuring landing it can be beneficial to reduce the pitch angle to reduce the generated lift in head wind.", "max": 45.0, "min": -10.0, "name": "VT_LND_PITCH_MIN", "shortDesc": "Minimum pitch angle during hover landing", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -5.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Any pitch setpoint below this value is translated to a forward force by the fixed-wing forward actuation if\nVT_FWD_TRHUST_EN is set.", "max": 45.0, "min": -10.0, "name": "VT_PITCH_MIN", "shortDesc": "Minimum pitch angle during hover", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.33, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Defines the slew rate of the puller/pusher throttle during transitions.\nZero will deactivate the slew rate limiting and thus produce an instant throttle\nrise to the transition throttle VT_F_TRANS_THR.", "min": 0.0, "name": "VT_PSHER_SLEW", "shortDesc": "Pusher throttle ramp up slew rate", "type": "Float", "units": "1/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Altitude error threshold for quad-chute triggering during fixed-wing flight.\nThe check is only active if altitude is controlled and the vehicle is below the current altitude reference.\nThe altitude error is relative to the highest altitude the vehicle has achieved since it has flown below the current\naltitude reference.\nSet to 0 do disable.", "max": 200.0, "min": 0.0, "name": "VT_QC_ALT_LOSS", "shortDesc": "Quad-chute uncommanded descent threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Altitude loss threshold for quad-chute triggering during VTOL transition to fixed-wing flight\nin altitude-controlled flight modes.\nActive until 5s after completing transition to fixed-wing.\nIf the current altitude is more than this value below the altitude at the beginning of the\ntransition, it will instantly switch back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 50.0, "min": 0.0, "name": "VT_QC_T_ALT_LOSS", "shortDesc": "Quad-chute transition altitude loss threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.1, "max": 1.0, "min": -1.0, "name": "VT_SPOILER_MC_LD", "shortDesc": "Spoiler setting while landing (hover)", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_FW", "shortDesc": "Normalized tilt in FW", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_MC", "shortDesc": "Normalized tilt in Hover", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.4, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_TRANS", "shortDesc": "Normalized tilt in transition to FW", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Minimum time in seconds for front transition.", "max": 20.0, "min": 0.0, "name": "VT_TRANS_MIN_TM", "shortDesc": "Front transition minimum time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Time in seconds it takes to tilt form VT_TILT_TRANS to VT_TILT_FW.", "max": 5.0, "min": 0.1, "name": "VT_TRANS_P2_DUR", "shortDesc": "Duration of front transition phase 2", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 15.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Time in seconds after which transition will be cancelled.", "max": 30.0, "min": 0.1, "name": "VT_TRANS_TIMEOUT", "shortDesc": "Front transition timeout", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "max": 2, "min": 0, "name": "VT_TYPE", "rebootRequired": true, "shortDesc": "VTOL Type (Tailsitter=0, Tiltrotor=1, Standard=2)", "type": "Int32", "values": [{"description": "Tailsitter", "value": 0}, {"description": "Tiltrotor", "value": 1}, {"description": "Standard", "value": 2}]}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "The desired gain to convert roll sp into yaw rate sp.", "max": 3.0, "min": 0.0, "name": "WV_GAIN", "shortDesc": "Weather-vane roll angle to yawrate", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 80.0, "group": "VTOL Takeoff", "increment": 1.0, "longDesc": "Altitude relative to home at which vehicle will loiter after front transition.", "max": 300.0, "min": 20.0, "name": "VTO_LOITER_ALT", "shortDesc": "VTOL Takeoff relative loiter altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Miscellaneous", "name": "UUV_SKIP_CTRL", "shortDesc": "Skip the controller", "type": "Int32", "values": [{"description": "use the module's controller", "value": 0}, {"description": "skip the controller and feedthrough the setpoints", "value": 1}]}], "translation": {"items": {"parameters": {"list": {"items": {"bitmask": {"list": {"key": "index", "translate": ["description"]}}, "values": {"list": {"key": "value", "translate": ["description"]}}}, "key": "name", "translate": ["shortDesc", "longDesc"], "translate-global": ["category", "group"]}}}}, "version": 1} \ No newline at end of file +{"parameters": [{"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets first 4 characters of a total of 8. Valid characters are A-Z, 0-9, \" \". Example \"PX4 \" -> 1347957792\nFor CALLSIGN shorter than 8 characters use the null terminator at the end '\\0'.", "name": "ADSB_CALLSIGN_1", "rebootRequired": true, "shortDesc": "First 4 characters of CALLSIGN", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets second 4 characters of a total of 8. Valid characters are A-Z, 0-9, \" \" only. Example \"TEST\" -> 1413829460\nFor CALLSIGN shorter than 8 characters use the null terminator at the end '\\0'.", "name": "ADSB_CALLSIGN_2", "rebootRequired": true, "shortDesc": "Second 4 characters of CALLSIGN", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets the vehicle emergency state", "max": 6, "min": 0, "name": "ADSB_EMERGC", "rebootRequired": true, "shortDesc": "ADSB-Out Emergency State", "type": "Int32", "values": [{"description": "NoEmergency", "value": 0}, {"description": "General", "value": 1}, {"description": "Medical", "value": 2}, {"description": "LowFuel", "value": 3}, {"description": "NoCommunications", "value": 4}, {"description": "Interference", "value": 5}, {"description": "Downed", "value": 6}]}, {"category": "Standard", "default": 14, "group": "ADSB", "longDesc": "Configure the emitter type of the vehicle.", "max": 15, "min": 0, "name": "ADSB_EMIT_TYPE", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Emitter Type", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "Light", "value": 1}, {"description": "Small", "value": 2}, {"description": "Large", "value": 3}, {"description": "HighVortex", "value": 4}, {"description": "Heavy", "value": 5}, {"description": "Performance", "value": 6}, {"description": "Rotorcraft", "value": 7}, {"description": "RESERVED", "value": 8}, {"description": "Glider", "value": 9}, {"description": "LightAir", "value": 10}, {"description": "Parachute", "value": 11}, {"description": "UltraLight", "value": 12}, {"description": "RESERVED", "value": 13}, {"description": "UAV", "value": 14}, {"description": "Space", "value": 15}, {"description": "RESERVED", "value": 16}, {"description": "EmergencySurf", "value": 17}, {"description": "ServiceSurf", "value": 18}, {"description": "PointObstacle", "value": 19}]}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets GPS lataral offset encoding", "max": 7, "min": 0, "name": "ADSB_GPS_OFF_LAT", "rebootRequired": true, "shortDesc": "ADSB-Out GPS Offset lat", "type": "Int32", "values": [{"description": "NoData", "value": 0}, {"description": "LatLeft2M", "value": 1}, {"description": "LatLeft4M", "value": 2}, {"description": "LatLeft6M", "value": 3}, {"description": "LatRight0M", "value": 4}, {"description": "LatRight2M", "value": 5}, {"description": "LatRight4M", "value": 6}, {"description": "LatRight6M", "value": 7}]}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Sets GPS longitudinal offset encoding", "max": 1, "min": 0, "name": "ADSB_GPS_OFF_LON", "rebootRequired": true, "shortDesc": "ADSB-Out GPS Offset lon", "type": "Int32", "values": [{"description": "NoData", "value": 0}, {"description": "AppliedBySensor", "value": 1}]}, {"category": "Standard", "default": 1194684, "group": "ADSB", "longDesc": "Defines the ICAO ID of the vehicle", "max": 16777215, "min": -1, "name": "ADSB_ICAO_ID", "rebootRequired": true, "shortDesc": "ADSB-Out ICAO configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "This vehicle is always tracked. Use 0 to disable.", "max": 16777215, "min": 0, "name": "ADSB_ICAO_SPECL", "rebootRequired": true, "shortDesc": "ADSB-In Special ICAO configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Enable Identification of Position feature", "name": "ADSB_IDENT", "rebootRequired": true, "shortDesc": "ADSB-Out Ident Configuration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "ADSB", "longDesc": "Report the length and width of the vehicle in meters. In most cases, use '1' for the smallest vehicle size.", "max": 15, "min": 0, "name": "ADSB_LEN_WIDTH", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Size Configuration", "type": "Int32", "values": [{"description": "SizeUnknown", "value": 0}, {"description": "Len15_Wid23", "value": 1}, {"description": "Len25_Wid28", "value": 2}, {"description": "Len25_Wid34", "value": 3}, {"description": "Len35_Wid33", "value": 4}, {"description": "Len35_Wid38", "value": 5}, {"description": "Len45_Wid39", "value": 6}, {"description": "Len45_Wid45", "value": 7}, {"description": "Len55_Wid45", "value": 8}, {"description": "Len55_Wid52", "value": 9}, {"description": "Len65_Wid59", "value": 10}, {"description": "Len65_Wid67", "value": 11}, {"description": "Len75_Wid72", "value": 12}, {"description": "Len75_Wid80", "value": 13}, {"description": "Len85_Wid80", "value": 14}, {"description": "Len85_Wid90", "value": 15}]}, {"category": "Standard", "default": 25, "group": "ADSB", "longDesc": "Change number of targets to track", "max": 50, "min": 0, "name": "ADSB_LIST_MAX", "rebootRequired": true, "shortDesc": "ADSB-In Vehicle List Size", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "ADSB", "longDesc": "Informs ADSB vehicles of this vehicle's max speed capability", "max": 6, "min": 0, "name": "ADSB_MAX_SPEED", "rebootRequired": true, "shortDesc": "ADSB-Out Vehicle Max Speed", "type": "Int32", "values": [{"description": "UnknownMaxSpeed", "value": 0}, {"description": "75Kts", "value": 1}, {"description": "150Kts", "value": 2}, {"description": "300Kts", "value": 3}, {"description": "600Kts", "value": 4}, {"description": "1200Kts", "value": 5}, {"description": "Over1200Kts", "value": 6}]}, {"category": "Standard", "default": 1200, "group": "ADSB", "longDesc": "This parameter defines the squawk code. Value should be between 0000 and 7777.", "max": 7777, "min": 0, "name": "ADSB_SQUAWK", "rebootRequired": true, "shortDesc": "ADSB-Out squawk code configuration", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 1.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC1", "shortDesc": "SIM Channel 1 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 10.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC10", "shortDesc": "SIM Channel 10 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 11.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC11", "shortDesc": "SIM Channel 11 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 12.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC12", "shortDesc": "SIM Channel 12 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 13.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC13", "shortDesc": "SIM Channel 13 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 14.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC14", "shortDesc": "SIM Channel 14 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 15.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC15", "shortDesc": "SIM Channel 15 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 16.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC16", "shortDesc": "SIM Channel 16 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 2.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC2", "shortDesc": "SIM Channel 2 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 3.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC3", "shortDesc": "SIM Channel 3 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 4.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC4", "shortDesc": "SIM Channel 4 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 5.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC5", "shortDesc": "SIM Channel 5 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 6.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC6", "shortDesc": "SIM Channel 6 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 7.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC7", "shortDesc": "SIM Channel 7 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 8.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC8", "shortDesc": "SIM Channel 8 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Select what should be output on SIM Channel 9.\nThe default failsafe value is set according to the selected function:\n- 'Min' for ConstantMin\n- 'Max' for ConstantMax\n- 'Max' for Parachute\n- ('Max'+'Min')/2 for Servos\n- 'Disarmed' for the rest", "name": "PWM_MAIN_FUNC9", "shortDesc": "SIM Channel 9 Output Function", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Constant Min", "value": 1}, {"description": "Constant Max", "value": 2}, {"description": "Motor 1", "value": 101}, {"description": "Motor 2", "value": 102}, {"description": "Motor 3", "value": 103}, {"description": "Motor 4", "value": 104}, {"description": "Motor 5", "value": 105}, {"description": "Motor 6", "value": 106}, {"description": "Motor 7", "value": 107}, {"description": "Motor 8", "value": 108}, {"description": "Motor 9", "value": 109}, {"description": "Motor 10", "value": 110}, {"description": "Motor 11", "value": 111}, {"description": "Motor 12", "value": 112}, {"description": "Servo 1", "value": 201}, {"description": "Servo 2", "value": 202}, {"description": "Servo 3", "value": 203}, {"description": "Servo 4", "value": 204}, {"description": "Servo 5", "value": 205}, {"description": "Servo 6", "value": 206}, {"description": "Servo 7", "value": 207}, {"description": "Servo 8", "value": 208}, {"description": "Peripheral via Actuator Set 1", "value": 301}, {"description": "Peripheral via Actuator Set 2", "value": 302}, {"description": "Peripheral via Actuator Set 3", "value": 303}, {"description": "Peripheral via Actuator Set 4", "value": 304}, {"description": "Peripheral via Actuator Set 5", "value": 305}, {"description": "Peripheral via Actuator Set 6", "value": 306}, {"description": "Landing Gear", "value": 400}, {"description": "Parachute", "value": 401}, {"description": "RC Roll", "value": 402}, {"description": "RC Pitch", "value": 403}, {"description": "RC Throttle", "value": 404}, {"description": "RC Yaw", "value": 405}, {"description": "RC Flaps", "value": 406}, {"description": "RC AUX 1", "value": 407}, {"description": "RC AUX 2", "value": 408}, {"description": "RC AUX 3", "value": 409}, {"description": "RC AUX 4", "value": 410}, {"description": "RC AUX 5", "value": 411}, {"description": "RC AUX 6", "value": 412}, {"description": "Gimbal Roll", "value": 420}, {"description": "Gimbal Pitch", "value": 421}, {"description": "Gimbal Yaw", "value": 422}, {"description": "Gripper", "value": 430}, {"description": "Landing Gear Wheel", "value": 440}, {"description": "IC Engine Ignition", "value": 450}, {"description": "IC Engine Throttle", "value": 451}, {"description": "IC Engine Choke", "value": 452}, {"description": "IC Engine Starter", "value": 453}]}, {"bitmask": [{"description": "SIM Channel 1", "index": 0}, {"description": "SIM Channel 2", "index": 1}, {"description": "SIM Channel 3", "index": 2}, {"description": "SIM Channel 4", "index": 3}, {"description": "SIM Channel 5", "index": 4}, {"description": "SIM Channel 6", "index": 5}, {"description": "SIM Channel 7", "index": 6}, {"description": "SIM Channel 8", "index": 7}, {"description": "SIM Channel 9", "index": 8}, {"description": "SIM Channel 10", "index": 9}, {"description": "SIM Channel 11", "index": 10}, {"description": "SIM Channel 12", "index": 11}, {"description": "SIM Channel 13", "index": 12}, {"description": "SIM Channel 14", "index": 13}, {"description": "SIM Channel 15", "index": 14}, {"description": "SIM Channel 16", "index": 15}], "category": "Standard", "default": 0, "group": "Actuator Outputs", "longDesc": "Allows to reverse the output range for each channel.\nNote: this is only useful for servos.", "max": 65535, "min": 0, "name": "PWM_MAIN_REV", "shortDesc": "Reverse Output Range for SIM", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "Airspeed Validator", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "max": 5, "min": 1, "name": "ASPD_BETA_GATE", "shortDesc": "Gate size for sideslip angle fusion", "type": "Int32", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Airspeed Validator", "longDesc": "Sideslip measurement noise of the internal wind estimator(s) of the airspeed selector.", "max": 1.0, "min": 0.0, "name": "ASPD_BETA_NOISE", "shortDesc": "Wind estimator sideslip measurement noise", "type": "Float", "units": "rad"}, {"bitmask": [{"description": "Only data missing check (triggers if more than 1s no data)", "index": 0}, {"description": "Data stuck (triggers if data is exactly constant for 2s in FW mode)", "index": 1}, {"description": "Innovation check (see ASPD_FS_INNOV)", "index": 2}, {"description": "Load factor check (triggers if measurement is below stall speed)", "index": 3}, {"description": "First principle check (airspeed change vs. throttle and pitch)", "index": 4}], "category": "Standard", "default": 7, "group": "Airspeed Validator", "longDesc": "Controls which checks are run to check airspeed data for validity. Only applied if ASPD_PRIMARY > 0.\nNote: The missing data check (bit 0) is implicitly always enabled when ASPD_DO_CHECKS > 0, even if bit 0 is not explicitly set.", "max": 31, "min": 0, "name": "ASPD_DO_CHECKS", "shortDesc": "Enable checks on airspeed sensors", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Airspeed Validator", "name": "ASPD_FALLBACK", "shortDesc": "Fallback options", "type": "Int32", "values": [{"description": "Fallback only to other airspeed sensors", "value": 0}, {"description": "Fallback to groundspeed-minus-windspeed airspeed estimation", "value": 1}, {"description": "Fallback to thrust based airspeed estimation", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Airspeed Validator", "longDesc": "Window for comparing airspeed change to throttle and pitch change.\nTriggers when the airspeed change within this window is negative while throttle increases\nand the vehicle pitches down.\nIs meant to catch degrading airspeed blockages as can happen when flying through icing conditions.\nRelies on FW_THR_TRIM being set accurately.", "min": 0.0, "name": "ASPD_FP_T_WINDOW", "shortDesc": "First principle airspeed check time window", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Airspeed Validator", "longDesc": "This specifies the minimum airspeed innovation required to trigger a failsafe. Larger values make the check less sensitive,\nsmaller values make it more sensitive. Large innovations indicate an inconsistency between predicted (groundspeed - windspeeed)\nand measured airspeed.\nThe time required to detect a fault when the threshold is exceeded depends on the size of the exceedance and is controlled by the ASPD_FS_INTEG parameter.", "max": 10.0, "min": 0.5, "name": "ASPD_FS_INNOV", "shortDesc": "Airspeed failure innovation threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Airspeed Validator", "longDesc": "This sets the time integral of airspeed innovation exceedance above ASPD_FS_INNOV required to trigger a failsafe.\nLarger values make the check less sensitive, smaller positive values make it more sensitive.", "max": 50.0, "min": 0.0, "name": "ASPD_FS_INTEG", "shortDesc": "Airspeed failure innovation integral threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Airspeed Validator", "longDesc": "Delay before switching back to using airspeed sensor if checks indicate sensor is good.\nSet to a negative value to disable the re-enabling in flight.", "min": -1.0, "name": "ASPD_FS_T_START", "shortDesc": "Airspeed failsafe start delay", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Airspeed Validator", "longDesc": "Delay before stopping use of airspeed sensor if checks indicate sensor is bad.", "min": 0.0, "name": "ASPD_FS_T_STOP", "shortDesc": "Airspeed failsafe stop delay", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Airspeed Validator", "name": "ASPD_PRIMARY", "rebootRequired": true, "shortDesc": "Index or primary airspeed measurement source", "type": "Int32", "values": [{"description": "Groundspeed minus windspeed", "value": 0}, {"description": "First airspeed sensor", "value": 1}, {"description": "Second airspeed sensor", "value": 2}, {"description": "Third airspeed sensor", "value": 3}, {"description": "Thrust based airspeed", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the first airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_1", "shortDesc": "Scale of airspeed sensor 1", "type": "Float", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the second airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_2", "shortDesc": "Scale of airspeed sensor 2", "type": "Float", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Airspeed Validator", "longDesc": "This is the scale IAS --> CAS of the third airspeed sensor instance", "max": 2.0, "min": 0.5, "name": "ASPD_SCALE_3", "shortDesc": "Scale of airspeed sensor 3", "type": "Float", "volatile": true}, {"category": "Standard", "default": 2, "group": "Airspeed Validator", "name": "ASPD_SCALE_APPLY", "shortDesc": "Controls when to apply the new estimated airspeed scale(s)", "type": "Int32", "values": [{"description": "Do not automatically apply the estimated scale", "value": 0}, {"description": "Apply the estimated scale after disarm", "value": 1}, {"description": "Apply the estimated scale in air", "value": 2}]}, {"category": "Standard", "decimalPlaces": 5, "default": 0.0001, "group": "Airspeed Validator", "longDesc": "Airspeed scale process noise of the internal wind estimator(s) of the airspeed selector.\nWhen unaided, the scale uncertainty (1-sigma, unitless) increases by this amount every second.", "max": 0.1, "min": 0.0, "name": "ASPD_SCALE_NSD", "shortDesc": "Wind estimator true airspeed scale process noise spectral density", "type": "Float", "units": "1/s/sqrt(Hz)"}, {"category": "Standard", "default": 4, "group": "Airspeed Validator", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "max": 5, "min": 1, "name": "ASPD_TAS_GATE", "shortDesc": "Gate size for true airspeed fusion", "type": "Int32", "units": "SD"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.4, "group": "Airspeed Validator", "longDesc": "True airspeed measurement noise of the internal wind estimator(s) of the airspeed selector.", "max": 4.0, "min": 0.0, "name": "ASPD_TAS_NOISE", "shortDesc": "Wind estimator true airspeed measurement noise", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Airspeed Validator", "longDesc": "The airspeed alternative derived from groundspeed and heading will be declared valid\nas soon and as long the horizontal wind uncertainty is below this value.", "max": 5.0, "min": 0.01, "name": "ASPD_WERR_THR", "shortDesc": "Horizontal wind uncertainty threshold for valid ground-minus-wind", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Airspeed Validator", "longDesc": "Wind process noise of the internal wind estimator(s) of the airspeed selector.\nWhen unaided, the wind estimate uncertainty (1-sigma, in m/s) increases by this amount every second.", "max": 1.0, "min": 0.0, "name": "ASPD_WIND_NSD", "shortDesc": "Wind estimator wind process noise spectral density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "name": "ATT_ACC_COMP", "shortDesc": "Acceleration compensation based on GPS velocity", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Attitude Q estimator", "max": 2.0, "min": 0.0, "name": "ATT_BIAS_MAX", "shortDesc": "Gyro bias limit", "type": "Float", "units": "rad/s"}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "longDesc": "Enable standalone quaternion based attitude estimator.", "name": "ATT_EN", "shortDesc": "standalone attitude estimator enable (unsupported)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Attitude Q estimator", "longDesc": "Set to 1 to use heading estimate from vision.\nSet to 2 to use heading from motion capture.", "max": 2, "min": 0, "name": "ATT_EXT_HDG_M", "shortDesc": "External heading usage mode (from Motion capture/Vision)", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Vision", "value": 1}, {"description": "Motion Capture", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Attitude Q estimator", "longDesc": "This parameter is not used in normal operation,\nas the declination is looked up based on the\nGPS coordinates of the vehicle.", "name": "ATT_MAG_DECL", "shortDesc": "Magnetic declination, in degrees", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 1, "group": "Attitude Q estimator", "name": "ATT_MAG_DECL_A", "shortDesc": "Automatic GPS based declination compensation", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_ACC", "shortDesc": "Complimentary filter accelerometer weight", "type": "Float"}, {"category": "Standard", "default": 0.1, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_EXT_HDG", "shortDesc": "Complimentary filter external heading weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Attitude Q estimator", "max": 1.0, "min": 0.0, "name": "ATT_W_GYRO_BIAS", "shortDesc": "Complimentary filter gyroscope bias weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Attitude Q estimator", "longDesc": "Set to 0 to avoid using the magnetometer.", "max": 1.0, "min": 0.0, "name": "ATT_W_MAG", "shortDesc": "Complimentary filter magnetometer weight", "type": "Float"}, {"category": "Standard", "default": 2, "group": "Autotune", "longDesc": "After the auto-tuning sequence is completed,\na new set of gains is available and can be applied\nimmediately or after landing.", "name": "FW_AT_APPLY", "shortDesc": "Controls when to apply the new gains", "type": "Int32", "values": [{"description": "Do not apply the new gains (logging only)", "value": 0}, {"description": "Apply the new gains after disarm", "value": 1}, {"description": "Apply the new gains in air", "value": 2}]}, {"bitmask": [{"description": "roll", "index": 0}, {"description": "pitch", "index": 1}, {"description": "yaw", "index": 2}], "category": "Standard", "default": 3, "group": "Autotune", "longDesc": "Defines which axes will be tuned during the auto-tuning sequence\nSet bits in the following positions to enable:\n0 : Roll\n1 : Pitch\n2 : Yaw", "max": 7, "min": 1, "name": "FW_AT_AXES", "shortDesc": "Tuning axes selection", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Autotune", "longDesc": "Defines which RC_MAP_AUXn parameter maps the manual control channel used to enable/disable auto tuning.", "max": 6, "min": 0, "name": "FW_AT_MAN_AUX", "shortDesc": "Enable/disable auto tuning using a manual control AUX input", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Aux1", "value": 1}, {"description": "Aux2", "value": 2}, {"description": "Aux3", "value": 3}, {"description": "Aux4", "value": 4}, {"description": "Aux5", "value": 5}, {"description": "Aux6", "value": 6}]}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Autotune", "longDesc": "Can be set lower or higher than the end frequency", "max": 30.0, "min": 0.1, "name": "FW_AT_SYSID_F0", "shortDesc": "Start frequency of the injected signal", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Autotune", "longDesc": "Can be set lower or higher than the start frequency", "max": 30.0, "min": 0.1, "name": "FW_AT_SYSID_F1", "shortDesc": "End frequency of the injected signal", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 0, "default": 10.0, "group": "Autotune", "longDesc": "Duration of the input signal sent on each axis during system identification", "max": 120.0, "min": 5.0, "name": "FW_AT_SYSID_TIME", "shortDesc": "Maneuver time for each axis", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Autotune", "longDesc": "Type of signal used during system identification to excite the system.", "name": "FW_AT_SYSID_TYPE", "shortDesc": "Input signal type", "type": "Int32", "values": [{"description": "Step", "value": 0}, {"description": "Linear sine sweep", "value": 1}, {"description": "Logarithmic sine sweep", "value": 2}]}, {"category": "Standard", "default": 1, "group": "Autotune", "longDesc": "After the auto-tuning sequence is completed,\na new set of gains is available and can be applied\nimmediately or after landing.\nWARNING Applying the gains in air is dangerous as there is no\nguarantee that those new gains will be able to stabilize\nthe drone properly.", "name": "MC_AT_APPLY", "shortDesc": "Controls when to apply the new gains", "type": "Int32", "values": [{"description": "Do not apply the new gains (logging only)", "value": 0}, {"description": "Apply the new gains after disarm", "value": 1}, {"description": "WARNING Apply the new gains in air", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Autotune", "name": "MC_AT_EN", "shortDesc": "Multicopter autotune module enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.14, "group": "Autotune", "max": 0.5, "min": 0.01, "name": "MC_AT_RISE_TIME", "shortDesc": "Desired angular rate closed-loop rise time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.7, "group": "Autotune", "max": 6.0, "min": 0.1, "name": "MC_AT_SYSID_AMP", "shortDesc": "Amplitude of the injected signal", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 1 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT1_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 1 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT1_N_CELLS", "shortDesc": "Number of cells for battery 1", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT1_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 1", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module / Analog'\nmeans that measurements are expected to come from either analog (ADC) inputs\nor an I2C power monitor (e.g. INA226). Analog inputs are voltage and current\nmeasurements read from the board's ADC channels, typically from an onboard\nvoltage divider and current shunt, or an external analog power module.\nI2C power monitors are digital sensors on the I2C bus.\nIf the value is set to 'External' then the system expects to receive MAVLink\nor CAN battery status messages, or the battery data is published by an external driver.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current (via ESC telemetry).", "name": "BAT1_SOURCE", "rebootRequired": true, "shortDesc": "Battery 1 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module / Analog", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT1_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT1_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 2 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT2_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 2 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT2_N_CELLS", "shortDesc": "Number of cells for battery 2", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT2_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 2", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": -1, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module / Analog'\nmeans that measurements are expected to come from either analog (ADC) inputs\nor an I2C power monitor (e.g. INA226). Analog inputs are voltage and current\nmeasurements read from the board's ADC channels, typically from an onboard\nvoltage divider and current shunt, or an external analog power module.\nI2C power monitors are digital sensors on the I2C bus.\nIf the value is set to 'External' then the system expects to receive MAVLink\nor CAN battery status messages, or the battery data is published by an external driver.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current (via ESC telemetry).", "name": "BAT2_SOURCE", "rebootRequired": true, "shortDesc": "Battery 2 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module / Analog", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT2_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT2_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Battery Calibration", "increment": 50.0, "longDesc": "Defines the capacity of battery 3 in mAh.", "max": 100000.0, "min": -1.0, "name": "BAT3_CAPACITY", "rebootRequired": true, "shortDesc": "Battery 3 capacity", "type": "Float", "units": "mAh"}, {"category": "Standard", "default": 0, "group": "Battery Calibration", "longDesc": "Defines the number of cells the attached battery consists of.", "name": "BAT3_N_CELLS", "shortDesc": "Number of cells for battery 3", "type": "Int32", "values": [{"description": "Unknown", "value": 0}, {"description": "1S Battery", "value": 1}, {"description": "2S Battery", "value": 2}, {"description": "3S Battery", "value": 3}, {"description": "4S Battery", "value": 4}, {"description": "5S Battery", "value": 5}, {"description": "6S Battery", "value": 6}, {"description": "7S Battery", "value": 7}, {"description": "8S Battery", "value": 8}, {"description": "9S Battery", "value": 9}, {"description": "10S Battery", "value": 10}, {"description": "11S Battery", "value": 11}, {"description": "12S Battery", "value": 12}, {"description": "13S Battery", "value": 13}, {"description": "14S Battery", "value": 14}, {"description": "15S Battery", "value": 15}, {"description": "16S Battery", "value": 16}]}, {"category": "Standard", "decimalPlaces": 4, "default": -1.0, "group": "Battery Calibration", "increment": 0.0005, "longDesc": "If non-negative, then this will be used instead of the online estimated internal resistance.", "max": 0.2, "min": -1.0, "name": "BAT3_R_INTERNAL", "rebootRequired": true, "shortDesc": "Explicitly defines the per cell internal resistance for battery 3", "type": "Float", "units": "Ohm"}, {"category": "Standard", "default": -1, "group": "Battery Calibration", "longDesc": "This parameter controls the source of battery data. The value 'Power Module / Analog'\nmeans that measurements are expected to come from either analog (ADC) inputs\nor an I2C power monitor (e.g. INA226). Analog inputs are voltage and current\nmeasurements read from the board's ADC channels, typically from an onboard\nvoltage divider and current shunt, or an external analog power module.\nI2C power monitors are digital sensors on the I2C bus.\nIf the value is set to 'External' then the system expects to receive MAVLink\nor CAN battery status messages, or the battery data is published by an external driver.\nIf the value is set to 'ESCs', the battery information are taken from the esc_status message.\nThis requires the ESC to provide both voltage as well as current (via ESC telemetry).", "name": "BAT3_SOURCE", "rebootRequired": true, "shortDesc": "Battery 3 monitoring source", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Power Module / Analog", "value": 0}, {"description": "External", "value": 1}, {"description": "ESCs", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 4.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered full.\nFor a more accurate estimate set this below the nominal voltage of e.g. 4.2V", "name": "BAT3_V_CHARGED", "rebootRequired": true, "shortDesc": "Full cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.6, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Defines the voltage where a single cell of the battery is considered empty.\nThe voltage should be chosen above the steep dropoff at 3.5V. A typical\nlithium battery can only be discharged under high load down to 10% before\nit drops off to a voltage level damaging the cells.", "name": "BAT3_V_EMPTY", "rebootRequired": true, "shortDesc": "Empty cell voltage", "type": "Float", "units": "V"}, {"category": "Standard", "decimalPlaces": 2, "default": 15.0, "group": "Battery Calibration", "increment": 0.1, "longDesc": "This value is used to initialize the in-flight average current estimation,\nwhich in turn is used for estimating remaining flight time and RTL triggering.", "max": 500.0, "min": 0.0, "name": "BAT_AVRG_CURRENT", "shortDesc": "Expected battery current in flight", "type": "Float", "units": "A"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.07, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as critically low.\nThis has to be lower than the low threshold. This threshold commonly\nwill trigger RTL.", "max": 0.5, "min": 0.05, "name": "BAT_CRIT_THR", "shortDesc": "Critical threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as dangerously low.\nThis has to be lower than the critical threshold. This threshold commonly\nwill trigger landing.", "max": 0.5, "min": 0.03, "name": "BAT_EMERGEN_THR", "shortDesc": "Emergency threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "Battery Calibration", "increment": 0.01, "longDesc": "Sets the threshold when the battery will be reported as low.\nThis has to be higher than the critical threshold.", "max": 0.5, "min": 0.12, "name": "BAT_LOW_THR", "shortDesc": "Low threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Camera trigger", "longDesc": "This parameter sets the time the trigger needs to pulled high or low.", "max": 3000.0, "min": 0.1, "name": "TRIG_ACT_TIME", "rebootRequired": true, "shortDesc": "Camera trigger activation time", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "Camera trigger", "increment": 1.0, "longDesc": "Sets the distance at which to trigger the camera.", "min": 0.0, "name": "TRIG_DISTANCE", "rebootRequired": true, "shortDesc": "Camera trigger distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 4, "group": "Camera trigger", "longDesc": "Selects the trigger interface", "name": "TRIG_INTERFACE", "rebootRequired": true, "shortDesc": "Camera trigger Interface", "type": "Int32", "values": [{"description": "GPIO", "value": 1}, {"description": "Seagull MAP2 (over PWM)", "value": 2}, {"description": "MAVLink (Camera Protocol v1)", "value": 3}, {"description": "Generic PWM (IR trigger, servo)", "value": 4}]}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Camera trigger", "longDesc": "This parameter sets the time between two consecutive trigger events", "max": 10000.0, "min": 4.0, "name": "TRIG_INTERVAL", "rebootRequired": true, "shortDesc": "Camera trigger interval", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Camera trigger", "longDesc": "This parameter sets the minimum time between two consecutive trigger events\nthe specific camera setup is supporting.", "max": 10000.0, "min": 1.0, "name": "TRIG_MIN_INTERVA", "rebootRequired": true, "shortDesc": "Minimum camera trigger interval", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "Camera trigger", "max": 4, "min": 0, "name": "TRIG_MODE", "rebootRequired": true, "shortDesc": "Camera trigger mode", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Time based, on command", "value": 1}, {"description": "Time based, always on", "value": 2}, {"description": "Distance based, always on", "value": 3}, {"description": "Distance based, on command (Survey mode)", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Camera trigger", "longDesc": "This parameter sets the polarity of the trigger (0 = active low, 1 = active high )", "max": 1, "min": 0, "name": "TRIG_POLARITY", "rebootRequired": true, "shortDesc": "Camera trigger polarity", "type": "Int32", "values": [{"description": "Active low", "value": 0}, {"description": "Active high", "value": 1}]}, {"category": "Standard", "default": 1500, "group": "Camera trigger", "max": 2000, "min": 1000, "name": "TRIG_PWM_NEUTRAL", "rebootRequired": true, "shortDesc": "PWM neutral output on trigger pin", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 1900, "group": "Camera trigger", "max": 2000, "min": 1000, "name": "TRIG_PWM_SHOOT", "rebootRequired": true, "shortDesc": "PWM output to trigger shot", "type": "Int32", "units": "us"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 782097 will disable the buzzer audio notification.\nSetting this parameter to 782090 will disable the startup tune, while keeping\nall others enabled.", "max": 782097, "min": 0, "name": "CBRK_BUZZER", "rebootRequired": true, "shortDesc": "Circuit breaker for disabling buzzer", "type": "Int32"}, {"category": "Developer", "default": 121212, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 121212 will disable the flight termination action if triggered\nby the FailureDetector logic or if FMU is lost.\nThis circuit breaker does not affect the RC loss, data link loss, geofence,\nand takeoff failure detection safety logic.", "max": 121212, "min": 0, "name": "CBRK_FLIGHTTERM", "rebootRequired": true, "shortDesc": "Circuit breaker for flight termination", "type": "Int32"}, {"category": "Developer", "default": 22027, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 22027 will disable IO safety.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 22027, "min": 0, "name": "CBRK_IO_SAFETY", "shortDesc": "Circuit breaker for IO safety", "type": "Int32"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 894281 will disable the power valid\nchecks in the commander.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 894281, "min": 0, "name": "CBRK_SUPPLY_CHK", "shortDesc": "Circuit breaker for power supply check", "type": "Int32"}, {"category": "Developer", "default": 197848, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 197848 will disable the USB connected\nchecks in the commander, setting it to 0 keeps them enabled (recommended).\nWe are generally recommending to not fly with the USB link\nconnected and production vehicles should set this parameter to\nzero to prevent users from flying USB powered. However, for R&D purposes\nit has proven over the years to work just fine.", "max": 197848, "min": 0, "name": "CBRK_USB_CHK", "shortDesc": "Circuit breaker for USB link check", "type": "Int32"}, {"category": "Developer", "default": 0, "group": "Circuit Breaker", "longDesc": "Setting this parameter to 159753 will enable arming in fixed-wing\nmode for VTOLs.\nWARNING: ENABLING THIS CIRCUIT BREAKER IS AT OWN RISK", "max": 159753, "min": 0, "name": "CBRK_VTOLARMING", "shortDesc": "Circuit breaker for arming in fixed-wing mode check", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Note: actuator failure needs to be enabled and configured via FD_ACT_*\nparameters.", "max": 3, "min": 0, "name": "COM_ACT_FAIL_ACT", "shortDesc": "Set the actuator failure failsafe mode", "type": "Int32", "values": [{"description": "Warning only", "value": 0}, {"description": "Hold mode", "value": 1}, {"description": "Land mode", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Terminate", "value": 4}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Set 0 to prevent accidental use of the vehicle e.g. for safety or maintenance reasons.", "name": "COM_ARMABLE", "shortDesc": "Flag to allow arming", "type": "Int32", "values": [{"description": "Disallow arming", "value": 0}, {"description": "Allow arming", "value": 1}]}, {"category": "Standard", "default": 10, "group": "Commander", "longDesc": "Used if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_ID", "shortDesc": "Arm authorizer system id", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Methods:\n- one arm: request authorization and arm when authorization is received\n- two step arm: 1st arm command request an authorization and\n2nd arm command arm the drone if authorized\nUsed if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_MET", "shortDesc": "Arm authorization method", "type": "Int32", "values": [{"description": "one arm", "value": 0}, {"description": "two step arm", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "By default off. The default allows to arm the vehicle without a arm authorization.", "name": "COM_ARM_AUTH_REQ", "shortDesc": "Require arm authorization to arm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "increment": 0.1, "longDesc": "Timeout for authorizer answer.\nUsed if arm authorization is requested by COM_ARM_AUTH_REQ.", "name": "COM_ARM_AUTH_TO", "shortDesc": "Arm authorization timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Commander", "increment": 0.01, "longDesc": "Threshold for battery percentage below arming is prohibited.\nA negative value means BAT_CRIT_THR is the threshold.", "max": 0.9, "min": -1.0, "name": "COM_ARM_BAT_MIN", "shortDesc": "Minimum battery level for arming", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "If this parameter is set, the system will check ESC's online status and failures.\nThis param is specific for ESCs reporting status. It shall be used only if ESCs support telemetry.", "name": "COM_ARM_CHK_ESCS", "shortDesc": "Enable checks on ESCs that report telemetry", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This check detects if there are hardfault files present on the\nSD card. If so, and the parameter is enabled, arming is prevented.", "name": "COM_ARM_HFLT_CHK", "shortDesc": "Enable FMU SD card hardfault detection check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "Commander", "increment": 0.05, "max": 1.0, "min": 0.1, "name": "COM_ARM_IMU_ACC", "shortDesc": "Maximum accelerometer inconsistency between IMU units that will allow arming", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Commander", "increment": 0.01, "max": 0.3, "min": 0.02, "name": "COM_ARM_IMU_GYR", "shortDesc": "Maximum rate gyro inconsistency between IMU units that will allow arming", "type": "Float", "units": "rad/s"}, {"category": "Standard", "default": 60, "group": "Commander", "longDesc": "Set -1 to disable the check.", "max": 180, "min": 3, "name": "COM_ARM_MAG_ANG", "shortDesc": "Maximum magnetic field inconsistency between units that will allow arming", "type": "Int32", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Commander", "longDesc": "Check if the estimator detects a strong magnetic\ndisturbance (check enabled by EKF2_MAG_CHECK)", "name": "COM_ARM_MAG_STR", "shortDesc": "Enable mag strength preflight check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Deny arming", "value": 1}, {"description": "Warning only", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The default allows to arm the vehicle without a valid mission.", "name": "COM_ARM_MIS_REQ", "shortDesc": "Require valid mission to arm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "This check detects if the Open Drone ID system is missing.\nDepending on the value of the parameter, the check can be\ndisabled, warn only or deny arming.", "name": "COM_ARM_ODID", "shortDesc": "Enable Drone ID system detection and health check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warning only", "value": 1}, {"description": "Enforce Open Drone ID system presence", "value": 2}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This check detects if the FMU SD card is missing.\nDepending on the value of the parameter, the check can be\ndisabled, warn only or deny arming.", "name": "COM_ARM_SDCARD", "shortDesc": "Enable FMU SD card detection check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warning only", "value": 1}, {"description": "Enforce SD card presence", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "0: Arming/disarming triggers on switch transition.\n1: Arming/disarming triggers when holding the momentary button down like the stick gesture.", "name": "COM_ARM_SWISBTN", "shortDesc": "Arm switch is a momentary button", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Configures whether arming is allowed without GNSS, for modes that require a global position\n(specifically, in those modes when a check defined by EKF2_GPS_CHECK fails).\nThe settings deny arming and warn, allow arming and warn, or silently allow arming.", "name": "COM_ARM_WO_GPS", "shortDesc": "Arming without GNSS configuration", "type": "Int32", "values": [{"description": "Deny arming", "value": 0}, {"description": "Allow arming (with warning)", "value": 1}, {"description": "Allow arming (no warning)", "value": 2}]}, {"category": "Standard", "default": 95.0, "group": "Commander", "increment": 1.0, "longDesc": "The check fails if the CPU load is above this threshold for 2s.\nA negative value disables the check.", "max": 100.0, "min": -1.0, "name": "COM_CPU_MAX", "shortDesc": "Maximum allowed CPU load to still arm", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Commander", "increment": 0.1, "longDesc": "A non-zero, positive value specifies the time-out period in seconds after which the vehicle will be\nautomatically disarmed in case a landing situation has been detected during this period.\nA zero or negative value means that automatic disarming triggered by landing detection is disabled.", "name": "COM_DISARM_LAND", "shortDesc": "Time-out for auto disarm after landing", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "0: Disallow disarming when not landed\n1: Allow disarming in multicopter flight in modes where\nthe thrust is directly controlled by thr throttle stick\ne.g. Stabilized, Acro", "name": "COM_DISARM_MAN", "shortDesc": "Allow disarming via switch/stick/button on multicopters in manual thrust modes", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Commander", "increment": 0.1, "longDesc": "A non-zero, positive value specifies the time in seconds, within which the\nvehicle is expected to take off after arming. In case the vehicle didn't takeoff\nwithin the timeout it disarms again.\nA negative value disables autmoatic disarming triggered by a pre-takeoff timeout.", "name": "COM_DISARM_PRFLT", "shortDesc": "Time-out for auto disarm if not taking off", "type": "Float", "units": "s"}, {"bitmask": [{"description": "Mission", "index": 0}, {"description": "Auto modes", "index": 1}, {"description": "Offboard", "index": 2}, {"description": "External Mode", "index": 3}, {"description": "Altitude Cruise", "index": 4}], "category": "Standard", "default": 0, "group": "Commander", "longDesc": "Specify modes in which ground control station connection loss is ignored and no failsafe action is triggered.\nSee also COM_RCL_EXCEPT.", "max": 31, "min": 0, "name": "COM_DLL_EXCEPT", "shortDesc": "Datalink loss exceptions", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10, "group": "Commander", "increment": 1, "longDesc": "After this amount of seconds without datalink, the GCS connection lost mode triggers", "max": 300, "min": 5, "name": "COM_DL_LOSS_T", "shortDesc": "GCS connection loss time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "longDesc": "Before entering failsafe (RTL, Land, Hold), wait COM_FAIL_ACT_T seconds in Hold mode\nfor the user to realize.\nDuring that time the user can switch modes, but cannot take over control via the stick override feature (see COM_RC_OVERRIDE).\nAfterwards the configured failsafe action is triggered and the user may use stick override.\nA zero value disables the delay.", "max": 25.0, "min": 0.0, "name": "COM_FAIL_ACT_T", "shortDesc": "Delay between failsafe condition triggered and failsafe reaction", "type": "Float", "units": "s"}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This number is incremented automatically after every flight on\ndisarming in order to remember the next flight UUID.\nThe first flight is 0.", "min": 0, "name": "COM_FLIGHT_UUID", "shortDesc": "Next flight UUID", "type": "Int32", "volatile": true}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE1", "shortDesc": "Mode slot 1", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE2", "shortDesc": "Mode slot 2", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE3", "shortDesc": "Mode slot 3", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE4", "shortDesc": "Mode slot 4", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE5", "shortDesc": "Mode slot 5", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "If the main switch channel is in this range the\nselected flight mode will be applied.", "name": "COM_FLTMODE6", "shortDesc": "Mode slot 6", "type": "Int32", "values": [{"description": "Unassigned", "value": -1}, {"description": "Manual", "value": 0}, {"description": "Altitude", "value": 1}, {"description": "Position", "value": 2}, {"description": "Mission", "value": 3}, {"description": "Hold", "value": 4}, {"description": "Return", "value": 5}, {"description": "Acro", "value": 6}, {"description": "Offboard", "value": 7}, {"description": "Stabilized", "value": 8}, {"description": "Position Slow", "value": 9}, {"description": "Takeoff", "value": 10}, {"description": "Land", "value": 11}, {"description": "Follow Me", "value": 12}, {"description": "Precision Land", "value": 13}, {"description": "Altitude Cruise", "value": 16}, {"description": "External Mode 1", "value": 100}, {"description": "External Mode 2", "value": 101}, {"description": "External Mode 3", "value": 102}, {"description": "External Mode 4", "value": 103}, {"description": "External Mode 5", "value": 104}, {"description": "External Mode 6", "value": 105}, {"description": "External Mode 7", "value": 106}, {"description": "External Mode 8", "value": 107}]}, {"category": "Standard", "default": 0, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when the remaining flight time is below\nthe estimated time it takes to reach the RTL destination.", "name": "COM_FLTT_LOW_ACT", "shortDesc": "Remaining flight time low failsafe", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Return", "value": 3}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Describes the intended use of the vehicle.\nCan be used by ground control software or log post processing.\nThis param does not influence the behavior within the firmware. This means for example the control logic is independent of the setting of this param (but depends on other params).", "name": "COM_FLT_PROFILE", "shortDesc": "User Flight Profile", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Pro User", "value": 100}, {"description": "Flight Tester", "value": 200}, {"description": "Developer", "value": 300}]}, {"category": "Standard", "default": -1, "group": "Commander", "longDesc": "The vehicle aborts the current operation and returns to launch when\nthe time since takeoff is above this value. It is not possible to resume the\nmission or switch to any auto mode other than RTL or Land. Taking over in any manual\nmode is still possible.\nStarting from 90% of the maximum flight time, a warning message will be sent\nevery 1 minute with the remaining time until automatic RTL.\nSet to -1 to disable.", "min": -1, "name": "COM_FLT_TIME_MAX", "shortDesc": "Maximum allowed flight time", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Force safety when the vehicle disarms", "name": "COM_FORCE_SAFETY", "shortDesc": "Enable force safety", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 120, "group": "Commander", "longDesc": "After this amount of seconds without datalink the data link lost mode triggers", "max": 3600, "min": 60, "name": "COM_HLDL_LOSS_T", "shortDesc": "High Latency Datalink loss time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "After a data link loss: after this number of seconds with a healthy datalink the 'datalink loss'\nflag is set back to false", "max": 60, "min": 0, "name": "COM_HLDL_REG_T", "shortDesc": "High Latency Datalink regain time threshold", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "Set home position automatically if possible.\nDuring missions, the latitude/longitude of the home position is locked and will not reset during intermediate landings.\nIt will only update once the mission is complete or landed outside of a mission.\nHowever, the altitude is still being adjusted to correct for GNSS vertical drift in the first 2 minutes after takeoff.", "name": "COM_HOME_EN", "rebootRequired": true, "shortDesc": "Home position enabled", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "If set to true, the autopilot is allowed to set its home position after takeoff\nThe true home position is back-computed if a local position is estimate if available.\nIf no local position is available, home is set to the current position.", "name": "COM_HOME_IN_AIR", "shortDesc": "Allows setting the home position after takeoff", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when an imbalanced propeller is detected by the failure detector.\nSee also FD_IMB_PROP_THR to set the failure threshold.", "name": "COM_IMB_PROP_ACT", "shortDesc": "Imbalanced propeller failsafe mode", "type": "Int32", "values": [{"description": "Disabled", "value": -1}, {"description": "Warning", "value": 0}, {"description": "Return", "value": 1}, {"description": "Land", "value": 2}]}, {"category": "Standard", "default": 5.0, "group": "Commander", "increment": 0.1, "longDesc": "Use RC_MAP_KILL_SW to map a kill switch.", "max": 30.0, "min": 0.0, "name": "COM_KILL_DISARM", "shortDesc": "Timeout value for disarming when kill switch is engaged", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 3.0, "group": "Commander", "longDesc": "A non-zero, positive value specifies the timeframe in seconds within failure detector is allowed to disarm the vehicle\nif attitude exceeds the limits defined in FD_FAIL_P and FD_FAIL_R.\nThe check is not executed for flight modes that do support acrobatic maneuvers, e.g: Acro (MC/FW) and Manual (FW).\nA zero or negative value means that the check is disabled.", "max": 5.0, "min": -1.0, "name": "COM_LKDOWN_TKO", "shortDesc": "Timeout for detecting a failure after takeoff", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Action the system takes at critical battery. See also BAT_CRIT_THR and BAT_EMERGEN_THR\nfor definition of battery states.", "name": "COM_LOW_BAT_ACT", "shortDesc": "Battery failsafe mode", "type": "Int32", "values": [{"description": "Warning", "value": 0}, {"description": "Land mode", "value": 2}, {"description": "Return at critical level, land at emergency level", "value": 3}]}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE0_HASH", "shortDesc": "External mode identifier 0", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE1_HASH", "shortDesc": "External mode identifier 1", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE2_HASH", "shortDesc": "External mode identifier 2", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE3_HASH", "shortDesc": "External mode identifier 3", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE4_HASH", "shortDesc": "External mode identifier 4", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE5_HASH", "shortDesc": "External mode identifier 5", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE6_HASH", "shortDesc": "External mode identifier 6", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Commander", "longDesc": "This parameter is automatically set to identify external modes. It ensures that modes\nget assigned to the same index independent from their startup order,\nwhich is required when mapping an external mode to an RC switch.", "name": "COM_MODE7_HASH", "shortDesc": "External mode identifier 7", "type": "Int32", "volatile": true}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "By default disabled for safety reasons", "name": "COM_MODE_ARM_CHK", "shortDesc": "Allow external mode registration while armed", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "If set, enables the actuator test interface via MAVLink (ACTUATOR_TEST), that\nallows spinning the motors and moving the servos for testing purposes.", "name": "COM_MOT_TEST_EN", "shortDesc": "Enable Actuator Testing", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 5.0, "group": "Commander", "increment": 0.01, "max": 60.0, "min": 0.0, "name": "COM_OBC_LOSS_T", "shortDesc": "Time-out to wait when onboard computer connection is lost before warning about loss connection", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The offboard loss failsafe will only be entered after a timeout,\nset by COM_OF_LOSS_T in seconds.", "name": "COM_OBL_RC_ACT", "shortDesc": "Set offboard loss failsafe mode", "type": "Int32", "values": [{"description": "Position mode", "value": 0}, {"description": "Altitude mode", "value": 1}, {"description": "Stabilized", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Land mode", "value": 4}, {"description": "Hold mode", "value": 5}, {"description": "Terminate", "value": 6}, {"description": "Disarm", "value": 7}]}, {"category": "Standard", "default": 1.0, "group": "Commander", "increment": 0.01, "longDesc": "See COM_OBL_RC_ACT to configure action.", "max": 60.0, "min": 0.0, "name": "COM_OF_LOSS_T", "shortDesc": "Time-out to wait when offboard connection is lost before triggering offboard lost action", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "name": "COM_PARACHUTE", "shortDesc": "Expect and require a healthy MAVLink parachute system", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "longDesc": "This is the horizontal position error (EPH) threshold that will trigger a failsafe.\nIf the previous position error was below this threshold, there is an additional\nfactor of 2.5 applied (threshold for invalidation 2.5 times the one for validation).\nOnly used for multicopters and VTOLs in hover mode.\nIndependent from estimator positioning data timeout threshold (see EKF2_NOAID_TOUT).\nSet to -1 to disable.", "max": 400.0, "min": -1.0, "name": "COM_POS_FS_EPH", "shortDesc": "Horizontal position error threshold for hovering systems", "type": "Float", "units": "m"}, {"category": "Standard", "default": 3, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when the estimated position has an accuracy below the specified threshold.\nSee COM_POS_LOW_EPH to set the failsafe threshold.\nThe failsafe action is only executed if the vehicle is in auto mission or auto loiter mode,\notherwise it is only a warning.", "name": "COM_POS_LOW_ACT", "shortDesc": "Low position accuracy action", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold", "value": 2}, {"description": "Return", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land", "value": 5}]}, {"category": "Standard", "default": -1.0, "group": "Commander", "longDesc": "This triggers the action specified in COM_POS_LOW_ACT if the estimated position accuracy is below this threshold.\nLocal position has to be still declared valid, which requires some kind of velocity aiding or large dead-reckoning time (EKF2_NOAID_TOUT),\nand a high failsafe threshold (COM_POS_FS_EPH).\nSet to -1 to disable.", "max": 1000.0, "min": -1.0, "name": "COM_POS_LOW_EPH", "shortDesc": "Low position accuracy failsafe threshold", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Commander", "longDesc": "This configures a check to verify the expected number of 5V rail power supplies are present. By default only one is expected.\nNote: CBRK_SUPPLY_CHK disables all power checks including this one.", "max": 4, "min": 0, "name": "COM_POWER_COUNT", "shortDesc": "Required number of redundant power modules", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Condition to enter the prearmed state, an intermediate state between disarmed and armed\nin which non-throttling actuators are active.", "name": "COM_PREARM_MODE", "shortDesc": "Condition to enter prearmed mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Safety button", "value": 1}, {"description": "Always", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Commander", "name": "COM_QC_ACT", "shortDesc": "Set action after a quadchute", "type": "Int32", "values": [{"description": "Warning only", "value": -1}, {"description": "Return mode", "value": 0}, {"description": "Land mode", "value": 1}, {"description": "Hold mode", "value": 2}]}, {"category": "Standard", "default": 95.0, "group": "Commander", "increment": 1.0, "longDesc": "The check fails if the RAM usage is above this threshold.\nA negative value disables the check.", "max": 100.0, "min": -1.0, "name": "COM_RAM_MAX", "shortDesc": "Maximum allowed RAM usage to pass checks", "type": "Float", "units": "%"}, {"bitmask": [{"description": "Mission", "index": 0}, {"description": "Auto modes", "index": 1}, {"description": "Offboard", "index": 2}, {"description": "External Mode", "index": 3}, {"description": "Altitude Cruise", "index": 4}], "category": "Standard", "default": 0, "group": "Commander", "longDesc": "Specify modes in which stick input is ignored and no failsafe action is triggered.\nExternal modes requiring stick input will still failsafe.\nAuto modes are: Hold, Takeoff, Land, RTL, Descend, Follow Target, Precland, Orbit.", "max": 31, "min": 0, "name": "COM_RCL_EXCEPT", "shortDesc": "Manual control loss exceptions", "type": "Int32"}, {"category": "Standard", "default": 3, "group": "Commander", "longDesc": "Selects stick input selection behavior:\neither a traditional remote control receiver (RC) or a MAVLink joystick (MANUAL_CONTROL message)\nPriority sources are immediately switched to whenever they get valid.\n0 RC only. Requires valid RC calibration.\n1 MAVLink only. RC and related checks are disabled.\n2 Switches only if current source becomes invalid.\n3 Locks to the first valid source until reboot.\n4 Ignores all sources.\n5 RC priority, then MAVLink (lower instance before higher)\n6 MAVLink priority (lower instance before higher), then RC\n7 RC priority, then MAVLink (higher instance before lower)\n8 MAVLink priority (higher instance before lower), then RC", "max": 8, "min": 0, "name": "COM_RC_IN_MODE", "shortDesc": "Manual control input source configuration", "type": "Int32", "values": [{"description": "RC only", "value": 0}, {"description": "MAVLink only", "value": 1}, {"description": "RC or MAVLink with fallback", "value": 2}, {"description": "RC or MAVLink keep first", "value": 3}, {"description": "Disable manual control", "value": 4}, {"description": "Prio: RC > MAVL 1 > MAVL 2", "value": 5}, {"description": "Prio: MAVL 1 > MAVL 2 > RC", "value": 6}, {"description": "Prio: RC > MAVL 2 > MAVL 1", "value": 7}, {"description": "Prio: MAVL 2 > MAVL 1 > RC", "value": 8}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Commander", "increment": 0.1, "longDesc": "The time in seconds without a new setpoint from RC or Joystick, after which the connection is considered lost.\nThis must be kept short as the vehicle will use the last supplied setpoint until the timeout triggers.\nEnsure the value is not set lower than the update interval of the RC or Joystick.", "max": 35.0, "min": 0.0, "name": "COM_RC_LOSS_T", "shortDesc": "Manual control loss timeout", "type": "Float", "units": "s"}, {"bitmask": [{"description": "Enable override during auto modes (except for in critical battery reaction)", "index": 0}, {"description": "Enable override during offboard mode", "index": 1}], "category": "Standard", "default": 1, "group": "Commander", "longDesc": "When enabled, moving the sticks more than COM_RC_STICK_OV\nimmediately gives control back to the pilot by switching to Position mode and\nif position is unavailable Altitude mode.\nNote: Only has an effect on multicopters, and VTOLs in multicopter mode.", "max": 3, "min": 0, "name": "COM_RC_OVERRIDE", "shortDesc": "Enable manual control stick override", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 0, "default": 30.0, "group": "Commander", "increment": 0.05, "longDesc": "If COM_RC_OVERRIDE is enabled and the joystick input is moved more than this threshold\nthe autopilot the pilot takes over control.", "max": 80.0, "min": 5.0, "name": "COM_RC_STICK_OV", "shortDesc": "Stick override threshold", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "increment": 0.1, "longDesc": "The minimal time from arming the motors until moving the vehicle is possible is COM_SPOOLUP_TIME seconds.\nGoal:\n- Motors and propellers spool up to idle speed before getting commanded to spin faster\n- Timeout for ESCs and smart batteries to successfulyy do failure checks\ne.g. for stuck rotors before the vehicle is off the ground", "max": 30.0, "min": 0.0, "name": "COM_SPOOLUP_TIME", "shortDesc": "Enforced delay between arming and further navigation", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The mode transition after TAKEOFF has completed successfully.", "name": "COM_TAKEOFF_ACT", "shortDesc": "Action after TAKEOFF has been accepted", "type": "Int32", "values": [{"description": "Hold", "value": 0}, {"description": "Mission (if valid)", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "Allows to start the vehicle by throwing it into the air.", "name": "COM_THROW_EN", "shortDesc": "Enable throw-start", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Commander", "increment": 0.1, "longDesc": "When the throw launch is enabled, the drone will only allow motors to spin after this speed\nis exceeded before detecting the freefall. This is a safety feature to ensure the drone does\nnot turn on after accidental drop or a rapid movement before the throw.\nSet to 0 to disable.", "min": 0.0, "name": "COM_THROW_SPEED", "shortDesc": "Minimum speed for the throw start", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Commander", "longDesc": "This is the horizontal velocity error (EVH) threshold that will trigger a failsafe.\nThe default is appropriate for a multicopter. Can be increased for a fixed-wing.\nIf the previous velocity error was below this threshold, there is an additional\nfactor of 2.5 applied (threshold for invalidation 2.5 times the one for validation).", "min": 0.0, "name": "COM_VEL_FS_EVH", "shortDesc": "Horizontal velocity error threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Commander", "increment": 0.1, "longDesc": "Wind speed threshold above which an automatic failsafe action is triggered.\nFailsafe action can be specified with COM_WIND_MAX_ACT.", "min": -1.0, "name": "COM_WIND_MAX", "shortDesc": "High wind speed failsafe threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "Commander", "increment": 1, "longDesc": "Action the system takes when a wind speed above the specified threshold is detected.\nSee COM_WIND_MAX to set the failsafe threshold.\nIf enabled, it is not possible to resume the mission or switch to any auto mode other than\nRTL or Land if this threshold is exceeded. Taking over in any manual\nmode is still possible.", "name": "COM_WIND_MAX_ACT", "shortDesc": "High wind failsafe mode", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold", "value": 2}, {"description": "Return", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Commander", "increment": 0.1, "longDesc": "A warning is triggered if the currently estimated wind speed is above this value.\nWarning is sent periodically (every 1 minute).\nSet to -1 to disable.", "min": -1.0, "name": "COM_WIND_WARN", "shortDesc": "Wind speed warning threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "Commander", "longDesc": "The GCS connection loss failsafe will only be entered after a timeout,\nset by COM_DL_LOSS_T in seconds. Once the timeout occurs the selected\naction will be executed.", "max": 6, "min": 0, "name": "NAV_DLL_ACT", "shortDesc": "Set GCS connection loss failsafe mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Hold mode", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Terminate", "value": 5}, {"description": "Disarm", "value": 6}]}, {"category": "Standard", "default": 2, "group": "Commander", "longDesc": "The manual control loss failsafe will only be entered after a timeout,\nset by COM_RC_LOSS_T in seconds.", "max": 6, "min": 1, "name": "NAV_RCL_ACT", "shortDesc": "Set manual control loss failsafe mode", "type": "Int32", "values": [{"description": "Hold mode", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Terminate", "value": 5}, {"description": "Disarm", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "max": 0.5, "min": 0.0, "name": "EKF2_ABIAS_INIT", "rebootRequired": true, "shortDesc": "1-sigma IMU accelerometer switch-on bias", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "EKF2", "longDesc": "If the magnitude of the IMU accelerometer vector exceeds this value, the EKF accel bias state estimation will be inhibited. This reduces the adverse effect of high manoeuvre accelerations and IMU nonlinerity and scale factor errors on the accel bias estimates.", "max": 200.0, "min": 20.0, "name": "EKF2_ABL_ACCLIM", "shortDesc": "Maximum IMU accel magnitude that allows IMU bias learning", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "If the magnitude of the IMU angular rate vector exceeds this value, the EKF accel bias state estimation will be inhibited. This reduces the adverse effect of rapid rotation rates and associated errors on the accel bias estimates.", "max": 20.0, "min": 2.0, "name": "EKF2_ABL_GYRLIM", "shortDesc": "Maximum IMU gyro angular rate magnitude that allows IMU bias learning", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "EKF2", "longDesc": "The ekf accel bias states will be limited to within a range equivalent to +- of this value.", "max": 0.8, "min": 0.0, "name": "EKF2_ABL_LIM", "shortDesc": "Accelerometer bias learning limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "The vector magnitude of angular rate and acceleration used to check if learning should be inhibited has a peak hold filter applied to it with an exponential decay. This parameter controls the time constant of the decay.", "max": 1.0, "min": 0.1, "name": "EKF2_ABL_TAU", "shortDesc": "Accel bias learning inhibit time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.003, "group": "EKF2", "max": 0.01, "min": 0.0, "name": "EKF2_ACC_B_NOISE", "shortDesc": "Process noise for IMU accelerometer bias prediction", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.35, "group": "EKF2", "max": 1.0, "min": 0.01, "name": "EKF2_ACC_NOISE", "shortDesc": "Accelerometer noise for covariance prediction", "type": "Float", "units": "m/s^2"}, {"bitmask": [{"description": "Horizontal position", "index": 0}, {"description": "Vertical position", "index": 1}], "category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Horizontal position fusion 1 : Vertical position fusion", "max": 3, "min": 0, "name": "EKF2_AGP_CTRL", "shortDesc": "Aux global position (AGP) sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_AGP_DELAY", "rebootRequired": true, "shortDesc": "Aux global position estimator delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_AGP_GATE", "shortDesc": "Gate size for aux global position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Automatic: reset on fusion timeout if no other source of position is available Dead-reckoning: reset on fusion timeout if no source of velocity is available", "name": "EKF2_AGP_MODE", "shortDesc": "Fusion reset mode", "type": "Int32", "values": [{"description": "Automatic", "value": 0}, {"description": "Dead-reckoning", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.9, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_AGP_NOISE", "shortDesc": "Measurement noise for aux global position measurements", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "EKF2", "max": 0.5, "min": 0.0, "name": "EKF2_ANGERR_INIT", "rebootRequired": true, "shortDesc": "1-sigma tilt angle uncertainty after gravity vector alignment", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "longDesc": "Airspeed data is fused for wind estimation if above this threshold. Set to 0 to disable airspeed fusion. For reliable wind estimation both sideslip (see EKF2_FUSE_BETA) and airspeed fusion should be enabled. Only applies to fixed-wing vehicles (or VTOLs in fixed-wing mode).", "min": 0.0, "name": "EKF2_ARSP_THR", "shortDesc": "Airspeed fusion threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "max": 50.0, "min": 5.0, "name": "EKF2_ASPD_MAX", "shortDesc": "Maximum airspeed used for baro static pressure compensation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_ASP_DELAY", "rebootRequired": true, "shortDesc": "Airspeed measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_AVEL_DELAY", "rebootRequired": true, "shortDesc": "Auxiliary Velocity Estimate delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "If this parameter is enabled then the estimator will make use of the barometric height measurements to estimate its height in addition to other height sources (if activated).", "name": "EKF2_BARO_CTRL", "shortDesc": "Barometric sensor height aiding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_BARO_DELAY", "rebootRequired": true, "shortDesc": "Barometer measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_BARO_GATE", "shortDesc": "Gate size for barometric and GPS height fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.5, "group": "EKF2", "max": 15.0, "min": 0.01, "name": "EKF2_BARO_NOISE", "shortDesc": "Measurement noise for barometric altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by bluff body drag along the forward/reverse axis when flying a multi-copter which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed squared. The predicted drag from the rotors is specified separately by the EKF2_MCOEF parameter. Set this parameter to zero to turn off the bluff body drag model for this axis.", "max": 200.0, "min": 0.0, "name": "EKF2_BCOEF_X", "shortDesc": "X-axis ballistic coefficient used for multi-rotor wind estimation", "type": "Float", "units": "kg/m^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by bluff body drag along the right/left axis when flying a multi-copter, which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed squared. The predicted drag from the rotors is specified separately by the EKF2_MCOEF parameter. Set this parameter to zero to turn off the bluff body drag model for this axis.", "max": 200.0, "min": 0.0, "name": "EKF2_BCOEF_Y", "shortDesc": "Y-axis ballistic coefficient used for multi-rotor wind estimation", "type": "Float", "units": "kg/m^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_BETA_GATE", "shortDesc": "Gate size for synthetic sideslip fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 1.0, "min": 0.1, "name": "EKF2_BETA_NOISE", "shortDesc": "Noise for synthetic sideslip fusion", "type": "Float", "units": "m/s"}, {"bitmask": [{"description": "use geo_lookup declination", "index": 0}, {"description": "save EKF2_MAG_DECL on disarm", "index": 1}], "category": "Standard", "default": 3, "group": "EKF2", "longDesc": "Set bits in the following positions to enable functions. 0 : Set to true to use the declination from the geo_lookup library when the GPS position becomes available, set to false to always use the EKF2_MAG_DECL value. 1 : Set to true to save the EKF2_MAG_DECL parameter to the value returned by the EKF when the vehicle disarms.", "max": 3, "min": 0, "name": "EKF2_DECL_TYPE", "rebootRequired": true, "shortDesc": "Integer bitmask controlling handling of magnetic declination", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 200.0, "group": "EKF2", "longDesc": "Defines the delay between the current time and the delayed-time horizon. This value should be at least as large as the largest EKF2_XXX_DELAY parameter.", "max": 1000.0, "min": 0.0, "name": "EKF2_DELAY_MAX", "rebootRequired": true, "shortDesc": "Maximum delay of all the aiding sensors", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Activate wind speed estimation using specific-force measurements and a drag model defined by EKF2_BCOEF_[XY] and EKF2_MCOEF. Only use on vehicles that have their thrust aligned with the Z axis and no thrust in the XY plane.", "name": "EKF2_DRAG_CTRL", "shortDesc": "Multirotor wind estimation selection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 2.5, "group": "EKF2", "longDesc": "Used by the multi-rotor specific drag force model. Increasing this makes the multi-rotor wind estimates adjust more slowly.", "max": 10.0, "min": 0.5, "name": "EKF2_DRAG_NOISE", "shortDesc": "Specific drag force observation noise variance", "type": "Float", "units": "(m/s^2)^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.4, "group": "EKF2", "max": 5.0, "min": 0.5, "name": "EKF2_EAS_NOISE", "shortDesc": "Measurement noise for airspeed fusion", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "EKF2", "name": "EKF2_EN", "shortDesc": "EKF2 enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "When enabled, constant position fusion is enabled when the vehicle is landed and armed. This is intended for IC engine warmup (e.g., fuel engines on catapult) to allow mode transitions to auto/takeoff despite vibrations from running engines.", "name": "EKF2_ENGINE_WRM", "shortDesc": "Enable constant position fusion during engine warmup", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.05, "name": "EKF2_EVA_NOISE", "shortDesc": "Measurement noise for vision angle measurements", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_EVP_GATE", "shortDesc": "Gate size for vision position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_EVP_NOISE", "shortDesc": "Measurement noise for vision position measurements", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_EVV_GATE", "shortDesc": "Gate size for vision velocity estimate fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "longDesc": "Used to lower bound or replace the uncertainty included in the message", "min": 0.01, "name": "EKF2_EVV_NOISE", "shortDesc": "Measurement noise for vision velocity measurements", "type": "Float", "units": "m/s"}, {"bitmask": [{"description": "Horizontal position", "index": 0}, {"description": "Vertical position", "index": 1}, {"description": "3D velocity", "index": 2}, {"description": "Yaw", "index": 3}], "category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Horizontal position fusion 1 : Vertical position fusion 2 : 3D velocity fusion 3 : Yaw", "max": 15, "min": 0, "name": "EKF2_EV_CTRL", "shortDesc": "External vision (EV) sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_EV_DELAY", "rebootRequired": true, "shortDesc": "Vision Position Estimator delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "If set to 0 (default) the measurement noise is taken from the vision message and the EV noise parameters are used as a lower bound. If set to 1 the observation noise is set from the parameters directly,", "name": "EKF2_EV_NOISE_MD", "shortDesc": "External vision (EV) noise mode", "type": "Int32", "values": [{"description": "EV reported variance (parameter lower bound)", "value": 0}, {"description": "EV noise parameters", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_X", "shortDesc": "X position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_Y", "shortDesc": "Y position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_EV_POS_Z", "shortDesc": "Z position of VI sensor focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0, "group": "EKF2", "longDesc": "External vision will only be started and fused if the quality metric is above this threshold. The quality metric is a completely optional field provided by some VIO systems.", "max": 100, "min": 0, "name": "EKF2_EV_QMIN", "shortDesc": "External vision (EV) minimum quality (optional)", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "For reliable wind estimation both sideslip and airspeed fusion (see EKF2_ARSP_THR) should be enabled. Only applies to vehicles in fixed-wing mode or with airspeed fusion active. Note: side slip fusion is currently not supported for tailsitters.", "name": "EKF2_FUSE_BETA", "shortDesc": "Enable synthetic sideslip fusion", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "max": 0.2, "min": 0.0, "name": "EKF2_GBIAS_INIT", "rebootRequired": true, "shortDesc": "1-sigma IMU gyro switch-on bias", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "EKF2", "longDesc": "Sets the value of deadzone applied to negative baro innovations. Deadzone is enabled when EKF2_GND_EFF_DZ > 0.", "max": 10.0, "min": 0.0, "name": "EKF2_GND_EFF_DZ", "shortDesc": "Baro deadzone range for height fusion", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "EKF2", "longDesc": "Sets the maximum distance to the ground level where negative baro innovations are expected.", "max": 5.0, "min": 0.0, "name": "EKF2_GND_MAX_HGT", "shortDesc": "Height above ground level for ground effect zone", "type": "Float", "units": "m"}, {"bitmask": [{"description": "Sat count (EKF2_REQ_NSATS)", "index": 0}, {"description": "PDOP (EKF2_REQ_PDOP)", "index": 1}, {"description": "EPH (EKF2_REQ_EPH)", "index": 2}, {"description": "EPV (EKF2_REQ_EPV)", "index": 3}, {"description": "Speed accuracy (EKF2_REQ_SACC)", "index": 4}, {"description": "Horizontal position drift (EKF2_REQ_HDRIFT)", "index": 5}, {"description": "Vertical position drift (EKF2_REQ_VDRIFT)", "index": 6}, {"description": "Horizontal speed offset (EKF2_REQ_HDRIFT)", "index": 7}, {"description": "Vertical speed offset (EKF2_REQ_VDRIFT)", "index": 8}, {"description": "Spoofing", "index": 9}, {"description": "GPS fix type (EKF2_REQ_FIX)", "index": 10}, {"description": "Jamming", "index": 11}], "category": "Standard", "default": 2047, "group": "EKF2", "longDesc": "Each threshold value is defined by the parameter indicated next to the check. Drift and offset checks only run when the vehicle is on ground and stationary.", "max": 4095, "min": 0, "name": "EKF2_GPS_CHECK", "shortDesc": "Integer bitmask controlling GPS checks", "type": "Int32"}, {"bitmask": [{"description": "Lon/lat", "index": 0}, {"description": "Altitude", "index": 1}, {"description": "3D velocity", "index": 2}, {"description": "Dual antenna heading", "index": 3}], "category": "Standard", "default": 7, "group": "EKF2", "longDesc": "Set bits in the following positions to enable: 0 : Longitude and latitude fusion 1 : Altitude fusion 2 : 3D velocity fusion 3 : Dual antenna heading fusion", "max": 15, "min": 0, "name": "EKF2_GPS_CTRL", "shortDesc": "GNSS sensor aiding", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 110.0, "group": "EKF2", "longDesc": "GPS measurement delay relative to IMU measurement if PPS time correction is not available/enabled (PPS_CAP_ENABLE).", "max": 300.0, "min": 0.0, "name": "EKF2_GPS_DELAY", "rebootRequired": true, "shortDesc": "GPS measurement delay relative to IMU measurement", "type": "Float", "units": "ms"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Automatic: reset on fusion timeout if no other source of position is available. Dead-reckoning: reset on fusion timeout if no source of velocity is available.", "name": "EKF2_GPS_MODE", "shortDesc": "Fusion reset mode", "type": "Int32", "values": [{"description": "Automatic", "value": 0}, {"description": "Dead-reckoning", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward (roll) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_X", "shortDesc": "X position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Right (pitch) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_Y", "shortDesc": "Y position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Down (yaw) axis with origin relative to vehicle centre of gravity", "name": "EKF2_GPS_POS_Z", "shortDesc": "Z position of GPS antenna in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_GPS_P_GATE", "shortDesc": "Gate size for GNSS position fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "max": 10.0, "min": 0.01, "name": "EKF2_GPS_P_NOISE", "shortDesc": "Measurement noise for GNSS position", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_GPS_V_GATE", "shortDesc": "Gate size for GNSS velocity fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 5.0, "min": 0.01, "name": "EKF2_GPS_V_NOISE", "shortDesc": "Measurement noise for GNSS velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 360.0, "min": 0.0, "name": "EKF2_GPS_YAW_OFF", "shortDesc": "Heading/Yaw offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "EKF2", "max": 10.0, "min": 0.1, "name": "EKF2_GRAV_NOISE", "shortDesc": "Accelerometer measurement noise for gravity based observations", "type": "Float", "units": "g0"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "EKF2", "longDesc": "If no airspeed measurements are available, the EKF-GSF AHRS calculation will assume this value of true airspeed when compensating for centripetal acceleration during turns. Set to zero to disable centripetal acceleration compensation during fixed wing flight modes.", "max": 100.0, "min": 0.0, "name": "EKF2_GSF_TAS", "shortDesc": "Default value of true airspeed used in EKF-GSF AHRS calculation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "EKF2", "longDesc": "The ekf gyro bias states will be limited to within a range equivalent to +- of this value.", "max": 0.4, "min": 0.0, "name": "EKF2_GYR_B_LIM", "shortDesc": "Gyro bias learning limit", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.001, "group": "EKF2", "max": 0.01, "min": 0.0, "name": "EKF2_GYR_B_NOISE", "shortDesc": "Process noise for IMU rate gyro bias prediction", "type": "Float", "units": "rad/s^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.015, "group": "EKF2", "max": 0.1, "min": 0.0001, "name": "EKF2_GYR_NOISE", "shortDesc": "Rate gyro noise for covariance prediction", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.6, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_HDG_GATE", "shortDesc": "Gate size for heading fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "EKF2", "max": 1.0, "min": 0.01, "name": "EKF2_HEAD_NOISE", "shortDesc": "Measurement noise for magnetic heading fusion", "type": "Float", "units": "rad"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "When multiple height sources are enabled at the same time, the height estimate will always converge towards the reference height source selected by this parameter. The range sensor and vision options should only be used when for operation over a flat surface as the local NED origin will move up and down with ground level. If GPS is set as reference but altitude fusion is disabled in EKF2_GPS_CTRL, the GPS altitude is still used to initiaize the bias of the other height sensors.", "name": "EKF2_HGT_REF", "rebootRequired": true, "shortDesc": "Determines the reference source of height data used by the EKF", "type": "Int32", "values": [{"description": "Barometric pressure", "value": 0}, {"description": "GPS", "value": 1}, {"description": "Range sensor", "value": 2}, {"description": "Vision", "value": 3}]}, {"bitmask": [{"description": "Gyro Bias", "index": 0}, {"description": "Accel Bias", "index": 1}, {"description": "Gravity vector fusion", "index": 2}], "category": "Standard", "default": 7, "group": "EKF2", "max": 7, "min": 0, "name": "EKF2_IMU_CTRL", "shortDesc": "IMU control", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_X", "shortDesc": "X position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_Y", "shortDesc": "Y position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_IMU_POS_Z", "shortDesc": "Z position of IMU in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "EKF2", "name": "EKF2_LOG_VERBOSE", "shortDesc": "Verbose logging", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "The heading is assumed to be observable when the body acceleration is greater than this parameter when a global position/velocity aiding source is active.", "max": 5.0, "min": 0.0, "name": "EKF2_MAG_ACCLIM", "shortDesc": "Horizontal acceleration threshold used for heading observability check", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.0001, "group": "EKF2", "max": 0.1, "min": 0.0, "name": "EKF2_MAG_B_NOISE", "shortDesc": "Process noise for body magnetic field prediction", "type": "Float", "units": "gauss/s"}, {"bitmask": [{"description": "Strength (EKF2_MAG_CHK_STR)", "index": 0}, {"description": "Inclination (EKF2_MAG_CHK_INC)", "index": 1}, {"description": "Wait for WMM", "index": 2}], "category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Bitmask to set which check is used to decide whether the magnetometer data is valid. If GNSS data is received, the magnetic field is compared to a World Magnetic Model (WMM), otherwise an average value is used. This check is useful to reject occasional hard iron disturbance. Set bits to 1 to enable checks. Checks enabled by the following bit positions 0 : Magnetic field strength. Set tolerance using EKF2_MAG_CHK_STR 1 : Magnetic field inclination. Set tolerance using EKF2_MAG_CHK_INC 2 : Wait for GNSS to find the theoretical strength and inclination using the WMM", "max": 7, "min": 0, "name": "EKF2_MAG_CHECK", "shortDesc": "Magnetic field strength test selection", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "longDesc": "Maximum allowed deviation from the expected magnetic field inclination to pass the check.", "max": 90.0, "min": 0.0, "name": "EKF2_MAG_CHK_INC", "shortDesc": "Magnetic field inclination check tolerance", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "longDesc": "Maximum allowed deviation from the expected magnetic field strength to pass the check.", "max": 1.0, "min": 0.0, "name": "EKF2_MAG_CHK_STR", "shortDesc": "Magnetic field strength check tolerance", "type": "Float", "units": "gauss"}, {"category": "System", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "name": "EKF2_MAG_DECL", "shortDesc": "Magnetic declination", "type": "Float", "units": "deg", "volatile": true}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_MAG_DELAY", "rebootRequired": true, "shortDesc": "Magnetometer measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 6, "default": 0.001, "group": "EKF2", "max": 0.1, "min": 0.0, "name": "EKF2_MAG_E_NOISE", "shortDesc": "Process noise for earth magnetic field prediction", "type": "Float", "units": "gauss/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_MAG_GATE", "shortDesc": "Gate size for magnetometer XYZ component fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "EKF2", "max": 1.0, "min": 0.001, "name": "EKF2_MAG_NOISE", "shortDesc": "Measurement noise for magnetometer 3-axis fusion", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Integer controlling the type of magnetometer fusion used - magnetic heading or 3-component vector. The fusion of magnetometer data as a three component vector enables vehicle body fixed hard iron errors to be learned, but requires a stable earth field. If set to 'Automatic' magnetic heading fusion is used when on-ground and 3-axis magnetic field fusion in-flight. If set to 'Magnetic heading' magnetic heading fusion is used at all times. If set to 'None' the magnetometer will not be used under any circumstance. If no external source of yaw is available, it is possible to use post-takeoff horizontal movement combined with GNSS velocity measurements to align the yaw angle. If set to 'Init' the magnetometer is only used to initalize the heading.", "name": "EKF2_MAG_TYPE", "rebootRequired": true, "shortDesc": "Type of magnetometer fusion", "type": "Int32", "values": [{"description": "Automatic", "value": 0}, {"description": "Magnetic heading", "value": 1}, {"description": "None", "value": 5}, {"description": "Init", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "EKF2", "longDesc": "This parameter controls the prediction of drag produced by the propellers when flying a multi-copter, which enables estimation of wind drift when enabled by the EKF2_DRAG_CTRL parameter. The drag produced by this effect scales with speed not speed squared and is produced because some of the air velocity normal to the propeller axis of rotation is lost when passing through the rotor disc. This changes the momentum of the flow which creates a drag reaction force. When comparing un-ducted propellers of the same diameter, the effect is roughly proportional to the area of the propeller blades when viewed side on and changes with propeller selection. Momentum drag is significantly higher for ducted rotors. To account for the drag produced by the body which scales with speed squared, see documentation for the EKF2_BCOEF_X and EKF2_BCOEF_Y parameters. Set this parameter to zero to turn off the momentum drag model for both axis.", "max": 1.0, "min": 0.0, "name": "EKF2_MCOEF", "shortDesc": "Propeller momentum drag coefficient for multi-rotor wind estimation", "type": "Float", "units": "1/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.01, "group": "EKF2", "longDesc": "If the vehicle is on ground, is not moving as determined by the motion test and the range finder is returning invalid or no data, then an assumed range value of EKF2_MIN_RNG will be used by the terrain estimator so that a terrain height estimate is available at the start of flight in situations where the range finder may be inside its minimum measurements distance when on ground.", "min": 0.01, "name": "EKF2_MIN_RNG", "shortDesc": "Expected range finder reading when on ground", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Maximum number of IMUs to use for Multi-EKF. Set 0 to disable. Requires SENS_IMU_MODE 0.", "max": 4, "min": 0, "name": "EKF2_MULTI_IMU", "rebootRequired": true, "shortDesc": "Multi-EKF IMUs", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Maximum number of magnetometers to use for Multi-EKF. Set 0 to disable. Requires SENS_MAG_MODE 0.", "max": 4, "min": 0, "name": "EKF2_MULTI_MAG", "rebootRequired": true, "shortDesc": "Multi-EKF Magnetometers", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "EKF2", "max": 50.0, "min": 0.5, "name": "EKF2_NOAID_NOISE", "shortDesc": "Measurement noise for non-aiding position hold", "type": "Float", "units": "m"}, {"category": "Standard", "default": 5000000, "group": "EKF2", "longDesc": "Maximum lapsed time from last fusion of measurements that constrain velocity drift before the EKF will report the horizontal nav solution as invalid", "max": 10000000, "min": 500000, "name": "EKF2_NOAID_TOUT", "shortDesc": "Maximum inertial dead-reckoning time", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Enable optical flow fusion.", "name": "EKF2_OF_CTRL", "shortDesc": "Optical flow aiding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "EKF2", "longDesc": "Assumes measurement is timestamped at trailing edge of integration period", "max": 300.0, "min": 0.0, "name": "EKF2_OF_DELAY", "rebootRequired": true, "shortDesc": "Optical flow measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_OF_GATE", "shortDesc": "Gate size for optical flow fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Auto: use gyro from optical flow message if available, internal gyro otherwise. Internal: always use internal gyro", "name": "EKF2_OF_GYR_SRC", "shortDesc": "Optical flow angular rate compensation source", "type": "Int32", "values": [{"description": "Auto", "value": 0}, {"description": "Internal", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "longDesc": "Measurement noise for the optical flow sensor when it's reported quality metric is at the minimum", "min": 0.05, "name": "EKF2_OF_N_MAX", "shortDesc": "Optical flow maximum noise", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.15, "group": "EKF2", "longDesc": "Measurement noise for the optical flow sensor when it's reported quality metric is at the maximum", "min": 0.05, "name": "EKF2_OF_N_MIN", "shortDesc": "Optical flow minimum noise", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_X", "shortDesc": "X position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_Y", "shortDesc": "Y position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_OF_POS_Z", "shortDesc": "Z position of optical flow focal point in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "Optical Flow data will only be used in air if the sensor reports a quality metric >= EKF2_OF_QMIN", "max": 255, "min": 0, "name": "EKF2_OF_QMIN", "shortDesc": "In air optical flow minimum quality", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Optical Flow data will only be used on the ground if the sensor reports a quality metric >= EKF2_OF_QMIN_GND", "max": 255, "min": 0, "name": "EKF2_OF_QMIN_GND", "shortDesc": "On ground optical flow minimum quality", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a negative wind relative velocity along the X body axis. If the baro height estimate rises during backwards flight, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_XN", "shortDesc": "Static pressure position error coefficient for the negative X axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a positive wind relative velocity along the X body axis. If the baro height estimate rises during forward flight, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_XP", "shortDesc": "Static pressure position error coefficient for the positive X axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the negative Y (LH) body axis. If the baro height estimate rises during sideways flight to the left, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_YN", "shortDesc": "Pressure position error coefficient for the negative Y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the positive Y (RH) body axis. If the baro height estimate rises during sideways flight to the right, then this will be a negative number.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_YP", "shortDesc": "Pressure position error coefficient for the positive Y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "EKF2", "longDesc": "This is the ratio of static pressure error to dynamic pressure generated by a wind relative velocity along the Z body axis.", "max": 0.5, "min": -0.5, "name": "EKF2_PCOEF_Z", "shortDesc": "Static pressure position error coefficient for the Z axis", "type": "Float"}, {"category": "Standard", "default": 10000, "group": "EKF2", "longDesc": "EKF prediction period in microseconds. This should ideally be an integer multiple of the IMU time delta. Actual filter update will be an integer multiple of IMU update.", "max": 20000, "min": 1000, "name": "EKF2_PREDICT_US", "shortDesc": "EKF prediction period", "type": "Int32", "units": "us"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "max": 100.0, "min": 2.0, "name": "EKF2_REQ_EPH", "shortDesc": "Required EPH to use GPS", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 100.0, "min": 2.0, "name": "EKF2_REQ_EPV", "shortDesc": "Required EPV to use GPS", "type": "Float", "units": "m"}, {"category": "Standard", "default": 3, "group": "EKF2", "longDesc": "Minimum GPS fix type required for GPS usage.", "name": "EKF2_REQ_FIX", "shortDesc": "Required GPS fix", "type": "Int32", "values": [{"description": "No fix required", "value": 0}, {"description": "2D fix", "value": 2}, {"description": "3D fix", "value": 3}, {"description": "RTCM code differential", "value": 4}, {"description": "RTK float", "value": 5}, {"description": "RTK fixed", "value": 6}, {"description": "Extrapolated", "value": 8}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "EKF2", "longDesc": "Minimum continuous period without GPS failure required to mark a healthy GPS status. It can be reduced to speed up initialization, but it's recommended to keep this unchanged for a vehicle.", "min": 0.1, "name": "EKF2_REQ_GPS_H", "rebootRequired": true, "shortDesc": "Required GPS health time on startup", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "max": 1.0, "min": 0.1, "name": "EKF2_REQ_HDRIFT", "shortDesc": "Maximum horizontal drift speed to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 6, "group": "EKF2", "max": 12, "min": 4, "name": "EKF2_REQ_NSATS", "shortDesc": "Required satellite count to use GPS", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "EKF2", "max": 5.0, "min": 1.5, "name": "EKF2_REQ_PDOP", "shortDesc": "Maximum PDOP to use GPS", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "max": 5.0, "min": 0.5, "name": "EKF2_REQ_SACC", "shortDesc": "Required speed accuracy to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "EKF2", "max": 1.5, "min": 0.1, "name": "EKF2_REQ_VDRIFT", "shortDesc": "Maximum vertical drift speed to use GPS", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 5.0, "group": "EKF2", "longDesc": "If the vehicle absolute altitude exceeds this value then the estimator will not fuse range measurements to estimate its height. This only applies when conditional range aid mode is activated (EKF2_RNG_CTRL = 1).", "max": 10.0, "min": 1.0, "name": "EKF2_RNG_A_HMAX", "shortDesc": "Maximum height above ground allowed for conditional range aid mode", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "If the vehicle horizontal speed exceeds this value then the estimator will not fuse range measurements to estimate its height. This only applies when conditional range aid mode is activated (EKF2_RNG_CTRL = 1).", "max": 2.0, "min": 0.1, "name": "EKF2_RNG_A_VMAX", "shortDesc": "Maximum horizontal velocity allowed for conditional range aid mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "EKF2", "longDesc": "WARNING: Range finder measurements are less reliable and can experience unexpected errors. For these reasons, if accurate control of height relative to ground is required, it is recommended to use the MPC_ALT_MODE parameter instead, unless baro errors are severe enough to cause problems with landing and takeoff. If this parameter is enabled then the estimator will make use of the range finder measurements to estimate its height in addition to other height sources (if activated). Range sensor aiding can be enabled (i.e.: always use) or set in \"conditional\" mode. Conditional mode: This enables the range finder to be used during low speed (< EKF2_RNG_A_VMAX) and low altitude (< EKF2_RNG_A_HMAX) operation, eg takeoff and landing, where baro interference from rotor wash is excessive and can corrupt EKF state estimates. It is intended to be used where a vertical takeoff and landing is performed, and horizontal flight does not occur until above EKF2_RNG_A_HMAX.", "name": "EKF2_RNG_CTRL", "shortDesc": "Range sensor height aiding", "type": "Int32", "values": [{"description": "Disable range fusion", "value": 0}, {"description": "Enabled (conditional mode)", "value": 1}, {"description": "Enabled", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "max": 300.0, "min": 0.0, "name": "EKF2_RNG_DELAY", "rebootRequired": true, "shortDesc": "Range finder measurement delay relative to IMU measurements", "type": "Float", "units": "ms"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "EKF2", "longDesc": "Limit for fog detection. If the range finder measures a distance greater than this value, the measurement is considered to not be blocked by fog or rain. If there's a jump from larger than RNG_FOG to smaller than EKF2_RNG_FOG, the measurement may gets rejected. 0 - disabled", "max": 20.0, "min": 0.0, "name": "EKF2_RNG_FOG", "shortDesc": "Maximum distance at which the range finder could detect fog (m)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_RNG_GATE", "shortDesc": "Gate size for range finder fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "To be used, the time derivative of the distance sensor measurements projected on the vertical axis needs to be statistically consistent with the estimated vertical velocity of the drone. Decrease this value to make the filter more robust against range finder faulty data (stuck, reflections, ...). Note: tune the range finder noise parameters (EKF2_RNG_NOISE and EKF2_RNG_SFE) before tuning this gate.", "max": 5.0, "min": 0.1, "name": "EKF2_RNG_K_GATE", "shortDesc": "Gate size used for range finder kinematic consistency check", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "EKF2", "min": 0.01, "name": "EKF2_RNG_NOISE", "shortDesc": "Measurement noise for range finder fusion", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "max": 0.75, "min": -0.75, "name": "EKF2_RNG_PITCH", "shortDesc": "Range sensor pitch offset", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_X", "shortDesc": "X position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_Y", "shortDesc": "Y position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "EKF2", "longDesc": "Forward axis with origin relative to vehicle centre of gravity", "name": "EKF2_RNG_POS_Z", "shortDesc": "Z position of range finder origin in body frame", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "Minimum duration during which the reported range finder signal quality needs to be non-zero in order to be declared valid (s)", "max": 5.0, "min": 0.1, "name": "EKF2_RNG_QLTY_T", "shortDesc": "Minumum range validity period", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0.05, "group": "EKF2", "longDesc": "Specifies the increase in range finder noise with range.", "max": 0.2, "min": 0.0, "name": "EKF2_RNG_SFE", "shortDesc": "Range finder range dependent noise scaler", "type": "Float", "units": "m/m"}, {"category": "Standard", "default": 0.2, "group": "EKF2", "longDesc": "EKF2 instances have to be better than the selected by at least this amount before their relative score can be reduced.", "name": "EKF2_SEL_ERR_RED", "shortDesc": "Selector error reduce threshold", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "EKF2", "longDesc": "EKF2 selector acceleration error threshold for comparing accelerometers. Acceleration vector differences larger than this will result in accumulated velocity error.", "name": "EKF2_SEL_IMU_ACC", "shortDesc": "Selector acceleration threshold", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "default": 15.0, "group": "EKF2", "longDesc": "EKF2 selector maximum accumulated angular error threshold for comparing gyros. Accumulated angular error larger than this will result in the sensor being declared faulty.", "name": "EKF2_SEL_IMU_ANG", "shortDesc": "Selector angular threshold", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 7.0, "group": "EKF2", "longDesc": "EKF2 selector angular rate error threshold for comparing gyros. Angular rate vector differences larger than this will result in accumulated angular error.", "name": "EKF2_SEL_IMU_RAT", "shortDesc": "Selector angular rate threshold", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 2.0, "group": "EKF2", "longDesc": "EKF2 selector maximum accumulated velocity threshold for comparing accelerometers. Accumulated velocity error larger than this will result in the sensor being declared faulty.", "name": "EKF2_SEL_IMU_VEL", "shortDesc": "Selector angular threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 0, "group": "EKF2", "longDesc": "Use for vehicles where the measured body Z magnetic field is subject to strong magnetic interference. For magnetic heading fusion the magnetometer Z measurement will be replaced by a synthetic value calculated using the knowledge of the 3D magnetic field vector at the location of the drone. Therefore, this parameter will only have an effect if the global position of the drone is known. For 3D mag fusion the magnetometer Z measurement will simply be ignored instead of fusing the synthetic value.", "name": "EKF2_SYNT_MAG_Z", "shortDesc": "Enable synthetic magnetometer Z component measurement", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "longDesc": "Sets the number of standard deviations used by the innovation consistency test.", "min": 1.0, "name": "EKF2_TAS_GATE", "shortDesc": "Gate size for TAS fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "EKF2", "longDesc": "Controls how tightly the output track the EKF states", "max": 1.0, "min": 0.1, "name": "EKF2_TAU_POS", "shortDesc": "Output predictor position time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "EKF2", "max": 1.0, "name": "EKF2_TAU_VEL", "shortDesc": "Time constant of the velocity output prediction and smoothing filter", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "EKF2", "min": 0.0, "name": "EKF2_TERR_GRAD", "shortDesc": "Magnitude of terrain gradient", "type": "Float", "units": "m/m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "EKF2", "min": 0.5, "name": "EKF2_TERR_NOISE", "shortDesc": "Terrain altitude process noise", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "EKF2", "max": 299792458.0, "name": "EKF2_VEL_LIM", "shortDesc": "Velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "EKF2", "longDesc": "When unaided, the wind estimate uncertainty (1-sigma, in m/s) increases by this amount every second.", "max": 1.0, "min": 0.0, "name": "EKF2_WIND_NSD", "shortDesc": "Process noise spectral density for wind velocity prediction", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "default": 0, "group": "Events", "longDesc": "Enable/disable event task for RC Loss. When enabled, an alarm tune will be\nplayed via buzzer or ESCs, if supported. The alarm will sound after a disarm,\nif the vehicle was previously armed and only if the vehicle had RC signal at\nsome point. Particularly useful for locating crashed drones without a GPS\nsensor.", "name": "EV_TSK_RC_LOSS", "rebootRequired": true, "shortDesc": "RC Loss Alarm", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Events", "longDesc": "Enable/disable event task for displaying the vehicle status using arm-mounted\nLEDs. When enabled and if the vehicle supports it, LEDs will flash\nindicating various vehicle status changes. Currently PX4 has not implemented\nany specific status events.\n-", "name": "EV_TSK_STAT_DIS", "rebootRequired": true, "shortDesc": "Status Display", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "Applies to both directions in all manual modes with attitude stabilization but without altitude control", "max": 90.0, "min": 0.0, "name": "FW_MAN_P_MAX", "shortDesc": "Maximum manual pitch angle", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 45.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "Applies to both directions in all manual modes with attitude stabilization", "max": 90.0, "min": 0.0, "name": "FW_MAN_R_MAX", "shortDesc": "Maximum manual roll angle", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "This is the maximally added yaw rate setpoint from the yaw stick in any attitude controlled flight mode.\nIt is added to the yaw rate setpoint generated by the controller for turn coordination.", "min": 0.0, "name": "FW_MAN_YR_MAX", "shortDesc": "Maximum manually added yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "An airframe specific offset of the pitch setpoint in degrees, the value is\nadded to the pitch setpoint and should correspond to the pitch at\ntypical cruise speed of the airframe.", "max": 90.0, "min": -90.0, "name": "FW_PSP_OFF", "shortDesc": "Pitch setpoint offset (pitch at level flight)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 60.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_P_RMAX_NEG", "shortDesc": "Maximum negative / down pitch rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 60.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_P_RMAX_POS", "shortDesc": "Maximum positive / up pitch rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "longDesc": "This defines the latency between a pitch step input and the achieved setpoint\n(inverse to a P gain). Smaller systems may require smaller values.", "max": 1.0, "min": 0.2, "name": "FW_P_TC", "shortDesc": "Attitude pitch time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 70.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_R_RMAX", "shortDesc": "Maximum roll rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "longDesc": "This defines the latency between a roll step input and the achieved setpoint\n(inverse to a P gain). Smaller systems may require smaller values.", "max": 1.0, "min": 0.2, "name": "FW_R_TC", "shortDesc": "Attitude Roll Time Constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Attitude Control", "increment": 0.05, "max": 10.0, "min": 0.0, "name": "FW_WR_FF", "shortDesc": "Wheel steering rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "FW Attitude Control", "increment": 0.005, "longDesc": "This gain defines how much control response will result out of a steady\nstate error. It trims any constant error.", "max": 10.0, "min": 0.0, "name": "FW_WR_I", "shortDesc": "Wheel steering rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Attitude Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_WR_IMAX", "shortDesc": "Wheel steering rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "FW Attitude Control", "increment": 0.005, "longDesc": "This defines how much the wheel steering input will be commanded depending on the\ncurrent body angular rate error.", "max": 10.0, "min": 0.0, "name": "FW_WR_P", "shortDesc": "Wheel steering rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 0, "group": "FW Attitude Control", "longDesc": "Only enabled during automatic runway takeoff and landing.\nIn all manual modes the wheel is directly controlled with yaw stick.", "name": "FW_W_EN", "shortDesc": "Enable wheel steering controller", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Attitude Control", "increment": 0.5, "longDesc": "This limits the maximum wheel steering rate the controller will output (in degrees per\nsecond).", "max": 90.0, "min": 0.0, "name": "FW_W_RMAX", "shortDesc": "Maximum wheel steering rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 50.0, "group": "FW Attitude Control", "increment": 0.5, "max": 180.0, "min": 0.0, "name": "FW_Y_RMAX", "shortDesc": "Maximum yaw rate setpoint", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Auto Landing", "increment": 0.01, "longDesc": "Sets a fraction of full flaps during landing.\nAlso applies to flaperons if enabled in the mixer/allocation.", "max": 1.0, "min": 0.0, "name": "FW_FLAPS_LND_SCL", "shortDesc": "Flaps setting during landing", "type": "Float", "units": "norm"}, {"bitmask": [{"description": "Abort if terrain is not found (only applies to mission landings)", "index": 0}, {"description": "Abort if terrain times out (after a first successful measurement)", "index": 1}], "category": "Standard", "default": 3, "group": "FW Auto Landing", "longDesc": "Terrain estimation:\nbit 0: Abort if terrain is not found\nbit 1: Abort if terrain times out (after a first successful measurement)\nThe last estimate is always used as ground, whether the last valid measurement or the land waypoint, depending on the\nselected abort criteria, until an abort condition is entered. If FW_LND_USETER == 0, these bits are ignored.\nTODO: Extend automatic abort conditions\ne.g. glide slope tracking error (horizontal and vertical)", "max": 3, "min": 0, "name": "FW_LND_ABORT", "shortDesc": "Bit mask to set the automatic landing abort conditions", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "The calibrated airspeed setpoint during landing.\nIf set <= 0, landing airspeed = FW_AIRSPD_MIN by default.", "min": -1.0, "name": "FW_LND_AIRSPD", "shortDesc": "Landing airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Typically the desired landing slope angle when landing configuration (flaps, airspeed) is enabled.\nSet this value within the vehicle's performance limits.", "max": 45.0, "min": 1.0, "name": "FW_LND_ANG", "shortDesc": "Maximum landing slope angle", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "FW Auto Landing", "longDesc": "Allows to deploy the landing configuration (flaps, landing airspeed, etc.) already in\nthe loiter-down waypoint before the final approach.\nOtherwise is enabled only in the final approach.", "name": "FW_LND_EARLYCFG", "shortDesc": "Early landing configuration deployment", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "NOTE: max(FW_LND_FLALT, FW_LND_FL_TIME * |z-velocity|) is taken as the flare altitude", "min": 0.0, "name": "FW_LND_FLALT", "shortDesc": "Landing flare altitude (relative to landing altitude)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Maximum pitch during landing flare.", "max": 45.0, "min": 0.0, "name": "FW_LND_FL_PMAX", "shortDesc": "Flare, maximum pitch", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "FW Auto Landing", "increment": 0.5, "longDesc": "Minimum pitch during landing flare.", "max": 15.0, "min": -5.0, "name": "FW_LND_FL_PMIN", "shortDesc": "Flare, minimum pitch", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "TECS will attempt to control the aircraft to this sink rate via pitch angle (throttle killed during flare)", "max": 2.0, "min": 0.0, "name": "FW_LND_FL_SINK", "shortDesc": "Landing flare sink rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "Multiplied by the descent rate to calculate a dynamic altitude at which\nto trigger the flare.\nNOTE: max(FW_LND_FLALT, FW_LND_FL_TIME * descent rate) is taken as the flare altitude", "max": 5.0, "min": 0.1, "name": "FW_LND_FL_TIME", "shortDesc": "Landing flare time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 2, "group": "FW Auto Landing", "longDesc": "Approach angle nudging: shifts the touchdown point laterally while keeping the approach entrance point constant\nApproach path nudging: shifts the touchdown point laterally along with the entire approach path\nThis is useful for manually adjusting the landing point in real time when map or GNSS errors cause an offset from the\ndesired landing vector. Nudging is done with yaw stick, constrained to FW_LND_TD_OFF (in meters) and the direction is\nrelative to the vehicle heading (stick deflection to the right = land point moves to the right as seen by the vehicle).", "max": 2, "min": 0, "name": "FW_LND_NUDGE", "shortDesc": "Landing touchdown nudging option", "type": "Int32", "values": [{"description": "Disable nudging", "value": 0}, {"description": "Nudge approach angle", "value": 1}, {"description": "Nudge approach path", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "FW Auto Landing", "increment": 1.0, "max": 10.0, "min": 0.0, "name": "FW_LND_TD_OFF", "shortDesc": "Maximum lateral position offset for the touchdown point", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "This is the time after the start of flaring that we expect the vehicle to touch the runway.\nAt this time, a 0.5s clamp down ramp will engage, constraining the pitch setpoint to RWTO_PSP.\nIf enabled, ensure that RWTO_PSP is configured appropriately for full gear contact on ground roll.\nSet to -1.0 to disable touchdown clamping. E.g. it may not be desirable to clamp on belly landings.\nThe touchdown time will be constrained to be greater than or equal to the flare time (FW_LND_FL_TIME).", "max": 5.0, "min": -1.0, "name": "FW_LND_TD_TIME", "shortDesc": "Landing touchdown time (since flare start)", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW Auto Landing", "increment": 0.1, "longDesc": "The TECS altitude time constant (FW_T_ALT_TC) is multiplied by this value.", "max": 1.0, "min": 0.2, "name": "FW_LND_THRTC_SC", "shortDesc": "Altitude time constant factor for landing and low-height flight", "type": "Float", "units": ""}, {"category": "Standard", "default": 1, "group": "FW Auto Landing", "longDesc": "This is critical for detecting when to flare, and should be enabled if possible.\nIf enabled and no measurement is found within a given timeout, the landing waypoint altitude will be used OR the landing\nwill be aborted, depending on the criteria set in FW_LND_ABORT.\nIf disabled, FW_LND_ABORT terrain based criteria are ignored.", "max": 2, "min": 0, "name": "FW_LND_USETER", "shortDesc": "Use terrain estimation during landing", "type": "Int32", "values": [{"description": "Disable the terrain estimate", "value": 0}, {"description": "Use the terrain estimate to trigger the flare (only)", "value": 1}, {"description": "Calculate landing glide slope relative to the terrain estimate", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Auto Landing", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "FW_SPOILERS_LND", "shortDesc": "Spoiler landing setting", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Auto Takeoff", "increment": 0.01, "longDesc": "Sets a fraction of full flaps during take-off.\nAlso applies to flaperons if enabled in the mixer/allocation.", "max": 1.0, "min": 0.0, "name": "FW_FLAPS_TO_SCL", "shortDesc": "Flaps setting during take-off", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "FW Auto Takeoff", "increment": 0.05, "longDesc": "Launch is detected when acceleration in body forward direction is above FW_LAUN_AC_THLD for FW_LAUN_AC_T seconds.", "max": 5.0, "min": 0.0, "name": "FW_LAUN_AC_T", "shortDesc": "Trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW Auto Takeoff", "increment": 0.5, "longDesc": "Launch is detected when acceleration in body forward direction is above FW_LAUN_AC_THLD for FW_LAUN_AC_T seconds.", "min": 0.0, "name": "FW_LAUN_AC_THLD", "shortDesc": "Trigger acceleration threshold", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Auto Takeoff", "increment": 0.1, "longDesc": "Locks control surfaces during pre-launch (armed) and until this time since launch has passed.\nOnly affects control surfaces that have corresponding flag set, and not active for runway takeoff.\nSet to 0 to disable any surface locking after arming.", "min": 0.0, "name": "FW_LAUN_CS_LK_DY", "shortDesc": "Control surface launch delay", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "FW Auto Takeoff", "longDesc": "Enables automatic launch detection based on measured acceleration. Use for hand- or catapult-launched vehicles.\nNot compatible with runway takeoff.", "name": "FW_LAUN_DETCN_ON", "shortDesc": "Fixed-wing launch detection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Auto Takeoff", "increment": 0.5, "longDesc": "Start the motor(s) this amount of seconds after launch is detected.", "max": 10.0, "min": 0.0, "name": "FW_LAUN_MOT_DEL", "shortDesc": "Motor delay", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Auto Takeoff", "increment": 0.1, "longDesc": "The calibrated airspeed setpoint during the takeoff climbout.\nIf set <= 0, FW_AIRSPD_MIN will be set by default.", "min": -1.0, "name": "FW_TKO_AIRSPD", "shortDesc": "Takeoff Airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW Auto Takeoff", "increment": 0.5, "max": 80.0, "min": -5.0, "name": "FW_TKO_PITCH_MIN", "shortDesc": "Minimum pitch during takeoff", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 30, "group": "FW General", "longDesc": "The time the system should do open loop loiter and wait for GPS recovery\nbefore it starts descending. Set to 0 to disable. Roll angle is set to FW_GPSF_R.\nDoes only apply for fixed-wing vehicles or VTOLs with NAV_FORCE_VT set to 0.", "min": 0, "name": "FW_GPSF_LT", "shortDesc": "GPS failure loiter time", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW General", "increment": 0.5, "longDesc": "Roll angle in GPS failure loiter mode.", "max": 60.0, "min": 0.0, "name": "FW_GPSF_R", "shortDesc": "GPS failure fixed roll angle", "type": "Float", "units": "deg"}, {"bitmask": [{"description": "Alternative stick configuration (height rate on throttle stick, airspeed on pitch stick)", "index": 0}, {"description": "Enable airspeed setpoint via sticks in altitude and position flight mode", "index": 1}], "category": "Standard", "default": 2, "group": "FW General", "longDesc": "Applies in manual Position and Altitude flight modes.", "max": 3, "min": 0, "name": "FW_POS_STK_CONF", "shortDesc": "Custom stick configuration", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 30.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 80.0, "min": 0.0, "name": "FW_P_LIM_MAX", "shortDesc": "Maximum pitch angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -30.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 0.0, "min": -60.0, "name": "FW_P_LIM_MIN", "shortDesc": "Minimum pitch angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 50.0, "group": "FW General", "increment": 0.5, "longDesc": "Applies in any altitude controlled flight mode.", "max": 75.0, "min": 35.0, "name": "FW_R_LIM", "shortDesc": "Maximum roll angle setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW General", "increment": 0.01, "longDesc": "This is the minimum throttle while on the ground (\"landed\") in auto modes.", "max": 1.0, "min": 0.0, "name": "FW_THR_IDLE", "shortDesc": "Idle throttle", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW General", "increment": 0.01, "longDesc": "Applies in any altitude controlled flight mode.\nShould be set accordingly to achieve FW_T_CLMB_MAX.", "max": 1.0, "min": 0.0, "name": "FW_THR_MAX", "shortDesc": "Throttle limit max", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW General", "increment": 0.01, "longDesc": "Applies in any altitude controlled flight mode.\nUsually set to 0 but can be increased to prevent the motor from stopping when\ndescending, which can increase achievable descent rates.", "max": 1.0, "min": 0.0, "name": "FW_THR_MIN", "shortDesc": "Throttle limit min", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "FW General", "increment": 0.01, "longDesc": "In auto modes: default climb rate output by controller to achieve altitude setpoints.\nIn manual modes: maximum climb rate setpoint.", "min": 0.1, "name": "FW_T_CLMB_R_SP", "shortDesc": "Default target climbrate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "FW General", "increment": 0.01, "longDesc": "In auto modes: default sink rate output by controller to achieve altitude setpoints.\nIn manual modes: maximum sink rate setpoint.", "min": 0.1, "name": "FW_T_SINK_R_SP", "shortDesc": "Default target sinkrate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "FW General", "increment": 1.0, "longDesc": "Adjusts the amount of weighting that the pitch control\napplies to speed vs height errors.\n0 -> control height only\n2 -> control speed only (gliders)", "max": 2.0, "min": 0.0, "name": "FW_T_SPDWEIGHT", "shortDesc": "Speed <--> Altitude weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "FW General", "increment": 1.0, "longDesc": "This is used to constrain a minimum altitude below which we keep wings level to avoid wing tip strike. It's safer\nto give a slight margin here (> 0m)", "min": 0.0, "name": "FW_WING_HEIGHT", "shortDesc": "Height (AGL) of the wings when the aircraft is on the ground", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "FW General", "increment": 0.1, "longDesc": "This is used for limiting the roll setpoint near the ground. (if multiple wings, take the longest span)", "min": 0.1, "name": "FW_WING_SPAN", "shortDesc": "The aircraft's wing span (length from tip to tip)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "FW Lateral Control", "increment": 1.0, "longDesc": "Maximum change in roll angle setpoint per second.\nApplied in all Auto modes, plus manual Position & Altitude modes.", "min": 0.0, "name": "FW_PN_R_SLEW_MAX", "shortDesc": "Path navigation roll slew rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "The controller will increase the commanded airspeed to maintain\nthis minimum groundspeed to the next waypoint.", "max": 40.0, "min": 0.0, "name": "FW_GND_SPD_MIN", "shortDesc": "Minimum groundspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "Maximum slew rate for the commanded throttle", "max": 1.0, "min": 0.0, "name": "FW_THR_SLEW_MAX", "shortDesc": "Throttle max slew rate", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "min": 2.0, "name": "FW_T_ALT_TC", "shortDesc": "Altitude error time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Longitudinal Control", "longDesc": "Minimum altitude error needed to descend with max airspeed and minimal throttle.\nA negative value disables fast descend.", "min": -1.0, "name": "FW_T_F_ALT_ERR", "shortDesc": "Fast descend: minimum altitude error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "FW Longitudinal Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_T_HRATE_FF", "shortDesc": "Height rate feed forward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Longitudinal Control", "increment": 0.05, "longDesc": "Increase it to trim out speed and height offsets faster,\nwith the downside of possible overshoots and oscillations.", "max": 2.0, "min": 0.0, "name": "FW_T_I_GAIN_PIT", "shortDesc": "Integrator gain pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Longitudinal Control", "increment": 0.1, "max": 2.0, "min": 0.0, "name": "FW_T_PTCH_DAMP", "shortDesc": "Pitch damping gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "Is used to compensate for the additional drag created by turning.\nIncrease this gain if the aircraft initially loses energy in turns\nand reduce if the aircraft initially gains energy in turns.", "max": 20.0, "min": 0.0, "name": "FW_T_RLL2THR", "shortDesc": "Roll -> Throttle feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Longitudinal Control", "increment": 0.01, "max": 3.0, "min": 0.5, "name": "FW_T_SEB_R_FF", "shortDesc": "Specific total energy balance rate feedforward gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "max": 15.0, "min": 1.0, "name": "FW_T_SINK_MAX", "shortDesc": "Maximum descent rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "For the airspeed filter in TECS.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_DEV_STD", "shortDesc": "Airspeed rate measurement standard deviation", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "This is defining the noise in the airspeed rate for the constant airspeed rate model\nof the TECS airspeed filter.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_PRC_STD", "shortDesc": "Process noise standard deviation for the airspeed rate", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.07, "group": "FW Longitudinal Control", "increment": 0.1, "longDesc": "For the airspeed filter in TECS.", "max": 10.0, "min": 0.01, "name": "FW_T_SPD_STD", "shortDesc": "Airspeed measurement standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "This filter is applied to the specific total energy rate used for throttle damping.", "max": 2.0, "min": 0.0, "name": "FW_T_STE_R_TC", "shortDesc": "Specific total energy rate first order filter time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "FW Longitudinal Control", "increment": 0.5, "min": 2.0, "name": "FW_T_TAS_TC", "shortDesc": "True airspeed error time constant", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "This is the damping gain for the throttle demand loop.", "max": 1.0, "min": 0.0, "name": "FW_T_THR_DAMPING", "shortDesc": "Throttle damping factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.02, "group": "FW Longitudinal Control", "increment": 0.005, "longDesc": "Increase it to trim out speed and height offsets faster,\nwith the downside of possible overshoots and oscillations.", "max": 1.0, "min": 0.0, "name": "FW_T_THR_INTEG", "shortDesc": "Integrator gain throttle", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Longitudinal Control", "increment": 1.0, "longDesc": "Height above ground threshold below which tighter altitude\ntracking gets enabled (see FW_LND_THRTC_SC). Below this height, TECS smoothly\n(1 sec / sec) transitions the altitude tracking time constant from FW_T_ALT_TC\nto FW_LND_THRTC_SC*FW_T_ALT_TC.\n-1 to disable.", "min": -1.0, "name": "FW_T_THR_LOW_HGT", "shortDesc": "Low-height threshold for tighter altitude tracking", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 7.0, "group": "FW Longitudinal Control", "increment": 0.5, "longDesc": "This is the maximum vertical acceleration\neither up or down that the controller will use to correct speed\nor height errors.", "max": 10.0, "min": 1.0, "name": "FW_T_VERT_ACC", "shortDesc": "Maximum vertical acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Longitudinal Control", "increment": 0.01, "longDesc": "Multiplying this factor with the current absolute wind estimate gives the airspeed offset\nadded to the minimum airspeed setpoint limit. This helps to make the\nsystem more robust against disturbances (turbulence) in high wind.", "min": 0.0, "name": "FW_WIND_ARSP_SC", "shortDesc": "Wind-based airspeed scaling factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "FW NPFG Control", "increment": 0.01, "longDesc": "Damping ratio of NPFG control law.", "max": 1.0, "min": 0.1, "name": "NPFG_DAMPING", "shortDesc": "NPFG damping ratio", "type": "Float"}, {"category": "Standard", "default": 1, "group": "FW NPFG Control", "longDesc": "Avoids limit cycling from a too aggressively tuned period/damping combination.\nIf false, also disables upper bound NPFG_PERIOD_UB.", "name": "NPFG_LB_PERIOD", "shortDesc": "Enable automatic lower bound on the NPFG period", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW NPFG Control", "increment": 0.1, "longDesc": "Period of NPFG control law.", "max": 100.0, "min": 1.0, "name": "NPFG_PERIOD", "shortDesc": "NPFG period", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "FW NPFG Control", "increment": 0.1, "longDesc": "Multiplied by period for conservative minimum period bounding (when period lower\nbounding is enabled). 1.0 bounds at marginal stability.", "max": 10.0, "min": 1.0, "name": "NPFG_PERIOD_SF", "shortDesc": "Period safety factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW NPFG Control", "increment": 0.05, "longDesc": "Time constant of roll controller command / response, modeled as first order delay.\nUsed to determine lower period bound. Setting zero disables automatic period bounding.", "max": 2.0, "min": 0.0, "name": "NPFG_ROLL_TC", "shortDesc": "Roll time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.32, "group": "FW NPFG Control", "increment": 0.01, "longDesc": "Multiplied by the track error boundary to determine when the aircraft switches\nto the next waypoint and/or path segment. Should be less than 1.", "max": 1.0, "min": 0.1, "name": "NPFG_SW_DST_MLT", "shortDesc": "NPFG switch distance multiplier", "type": "Float"}, {"category": "Standard", "default": 1, "group": "FW NPFG Control", "longDesc": "Adapts period to maintain track keeping in variable winds and path curvature.", "name": "NPFG_UB_PERIOD", "shortDesc": "Enable automatic upper bound on the NPFG period", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Factor applied to the minimum and stall airspeed when flaps are fully deployed.", "max": 1.0, "min": 0.5, "name": "FW_AIRSPD_FLP_SC", "shortDesc": "Airspeed scale with full flaps", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The maximal airspeed (calibrated airspeed) the user is able to command.", "min": 0.5, "name": "FW_AIRSPD_MAX", "shortDesc": "Maximum Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The minimal airspeed (calibrated airspeed) the user is able to command.\nFurther, if the airspeed falls below this value, the TECS controller will try to\nincrease airspeed more aggressively.\nHas to be set according to the vehicle's stall speed (which should be set in FW_AIRSPD_STALL),\nwith some margin between the stall speed and minimum airspeed.\nThis value corresponds to the desired minimum speed with the default load factor (level flight, default weight),\nand is automatically adpated to the current load factor (calculated from roll setpoint and WEIGHT_GROSS/WEIGHT_BASE).", "min": 0.5, "name": "FW_AIRSPD_MIN", "shortDesc": "Minimum Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 7.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The stall airspeed (calibrated airspeed) of the vehicle.\nIt is used for airspeed sensor failure detection and for the control\nsurface scaling airspeed limits.", "min": 0.5, "name": "FW_AIRSPD_STALL", "shortDesc": "Stall Airspeed (CAS)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "FW Performance", "increment": 0.5, "longDesc": "The trim CAS (calibrated airspeed) of the vehicle. If an airspeed controller is active,\nthis is the default airspeed setpoint that the controller will try to achieve.\nThis value corresponds to the trim airspeed with the default load factor (level flight, default weight).", "min": 0.5, "name": "FW_AIRSPD_TRIM", "shortDesc": "Trim (Cruise) Airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "FW Performance", "increment": 1.0, "longDesc": "Altitude in standard atmosphere at which the vehicle in normal configuration (WEIGHT_BASE) is still able to achieve a maximum climb rate of\n0.5m/s at maximum throttle (FW_THR_MAX). Used to compensate for air density in FW_T_CLMB_MAX.\nSet negative to disable.", "min": -1.0, "name": "FW_SERVICE_CEIL", "shortDesc": "Service ceiling", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at maximum airspeed FW_AIRSPD_MAX\nSet to 0 to disable mapping of airspeed to trim throttle.", "max": 1.0, "min": 0.0, "name": "FW_THR_ASPD_MAX", "shortDesc": "Throttle at max airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at minimum airspeed FW_AIRSPD_MIN\nSet to 0 to disable mapping of airspeed to trim throttle below FW_AIRSPD_TRIM.", "max": 1.0, "min": 0.0, "name": "FW_THR_ASPD_MIN", "shortDesc": "Throttle at min airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "FW Performance", "increment": 0.01, "longDesc": "Required throttle (at sea level, standard atmosphere) for level flight at FW_AIRSPD_TRIM", "max": 1.0, "min": 0.0, "name": "FW_THR_TRIM", "shortDesc": "Trim throttle", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the maximum calibrated climb rate that the aircraft can achieve with\nthe throttle set to FW_THR_MAX and the airspeed set to the\ntrim value. For electric aircraft make sure this number can be\nachieved towards the end of flight when the battery voltage has reduced.", "min": 1.0, "name": "FW_T_CLMB_MAX", "shortDesc": "Maximum climb rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the minimum calibrated sink rate of the aircraft with the throttle\nset to THR_MIN and flown at the same airspeed as used\nto measure FW_T_CLMB_MAX.", "min": 1.0, "name": "FW_T_SINK_MIN", "shortDesc": "Minimum descent rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Performance", "increment": 0.5, "longDesc": "This is the weight of the vehicle at which it's performance limits were derived. A zero or negative value\ndisables trim throttle and minimum airspeed compensation based on weight.", "name": "WEIGHT_BASE", "shortDesc": "Vehicle base weight", "type": "Float", "units": "kg"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "FW Performance", "increment": 0.1, "longDesc": "This is the actual weight of the vehicle at any time. This value will differ from WEIGHT_BASE in case weight was added\nor removed from the base weight. Examples are the addition of payloads or larger batteries. A zero or negative value\ndisables trim throttle and minimum airspeed compensation based on weight.", "name": "WEIGHT_GROSS", "shortDesc": "Vehicle gross weight", "type": "Float", "units": "kg"}, {"category": "Standard", "default": 90.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_X_MAX", "shortDesc": "Acro body roll max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "If this parameter is set to 1, the yaw rate controller is enabled in Fixed-wing Acro mode.\nOtherwise the pilot commands directly the yaw actuator.\nIt is disabled by default because an active yaw rate controller will fight against the\nnatural turn coordination of the plane.", "name": "FW_ACRO_YAW_EN", "shortDesc": "Enable yaw rate controller in Acro", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 90.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_Y_MAX", "shortDesc": "Acro body pitch max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 45.0, "group": "FW Rate Control", "max": 720.0, "min": 10.0, "name": "FW_ACRO_Z_MAX", "shortDesc": "Acro body yaw max rate setpoint", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 1, "group": "FW Rate Control", "longDesc": "This enables a logic that automatically adjusts the output of the rate controller to take\ninto account the real torque produced by an aerodynamic control surface given\nthe current deviation from the trim airspeed (FW_AIRSPD_TRIM).\nEnable when using aerodynamic control surfaces (e.g.: plane)\nDisable when using rotor wings (e.g.: autogyro)", "name": "FW_ARSP_SCALE_EN", "shortDesc": "Enable airspeed scaling", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "This compensates for voltage drop of the battery over time by attempting to\nnormalize performance across the operating range of the battery.", "name": "FW_BAT_SCALE_EN", "shortDesc": "Enable throttle scale by battery level", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_PITCH when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_P_VMAX", "shortDesc": "Pitch trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_PITCH when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_P_VMIN", "shortDesc": "Pitch trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_ROLL when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_R_VMAX", "shortDesc": "Roll trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_ROLL when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_R_VMIN", "shortDesc": "Roll trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_YAW when airspeed is FW_AIRSPD_MAX.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_Y_VMAX", "shortDesc": "Yaw trim increment at maximum airspeed", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This increment is added to TRIM_YAW when airspeed is FW_AIRSPD_MIN.", "max": 0.5, "min": -0.5, "name": "FW_DTRIM_Y_VMIN", "shortDesc": "Yaw trim increment at minimum airspeed", "type": "Float"}, {"category": "Standard", "default": 1, "group": "FW Rate Control", "name": "FW_GC_EN", "shortDesc": "Enable rate gain compression", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "FW Rate Control", "increment": 0.01, "longDesc": "The range of the compression gain is between this parameter and 1.0", "max": 1.0, "min": 0.0, "name": "FW_GC_GAIN_MIN", "shortDesc": "Compression gain lower limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired pitch actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "min": 0.0, "name": "FW_MAN_P_SC", "shortDesc": "Manual pitch scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired roll actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "max": 1.0, "min": 0.0, "name": "FW_MAN_R_SC", "shortDesc": "Manual roll scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "Scale factor applied to the desired yaw actuator command in full manual mode. This parameter allows\nto adjust the throws of the control surfaces.", "min": 0.0, "name": "FW_MAN_Y_SC", "shortDesc": "Manual yaw scale", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "longDesc": "Pitch rate differential gain.", "max": 10.0, "min": 0.0, "name": "FW_PR_D", "shortDesc": "Pitch rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output", "max": 10.0, "min": 0.0, "name": "FW_PR_FF", "shortDesc": "Pitch rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_PR_I", "shortDesc": "Pitch rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_PR_IMAX", "shortDesc": "Pitch rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.08, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_PR_P", "shortDesc": "Pitch rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "FW Rate Control", "increment": 0.01, "longDesc": "This gain can be used to counteract the \"adverse yaw\" effect for fixed wings.\nWhen the plane enters a roll it will tend to yaw the nose out of the turn.\nThis gain enables the use of a yaw actuator to counteract this effect.", "min": 0.0, "name": "FW_RLL_TO_YAW_FF", "shortDesc": "Roll control to yaw control feedforward gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_RR_D", "shortDesc": "Roll rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output.", "max": 10.0, "min": 0.0, "name": "FW_RR_FF", "shortDesc": "Roll rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "FW Rate Control", "increment": 0.01, "max": 10.0, "min": 0.0, "name": "FW_RR_I", "shortDesc": "Roll rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_RR_IMAX", "shortDesc": "Roll integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_RR_P", "shortDesc": "Roll rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 0, "group": "FW Rate Control", "longDesc": "Chose source for manual setting of spoilers in manual flight modes.", "name": "FW_SPOILERS_MAN", "shortDesc": "Spoiler input in manual flight", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Flaps channel", "value": 1}, {"description": "Aux1", "value": 2}]}, {"category": "Standard", "default": 1, "group": "FW Rate Control", "longDesc": "If set to 1, the airspeed measurement data, if valid, is used in the following controllers:\n- Rate controller: output scaling\n- Attitude controller: coordinated turn controller\n- Position controller: airspeed setpoint tracking, takeoff logic\n- VTOL: transition logic", "name": "FW_USE_AIRSPD", "shortDesc": "Use airspeed for control", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_YR_D", "shortDesc": "Yaw rate derivative gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "FW Rate Control", "increment": 0.05, "longDesc": "Direct feed forward from rate setpoint to control surface output", "max": 10.0, "min": 0.0, "name": "FW_YR_FF", "shortDesc": "Yaw rate feed forward", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.1, "group": "FW Rate Control", "increment": 0.5, "max": 10.0, "min": 0.0, "name": "FW_YR_I", "shortDesc": "Yaw rate integrator gain", "type": "Float", "units": "%/rad"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "FW Rate Control", "increment": 0.05, "max": 1.0, "min": 0.0, "name": "FW_YR_IMAX", "shortDesc": "Yaw rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "FW Rate Control", "increment": 0.005, "max": 10.0, "min": 0.0, "name": "FW_YR_P", "shortDesc": "Yaw rate proportional gain", "type": "Float", "units": "%/rad/s"}, {"category": "Standard", "default": 0, "group": "Failure Detector", "longDesc": "If enabled, failure detector will verify that for motors, a minimum amount of ESC current per throttle\nlevel is being consumed.\nOtherwise this indicates an motor failure.", "name": "FD_ACT_EN", "rebootRequired": true, "shortDesc": "Enable Actuator Failure check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Failure Detector", "increment": 1.0, "longDesc": "threshold = FD_ACT_MOT_C2T * thrust + FD_ACT_HIGH_OFF", "max": 30.0, "min": 0.0, "name": "FD_ACT_HIGH_OFF", "shortDesc": "Overcurrent motor failure limit offset", "type": "Float", "units": "A"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Failure Detector", "increment": 1.0, "longDesc": "threshold = FD_ACT_MOT_C2T * thrust - FD_ACT_LOW_OFF", "max": 30.0, "min": 0.0, "name": "FD_ACT_LOW_OFF", "shortDesc": "Undercurrent motor failure limit offset", "type": "Float", "units": "A"}, {"category": "Standard", "decimalPlaces": 2, "default": 35.0, "group": "Failure Detector", "increment": 1.0, "longDesc": "Determines the slope between expected steady state current and linearized, normalized thrust command.\nE.g. FD_ACT_MOT_C2T A represents the expected steady state current at 100%.\nFD_ACT_LOW_OFF and FD_ACT_HIGH_OFF offset the threshold from that slope.", "max": 50.0, "min": 0.0, "name": "FD_ACT_MOT_C2T", "shortDesc": "Motor Failure Current/Throttle Scale", "type": "Float", "units": "A/%"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Failure Detector", "increment": 0.01, "longDesc": "Failure detection per motor only triggers above this thrust value.\nSet to 1 to disable the detection.", "max": 1.0, "min": 0.0, "name": "FD_ACT_MOT_THR", "shortDesc": "Motor Failure Thrust Threshold", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 1000, "group": "Failure Detector", "increment": 100, "longDesc": "Motor failure only triggers after current thresholds are exceeded for this time.", "max": 10000, "min": 10, "name": "FD_ACT_MOT_TOUT", "shortDesc": "Motor Failure Hysteresis Time", "type": "Int32", "units": "ms"}, {"category": "Standard", "default": 1, "group": "Failure Detector", "longDesc": "If enabled, failure detector will verify that all the ESCs have successfully armed when the vehicle has transitioned to the armed state.\nTimeout for receiving an acknowledgement from the ESCs is 0.3s, if no feedback is received the failure detector will auto disarm the vehicle.", "name": "FD_ESCS_EN", "shortDesc": "Enable checks on ESCs that report their arming state", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Failure Detector", "longDesc": "Enabled on either AUX5 or MAIN5 depending on board.\nExternal ATS is required by ASTM F3322-18.", "name": "FD_EXT_ATS_EN", "rebootRequired": true, "shortDesc": "Enable PWM input on for engaging failsafe from an external automatic trigger system (ATS)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1900, "group": "Failure Detector", "longDesc": "External ATS is required by ASTM F3322-18.", "name": "FD_EXT_ATS_TRIG", "shortDesc": "The PWM threshold from external automatic trigger system for engaging failsafe", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 60, "group": "Failure Detector", "longDesc": "Maximum pitch angle before FailureDetector triggers the attitude_failure flag.\nThe flag triggers flight termination (if @CBRK_FLIGHTTERM = 0),\nwhich sets outputs to their failsafe values.\nOn takeoff the flag triggers lockdown (irrespective of @CBRK_FLIGHTTERM),\nwhich disarms motors but does not set outputs to failsafe values.\nSetting this parameter to 0 disables the check", "max": 180, "min": 0, "name": "FD_FAIL_P", "shortDesc": "FailureDetector Max Pitch", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Failure Detector", "longDesc": "Seconds (decimal) that pitch has to exceed FD_FAIL_P before being considered as a failure.", "max": 5.0, "min": 0.02, "name": "FD_FAIL_P_TTRI", "shortDesc": "Pitch failure trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 60, "group": "Failure Detector", "longDesc": "Maximum roll angle before FailureDetector triggers the attitude_failure flag.\nThe flag triggers flight termination (if @CBRK_FLIGHTTERM = 0),\nwhich sets outputs to their failsafe values.\nOn takeoff the flag triggers lockdown (irrespective of @CBRK_FLIGHTTERM),\nwhich disarms motors but does not set outputs to failsafe values.\nSetting this parameter to 0 disables the check", "max": 180, "min": 0, "name": "FD_FAIL_R", "shortDesc": "FailureDetector Max Roll", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Failure Detector", "longDesc": "Seconds (decimal) that roll has to exceed FD_FAIL_R before being considered as a failure.", "max": 5.0, "min": 0.02, "name": "FD_FAIL_R_TTRI", "shortDesc": "Roll failure trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 30, "group": "Failure Detector", "increment": 1, "longDesc": "Value at which the imbalanced propeller metric (based on horizontal and\nvertical acceleration variance) triggers a failure\nSetting this value to 0 disables the feature.", "max": 1000, "min": 0, "name": "FD_IMB_PROP_THR", "shortDesc": "Imbalanced propeller check threshold", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 1000.0, "group": "Flight Task Orbit", "increment": 0.5, "max": 10000.0, "min": 1.0, "name": "MC_ORBIT_RAD_MAX", "shortDesc": "Maximum radius of orbit", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Flight Task Orbit", "name": "MC_ORBIT_YAW_MOD", "shortDesc": "Yaw behaviour during orbit flight", "type": "Int32", "values": [{"description": "Front to Circle Center", "value": 0}, {"description": "Hold Initial Heading", "value": 1}, {"description": "Uncontrolled", "value": 2}, {"description": "Hold Front Tangent to Circle", "value": 3}, {"description": "Manually (yaw stick) Controlled", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Follow target", "longDesc": "Maintain altitude or track target's altitude. When maintaining the altitude,\nthe drone can crash into terrain when the target moves uphill. When tracking\nthe target's altitude, the follow altitude FLW_TGT_HT should be high enough\nto prevent terrain collisions due to GPS inaccuracies of the target.", "name": "FLW_TGT_ALT_M", "shortDesc": "Altitude control mode", "type": "Int32", "values": [{"description": "2D Tracking: Maintain constant altitude relative to home and track XY position only", "value": 0}, {"description": "2D + Terrain: Maintain constant altitude relative to terrain below and track XY position", "value": 1}, {"description": "3D Tracking: Track target's altitude (be aware that GPS altitude bias usually makes this useless)", "value": 2}]}, {"category": "Standard", "default": 8.0, "group": "Follow target", "longDesc": "The distance in meters to follow the target at", "min": 1.0, "name": "FLW_TGT_DST", "shortDesc": "Distance to follow target from", "type": "Float", "units": "m"}, {"category": "Standard", "default": 180.0, "group": "Follow target", "longDesc": "Angle to follow the target from. 0.0 Equals straight in front of the target's\ncourse (direction of motion) and the angle increases in clockwise direction,\nmeaning Right-side would be 90.0 degrees while Left-side is -90.0 degrees\nNote: When the user force sets the angle out of the min/max range, it will be\nwrapped (e.g. 480 -> 120) in the range to gracefully handle the out of range.", "max": 180.0, "min": -180.0, "name": "FLW_TGT_FA", "shortDesc": "Follow Angle setting in degrees", "type": "Float"}, {"category": "Standard", "default": 8.0, "group": "Follow target", "longDesc": "Following height above the target", "min": 8.0, "name": "FLW_TGT_HT", "shortDesc": "Follow target height", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Follow target", "longDesc": "This is the maximum tangential velocity the drone will circle around the target whenever\nan orbit angle setpoint changes. Higher value means more aggressive follow behavior.", "max": 20.0, "min": 0.0, "name": "FLW_TGT_MAX_VEL", "shortDesc": "Maximum tangential velocity setting for generating the follow orbit trajectory", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Follow target", "longDesc": "lower values increase the responsiveness to changing position, but also ignore less noise", "max": 1.0, "min": 0.0, "name": "FLW_TGT_RS", "shortDesc": "Responsiveness to target movement in Target Estimator", "type": "Float"}, {"bitmask": [{"description": "GPS (with QZSS)", "index": 0}, {"description": "SBAS", "index": 1}, {"description": "Galileo", "index": 2}, {"description": "BeiDou", "index": 3}, {"description": "GLONASS", "index": 4}, {"description": "NAVIC", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "longDesc": "This integer bitmask controls the set of GNSS systems used by the receiver. Check your\nreceiver's documentation on how many systems are supported to be used in parallel.\nCurrently this functionality is just implemented for u-blox receivers.\nWhen no bits are set, the receiver's default configuration should be used.\nSet bits true to enable:\n0 : Use GPS (with QZSS)\n1 : Use SBAS (multiple GPS augmentation systems)\n2 : Use Galileo\n3 : Use BeiDou\n4 : Use GLONASS\n5 : Use NAVIC", "max": 63, "min": 0, "name": "GPS_1_GNSS", "rebootRequired": true, "shortDesc": "GNSS Systems for Primary GPS (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "GPS", "longDesc": "Select the GPS protocol over serial.\nAuto-detection will probe all protocols, and thus is a bit slower.", "max": 7, "min": 0, "name": "GPS_1_PROTOCOL", "rebootRequired": true, "shortDesc": "Protocol for Main GPS", "type": "Int32", "values": [{"description": "Auto detect", "value": 0}, {"description": "u-blox", "value": 1}, {"description": "MTK", "value": 2}, {"description": "Ashtech / Trimble", "value": 3}, {"description": "Emlid Reach", "value": 4}, {"description": "Femtomes", "value": 5}, {"description": "NMEA (generic)", "value": 6}]}, {"bitmask": [{"description": "GPS (with QZSS)", "index": 0}, {"description": "SBAS", "index": 1}, {"description": "Galileo", "index": 2}, {"description": "BeiDou", "index": 3}, {"description": "GLONASS", "index": 4}, {"description": "NAVIC", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "longDesc": "This integer bitmask controls the set of GNSS systems used by the receiver. Check your\nreceiver's documentation on how many systems are supported to be used in parallel.\nCurrently this functionality is just implemented for u-blox receivers.\nWhen no bits are set, the receiver's default configuration should be used.\nSet bits true to enable:\n0 : Use GPS (with QZSS)\n1 : Use SBAS (multiple GPS augmentation systems)\n2 : Use Galileo\n3 : Use BeiDou\n4 : Use GLONASS\n5 : Use NAVIC", "max": 63, "min": 0, "name": "GPS_2_GNSS", "rebootRequired": true, "shortDesc": "GNSS Systems for Secondary GPS (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "GPS", "longDesc": "Select the GPS protocol over serial.\nAuto-detection will probe all protocols, and thus is a bit slower.", "max": 6, "min": 0, "name": "GPS_2_PROTOCOL", "rebootRequired": true, "shortDesc": "Protocol for Secondary GPS", "type": "Int32", "values": [{"description": "Auto detect", "value": 0}, {"description": "u-blox", "value": 1}, {"description": "MTK", "value": 2}, {"description": "Ashtech / Trimble", "value": 3}, {"description": "Emlid Reach", "value": 4}, {"description": "Femtomes", "value": 5}, {"description": "NMEA (generic)", "value": 6}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Some UBX modules have a FLASH that allows to store persistent configuration that will be loaded on start.\nPX4 does override all configuration parameters it needs in RAM, which takes precedence over the values in FLASH.\nHowever, configuration parameters that are not overriden by PX4 can still cause unexpected problems during flight.\nTo avoid these kind of problems a clean config can be reached by wiping the FLASH on boot.\nNote: Currently only supported on UBX.", "name": "GPS_CFG_WIPE", "rebootRequired": true, "shortDesc": "Wipes the flash config of UBX modules", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "If this is set to 1, all GPS communication data will be published via uORB,\nand written to the log file as gps_dump message.\nIf this is set to 2, the main GPS is configured to output RTCM data,\nwhich is then logged as gps_dump and can be used for PPK.", "max": 2, "min": 0, "name": "GPS_DUMP_COMM", "shortDesc": "Log GPS communication data", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Full communication", "value": 1}, {"description": "RTCM output (PPK)", "value": 2}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Enable publication of satellite info (ORB_ID(satellite_info)) if possible.\nNot available on MTK.", "name": "GPS_SAT_INFO", "rebootRequired": true, "shortDesc": "Enable sat info (if available)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 230400, "group": "GPS", "longDesc": "Select a baudrate for the F9P's UART2 port.\nIn GPS_UBX_MODE 1, 2, and 3, the F9P's UART2 port is configured to send/receive RTCM corrections.\nSet this to 57600 if you want to attach a telemetry radio on UART2.", "min": 0, "name": "GPS_UBX_BAUD2", "rebootRequired": true, "shortDesc": "u-blox F9P UART2 Baudrate", "type": "Int32", "units": "B/s"}, {"bitmask": [{"description": "Enable I2C input protocol UBX", "index": 0}, {"description": "Enable I2C input protocol NMEA", "index": 1}, {"description": "Enable I2C input protocol RTCM3X", "index": 2}, {"description": "Enable I2C output protocol UBX", "index": 3}, {"description": "Enable I2C output protocol NMEA", "index": 4}, {"description": "Enable I2C output protocol RTCM3X", "index": 5}], "category": "Standard", "default": 0, "group": "GPS", "max": 32, "min": 0, "name": "GPS_UBX_CFG_INTF", "rebootRequired": true, "shortDesc": "u-blox protocol configuration for interfaces", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "When set to 0 (default), default DGNSS timeout set by u-blox will be used.", "max": 255, "min": 0, "name": "GPS_UBX_DGNSS_TO", "rebootRequired": true, "shortDesc": "u-blox GPS DGNSS timeout", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 7, "group": "GPS", "longDesc": "u-blox receivers support different dynamic platform models to adjust the navigation engine to\nthe expected application environment.", "max": 9, "min": 0, "name": "GPS_UBX_DYNMODEL", "rebootRequired": true, "shortDesc": "u-blox GPS dynamic platform model", "type": "Int32", "values": [{"description": "stationary", "value": 2}, {"description": "automotive", "value": 4}, {"description": "airborne with <1g acceleration", "value": 6}, {"description": "airborne with <2g acceleration", "value": 7}, {"description": "airborne with <4g acceleration", "value": 8}]}, {"category": "Standard", "default": 1, "group": "GPS", "longDesc": "Enables or disables the high sensitivity mode for the u-blox jamming detection\n(CFG-SEC-JAMDET_SENSITIVITY_HI). When enabled, the receiver uses a\nmore sensitive algorithm to detect jamming. Disabling this may reduce false\npositives in electrically noisy environments.", "name": "GPS_UBX_JAM_DET", "rebootRequired": true, "shortDesc": "u-blox GPS jamming detection high sensitivity mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "When set to 0 (default), default minimum satellite signal level set by u-blox wll be used.", "max": 255, "min": 0, "name": "GPS_UBX_MIN_CNO", "rebootRequired": true, "shortDesc": "u-blox GPS minimum satellite signal level for navigation", "type": "Int32", "units": "dBHz"}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "When set to 0 (default), default minimum elevation set by u-blox will be used.", "max": 127, "min": 0, "name": "GPS_UBX_MIN_ELEV", "rebootRequired": true, "shortDesc": "u-blox GPS minimum elevation for a GNSS satellite to be used in navigation", "type": "Int32", "units": "deg"}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Select the u-blox configuration setup. Most setups will use the default, including RTK and\ndual GPS without heading.\nIf rover has RTCM corrections from a static base (or other static correction source) coming in on UART2, then select Mode 5.\nThe Heading mode requires 2 F9P devices to be attached. The main GPS will act as rover and output\nheading information, whereas the secondary will act as moving base.\nModes 1 and 2 require each F9P UART1 to be connected to the Autopilot. In addition, UART2 on the\nF9P units are connected to each other.\nModes 3 and 4 only require UART1 on each F9P connected to the Autopilot or Can Node. UART RX DMA is required.\nRTK is still possible with this setup.\nMode 6 is intended for use with a ground control station (not necessarily an RTK correction base).", "max": 1, "min": 0, "name": "GPS_UBX_MODE", "rebootRequired": true, "shortDesc": "u-blox GPS Mode", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Heading (Rover With Moving Base UART1 Connected To Autopilot, UART2 Connected To Moving Base)", "value": 1}, {"description": "Moving Base (UART1 Connected To Autopilot, UART2 Connected To Rover)", "value": 2}, {"description": "Heading (Rover With Moving Base UART1 Connected to Autopilot Or Can Node At 921600)", "value": 3}, {"description": "Moving Base (Moving Base UART1 Connected to Autopilot Or Can Node At 921600)", "value": 4}, {"description": "Rover with Static Base on UART2 (similar to Default, except coming in on UART2)", "value": 5}, {"description": "Ground Control Station (UART2 outputs NMEA)", "value": 6}]}, {"category": "Standard", "default": 0, "group": "GPS", "name": "GPS_UBX_PPK", "rebootRequired": true, "shortDesc": "Enable MSM7 message output for PPK workflow", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "GPS", "longDesc": "Configure the output rate of u-blox GPS receivers (protocol v27+).\nWhen set to 0, automatic rate selection is used based on the receiver model.\nDefault rates: M9N=8Hz, F9P L1L2=5Hz, F9P L1L5=5Hz, Others=10Hz.\nNote: Higher rates reduce satellite count (e.g., >8Hz limits to 16 SVs on M9N).\nMax rates vary by model and RTK mode: F9P L1L2=5-7Hz, F9P L1L5=7-8Hz, X20=25Hz.\nHigh rates at 115200 baud may cause dropouts.", "max": 25, "min": 0, "name": "GPS_UBX_RATE", "rebootRequired": true, "shortDesc": "u-blox GPS output rate", "type": "Int32", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "GPS", "longDesc": "Heading offset angle for dual antenna GPS setups that support heading estimation.\nSet this to 0 if the antennas are parallel to the forward-facing direction\nof the vehicle and the rover (or Unicore primary) antenna is in front.\nThe offset angle increases clockwise.\nSet this to 90 if the rover (or Unicore primary, or Septentrio Mosaic Aux)\nantenna is placed on the right side of the vehicle and the moving base\nantenna is on the left side.\n(Note: the Unicore primary antenna is the one connected on the right as seen\nfrom the top).", "max": 360.0, "min": 0.0, "name": "GPS_YAW_OFFSET", "rebootRequired": true, "shortDesc": "Heading/Yaw offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Geofence", "longDesc": "Note: Setting this value to 4 enables flight termination,\nwhich will kill the vehicle on violation of the fence.", "max": 5, "min": 0, "name": "GF_ACTION", "shortDesc": "Geofence violation action", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Warning", "value": 1}, {"description": "Hold mode", "value": 2}, {"description": "Return mode", "value": 3}, {"description": "Terminate", "value": 4}, {"description": "Land mode", "value": 5}]}, {"category": "Standard", "default": 0.0, "group": "Geofence", "increment": 1.0, "longDesc": "Maximum horizontal distance in meters the vehicle can be from Home before triggering a geofence action.\nDisabled if 0.", "max": 10000.0, "min": 0.0, "name": "GF_MAX_HOR_DIST", "shortDesc": "Max horizontal distance from Home", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0.0, "group": "Geofence", "increment": 1.0, "longDesc": "Maximum vertical distance in meters the vehicle can be from Home before triggering a geofence action.\nDisabled if 0.", "max": 10000.0, "min": 0.0, "name": "GF_MAX_VER_DIST", "shortDesc": "Max vertical distance from Home", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geofence", "longDesc": "WARNING: This experimental feature may cause flyaways. Use at your own risk.\nPredict the motion of the vehicle and trigger the breach if it is determined that the current trajectory\nwould result in a breach happening before the vehicle can make evasive maneuvers.\nThe vehicle is then re-routed to a safe hold position (stop for multirotor, loiter for fixed wing).", "name": "GF_PREDICT", "shortDesc": "[EXPERIMENTAL] Use Pre-emptive geofence triggering", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Geofence", "longDesc": "Select which position source should be used. Selecting GPS instead of global position makes sure that there is\nno dependence on the position estimator\n0 = global position, 1 = GPS", "max": 1, "min": 0, "name": "GF_SOURCE", "shortDesc": "Geofence source", "type": "Int32", "values": [{"description": "GPOS", "value": 0}, {"description": "GPS", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines which mixer implementation to use.\nSome are generic, while others are specifically fit to a certain vehicle with a fixed set of actuators.\n'Custom' should only be used if noting else can be used.", "name": "CA_AIRFRAME", "shortDesc": "Airframe selection", "type": "Int32", "values": [{"description": "Multirotor", "value": 0}, {"description": "Fixed-wing", "value": 1}, {"description": "Standard VTOL", "value": 2}, {"description": "Tiltrotor VTOL", "value": 3}, {"description": "Tailsitter VTOL", "value": 4}, {"description": "Rover (Ackermann)", "value": 5}, {"description": "Rover (Differential)", "value": 6}, {"description": "Motors (6DOF)", "value": 7}, {"description": "Multirotor with Tilt", "value": 8}, {"description": "Custom", "value": 9}, {"description": "Helicopter (tail ESC)", "value": 10}, {"description": "Helicopter (tail Servo)", "value": 11}, {"description": "Helicopter (Coaxial)", "value": 12}, {"description": "Rover (Mecanum)", "value": 13}, {"description": "Spacecraft 2D", "value": 14}, {"description": "Spacecraft 3D", "value": 15}]}, {"bitmask": [{"description": "Control Surface 1", "index": 0}, {"description": "Control Surface 2", "index": 1}, {"description": "Control Surface 3", "index": 2}, {"description": "Control Surface 4", "index": 3}, {"description": "Control Surface 5", "index": 4}, {"description": "Control Surface 6", "index": 5}, {"description": "Control Surface 7", "index": 6}, {"description": "Control Surface 8", "index": 7}], "category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If actuator launch lock is enabled, this surface is kept at the disarmed value.", "max": 255, "min": 0, "name": "CA_CS_LAUN_LK", "shortDesc": "Control surface launch lock enabled", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "This is used to specify how to handle motor failures\nreported by failure detector.", "name": "CA_FAILURE_MODE", "shortDesc": "Motor failure handling mode", "type": "Int32", "values": [{"description": "Ignore", "value": 0}, {"description": "Remove first failed motor from effectiveness", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": -0.05, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 0 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C0", "shortDesc": "Collective pitch curve at position 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0725, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 1 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C1", "shortDesc": "Collective pitch curve at position 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 2 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C2", "shortDesc": "Collective pitch curve at position 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.325, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 3 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C3", "shortDesc": "Collective pitch curve at position 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.45, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the collective pitch at the interval position 4 for a given thrust setpoint.\nUse negative values if the swash plate needs to move down to provide upwards thrust.", "max": 1.0, "min": -1.0, "name": "CA_HELI_PITCH_C4", "shortDesc": "Collective pitch curve at position 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Same definition as the proportional gain but for integral.", "max": 10.0, "min": 0.0, "name": "CA_HELI_RPM_I", "shortDesc": "Integral gain for rpm control", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Ratio between rpm error devided by 1000 to how much normalized output gets added to correct for it.\nmotor_command = throttle_curve + CA_HELI_RPM_P * (rpm_setpoint - rpm_measurement) / 1000", "max": 10.0, "min": 0.0, "name": "CA_HELI_RPM_P", "shortDesc": "Proportional gain for rpm control", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": 1500.0, "group": "Geometry", "increment": 1.0, "longDesc": "Requires rpm feedback for the controller.", "max": 10000.0, "min": 100.0, "name": "CA_HELI_RPM_SP", "shortDesc": "Setpoint for main rotor rpm", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 0.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C0", "shortDesc": "Throttle curve at position 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 1.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C1", "shortDesc": "Throttle curve at position 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 2.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C2", "shortDesc": "Throttle curve at position 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 3.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C3", "shortDesc": "Throttle curve at position 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Defines the output throttle at the interval position 4.", "max": 1.0, "min": 0.0, "name": "CA_HELI_THR_C4", "shortDesc": "Throttle curve at position 4", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Default configuration is for a clockwise turning main rotor and\npositive thrust of the tail rotor is expected to rotate the vehicle clockwise.\nSet this parameter to true if the tail rotor provides thrust in counter-clockwise direction\nwhich is mostly the case when the main rotor turns counter-clockwise.", "name": "CA_HELI_YAW_CCW", "shortDesc": "Main rotor turns counter-clockwise", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to specify which collective pitch command results in the least amount of rotor drag.\nThis is used to increase the accuracy of the yaw drag torque compensation based on collective pitch\nby aligning the lowest rotor drag with zero compensation.\nFor symmetric profile blades this is the command that results in exactly 0\u00b0 collective blade angle.\nFor lift profile blades this is typically a command resulting in slightly negative collective blade angle.\ntail_output += CA_HELI_YAW_CP_S * abs(collective_pitch - CA_HELI_YAW_CP_O)", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_CP_O", "shortDesc": "Offset for yaw compensation based on collective pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to add a proportional factor of the collective pitch command to the yaw command.\nA negative value is needed when positive thrust of the tail rotor rotates the vehicle opposite to the main rotor turn direction.\ntail_output += CA_HELI_YAW_CP_S * abs(collective_pitch - CA_HELI_YAW_CP_O)", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_CP_S", "shortDesc": "Scale for yaw compensation based on collective pitch", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "This allows to add a proportional factor of the throttle command to the yaw command.\nA negative value is needed when positive thrust of the tail rotor rotates the vehicle opposite to the main rotor turn direction.\ntail_output += CA_HELI_YAW_TH_S * throttle", "max": 2.0, "min": -2.0, "name": "CA_HELI_YAW_TH_S", "shortDesc": "Scale for yaw compensation based on throttle", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Ice shedding prevents ice buildup in VTOL aircraft motors by\nperiodically spinning inactive rotors. When enabled (period\n> 0), every cycle lasts for the defined period and includes\na 2\u2011second spin at 0.01 motor output. If period <= 0, the\nfeature is disabled.", "min": 0.0, "name": "CA_ICE_PERIOD", "shortDesc": "Ice shedding cycle period", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Used to linearize mechanical output of swashplate servos to avoid axis coupling and binding with 4 servo redundancy.\nThis requires a symmetric setup where the servo horn is exactly centered with a 0 command.\nSetting to zero disables feature.", "max": 75.0, "min": 0.0, "name": "CA_MAX_SVO_THROW", "shortDesc": "Throw angle of swashplate servo at maximum commands for linearization", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 2, "group": "Geometry", "longDesc": "Selects the algorithm and desaturation method.\nIf set to Automatic, the selection is based on the airframe (CA_AIRFRAME).", "name": "CA_METHOD", "shortDesc": "Control allocation method", "type": "Int32", "values": [{"description": "Pseudo-inverse with output clipping", "value": 0}, {"description": "Pseudo-inverse with sequential desaturation technique", "value": 1}, {"description": "Automatic", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R0_SLEW", "shortDesc": "Motor 0 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R10_SLEW", "shortDesc": "Motor 10 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R11_SLEW", "shortDesc": "Motor 11 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R1_SLEW", "shortDesc": "Motor 1 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R2_SLEW", "shortDesc": "Motor 2 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R3_SLEW", "shortDesc": "Motor 3 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R4_SLEW", "shortDesc": "Motor 4 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R5_SLEW", "shortDesc": "Motor 5 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R6_SLEW", "shortDesc": "Motor 6 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R7_SLEW", "shortDesc": "Motor 7 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R8_SLEW", "shortDesc": "Motor 8 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.01, "longDesc": "Forces the motor output signal to take at least the configured time (in seconds)\nto traverse its full range (normally [0, 1], or if reversible [-1, 1]).\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_R9_SLEW", "shortDesc": "Motor 9 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AX", "shortDesc": "Axis of rotor 0 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AY", "shortDesc": "Axis of rotor 0 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_AZ", "shortDesc": "Axis of rotor 0 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR0_CT", "shortDesc": "Thrust coefficient of rotor 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR0_KM", "shortDesc": "Moment coefficient of rotor 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PX", "shortDesc": "Position of rotor 0 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PY", "shortDesc": "Position of rotor 0 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR0_PZ", "shortDesc": "Position of rotor 0 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR0_TILT", "shortDesc": "Rotor 0 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AX", "shortDesc": "Axis of rotor 10 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AY", "shortDesc": "Axis of rotor 10 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_AZ", "shortDesc": "Axis of rotor 10 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR10_CT", "shortDesc": "Thrust coefficient of rotor 10", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR10_KM", "shortDesc": "Moment coefficient of rotor 10", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PX", "shortDesc": "Position of rotor 10 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PY", "shortDesc": "Position of rotor 10 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR10_PZ", "shortDesc": "Position of rotor 10 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR10_TILT", "shortDesc": "Rotor 10 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AX", "shortDesc": "Axis of rotor 11 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AY", "shortDesc": "Axis of rotor 11 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_AZ", "shortDesc": "Axis of rotor 11 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR11_CT", "shortDesc": "Thrust coefficient of rotor 11", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR11_KM", "shortDesc": "Moment coefficient of rotor 11", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PX", "shortDesc": "Position of rotor 11 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PY", "shortDesc": "Position of rotor 11 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR11_PZ", "shortDesc": "Position of rotor 11 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR11_TILT", "shortDesc": "Rotor 11 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AX", "shortDesc": "Axis of rotor 1 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AY", "shortDesc": "Axis of rotor 1 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_AZ", "shortDesc": "Axis of rotor 1 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR1_CT", "shortDesc": "Thrust coefficient of rotor 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR1_KM", "shortDesc": "Moment coefficient of rotor 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PX", "shortDesc": "Position of rotor 1 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PY", "shortDesc": "Position of rotor 1 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR1_PZ", "shortDesc": "Position of rotor 1 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR1_TILT", "shortDesc": "Rotor 1 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AX", "shortDesc": "Axis of rotor 2 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AY", "shortDesc": "Axis of rotor 2 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_AZ", "shortDesc": "Axis of rotor 2 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR2_CT", "shortDesc": "Thrust coefficient of rotor 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR2_KM", "shortDesc": "Moment coefficient of rotor 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PX", "shortDesc": "Position of rotor 2 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PY", "shortDesc": "Position of rotor 2 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR2_PZ", "shortDesc": "Position of rotor 2 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR2_TILT", "shortDesc": "Rotor 2 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AX", "shortDesc": "Axis of rotor 3 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AY", "shortDesc": "Axis of rotor 3 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_AZ", "shortDesc": "Axis of rotor 3 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR3_CT", "shortDesc": "Thrust coefficient of rotor 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR3_KM", "shortDesc": "Moment coefficient of rotor 3", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PX", "shortDesc": "Position of rotor 3 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PY", "shortDesc": "Position of rotor 3 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR3_PZ", "shortDesc": "Position of rotor 3 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR3_TILT", "shortDesc": "Rotor 3 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AX", "shortDesc": "Axis of rotor 4 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AY", "shortDesc": "Axis of rotor 4 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_AZ", "shortDesc": "Axis of rotor 4 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR4_CT", "shortDesc": "Thrust coefficient of rotor 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR4_KM", "shortDesc": "Moment coefficient of rotor 4", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PX", "shortDesc": "Position of rotor 4 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PY", "shortDesc": "Position of rotor 4 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR4_PZ", "shortDesc": "Position of rotor 4 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR4_TILT", "shortDesc": "Rotor 4 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AX", "shortDesc": "Axis of rotor 5 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AY", "shortDesc": "Axis of rotor 5 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_AZ", "shortDesc": "Axis of rotor 5 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR5_CT", "shortDesc": "Thrust coefficient of rotor 5", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR5_KM", "shortDesc": "Moment coefficient of rotor 5", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PX", "shortDesc": "Position of rotor 5 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PY", "shortDesc": "Position of rotor 5 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR5_PZ", "shortDesc": "Position of rotor 5 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR5_TILT", "shortDesc": "Rotor 5 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AX", "shortDesc": "Axis of rotor 6 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AY", "shortDesc": "Axis of rotor 6 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_AZ", "shortDesc": "Axis of rotor 6 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR6_CT", "shortDesc": "Thrust coefficient of rotor 6", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR6_KM", "shortDesc": "Moment coefficient of rotor 6", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PX", "shortDesc": "Position of rotor 6 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PY", "shortDesc": "Position of rotor 6 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR6_PZ", "shortDesc": "Position of rotor 6 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR6_TILT", "shortDesc": "Rotor 6 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AX", "shortDesc": "Axis of rotor 7 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AY", "shortDesc": "Axis of rotor 7 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_AZ", "shortDesc": "Axis of rotor 7 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR7_CT", "shortDesc": "Thrust coefficient of rotor 7", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR7_KM", "shortDesc": "Moment coefficient of rotor 7", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PX", "shortDesc": "Position of rotor 7 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PY", "shortDesc": "Position of rotor 7 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR7_PZ", "shortDesc": "Position of rotor 7 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR7_TILT", "shortDesc": "Rotor 7 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AX", "shortDesc": "Axis of rotor 8 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AY", "shortDesc": "Axis of rotor 8 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_AZ", "shortDesc": "Axis of rotor 8 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR8_CT", "shortDesc": "Thrust coefficient of rotor 8", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR8_KM", "shortDesc": "Moment coefficient of rotor 8", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PX", "shortDesc": "Position of rotor 8 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PY", "shortDesc": "Position of rotor 8 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR8_PZ", "shortDesc": "Position of rotor 8 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR8_TILT", "shortDesc": "Rotor 8 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AX", "shortDesc": "Axis of rotor 9 thrust vector, X body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AY", "shortDesc": "Axis of rotor 9 thrust vector, Y body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Geometry", "increment": 0.1, "longDesc": "Only the direction is considered (the vector is normalized).", "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_AZ", "shortDesc": "Axis of rotor 9 thrust vector, Z body axis component", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.5, "group": "Geometry", "increment": 1.0, "longDesc": "The thrust coefficient if defined as Thrust = CT * u^2,\nwhere u (with value between actuator minimum and maximum)\nis the output signal sent to the motor controller.", "max": 100.0, "min": 0.0, "name": "CA_ROTOR9_CT", "shortDesc": "Thrust coefficient of rotor 9", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Geometry", "increment": 0.01, "longDesc": "The moment coefficient if defined as Torque = KM * Thrust.\nUse a positive value for a rotor with CCW rotation.\nUse a negative value for a rotor with CW rotation.", "max": 1.0, "min": -1.0, "name": "CA_ROTOR9_KM", "shortDesc": "Moment coefficient of rotor 9", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PX", "shortDesc": "Position of rotor 9 along X body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PY", "shortDesc": "Position of rotor 9 along Y body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.1, "max": 100.0, "min": -100.0, "name": "CA_ROTOR9_PZ", "shortDesc": "Position of rotor 9 along Z body axis relative to center of gravity", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "If not set to None, this motor is tilted by the configured tilt servo.", "name": "CA_ROTOR9_TILT", "shortDesc": "Rotor 9 tilt assignment", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Tilt 1", "value": 1}, {"description": "Tilt 2", "value": 2}, {"description": "Tilt 3", "value": 3}, {"description": "Tilt 4", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_ROTOR_COUNT", "shortDesc": "Total number of rotors", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}, {"description": "5", "value": 5}, {"description": "6", "value": 6}, {"description": "7", "value": 7}, {"description": "8", "value": 8}, {"description": "9", "value": 9}, {"description": "10", "value": 10}, {"description": "11", "value": 11}, {"description": "12", "value": 12}]}, {"bitmask": [{"description": "Motor 1", "index": 0}, {"description": "Motor 2", "index": 1}, {"description": "Motor 3", "index": 2}, {"description": "Motor 4", "index": 3}, {"description": "Motor 5", "index": 4}, {"description": "Motor 6", "index": 5}, {"description": "Motor 7", "index": 6}, {"description": "Motor 8", "index": 7}, {"description": "Motor 9", "index": 8}, {"description": "Motor 10", "index": 9}, {"description": "Motor 11", "index": 10}, {"description": "Motor 12", "index": 11}], "category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Configure motors to be bidirectional/reversible. Note that the output driver needs to support this as well.", "max": 4095, "min": 0, "name": "CA_R_REV", "shortDesc": "Bidirectional/Reversible motors", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG0", "shortDesc": "Angle for swash plate servo 0", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 140.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG1", "shortDesc": "Angle for swash plate servo 1", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 220.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG2", "shortDesc": "Angle for swash plate servo 2", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "increment": 10.0, "longDesc": "The angle is measured clockwise (as seen from top), with 0 pointing forwards (X axis).", "max": 360.0, "min": 0.0, "name": "CA_SP0_ANG3", "shortDesc": "Angle for swash plate servo 3", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L0", "shortDesc": "Arm length for swash plate servo 0", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L1", "shortDesc": "Arm length for swash plate servo 1", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L2", "shortDesc": "Arm length for swash plate servo 2", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Geometry", "increment": 0.1, "longDesc": "This is relative to the other arm lengths.", "max": 10.0, "min": 0.0, "name": "CA_SP0_ARM_L3", "shortDesc": "Arm length for swash plate servo 3", "type": "Float"}, {"category": "Standard", "default": 3, "group": "Geometry", "name": "CA_SP0_COUNT", "shortDesc": "Number of swash plates servos", "type": "Int32", "values": [{"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV0_SLEW", "shortDesc": "Servo 0 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV1_SLEW", "shortDesc": "Servo 1 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV2_SLEW", "shortDesc": "Servo 2 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV3_SLEW", "shortDesc": "Servo 3 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV4_SLEW", "shortDesc": "Servo 4 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV5_SLEW", "shortDesc": "Servo 5 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV6_SLEW", "shortDesc": "Servo 6 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "increment": 0.05, "longDesc": "Forces the servo output signal to take at least the configured time (in seconds)\nto traverse its full range [-100%, 100%].\nZero means that slew rate limiting is disabled.", "max": 10.0, "min": 0.0, "name": "CA_SV7_SLEW", "shortDesc": "Servo 7 slew rate limit", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_FLAP", "shortDesc": "Control Surface 0 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_SPOIL", "shortDesc": "Control Surface 0 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS0_TRIM", "shortDesc": "Control Surface 0 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_P", "shortDesc": "Control Surface 0 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_R", "shortDesc": "Control Surface 0 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS0_TRQ_Y", "shortDesc": "Control Surface 0 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS0_TYPE", "shortDesc": "Control Surface 0 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_FLAP", "shortDesc": "Control Surface 1 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_SPOIL", "shortDesc": "Control Surface 1 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS1_TRIM", "shortDesc": "Control Surface 1 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_P", "shortDesc": "Control Surface 1 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_R", "shortDesc": "Control Surface 1 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS1_TRQ_Y", "shortDesc": "Control Surface 1 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS1_TYPE", "shortDesc": "Control Surface 1 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_FLAP", "shortDesc": "Control Surface 2 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_SPOIL", "shortDesc": "Control Surface 2 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS2_TRIM", "shortDesc": "Control Surface 2 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_P", "shortDesc": "Control Surface 2 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_R", "shortDesc": "Control Surface 2 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS2_TRQ_Y", "shortDesc": "Control Surface 2 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS2_TYPE", "shortDesc": "Control Surface 2 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_FLAP", "shortDesc": "Control Surface 3 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_SPOIL", "shortDesc": "Control Surface 3 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS3_TRIM", "shortDesc": "Control Surface 3 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_P", "shortDesc": "Control Surface 3 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_R", "shortDesc": "Control Surface 3 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS3_TRQ_Y", "shortDesc": "Control Surface 3 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS3_TYPE", "shortDesc": "Control Surface 3 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_FLAP", "shortDesc": "Control Surface 4 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_SPOIL", "shortDesc": "Control Surface 4 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS4_TRIM", "shortDesc": "Control Surface 4 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_P", "shortDesc": "Control Surface 4 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_R", "shortDesc": "Control Surface 4 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS4_TRQ_Y", "shortDesc": "Control Surface 4 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS4_TYPE", "shortDesc": "Control Surface 4 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_FLAP", "shortDesc": "Control Surface 5 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_SPOIL", "shortDesc": "Control Surface 5 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS5_TRIM", "shortDesc": "Control Surface 5 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_P", "shortDesc": "Control Surface 5 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_R", "shortDesc": "Control Surface 5 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS5_TRQ_Y", "shortDesc": "Control Surface 5 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS5_TYPE", "shortDesc": "Control Surface 5 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_FLAP", "shortDesc": "Control Surface 6 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_SPOIL", "shortDesc": "Control Surface 6 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS6_TRIM", "shortDesc": "Control Surface 6 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_P", "shortDesc": "Control Surface 6 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_R", "shortDesc": "Control Surface 6 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS6_TRQ_Y", "shortDesc": "Control Surface 6 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS6_TYPE", "shortDesc": "Control Surface 6 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_FLAP", "shortDesc": "Control Surface 7 configuration as flap", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_SPOIL", "shortDesc": "Control Surface 7 configuration as spoiler", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "longDesc": "Can be used to add an offset to the servo control.\nNOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead.\nThis parameter can only be set if all PWM Center parameters are set to default.", "max": 1.0, "min": -1.0, "name": "CA_SV_CS7_TRIM", "shortDesc": "Control Surface 7 trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_P", "shortDesc": "Control Surface 7 pitch torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_R", "shortDesc": "Control Surface 7 roll torque scaling", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Geometry", "name": "CA_SV_CS7_TRQ_Y", "shortDesc": "Control Surface 7 yaw torque scaling", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS7_TYPE", "shortDesc": "Control Surface 7 type", "type": "Int32", "values": [{"description": "(Not set)", "value": 0}, {"description": "Left Aileron", "value": 1}, {"description": "Right Aileron", "value": 2}, {"description": "Elevator", "value": 3}, {"description": "Rudder", "value": 4}, {"description": "Left Elevon", "value": 5}, {"description": "Right Elevon", "value": 6}, {"description": "Left V-Tail", "value": 7}, {"description": "Right V-Tail", "value": 8}, {"description": "Left Flap", "value": 9}, {"description": "Right Flap", "value": 10}, {"description": "Airbrake", "value": 11}, {"description": "Custom", "value": 12}, {"description": "Left A-tail", "value": 13}, {"description": "Right A-tail", "value": 14}, {"description": "Single Channel Aileron", "value": 15}, {"description": "Steering Wheel", "value": 16}, {"description": "Left Spoiler", "value": 17}, {"description": "Right Spoiler", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_CS_COUNT", "shortDesc": "Total number of Control Surfaces", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}, {"description": "5", "value": 5}, {"description": "6", "value": 6}, {"description": "7", "value": 7}, {"description": "8", "value": 8}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Geometry", "max": 5.0, "min": 0.0, "name": "CA_SV_FLAP_SLEW", "shortDesc": "Control Surface slew rate for normalized flaps setpoint", "type": "Float"}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL0_CT", "shortDesc": "Tilt 0 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL0_MAXA", "shortDesc": "Tilt Servo 0 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL0_MINA", "shortDesc": "Tilt Servo 0 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL0_TD", "shortDesc": "Tilt Servo 0 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL1_CT", "shortDesc": "Tilt 1 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL1_MAXA", "shortDesc": "Tilt Servo 1 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL1_MINA", "shortDesc": "Tilt Servo 1 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL1_TD", "shortDesc": "Tilt Servo 1 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL2_CT", "shortDesc": "Tilt 2 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL2_MAXA", "shortDesc": "Tilt Servo 2 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL2_MINA", "shortDesc": "Tilt Servo 2 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL2_TD", "shortDesc": "Tilt Servo 2 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 1, "group": "Geometry", "longDesc": "Define if this servo is used for additional control.", "name": "CA_SV_TL3_CT", "shortDesc": "Tilt 3 is used for control", "type": "Int32", "values": [{"description": "None", "value": 0}, {"description": "Yaw", "value": 1}, {"description": "Pitch", "value": 2}, {"description": "Yaw and Pitch", "value": 3}]}, {"category": "Standard", "decimalPlaces": 0, "default": 90.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the maximum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL3_MAXA", "shortDesc": "Tilt Servo 3 Tilt Angle at Maximum", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 0.0, "group": "Geometry", "longDesc": "Defines the tilt angle when the servo is at the minimum.\nAn angle of zero means upwards.", "max": 90.0, "min": -90.0, "name": "CA_SV_TL3_MINA", "shortDesc": "Tilt Servo 3 Tilt Angle at Minimum", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Geometry", "longDesc": "Defines the direction the servo tilts towards when moving towards the maximum tilt angle.\nFor example if the minimum tilt angle is -90, the maximum 90, and the direction 'Towards Front',\nthe motor axis aligns with the XZ-plane, points towards -X at the minimum and +X at the maximum tilt.", "max": 359, "min": 0, "name": "CA_SV_TL3_TD", "shortDesc": "Tilt Servo 3 Tilt Direction", "type": "Int32", "values": [{"description": "Towards Front", "value": 0}, {"description": "Towards Right", "value": 90}]}, {"category": "Standard", "default": 0, "group": "Geometry", "name": "CA_SV_TL_COUNT", "shortDesc": "Total number of Tilt Servos", "type": "Int32", "values": [{"description": "0", "value": 0}, {"description": "1", "value": 1}, {"description": "2", "value": 2}, {"description": "3", "value": 3}, {"description": "4", "value": 4}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Hover Thrust Estimator", "longDesc": "Sets the number of standard deviations used\nby the innovation consistency test.", "max": 10.0, "min": 1.0, "name": "HTE_ACC_GATE", "shortDesc": "Gate size for acceleration fusion", "type": "Float", "units": "SD"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Hover Thrust Estimator", "longDesc": "Sets the number of standard deviations used\nby the innovation consistency test.", "max": 1.0, "min": 0.0, "name": "HTE_HT_ERR_INIT", "shortDesc": "1-sigma initial hover thrust uncertainty", "type": "Float", "units": "normalized_thrust"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0036, "group": "Hover Thrust Estimator", "longDesc": "Reduce to make the hover thrust estimate\nmore stable, increase if the real hover thrust\nis expected to change quickly over time.", "max": 1.0, "min": 0.0001, "name": "HTE_HT_NOISE", "shortDesc": "Hover thrust process noise", "type": "Float", "units": "normalized_thrust/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Hover Thrust Estimator", "longDesc": "Defines the range of the hover thrust estimate around MPC_THR_HOVER.\nA value of 0.2 with MPC_THR_HOVER at 0.5 results in a range of [0.3, 0.7].\nSet to a large value if the vehicle operates in varying physical conditions that\naffect the required hover thrust strongly (e.g. differently sized payloads).", "max": 0.4, "min": 0.01, "name": "HTE_THR_RANGE", "shortDesc": "Max deviation from MPC_THR_HOVER", "type": "Float", "units": "normalized_thrust"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Hover Thrust Estimator", "longDesc": "Above this speed, the measurement noise is linearly increased\nto reduce the sensitivity of the estimator from biased measurement.\nSet to a low value on vehicles with large lifting surfaces.", "max": 20.0, "min": 1.0, "name": "HTE_VXY_THR", "shortDesc": "Horizontal velocity threshold for sensitivity reduction", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Hover Thrust Estimator", "longDesc": "Above this speed, the measurement noise is linearly increased\nto reduce the sensitivity of the estimator from biased measurement.\nSet to a low value on vehicles affected by air drag when climbing or descending.", "max": 10.0, "min": 1.0, "name": "HTE_VZ_THR", "shortDesc": "Vertical velocity threshold for sensitivity reduction", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.0, "group": "Land Detector", "longDesc": "Maximum airspeed allowed in the landed state", "max": 30.0, "min": 2.0, "name": "LNDFW_AIRSPD_MAX", "shortDesc": "Fixed-wing land detector: Max airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Land Detector", "longDesc": "Maximum allowed norm of the angular velocity in the landed state.\nOnly used if neither airspeed nor groundspeed can be used for landing detection.", "name": "LNDFW_ROT_MAX", "shortDesc": "Fixed-wing land detector: max rotational speed", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Land Detector", "longDesc": "Time the land conditions (speeds and acceleration) have to be satisfied to detect a landing.", "min": 0.1, "name": "LNDFW_TRIG_TIME", "rebootRequired": true, "shortDesc": "Fixed-wing land detection trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Land Detector", "longDesc": "Maximum horizontal velocity allowed in the landed state.\nA factor of 0.7 is applied in case of airspeed-less flying\n(either because no sensor is present or sensor data got invalid in flight).", "max": 20.0, "min": 0.5, "name": "LNDFW_VEL_XY_MAX", "shortDesc": "Fixed-wing land detector: Max horizontal velocity threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Land Detector", "longDesc": "Maximum vertical velocity allowed in the landed state.", "max": 20.0, "min": 0.1, "name": "LNDFW_VEL_Z_MAX", "shortDesc": "Fixed-wing land detector: Max vertiacal velocity threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 8.0, "group": "Land Detector", "longDesc": "Maximum horizontal (x,y body axes) acceleration allowed in the landed state", "max": 30.0, "min": 2.0, "name": "LNDFW_XYACC_MAX", "shortDesc": "Fixed-wing land detector: Max horizontal acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Land Detector", "longDesc": "The height above ground below which ground effect creates barometric altitude errors.\nA negative value indicates no ground effect.", "min": -1.0, "name": "LNDMC_ALT_GND", "shortDesc": "Ground effect altitude for multicopters", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Land Detector", "longDesc": "Maximum allowed norm of the angular velocity (roll, pitch) in the landed state.", "name": "LNDMC_ROT_MAX", "shortDesc": "Multicopter max rotational speed", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Land Detector", "longDesc": "Total time it takes to go through all three land detection stages:\nground contact, maybe landed, landed\nwhen all necessary conditions are constantly met.", "max": 10.0, "min": 0.1, "name": "LNDMC_TRIG_TIME", "shortDesc": "Multicopter land detection trigger time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Land Detector", "longDesc": "Maximum horizontal velocity allowed in the landed state", "name": "LNDMC_XY_VEL_MAX", "shortDesc": "Multicopter max horizontal velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.25, "group": "Land Detector", "longDesc": "Vertical velocity threshold to detect landing.\nHas to be set lower than the expected minimal speed for landing,\nwhich is either MPC_LAND_SPEED or MPC_LAND_CRWL.\nThis is enforced by an automatic check.", "min": 0.0, "name": "LNDMC_Z_VEL_MAX", "shortDesc": "Multicopter vertical velocity threshold", "type": "Float", "units": "m/s"}, {"category": "System", "default": 0, "group": "Land Detector", "longDesc": "Total flight time of this autopilot. Higher 32 bits of the value.\nFlight time in microseconds = (LND_FLIGHT_T_HI << 32) | LND_FLIGHT_T_LO.", "min": 0, "name": "LND_FLIGHT_T_HI", "shortDesc": "Total flight time in microseconds", "type": "Int32", "volatile": true}, {"category": "System", "default": 0, "group": "Land Detector", "longDesc": "Total flight time of this autopilot. Lower 32 bits of the value.\nFlight time in microseconds = (LND_FLIGHT_T_HI << 32) | LND_FLIGHT_T_LO.", "min": 0, "name": "LND_FLIGHT_T_LO", "shortDesc": "Total flight time in microseconds", "type": "Int32", "volatile": true}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Landing Target Estimator", "longDesc": "Variance of acceleration measurement used for landing target position prediction.\nHigher values results in tighter following of the measurements and more lenient outlier rejection", "min": 0.01, "name": "LTEST_ACC_UNC", "shortDesc": "Acceleration uncertainty", "type": "Float", "units": "(m/s^2)^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.005, "group": "Landing Target Estimator", "longDesc": "Variance of the landing target measurement from the driver.\nHigher values result in less aggressive following of the measurement and a smoother output as well as fewer rejected measurements.", "name": "LTEST_MEAS_UNC", "shortDesc": "Landing target measurement uncertainty", "type": "Float", "units": "tan(rad)^2"}, {"category": "Standard", "default": 0, "group": "Landing Target Estimator", "longDesc": "Configure the mode of the landing target. Depending on the mode, the landing target observations are used differently to aid position estimation.\nMode Moving: The landing target may be moving around while in the field of view of the vehicle. Landing target measurements are not used to aid positioning.\nMode Stationary: The landing target is stationary. Measured velocity w.r.t. the landing target is used to aid velocity estimation.", "max": 1, "min": 0, "name": "LTEST_MODE", "shortDesc": "Landing target mode", "type": "Int32", "values": [{"description": "Moving", "value": 0}, {"description": "Stationary", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Landing Target Estimator", "longDesc": "Initial variance of the relative landing target position in x and y direction", "min": 0.001, "name": "LTEST_POS_UNC_IN", "shortDesc": "Initial landing target position uncertainty", "type": "Float", "units": "m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Landing Target Estimator", "longDesc": "Landing target x measurements are scaled by this factor before being used", "min": 0.01, "name": "LTEST_SCALE_X", "shortDesc": "Scale factor for sensor measurements in sensor x axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Landing Target Estimator", "longDesc": "Landing target y measurements are scaled by this factor before being used", "min": 0.01, "name": "LTEST_SCALE_Y", "shortDesc": "Scale factor for sensor measurements in sensor y axis", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_X", "rebootRequired": true, "shortDesc": "X Position of IRLOCK in body frame (forward)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_Y", "rebootRequired": true, "shortDesc": "Y Position of IRLOCK in body frame (right)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Landing Target Estimator", "name": "LTEST_SENS_POS_Z", "rebootRequired": true, "shortDesc": "Z Position of IRLOCK in body frame (downward)", "type": "Float", "units": "m"}, {"category": "Standard", "default": 2, "group": "Landing Target Estimator", "longDesc": "Default orientation of Yaw 90\u00b0", "max": 40, "min": -1, "name": "LTEST_SENS_ROT", "rebootRequired": true, "shortDesc": "Rotation of IRLOCK sensor relative to airframe", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Landing Target Estimator", "longDesc": "Initial variance of the relative landing target velocity in x and y directions", "min": 0.001, "name": "LTEST_VEL_UNC_IN", "shortDesc": "Initial landing target velocity uncertainty", "type": "Float", "units": "(m/s)^2"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.012, "group": "Local Position Estimator", "longDesc": "Data sheet noise density = 150ug/sqrt(Hz) = 0.0015 m/s^2/sqrt(Hz)\nLarger than data sheet to account for tilt error.", "max": 2.0, "min": 1e-05, "name": "LPE_ACC_XY", "shortDesc": "Accelerometer xy noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.02, "group": "Local Position Estimator", "longDesc": "Data sheet noise density = 150ug/sqrt(Hz) = 0.0015 m/s^2/sqrt(Hz)", "max": 2.0, "min": 1e-05, "name": "LPE_ACC_Z", "shortDesc": "Accelerometer z noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Local Position Estimator", "max": 100.0, "min": 0.01, "name": "LPE_BAR_Z", "shortDesc": "Barometric presssure altitude z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Local Position Estimator", "name": "LPE_EN", "shortDesc": "Local position estimator enable (unsupported)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 3.0, "group": "Local Position Estimator", "max": 5.0, "min": 1.0, "name": "LPE_EPH_MAX", "shortDesc": "Max EPH allowed for GPS initialization", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 5.0, "group": "Local Position Estimator", "max": 5.0, "min": 1.0, "name": "LPE_EPV_MAX", "shortDesc": "Max EPV allowed for GPS initialization", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Local Position Estimator", "longDesc": "By initializing the estimator to the LPE_LAT/LON parameters when global information is unavailable", "max": 1, "min": 0, "name": "LPE_FAKE_ORIGIN", "shortDesc": "Enable publishing of a fake global position (e.g for AUTO missions using Optical Flow)", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.001, "group": "Local Position Estimator", "max": 2.0, "min": 0.0, "name": "LPE_FGYRO_HP", "shortDesc": "Flow gyro high pass filter cut off frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_FLW_OFF_Z", "shortDesc": "Optical flow z offset from center", "type": "Float", "units": "m"}, {"category": "Standard", "default": 150, "group": "Local Position Estimator", "max": 255, "min": 0, "name": "LPE_FLW_QMIN", "shortDesc": "Optical flow minimum quality threshold", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 7.0, "group": "Local Position Estimator", "max": 10.0, "min": 0.1, "name": "LPE_FLW_R", "shortDesc": "Optical flow rotation (roll/pitch) noise gain", "type": "Float", "units": "m/s/rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 7.0, "group": "Local Position Estimator", "max": 10.0, "min": 0.0, "name": "LPE_FLW_RR", "shortDesc": "Optical flow angular velocity noise gain", "type": "Float", "units": "m/rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.3, "group": "Local Position Estimator", "max": 10.0, "min": 0.1, "name": "LPE_FLW_SCALE", "shortDesc": "Optical flow scale", "type": "Float", "units": "m"}, {"bitmask": [{"description": "fuse GPS, requires GPS for alt. init", "index": 0}, {"description": "fuse optical flow", "index": 1}, {"description": "fuse vision position", "index": 2}, {"description": "fuse landing target", "index": 3}, {"description": "fuse land detector", "index": 4}, {"description": "pub agl as lpos down", "index": 5}, {"description": "flow gyro compensation", "index": 6}, {"description": "fuse baro", "index": 7}], "category": "Standard", "default": 145, "group": "Local Position Estimator", "longDesc": "Set bits in the following positions to enable:\n0 : Set to true to fuse GPS data if available, also requires GPS for altitude init\n1 : Set to true to fuse optical flow data if available\n2 : Set to true to fuse vision position\n3 : Set to true to enable landing target\n4 : Set to true to fuse land detector\n5 : Set to true to publish AGL as local position down component\n6 : Set to true to enable flow gyro compensation\n7 : Set to true to enable baro fusion\ndefault (145 - GPS, baro, land detector)", "max": 255, "min": 0, "name": "LPE_FUSION", "shortDesc": "Integer bitmask controlling data fusion", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.29, "group": "Local Position Estimator", "max": 0.4, "min": 0.0, "name": "LPE_GPS_DELAY", "shortDesc": "GPS delay compensaton", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Local Position Estimator", "longDesc": "EPV used if greater than this value.", "max": 2.0, "min": 0.01, "name": "LPE_GPS_VXY", "shortDesc": "GPS xy velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.25, "group": "Local Position Estimator", "max": 2.0, "min": 0.01, "name": "LPE_GPS_VZ", "shortDesc": "GPS z velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Local Position Estimator", "max": 5.0, "min": 0.01, "name": "LPE_GPS_XY", "shortDesc": "Minimum GPS xy standard deviation, uses reported EPH if greater", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Local Position Estimator", "max": 200.0, "min": 0.01, "name": "LPE_GPS_Z", "shortDesc": "Minimum GPS z standard deviation, uses reported EPV if greater", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Local Position Estimator", "max": 10.0, "min": 0.01, "name": "LPE_LAND_VXY", "shortDesc": "Land detector xy velocity standard deviation", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Local Position Estimator", "max": 10.0, "min": 0.001, "name": "LPE_LAND_Z", "shortDesc": "Land detector z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 8, "default": 47.397742, "group": "Local Position Estimator", "max": 90.0, "min": -90.0, "name": "LPE_LAT", "shortDesc": "Local origin latitude for nav w/o GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_LDR_OFF_Z", "shortDesc": "Lidar z offset from center of vehicle +down", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_LDR_Z", "shortDesc": "Lidar z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 8, "default": 8.545594, "group": "Local Position Estimator", "max": 180.0, "min": -180.0, "name": "LPE_LON", "shortDesc": "Local origin longitude for nav w/o GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0001, "group": "Local Position Estimator", "max": 10.0, "min": 0.0, "name": "LPE_LT_COV", "shortDesc": "Minimum landing target standard covariance, uses reported covariance if greater", "type": "Float", "units": "m^2"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0, "name": "LPE_PN_B", "shortDesc": "Accel bias propagation noise density", "type": "Float", "units": "m/s^3/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Increase to trust measurements more.\nDecrease to trust model more.", "max": 1.0, "min": 0.0, "name": "LPE_PN_P", "shortDesc": "Position propagation noise density", "type": "Float", "units": "m/s/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0, "name": "LPE_PN_T", "shortDesc": "Terrain random walk noise density, hilly/outdoor (0.1), flat/Indoor (0.001)", "type": "Float", "units": "m/s/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 8, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Increase to trust measurements more.\nDecrease to trust model more.", "max": 1.0, "min": 0.0, "name": "LPE_PN_V", "shortDesc": "Velocity propagation noise density", "type": "Float", "units": "m/s^2/sqrt(Hz)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Local Position Estimator", "max": 1.0, "min": -1.0, "name": "LPE_SNR_OFF_Z", "shortDesc": "Sonar z offset from center of vehicle +down", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.05, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_SNR_Z", "shortDesc": "Sonar z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Local Position Estimator", "longDesc": "Used to calculate increased terrain random walk nosie due to movement.", "max": 100.0, "min": 0.0, "name": "LPE_T_MAX_GRADE", "shortDesc": "Terrain maximum percent grade, hilly/outdoor (100 = 45 deg), flat/Indoor (0 = 0 deg)", "type": "Float", "units": "%"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.001, "group": "Local Position Estimator", "max": 1.0, "min": 0.0001, "name": "LPE_VIC_P", "shortDesc": "Vicon position standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Local Position Estimator", "longDesc": "Set to zero to enable automatic compensation from measurement timestamps", "max": 0.1, "min": 0.0, "name": "LPE_VIS_DELAY", "shortDesc": "Vision delay compensation", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_VIS_XY", "shortDesc": "Vision xy standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "Local Position Estimator", "max": 100.0, "min": 0.01, "name": "LPE_VIS_Z", "shortDesc": "Vision z standard deviation", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.3, "group": "Local Position Estimator", "max": 1.0, "min": 0.01, "name": "LPE_VXY_PUB", "shortDesc": "Required velocity xy standard deviation to publish position", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 5.0, "group": "Local Position Estimator", "max": 1000.0, "min": 5.0, "name": "LPE_X_LP", "shortDesc": "Cut frequency for state publication", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Local Position Estimator", "max": 5.0, "min": 0.3, "name": "LPE_Z_PUB", "shortDesc": "Required z standard deviation to publish altitude/ terrain", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_0_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 0", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_0_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 0", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_0_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 0", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 0, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_0_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 0", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_0_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 0", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_0_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 0", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1200, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_0_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 0", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 14550, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 0,\nselected remote port will be set and used in MAVLink instance 0.", "name": "MAV_0_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 0", "type": "Int32"}, {"category": "Standard", "default": 14556, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 0,\nselected udp port will be set and used in MAVLink instance 0.", "name": "MAV_0_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 0", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_1_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 1", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_1_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 1", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_1_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 1", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 1, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_1_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 1", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_1_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 1", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_1_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 1", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_1_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 1", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 1,\nselected remote port will be set and used in MAVLink instance 1.", "name": "MAV_1_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 1", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 1,\nselected udp port will be set and used in MAVLink instance 1.", "name": "MAV_1_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 1", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "This allows a ground control station to automatically find the drone\non the local network.", "name": "MAV_2_BROADCAST", "shortDesc": "Broadcast heartbeats on local network for MAVLink instance 2", "type": "Int32", "values": [{"description": "Never broadcast", "value": 0}, {"description": "Always broadcast", "value": 1}, {"description": "Only multicast", "value": 2}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "longDesc": "This is used to force flow control on or off for the the mavlink\ninstance. By default it is auto detected. Use when auto detection fails.", "name": "MAV_2_FLOW_CTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for instance 2", "type": "Int32", "values": [{"description": "Force off", "value": 0}, {"description": "Force on", "value": 1}, {"description": "Auto-detected", "value": 2}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If enabled, forward incoming MAVLink messages to other MAVLink ports if the\nmessage is either broadcast or the target is not the autopilot.\nThis allows for example a GCS to talk to a camera that is connected to the\nautopilot via MAVLink (on a different link than the GCS).", "name": "MAV_2_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink Message forwarding for instance 2", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.015, "group": "MAVLink", "increment": 0.001, "longDesc": "Positive real value that configures the transmission frequency of the\nHIGH_LATENCY2 stream for instance 2, configured in iridium mode.\nThis parameter has no effect if the instance mode is different from iridium.", "max": 50.0, "min": 0.0, "name": "MAV_2_HL_FREQ", "rebootRequired": true, "shortDesc": "Configures the frequency of HIGH_LATENCY2 stream for instance 2", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_2_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for instance 2", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Custom", "value": 1}, {"description": "Onboard", "value": 2}, {"description": "OSD", "value": 3}, {"description": "Magic", "value": 4}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "External Vision", "value": 8}, {"description": "Gimbal", "value": 10}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "uAvionix", "value": 12}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If enabled, MAVLink messages will be throttled according to\n`txbuf` field reported by radio_status.\nRequires a radio to send the mavlink message RADIO_STATUS.", "name": "MAV_2_RADIO_CTL", "rebootRequired": true, "shortDesc": "Enable software throttling of mavlink on instance 2", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "Configure the maximum sending rate for the MAVLink streams in Bytes/sec.\nIf the configured streams exceed the maximum rate, the sending rate of\neach stream is automatically decreased.\nIf this is set to 0 a value of half of the theoretical maximum bandwidth is used.\nThis corresponds to baudrate/20 Bytes/s (baudrate/10 = maximum data rate on\n8N1-configured links).", "min": 0, "name": "MAV_2_RATE", "rebootRequired": true, "shortDesc": "Maximum MAVLink sending rate for instance 2", "type": "Int32", "units": "B/s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 2,\nselected remote port will be set and used in MAVLink instance 2.", "name": "MAV_2_REMOTE_PRT", "rebootRequired": true, "shortDesc": "MAVLink Remote Port for instance 2", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If ethernet enabled and selected as configuration for MAVLink instance 2,\nselected udp port will be set and used in MAVLink instance 2.", "name": "MAV_2_UDP_PRT", "rebootRequired": true, "shortDesc": "MAVLink Network Port for instance 2", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "max": 250, "min": 1, "name": "MAV_COMP_ID", "rebootRequired": true, "shortDesc": "MAVLink component ID", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "If set to 1 incoming external setpoint messages will be directly forwarded\nto the controllers if in offboard control mode", "name": "MAV_FWDEXTSP", "shortDesc": "Forward external setpoint messages", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "Disabling the parameter hash check functionality will make the mavlink instance\nstream parameters continuously.", "name": "MAV_HASH_CHK_EN", "shortDesc": "Parameter hash check", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "MAVLink", "longDesc": "The mavlink heartbeat message will not be forwarded if this parameter is set to 'disabled'.\nThe main reason for disabling heartbeats to be forwarded is because they confuse dronekit.", "name": "MAV_HB_FORW_EN", "shortDesc": "Heartbeat message forwarding", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 2, "group": "MAVLink", "name": "MAV_PROTO_VER", "shortDesc": "MAVLink protocol version", "type": "Int32", "values": [{"description": "Version 1 with auto-upgrade to v2 if detected", "value": 1}, {"description": "Version 2", "value": 2}]}, {"category": "Standard", "default": 5, "group": "MAVLink", "longDesc": "If the connected radio stops reporting RADIO_STATUS for a certain time,\na warning is triggered and, if MAV_X_RADIO_CTL is enabled, the software-flow\ncontrol is reset.", "max": 250, "min": 1, "name": "MAV_RADIO_TOUT", "shortDesc": "Timeout in seconds for the RADIO_STATUS reports coming in", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "When non-zero the MAVLink app will attempt to configure the\nSiK radio to this ID and re-set the parameter to 0. If the value\nis negative it will reset the complete radio config to\nfactory defaults. Only applies if this mavlink instance is going through a SiK radio", "max": 240, "min": -1, "name": "MAV_SIK_RADIO_ID", "shortDesc": "MAVLink SiK Radio ID", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "MAVLink", "max": 250, "min": 1, "name": "MAV_SYS_ID", "rebootRequired": true, "shortDesc": "MAVLink system ID", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "TELEM2 on Skynode only.", "name": "MAV_S_FORWARD", "rebootRequired": true, "shortDesc": "Enable MAVLink forwarding on TELEM2", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 11, "group": "MAVLink", "longDesc": "The MAVLink Mode defines the set of streamed messages (for example the\nvehicle's attitude) and their sending rates.", "name": "MAV_S_MODE", "rebootRequired": true, "shortDesc": "MAVLink Mode for SOM to FMU communication channel", "type": "Int32", "values": [{"description": "Normal", "value": 0}, {"description": "Onboard", "value": 2}, {"description": "Config", "value": 5}, {"description": "Minimal", "value": 7}, {"description": "Onboard Low Bandwidth", "value": 11}, {"description": "Low Bandwidth", "value": 13}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "max": 22, "min": 0, "name": "MAV_TYPE", "shortDesc": "MAVLink airframe type", "type": "Int32", "values": [{"description": "Generic micro air vehicle", "value": 0}, {"description": "Fixed wing aircraft", "value": 1}, {"description": "Quadrotor", "value": 2}, {"description": "Coaxial helicopter", "value": 3}, {"description": "Normal helicopter with tail rotor", "value": 4}, {"description": "Airship, controlled", "value": 7}, {"description": "Free balloon, uncontrolled", "value": 8}, {"description": "Ground rover", "value": 10}, {"description": "Surface vessel, boat, ship", "value": 11}, {"description": "Submarine", "value": 12}, {"description": "Hexarotor", "value": 13}, {"description": "Octorotor", "value": 14}, {"description": "Tricopter", "value": 15}, {"description": "VTOL Two-rotor Tailsitter", "value": 19}, {"description": "VTOL Quad-rotor Tailsitter", "value": 20}, {"description": "VTOL Tiltrotor", "value": 21}, {"description": "VTOL Standard (separate fixed rotors for hover and cruise flight)", "value": 22}, {"description": "VTOL Tailsitter", "value": 23}]}, {"category": "Standard", "default": 0, "group": "MAVLink", "longDesc": "If set to 1 incoming HIL GPS messages are parsed.", "name": "MAV_USEHILGPS", "shortDesc": "Use/Accept HIL GPS message even if not in HIL mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Magnetometer Bias Estimator", "longDesc": "This enables continuous calibration of the magnetometers\nbefore takeoff using gyro data.", "name": "MBE_ENABLE", "rebootRequired": true, "shortDesc": "Enable online mag bias calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 18.0, "group": "Magnetometer Bias Estimator", "increment": 0.1, "longDesc": "Increase to make the estimator more responsive\nDecrease to make the estimator more robust to noise", "max": 100.0, "min": 0.1, "name": "MBE_LEARN_GAIN", "shortDesc": "Mag bias estimator learning gain", "type": "Float"}, {"category": "Standard", "default": 1, "group": "Manual Control", "longDesc": "This determines if moving the left stick to the lower right\narms and to the lower left disarms the vehicle.", "name": "MAN_ARM_GESTURE", "shortDesc": "Enable arm/disarm stick gesture", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Manual Control", "increment": 0.01, "longDesc": "Range around stick center ignored to prevent\nvehicle drift from stick hardware inaccuracy.\nDoes not apply to any precise constant input like\nthrottle and attitude or rate piloting.", "max": 1.0, "min": 0.0, "name": "MAN_DEADZONE", "shortDesc": "Deadzone for sticks (only specific use cases)", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Manual Control", "longDesc": "The timeout for holding the left stick to the lower left\nand the right stick to the lower right at the same time until the gesture\nkills the actuators one-way.\nA negative value disables the feature.", "max": 15.0, "min": -1.0, "name": "MAN_KILL_GEST_T", "shortDesc": "Trigger time for kill stick gesture", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Mission", "longDesc": "Ensure:\ngripper: NAV_CMD_DO_GRIPPER\nhas released before continuing mission.\nwinch: CMD_DO_WINCH\nhas delivered before continuing mission.\ngimbal: CMD_DO_GIMBAL_MANAGER_PITCHYAW\nhas reached the commanded orientation before beginning to take pictures.", "min": 0.0, "name": "MIS_COMMAND_TOUT", "shortDesc": "Timeout to allow the payload to execute the mission command", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 10000.0, "group": "Mission", "increment": 100.0, "longDesc": "There will be a warning message if the current waypoint is more distant than MIS_DIST_1WP from Home.\nHas no effect on mission validity.\nSet a value of zero or less to disable.", "max": 100000.0, "min": -1.0, "name": "MIS_DIST_1WP", "shortDesc": "Maximal horizontal distance from Home to first waypoint", "type": "Float", "units": "m"}, {"category": "Standard", "default": 30, "group": "Mission", "longDesc": "Minimum altitude above landing point that the vehicle will climb to after an aborted landing.\nThen vehicle will loiter in this altitude until further command is received.\nOnly applies to fixed-wing vehicles.", "min": 0, "name": "MIS_LND_ABRT_ALT", "shortDesc": "Landing abort min altitude", "type": "Int32", "units": "m"}, {"category": "Standard", "default": 0, "group": "Mission", "longDesc": "If enabled, yaw commands will be sent to the mount and the vehicle will follow its heading towards the flight direction.\nIf disabled, the vehicle will yaw towards the ROI.", "max": 1, "min": 0, "name": "MIS_MNT_YAW_CTL", "shortDesc": "Enable yaw control of the mount. (Only affects multicopters and ROI mission items)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Enable", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 2.5, "group": "Mission", "increment": 0.5, "longDesc": "This is the relative altitude the system will take off to\nif not otherwise specified.", "min": 0.0, "name": "MIS_TAKEOFF_ALT", "shortDesc": "Default take-off altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Mission", "longDesc": "Specifies if a mission has to contain a takeoff and/or mission landing.\nValidity of configured takeoffs/landings is checked independently of the setting here.", "name": "MIS_TKO_LAND_REQ", "shortDesc": "Mission takeoff/landing required", "type": "Int32", "values": [{"description": "No requirements", "value": 0}, {"description": "Require a takeoff", "value": 1}, {"description": "Require a landing", "value": 2}, {"description": "Require a takeoff and a landing", "value": 3}, {"description": "Require both a takeoff and a landing, or neither", "value": 4}, {"description": "Same as previous when landed, in-air require landing only if no valid VTOL approach is present", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": 12.0, "group": "Mission", "increment": 1.0, "max": 90.0, "min": 0.0, "name": "MIS_YAW_ERR", "shortDesc": "Max yaw error in degrees needed for waypoint heading acceptance", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 1.0, "longDesc": "If set > 0 it will ignore the target heading for normal waypoint acceptance. If the\nwaypoint forces the heading the timeout will matter. For example on VTOL forwards transition.\nMainly useful for VTOLs that have less yaw authority and might not reach target\nyaw in wind. Disabled by default.", "max": 20.0, "min": -1.0, "name": "MIS_YAW_TMT", "shortDesc": "Time in seconds we wait on reaching target heading at a waypoint if it is forced", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Mission", "max": 4, "min": 0, "name": "MPC_YAW_MODE", "shortDesc": "Heading behavior in autonomous modes", "type": "Int32", "values": [{"description": "towards waypoint", "value": 0}, {"description": "towards home", "value": 1}, {"description": "away from home", "value": 2}, {"description": "along trajectory", "value": 3}, {"description": "towards waypoint (yaw first)", "value": 4}, {"description": "yaw fixed", "value": 5}]}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Mission", "increment": 0.5, "longDesc": "Default acceptance radius, overridden by acceptance radius of waypoint if set.\nFor fixed wing the npfg switch distance is used for horizontal acceptance.", "max": 200.0, "min": 0.05, "name": "NAV_ACC_RAD", "shortDesc": "Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Mission", "name": "NAV_FORCE_VT", "shortDesc": "Force VTOL mode takeoff and land", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Mission", "longDesc": "Altitude acceptance used for the last waypoint before a fixed-wing landing. This is usually smaller\nthan the standard vertical acceptance because close to the ground higher accuracy is required.", "max": 200.0, "min": 0.05, "name": "NAV_FW_ALTL_RAD", "shortDesc": "FW Altitude Acceptance Radius before a landing", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Mission", "increment": 0.5, "longDesc": "Acceptance radius for fixedwing altitude.", "max": 200.0, "min": 0.05, "name": "NAV_FW_ALT_RAD", "shortDesc": "FW Altitude Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 80.0, "group": "Mission", "increment": 0.5, "longDesc": "Default value of loiter radius in fixed-wing mode (e.g. for Loiter mode).\nThe direction of the loiter can be set via the sign: A positive value for\nclockwise, negative for counter-clockwise.", "max": 10000.0, "min": -10000.0, "name": "NAV_LOITER_RAD", "shortDesc": "Loiter radius (FW only)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.8, "group": "Mission", "increment": 0.5, "longDesc": "Acceptance radius for multicopter altitude.", "max": 200.0, "min": 0.05, "name": "NAV_MC_ALT_RAD", "shortDesc": "MC Altitude Acceptance Radius", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 1.0, "longDesc": "Minimum height above ground the vehicle is allowed to descend to during Mission and RTL,\nexcluding landing commands.\nRequires a distance sensor to be set up.\nNote: only prevents the vehicle from descending further, but does not force it to climb.\nSet to a negative value to disable.", "min": -1.0, "name": "NAV_MIN_GND_DIST", "shortDesc": "Minimum height above ground during Mission and RTL", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Mission", "increment": 0.5, "longDesc": "This is the minimum altitude above Home the system will always obey in Loiter (Hold) mode if switched into this\nmode without specifying an altitude (e.g. through Loiter switch on RC).\nDoesn't affect Loiters that are part of Missions or that are entered through a reposition setpoint (\"Go to\").\nSet to a negative value to disable.", "min": -1.0, "name": "NAV_MIN_LTR_ALT", "shortDesc": "Minimum Loiter altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 1, "group": "Mission", "longDesc": "Enabling this will allow the system to respond\nto transponder data from e.g. ADSB transponders", "name": "NAV_TRAFF_AVOID", "shortDesc": "Set traffic avoidance mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Warn only", "value": 1}, {"description": "Return mode", "value": 2}, {"description": "Land mode", "value": 3}, {"description": "Position Hold mode", "value": 4}]}, {"category": "Standard", "default": 500.0, "group": "Mission", "longDesc": "Defines a crosstrack horizontal distance", "min": 500.0, "name": "NAV_TRAFF_A_HOR", "shortDesc": "Set NAV TRAFFIC AVOID horizontal distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 500.0, "group": "Mission", "max": 500.0, "min": 10.0, "name": "NAV_TRAFF_A_VER", "shortDesc": "Set NAV TRAFFIC AVOID vertical distance", "type": "Float", "units": "m"}, {"category": "Standard", "default": 60, "group": "Mission", "longDesc": "Minimum acceptable time until collsion.\nAssumes constant speed over 3d distance.", "max": 900000000, "min": 1, "name": "NAV_TRAFF_COLL_T", "shortDesc": "Estimated time until collision", "type": "Int32", "units": "s"}, {"category": "Standard", "default": 0, "group": "Mixer Output", "longDesc": "The air-mode enables the mixer to increase the total thrust of the multirotor\nin order to keep attitude and rate control even at low and high throttle.\nThis function should be disabled during tuning as it will help the controller\nto diverge if the closed-loop is unstable (i.e. the vehicle is not tuned yet).\nEnabling air-mode for yaw requires the use of an arming switch.", "name": "MC_AIRMODE", "shortDesc": "Multicopter air-mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Roll/Pitch", "value": 1}, {"description": "Roll/Pitch/Yaw", "value": 2}]}, {"category": "Standard", "default": 0, "group": "Mount", "longDesc": "Set to true for servo gimbal, false for passthrough.\nThis is required for a gimbal which is not capable of stabilizing itself\nand relies on the IMU's attitude estimation.", "name": "MNT_DO_STAB", "shortDesc": "Stabilize the mount", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "Stabilize all axis", "value": 1}, {"description": "Stabilize yaw for absolute/lock mode.", "value": 2}, {"description": "Stabilize pitch for absolute/lock mode.", "value": 3}]}, {"category": "Standard", "decimalPlaces": 1, "default": 90.0, "group": "Mount", "max": 90.0, "min": -90.0, "name": "MNT_LND_P_MAX", "shortDesc": "Pitch maximum when landed", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -90.0, "group": "Mount", "max": 90.0, "min": -90.0, "name": "MNT_LND_P_MIN", "shortDesc": "Pitch minimum when landed", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_PITCH", "shortDesc": "Auxiliary channel to control pitch (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_ROLL", "shortDesc": "Auxiliary channel to control roll (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Mount", "max": 6, "min": 0, "name": "MNT_MAN_YAW", "shortDesc": "Auxiliary channel to control yaw (in AUX input or manual mode)", "type": "Int32", "values": [{"description": "Disable", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 154, "group": "Mount", "longDesc": "If MNT_MODE_OUT is MAVLink protocol v2, mount configure/control commands will be sent with this component ID.", "name": "MNT_MAV_COMPID", "shortDesc": "Mavlink Component ID of the mount", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "Mount", "longDesc": "If MNT_MODE_OUT is MAVLink gimbal protocol v1, mount configure/control commands will be sent with this target ID.", "name": "MNT_MAV_SYSID", "shortDesc": "Mavlink System ID of the mount", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 45.0, "group": "Mount", "longDesc": "Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX).", "name": "MNT_MAX_PITCH", "shortDesc": "Max positive angle of pitch setpoint (only in MNT_MODE_OUT=AUX)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": -45.0, "group": "Mount", "longDesc": "Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX).", "name": "MNT_MIN_PITCH", "shortDesc": "Min negative angle of pitch setpoint (only in MNT_MODE_OUT=AUX)", "type": "Float", "units": "deg"}, {"category": "Standard", "default": -1, "group": "Mount", "longDesc": "This is the protocol used between the ground station and the autopilot.\nRecommended is Auto, RC only or MAVLink gimbal protocol v2.\nThe rest will be deprecated.", "max": 4, "min": -1, "name": "MNT_MODE_IN", "rebootRequired": true, "shortDesc": "Mount input mode", "type": "Int32", "values": [{"description": "DISABLED", "value": -1}, {"description": "Auto (RC and MAVLink gimbal protocol v2)", "value": 0}, {"description": "RC", "value": 1}, {"description": "MAVLINK_ROI (protocol v1, to be deprecated)", "value": 2}, {"description": "MAVLINK_DO_MOUNT (protocol v1, to be deprecated)", "value": 3}, {"description": "MAVlink gimbal protocol v2", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Mount", "longDesc": "This is the protocol used between the autopilot and a connected gimbal.\nRecommended is the MAVLink gimbal protocol v2 if the gimbal supports it.", "max": 2, "min": 0, "name": "MNT_MODE_OUT", "rebootRequired": true, "shortDesc": "Mount output mode", "type": "Int32", "values": [{"description": "AUX", "value": 0}, {"description": "MAVLink gimbal protocol v1", "value": 1}, {"description": "MAVLink gimbal protocol v2", "value": 2}]}, {"category": "Standard", "decimalPlaces": 1, "default": 90.0, "group": "Mount", "longDesc": "Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). Note that only symmetric angular ranges are supported.", "max": 720.0, "min": 1.0, "name": "MNT_RANGE_ROLL", "shortDesc": "Range of roll channel output (only in MNT_MODE_OUT=AUX)", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 360.0, "group": "Mount", "longDesc": "Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). Note that only symmetric angular ranges are supported.", "max": 720.0, "min": 1.0, "name": "MNT_RANGE_YAW", "shortDesc": "Range of yaw channel output (only in MNT_MODE_OUT=AUX)", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 30.0, "group": "Mount", "longDesc": "Full stick input [-1..1] translats to [-pitch rate..pitch rate].", "max": 90.0, "min": 1.0, "name": "MNT_RATE_PITCH", "shortDesc": "Angular pitch rate for manual input in degrees/second", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 30.0, "group": "Mount", "longDesc": "Full stick input [-1..1] translats to [-yaw rate..yaw rate].", "max": 90.0, "min": 1.0, "name": "MNT_RATE_YAW", "shortDesc": "Angular yaw rate for manual input in degrees/second", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 1, "group": "Mount", "max": 1, "min": 0, "name": "MNT_RC_IN_MODE", "shortDesc": "Input mode for RC gimbal input", "type": "Int32", "values": [{"description": "Angle", "value": 0}, {"description": "Angular rate", "value": 1}]}, {"category": "Standard", "default": 0.3, "group": "Mount", "longDesc": "Use when no angular position feedback is available.\nWith MNT_MODE_OUT set to AUX, the mount operates in open-loop and directly commands the servo output.\nParameters must be tuned for the specific servo to approximate its speed and response.", "min": 0.0, "name": "MNT_TAU", "shortDesc": "Alpha filter time constant defining the convergence rate (in seconds) for open-loop AUX mount control", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "Exponential factor for tuning the input curve shape.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MC_ACRO_EXPO", "shortDesc": "Acro mode roll, pitch expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "Exponential factor for tuning the input curve shape.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "MC_ACRO_EXPO_Y", "shortDesc": "Acro mode yaw expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_P_MAX", "shortDesc": "Acro mode maximum pitch rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_R_MAX", "shortDesc": "Acro mode maximum roll rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "\"Superexponential\" factor for refining the input curve shape tuned using MC_ACRO_EXPO.\n0 Pure Expo function\n0.7 reasonable shape enhancement for intuitive stick feel\n0.95 very strong bent input curve only near maxima have effect", "max": 0.95, "min": 0.0, "name": "MC_ACRO_SUPEXPO", "shortDesc": "Acro mode roll, pitch super expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Acro Mode", "longDesc": "\"Superexponential\" factor for refining the input curve shape tuned using MC_ACRO_EXPO_Y.\n0 Pure Expo function\n0.7 reasonable shape enhancement for intuitive stick feel\n0.95 very strong bent input curve only near maxima have effect", "max": 0.95, "min": 0.0, "name": "MC_ACRO_SUPEXPOY", "shortDesc": "Acro mode yaw super expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 100.0, "group": "Multicopter Acro Mode", "increment": 5.0, "longDesc": "Full stick deflection leads to this rate.", "max": 1800.0, "min": 0.0, "name": "MC_ACRO_Y_MAX", "shortDesc": "Acro mode maximum yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 220.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limit for pitch rate in manual and auto modes (except acro).\nHas effect for large rotations in autonomous mode, to avoid large control\noutput and mixer saturation.\nThis is not only limited by the vehicle's properties, but also by the maximum\nmeasurement rate of the gyro.", "max": 1800.0, "min": 0.0, "name": "MC_PITCHRATE_MAX", "shortDesc": "Max pitch rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Pitch proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 12.0, "min": 0.0, "name": "MC_PITCH_P", "shortDesc": "Pitch P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 220.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limit for roll rate in manual and auto modes (except acro).\nHas effect for large rotations in autonomous mode, to avoid large control\noutput and mixer saturation.\nThis is not only limited by the vehicle's properties, but also by the maximum\nmeasurement rate of the gyro.", "max": 1800.0, "min": 0.0, "name": "MC_ROLLRATE_MAX", "shortDesc": "Max roll rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Roll proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 12.0, "min": 0.0, "name": "MC_ROLL_P", "shortDesc": "Roll P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 200.0, "group": "Multicopter Attitude Control", "increment": 5.0, "max": 1800.0, "min": 0.0, "name": "MC_YAWRATE_MAX", "shortDesc": "Max yaw rate", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.8, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "Yaw proportional gain, i.e. desired angular speed in rad/s for error 1 rad.", "max": 5.0, "min": 0.0, "name": "MC_YAW_P", "shortDesc": "Yaw P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "Multicopter Attitude Control", "increment": 0.1, "longDesc": "A fraction [0,1] deprioritizing yaw compared to roll and pitch in non-linear attitude control.\nDeprioritizing yaw is necessary because multicopters have much less control authority\nin yaw compared to the other axes and it makes sense because yaw is not critical for\nstable hovering or 3D navigation.\nFor yaw control tuning use MC_YAW_P. This ratio has no impact on the yaw gain.", "max": 1.0, "min": 0.0, "name": "MC_YAW_WEIGHT", "shortDesc": "Yaw weight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 0, "default": 20.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limits the acceleration of the yaw setpoint to avoid large\ncontrol output and mixer saturation.", "max": 360.0, "min": 5.0, "name": "MPC_YAWRAUTO_ACC", "shortDesc": "Maximum yaw acceleration in autonomous modes", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 0, "default": 60.0, "group": "Multicopter Attitude Control", "increment": 5.0, "longDesc": "Limits the rate of change of the yaw setpoint to avoid large\ncontrol output and mixer saturation.", "max": 360.0, "min": 5.0, "name": "MPC_YAWRAUTO_MAX", "shortDesc": "Maximum yaw rate in autonomous modes", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0.4, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "max": 1.0, "min": 0.0, "name": "CP_DELAY", "shortDesc": "Average delay of the range sensor message plus the tracking delay of the position controller in seconds", "type": "Float", "units": "s"}, {"category": "Standard", "default": -1.0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode. Collision avoidance is disabled by setting this parameter to a negative value", "max": 15.0, "min": -1.0, "name": "CP_DIST", "shortDesc": "Minimum distance the vehicle should keep to all obstacles", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "name": "CP_GO_NO_DATA", "shortDesc": "Boolean to allow moving into directions where there is no sensor data (outside FOV)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 30.0, "group": "Multicopter Position Control", "longDesc": "Only used in Position mode.", "max": 90.0, "min": 0.0, "name": "CP_GUIDE_ANG", "shortDesc": "Angle left/right from the commanded setpoint by which the collision prevention algorithm can choose to change the setpoint direction", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Position Control", "longDesc": "Setting this parameter to 0 disables the filter", "max": 2.0, "min": 0.0, "name": "MC_MAN_TILT_TAU", "shortDesc": "Manual tilt input filter time constant", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "Multicopter Position Control", "longDesc": "Set to decouple tilt from vertical acceleration.\nThis provides smoother flight but slightly worse tracking in position and auto modes.\nUnset if accurate position tracking during dynamic maneuvers is more important than a smooth flight.", "name": "MPC_ACC_DECOUPLE", "shortDesc": "Acceleration to tilt coupling", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 15.0, "min": 2.0, "name": "MPC_ACC_DOWN_MAX", "shortDesc": "Maximum downwards acceleration in climb rate controlled modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "When piloting manually, this parameter is only used in MPC_POS_MODE Acceleration based.", "max": 15.0, "min": 2.0, "name": "MPC_ACC_HOR", "shortDesc": "Acceleration for autonomous and for manual modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "MPC_POS_MODE\n1 just deceleration\n4 not used, use MPC_ACC_HOR instead", "max": 15.0, "min": 2.0, "name": "MPC_ACC_HOR_MAX", "shortDesc": "Maximum horizontal acceleration", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 15.0, "min": 2.0, "name": "MPC_ACC_UP_MAX", "shortDesc": "Maximum upwards acceleration in climb rate controlled modes", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "default": 2, "group": "Multicopter Position Control", "longDesc": "Control height\n0: relative earth frame origin which may drift due to sensors\n1: relative to ground (requires distance sensor) which changes with terrain variation.\nIt will revert to relative earth frame if the distance to ground estimate becomes invalid.\n2: relative to ground (requires distance sensor) when stationary\nand relative to earth frame when moving horizontally.\nThe speed threshold is MPC_HOLD_MAX_XY", "max": 2, "min": 0, "name": "MPC_ALT_MODE", "shortDesc": "Altitude reference mode", "type": "Int32", "values": [{"description": "Altitude following", "value": 0}, {"description": "Terrain following", "value": 1}, {"description": "Terrain hold", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.8, "group": "Multicopter Position Control", "longDesc": "Only used with MPC_POS_MODE Direct velocity or MPC_ALT_MODE 2", "max": 3.0, "min": 0.0, "name": "MPC_HOLD_MAX_XY", "shortDesc": "Maximum horizontal velocity for which position hold is enabled (use 0 to disable check)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.6, "group": "Multicopter Position Control", "longDesc": "Only used with MPC_ALT_MODE 1", "max": 3.0, "min": 0.0, "name": "MPC_HOLD_MAX_Z", "shortDesc": "Maximum vertical velocity for which position hold is enabled (use 0 to disable check)", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 4.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Limit the maximum jerk of the vehicle (how fast the acceleration can change).\nA lower value leads to smoother vehicle motions but also limited agility.", "max": 80.0, "min": 1.0, "name": "MPC_JERK_AUTO", "shortDesc": "Jerk limit in autonomous modes", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 0, "default": 8.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Limit the maximum jerk (acceleration change) of the vehicle.\nA lower value leads to smoother motions but limits agility.\nSetting this to the maximum value essentially disables the limit.\nOnly used with MPC_POS_MODE Acceleration based.", "max": 500.0, "min": 0.5, "name": "MPC_JERK_MAX", "shortDesc": "Maximum horizontal and vertical jerk in Position/Altitude mode", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Multicopter Position Control", "longDesc": "Below this altitude descending velocity gets limited to a value\nbetween \"MPC_Z_VEL_MAX_DN\" (or \"MPC_Z_V_AUTO_DN\") and \"MPC_LAND_SPEED\"\nValue needs to be higher than \"MPC_LAND_ALT2\"", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT1", "shortDesc": "Altitude for 1. step of slow landing (descend)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "longDesc": "Below this altitude descending velocity gets\nlimited to \"MPC_LAND_SPEED\"\nValue needs to be lower than \"MPC_LAND_ALT1\"", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT2", "shortDesc": "Altitude for 2. step of slow landing (landing)", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Multicopter Position Control", "longDesc": "If a valid distance sensor measurement to the ground is available,\nlimit descending velocity to \"MPC_LAND_CRWL\" below this altitude.", "max": 122.0, "min": 0.0, "name": "MPC_LAND_ALT3", "shortDesc": "Altitude for 3. step of slow landing", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.3, "group": "Multicopter Position Control", "longDesc": "Used below MPC_LAND_ALT3 if distance sensor data is availabe.", "min": 0.1, "name": "MPC_LAND_CRWL", "shortDesc": "Land crawl descend rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": -1.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "When nudging is enabled (see MPC_LAND_RC_HELP), this defines the maximum\nallowed horizontal displacement from the original landing point.\n- If inside of the radius, only allow nudging inputs that do not move the vehicle outside of it.\n- If outside of the radius, only allow nudging inputs that move the vehicle back towards it.\nSet it to -1 for infinite radius.", "min": -1.0, "name": "MPC_LAND_RADIUS", "shortDesc": "User assisted landing radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Using stick input the vehicle can be moved horizontally and yawed.\nThe descend speed is amended:\nstick full up - 0\nstick centered - MPC_LAND_SPEED\nstick full down - 2 * MPC_LAND_SPEED\nManual override during auto modes has to be disabled to use this feature (see COM_RC_OVERRIDE).", "max": 1, "min": 0, "name": "MPC_LAND_RC_HELP", "shortDesc": "Enable nudging based on user input during autonomous land routine", "type": "Int32", "values": [{"description": "Nudging disabled", "value": 0}, {"description": "Nudging enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.7, "group": "Multicopter Position Control", "min": 0.6, "name": "MPC_LAND_SPEED", "shortDesc": "Landing descend rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "The value is mapped to the lowest throttle stick position in Stabilized mode.\nToo low collective thrust leads to loss of roll/pitch/yaw torque control authority.\nAirmode is used to keep torque authority with zero thrust (see MC_AIRMODE).", "max": 1.0, "min": 0.0, "name": "MPC_MANTHR_MIN", "shortDesc": "Minimum collective thrust in Stabilized mode", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 0, "default": 35.0, "group": "Multicopter Position Control", "increment": 1.0, "max": 70.0, "min": 1.0, "name": "MPC_MAN_TILT_MAX", "shortDesc": "Maximal tilt angle in Stabilized, Altitude and Altitude Cruise mode", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 150.0, "group": "Multicopter Position Control", "increment": 10.0, "max": 400.0, "min": 0.0, "name": "MPC_MAN_Y_MAX", "shortDesc": "Max manual yaw rate for Stabilized, Altitude, Position mode", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Not used in Stabilized mode\nSetting this parameter to 0 disables the filter", "max": 5.0, "min": 0.0, "name": "MPC_MAN_Y_TAU", "shortDesc": "Manual yaw rate input filter time constant", "type": "Float", "units": "s"}, {"category": "Standard", "default": 4, "group": "Multicopter Position Control", "longDesc": "The supported sub-modes are:\nDirect velocity:\nSticks directly map to velocity setpoints without smoothing.\nAlso applies to vertical direction and Altitude mode.\nUseful for velocity control tuning.\nAcceleration based:\nSticks map to acceleration and there's a virtual brake drag", "name": "MPC_POS_MODE", "shortDesc": "Position/Altitude mode variant", "type": "Int32", "values": [{"description": "Direct velocity", "value": 0}, {"description": "Acceleration based", "value": 4}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "longDesc": "Defines how the throttle stick is mapped to collective thrust in Stabilized mode.\nRescale to hover thrust estimate:\nStick input is linearly rescaled, such that a centered throttle stick corresponds to the hover thrust estimator's output.\nNo rescale:\nDirectly map the stick 1:1 to the output.\nCan be useful with very low hover thrust which leads to much distortion and the upper half getting sensitive.\nRescale to hover thrust parameter:\nSimilar to rescaling to the hover thrust estimate, but it uses the hover thrust parameter value (see MPC_THR_HOVER) instead of estimated value.\nWith MPC_THR_HOVER 0.5 it's equivalent to No rescale.", "name": "MPC_THR_CURVE", "shortDesc": "Thrust curve mapping in Stabilized Mode", "type": "Int32", "values": [{"description": "Rescale to estimate", "value": 0}, {"description": "No rescale", "value": 1}, {"description": "Rescale to parameter", "value": 2}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Mapped to center throttle stick in Stabilized mode (see MPC_THR_CURVE).\nUsed for initialization of the hover thrust estimator (see MPC_USE_HTE).\nThe estimated hover thrust is used as base for zero vertical acceleration in altitude control.\nThe hover thrust is important for land detection to work correctly.", "max": 0.8, "min": 0.1, "name": "MPC_THR_HOVER", "shortDesc": "Vertical thrust required to hover", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Control", "increment": 0.05, "longDesc": "Limit allowed thrust e.g. for indoor test of overpowered vehicle.", "max": 1.0, "min": 0.0, "name": "MPC_THR_MAX", "shortDesc": "Maximum collective thrust in climb rate controlled modes", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.12, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Too low thrust leads to loss of roll/pitch/yaw torque control authority.\nWith airmode enabled this parameters can be set to 0\nwhile still keeping torque authority (see MC_AIRMODE).", "max": 0.5, "min": 0.05, "name": "MPC_THR_MIN", "shortDesc": "Minimum collective thrust in climb rate controlled modes", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Control", "increment": 0.01, "longDesc": "Margin that is kept for horizontal control when higher priority vertical thrust is saturated.\nTo avoid completely starving horizontal control with high vertical error.", "max": 0.5, "min": 0.0, "name": "MPC_THR_XY_MARG", "shortDesc": "Horizontal thrust margin", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 0, "default": 45.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Absolute maximum for all velocity or acceleration controlled modes.\nAny higher value is truncated.", "max": 89.0, "min": 20.0, "name": "MPC_TILTMAX_AIR", "shortDesc": "Maximum tilt angle in air", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 0, "default": 12.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Tighter tilt limit during takeoff to avoid tip over.", "max": 89.0, "min": 5.0, "name": "MPC_TILTMAX_LND", "shortDesc": "Maximum tilt during inital takeoff ramp", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 3.0, "group": "Multicopter Position Control", "longDesc": "Increasing this value will make climb rate controlled takeoff slower.\nIf it's too slow the drone might scratch the ground and tip over.\nA time constant of 0 disables the ramp", "max": 5.0, "min": 0.0, "name": "MPC_TKO_RAMP_T", "shortDesc": "Smooth takeoff ramp time constant", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.5, "group": "Multicopter Position Control", "max": 5.0, "min": 1.0, "name": "MPC_TKO_SPEED", "shortDesc": "Takeoff climb rate", "type": "Float", "units": "m/s"}, {"category": "Standard", "default": 1, "group": "Multicopter Position Control", "longDesc": "Disable to use the fixed parameter MPC_THR_HOVER instead of the hover thrust estimate in the position controller.\nThis parameter does not influence Stabilized mode throttle curve (see MPC_THR_CURVE).", "name": "MPC_USE_HTE", "shortDesc": "Use hover thrust estimate for altitude control", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VELD_LP", "shortDesc": "Velocity derivative low pass cutoff frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_LP", "shortDesc": "Velocity low pass cutoff frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Must be smaller than MPC_XY_VEL_MAX.\nThe maximum sideways and backward speed can be set differently\nusing MPC_VEL_MAN_SIDE and MPC_VEL_MAN_BACK, respectively.", "max": 20.0, "min": 3.0, "name": "MPC_VEL_MANUAL", "shortDesc": "Maximum horizontal velocity setpoint in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a negative value or larger than\nMPC_VEL_MANUAL then MPC_VEL_MANUAL is used.", "max": 20.0, "min": -1.0, "name": "MPC_VEL_MAN_BACK", "shortDesc": "Maximum backward velocity in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a negative value or larger than\nMPC_VEL_MANUAL then MPC_VEL_MANUAL is used.", "max": 20.0, "min": -1.0, "name": "MPC_VEL_MAN_SIDE", "shortDesc": "Maximum sideways velocity in Position mode", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "A value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_NF_BW", "shortDesc": "Velocity notch filter bandwidth", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "The center frequency for the 2nd order notch filter on the velocity.\nA value of 0 disables the filter.", "max": 50.0, "min": 0.0, "name": "MPC_VEL_NF_FRQ", "shortDesc": "Velocity notch filter frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 0, "default": 5.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "e.g. in Missions, RTL, Goto if the waypoint does not specify differently", "max": 20.0, "min": 3.0, "name": "MPC_XY_CRUISE", "shortDesc": "Default horizontal velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "The integration speed of the trajectory setpoint is linearly\nreduced with the horizontal position tracking error. When the\nerror is above this parameter, the integration of the\ntrajectory is stopped to wait for the drone.\nThis value can be adjusted depending on the tracking\ncapabilities of the vehicle.", "max": 10.0, "min": 0.1, "name": "MPC_XY_ERR_MAX", "shortDesc": "Maximum horizontal error allowed by the trajectory generator", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.95, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective velocity in m/s per m position error", "max": 2.0, "min": 0.0, "name": "MPC_XY_P", "shortDesc": "Proportional gain for horizontal position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.5, "group": "Multicopter Position Control", "increment": 0.1, "max": 1.0, "min": 0.1, "name": "MPC_XY_TRAJ_P", "shortDesc": "Proportional gain for horizontal trajectory position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": -10.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "If set to a value greater than zero, other parameters are automatically set (such as\nMPC_XY_VEL_MAX or MPC_VEL_MANUAL).\nIf set to a negative value, the existing individual parameters are used.", "max": 20.0, "min": -20.0, "name": "MPC_XY_VEL_ALL", "shortDesc": "Overall Horizontal Velocity Limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s^2 velocity derivative", "max": 2.0, "min": 0.1, "name": "MPC_XY_VEL_D_ACC", "shortDesc": "Differential gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.4, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as correction acceleration in m/s^2 per m velocity integral\nAllows to eliminate steady state errors in disturbances like wind.", "max": 60.0, "min": 0.0, "name": "MPC_XY_VEL_I_ACC", "shortDesc": "Integral gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 12.0, "group": "Multicopter Position Control", "increment": 1.0, "longDesc": "Absolute maximum for all velocity controlled modes.\nAny higher value is truncated.", "max": 20.0, "min": 0.0, "name": "MPC_XY_VEL_MAX", "shortDesc": "Maximum horizontal velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.8, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s velocity error", "max": 5.0, "min": 1.2, "name": "MPC_XY_VEL_P_ACC", "shortDesc": "Proportional gain for horizontal velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective velocity in m/s per m position error", "max": 1.5, "min": 0.1, "name": "MPC_Z_P", "shortDesc": "Proportional gain for vertical position error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": -3.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "If set to a value greater than zero, other parameters are automatically set (such as\nMPC_Z_VEL_MAX_UP or MPC_LAND_SPEED).\nIf set to a negative value, the existing individual parameters are used.", "max": 8.0, "min": -3.0, "name": "MPC_Z_VEL_ALL", "shortDesc": "Overall Vertical Velocity Limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Multicopter Position Control", "increment": 0.02, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s^2 velocity derivative", "max": 2.0, "min": 0.0, "name": "MPC_Z_VEL_D_ACC", "shortDesc": "Differential gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m velocity integral", "max": 3.0, "min": 0.2, "name": "MPC_Z_VEL_I_ACC", "shortDesc": "Integral gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Absolute maximum for all climb rate controlled modes.\nIn manually piloted modes full stick deflection commands this velocity.\nFor default autonomous velocity see MPC_Z_V_AUTO_UP", "max": 4.0, "min": 0.5, "name": "MPC_Z_VEL_MAX_DN", "shortDesc": "Maximum descent velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Absolute maximum for all climb rate controlled modes.\nIn manually piloted modes full stick deflection commands this velocity.\nFor default autonomous velocity see MPC_Z_V_AUTO_UP", "max": 8.0, "min": 0.5, "name": "MPC_Z_VEL_MAX_UP", "shortDesc": "Maximum ascent velocity", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "Multicopter Position Control", "increment": 0.1, "longDesc": "Defined as corrective acceleration in m/s^2 per m/s velocity error", "max": 15.0, "min": 2.0, "name": "MPC_Z_VEL_P_ACC", "shortDesc": "Proportional gain for vertical velocity error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.5, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "For manual modes and offboard, see MPC_Z_VEL_MAX_DN", "max": 4.0, "min": 0.5, "name": "MPC_Z_V_AUTO_DN", "shortDesc": "Descent velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "Multicopter Position Control", "increment": 0.5, "longDesc": "For manually controlled modes and offboard see MPC_Z_VEL_MAX_UP", "max": 8.0, "min": 0.5, "name": "MPC_Z_V_AUTO_UP", "shortDesc": "Ascent velocity in autonomous modes", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": -0.4, "group": "Multicopter Position Control", "increment": 0.05, "longDesc": "Changes the overall responsiveness of the vehicle.\nThe higher the value, the faster the vehicle will react.\nIf set to a value greater than zero, other parameters are automatically set (such as\nthe acceleration or jerk limits).\nIf set to a negative value, the existing individual parameters are used.", "max": 1.0, "min": -1.0, "name": "SYS_VEHICLE_RESP", "shortDesc": "Responsiveness", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Control", "name": "WV_EN", "shortDesc": "Enable weathervane", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1.0, "group": "Multicopter Position Control", "max": 5.0, "min": 0.0, "name": "WV_ROLL_MIN", "shortDesc": "Minimum roll angle setpoint for weathervane controller to demand a yaw-rate", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 90.0, "group": "Multicopter Position Control", "max": 120.0, "min": 0.0, "name": "WV_YRATE_MAX", "shortDesc": "Maximum yawrate the weathervane controller is allowed to demand", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 0.1, "name": "MC_SLOW_DEF_HVEL", "shortDesc": "Default horizontal velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 0.1, "name": "MC_SLOW_DEF_VVEL", "shortDesc": "Default vertical velocity limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 45.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "This value is used in slow mode if\nno aux channel is mapped and\nno limit is commanded through MAVLink.", "min": 1.0, "name": "MC_SLOW_DEF_YAWR", "shortDesc": "Default yaw rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_HVEL", "shortDesc": "Manual input mapped to scale horizontal velocity in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_PTCH", "shortDesc": "RC_MAP_AUX{N} to allow for gimbal pitch rate control in position slow mode", "type": "Int32", "values": [{"description": "No pitch rate input", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_VVEL", "shortDesc": "Manual input mapped to scale vertical velocity in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "default": 0, "group": "Multicopter Position Slow Mode", "name": "MC_SLOW_MAP_YAWR", "shortDesc": "Manual input mapped to scale yaw rate in position slow mode", "type": "Int32", "values": [{"description": "No rescaling", "value": 0}, {"description": "AUX1", "value": 1}, {"description": "AUX2", "value": 2}, {"description": "AUX3", "value": 3}, {"description": "AUX4", "value": 4}, {"description": "AUX5", "value": 5}, {"description": "AUX6", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this velocity.", "min": 0.1, "name": "MC_SLOW_MIN_HVEL", "shortDesc": "Horizontal velocity lower limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this velocity.", "min": 0.1, "name": "MC_SLOW_MIN_VVEL", "shortDesc": "Vertical velocity lower limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 0, "default": 3.0, "group": "Multicopter Position Slow Mode", "increment": 0.1, "longDesc": "The lowest input maps and is clamped to this rate.", "min": 1.0, "name": "MC_SLOW_MIN_YAWR", "shortDesc": "Yaw rate lower limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "default": 0, "group": "Multicopter Rate Control", "longDesc": "This compensates for voltage drop of the battery over time by attempting to\nnormalize performance across the operating range of the battery. The copter\nshould constantly behave as if it was fully charged with reduced max acceleration\nat lower battery percentages. i.e. if hover is at 0.5 throttle at 100% battery,\nit will still be 0.5 at 60% battery.", "name": "MC_BAT_SCALE_EN", "shortDesc": "Battery power level scaler", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 4, "default": 0.003, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Pitch rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "min": 0.0, "name": "MC_PITCHRATE_D", "shortDesc": "Pitch rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_PITCHRATE_FF", "shortDesc": "Pitch rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_PITCHRATE_I", "shortDesc": "Pitch rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_PITCHRATE_K * (MC_PITCHRATE_P * error\n+ MC_PITCHRATE_I * error_integral\n+ MC_PITCHRATE_D * error_derivative)\nSet MC_PITCHRATE_P=1 to implement a PID in the ideal form.\nSet MC_PITCHRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.01, "name": "MC_PITCHRATE_K", "shortDesc": "Pitch rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.6, "min": 0.01, "name": "MC_PITCHRATE_P", "shortDesc": "Pitch rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Pitch rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large pitch moment trim changes.", "min": 0.0, "name": "MC_PR_INT_LIM", "shortDesc": "Pitch rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.003, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Roll rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "max": 0.01, "min": 0.0, "name": "MC_ROLLRATE_D", "shortDesc": "Roll rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_ROLLRATE_FF", "shortDesc": "Roll rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_ROLLRATE_I", "shortDesc": "Roll rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_ROLLRATE_K * (MC_ROLLRATE_P * error\n+ MC_ROLLRATE_I * error_integral\n+ MC_ROLLRATE_D * error_derivative)\nSet MC_ROLLRATE_P=1 to implement a PID in the ideal form.\nSet MC_ROLLRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.01, "name": "MC_ROLLRATE_K", "shortDesc": "Roll rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.15, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.5, "min": 0.01, "name": "MC_ROLLRATE_P", "shortDesc": "Roll rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Roll rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large roll moment trim changes.", "min": 0.0, "name": "MC_RR_INT_LIM", "shortDesc": "Roll rate integrator limit", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Yaw rate differential gain. Small values help reduce fast oscillations. If value is too big oscillations will appear again.", "min": 0.0, "name": "MC_YAWRATE_D", "shortDesc": "Yaw rate D gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Multicopter Rate Control", "longDesc": "Improves tracking performance.", "min": 0.0, "name": "MC_YAWRATE_FF", "shortDesc": "Yaw rate feedforward", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate integral gain. Can be set to compensate static thrust difference or gravity center offset.", "min": 0.0, "name": "MC_YAWRATE_I", "shortDesc": "Yaw rate I gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 4, "default": 1.0, "group": "Multicopter Rate Control", "increment": 0.0005, "longDesc": "Global gain of the controller.\nThis gain scales the P, I and D terms of the controller:\noutput = MC_YAWRATE_K * (MC_YAWRATE_P * error\n+ MC_YAWRATE_I * error_integral\n+ MC_YAWRATE_D * error_derivative)\nSet MC_YAWRATE_P=1 to implement a PID in the ideal form.\nSet MC_YAWRATE_K=1 to implement a PID in the parallel form.", "max": 5.0, "min": 0.01, "name": "MC_YAWRATE_K", "shortDesc": "Yaw rate controller gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.2, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate proportional gain, i.e. control output for angular speed error 1 rad/s.", "max": 0.6, "min": 0.0, "name": "MC_YAWRATE_P", "shortDesc": "Yaw rate P gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 2.0, "group": "Multicopter Rate Control", "longDesc": "Reduces vibrations by lowering high frequency torque caused by rotor acceleration.\n0 disables the filter", "max": 10.0, "min": 0.0, "name": "MC_YAW_TQ_CUTOFF", "shortDesc": "Low pass filter cutoff frequency for yaw torque setpoint", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "Multicopter Rate Control", "increment": 0.01, "longDesc": "Yaw rate integrator limit. Can be set to increase the amount of integrator available to counteract disturbances or reduced to improve settling time after large yaw moment trim changes.", "min": 0.0, "name": "MC_YR_INT_LIM", "shortDesc": "Yaw rate integrator limit", "type": "Float"}, {"category": "Standard", "default": 0, "group": "OSD", "longDesc": "Controls the vertical position of the crosshair display.\nResolution is limited by OSD to 15 discrete values. Negative\nvalues will display the crosshairs below the horizon", "max": 8, "min": -8, "name": "OSD_CH_HEIGHT", "shortDesc": "OSD Crosshairs Height", "type": "Int32"}, {"category": "Standard", "default": 500, "group": "OSD", "longDesc": "Amount of time in milliseconds to dwell at the beginning of the display, when scrolling.", "max": 10000, "min": 100, "name": "OSD_DWELL_TIME", "shortDesc": "OSD Dwell Time (ms)", "type": "Int32"}, {"category": "Standard", "default": 3, "group": "OSD", "longDesc": "Minimum security of log level to display on the OSD.", "name": "OSD_LOG_LEVEL", "shortDesc": "OSD Warning Level", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "OSD", "longDesc": "Forward RC stick input to VTX when disarmed", "max": 1, "min": 0, "name": "OSD_RC_STICK", "shortDesc": "OSD RC Stick commands", "type": "Int32"}, {"category": "Standard", "default": 125, "group": "OSD", "longDesc": "Scroll rate in milliseconds for OSD messages longer than available character width.\nThis is lower-bounded by the nominal loop rate of this module.", "max": 1000, "min": 100, "name": "OSD_SCROLL_RATE", "shortDesc": "OSD Scroll Rate (ms)", "type": "Int32"}, {"bitmask": [{"description": "CRAFT_NAME", "index": 0}, {"description": "DISARMED", "index": 1}, {"description": "GPS_LAT", "index": 2}, {"description": "GPS_LON", "index": 3}, {"description": "GPS_SATS", "index": 4}, {"description": "GPS_SPEED", "index": 5}, {"description": "HOME_DIST", "index": 6}, {"description": "HOME_DIR", "index": 7}, {"description": "MAIN_BATT_VOLTAGE", "index": 8}, {"description": "CURRENT_DRAW", "index": 9}, {"description": "MAH_DRAWN", "index": 10}, {"description": "RSSI_VALUE", "index": 11}, {"description": "ALTITUDE", "index": 12}, {"description": "NUMERICAL_VARIO", "index": 13}, {"description": "(unused) FLYMODE", "index": 14}, {"description": "(unused) ESC_TMP", "index": 15}, {"description": "(unused) PITCH_ANGLE", "index": 16}, {"description": "(unused) ROLL_ANGLE", "index": 17}, {"description": "CROSSHAIRS", "index": 18}, {"description": "AVG_CELL_VOLTAGE", "index": 19}, {"description": "(unused) HORIZON_SIDEBARS", "index": 20}, {"description": "POWER", "index": 21}], "category": "Standard", "default": 16383, "group": "OSD", "longDesc": "Configure / toggle support display options.", "max": 4194303, "min": 0, "name": "OSD_SYMBOLS", "shortDesc": "OSD Symbol Selection", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "PWM Outputs", "increment": 0.1, "longDesc": "Parameter used to model the nonlinear relationship between\nmotor control signal (e.g. PWM) and static thrust.\nThe model is: rel_thrust = factor * rel_signal^2 + (1-factor) * rel_signal,\nwhere rel_thrust is the normalized thrust between 0 and 1, and\nrel_signal is the relative motor control signal between 0 and 1.", "max": 1.0, "min": 0.0, "name": "THR_MDL_FAC", "shortDesc": "Thrust to motor control signal model parameter", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Payload Deliverer", "longDesc": "Maximum time Gripper will wait while the successful griper actuation isn't recognised.\nIf the gripper has no feedback sensor, it will simply wait for\nthis time before considering gripper actuation successful and publish a\n'VehicleCommandAck' signaling successful gripper action", "min": 0.0, "name": "PD_GRIPPER_TO", "shortDesc": "Timeout for successful gripper actuation acknowledgement", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Payload Deliverer", "max": 0, "min": -1, "name": "PD_GRIPPER_TYPE", "shortDesc": "Type of Gripper (Servo, etc.)", "type": "Int32", "values": [{"description": "Undefined", "value": -1}, {"description": "Servo", "value": 0}]}, {"category": "Standard", "decimalPlaces": 1, "default": 5.0, "group": "Precision Land", "increment": 0.5, "longDesc": "Time after which the landing target is considered lost without any new measurements.", "max": 50.0, "min": 0.0, "name": "PLD_BTOUT", "shortDesc": "Landing Target Timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Precision Land", "increment": 0.1, "longDesc": "Allow final approach (without horizontal positioning) if losing landing target closer than this to the ground.", "max": 10.0, "min": 0.0, "name": "PLD_FAPPR_ALT", "shortDesc": "Final approach altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Precision Land", "increment": 0.1, "longDesc": "Start descending if closer above landing target than this.", "max": 10.0, "min": 0.0, "name": "PLD_HACC_RAD", "shortDesc": "Horizontal acceptance radius", "type": "Float", "units": "m"}, {"category": "Standard", "default": 3, "group": "Precision Land", "longDesc": "Maximum number of times to search for the landing target if it is lost during the precision landing.", "max": 100, "min": 0, "name": "PLD_MAX_SRCH", "shortDesc": "Maximum number of search attempts", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Precision Land", "increment": 0.1, "longDesc": "Altitude above home to which to climb when searching for the landing target.", "max": 100.0, "min": 0.0, "name": "PLD_SRCH_ALT", "shortDesc": "Search altitude", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Precision Land", "increment": 0.1, "longDesc": "Time allowed to search for the landing target before falling back to normal landing.", "max": 100.0, "min": 0.0, "name": "PLD_SRCH_TOUT", "shortDesc": "Search timeout", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Pure Pursuit", "increment": 0.01, "longDesc": "Lower value -> More aggressive controller (beware overshoot/oscillations)", "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_GAIN", "shortDesc": "Tuning parameter for the pure pursuit controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "Pure Pursuit", "increment": 0.01, "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_MAX", "shortDesc": "Maximum lookahead distance for the pure pursuit controller", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Pure Pursuit", "increment": 0.01, "max": 100.0, "min": 0.1, "name": "PP_LOOKAHD_MIN", "shortDesc": "Minimum lookahead distance for the pure pursuit controller", "type": "Float", "units": "m"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC10_MAX", "shortDesc": "RC channel 10 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC10_MIN", "shortDesc": "RC channel 10 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC10_REV", "shortDesc": "RC channel 10 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC10_TRIM", "shortDesc": "RC channel 10 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC11_MAX", "shortDesc": "RC channel 11 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC11_MIN", "shortDesc": "RC channel 11 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC11_REV", "shortDesc": "RC channel 11 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC11_TRIM", "shortDesc": "RC channel 11 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC12_MAX", "shortDesc": "RC channel 12 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC12_MIN", "shortDesc": "RC channel 12 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC12_REV", "shortDesc": "RC channel 12 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC12_TRIM", "shortDesc": "RC channel 12 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC13_MAX", "shortDesc": "RC channel 13 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC13_MIN", "shortDesc": "RC channel 13 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC13_REV", "shortDesc": "RC channel 13 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC13_TRIM", "shortDesc": "RC channel 13 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC14_MAX", "shortDesc": "RC channel 14 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC14_MIN", "shortDesc": "RC channel 14 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC14_REV", "shortDesc": "RC channel 14 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC14_TRIM", "shortDesc": "RC channel 14 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC15_MAX", "shortDesc": "RC channel 15 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC15_MIN", "shortDesc": "RC channel 15 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC15_REV", "shortDesc": "RC channel 15 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC15_TRIM", "shortDesc": "RC channel 15 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC16_MAX", "shortDesc": "RC channel 16 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC16_MIN", "shortDesc": "RC channel 16 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC16_REV", "shortDesc": "RC channel 16 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC16_TRIM", "shortDesc": "RC channel 16 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC17_MAX", "shortDesc": "RC channel 17 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC17_MIN", "shortDesc": "RC channel 17 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC17_REV", "shortDesc": "RC channel 17 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC17_TRIM", "shortDesc": "RC channel 17 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC18_MAX", "shortDesc": "RC channel 18 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC18_MIN", "shortDesc": "RC channel 18 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC18_REV", "shortDesc": "RC channel 18 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC18_TRIM", "shortDesc": "RC channel 18 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for RC channel 1", "max": 2200.0, "min": 1500.0, "name": "RC1_MAX", "shortDesc": "RC channel 1 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for RC channel 1", "max": 1500.0, "min": 800.0, "name": "RC1_MIN", "shortDesc": "RC channel 1 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC1_REV", "shortDesc": "RC channel 1 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC1_TRIM", "shortDesc": "RC channel 1 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC2_MAX", "shortDesc": "RC channel 2 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC2_MIN", "shortDesc": "RC channel 2 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC2_REV", "shortDesc": "RC channel 2 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC2_TRIM", "shortDesc": "RC channel 2 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC3_MAX", "shortDesc": "RC channel 3 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC3_MIN", "shortDesc": "RC channel 3 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC3_REV", "shortDesc": "RC channel 3 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC3_TRIM", "shortDesc": "RC channel 3 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC4_MAX", "shortDesc": "RC channel 4 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC4_MIN", "shortDesc": "RC channel 4 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC4_REV", "shortDesc": "RC channel 4 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC4_TRIM", "shortDesc": "RC channel 4 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC5_MAX", "shortDesc": "RC channel 5 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC5_MIN", "shortDesc": "RC channel 5 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC5_REV", "shortDesc": "RC channel 5 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC5_TRIM", "shortDesc": "RC channel 5 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC6_MAX", "shortDesc": "RC channel 6 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC6_MIN", "shortDesc": "RC channel 6 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC6_REV", "shortDesc": "RC channel 6 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC6_TRIM", "shortDesc": "RC channel 6 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC7_MAX", "shortDesc": "RC channel 7 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC7_MIN", "shortDesc": "RC channel 7 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC7_REV", "shortDesc": "RC channel 7 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC7_TRIM", "shortDesc": "RC channel 7 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC8_MAX", "shortDesc": "RC channel 8 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC8_MIN", "shortDesc": "RC channel 8 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC8_REV", "shortDesc": "RC channel 8 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC8_TRIM", "shortDesc": "RC channel 8 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 2000.0, "group": "Radio Calibration", "longDesc": "Maximum value for this channel.", "max": 2200.0, "min": 1500.0, "name": "RC9_MAX", "shortDesc": "RC channel 9 maximum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1000.0, "group": "Radio Calibration", "longDesc": "Minimum value for this channel.", "max": 1500.0, "min": 800.0, "name": "RC9_MIN", "shortDesc": "RC channel 9 minimum", "type": "Float", "units": "us"}, {"category": "Standard", "default": 1.0, "group": "Radio Calibration", "longDesc": "Set to -1 to reverse channel.", "max": 1.0, "min": -1.0, "name": "RC9_REV", "shortDesc": "RC channel 9 reverse", "type": "Float", "values": [{"description": "Reverse", "value": -1.0}, {"description": "Normal", "value": 1.0}]}, {"category": "Standard", "default": 1500.0, "group": "Radio Calibration", "longDesc": "Mid point value", "max": 2200.0, "min": 800.0, "name": "RC9_TRIM", "shortDesc": "RC channel 9 trim", "type": "Float", "units": "us"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "This parameter is used by Ground Station software to save the number\nof channels which were used during RC calibration. It is only meant\nfor ground station use.", "max": 18, "min": 0, "name": "RC_CHAN_CNT", "shortDesc": "RC channel count", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Use RC_MAP_FAILSAFE to specify which channel is used to indicate RC loss via this threshold.\nBy default this is the throttle channel.\nSet to a PWM value slightly above the PWM value for the channel (e.g. throttle) in a failsafe event,\nbut below the minimum PWM value for the channel during normal operation.\nNote: The default value of 0 disables the feature (it is below the expected range).", "max": 2200, "min": 0, "name": "RC_FAILS_THR", "shortDesc": "Failsafe channel PWM threshold", "type": "Int32", "units": "us"}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX1", "shortDesc": "AUX1 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX2", "shortDesc": "AUX2 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX3", "shortDesc": "AUX3 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX4", "shortDesc": "AUX4 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX5", "shortDesc": "AUX5 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_AUX6", "shortDesc": "AUX6 Passthrough RC channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "max": 18, "min": 0, "name": "RC_MAP_ENG_MOT", "shortDesc": "RC channel to engage the main motor (for helicopters)", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Configures which RC channel is used by the receiver to indicate the signal was lost\n(on receivers that use output a fixed signal value to report lost signal).\nIf set to 0, the channel mapped to throttle is used.\nUse RC_FAILS_THR to set the threshold indicating lost signal. By default it's below\nthe expected range and hence disabled.", "max": 18, "min": 0, "name": "RC_MAP_FAILSAFE", "shortDesc": "Failsafe channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 1st parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM1", "shortDesc": "PARAM1 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 2nd parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM2", "shortDesc": "PARAM2 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "Can be used for parameter tuning with the RC. This one is further referenced as the 3th parameter channel.\nSet to 0 to deactivate *", "max": 18, "min": 0, "name": "RC_MAP_PARAM3", "shortDesc": "PARAM3 tuning channel", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading pitch inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_PITCH", "shortDesc": "Pitch control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading roll inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_ROLL", "shortDesc": "Roll control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading throttle inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_THROTTLE", "shortDesc": "Throttle control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "The channel index (starting from 1 for channel 1) indicates\nwhich channel should be used for reading yaw inputs from.\nA value of zero indicates the switch is not assigned.", "max": 18, "min": 0, "name": "RC_MAP_YAW", "shortDesc": "Yaw control channel mapping", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 0, "group": "Radio Calibration", "longDesc": "0: do not read RSSI from input channel\n1-18: read RSSI from specified input channel\nSpecify the range for RSSI input with RC_RSSI_PWM_MIN and RC_RSSI_PWM_MAX parameters.", "max": 18, "min": 0, "name": "RC_RSSI_PWM_CHAN", "shortDesc": "PWM input channel that provides RSSI", "type": "Int32", "values": [{"description": "Unassigned", "value": 0}, {"description": "Channel 1", "value": 1}, {"description": "Channel 2", "value": 2}, {"description": "Channel 3", "value": 3}, {"description": "Channel 4", "value": 4}, {"description": "Channel 5", "value": 5}, {"description": "Channel 6", "value": 6}, {"description": "Channel 7", "value": 7}, {"description": "Channel 8", "value": 8}, {"description": "Channel 9", "value": 9}, {"description": "Channel 10", "value": 10}, {"description": "Channel 11", "value": 11}, {"description": "Channel 12", "value": 12}, {"description": "Channel 13", "value": 13}, {"description": "Channel 14", "value": 14}, {"description": "Channel 15", "value": 15}, {"description": "Channel 16", "value": 16}, {"description": "Channel 17", "value": 17}, {"description": "Channel 18", "value": 18}]}, {"category": "Standard", "default": 2000, "group": "Radio Calibration", "longDesc": "Only used if RC_RSSI_PWM_CHAN > 0", "max": 2000, "min": 0, "name": "RC_RSSI_PWM_MAX", "shortDesc": "Max input value for RSSI reading", "type": "Int32"}, {"category": "Standard", "default": 1000, "group": "Radio Calibration", "longDesc": "Only used if RC_RSSI_PWM_CHAN > 0", "max": 2000, "min": 0, "name": "RC_RSSI_PWM_MIN", "shortDesc": "Min input value for RSSI reading", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_PITCH", "shortDesc": "Pitch trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_ROLL", "shortDesc": "Roll trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Radio Calibration", "increment": 0.01, "longDesc": "The trim value is the actuator control value the system needs\nfor straight and level flight.", "max": 0.5, "min": -0.5, "name": "TRIM_YAW", "shortDesc": "Yaw trim", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.75, "group": "Radio Switches", "longDesc": "0-1 indicate where in the full channel range the threshold sits\n0 : min\n1 : max\nsign indicates polarity of comparison\npositive : true when channel>th\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channelth\nnegative : true when channel The rover starts to cut the corner earlier.", "max": 100.0, "min": 1.0, "name": "RA_ACC_RAD_GAIN", "shortDesc": "Tuning parameter for corner cutting", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Ackermann", "increment": 0.01, "longDesc": "The controller scales the acceptance radius based on the angle between\nthe previous, current and next waypoint.\nHigher value -> smoother trajectory at the cost of how close the rover gets\nto the waypoint (Set to -1 to disable corner cutting).", "max": 100.0, "min": -1.0, "name": "RA_ACC_RAD_MAX", "shortDesc": "Maximum acceptance radius for the waypoints", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Ackermann", "increment": 0.01, "max": 1.5708, "min": 0.0, "name": "RA_MAX_STR_ANG", "shortDesc": "Maximum steering angle", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Ackermann", "increment": 0.01, "longDesc": "Set to -1 to disable.", "max": 1000.0, "min": -1.0, "name": "RA_STR_RATE_LIM", "shortDesc": "Steering rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Ackermann", "increment": 0.001, "longDesc": "Distance from the front to the rear axle.", "max": 100.0, "min": 0.0, "name": "RA_WHEEL_BASE", "shortDesc": "Wheel base", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Attitude Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_P", "shortDesc": "Proportional gain for closed loop yaw controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.174533, "group": "Rover Differential", "increment": 0.01, "longDesc": "This threshold is used for the state machine to switch from driving to turning based on the\nerror between the desired and actual yaw. It is also used as the threshold whether the rover should come\nto a smooth stop at the next waypoint. This slow down effect is active if the angle between the\nline segments from prevWP-currWP and currWP-nextWP is smaller then 180 - RD_TRANS_DRV_TRN.", "max": 3.14159, "min": 0.001, "name": "RD_TRANS_DRV_TRN", "shortDesc": "Yaw error threshhold to switch from driving to spot turning", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0872665, "group": "Rover Differential", "increment": 0.01, "longDesc": "This threshold is used for the state machine to switch from turning to driving based on the\nerror between the desired and actual yaw.", "max": 3.14159, "min": 0.001, "name": "RD_TRANS_TRN_DRV", "shortDesc": "Yaw error threshhold to switch from spot turning to driving", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Differential", "increment": 0.001, "longDesc": "Distance from the center of the right wheel to the center of the left wheel.", "max": 100.0, "min": 0.0, "name": "RD_WHEEL_TRACK", "shortDesc": "Wheel track", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Rover Differential", "increment": 0.01, "longDesc": "Assign value <1.0 to decrease stick response for yaw control.", "max": 1.0, "min": 0.1, "name": "RD_YAW_STK_GAIN", "shortDesc": "Yaw stick gain for Manual mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.17, "group": "Rover Mecanum", "increment": 0.01, "longDesc": "Threshold for the angle between the active cruise direction and the cruise direction given\nby the stick inputs.\nThis can be understood as a deadzone for the combined stick inputs for forward/backwards\nand lateral speed which defines a course direction.", "max": 3.14, "min": 0.0, "name": "RM_COURSE_CTL_TH", "shortDesc": "Threshold to update course control in manual position mode", "type": "Float", "units": "rad"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Mecanum", "increment": 0.001, "longDesc": "Distance from the center of the right wheel to the center of the left wheel.", "max": 100.0, "min": 0.0, "name": "RM_WHEEL_TRACK", "shortDesc": "Wheel track", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "Rover Mecanum", "increment": 0.01, "longDesc": "Assign value <1.0 to decrease stick response for yaw control.", "max": 1.0, "min": 0.1, "name": "RM_YAW_STK_GAIN", "shortDesc": "Yaw stick gain for Manual mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap how quickly the magnitude of yaw rate setpoints can increase.\nSet to -1 to disable.", "max": 10000.0, "min": -1.0, "name": "RO_YAW_ACCEL_LIM", "shortDesc": "Yaw acceleration limit", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap how quickly the magnitude of yaw rate setpoints can decrease.\nSet to -1 to disable.", "max": 10000.0, "min": -1.0, "name": "RO_YAW_DECEL_LIM", "shortDesc": "Yaw deceleration limit", "type": "Float", "units": "deg/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Rate Control", "longDesc": "Exponential factor for tuning the input curve shape.\n0 Purely linear input curve\n1 Purely cubic input curve", "max": 1.0, "min": 0.0, "name": "RO_YAW_EXPO", "shortDesc": "Yaw rate expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Multiplicative correction factor for the feedforward mapping of the yaw rate controller.\nIncrease this value (x > 1) if the measured yaw rate is lower than the setpoint, decrease (0 < x < 1) otherwise.\nNote: Tuning this is particularly useful for skid-steered rovers, or rovers with misaligned wheels/steering axes\nthat cause a lot of friction when turning.", "max": 10000.0, "min": 0.01, "name": "RO_YAW_RATE_CORR", "shortDesc": "Yaw rate correction factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_I", "shortDesc": "Integral gain for closed loop yaw rate controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Used to cap yaw rate setpoints and map controller inputs to yaw rate setpoints\nin Acro, Stabilized and Position mode.", "max": 10000.0, "min": 0.0, "name": "RO_YAW_RATE_LIM", "shortDesc": "Yaw rate limit", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Rate Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_P", "shortDesc": "Proportional gain for closed loop yaw rate controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 3.0, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "The minimum threshold for the yaw rate measurement not to be interpreted as zero.", "max": 100.0, "min": 0.0, "name": "RO_YAW_RATE_TH", "shortDesc": "Yaw rate measurement threshold", "type": "Float", "units": "deg/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Rover Rate Control", "increment": 0.01, "longDesc": "Percentage of stick input range that will be interpreted as zero around the stick centered value.", "max": 1.0, "min": 0.0, "name": "RO_YAW_STICK_DZ", "shortDesc": "Yaw stick deadzone", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Rate Control", "longDesc": "\"Superexponential\" factor for refining the input curve shape tuned using RO_YAW_EXPO.\n0 Pure Expo function\n0.7 reasonable shape enhancement for intuitive stick feel\n0.95 very strong bent input curve only near maxima have effect", "max": 0.95, "min": 0.0, "name": "RO_YAW_SUPEXPO", "shortDesc": "Yaw rate super expo factor", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nFor mecanum rovers this limit is used for longitudinal and lateral acceleration.", "max": 100.0, "min": -1.0, "name": "RO_ACCEL_LIM", "shortDesc": "Acceleration limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nNote that if it is disabled the rover will not slow down when approaching waypoints in auto modes.\nFor mecanum rovers this limit is used for longitudinal and lateral deceleration.", "max": 100.0, "min": -1.0, "name": "RO_DECEL_LIM", "shortDesc": "Deceleration limit", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nNote that if it is disabled the rover will not slow down when approaching waypoints in auto modes.\nFor mecanum rovers this limit is used for longitudinal and lateral jerk.", "max": 100.0, "min": -1.0, "name": "RO_JERK_LIM", "shortDesc": "Jerk limit", "type": "Float", "units": "m/s^3"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Used to linearly map speeds [m/s] to throttle values [-1. 1].", "max": 100.0, "min": 0.0, "name": "RO_MAX_THR_SPEED", "shortDesc": "Speed the rover drives at maximum throttle", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.001, "max": 100.0, "min": 0.0, "name": "RO_SPEED_I", "shortDesc": "Integral gain for ground speed controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Used to cap speed setpoints and map controller inputs to speed setpoints in Position mode.", "max": 100.0, "min": -1.0, "name": "RO_SPEED_LIM", "shortDesc": "Speed limit", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.0, "group": "Rover Velocity Control", "increment": 0.01, "max": 100.0, "min": 0.0, "name": "RO_SPEED_P", "shortDesc": "Proportional gain for ground speed controller", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": -1.0, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Reduced_speed = RO_MAX_THR_SPEED * (1 - normalized_course_error * RO_SPEED_RED)\nThe normalized course error is the angle between the current course and the bearing setpoint\ninterpolated from [0, 180] -> [0, 1].\nHigher value -> More speed reduction.\nNote: This is also used to calculate the speed at which the vehicle arrives at a waypoint in auto modes.\nSet to -1 to disable bearing error based speed reduction.", "max": 100.0, "min": -1.0, "name": "RO_SPEED_RED", "shortDesc": "Tuning parameter for the speed reduction based on the course error", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "Rover Velocity Control", "increment": 0.01, "longDesc": "Set to -1 to disable.\nThe minimum threshold for the speed measurement not to be interpreted as zero.", "max": 100.0, "min": 0.0, "name": "RO_SPEED_TH", "shortDesc": "Speed measurement threshold", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Runway Takeoff", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "RWTO_MAX_THR", "shortDesc": "Throttle during runway takeoff", "type": "Float", "units": "norm"}, {"category": "Standard", "default": 1, "group": "Runway Takeoff", "longDesc": "This is useful when map, GNSS, or yaw errors on ground are misaligned with what the operator intends for takeoff course.\nParticularly useful for skinny runways or if the wheel servo is a bit off trim.", "name": "RWTO_NUDGE", "shortDesc": "Enable use of yaw stick for nudging the wheel during runway ground roll", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Runway Takeoff", "increment": 0.5, "longDesc": "A taildragger with steerable wheel might need to pitch up\na little to keep its wheel on the ground before airspeed\nto takeoff is reached.", "max": 20.0, "min": -10.0, "name": "RWTO_PSP", "shortDesc": "Pitch setpoint during taxi / before takeoff rotation airspeed is reached", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "Runway Takeoff", "increment": 0.1, "max": 15.0, "min": 1.0, "name": "RWTO_RAMP_TIME", "shortDesc": "Throttle ramp up time for runway takeoff", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": -1.0, "group": "Runway Takeoff", "increment": 0.1, "longDesc": "The calibrated airspeed threshold during the takeoff ground roll when the plane should start rotating (pitching up).\nMust be less than the takeoff airspeed, will otherwise be capped at the takeoff airpeed (see FW_TKO_AIRSPD).\nIf set <= 0.0, defaults to 0.9 * takeoff airspeed (see FW_TKO_AIRSPD)", "min": -1.0, "name": "RWTO_ROT_AIRSPD", "shortDesc": "Takeoff rotation airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "Runway Takeoff", "increment": 0.1, "longDesc": "This is the time desired to linearly ramp in takeoff pitch constraints during the takeoff rotation", "min": 0.1, "name": "RWTO_ROT_TIME", "shortDesc": "Takeoff rotation time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Runway Takeoff", "name": "RWTO_TKOFF", "shortDesc": "Runway takeoff with landing gear", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"bitmask": [{"description": "SD card logging", "index": 0}, {"description": "Mavlink logging", "index": 1}], "category": "Standard", "default": 3, "group": "SD Logging", "longDesc": "If no logging is set the logger will not be started. Set bits true to enable: 0: SD card logging 1: Mavlink logging", "max": 3, "min": 0, "name": "SDLOG_BACKEND", "rebootRequired": true, "shortDesc": "Logging Backend (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "When enabled, logging will not start from boot if battery power is not detected (e.g. powered via USB on a test bench). This prevents extraneous flight logs from being created during bench testing. Note that this only applies to log-from-boot modes. This has no effect on arm-based modes.", "name": "SDLOG_BOOT_BAT", "shortDesc": "Battery-only Logging", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "If there are more log directories than this value, the system will delete the oldest directories during startup. In addition, the system will delete old logs if there is not enough free space left. The minimum amount is 300 MB. If this is set to 0, old directories will only be removed if the free space falls below the minimum. Note: this does not apply to mission log files.", "max": 1000, "min": 0, "name": "SDLOG_DIRS_MAX", "rebootRequired": true, "shortDesc": "Maximum number of log directories to keep", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "If enabled, a small additional \"mission\" log file will be written to the SD card. The log contains just those messages that are useful for tasks like generating flight statistics and geotagging. The different modes can be used to further reduce the logged data (and thus the log file size). For example, choose geotagging mode to only log data required for geotagging. Note that the normal/full log is still created, and contains all the data in the mission log (and more).", "name": "SDLOG_MISSION", "rebootRequired": true, "shortDesc": "Mission Log", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "All mission messages", "value": 1}, {"description": "Geotagging messages", "value": 2}]}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "Determines when to start and stop logging. By default, logging is started when arming the system, and stopped when disarming. Note: The logging start/end points that can be configured here only apply to SD logging. The mavlink backend is started/stopped independently of these points.", "name": "SDLOG_MODE", "rebootRequired": true, "shortDesc": "Logging Mode", "type": "Int32", "values": [{"description": "when armed until disarm (default)", "value": 0}, {"description": "from boot until disarm", "value": 1}, {"description": "from boot until shutdown", "value": 2}, {"description": "while manual input AUX1 >30%", "value": 3}, {"description": "from 1st armed until shutdown", "value": 4}]}, {"bitmask": [{"description": "Default set (general log analysis)", "index": 0}, {"description": "Estimator replay (EKF2)", "index": 1}, {"description": "Thermal calibration", "index": 2}, {"description": "System identification", "index": 3}, {"description": "High rate", "index": 4}, {"description": "Debug", "index": 5}, {"description": "Sensor comparison", "index": 6}, {"description": "Computer Vision and Avoidance", "index": 7}, {"description": "Raw FIFO high-rate IMU (Gyro)", "index": 8}, {"description": "Raw FIFO high-rate IMU (Accel)", "index": 9}, {"description": "Mavlink tunnel message logging", "index": 10}, {"description": "High rate sensors", "index": 11}], "category": "Standard", "default": 1, "group": "SD Logging", "longDesc": "This integer bitmask controls the set and rates of logged topics. The default allows for general log analysis while keeping the log file size reasonably small. Enabling multiple sets leads to higher bandwidth requirements and larger log files. Set bits true to enable: 0 : Default set (used for general log analysis) 1 : Full rate estimator (EKF2) replay topics 2 : Topics for thermal calibration (high rate raw IMU and Baro sensor data) 3 : Topics for system identification (high rate actuator control and IMU data) 4 : Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators) 5 : Debugging topics (debug_*.msg topics, for custom code) 6 : Topics for sensor comparison (low rate raw IMU, Baro and magnetometer data) 7 : Topics for computer vision and collision prevention 8 : Raw FIFO high-rate IMU (Gyro) 9 : Raw FIFO high-rate IMU (Accel) 10: Logging of mavlink tunnel message (useful for payload communication debugging)", "max": 4095, "min": 0, "name": "SDLOG_PROFILE", "rebootRequired": true, "shortDesc": "Logging topic profile (integer bitmask)", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "SD Logging", "longDesc": "the difference in hours and minutes from Coordinated Universal Time (UTC) for a your place and date. for example, In case of South Korea(UTC+09:00), UTC offset is 540 min (9*60) refer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets", "max": 1000, "min": -1000, "name": "SDLOG_UTC_OFFSET", "shortDesc": "UTC offset (unit: min)", "type": "Int32", "units": "min"}, {"category": "Standard", "default": 1, "group": "SD Logging", "longDesc": "If set to 1, add an ID to the log, which uniquely identifies the vehicle", "name": "SDLOG_UUID", "shortDesc": "Log UUID", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 60.0, "group": "SITL", "increment": 1.0, "max": 86400.0, "min": 1.0, "name": "SIM_BAT_DRAIN", "shortDesc": "Simulator Battery drain interval", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "SITL", "longDesc": "Enable or disable the internal battery simulation. This is useful\nwhen the battery is simulated externally and interfaced with PX4\nthrough MAVLink for example.", "name": "SIM_BAT_ENABLE", "shortDesc": "Simulator Battery enabled", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 50.0, "group": "SITL", "increment": 0.1, "longDesc": "Can be used to alter the battery level during SITL- or HITL-simulation on the fly.\nParticularly useful for testing different low-battery behaviour.", "max": 100.0, "min": 0.0, "name": "SIM_BAT_MIN_PCT", "shortDesc": "Simulator Battery minimal percentage", "type": "Float", "units": "%"}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC0_ID", "shortDesc": "Accelerometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC0_PRIO", "shortDesc": "Accelerometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC0_ROT", "shortDesc": "Accelerometer 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_XOFF", "shortDesc": "Accelerometer 0 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_XSCALE", "shortDesc": "Accelerometer 0 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_YOFF", "shortDesc": "Accelerometer 0 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_YSCALE", "shortDesc": "Accelerometer 0 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC0_ZOFF", "shortDesc": "Accelerometer 0 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC0_ZSCALE", "shortDesc": "Accelerometer 0 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC1_ID", "shortDesc": "Accelerometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC1_PRIO", "shortDesc": "Accelerometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC1_ROT", "shortDesc": "Accelerometer 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_XOFF", "shortDesc": "Accelerometer 1 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_XSCALE", "shortDesc": "Accelerometer 1 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_YOFF", "shortDesc": "Accelerometer 1 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_YSCALE", "shortDesc": "Accelerometer 1 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC1_ZOFF", "shortDesc": "Accelerometer 1 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC1_ZSCALE", "shortDesc": "Accelerometer 1 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC2_ID", "shortDesc": "Accelerometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC2_PRIO", "shortDesc": "Accelerometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC2_ROT", "shortDesc": "Accelerometer 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_XOFF", "shortDesc": "Accelerometer 2 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_XSCALE", "shortDesc": "Accelerometer 2 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_YOFF", "shortDesc": "Accelerometer 2 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_YSCALE", "shortDesc": "Accelerometer 2 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC2_ZOFF", "shortDesc": "Accelerometer 2 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC2_ZSCALE", "shortDesc": "Accelerometer 2 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the accelerometer this calibration applies to.", "name": "CAL_ACC3_ID", "shortDesc": "Accelerometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": -1, "group": "Sensor Calibration", "name": "CAL_ACC3_PRIO", "shortDesc": "Accelerometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_ACC3_ROT", "shortDesc": "Accelerometer 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_XOFF", "shortDesc": "Accelerometer 3 X-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_XSCALE", "shortDesc": "Accelerometer 3 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_YOFF", "shortDesc": "Accelerometer 3 Y-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_YSCALE", "shortDesc": "Accelerometer 3 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_ACC3_ZOFF", "shortDesc": "Accelerometer 3 Z-axis offset", "type": "Float", "units": "m/s^2", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_ACC3_ZSCALE", "shortDesc": "Accelerometer 3 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO0_ID", "shortDesc": "Barometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO0_OFF", "shortDesc": "Barometer 0 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO0_PRIO", "shortDesc": "Barometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO1_ID", "shortDesc": "Barometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO1_OFF", "shortDesc": "Barometer 1 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO1_PRIO", "shortDesc": "Barometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO2_ID", "shortDesc": "Barometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO2_OFF", "shortDesc": "Barometer 2 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO2_PRIO", "shortDesc": "Barometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the barometer this calibration applies to.", "name": "CAL_BARO3_ID", "shortDesc": "Barometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_BARO3_OFF", "shortDesc": "Barometer 3 offset", "type": "Float", "volatile": true}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_BARO3_PRIO", "shortDesc": "Barometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO0_ID", "shortDesc": "Gyroscope 0 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO0_PRIO", "shortDesc": "Gyroscope 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO0_ROT", "shortDesc": "Gyroscope 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_XOFF", "shortDesc": "Gyroscope 0 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_YOFF", "shortDesc": "Gyroscope 0 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO0_ZOFF", "shortDesc": "Gyroscope 0 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO1_ID", "shortDesc": "Gyroscope 1 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO1_PRIO", "shortDesc": "Gyroscope 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO1_ROT", "shortDesc": "Gyroscope 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_XOFF", "shortDesc": "Gyroscope 1 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_YOFF", "shortDesc": "Gyroscope 1 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO1_ZOFF", "shortDesc": "Gyroscope 1 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO2_ID", "shortDesc": "Gyroscope 2 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO2_PRIO", "shortDesc": "Gyroscope 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO2_ROT", "shortDesc": "Gyroscope 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_XOFF", "shortDesc": "Gyroscope 2 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_YOFF", "shortDesc": "Gyroscope 2 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO2_ZOFF", "shortDesc": "Gyroscope 2 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the gyroscope this calibration applies to.", "name": "CAL_GYRO3_ID", "shortDesc": "Gyroscope 3 calibration device ID", "type": "Int32"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_GYRO3_PRIO", "shortDesc": "Gyroscope 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.", "max": 40, "min": -1, "name": "CAL_GYRO3_ROT", "shortDesc": "Gyroscope 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_XOFF", "shortDesc": "Gyroscope 3 X-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_YOFF", "shortDesc": "Gyroscope 3 Y-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_GYRO3_ZOFF", "shortDesc": "Gyroscope 3 Z-axis offset", "type": "Float", "units": "rad/s", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG0_ID", "shortDesc": "Magnetometer 0 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_PITCH", "shortDesc": "Magnetometer 0 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG0_PRIO", "shortDesc": "Magnetometer 0 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_ROLL", "shortDesc": "Magnetometer 0 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG0_ROLL, CAL_MAG0_PITCH and CAL_MAG0_YAW.", "max": 100, "min": -1, "name": "CAL_MAG0_ROT", "shortDesc": "Magnetometer 0 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_XCOMP", "shortDesc": "Magnetometer 0 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_XODIAG", "shortDesc": "Magnetometer 0 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_XOFF", "shortDesc": "Magnetometer 0 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_XSCALE", "shortDesc": "Magnetometer 0 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG0_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG0_YAW", "shortDesc": "Magnetometer 0 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_YCOMP", "shortDesc": "Magnetometer 0 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_YODIAG", "shortDesc": "Magnetometer 0 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_YOFF", "shortDesc": "Magnetometer 0 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_YSCALE", "shortDesc": "Magnetometer 0 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG0_ZCOMP", "shortDesc": "Magnetometer 0 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_ZODIAG", "shortDesc": "Magnetometer 0 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG0_ZOFF", "shortDesc": "Magnetometer 0 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG0_ZSCALE", "shortDesc": "Magnetometer 0 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG1_ID", "shortDesc": "Magnetometer 1 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_PITCH", "shortDesc": "Magnetometer 1 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG1_PRIO", "shortDesc": "Magnetometer 1 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_ROLL", "shortDesc": "Magnetometer 1 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG1_ROLL, CAL_MAG1_PITCH and CAL_MAG1_YAW.", "max": 100, "min": -1, "name": "CAL_MAG1_ROT", "shortDesc": "Magnetometer 1 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_XCOMP", "shortDesc": "Magnetometer 1 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_XODIAG", "shortDesc": "Magnetometer 1 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_XOFF", "shortDesc": "Magnetometer 1 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_XSCALE", "shortDesc": "Magnetometer 1 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG1_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG1_YAW", "shortDesc": "Magnetometer 1 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_YCOMP", "shortDesc": "Magnetometer 1 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_YODIAG", "shortDesc": "Magnetometer 1 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_YOFF", "shortDesc": "Magnetometer 1 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_YSCALE", "shortDesc": "Magnetometer 1 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG1_ZCOMP", "shortDesc": "Magnetometer 1 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_ZODIAG", "shortDesc": "Magnetometer 1 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG1_ZOFF", "shortDesc": "Magnetometer 1 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG1_ZSCALE", "shortDesc": "Magnetometer 1 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG2_ID", "shortDesc": "Magnetometer 2 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_PITCH", "shortDesc": "Magnetometer 2 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG2_PRIO", "shortDesc": "Magnetometer 2 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_ROLL", "shortDesc": "Magnetometer 2 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG2_ROLL, CAL_MAG2_PITCH and CAL_MAG2_YAW.", "max": 100, "min": -1, "name": "CAL_MAG2_ROT", "shortDesc": "Magnetometer 2 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_XCOMP", "shortDesc": "Magnetometer 2 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_XODIAG", "shortDesc": "Magnetometer 2 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_XOFF", "shortDesc": "Magnetometer 2 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_XSCALE", "shortDesc": "Magnetometer 2 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG2_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG2_YAW", "shortDesc": "Magnetometer 2 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_YCOMP", "shortDesc": "Magnetometer 2 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_YODIAG", "shortDesc": "Magnetometer 2 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_YOFF", "shortDesc": "Magnetometer 2 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_YSCALE", "shortDesc": "Magnetometer 2 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG2_ZCOMP", "shortDesc": "Magnetometer 2 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_ZODIAG", "shortDesc": "Magnetometer 2 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG2_ZOFF", "shortDesc": "Magnetometer 2 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG2_ZSCALE", "shortDesc": "Magnetometer 2 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Device ID of the magnetometer this calibration applies to.", "name": "CAL_MAG3_ID", "shortDesc": "Magnetometer 3 calibration device ID", "type": "Int32"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_PITCH", "shortDesc": "Magnetometer 3 Custom Euler Pitch Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "name": "CAL_MAG3_PRIO", "shortDesc": "Magnetometer 3 priority", "type": "Int32", "values": [{"description": "Uninitialized", "value": -1}, {"description": "Disabled", "value": 0}, {"description": "Min", "value": 1}, {"description": "Low", "value": 25}, {"description": "Medium (Default)", "value": 50}, {"description": "High", "value": 75}, {"description": "Max", "value": 100}]}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_ROLL", "shortDesc": "Magnetometer 3 Custom Euler Roll Angle", "type": "Float", "units": "deg"}, {"category": "System", "default": -1, "group": "Sensor Calibration", "longDesc": "An internal sensor will force a value of -1, so a GCS should only attempt to configure the rotation if the value is greater than or equal to zero.\nSet to \"Custom Euler Angle\" to define the rotation using CAL_MAG3_ROLL, CAL_MAG3_PITCH and CAL_MAG3_YAW.", "max": 100, "min": -1, "name": "CAL_MAG3_ROT", "shortDesc": "Magnetometer 3 rotation relative to airframe", "type": "Int32", "values": [{"description": "Internal", "value": -1}, {"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}, {"description": "Custom Euler Angle", "value": 100}]}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nX component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_XCOMP", "shortDesc": "Magnetometer 3 X Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_XODIAG", "shortDesc": "Magnetometer 3 X-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_XOFF", "shortDesc": "Magnetometer 3 X-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_XSCALE", "shortDesc": "Magnetometer 3 X-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Setting this parameter changes CAL_MAG3_ROT to \"Custom Euler Angle\"", "max": 180.0, "min": -180.0, "name": "CAL_MAG3_YAW", "shortDesc": "Magnetometer 3 Custom Euler Yaw Angle", "type": "Float", "units": "deg"}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nY component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_YCOMP", "shortDesc": "Magnetometer 3 Y Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_YODIAG", "shortDesc": "Magnetometer 3 Y-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_YOFF", "shortDesc": "Magnetometer 3 Y-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_YSCALE", "shortDesc": "Magnetometer 3 Y-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "longDesc": "Coefficient describing linear relationship between\nZ component of magnetometer in body frame axis\nand either current or throttle depending on value of CAL_MAG_COMP_TYP.\nUnit for throttle-based compensation is [G] and\nfor current-based compensation [G/kA]", "name": "CAL_MAG3_ZCOMP", "shortDesc": "Magnetometer 3 Z Axis throttle compensation", "type": "Float", "volatile": true}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_ZODIAG", "shortDesc": "Magnetometer 3 Z-axis off diagonal scale factor", "type": "Float", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 0.0, "group": "Sensor Calibration", "name": "CAL_MAG3_ZOFF", "shortDesc": "Magnetometer 3 Z-axis offset", "type": "Float", "units": "gauss", "volatile": true}, {"category": "System", "decimalPlaces": 3, "default": 1.0, "group": "Sensor Calibration", "max": 3.0, "min": 0.1, "name": "CAL_MAG3_ZSCALE", "shortDesc": "Magnetometer 3 Z-axis scaling factor", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "name": "CAL_MAG_COMP_TYP", "shortDesc": "Type of magnetometer compensation", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Throttle-based compensation", "value": 1}, {"description": "Current-based compensation (battery_status instance 0)", "value": 2}, {"description": "Current-based compensation (battery_status instance 1)", "value": 3}]}, {"category": "Standard", "default": 0.0, "group": "Sensor Calibration", "longDesc": "Pick the appropriate scaling from the datasheet.\nthis number defines the (linear) conversion from voltage\nto Pascal (pa). For the MPXV7002DP this is 1000.\nNOTE: If the sensor always registers zero, try switching\nthe static and dynamic tubes.", "name": "SENS_DPRES_ANSC", "shortDesc": "Differential pressure sensor analog scaling", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Sensor Calibration", "longDesc": "The offset (zero-reading) in Pascal", "name": "SENS_DPRES_OFF", "shortDesc": "Differential pressure sensor offset", "type": "Float", "volatile": true}, {"category": "System", "default": 0, "group": "Sensor Calibration", "longDesc": "Reverse the raw measurements of all differential pressure sensors.\nThis can be enabled if the sensors have static and dynamic ports swapped.", "name": "SENS_DPRES_REV", "shortDesc": "Reverse differential pressure sensor readings", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 100.0, "group": "Sensor Calibration", "increment": 0.1, "longDesc": "This parameter defines the maximum distance from ground at which the optical flow sensor operates reliably.\nThe height setpoint will be limited to be no greater than this value when the navigation system\nis completely reliant on optical flow data and the height above ground estimate is valid.\nThe sensor may be usable above this height, but accuracy will progressively degrade.", "max": 100.0, "min": 1.0, "name": "SENS_FLOW_MAXHGT", "shortDesc": "Maximum height above ground when reliant on optical flow", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 8.0, "group": "Sensor Calibration", "longDesc": "Optical flow data will not fused by the estimators if the magnitude of the flow rate exceeds this value and\ncontrol loops will be instructed to limit ground speed such that the flow rate produced by movement over ground\nis less than 50% of this value.", "min": 1.0, "name": "SENS_FLOW_MAXR", "shortDesc": "Magnitude of maximum angular flow rate reliably measurable by the optical flow sensor", "type": "Float", "units": "rad/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.08, "group": "Sensor Calibration", "increment": 0.1, "longDesc": "This parameter defines the minimum distance from ground at which the optical flow sensor operates reliably.\nThe sensor may be usable below this height, but accuracy will progressively reduce to loss of focus.", "max": 1.0, "min": 0.0, "name": "SENS_FLOW_MINHGT", "shortDesc": "Minimum height above ground when reliant on optical flow", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "Model with Pitot\nCAL_AIR_TUBED_MM: Not used, 1.5 mm tubes assumed.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor.\nModel without Pitot (1.5 mm tubes)\nCAL_AIR_TUBED_MM: Not used, 1.5 mm tubes assumed.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor.\nTube Pressure Drop\nCAL_AIR_TUBED_MM: Diameter in mm of the pitot and tubes, must have the same diameter.\nCAL_AIR_TUBELEN: Length of the tubes connecting the pitot to the sensor and the static + dynamic port length of the pitot.", "name": "CAL_AIR_CMODEL", "shortDesc": "Airspeed sensor compensation model for the SDP3x", "type": "Int32", "values": [{"description": "Model with Pitot", "value": 0}, {"description": "Model without Pitot (1.5 mm tubes)", "value": 1}, {"description": "Tube Pressure Drop", "value": 2}]}, {"category": "Standard", "default": 1.5, "group": "Sensors", "max": 100.0, "min": 1.5, "name": "CAL_AIR_TUBED_MM", "shortDesc": "Airspeed sensor tube diameter. Only used for the Tube Pressure Drop Compensation", "type": "Float", "units": "mm"}, {"category": "Standard", "default": 0.2, "group": "Sensors", "longDesc": "See the CAL_AIR_CMODEL explanation on how this parameter should be set.", "max": 2.0, "min": 0.01, "name": "CAL_AIR_TUBELEN", "shortDesc": "Airspeed sensor tube length", "type": "Float", "units": "m"}, {"category": "Developer", "default": 63, "group": "Sensors", "longDesc": "Use SENS_MAG_SIDES instead", "name": "CAL_MAG_SIDES", "shortDesc": "For legacy QGC support only", "type": "Int32"}, {"category": "Standard", "default": 30.0, "group": "Sensors", "longDesc": "The cutoff frequency for the 2nd order butterworth filter on the primary accelerometer.\nThis only affects the signal sent to the controllers, not the estimators. 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_ACCEL_CUTOFF", "rebootRequired": true, "shortDesc": "Low pass filter cutoff frequency for accel", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The cutoff frequency for the 2nd order butterworth filter used on\nthe time derivative of the measured angular velocity, also known as\nthe D-term filter in the rate controller. The D-term uses the derivative of\nthe rate and thus is the most susceptible to noise. Therefore, using\na D-term filter allows to increase IMU_GYRO_CUTOFF, which\nleads to reduced control latency and permits to increase the P gains.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_DGYRO_CUTOFF", "rebootRequired": true, "shortDesc": "Cutoff frequency for angular acceleration (D-Term filter)", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 1, "group": "Sensors", "name": "IMU_GYRO_CAL_EN", "rebootRequired": true, "shortDesc": "IMU gyro auto calibration enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 1, "default": 40.0, "group": "Sensors", "increment": 0.1, "longDesc": "The cutoff frequency for the 2nd order butterworth filter on the primary gyro.\nThis only affects the angular velocity sent to the controllers, not the estimators.\nIt applies also to the angular acceleration (D-Term filter), see IMU_DGYRO_CUTOFF.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_CUTOFF", "rebootRequired": true, "shortDesc": "Low pass filter cutoff frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 15.0, "group": "Sensors", "increment": 0.1, "longDesc": "Bandwidth per notch filter when using dynamic notch filtering with ESC RPM.", "max": 30.0, "min": 5.0, "name": "IMU_GYRO_DNF_BW", "shortDesc": "IMU gyro ESC notch filter bandwidth", "type": "Float", "units": "Hz"}, {"bitmask": [{"description": "ESC RPM", "index": 0}, {"description": "FFT", "index": 1}], "category": "Standard", "default": 0, "group": "Sensors", "longDesc": "Enable bank of dynamically updating notch filters.\nRequires ESC RPM feedback or onboard FFT (IMU_GYRO_FFT_EN).", "max": 3, "min": 0, "name": "IMU_GYRO_DNF_EN", "shortDesc": "IMU gyro dynamic notch filtering", "type": "Int32"}, {"category": "Standard", "default": 3, "group": "Sensors", "longDesc": "ESC RPM number of harmonics (multiples of RPM) for ESC RPM dynamic notch filtering.", "max": 7, "min": 1, "name": "IMU_GYRO_DNF_HMC", "shortDesc": "IMU gyro dynamic notch filter harmonics", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 25.0, "group": "Sensors", "increment": 0.1, "longDesc": "Minimum notch filter frequency in Hz.", "name": "IMU_GYRO_DNF_MIN", "shortDesc": "IMU gyro dynamic notch filter minimum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "Sensors", "name": "IMU_GYRO_FFT_EN", "rebootRequired": true, "shortDesc": "IMU gyro FFT enable", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 512, "group": "Sensors", "name": "IMU_GYRO_FFT_LEN", "rebootRequired": true, "shortDesc": "IMU gyro FFT length", "type": "Int32", "units": "Hz", "values": [{"description": "256", "value": 256}, {"description": "512", "value": 512}, {"description": "1024", "value": 1024}, {"description": "4096", "value": 4096}]}, {"category": "Standard", "default": 150.0, "group": "Sensors", "max": 1000.0, "min": 1.0, "name": "IMU_GYRO_FFT_MAX", "rebootRequired": true, "shortDesc": "IMU gyro FFT maximum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 30.0, "group": "Sensors", "max": 1000.0, "min": 1.0, "name": "IMU_GYRO_FFT_MIN", "rebootRequired": true, "shortDesc": "IMU gyro FFT minimum frequency", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 10.0, "group": "Sensors", "max": 30.0, "min": 1.0, "name": "IMU_GYRO_FFT_SNR", "shortDesc": "IMU gyro FFT SNR", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The frequency width of the stop band for the 2nd order notch filter on the primary gyro.\nSee \"IMU_GYRO_NF0_FRQ\" to activate the filter and to set the notch frequency.\nApplies to both angular velocity and angular acceleration sent to the controllers.", "max": 100.0, "min": 0.0, "name": "IMU_GYRO_NF0_BW", "rebootRequired": true, "shortDesc": "Notch filter bandwidth for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "increment": 0.1, "longDesc": "The center frequency for the 2nd order notch filter on the primary gyro.\nThis filter can be enabled to avoid feedback amplification of structural resonances at a specific frequency.\nThis only affects the signal sent to the controllers, not the estimators.\nApplies to both angular velocity and angular acceleration sent to the controllers.\nSee \"IMU_GYRO_NF0_BW\" to set the bandwidth of the filter.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_NF0_FRQ", "rebootRequired": true, "shortDesc": "Notch filter frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "Sensors", "increment": 0.1, "longDesc": "The frequency width of the stop band for the 2nd order notch filter on the primary gyro.\nSee \"IMU_GYRO_NF1_FRQ\" to activate the filter and to set the notch frequency.\nApplies to both angular velocity and angular acceleration sent to the controllers.", "max": 100.0, "min": 0.0, "name": "IMU_GYRO_NF1_BW", "rebootRequired": true, "shortDesc": "Notch filter 1 bandwidth for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "increment": 0.1, "longDesc": "The center frequency for the 2nd order notch filter on the primary gyro.\nThis filter can be enabled to avoid feedback amplification of structural resonances at a specific frequency.\nThis only affects the signal sent to the controllers, not the estimators.\nApplies to both angular velocity and angular acceleration sent to the controllers.\nSee \"IMU_GYRO_NF1_BW\" to set the bandwidth of the filter.\nA value of 0 disables the filter.", "max": 1000.0, "min": 0.0, "name": "IMU_GYRO_NF1_FRQ", "rebootRequired": true, "shortDesc": "Notch filter 2 frequency for gyro", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 400, "group": "Sensors", "longDesc": "The maximum rate the gyro control data (vehicle_angular_velocity) will be\nallowed to publish at. This is the loop rate for the rate controller and outputs.\nNote: sensor data is always read and filtered at the full raw rate (eg commonly 8 kHz) regardless of this setting.", "max": 2000, "min": 100, "name": "IMU_GYRO_RATEMAX", "rebootRequired": true, "shortDesc": "Gyro control data maximum publication rate (inner loop rate)", "type": "Int32", "units": "Hz", "values": [{"description": "100 Hz", "value": 100}, {"description": "250 Hz", "value": 250}, {"description": "400 Hz", "value": 400}, {"description": "800 Hz", "value": 800}, {"description": "1000 Hz", "value": 1000}, {"description": "2000 Hz", "value": 2000}]}, {"category": "Standard", "default": 200, "group": "Sensors", "longDesc": "The rate at which raw IMU data is integrated to produce delta angles and delta velocities.\nRecommended to set this to a multiple of the estimator update period (currently 10 ms for ekf2).", "max": 1000, "min": 100, "name": "IMU_INTEG_RATE", "rebootRequired": true, "shortDesc": "IMU integration rate", "type": "Int32", "units": "Hz", "values": [{"description": "100 Hz", "value": 100}, {"description": "200 Hz", "value": 200}, {"description": "250 Hz", "value": 250}, {"description": "400 Hz", "value": 400}]}, {"category": "Standard", "default": 1013.25, "group": "Sensors", "max": 1500.0, "min": 500.0, "name": "SENS_BARO_QNH", "shortDesc": "QNH for barometer", "type": "Float", "units": "hPa"}, {"category": "Standard", "default": 20.0, "group": "Sensors", "longDesc": "Barometric air data maximum publication rate. This is an upper bound,\nactual barometric data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_BARO_RATE", "shortDesc": "Baro max rate", "type": "Float", "units": "Hz"}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Automatically calibrate barometer based on the GNSS height", "name": "SENS_BAR_AUTOCAL", "shortDesc": "Barometer auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "This parameter defines the rotation of the FMU board relative to the platform.", "max": 40, "min": -1, "name": "SENS_BOARD_ROT", "rebootRequired": true, "shortDesc": "Board rotation", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}, {"description": "Roll 180\u00b0", "value": 8}, {"description": "Roll 180\u00b0, Yaw 45\u00b0", "value": 9}, {"description": "Roll 180\u00b0, Yaw 90\u00b0", "value": 10}, {"description": "Roll 180\u00b0, Yaw 135\u00b0", "value": 11}, {"description": "Pitch 180\u00b0", "value": 12}, {"description": "Roll 180\u00b0, Yaw 225\u00b0", "value": 13}, {"description": "Roll 180\u00b0, Yaw 270\u00b0", "value": 14}, {"description": "Roll 180\u00b0, Yaw 315\u00b0", "value": 15}, {"description": "Roll 90\u00b0", "value": 16}, {"description": "Roll 90\u00b0, Yaw 45\u00b0", "value": 17}, {"description": "Roll 90\u00b0, Yaw 90\u00b0", "value": 18}, {"description": "Roll 90\u00b0, Yaw 135\u00b0", "value": 19}, {"description": "Roll 270\u00b0", "value": 20}, {"description": "Roll 270\u00b0, Yaw 45\u00b0", "value": 21}, {"description": "Roll 270\u00b0, Yaw 90\u00b0", "value": 22}, {"description": "Roll 270\u00b0, Yaw 135\u00b0", "value": 23}, {"description": "Pitch 90\u00b0", "value": 24}, {"description": "Pitch 270\u00b0", "value": 25}, {"description": "Pitch 180\u00b0, Yaw 90\u00b0", "value": 26}, {"description": "Pitch 180\u00b0, Yaw 270\u00b0", "value": 27}, {"description": "Roll 90\u00b0, Pitch 90\u00b0", "value": 28}, {"description": "Roll 180\u00b0, Pitch 90\u00b0", "value": 29}, {"description": "Roll 270\u00b0, Pitch 90\u00b0", "value": 30}, {"description": "Roll 90\u00b0, Pitch 180\u00b0", "value": 31}, {"description": "Roll 270\u00b0, Pitch 180\u00b0", "value": 32}, {"description": "Roll 90\u00b0, Pitch 270\u00b0", "value": 33}, {"description": "Roll 180\u00b0, Pitch 270\u00b0", "value": 34}, {"description": "Roll 270\u00b0, Pitch 270\u00b0", "value": 35}, {"description": "Roll 90\u00b0, Pitch 180\u00b0, Yaw 90\u00b0", "value": 36}, {"description": "Roll 90\u00b0, Yaw 270\u00b0", "value": 37}, {"description": "Roll 90\u00b0, Pitch 68\u00b0, Yaw 293\u00b0", "value": 38}, {"description": "Pitch 315\u00b0", "value": 39}, {"description": "Roll 90\u00b0, Pitch 315\u00b0", "value": 40}]}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nThis parameter gets set during the \"level horizon\" calibration or can be\nset manually.", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_X_OFF", "shortDesc": "Board rotation X (roll) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nThis parameter gets set during the \"level horizon\" calibration or can be\nset manually.", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_Y_OFF", "shortDesc": "Board rotation Y (pitch) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "Sensors", "longDesc": "Rotation from flight controller board to vehicle body frame.\nHas to be set manually (not set by any calibration).", "max": 45.0, "min": -45.0, "name": "SENS_BOARD_Z_OFF", "shortDesc": "Board rotation Z (yaw) offset", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_AGPSIM", "rebootRequired": true, "shortDesc": "Simulate Aux Global Position (AGP)", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_ARSPDSIM", "rebootRequired": true, "shortDesc": "Enable simulated airspeed sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_BAROSIM", "rebootRequired": true, "shortDesc": "Enable simulated barometer sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_GPSSIM", "rebootRequired": true, "shortDesc": "Enable simulated GPS sinstance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SENS_EN_MAGSIM", "rebootRequired": true, "shortDesc": "Enable simulated magnetometer sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": -1, "group": "Sensors", "name": "SENS_EN_THERMAL", "shortDesc": "Thermal control of sensor temperature", "type": "Int32", "values": [{"description": "Thermal control unavailable", "value": -1}, {"description": "Thermal control off", "value": 0}, {"description": "Thermal control enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Probe for optional external I2C devices.", "name": "SENS_EXT_I2C_PRB", "shortDesc": "External I2C probe", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 70.0, "group": "Sensors", "longDesc": "Optical flow data maximum publication rate. This is an upper bound,\nactual optical flow data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_FLOW_RATE", "rebootRequired": true, "shortDesc": "Optical flow max rate", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "This parameter defines the yaw rotation of the optical flow relative to the vehicle body frame.\nZero rotation is defined as X on flow board pointing towards front of vehicle.", "name": "SENS_FLOW_ROT", "shortDesc": "Optical flow rotation", "type": "Int32", "values": [{"description": "No rotation", "value": 0}, {"description": "Yaw 45\u00b0", "value": 1}, {"description": "Yaw 90\u00b0", "value": 2}, {"description": "Yaw 135\u00b0", "value": 3}, {"description": "Yaw 180\u00b0", "value": 4}, {"description": "Yaw 225\u00b0", "value": 5}, {"description": "Yaw 270\u00b0", "value": 6}, {"description": "Yaw 315\u00b0", "value": 7}]}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Sensors", "max": 1.5, "min": 0.5, "name": "SENS_FLOW_SCALE", "shortDesc": "Optical flow scale factor", "type": "Float"}, {"bitmask": [{"description": "use speed accuracy", "index": 0}, {"description": "use hpos accuracy", "index": 1}, {"description": "use vpos accuracy", "index": 2}], "category": "Standard", "default": 7, "group": "Sensors", "longDesc": "Set bits in the following positions to set which GPS accuracy metrics will be used to calculate the blending weight. Set to zero to disable and always used first GPS instance.\n0 : Set to true to use speed accuracy\n1 : Set to true to use horizontal position accuracy\n2 : Set to true to use vertical position accuracy", "max": 7, "min": 0, "name": "SENS_GPS_MASK", "shortDesc": "Multi GPS Blending Control Mask", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Sensors", "longDesc": "When no blending is active, this defines the preferred GPS receiver instance.\nThe GPS selection logic waits until the primary receiver is available to\nsend data to the EKF even if a secondary instance is already available.\nThe secondary instance is then only used if the primary one times out.\nAccepted values:\n-1 : Auto (equal priority for all instances)\n0 : Main serial GPS instance\n1 : Secondary serial GPS instance\n2-127 : UAVCAN module node ID\nThis parameter has no effect if blending is active.", "max": 127, "min": -1, "name": "SENS_GPS_PRIME", "shortDesc": "Multi GPS primary instance", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 1, "default": 10.0, "group": "Sensors", "longDesc": "Sets the longest time constant that will be applied to the calculation of GPS position and height offsets used to correct data from multiple GPS data for steady state position differences.", "max": 100.0, "min": 1.0, "name": "SENS_GPS_TAU", "shortDesc": "Multi GPS Blending Time Constant", "type": "Float", "units": "s"}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Automatically initialize IMU (accel/gyro) calibration from bias estimates if available.", "name": "SENS_IMU_AUTOCAL", "shortDesc": "IMU auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Notify the user if the IMU is clipping", "name": "SENS_IMU_CLPNOTI", "shortDesc": "IMU notify clipping", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "name": "SENS_IMU_MODE", "rebootRequired": true, "shortDesc": "Sensors hub IMU mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Publish primary IMU selection", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "For systems with an external barometer, this should be set to false to make sure that the external is used.", "name": "SENS_INT_BARO_EN", "rebootRequired": true, "shortDesc": "Enable internal barometers", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "longDesc": "Automatically initialize magnetometer calibration from bias estimate if available.", "name": "SENS_MAG_AUTOCAL", "shortDesc": "Magnetometer auto calibration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Sensors", "longDesc": "During calibration attempt to automatically determine the rotation of external magnetometers.", "name": "SENS_MAG_AUTOROT", "shortDesc": "Automatically set external rotations", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "Sensors", "name": "SENS_MAG_MODE", "rebootRequired": true, "shortDesc": "Sensors hub mag mode", "type": "Int32", "values": [{"description": "Publish all magnetometers", "value": 0}, {"description": "Publish primary magnetometer", "value": 1}]}, {"category": "Standard", "default": 15.0, "group": "Sensors", "longDesc": "Magnetometer data maximum publication rate. This is an upper bound,\nactual magnetometer data rate is still dependent on the sensor.", "max": 200.0, "min": 1.0, "name": "SENS_MAG_RATE", "rebootRequired": true, "shortDesc": "Magnetometer max rate", "type": "Float", "units": "Hz"}, {"category": "Standard", "default": 63, "group": "Sensors", "longDesc": "If set to two side calibration, only the offsets are estimated, the scale\ncalibration is left unchanged. Thus an initial six side calibration is\nrecommended.\nBits:\nORIENTATION_TAIL_DOWN = 1\nORIENTATION_NOSE_DOWN = 2\nORIENTATION_LEFT = 4\nORIENTATION_RIGHT = 8\nORIENTATION_UPSIDE_DOWN = 16\nORIENTATION_RIGHTSIDE_UP = 32", "max": 63, "min": 34, "name": "SENS_MAG_SIDES", "shortDesc": "Bitfield selecting mag sides for calibration", "type": "Int32", "values": [{"description": "Two side calibration", "value": 34}, {"description": "Three side calibration", "value": 38}, {"description": "Six side calibration", "value": 63}]}, {"category": "Standard", "default": 0, "group": "Sensors", "max": 1, "min": 0, "name": "SIM_ARSPD_FAIL", "rebootRequired": true, "shortDesc": "Dynamically simulate failure of airspeed sensor instance", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "Septentrio", "longDesc": "By default, the receiver is automatically configured. Sometimes it may be used for multiple purposes.\nIf the offered parameters aren't sufficient, this parameter can be disabled to have full control of the receiver configuration.\nA good way to use this is to enable automatic configuration, let the receiver be configured, and then disable it to make manual adjustments.", "name": "SEP_AUTO_CONFIG", "rebootRequired": true, "shortDesc": "Toggle automatic receiver configuration", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"bitmask": [{"description": "GPS", "index": 0}, {"description": "GLONASS", "index": 1}, {"description": "Galileo", "index": 2}, {"description": "SBAS", "index": 3}, {"description": "BeiDou", "index": 4}], "category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "Choice of which constellations the receiver should use for PVT computation.\nWhen this is 0, the constellation usage isn't changed.", "max": 63, "min": 0, "name": "SEP_CONST_USAGE", "rebootRequired": true, "shortDesc": "Usage of different constellations", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "Log raw communication between the driver and connected receivers.\nFor example, \"To receiver\" will log all commands and corrections sent by the driver to the receiver.", "max": 3, "min": 0, "name": "SEP_DUMP_COMM", "shortDesc": "Log GPS communication data", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "From receiver", "value": 1}, {"description": "To receiver", "value": 2}, {"description": "Both", "value": 3}]}, {"category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "Setup and expected use of the hardware.\n- Default: Use two receivers as completely separate instances.\n- Moving base: Use two receivers in a rover & moving base setup for heading.", "max": 1, "min": 0, "name": "SEP_HARDW_SETUP", "rebootRequired": true, "shortDesc": "Setup and expected use of the hardware", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Moving base", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "When the receiver is already set up to log data, this decides whether extra logged data should be added or overwrite existing data.", "name": "SEP_LOG_FORCE", "rebootRequired": true, "shortDesc": "Whether to overwrite or add to existing logging", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "Select the frequency at which the connected receiver should log data to its internal storage.", "max": 10, "min": 0, "name": "SEP_LOG_HZ", "rebootRequired": true, "shortDesc": "Logging frequency for the receiver", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "0.1 Hz", "value": 1}, {"description": "0.2 Hz", "value": 2}, {"description": "0.5 Hz", "value": 3}, {"description": "1 Hz", "value": 4}, {"description": "2 Hz", "value": 5}, {"description": "5 Hz", "value": 6}, {"description": "10 Hz", "value": 7}, {"description": "20 Hz", "value": 8}, {"description": "25 Hz", "value": 9}, {"description": "50 Hz", "value": 10}]}, {"category": "Standard", "default": 2, "group": "Septentrio", "longDesc": "Select the level of detail that needs to be logged by the receiver.", "max": 3, "min": 0, "name": "SEP_LOG_LEVEL", "rebootRequired": true, "shortDesc": "Logging level for the receiver", "type": "Int32", "values": [{"description": "Lite", "value": 0}, {"description": "Basic", "value": 1}, {"description": "Default", "value": 2}, {"description": "Full", "value": 3}]}, {"category": "Standard", "default": 1, "group": "Septentrio", "longDesc": "The output frequency of the main SBF blocks needed for PVT information.", "max": 3, "min": 0, "name": "SEP_OUTP_HZ", "rebootRequired": true, "shortDesc": "Output frequency of main SBF blocks", "type": "Int32", "values": [{"description": "5 Hz", "value": 0}, {"description": "10 Hz", "value": 1}, {"description": "20 Hz", "value": 2}, {"description": "25 Hz", "value": 3}]}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Septentrio", "longDesc": "Vertical offsets can be compensated for by adjusting the Pitch offset.\nNote that this can be interpreted as the \"roll\" angle in case the antennas are aligned along the perpendicular axis.\nThis occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame.\nSince pitch is defined as the right-handed rotation about the vehicle Y axis,\na situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch.", "max": 90.0, "min": -90.0, "name": "SEP_PITCH_OFFS", "rebootRequired": true, "shortDesc": "Pitch offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 0, "group": "Septentrio", "longDesc": "Enable publication of satellite info (ORB_ID(satellite_info)) if possible.", "name": "SEP_SAT_INFO", "rebootRequired": true, "shortDesc": "Enable sat info", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 2, "group": "Septentrio", "longDesc": "The stream the autopilot sets up on the receiver to output the logging data.\nSet this to another value if the default stream is already used for another purpose.", "max": 10, "min": 1, "name": "SEP_STREAM_LOG", "rebootRequired": true, "shortDesc": "Logging stream used during automatic configuration", "type": "Int32"}, {"category": "Standard", "default": 1, "group": "Septentrio", "longDesc": "The stream the autopilot sets up on the receiver to output the main data.\nSet this to another value if the default stream is already used for another purpose.", "max": 10, "min": 1, "name": "SEP_STREAM_MAIN", "rebootRequired": true, "shortDesc": "Main stream used during automatic configuration", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Septentrio", "longDesc": "Heading offset angle for dual antenna GPS setups that support heading estimation.\nSet this to 0 if the antennas are parallel to the forward-facing direction\nof the vehicle and the rover antenna is in front.\nThe offset angle increases clockwise.\nSet this to 90 if the rover antenna is placed on the\nright side of the vehicle and the moving base antenna is on the left side.", "max": 360.0, "min": -360.0, "name": "SEP_YAW_OFFS", "rebootRequired": true, "shortDesc": "Heading/Yaw offset for dual antenna GPS", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 4, "default": 100.0, "group": "Simulation In Hardware", "increment": 0.01, "max": 1000.0, "min": 0.0, "name": "SIH_DISTSNSR_MAX", "shortDesc": "distance sensor maximum range", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 4, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.01, "max": 10.0, "min": 0.0, "name": "SIH_DISTSNSR_MIN", "shortDesc": "distance sensor minimum range", "type": "Float", "units": "m"}, {"category": "Standard", "default": -1.0, "group": "Simulation In Hardware", "longDesc": "Absolute value superior to 10000 will disable distance sensor", "name": "SIH_DISTSNSR_OVR", "shortDesc": "if >= 0 the distance sensor measures will be overridden by this value", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IXX", "shortDesc": "Vehicle inertia about X axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IXY", "shortDesc": "Vehicle cross term inertia xy", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IXZ", "shortDesc": "Vehicle cross term inertia xz", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IYY", "shortDesc": "Vehicle inertia about Y axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nThis value can be set to 0 for a quad symmetric about its center of mass.", "name": "SIH_IYZ", "shortDesc": "Vehicle cross term inertia yz", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.03, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "The inertia is a 3 by 3 symmetric matrix.\nIt represents the difficulty of the vehicle to modify its angular rate.", "min": 0.0, "name": "SIH_IZZ", "shortDesc": "Vehicle inertia about Z axis", "type": "Float", "units": "kg m^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "Physical coefficient representing the friction with air particules.\nThe greater this value, the slower the quad will move.\nDrag force function of velocity: D=-KDV*V.\nThe maximum freefall velocity can be computed as V=10*MASS/KDV [m/s]", "min": 0.0, "name": "SIH_KDV", "shortDesc": "First order drag coefficient", "type": "Float", "units": "N/(m/s)"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.025, "group": "Simulation In Hardware", "increment": 0.005, "longDesc": "Physical coefficient representing the friction with air particules during rotations.\nThe greater this value, the slower the quad will rotate.\nAerodynamic moment function of body rate: Ma=-KDW*W_B.\nThis value can be set to 0 if unknown.", "min": 0.0, "name": "SIH_KDW", "shortDesc": "First order angular damper coefficient", "type": "Float", "units": "Nm/(rad/s)"}, {"category": "Standard", "decimalPlaces": 2, "default": 489.4, "group": "Simulation In Hardware", "increment": 0.01, "longDesc": "This value represents the Above Mean Sea Level (AMSL) altitude where the simulation begins.\nIf using FlightGear as a visual animation,\nthis value can be tweaked such that the vehicle lies on the ground at takeoff.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 8848.0, "min": -420.0, "name": "SIH_LOC_H0", "shortDesc": "Initial AMSL ground altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 47.397742, "group": "Simulation In Hardware", "longDesc": "This value represents the North-South location on Earth where the simulation begins.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 90.0, "min": -90.0, "name": "SIH_LOC_LAT0", "shortDesc": "Initial geodetic latitude", "type": "Float", "units": "deg"}, {"category": "Standard", "default": 8.545594, "group": "Simulation In Hardware", "longDesc": "This value represents the East-West location on Earth where the simulation begins.\nLAT0, LON0, H0, MU_X, MU_Y, and MU_Z should ideally be consistent among each others\nto represent a physical ground location on Earth.", "max": 180.0, "min": -180.0, "name": "SIH_LOC_LON0", "shortDesc": "Initial geodetic longitude", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the arm length generating the pitching moment\nThis value can be measured with a ruler.\nThis corresponds to half the distance between the front and rear motors.", "min": 0.0, "name": "SIH_L_PITCH", "shortDesc": "Pitch arm length", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.2, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the arm length generating the rolling moment\nThis value can be measured with a ruler.\nThis corresponds to half the distance between the left and right motors.", "min": 0.0, "name": "SIH_L_ROLL", "shortDesc": "Roll arm length", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "Simulation In Hardware", "increment": 0.1, "longDesc": "This value can be measured by weighting the quad on a scale.", "min": 0.0, "name": "SIH_MASS", "shortDesc": "Vehicle mass", "type": "Float", "units": "kg"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.1, "group": "Simulation In Hardware", "increment": 0.05, "longDesc": "This is the maximum torque delivered by one propeller\nwhen the motor is running at full speed.\nThis value is usually about few percent of the maximum thrust force.", "min": 0.0, "name": "SIH_Q_MAX", "shortDesc": "Max propeller torque", "type": "Float", "units": "Nm"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "Simulation In Hardware", "increment": 0.5, "longDesc": "This is the maximum force delivered by one propeller\nwhen the motor is running at full speed.\nThis value is usually about 5 times the mass of the quadrotor.", "min": 0.0, "name": "SIH_T_MAX", "shortDesc": "Max propeller thrust force", "type": "Float", "units": "N"}, {"category": "Standard", "default": 0.05, "group": "Simulation In Hardware", "longDesc": "the time taken for the thruster to step from 0 to 100% should be about 4 times tau", "name": "SIH_T_TAU", "shortDesc": "thruster time constant tau", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "Simulation In Hardware", "name": "SIH_VEHICLE_TYPE", "rebootRequired": true, "shortDesc": "Vehicle type", "type": "Int32", "values": [{"description": "Quadcopter", "value": 0}, {"description": "Fixed-Wing", "value": 1}, {"description": "Tailsitter", "value": 2}, {"description": "Standard VTOL", "value": 3}, {"description": "Hexacopter", "value": 4}, {"description": "Rover Ackermann", "value": 5}]}, {"bitmask": [{"description": "Stuck", "index": 0}, {"description": "Drift", "index": 1}], "category": "Standard", "default": 0, "group": "Simulator", "longDesc": "Stuck: freeze the measurement to the current location\nDrift: add a linearly growing bias to the sensor data", "max": 3, "min": 0, "name": "SIM_AGP_FAIL", "shortDesc": "AGP failure mode", "type": "Int32"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_BARO_OFF_P", "shortDesc": "simulated barometer pressure offset", "type": "Float"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_BARO_OFF_T", "shortDesc": "simulated barometer temperature offset", "type": "Float", "units": "celcius"}, {"category": "Standard", "default": 10, "group": "Simulator", "max": 50, "min": 0, "name": "SIM_GPS_USED", "shortDesc": "simulated GPS number of satellites used", "type": "Int32"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_X", "shortDesc": "simulated magnetometer X offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_Y", "shortDesc": "simulated magnetometer Y offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0.0, "group": "Simulator", "name": "SIM_MAG_OFFSET_Z", "shortDesc": "simulated magnetometer Z offset", "type": "Float", "units": "gauss"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "Set to 1 to reset parameters on next system startup (setting defaults).\nPlatform-specific values are used if available.\nRC* parameters are preserved.", "name": "SYS_AUTOCONFIG", "shortDesc": "Automatically configure default values", "type": "Int32", "values": [{"description": "Keep parameters", "value": 0}, {"description": "Reset parameters to airframe defaults", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "CHANGING THIS VALUE REQUIRES A RESTART. Defines the auto-start script used to bootstrap the system.", "max": 9999999, "min": 0, "name": "SYS_AUTOSTART", "rebootRequired": true, "shortDesc": "Auto-start script index", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled, update the bootloader on the next boot.\nWARNING: do not cut the power during an update process, otherwise you will\nhave to recover using some alternative method (e.g. JTAG).\nInstructions:\n- Insert an SD card\n- Enable this parameter\n- Reboot the board (plug the power or send a reboot command)\n- Wait until the board comes back up (or at least 2 minutes)\n- If it does not come back, check the file bootlog.txt on the SD card", "name": "SYS_BL_UPDATE", "rebootRequired": true, "shortDesc": "Bootloader update", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_ACCEL", "shortDesc": "Enable auto start of accelerometer thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_BARO", "shortDesc": "Enable auto start of barometer thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "0 : Set to 0 to do nothing\n1 : Set to 1 to start a calibration at next boot\nThis parameter is reset to zero when the temperature calibration starts.\ndefault (0, no calibration)", "max": 1, "min": 0, "name": "SYS_CAL_GYRO", "shortDesc": "Enable auto start of rate gyro thermal calibration at the next power up", "type": "Int32"}, {"category": "Standard", "default": 24, "group": "System", "longDesc": "A temperature increase greater than this value is required during calibration.\nCalibration will complete for each sensor when the temperature increase above the starting temperature exceeds the value set by SYS_CAL_TDEL.\nIf the temperature rise is insufficient, the calibration will continue indefinitely and the board will need to be repowered to exit.", "min": 10, "name": "SYS_CAL_TDEL", "shortDesc": "Required temperature rise during thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 10, "group": "System", "longDesc": "Temperature calibration will not start if the temperature of any sensor is higher than the value set by SYS_CAL_TMAX.", "name": "SYS_CAL_TMAX", "shortDesc": "Maximum starting temperature for thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 5, "group": "System", "longDesc": "Temperature calibration for each sensor will ignore data if the temperature is lower than the value set by SYS_CAL_TMIN.", "name": "SYS_CAL_TMIN", "shortDesc": "Minimum starting temperature for thermal calibration", "type": "Int32", "units": "celcius"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If the board supports persistent storage (i.e., the KConfig variable DATAMAN_PERSISTENT_STORAGE is set),\nthe 'Default storage' backend uses a file on persistent storage. If not supported, this backend uses\nnon-persistent storage in RAM.", "name": "SYS_DM_BACKEND", "rebootRequired": true, "shortDesc": "Dataman storage backend", "type": "Int32", "values": [{"description": "Dataman disabled", "value": -1}, {"description": "Default storage", "value": 0}, {"description": "RAM storage", "value": 1}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled, future sensor calibrations will be stored to /fs/mtd_caldata.\nNote: this is only supported on boards with a separate calibration storage\n/fs/mtd_caldata.", "name": "SYS_FAC_CAL_MODE", "shortDesc": "Enable factory calibration mode", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "All sensors", "value": 1}, {"description": "All sensors except mag", "value": 2}]}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "If enabled allows MAVLink INJECT_FAILURE commands.\nWARNING: the failures can easily cause crashes and are to be used with caution!", "name": "SYS_FAILURE_EN", "shortDesc": "Enable failure injection", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "Disable this if the board has no barometer, such as some of the Omnibus\nF4 SD variants.\nIf disabled, the preflight checks will not check for the presence of a\nbarometer.", "name": "SYS_HAS_BARO", "rebootRequired": true, "shortDesc": "Control if the vehicle has a barometer", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "Disable this if the system has no GPS.\nIf disabled, the sensors hub will not process sensor_gps,\nand GPS will not be available for the rest of the system.", "name": "SYS_HAS_GPS", "rebootRequired": true, "shortDesc": "Control if the vehicle has a GPS", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "0: System has no magnetometer, preflight checks should pass without one.\n1-N: Require the presence of N magnetometer sensors for check to pass.", "name": "SYS_HAS_MAG", "rebootRequired": true, "shortDesc": "Control if and how many magnetometers are expected", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "Set this to 0 if the board has no airspeed sensor.\nIf set to 0, the preflight checks will not check for the presence of an\nairspeed sensor.", "max": 1, "min": 0, "name": "SYS_HAS_NUM_ASPD", "shortDesc": "Control if the vehicle has an airspeed sensor", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "The preflight check will fail if fewer than this number of distance sensors with valid data is present.\nDisable the check with 0.", "max": 4, "min": 0, "name": "SYS_HAS_NUM_DIST", "shortDesc": "Number of distance sensors to check being available", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "The preflight check will fail if fewer than this number of optical flow sensors with valid data are present.", "max": 1, "min": 0, "name": "SYS_HAS_NUM_OF", "shortDesc": "Number of optical flow sensors required to be available", "type": "Int32"}, {"category": "Standard", "default": 0, "group": "System", "longDesc": "While enabled the system will boot in Hardware-In-The-Loop (HITL)\nor Simulation-In-Hardware (SIH) mode and not enable all sensors and checks.\nWhen disabled the same vehicle can be flown normally.\nSet to 'external HITL', if the system should perform as if it were a real\nvehicle (the only difference to a real system is then only the parameter\nvalue, which can be used for log analysis).", "name": "SYS_HITL", "rebootRequired": true, "shortDesc": "Enable HITL/SIH mode on next boot", "type": "Int32", "values": [{"description": "external HITL", "value": -1}, {"description": "HITL and SIH disabled", "value": 0}, {"description": "HITL enabled", "value": 1}, {"description": "SIH enabled", "value": 2}]}, {"category": "Standard", "default": 1, "group": "System", "longDesc": "This is used internally only: an airframe configuration might set an expected\nparameter version value via PARAM_DEFAULTS_VER. This is checked on bootup\nagainst SYS_PARAM_VER, and if they do not match, parameters are reset and\nreloaded from the airframe configuration.", "min": 0, "name": "SYS_PARAM_VER", "shortDesc": "Parameter version", "type": "Int32"}, {"category": "Standard", "default": 1.0, "group": "System", "longDesc": "Set to 0 to disable, 1 for maximum brightness", "name": "SYS_RGB_MAXBRT", "shortDesc": "RGB Led brightness limit", "type": "Float", "units": "%"}, {"category": "Standard", "default": 1, "group": "System", "name": "SYS_STCK_EN", "shortDesc": "Enable stack checking", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 2, "group": "Testing", "name": "TEST_1", "shortDesc": "TEST_1", "type": "Int32"}, {"category": "Standard", "default": 4, "group": "Testing", "name": "TEST_2", "shortDesc": "TEST_2", "type": "Int32"}, {"category": "Standard", "default": 5.0, "group": "Testing", "name": "TEST_3", "shortDesc": "TEST_3", "type": "Float"}, {"category": "Standard", "default": 0.01, "group": "Testing", "name": "TEST_D", "shortDesc": "TEST_D", "type": "Float"}, {"category": "Standard", "default": 2.0, "group": "Testing", "name": "TEST_DEV", "shortDesc": "TEST_DEV", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_D_LP", "shortDesc": "TEST_D_LP", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_HP", "shortDesc": "TEST_HP", "type": "Float"}, {"category": "Standard", "default": 0.1, "group": "Testing", "name": "TEST_I", "shortDesc": "TEST_I", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_I_MAX", "shortDesc": "TEST_I_MAX", "type": "Float"}, {"category": "Standard", "default": 10.0, "group": "Testing", "name": "TEST_LP", "shortDesc": "TEST_LP", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_MAX", "shortDesc": "TEST_MAX", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "Testing", "name": "TEST_MEAN", "shortDesc": "TEST_MEAN", "type": "Float"}, {"category": "Standard", "default": -1.0, "group": "Testing", "name": "TEST_MIN", "shortDesc": "TEST_MIN", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "Testing", "name": "TEST_P", "shortDesc": "TEST_P", "type": "Float"}, {"category": "Standard", "default": 12345678, "group": "Testing", "name": "TEST_PARAMS", "shortDesc": "TEST_PARAMS", "type": "Int32"}, {"category": "Standard", "default": 16, "group": "Testing", "name": "TEST_RC2_X", "shortDesc": "TEST_RC2_X", "type": "Int32"}, {"category": "Standard", "default": 8, "group": "Testing", "name": "TEST_RC_X", "shortDesc": "TEST_RC_X", "type": "Int32"}, {"category": "Standard", "default": 0.5, "group": "Testing", "name": "TEST_TRIM", "shortDesc": "TEST_TRIM", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A0_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A0_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A0_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A0_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A1_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A1_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A1_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A1_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A2_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A2_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A2_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A2_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_A3_ID", "shortDesc": "ID of Accelerometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_A3_TMAX", "shortDesc": "Accelerometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_TMIN", "shortDesc": "Accelerometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_A3_TREF", "shortDesc": "Accelerometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_0", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_1", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X0_2", "shortDesc": "Accelerometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_0", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_1", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X1_2", "shortDesc": "Accelerometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_0", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_1", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X2_2", "shortDesc": "Accelerometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_0", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_1", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_A3_X3_2", "shortDesc": "Accelerometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_A_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for accelerometer sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B0_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B0_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B0_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B0_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B0_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B1_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B1_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B1_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B1_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B1_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B2_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B2_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B2_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B2_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B2_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_B3_ID", "shortDesc": "ID of Barometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 75.0, "group": "Thermal Compensation", "name": "TC_B3_TMAX", "shortDesc": "Barometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 5.0, "group": "Thermal Compensation", "name": "TC_B3_TMIN", "shortDesc": "Barometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 40.0, "group": "Thermal Compensation", "name": "TC_B3_TREF", "shortDesc": "Barometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X0", "shortDesc": "Barometer offset temperature ^0 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X1", "shortDesc": "Barometer offset temperature ^1 polynomial coefficients", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X2", "shortDesc": "Barometer offset temperature ^2 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X3", "shortDesc": "Barometer offset temperature ^3 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X4", "shortDesc": "Barometer offset temperature ^4 polynomial coefficient", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_B3_X5", "shortDesc": "Barometer offset temperature ^5 polynomial coefficient", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_B_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for barometric pressure sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G0_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G0_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G0_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G0_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G1_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G1_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G1_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G1_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G2_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G2_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G2_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G2_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_G3_ID", "shortDesc": "ID of Gyro that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_G3_TMAX", "shortDesc": "Gyro calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_TMIN", "shortDesc": "Gyro calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_G3_TREF", "shortDesc": "Gyro calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_0", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_1", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X0_2", "shortDesc": "Gyro rate offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_0", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_1", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X1_2", "shortDesc": "Gyro rate offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_0", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_1", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X2_2", "shortDesc": "Gyro rate offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_0", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_1", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_G3_X3_2", "shortDesc": "Gyro rate offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_G_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for rate gyro sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M0_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M0_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M0_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M0_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M1_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M1_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M1_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M1_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M2_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M2_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M2_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M2_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0, "group": "Thermal Compensation", "name": "TC_M3_ID", "shortDesc": "ID of Magnetometer that the calibration is for", "type": "Int32"}, {"category": "System", "default": 100.0, "group": "Thermal Compensation", "name": "TC_M3_TMAX", "shortDesc": "Magnetometer calibration maximum temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_TMIN", "shortDesc": "Magnetometer calibration minimum temperature", "type": "Float"}, {"category": "System", "default": 25.0, "group": "Thermal Compensation", "name": "TC_M3_TREF", "shortDesc": "Magnetometer calibration reference temperature", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_0", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_1", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X0_2", "shortDesc": "Magnetometer offset temperature ^0 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_0", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_1", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X1_2", "shortDesc": "Magnetometer offset temperature ^1 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_0", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_1", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X2_2", "shortDesc": "Magnetometer offset temperature ^2 polynomial coefficient - Z axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_0", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - X axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_1", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Y axis", "type": "Float"}, {"category": "System", "default": 0.0, "group": "Thermal Compensation", "name": "TC_M3_X3_2", "shortDesc": "Magnetometer offset temperature ^3 polynomial coefficient - Z axis", "type": "Float"}, {"category": "Standard", "default": 0, "group": "Thermal Compensation", "name": "TC_M_ENABLE", "rebootRequired": true, "shortDesc": "Thermal compensation for magnetometer sensors", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_MGM_PITCH", "shortDesc": "Pitch gain for manual inputs in manual control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_MGM_ROLL", "shortDesc": "Roll gain for manual inputs in manual control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_MGM_THRTL", "shortDesc": "Throttle gain for manual inputs in manual control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.05, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_MGM_YAW", "shortDesc": "Yaw gain for manual inputs in manual control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "UUV Attitude Control", "name": "UUV_PITCH_D", "shortDesc": "Pitch differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_PITCH_P", "shortDesc": "Pitch proportional gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 100.0, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_RGM_PITCH", "shortDesc": "Pitch gain for manual inputs in rate control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 100.0, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_RGM_ROLL", "shortDesc": "Roll gain for manual inputs in rate control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_RGM_THRTL", "shortDesc": "Throttle gain for manual inputs in rate control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 100.0, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_RGM_YAW", "shortDesc": "Yaw gain for manual inputs in rate control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.5, "group": "UUV Attitude Control", "name": "UUV_ROLL_D", "shortDesc": "Roll differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_ROLL_P", "shortDesc": "Roll proportional gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_SGM_PITCH", "shortDesc": "Pitch gain for manual inputs in attitude control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_SGM_ROLL", "shortDesc": "Roll gain for manual inputs in attitude control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_SGM_THRTL", "shortDesc": "Throttle gain for manual inputs in attitude control mode", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.5, "group": "UUV Attitude Control", "min": 0.0, "name": "UUV_SGM_YAW", "shortDesc": "Yaw gain for manual inputs in attitude control mode", "type": "Float"}, {"category": "Standard", "default": 2.0, "group": "UUV Attitude Control", "name": "UUV_SP_MAX_AGE", "shortDesc": "Maximum time (in seconds) before resetting setpoint", "type": "Float"}, {"category": "Standard", "default": 0, "group": "UUV Attitude Control", "max": 1, "min": 0, "name": "UUV_STICK_MODE", "shortDesc": "Stick mode selector (0=Heave/sway control, roll/pitch leveled; 1=Pitch/roll control)", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "UUV Attitude Control", "max": 1.0, "min": 0.0, "name": "UUV_THRUST_SAT", "shortDesc": "UUV Thrust setpoint Saturation", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.3, "group": "UUV Attitude Control", "max": 1.0, "min": 0.0, "name": "UUV_TORQUE_SAT", "shortDesc": "UUV Torque setpoint Saturation", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "UUV Attitude Control", "name": "UUV_YAW_D", "shortDesc": "Yaw differential gain", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 4.0, "group": "UUV Attitude Control", "name": "UUV_YAW_P", "shortDesc": "Yawh proportional gain", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_X_D", "shortDesc": "Gain of D controller X", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_X_P", "shortDesc": "Gain of P controller X", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_Y_D", "shortDesc": "Gain of D controller Y", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_Y_P", "shortDesc": "Gain of P controller Y", "type": "Float"}, {"category": "Standard", "default": 0.2, "group": "UUV Position Control", "name": "UUV_GAIN_Z_D", "shortDesc": "Gain of D controller Z", "type": "Float"}, {"category": "Standard", "default": 1.0, "group": "UUV Position Control", "name": "UUV_GAIN_Z_P", "shortDesc": "Gain of P controller Z", "type": "Float"}, {"category": "Standard", "default": 0.5, "group": "UUV Position Control", "name": "UUV_PGM_VEL", "shortDesc": "Gain for position control velocity setpoint update", "type": "Float"}, {"category": "Standard", "default": 1, "group": "UUV Position Control", "name": "UUV_POS_MODE", "shortDesc": "Stabilization mode(1) or Position Control(0)", "type": "Int32", "values": [{"description": "Moves position setpoint in world frame", "value": 0}, {"description": "Moves position setpoint in body frame", "value": 1}]}, {"category": "Standard", "default": 0.1, "group": "UUV Position Control", "name": "UUV_POS_STICK_DB", "shortDesc": "Deadband for changing position setpoint", "type": "Float"}, {"category": "Standard", "default": 1, "group": "UUV Position Control", "name": "UUV_STAB_MODE", "shortDesc": "Stabilization mode(1) or Position Control(0)", "type": "Int32", "values": [{"description": "Tracks previous attitude setpoint", "value": 0}, {"description": "Tracks horizontal attitude (allows yaw change)", "value": 1}]}, {"category": "Standard", "default": 2130706433, "group": "UXRCE-DDS Client", "longDesc": "If ethernet is enabled and is the selected configuration for uXRCE-DDS,\nthe selected Agent IP address will be set and used.\nDecimal dot notation is not supported. IP address must be provided\nin int32 format. For example, 192.168.1.2 is mapped to -1062731518;\n127.0.0.1 is mapped to 2130706433.", "name": "UXRCE_DDS_AG_IP", "rebootRequired": true, "shortDesc": "uXRCE-DDS Agent IP address", "type": "Int32"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "uXRCE-DDS domain ID", "name": "UXRCE_DDS_DOM_ID", "rebootRequired": true, "shortDesc": "uXRCE-DDS domain ID", "type": "Int32"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "This is used to enable flow control for the serial uXRCE instance.\nUsed for reliable high bandwidth communication.", "name": "UXRCE_DDS_FLCTRL", "rebootRequired": true, "shortDesc": "Enable serial flow control for UXRCE interface", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "UXRCE-DDS Client", "longDesc": "uXRCE-DDS key, must be different from zero.\nIn a single agent - multi client configuration, each client\nmust have a unique session key.", "name": "UXRCE_DDS_KEY", "rebootRequired": true, "shortDesc": "uXRCE-DDS session key", "type": "Int32"}, {"category": "System", "default": -1, "group": "UXRCE-DDS Client", "longDesc": "Defines an index-based namespace for DDS messages, e.g, uav_0, uav_1, up to uav_9999\nA value less than zero leaves the namespace empty", "max": 9999, "min": -1, "name": "UXRCE_DDS_NS_IDX", "rebootRequired": true, "shortDesc": "Define an index-based message namespace", "type": "Int32"}, {"category": "Standard", "default": 8888, "group": "UXRCE-DDS Client", "longDesc": "If ethernet is enabled and is the selected configuration for uXRCE-DDS,\nthe selected UDP port will be set and used.", "max": 65535, "min": 0, "name": "UXRCE_DDS_PRT", "rebootRequired": true, "shortDesc": "uXRCE-DDS UDP port", "type": "Int32"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "Set the participant configuration on the Agent's system.\n0: Use the default configuration.\n1: Restrict messages to localhost\n(use in combination with ROS_LOCALHOST_ONLY=1).\n2: Use a custom participant with the profile name \"px4_participant\".", "max": 2, "min": 0, "name": "UXRCE_DDS_PTCFG", "rebootRequired": true, "shortDesc": "uXRCE-DDS participant configuration", "type": "Int32", "values": [{"description": "Default", "value": 0}, {"description": "Localhost-only", "value": 1}, {"description": "Custom participant", "value": 2}]}, {"category": "System", "default": -1, "group": "UXRCE-DDS Client", "longDesc": "Specifies after how many seconds without receiving data the DDS connection is reestablished.\nA value less than one disables the RX rate timeout.", "name": "UXRCE_DDS_RX_TO", "rebootRequired": true, "shortDesc": "RX rate timeout configuration", "type": "Int32", "units": "s"}, {"category": "System", "default": 0, "group": "UXRCE-DDS Client", "longDesc": "When enabled along with UXRCE_DDS_SYNCT, uxrce_dds_client will set the system clock using the agents UTC timestamp.", "name": "UXRCE_DDS_SYNCC", "rebootRequired": true, "shortDesc": "Enable uXRCE-DDS system clock synchronization", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 1, "group": "UXRCE-DDS Client", "longDesc": "When enabled, uxrce_dds_client will synchronize the timestamps of the incoming and outgoing messages measuring the offset between the Agent OS time and the PX4 time.", "name": "UXRCE_DDS_SYNCT", "rebootRequired": true, "shortDesc": "Enable uXRCE-DDS timestamp synchronization", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "System", "default": 3, "group": "UXRCE-DDS Client", "longDesc": "Specifies after how many seconds without sending data the DDS connection is reestablished.\nA value less than one disables the TX rate timeout.", "name": "UXRCE_DDS_TX_TO", "rebootRequired": true, "shortDesc": "TX rate timeout configuration", "type": "Int32", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 8.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Airspeed at which we can start blending both fw and mc controls. Set to 0 to disable.", "max": 30.0, "min": 0.0, "name": "VT_ARSP_BLEND", "shortDesc": "Transition blending airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Airspeed at which we can switch to fw mode", "max": 30.0, "min": 0.0, "name": "VT_ARSP_TRANS", "shortDesc": "Transition airspeed", "type": "Float", "units": "m/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Time in seconds it takes to tilt form VT_TILT_FW to VT_TILT_MC.", "max": 10.0, "min": 0.1, "name": "VT_BT_TILT_DUR", "shortDesc": "Duration motor tilt up in backtransition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "VTOL Attitude Control", "increment": 0.05, "max": 0.3, "min": 0.0, "name": "VT_B_DEC_I", "shortDesc": "Backtransition deceleration setpoint to tilt I gain", "type": "Float", "units": "rad s/m"}, {"category": "Standard", "decimalPlaces": 2, "default": 2.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Used to calculate back transition distance in an auto mode.\nFor standard vtol and tiltrotors a controller is used to track this value during the transition.", "max": 10.0, "min": 0.5, "name": "VT_B_DEC_MSS", "shortDesc": "Approximate deceleration during back transition", "type": "Float", "units": "m/s^2"}, {"category": "Standard", "decimalPlaces": 2, "default": 10.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Transition is also declared over if the groundspeed drops below MPC_XY_CRUISE.", "max": 20.0, "min": 0.1, "name": "VT_B_TRANS_DUR", "shortDesc": "Maximum duration of a back transition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 3.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "This sets the duration during which the MC motors ramp up to the commanded thrust during the back transition stage.", "max": 20.0, "min": 0.0, "name": "VT_B_TRANS_RAMP", "shortDesc": "Back transition MC motor ramp up time", "type": "Float", "units": "s"}, {"category": "Standard", "default": 1, "group": "VTOL Attitude Control", "longDesc": "If set to 1 the control surfaces are locked at the disarmed value in multicopter mode.", "name": "VT_ELEV_MC_LOCK", "shortDesc": "Lock control surfaces in hover", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled", "value": 1}]}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Prevents downforce from pitching the body down when facing wind.\nUses puller/pusher (standard VTOL), or forward-tilt (tiltrotor VTOL) to accelerate forward instead.\nOnly active if demanded pitch is below VT_PITCH_MIN.\nUse VT_FWD_THRUST_SC to tune it.\nDescend mode is treated as Landing too.\nOnly active (if enabled) in height-rate controlled modes.", "name": "VT_FWD_THRUST_EN", "shortDesc": "Use fixed-wing actuation in hover to accelerate forward", "type": "Int32", "values": [{"description": "Disabled", "value": 0}, {"description": "Enabled (except LANDING)", "value": 1}, {"description": "Enabled if above MPC_LAND_ALT1", "value": 2}, {"description": "Enabled if above MPC_LAND_ALT2", "value": 3}, {"description": "Enabled constantly", "value": 4}, {"description": "Enabled if above MPC_LAND_ALT1 (except LANDING)", "value": 5}, {"description": "Enabled if above MPC_LAND_ALT2 (except LANDING)", "value": 6}]}, {"category": "Standard", "decimalPlaces": 2, "default": 0.7, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Scale applied to the demanded pitch (below VT_PITCH_MIN) to get the fixed-wing forward actuation in hover mode.\nEnabled via VT_FWD_THRUST_EN.", "max": 5.0, "min": 0.0, "name": "VT_FWD_THRUST_SC", "shortDesc": "Fixed-wing actuation thrust scale in hover", "type": "Float"}, {"bitmask": [{"description": "Yaw", "index": 0}, {"description": "Roll", "index": 1}, {"description": "Pitch", "index": 2}], "category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Enable differential thrust seperately for roll, pitch, yaw in forward (fixed-wing) mode.\nThe effectiveness of differential thrust around the corresponding axis can be\ntuned by setting VT_FW_DIFTHR_S_R / VT_FW_DIFTHR_S_P / VT_FW_DIFTHR_S_Y.", "max": 7, "min": 0, "name": "VT_FW_DIFTHR_EN", "shortDesc": "Differential thrust in forwards flight", "type": "Int32"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_P", "shortDesc": "Pitch differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_R", "shortDesc": "Roll differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.1, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Differential thrust in forward flight is enabled via VT_FW_DIFTHR_EN.", "max": 2.0, "min": 0.0, "name": "VT_FW_DIFTHR_S_Y", "shortDesc": "Yaw differential thrust factor in forward flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Minimum altitude for fixed-wing flight. When the vehicle is in fixed-wing mode\nand the altitude drops below this altitude (relative altitude above local origin),\nit will instantly switch back to MC mode and execute behavior defined in COM_QC_ACT.", "max": 200.0, "min": 0.0, "name": "VT_FW_MIN_ALT", "shortDesc": "Quad-chute altitude", "type": "Float", "units": "m"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "increment": 1, "longDesc": "Maximum height above the ground (if available, otherwise above\nHome if available, otherwise above the local origin) where triggering a quad-chute is possible.\nAt high altitudes there is a big risk to deplete the battery and therefore crash if quad-chuting there.", "min": 0, "name": "VT_FW_QC_HMAX", "shortDesc": "Quad-chute maximum height", "type": "Int32", "units": "m"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Absolute pitch threshold for quad-chute triggering in FW mode.\nAbove this the vehicle will transition back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 180, "min": 0, "name": "VT_FW_QC_P", "shortDesc": "Quad-chute max pitch threshold", "type": "Int32", "units": "deg"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "longDesc": "Absolute roll threshold for quad-chute triggering in FW mode.\nAbove this the vehicle will transition back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 180, "min": 0, "name": "VT_FW_QC_R", "shortDesc": "Quad-chute max roll threshold", "type": "Int32", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 5.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Time in seconds used for a transition", "max": 20.0, "min": 0.1, "name": "VT_F_TRANS_DUR", "shortDesc": "Duration of a front transition", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_F_TRANS_THR", "shortDesc": "Target throttle value for the transition to fixed-wing flight", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 6.0, "group": "VTOL Attitude Control", "increment": 0.5, "longDesc": "The duration of the front transition when there is no airspeed feedback available.\nWhen airspeed is used, transition timeout is declared if airspeed does not\nreach VT_ARSP_BLEND after this time.", "max": 30.0, "min": 1.0, "name": "VT_F_TR_OL_TM", "shortDesc": "Airspeed-less front transition time (open loop)", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Overrides VT_PITCH_MIN when the vehicle is in LAND mode (hovering).\nDuring landing it can be beneficial to reduce the pitch angle to reduce the generated lift in head wind.", "max": 45.0, "min": -10.0, "name": "VT_LND_PITCH_MIN", "shortDesc": "Minimum pitch angle during hover landing", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Any pitch setpoint below this value is translated to a forward force by the fixed-wing forward actuation if\nVT_FWD_TRHUST_EN is set.", "max": 45.0, "min": -10.0, "name": "VT_PITCH_MIN", "shortDesc": "Minimum pitch angle during hover", "type": "Float", "units": "deg"}, {"category": "Standard", "decimalPlaces": 2, "default": 0.33, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Defines the slew rate of the puller/pusher throttle during transitions.\nZero will deactivate the slew rate limiting and thus produce an instant throttle\nrise to the transition throttle VT_F_TRANS_THR.", "min": 0.0, "name": "VT_PSHER_SLEW", "shortDesc": "Pusher throttle ramp up slew rate", "type": "Float", "units": "1/s"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Altitude error threshold for quad-chute triggering during fixed-wing flight.\nThe check is only active if altitude is controlled and the vehicle is below the current altitude reference.\nThe altitude error is relative to the highest altitude the vehicle has achieved since it has flown below the current\naltitude reference.\nSet to 0 do disable.", "max": 200.0, "min": 0.0, "name": "VT_QC_ALT_LOSS", "shortDesc": "Quad-chute uncommanded descent threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 20.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Altitude loss threshold for quad-chute triggering during VTOL transition to fixed-wing flight\nin altitude-controlled flight modes.\nActive until 5s after completing transition to fixed-wing.\nIf the current altitude is more than this value below the altitude at the beginning of the\ntransition, it will instantly switch back to MC mode and execute behavior defined in COM_QC_ACT.\nSet to 0 do disable this threshold.", "max": 50.0, "min": 0.0, "name": "VT_QC_T_ALT_LOSS", "shortDesc": "Quad-chute transition altitude loss threshold", "type": "Float", "units": "m"}, {"category": "Standard", "decimalPlaces": 1, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.1, "max": 1.0, "min": -1.0, "name": "VT_SPOILER_MC_LD", "shortDesc": "Spoiler setting while landing (hover)", "type": "Float", "units": "norm"}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_FW", "shortDesc": "Normalized tilt in FW", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.0, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_MC", "shortDesc": "Normalized tilt in Hover", "type": "Float"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.4, "group": "VTOL Attitude Control", "increment": 0.01, "max": 1.0, "min": 0.0, "name": "VT_TILT_TRANS", "shortDesc": "Normalized tilt in transition to FW", "type": "Float"}, {"category": "Standard", "decimalPlaces": 1, "default": 2.0, "group": "VTOL Attitude Control", "increment": 0.1, "longDesc": "Minimum time in seconds for front transition.", "max": 20.0, "min": 0.0, "name": "VT_TRANS_MIN_TM", "shortDesc": "Front transition minimum time", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 3, "default": 0.5, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "Time in seconds it takes to tilt form VT_TILT_TRANS to VT_TILT_FW.", "max": 5.0, "min": 0.1, "name": "VT_TRANS_P2_DUR", "shortDesc": "Duration of front transition phase 2", "type": "Float", "units": "s"}, {"category": "Standard", "decimalPlaces": 2, "default": 15.0, "group": "VTOL Attitude Control", "increment": 1.0, "longDesc": "Time in seconds after which transition will be cancelled.", "max": 30.0, "min": 0.1, "name": "VT_TRANS_TIMEOUT", "shortDesc": "Front transition timeout", "type": "Float", "units": "s"}, {"category": "Standard", "default": 0, "group": "VTOL Attitude Control", "max": 2, "min": 0, "name": "VT_TYPE", "rebootRequired": true, "shortDesc": "VTOL Type (Tailsitter=0, Tiltrotor=1, Standard=2)", "type": "Int32", "values": [{"description": "Tailsitter", "value": 0}, {"description": "Tiltrotor", "value": 1}, {"description": "Standard", "value": 2}]}, {"category": "Standard", "decimalPlaces": 3, "default": 1.0, "group": "VTOL Attitude Control", "increment": 0.01, "longDesc": "The desired gain to convert roll sp into yaw rate sp.", "max": 3.0, "min": 0.0, "name": "WV_GAIN", "shortDesc": "Weather-vane roll angle to yawrate", "type": "Float", "units": "Hz"}, {"category": "Standard", "decimalPlaces": 1, "default": 80.0, "group": "VTOL Takeoff", "increment": 1.0, "longDesc": "Altitude relative to home at which vehicle will loiter after front transition.", "max": 300.0, "min": 20.0, "name": "VTO_LOITER_ALT", "shortDesc": "VTOL Takeoff relative loiter altitude", "type": "Float", "units": "m"}], "translation": {"items": {"parameters": {"list": {"items": {"bitmask": {"list": {"key": "index", "translate": ["description"]}}, "values": {"list": {"key": "value", "translate": ["description"]}}}, "key": "name", "translate": ["shortDesc", "longDesc"], "translate-global": ["category", "group"]}}}}, "version": 1} \ No newline at end of file diff --git a/docs/public/og-image.png b/docs/public/og-image.png new file mode 100644 index 0000000000..5625b82550 Binary files /dev/null and b/docs/public/og-image.png differ diff --git a/docs/uk/SUMMARY.md b/docs/uk/SUMMARY.md index 80ccf0fc76..dc24c04642 100644 --- a/docs/uk/SUMMARY.md +++ b/docs/uk/SUMMARY.md @@ -7,6 +7,7 @@ - [Position Mode (MC)](flight_modes_mc/position.md) - [Position Slow Mode (MC)](flight_modes_mc/position_slow.md) - [Altitude Mode (MC)](flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](flight_modes_mc/manual_stabilized.md) - [Acro Mode (MC)](flight_modes_mc/acro.md) - [Orbit Mode (MC)](flight_modes_mc/orbit.md) @@ -34,7 +35,7 @@ - [Static Pressure Buildup](advanced_config/static_pressure_buildup.md) - [Flying (Basics)](flying/basic_flying_mc.md) - [Complete Vehicles](complete_vehicles_mc/index.md) - - [ModalAI Starling (PX4 Dev Kit)](complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling](complete_vehicles_mc/modalai_starling.md) - [PX4 Vision Kit](complete_vehicles_mc/px4_vision_kit.md) - [MindRacer BNF & RTF](complete_vehicles_mc/mindracer_BNF_RTF.md) - [MindRacer 210](complete_vehicles_mc/mindracer210.md) @@ -55,11 +56,14 @@ - [DJI F450 (CUAV v5 nano)](frames_multicopter/dji_f450_cuav_5nano.md) - [Літаки (з фіксованим крилом)](frames_plane/index.md) + - [Features](features_fw/index.md) + - [Gain compression](features_fw/gain_compression.md) - [Збірка](assembly/assembly_fw.md) - [Конфігурація/підлаштування](config_fw/index.md) - [Auto-tune](config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](flying/basic_flying_fw.md) @@ -89,6 +93,7 @@ - [Настройка Зворотнього Переходу](config_vtol/vtol_back_transition_tuning.md) - [ВЗІП Датчик польоту](config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [Режим польоту](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -124,6 +129,7 @@ - [Значення світлодіодів](getting_started/led_meanings.md) - [Значення звуків та мелодій](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Вибір обладнання & Налаштування](hardware/drone_parts.md) - [Flight Controllers (Autopilots)](flight_controller/index.md) @@ -157,6 +163,7 @@ - [Швидке підключення mRo (3DR) Pixhawk](assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Припинено](flight_controller/pixhawk_mini.md) - [Автопілоти, що підтримуються виробником](flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](flight_controller/mindpx.md) - [AirMind MindRacer](flight_controller/mindracer.md) - [ARK Electronics ARKV6X](flight_controller/ark_v6x.md) @@ -180,12 +187,16 @@ - [Wiring Quickstart](assembly/quick_start_durandal.md) - [Holybro Pix32 v5](flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](assembly/quick_start_holybro_pix32_v5.md) + - [MicoAir H743 Lite](flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](flight_controller/modalai_voxl_2.md) - [mRo Control Zero F7](flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](flight_controller/spracingh7extreme.md) + - [SVehicle E2](flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](flight_controller/thepeach_r1.md) + - [AP-H743-R1](flight_controller/x-mav_ap-h743r1.md) - [Калібрування рівня горизонту](flight_controller/autopilot_experimental.md) - [BeagleBone Blue](flight_controller/beaglebone_blue.md) - [Raspberry Pi 2/3 Navio2](flight_controller/raspberry_pi_navio2.md) @@ -238,18 +249,22 @@ - [ВЗІП Датчик польоту](sensor/airspeed_tfslot.md) - [Барометри](sensor/barometer.md) - [Датчики відстані \(далекодобива\)](sensor/rangefinders.md) + - [Стандартний радарний висотомір Ainstein US-D1](sensor/ulanding_radar.md) + - [ARK DIST SR (CAN/UART)](dronecan/ark_dist.md) + - [ARK DIST MR (CAN/UART)](dronecan/ark_dist_mr.md) + - [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 SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md) - - [Стандартний радарний висотомір Ainstein US-D1](sensor/ulanding_radar.md) - - [LeddarOne Lidar](sensor/leddar_one.md) - - [Benewake TFmini Lidar](sensor/tfmini.md) - - [Lidar-Lite](sensor/lidar_lite.md) - [TeraRanger](sensor/teraranger.md) - [✘ Lanbao PSK-CM8JL65-CC5](sensor/cm8jl65_ir_distance_sensor.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface (CAN)](dronecan/avanon_laser_interface.md) - [GNSS (GPS)](gps_compass/index.md) - [ARK GPS (CAN)](dronecan/ark_gps.md) + - [ARK DAN GPS](gps_compass/ark_dan_gps.md) - [ARK SAM GPS](gps_compass/ark_sam_gps.md) + - [ARK SAM GPS MINI](gps_compass/ark_sam_gps_mini.md) - [ARK TESEO GPS](dronecan/ark_teseo_gps.md) - [CUAV NEO 3 GPS](gps_compass/gps_cuav_neo_3.md) - [CUAV NEO 3 Pro GPS (CAN)](gps_compass/gps_cuav_neo_3pro.md) @@ -260,7 +275,11 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) + - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) + - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) - [ARK MOSAIC-X5 RTK GPS (CAN)](dronecan/ark_mosaic__rtk_gps.md) - [RTK GPS Heading with Dual u-blox F9P](gps_compass/u-blox_f9p_heading.md) - [CUAV C-RTK](gps_compass/rtk_gps_cuav_c-rtk.md) @@ -283,6 +302,8 @@ - [CubePilot Here+ (Discontined)](gps_compass/rtk_gps_hex_hereplus.md) - [INS (Інерціальна навігація/GNSS)](sensor/inertial_navigation_systems.md) - [InertialLabs](sensor/inertiallabs.md) + - [MicroStrain](sensor/microstrain.md) + - [sbgECom](sensor/sbgecom.md) - [VectorNav](sensor/vectornav.md) - [Optical Flow](sensor/optical_flow.md) - [ARK Flow](dronecan/ark_flow.md) @@ -298,15 +319,17 @@ - [Розподіл приводу](config/actuators.md) - [Калібрування ESC (плати контролю двигунів)](advanced_config/esc_calibration.md) - [ESCs & Двигуни](peripherals/esc_motors.md) + - [ESC Protocols](esc/esc_protocols.md) - [PWM ESCs та сервоприводи](peripherals/pwm_escs_and_servo.md) - [DShot ESCs](peripherals/dshot.md) - [OneShot ESCs та сервоприводи](peripherals/oneshot.md) - [DroneCAN ESCs](dronecan/escs.md) - - [Zubax Telega](dronecan/zubax_telega.md) - - [Прошивка PX4 Sapog ESC](dronecan/sapog.md) - - [Holybro Kotleta](dronecan/holybro_kotleta.md) - - [Vertiq](peripherals/vertiq.md) - - [VESC](peripherals/vesc.md) + - [PX4 Sapog ESC Firmware](dronecan/sapog.md) + - [ARK 4IN1 ESC](esc/ark_4in1_esc.md) + - [Holybro Kotleta](dronecan/holybro_kotleta.md) + - [Vertiq Motor/ESC Modules](peripherals/vertiq.md) + - [VESC Project ESCs](peripherals/vesc.md) + - [Zubax Telega ESCs](dronecan/zubax_telega.md) - [Радіокерування (RC)](getting_started/rc_transmitter_receiver.md) - [Налаштування радіо](config/radio.md) @@ -339,17 +362,20 @@ - [Супутниковий зв'язок (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) + - [Енергетичні системи](power_systems/index.md) - [Налаштування оцінки батареї](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) - [Силові модулі/PDB](power_module/index.md) + - [ARK PAB Power Module](power_module/ark_pab_power_module.md) + - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](power_module/ark_12s_payload_power_module.md) - [CUAV HV pm](power_module/cuav_hv_pm.md) - [CUAV CAN PMU](dronecan/cuav_can_pmu.md) - [Holybro PM02](power_module/holybro_pm02.md) - [Holybro PM07](power_module/holybro_pm07_pixhawk4_power_module.md) - [Holybro PM06 V2](power_module/holybro_pm06_pixhawk4mini_power_module.md) - - [ARK PAB Power Module](power_module/ark_pab_power_module.md) - - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) - [Holybro PM02D (цифровий)](power_module/holybro_pm02d.md) - [Holybro PM03D (цифровий)](power_module/holybro_pm03d.md) - [Силовий модуль Pomegranate Systems](dronecan/pomegranate_systems_pm.md) @@ -432,6 +458,7 @@ - [Attitude Tuning](config_rover/attitude_tuning.md) - [Velocity Tuning](config_rover/velocity_tuning.md) - [Position Tuning](config_rover/position_tuning.md) + - [Apps & API](flight_modes_rover/api.md) - [Complete Vehicles](complete_vehicles_rover/index.md) - [Aion Robotics R1](complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](frames_sub/index.md) @@ -497,8 +524,10 @@ - [UART/Послідовний порт](uart/index.md) - [Драйвери послідовного порту і їх налаштування](uart/user_configurable_serial_driver.md) - [RTK GPS (Інтеграція)](advanced/rtk_gps.md) + - [PPS Time Synchronization](advanced/pps_time_sync.md) - [Проміжне програмне забезпечення](middleware/index.md) - [Повідомлення uORB](middleware/uorb.md) + - [uORB Docs Standard](uorb/uorb_documentation.md) - [Граф uORB](middleware/uorb_graph.md) - [Опис повідомлень uORB](msg_docs/index.md) - [Versioned](msg_docs/versioned_messages.md) @@ -561,6 +590,7 @@ - [DebugKeyValue](msg_docs/DebugKeyValue.md) - [DebugValue](msg_docs/DebugValue.md) - [DebugVect](msg_docs/DebugVect.md) + - [DeviceInformation](msg_docs/DeviceInformation.md) - [DifferentialPressure](msg_docs/DifferentialPressure.md) - [DistanceSensor](msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](msg_docs/DistanceSensorModeChangeRequest.md) @@ -593,6 +623,7 @@ - [FollowTargetEstimator](msg_docs/FollowTargetEstimator.md) - [FollowTargetStatus](msg_docs/FollowTargetStatus.md) - [FuelTankStatus](msg_docs/FuelTankStatus.md) + - [GainCompression](msg_docs/GainCompression.md) - [GeneratorStatus](msg_docs/GeneratorStatus.md) - [GeofenceResult](msg_docs/GeofenceResult.md) - [GeofenceStatus](msg_docs/GeofenceStatus.md) @@ -679,10 +710,10 @@ - [RoverPositionSetpoint](msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](msg_docs/RoverVelocityStatus.md) - [Rpm](msg_docs/Rpm.md) - [RtlStatus](msg_docs/RtlStatus.md) - [RtlTimeEstimate](msg_docs/RtlTimeEstimate.md) @@ -694,6 +725,7 @@ - [SensorCombined](msg_docs/SensorCombined.md) - [SensorCorrection](msg_docs/SensorCorrection.md) - [SensorGnssRelative](msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](msg_docs/SensorGnssStatus.md) - [SensorGps](msg_docs/SensorGps.md) - [SensorGyro](msg_docs/SensorGyro.md) - [SensorGyroFft](msg_docs/SensorGyroFft.md) @@ -703,6 +735,7 @@ - [SensorOpticalFlow](msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](msg_docs/SensorPreflightMag.md) - [SensorSelection](msg_docs/SensorSelection.md) + - [SensorTemp](msg_docs/SensorTemp.md) - [SensorUwb](msg_docs/SensorUwb.md) - [SensorsStatus](msg_docs/SensorsStatus.md) - [SensorsStatusImu](msg_docs/SensorsStatusImu.md) @@ -739,9 +772,13 @@ - [YawEstimatorStatus](msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](msg_docs/AirspeedValidatedV0.md) - [ArmingCheckReplyV0](msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](msg_docs/ArmingCheckRequestV0.md) - [BatteryStatusV0](msg_docs/BatteryStatusV0.md) + - [ConfigOverridesV0](msg_docs/ConfigOverridesV0.md) - [EventV0](msg_docs/EventV0.md) - [HomePositionV0](msg_docs/HomePositionV0.md) + - [RegisterExtComponentReplyV0](msg_docs/RegisterExtComponentReplyV0.md) + - [RegisterExtComponentRequestV0](msg_docs/RegisterExtComponentRequestV0.md) - [VehicleAttitudeSetpointV0](msg_docs/VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](msg_docs/VehicleStatusV0.md) @@ -754,6 +791,7 @@ - [Standard Modes Protocol](mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](middleware/uxrce_dds.md) - [UORB Bridged to ROS 2](middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](middleware/zenoh.md) - [Модулі & Команди](modules/modules_main.md) - [Автоматичне підлаштування](modules/modules_autotune.md) - [Команди](modules/modules_command.md) @@ -771,6 +809,7 @@ - [Датчик швидкості обертання](modules/modules_driver_rpm_sensor.md) - [Radio Control](modules/modules_driver_radio_control.md) - [Транспондер](modules/modules_driver_transponder.md) + - [adc](modules/modules_driver_adc.md) - [Естіматори](modules/modules_estimator.md) - [Симуляції](modules/modules_simulation.md) - [Система](modules/modules_system.md) @@ -807,9 +846,11 @@ - [Інтеграція камери/Архітектура](camera/camera_architecture.md) - [Комп'ютерний зір](advanced/computer_vision.md) - [Захоплення руху (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [Встановлюється драйвер для Intel RealSense R200](advanced/realsense_intel_driver.md) - [Перемикання оцінювачів стану](advanced/switching_state_estimators.md) - [Out-of-Tree модулі](advanced/out_of_tree_modules.md) @@ -843,6 +884,10 @@ - [Тест MC_04 - Тестування відмовостійкості](test_cards/mc_04_failsafe_testing.md) - [Test MC_05 - Manual Modes (Inside)](test_cards/mc_05_indoor_flight_manual_modes.md) - [Test MC_06 - Optical Flow (Inside)](test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](test_cards/mc_10_optical_flow_gps_mixed.md) - [Модульні Тести](test_and_ci/unit_tests.md) - [Fuzz Tests](test_and_ci/fuzz_tests.md) - [Безперервна інтеграція](test_and_ci/continous_integration.md) @@ -863,6 +908,7 @@ - [Інтерфейсна бібліотека PX4 ROS 2](ros2/px4_ros2_interface_lib.md) - [Керування інтерфейсом](ros2/px4_ros2_control_interface.md) - [Навігаційний інтерфейс](ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](ros/ros1.md) - [Посібник із встановлення ROS/MAVROS](ros/mavros_installation.md) @@ -887,6 +933,7 @@ - [Релізи](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/uk/_sidebar.md b/docs/uk/_sidebar.md index cc14b8eb8a..19a3cb9440 100644 --- a/docs/uk/_sidebar.md +++ b/docs/uk/_sidebar.md @@ -1,15 +1,14 @@ - [Введення](/index.md) - - [Основні поняття](/getting_started/px4_basic_concepts.md) - [Мультикоптери](/frames_multicopter/index.md) - - [Функції](/features_mc/index.md) - [Режим польоту](/flight_modes_mc/index.md) - [Position Mode (MC)](/flight_modes_mc/position.md) - [Position Slow Mode (MC)](/flight_modes_mc/position_slow.md) - [Altitude Mode (MC)](/flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](/flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](/flight_modes_mc/manual_stabilized.md) - [Acro Mode (MC)](/flight_modes_mc/acro.md) - [Orbit Mode (MC)](/flight_modes_mc/orbit.md) @@ -37,7 +36,7 @@ - [Static Pressure Buildup](/advanced_config/static_pressure_buildup.md) - [Flying (Basics)](/flying/basic_flying_mc.md) - [Complete Vehicles](/complete_vehicles_mc/index.md) - - [ModalAI Starling](/complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling (PX4 Dev Kit)](/complete_vehicles_mc/modalai_starling.md) - [PX4 Vision Kit](/complete_vehicles_mc/px4_vision_kit.md) - [MindRacer BNF & RTF](/complete_vehicles_mc/mindracer_BNF_RTF.md) - [MindRacer 210](/complete_vehicles_mc/mindracer210.md) @@ -58,12 +57,14 @@ - [DJI F450 (CUAV v5 nano)](/frames_multicopter/dji_f450_cuav_5nano.md) - [Літаки (з фіксованим крилом)](/frames_plane/index.md) - + - [Features](/features_fw/index.md) + - [Gain compression](/features_fw/gain_compression.md) - [Збірка](/assembly/assembly_fw.md) - [Конфігурація/підлаштування](/config_fw/index.md) - [Auto-tune](/config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](/config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](/config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](/config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](/config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](/config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](/flying/basic_flying_fw.md) @@ -86,7 +87,6 @@ - [Wing Wing Z84 (Pixracer)](/frames_plane/wing_wing_z84.md) - [VTOL (Вертикальний зліт та посадка)](/frames_vtol/index.md) - - [Assembly](/assembly/assembly_vtol.md) - [Конфігурація/Налаштування VTOL](/config_vtol/index.md) - [Auto-tune](/config/autotune_vtol.md) @@ -111,7 +111,6 @@ - [Complete Vehicles](/complete_vehicles_vtol/index.md) - [Operations](/config/operations.md) - - [Безпека](/config/safety_intro.md) - [Конфігурація безпеки (запобіжники)](/config/safety.md) - [Моделювання відмовостійкості](/config/safety_simulation.md) @@ -132,7 +131,6 @@ - [QGroundControl Flight-Readiness Status](/flying/pre_flight_checks.md) - [Вибір обладнання & Налаштування](/hardware/drone_parts.md) - - [Flight Controllers (Autopilots)](/flight_controller/index.md) - [Польотні контролери](/getting_started/flight_controller_selection.md) - [Серія Pixhawk](/flight_controller/pixhawk_series.md) @@ -164,18 +162,18 @@ - [Швидке підключення mRo (3DR) Pixhawk](/assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Припинено](/flight_controller/pixhawk_mini.md) - [Автопілоти, що підтримуються виробником](/flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](/flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](/flight_controller/mindpx.md) - [AirMind MindRacer](/flight_controller/mindracer.md) - [ARK Electronics ARKV6X](/flight_controller/ark_v6x.md) - [ARK FPV Flight Controller](/flight_controller/ark_fpv.md) - [ARK Pi6X Flow Flight Controller](/flight_controller/ark_pi6x.md) - - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV Nora](/flight_controller/cuav_nora.md) - [CUAV V5+ (FMUv5)](/flight_controller/cuav_v5_plus.md) - [Wiring Quickstart](/assembly/quick_start_cuav_v5_plus.md) - [CUAV V5 nano (FMUv5)](/flight_controller/cuav_v5_nano.md) - [Швидке підключення CUAV V5 nano](/assembly/quick_start_cuav_v5_nano.md) - - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) + - [CUAV X25 EVO](/flight_controller/cuav_x25-evo.md) - [CubePilot Cube Orange+ (CubePilot)](/flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange (CubePilot)](/flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](/flight_controller/cubepilot_cube_yellow.md) @@ -188,13 +186,13 @@ - [Wiring Quickstart](/assembly/quick_start_durandal.md) - [Holybro Pix32 v5](/flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](/assembly/quick_start_holybro_pix32_v5.md) - - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) - - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [MicoAir H743 Lite](/flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](/flight_controller/modalai_voxl_2.md) - - [mRobotics-X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - - [mRo Control Zero F7)](/flight_controller/mro_control_zero_f7.md) + - [mRo Control Zero F7](/flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](/flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](/flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](/flight_controller/spracingh7extreme.md) + - [SVehicle E2](/flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](/flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](/flight_controller/thepeach_r1.md) - [Калібрування рівня горизонту](/flight_controller/autopilot_experimental.md) @@ -206,18 +204,20 @@ - [Зняті з виробництва автопілоти/транспортні засоби](/flight_controller/autopilot_discontinued.md) - [Drotek Dropix (FMUv2)](/flight_controller/dropix.md) - [Omnibus F4 SD](/flight_controller/omnibus_f4_sd.md) - - [BetaFPV Beta75X 2S Brushless Whoop](/complete_vehicles_mc/betafpv_beta75x.md) - [Bitcraze Crazyflie 2.0 ](/complete_vehicles_mc/crazyflie2.md) - [Aerotenna OcPoC-Zynq Mini](/flight_controller/ocpoc_zynq.md) + - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV v5](/flight_controller/cuav_v5.md) + - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) - [Holybro Kakute F7](/flight_controller/kakutef7.md) - [Holybro Pixfalcon](/flight_controller/pixfalcon.md) - [Holybro pix32 (FMUv2)](/flight_controller/holybro_pix32.md) + - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) + - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [mRo X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - [mRo AUAV-X2](/flight_controller/auav_x2.md) - [NXP RDDRONE-FMUK66 FMU](/flight_controller/nxp_rddrone_fmuk66.md) - [3DR Pixhawk 1](/flight_controller/pixhawk.md) - - [Snapdragon Flight](/flight_controller/snapdragon_flight.md) - - [Intel® Aero RTF Drone](/complete_vehicles_mc/intel_aero.md) - [Pixhawk Autopilot Bus (PAB) & Carriers](/flight_controller/pixhawk_autopilot_bus.md) - [ARK Electronics Pixhawk Autopilot Bus Carrier](/flight_controller/ark_pab.md) - [Кріплення польотного контролера](/assembly/mount_and_orient_controller.md) @@ -229,7 +229,9 @@ - [Оновлення завантажувача](/advanced_config/bootloader_update.md) - [Оновлення бутлоадера FMUv6X-RT через USB](/advanced_config/bootloader_update_v6xrt.md) - [Bootloader прошивка на системи Betaflight](/advanced_config/bootloader_update_from_betaflight.md) + - [Airframe Selection](/config/airframe.md) + - [Сенсори](/sensor/index.md) - [Акселерометр](/sensor/accelerometer.md) - [Калібрування](/config/accelerometer.md) @@ -241,6 +243,7 @@ - [Compass Power Compensation](/advanced_config/compass_power_compensation.md) - [Датчики швидкості повітря](/sensor/airspeed.md) - [Калібрування](/config/airspeed.md) + - [Airspeed Validation](/advanced_config/airspeed_validation.md) - [ВЗІП Датчик польоту](/sensor/airspeed_tfslot.md) - [Барометри](/sensor/barometer.md) - [Датчики відстані \(далекодобива\)](/sensor/rangefinders.md) @@ -272,6 +275,7 @@ - [CUAV C-RTK](/gps_compass/rtk_gps_cuav_c-rtk.md) - [CUAV C-RTK2 PPK/RTK GNSS](/gps_compass/rtk_gps_cuav_c-rtk2.md) - [CUAV C-RTK 9Ps](/gps_compass/rtk_gps_cuav_c-rtk-9ps.md) + - [DATAGNSS NANO HRTK GNSS](/gps_compass/rtk_gps_datagnss_nano_hrtk.md) - [DATAGNSS GEM1305 RTK GNSS](/gps_compass/rtk_gps_gem1305.md) - [Femtones MINI2 Receiver](/gps_compass/rtk_gps_fem_mini2.md) - [Freefly RTK GPS](/gps_compass/rtk_gps_freefly.md) @@ -287,6 +291,9 @@ - [Trimble MB-Two](/gps_compass/rtk_gps_trimble_mb_two.md) - [CubePilot Here+ (Discontined)](/gps_compass/rtk_gps_hex_hereplus.md) - [INS (Інерціальна навігація/GNSS)](/sensor/inertial_navigation_systems.md) + - [InertialLabs](/sensor/inertiallabs.md) + - [MicroStrain](/sensor/microstrain.md) + - [sbgECom](/sensor/sbgecom.md) - [VectorNav](/sensor/vectornav.md) - [Optical Flow](/sensor/optical_flow.md) - [ARK Flow](/dronecan/ark_flow.md) @@ -297,6 +304,7 @@ - [Датчик тахометра ThunderFly TFRPM01](/sensor/thunderfly_tachometer.md) - [Заводське калібрування IMU](/advanced_config/imu_factory_calibration.md) - [Sensor Thermal Compensation](/advanced_config/sensor_thermal_calibration.md) + - [Актуатори](/actuators/index.md) - [Розподіл приводу](/config/actuators.md) - [Калібрування ESC (плати контролю двигунів)](/advanced_config/esc_calibration.md) @@ -308,19 +316,22 @@ - [Zubax Telega](/dronecan/zubax_telega.md) - [Прошивка PX4 Sapog ESC](/dronecan/sapog.md) - [Holybro Kotleta](/dronecan/holybro_kotleta.md) - - [Zubax Orel](/dronecan/zubax_orel.md) - [Vertiq](/peripherals/vertiq.md) - [VESC](/peripherals/vesc.md) + - [Радіокерування (RC)](/getting_started/rc_transmitter_receiver.md) - [Налаштування радіо](/config/radio.md) - [Режими польоту](/config/flight_mode.md) + - [Джойстики](/config/joystick.md) + - [Посилання даних](/data_links/index.md) - [MAVLink Telemetry (OSD/GCS)](/peripherals/mavlink_peripherals.md) - [Телеметричні радіостанції](/telemetry/index.md) - [SiK Radio](/telemetry/sik_radio.md) - [Телеметричне радіо RFD900 (SiK)](/telemetry/rfd900_telemetry.md) + - [ThunderFly TFSIK01 Telemetry Radio](/telemetry/tfsik_telemetry.md) - [HolyBro (SIK) Телеметричне радіо](/telemetry/holybro_sik_radio.md) - [Телеметрія Wi-Fi](/telemetry/telemetry_wifi.md) - [Модуль WiFi ESP8266](/telemetry/esp8266_wifi_module.md) @@ -338,6 +349,7 @@ - [TBS Crossfire (CRSF) телеметрія](/telemetry/crsf_telemetry.md) - [Супутниковий зв'язок (Iridium/RockBlock)](/advanced_features/satcom_roadblock.md) + - [Енергетичні системи](/power_systems/index.md) - [Налаштування оцінки батареї](/config/battery.md) - [Battery Chemistry Overview](/power_systems/battery_chemistry.md) @@ -356,6 +368,7 @@ - [Sky-Drones SmartAP PDB](/power_module/sky-drones_smartap-pdb.md) - [Акумулятори Smart/MAVLink](/smart_batteries/index.md) - [Rotoye Batmon Комплект інтелектуального акумулятора](/smart_batteries/rotoye_batmon.md) + - [Вантажі & камери](/payloads/index.md) - [Випадки використання](/payloads/use_cases.md) - [Місія доставки посилок](/flying/package_delivery_mission.md) @@ -367,19 +380,25 @@ - [Конфігурація Gimbal \(Mount\)](/advanced/gimbal_control.md) - [Grippers](/peripherals/gripper.md) - [Servo Gripper](/peripherals/gripper_servo.md) + - [Периферія](/peripherals/index.md) - [ADSB/FLARM/UTM (уникнення трафіку)](/peripherals/adsb_flarm.md) - [Парашут](/peripherals/parachute.md) - [Remote ID](/peripherals/remote_id.md) + - [Периферійні пристрої I2C](/sensor_bus/i2c_general.md) - [Прискорювачі шини I2C](/sensor_bus/i2c_general.md#i2c-bus-accelerators) - [TFI2CADT01 Транслятор адреси I2C](/sensor_bus/translator_tfi2cadt.md) + - [Периферійні пристрої CAN](/can/index.md) + - [Периферійні пристрої DroneCAN](/dronecan/index.md) - [Прошивка PX4 DroneCAN](/dronecan/px4_cannode_fw.md) - [ARK CANnode](/dronecan/ark_cannode.md) - [RaccoonLab CAN Nodes](/dronecan/raccoonlab_nodes.md) + - [Підключення дротів](/assembly/cable_wiring.md) + - [Комп’ютери-супутники](/companion_computer/index.md) - [Налаштування Pixhawk + Companion](/companion_computer/pixhawk_companion.md) - [RPi Pixhawk Companion](/companion_computer/pixhawk_rpi.md) @@ -395,16 +414,19 @@ - [Realsense T265 Tracking Camera (VIO)](/camera/camera_intel_realsense_t265_vio.md) - [Потокове відео](/companion_computer/video_streaming.md) - [Потокове відео за допомогою WFB-ng Wi-Fi (далекий діапазон)](/companion_computer/video_streaming_wfb_ng_wifi.md) + - [Serial Port Configuration](/peripherals/serial_configuration.md) + - [PX4 Ethernet Setup](/advanced_config/ethernet_setup.md) + - [Стандартна конфігурація](/config/index.md) + - [Розширені налаштування](/advanced_config/index.md) - [Using PX4's Navigation Filter (EKF2)](/advanced_config/tuning_the_ecl_ekf.md) - [Finding/Updating Parameters](/advanced_config/parameters.md) - [Full Parameter Reference](/advanced_config/parameter_reference.md) - [Інші транспортні засоби](/airframes/index.md) - - [Airships (experimental)](/frames_airship/index.md) - [Autogyros (experimental)](/frames_autogyro/index.md) - [ThunderFly Auto-G2 (Holybro pix32)](/frames_autogyro/thunderfly_auto_g2.md) @@ -412,17 +434,18 @@ - [Helicopter (experimental)](/frames_helicopter/index.md) - [Конфігурація/Підлаштування](/config_heli/index.md) - [Rovers (experimental)](/frames_rover/index.md) - - [Ackermann Rovers](/frames_rover/ackermann.md) - - [Drive Modes](/flight_modes_rover/ackermann.md) - - [Конфігурація/Підлаштування](/config_rover/ackermann.md) - - [Differential Rovers](/frames_rover/differential.md) - - [Drive Modes](/flight_modes_rover/differential.md) - - [Конфігурація/Підлаштування](/config_rover/differential.md) - - [Aion Robotics R1](/frames_rover/aion_r1.md) - - [Mecanum Rovers](/frames_rover/mecanum.md) - - [Drive Modes](/flight_modes_rover/mecanum.md) - - [Конфігурація/Підлаштування](/config_rover/mecanum.md) - - [(Deprecated) Rover Position Control](/frames_rover/rover_position_control.md) + - [Drive Modes](/flight_modes_rover/index.md) + - [Manual](/flight_modes_rover/manual.md) + - [Auto](/flight_modes_rover/auto.md) + - [Configuration/Tuning](/config_rover/index.md) + - [Basic Setup](/config_rover/basic_setup.md) + - [Rate Tuning](/config_rover/rate_tuning.md) + - [Attitude Tuning](/config_rover/attitude_tuning.md) + - [Velocity Tuning](/config_rover/velocity_tuning.md) + - [Position Tuning](/config_rover/position_tuning.md) + - [Apps & API](/flight_modes_rover/api.md) + - [Complete Vehicles](/complete_vehicles_rover/index.md) + - [Aion Robotics R1](/complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](/frames_sub/index.md) - [BlueROV2](/frames_sub/bluerov2.md) - [Airframes Reference](/airframes/airframe_reference.md) @@ -486,6 +509,7 @@ - [UART/Послідовний порт](/uart/index.md) - [Драйвери послідовного порту і їх налаштування](/uart/user_configurable_serial_driver.md) - [RTK GPS (Інтеграція)](/advanced/rtk_gps.md) + - [PPS Time Synchronization](/advanced/pps_time_sync.md) - [Проміжне програмне забезпечення](/middleware/index.md) - [Повідомлення uORB](/middleware/uorb.md) - [Граф uORB](/middleware/uorb_graph.md) @@ -534,6 +558,7 @@ - [Airspeed](/msg_docs/Airspeed.md) - [AirspeedWind](/msg_docs/AirspeedWind.md) - [AutotuneAttitudeControlStatus](/msg_docs/AutotuneAttitudeControlStatus.md) + - [BatteryInfo](/msg_docs/BatteryInfo.md) - [ButtonEvent](/msg_docs/ButtonEvent.md) - [CameraCapture](/msg_docs/CameraCapture.md) - [CameraStatus](/msg_docs/CameraStatus.md) @@ -552,6 +577,7 @@ - [DifferentialPressure](/msg_docs/DifferentialPressure.md) - [DistanceSensor](/msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](/msg_docs/DistanceSensorModeChangeRequest.md) + - [DronecanNodeStatus](/msg_docs/DronecanNodeStatus.md) - [Ekf2Timestamps](/msg_docs/Ekf2Timestamps.md) - [EscReport](/msg_docs/EscReport.md) - [EscStatus](/msg_docs/EscStatus.md) @@ -626,6 +652,7 @@ - [MountOrientation](/msg_docs/MountOrientation.md) - [NavigatorMissionItem](/msg_docs/NavigatorMissionItem.md) - [NavigatorStatus](/msg_docs/NavigatorStatus.md) + - [NeuralControl](/msg_docs/NeuralControl.md) - [NormalizedUnsignedSetpoint](/msg_docs/NormalizedUnsignedSetpoint.md) - [ObstacleDistance](/msg_docs/ObstacleDistance.md) - [OffboardControlMode](/msg_docs/OffboardControlMode.md) @@ -665,10 +692,10 @@ - [RoverPositionSetpoint](/msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](/msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](/msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](/msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](/msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](/msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](/msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](/msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](/msg_docs/RoverVelocityStatus.md) - [Rpm](/msg_docs/Rpm.md) - [RtlStatus](/msg_docs/RtlStatus.md) - [RtlTimeEstimate](/msg_docs/RtlTimeEstimate.md) @@ -680,6 +707,7 @@ - [SensorCombined](/msg_docs/SensorCombined.md) - [SensorCorrection](/msg_docs/SensorCorrection.md) - [SensorGnssRelative](/msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](/msg_docs/SensorGnssStatus.md) - [SensorGps](/msg_docs/SensorGps.md) - [SensorGyro](/msg_docs/SensorGyro.md) - [SensorGyroFft](/msg_docs/SensorGyroFft.md) @@ -689,6 +717,7 @@ - [SensorOpticalFlow](/msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](/msg_docs/SensorPreflightMag.md) - [SensorSelection](/msg_docs/SensorSelection.md) + - [SensorTemp](/msg_docs/SensorTemp.md) - [SensorUwb](/msg_docs/SensorUwb.md) - [SensorsStatus](/msg_docs/SensorsStatus.md) - [SensorsStatusImu](/msg_docs/SensorsStatusImu.md) @@ -724,7 +753,13 @@ - [Wind](/msg_docs/Wind.md) - [YawEstimatorStatus](/msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](/msg_docs/AirspeedValidatedV0.md) + - [ArmingCheckReplyV0](/msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](/msg_docs/ArmingCheckRequestV0.md) + - [BatteryStatusV0](/msg_docs/BatteryStatusV0.md) + - [EventV0](/msg_docs/EventV0.md) + - [HomePositionV0](/msg_docs/HomePositionV0.md) - [VehicleAttitudeSetpointV0](/msg_docs/VehicleAttitudeSetpointV0.md) + - [VehicleLocalPositionV0](/msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](/msg_docs/VehicleStatusV0.md) - [MAVLink Messaging](/mavlink/index.md) - [Adding Messages](/mavlink/adding_messages.md) @@ -734,6 +769,8 @@ - [Protocols/Microservices](/mavlink/protocols.md) - [Standard Modes Protocol](/mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](/middleware/uxrce_dds.md) + - [UORB Bridged to ROS 2](/middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](/middleware/zenoh.md) - [Модулі & Команди](/modules/modules_main.md) - [Автоматичне підлаштування](/modules/modules_autotune.md) - [Команди](/modules/modules_command.md) @@ -751,6 +788,7 @@ - [Датчик швидкості обертання](/modules/modules_driver_rpm_sensor.md) - [Radio Control](/modules/modules_driver_radio_control.md) - [Транспондер](/modules/modules_driver_transponder.md) + - [adc](/modules/modules_driver_adc.md) - [Естіматори](/modules/modules_estimator.md) - [Симуляції](/modules/modules_simulation.md) - [Система](/modules/modules_system.md) @@ -763,7 +801,7 @@ - [Відлагодження з GDB](/debug/gdb_debugging.md) - [Порт для налагодження SWD](/debug/swd_debug.md) - [JLink адаптер](/debug/probe_jlink.md) - - [Black Magic / Dronecode адаптери](/debug/probe_bmp.md) + - [Black Magic/Zubax BugFace BF1 Probe](/debug/probe_bmp.md) - [STLink адаптер](/debug/probe_stlink.md) - [MCU-Link адаптер](/debug/probe_mculink.md) - [Відлагодження Hardfault ](/debug/gdb_hardfault.md) @@ -787,6 +825,9 @@ - [Інтеграція камери/Архітектура](/camera/camera_architecture.md) - [Комп'ютерний зір](/advanced/computer_vision.md) - [Захоплення руху (VICON, Optitrack, NOKOV)](/tutorials/motion-capture.md) + - [Neural Networks](/advanced/neural_networks.md) + - [Neural Network Module Utilities](/advanced/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](/advanced/tflm.md) - [Встановлюється драйвер для Intel RealSense R200](/advanced/realsense_intel_driver.md) - [Перемикання оцінювачів стану](/advanced/switching_state_estimators.md) - [Out-of-Tree модулі](/advanced/out_of_tree_modules.md) @@ -818,8 +859,14 @@ - [Тест MC_02 - Повна автономність](/test_cards/mc_02_full_autonomous.md) - [Тест MC_03 - поєднання автоматичного і ручного керування](/test_cards/mc_03_auto_manual_mix.md) - [Тест MC_04 - Тестування відмовостійкості](/test_cards/mc_04_failsafe_testing.md) - - [Тест MC_05 - Політ у приміщенні (ручні режими)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_05 - Manual Modes (Inside)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_06 - Optical Flow (Inside)](/test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](/test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](/test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](/test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](/test_cards/mc_10_optical_flow_gps_mixed.md) - [Модульні Тести](/test_and_ci/unit_tests.md) + - [Fuzz Tests](/test_and_ci/fuzz_tests.md) - [Безперервна інтеграція](/test_and_ci/continous_integration.md) - [Integration Testing](/test_and_ci/integration_testing.md) - [MAVSDK Тестування інтеграції ](/test_and_ci/integration_testing_mavsdk.md) @@ -838,6 +885,7 @@ - [Інтерфейсна бібліотека PX4 ROS 2](/ros2/px4_ros2_interface_lib.md) - [Керування інтерфейсом](/ros2/px4_ros2_control_interface.md) - [Навігаційний інтерфейс](/ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](/ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](/ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](/ros/ros1.md) - [Посібник із встановлення ROS/MAVROS](/ros/mavros_installation.md) @@ -862,8 +910,8 @@ - [Релізи](/releases/index.md) - [main (alpha)](/releases/main.md) - - [1.16 (release candidate)](/releases/1.16.md) - - [1.15 (stable)](/releases/1.15.md) + - [1.16 (stable)](/releases/1.16.md) + - [1.15](/releases/1.15.md) - [1.14](/releases/1.14.md) - [1.13](/releases/1.13.md) - [1.12](/releases/1.12.md) diff --git a/docs/uk/advanced/gimbal_control.md b/docs/uk/advanced/gimbal_control.md index 3cf2fbbaf4..68ca5a651f 100644 --- a/docs/uk/advanced/gimbal_control.md +++ b/docs/uk/advanced/gimbal_control.md @@ -74,7 +74,7 @@ Gimbal також можна контролювати шляхом підклю ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -PWM значення для використання при відблокованому, максимальному та мінімальному значеннях можна визначити так само, як і для інших сервоприводів, використовуючи [повзунки тесту приводу](../config/actuators.md#actuator-testing), щоб підтвердити, що кожний повзунок переміщує відповідну вісь, і змінюючи значення так, щоб гімбал знаходився у відповідному положенні при відблокованому стані, низькому і високому положенні повзунка. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. Значення також можуть бути наведені у документації гімбала. ## Gimbal Control in Missions @@ -131,7 +131,7 @@ The on-screen gimbal control can be used to move/test a connected MAVLink camera 2. Open QGroundControl and enable the on-screen camera control (Application settings). - ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) + ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) 3. Make sure the vehicle is armed and flying, e.g. by entering with `commander takeoff`. diff --git a/docs/uk/advanced/neural_networks.md b/docs/uk/advanced/neural_networks.md index 2c9cf4ff27..039259fd5f 100644 --- a/docs/uk/advanced/neural_networks.md +++ b/docs/uk/advanced/neural_networks.md @@ -1,115 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Вхід - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### Output - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/uk/advanced/pps_time_sync.md b/docs/uk/advanced/pps_time_sync.md new file mode 100644 index 0000000000..67456cc75d --- /dev/null +++ b/docs/uk/advanced/pps_time_sync.md @@ -0,0 +1,135 @@ +# PPS Time Synchronization (PX4 Integration) + +[Pulse Per Second](https://en.wikipedia.org/wiki/Pulse-per-second_signal) (PPS) time synchronization provides high-precision timing for GNSS receivers. +This page explains how PPS is integrated into PX4 and how to configure it. + +## Загальний огляд + +PPS (Pulse Per Second) is a timing signal provided by GNSS receivers that outputs an electrical pulse once per second, synchronized to UTC time. +The PPS signal provides a highly accurate timing reference that PX4 can use to: + +- Refine GNSS time measurements and compensate for clock drift +- Provide precise UTC timestamps for camera capture events (for photogrammetry and mapping applications) +- Enable offline position refinement through accurate time correlation + +## Підтримуване обладнання + +PPS time synchronization can be supported on flight controllers that have a hardware timer input pin that can be configured for PPS capture, by [enabling the PPS capture driver](#enable-pps-driver-in-board-configuration) in the board configuration. + +Supported boards include (at time of writing): + +- [Ark FMUv6x](../flight_controller/ark_v6x.md) +- Auterion FMUv6x +- Auterion FMUv6s + +## Установка + +### Enable PPS Driver in Board Configuration + +The [PPS capture driver](../modules/modules_driver.md#pps-capture) must be enabled in the board configuration. +This is done by adding the following to your board's configuration: + +```ini +CONFIG_DRIVERS_PPS_CAPTURE=y +``` + +### Configure PPS Parameters + +The configuration varies depending on your flight controller hardware. + +#### FMUv6X + +For FMUv6X-based flight controllers, configure PWM AUX Timer 3 and Function 9: + +```sh +param set PWM_AUX_TIM3 -2 +param set PWM_AUX_FUNC9 2064 +param set PPS_CAP_ENABLE 1 +``` + +#### FMUv6S + +For FMUv6S-based flight controllers, configure PWM MAIN Timer 3 and Function 10: + +```sh +param set PWM_MAIN_TIM3 -2 +param set PWM_MAIN_FUNC10 2064 +param set PPS_CAP_ENABLE 1 +``` + +### Підключення + +The wiring configuration depends on your specific flight controller. + +#### Skynode X (FMUv6x) + +Connect the PPS signal from your GNSS module to the flight controller using the 11-pin or 6-pin GPS connector: + +For detailed pinout information, refer to: + +- [Skynode GPS Peripherals - Pinouts](https://docs.auterion.com/hardware-integration/skynode/peripherals/gps#pinouts) + +#### Skynode S (FMUv6S) + +For FMUv6S, you need to route the PPS signal separately: + +1. Connect your GNSS module using the standard 6-pin GPS connector: [Skynode S GPS Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#gps) +2. Connect the PPS signal from your GNSS module to the **PPM_IN** pin: [Skynode S Extras 1 Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#extras-1) + +#### ARK Jetson Carrier Board (FMUv6x) + +For ARK FMUv6X on the Jetson carrier board: + +1. Connect your GNSS module using either the 10-pin or 6-pin GPS connector: [ARK PAB GPS1 Interface](../flight_controller/ark_pab#gps1) +2. Connect the PPS signal to the **FMU_CAP** pin: [ARK PAB ADIO Interface](../flight_controller/ark_pab.md#adio) + +## Перевірка + +After configuring PPS, you can verify that it is working correctly: + +1. Connect to the [PX4 System Console](../debug/system_console.md) (via MAVLink shell or serial console). + +2. Wait for GNSS fix. + +3. Check the PPS capture status to confirm it is up and running: + + ```sh + pps_capture status + ``` + +4. You can also check the [PpsCapture](../msg_docs/PpsCapture.md) uORB topic + + ```sh + listener pps_capture + ``` + + Where you should see: `timestamp`, `rtc_timestamp`, and `pps_rate_exceeded_counter`. + +### PPS Capture Driver + +The PPS capture driver is located in `src/drivers/pps_capture` and uses hardware timer input capture to precisely measure the arrival time of each PPS pulse. + +Основні функції: + +- Sub-microsecond pulse capture precision (hardware-dependent) +- Automatic drift calculation and compensation +- Integration with the GNSS driver for refined time stamping + +See also: + +- [PPS Capture Driver Documentation](../modules/modules_driver.md#pps-capture) +- [PpsCapture Message](../msg_docs/PpsCapture.md) + +### Time Synchronization Flow + +1. GNSS module sends position/time data at ~1-20 Hz. +2. GNSS module outputs PPS pulse at 1 Hz, precisely aligned to UTC second boundary. +3. PPS capture driver measures the exact time of the PPS pulse arrival using hardware timer. +4. Driver calculates the offset between GNSS time (from UART data) and autopilot clock (from PPS measurement). +5. This offset is used to correct GNSS timestamps and improve sensor fusion accuracy. + +The PPS signal provides much higher temporal precision than the transmitted time data, which has latency and jitter from serial communication. + +:::warning +If the PPS driver does not sending any data for 5 seconds (despite having `PPS_CAP_ENABLE` set to 1), the `EKF2_GPS_DELAY` will be used instead for estimating the latency. +::: diff --git a/docs/uk/advanced/system_tunes.md b/docs/uk/advanced/system_tunes.md index 2d169f624c..a7bcaa0e16 100644 --- a/docs/uk/advanced/system_tunes.md +++ b/docs/uk/advanced/system_tunes.md @@ -52,7 +52,7 @@ PX4 визначає ряд [стандартних мелодій/тем](../ge 7. Коли ви будете готові зберегти музику: - Натисніть **F2**, щоб дати мелодії назву та зберегти її у підпапці _/Music_ вашої інсталяції Melody Master. - Натисніть **F7**, прокрутіть список вихідних форматів праворуч, щоб перейти до ANSI. - Файл буде експортовано в _кореневий каталог_ каталогу Melody Master (з такою самою назвою та розширенням типу файлу). + Файл буде експортовано в _кореневий каталог_ каталогу Melody Master (з такою самою назвою та розширенням типу файлу). 8. Відкрийте файл. Результат може виглядати так: diff --git a/docs/uk/advanced_config/advanced_flight_controller_orientation_leveling.md b/docs/uk/advanced_config/advanced_flight_controller_orientation_leveling.md index 5b033e1371..f21f7bbb51 100644 --- a/docs/uk/advanced_config/advanced_flight_controller_orientation_leveling.md +++ b/docs/uk/advanced_config/advanced_flight_controller_orientation_leveling.md @@ -23,7 +23,7 @@ 1. Відкрийте меню QGroundControl: **Settings > Parameters > Sensor Calibration**. 2. Параметри, розташовані в розділі, як показано нижче (або ви можете знайти їх): - ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) + ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) ## Підсумок параметра diff --git a/docs/uk/advanced_config/airspeed_validation.md b/docs/uk/advanced_config/airspeed_validation.md index 0f612d0186..a9b25c727b 100644 --- a/docs/uk/advanced_config/airspeed_validation.md +++ b/docs/uk/advanced_config/airspeed_validation.md @@ -10,36 +10,13 @@ By default, the [Missing Data](#missing-data-check), [Data Stuck](#data-stuck-ch You can configure which checks are active using the [ASPD_DO_CHECKS](#aspd_do_checks_table) parameter. ::: -## Airspeed in PX4 - -PX4 handles multiple types of airspeed: - -- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). - -- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. - -- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. - While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. - -- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). - -The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. - ## CAS Scale Estimation -PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. -To compute the final TAS, standard environment conversions are applied (CAS → TAS). - -This CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. +Calibrated Airspeed (CAS) is the measured Indicated Airspeed (IAS) scaled to correct for sensor-specific and installation-related errors. +CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. If the estimated CAS scale is inaccurate, it can mask real airspeed faults or trigger false positives. -If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, you can manually set it using [ASPD_SCALE_n](#aspd_scale_n_table) (where `n` is the sensor number). -[ASPD_SCALE_APPLY](#aspd_scale_apply_table) can be used to configure when/if the estimated scale is applied. - -:::info -For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). -The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for [ASPD_SCALE_n](#aspd_scale_n_table). -::: +If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, follow the steps outlined in [Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md#recommended-first-flight-process). ## Validation Checks diff --git a/docs/uk/advanced_config/bootloader_update.md b/docs/uk/advanced_config/bootloader_update.md index 9d9c19989d..faed8e2e0e 100644 --- a/docs/uk/advanced_config/bootloader_update.md +++ b/docs/uk/advanced_config/bootloader_update.md @@ -37,8 +37,8 @@ You can enable this key in your own custom firmware if needed. 2. [Оновіть прошивку](../config/firmware.md#custom) з образом, що містить новий/потрібний завантажувач. - ::: info - The updated bootloader might be included the default firmware for your board or supplied in custom firmware. + ::: info + The updated bootloader might be included the default firmware for your board or supplied in custom firmware. ::: @@ -47,7 +47,7 @@ You can enable this key in your own custom firmware if needed. 4. [Знайдіть](../advanced_config/parameters.md) та увімкніть параметр [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 5. Перезавантажте (відключіть / підключіть плату). - Оновлення завантажувача займе лише кілька секунд. + Оновлення завантажувача займе лише кілька секунд. Зазвичай на цьому етапі ви можливо захочете [оновити прошивку](../config/firmware.md) ще раз, використовуючи правильно/ново встановлений загрузчик. @@ -89,80 +89,80 @@ PX4 boards up to FMUv5X (before STM32H7) used the [PX4 bootloader](https://githu 1. Отримайте бінарний файл, який містить завантажувальник (або від команди розробників, або [зіберіть його самостійно](#building-the-px4-bootloader)). 2. Get a [Debug Probe](../debug/swd_debug.md#debug-probes-for-px4-hardware). - Підключіть зонд до комп'ютера за допомогою USB та налаштуйте `gdbserver`. + Підключіть зонд до комп'ютера за допомогою USB та налаштуйте `gdbserver`. 3. Перейдіть до каталогу, що містить бінарний файл, і запустіть команду для обраного вами завантажувача в терміналі: - - FMUv6X + - FMUv6X - ```sh - arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf + ``` - - FMUv6X-RT + - FMUv6X-RT - ```sh - arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf + ``` - - FMUv5 + - FMUv5 - ```sh - arm-none-eabi-gdb px4fmuv5_bl.elf - ``` + ```sh + arm-none-eabi-gdb px4fmuv5_bl.elf + ``` - H7 Завантажувачі з [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) мають назву за шаблоном `*._bootloader.elf`. - Завантажувачі з [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) мають назву за шаблоном `*_bl.elf`. + H7 Завантажувачі з [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) мають назву за шаблоном `*._bootloader.elf`. + Завантажувачі з [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) мають назву за шаблоном `*_bl.elf`. ::: 4. The _gdb terminal_ appears and it should display (something like) the following output: - ```sh - GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git - Copyright (C) 2017 Free Software Foundation, Inc. - License GPLv3+: GNU GPL version 3 or later - This is free software: you are free to change and redistribute it. - There is NO WARRANTY, to the extent permitted by law. - Type "show copying" and "show warranty" for details. - This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". - Type "show configuration" for configuration details. - For bug reporting instructions, please see: - . - Find the GDB manual and other documentation resources online at: - . - For help, type "help". - Type "apropos word" to search for commands related to "word"... - Reading symbols from px4fmuv5_bl.elf...done. - ``` + ```sh + GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git + Copyright (C) 2017 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from px4fmuv5_bl.elf...done. + ``` 5. Find your `` by running an `ls` command in the **/dev/serial/by-id** directory. 6. Тепер підключіться до debug probe з наступною командою: - ```sh - tar ext /dev/serial/by-id/ - ``` + ```sh + tar ext /dev/serial/by-id/ + ``` 7. Увімкніть Pixhawk за допомогою іншого USB-кабелю та під’єднайте зонд до порту `FMU-DEBUG`. - ::: info - If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). + ::: info + If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). ::: 8. Використовуйте таку команду, щоб знайти SWD Pixhawk і підключитися до нього: - ```sh - (gdb) mon swdp_scan - (gdb) attach 1 - ``` + ```sh + (gdb) mon swdp_scan + (gdb) attach 1 + ``` 9. Завантажте двійковий файл в Pixhawk: - ```sh - (gdb) load - ``` + ```sh + (gdb) load + ``` Після оновлення завантажувача ви можете [завантажити прошивку PX4](../config/firmware.md) за допомогою _QGroundControl_. @@ -181,25 +181,25 @@ This example explains how you can use [QGC Bootloader Update](qgc-bootloader-upd 1. Вставте SD-карту (це дозволяє реєструвати журнали завантаження для відлагодження будь-яких проблем). 2. [Оновіть програмне забезпечення](../config/firmware.md) до версії PX4 _master_ (під час оновлення програмного забезпечення перевірте **Розширені налаштування** і виберіть **Розробницьку збірку (master)** із випадаючого списку). - _QGroundControl_ автоматично виявить, що апаратне забезпечення підтримує FMUv2 і встановить відповідне програмне забезпечення. + _QGroundControl_ автоматично виявить, що апаратне забезпечення підтримує FMUv2 і встановить відповідне програмне забезпечення. - ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) + ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) - Зачекайте, доки транспортний засіб перезавантажиться. + Зачекайте, доки транспортний засіб перезавантажиться. 3. [Знайдіть](../advanced_config/parameters.md) та увімкніть параметр [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 4. Перезавантажте (відключіть / підключіть плату). - Оновлення завантажувача займе лише кілька секунд. + Оновлення завантажувача займе лише кілька секунд. 5. Тоді знову [Оновити програмне забезпечення](../config/firmware.md). - На цей раз _QGroundControl_ повинен автоматично визначити обладнання як FMUv3 і відповідним чином оновити програмне забезпечення. + На цей раз _QGroundControl_ повинен автоматично визначити обладнання як FMUv3 і відповідним чином оновити програмне забезпечення. - ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) + ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) - ::: info - Якщо апаратне забезпечення має [Помилки в кремнієвій мікросхемі](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata), воно все одно буде виявлене як FMUv2, і ви побачите, що FMUv2 було знову встановлено (у консолі). - У цьому випадку ви не зможете встановити апаратне забезпечення FMUv3. + ::: info + Якщо апаратне забезпечення має [Помилки в кремнієвій мікросхемі](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata), воно все одно буде виявлене як FMUv2, і ви побачите, що FMUv2 було знову встановлено (у консолі). + У цьому випадку ви не зможете встановити апаратне забезпечення FMUv3. ::: diff --git a/docs/uk/advanced_config/bootloader_update_from_betaflight.md b/docs/uk/advanced_config/bootloader_update_from_betaflight.md index 803e8511bc..236e06f4eb 100644 --- a/docs/uk/advanced_config/bootloader_update_from_betaflight.md +++ b/docs/uk/advanced_config/bootloader_update_from_betaflight.md @@ -89,7 +89,7 @@ dfu-util -a 0 --dfuse-address 0x08000000 -D build//.bin Список контролерів, яких це стосується, можна отримати, виконавши наступну команду `make` і зазначивши цілі `make`, які закінчуються на `_bootloader` ``` -$make list_config_targets +$ make list_config_targets ... cuav_nora_bootloader diff --git a/docs/uk/advanced_config/esc_calibration.md b/docs/uk/advanced_config/esc_calibration.md index b2fce9058f..c48d3ecf1d 100644 --- a/docs/uk/advanced_config/esc_calibration.md +++ b/docs/uk/advanced_config/esc_calibration.md @@ -92,29 +92,29 @@ ESC OneShot слід [налаштувати на використання ре - Мінімальне значення для мотора (за замовчуванням: 1100 мкс) повинно забезпечувати повільний, але надійний оберт мотора, а також надійно запускати його після зупинки. - Ви можете підтвердити, що мотор обертається мінімально (без пропеллерів) в [TestActuator](../config/actuators. d#actuator-testing), увімкнувши повзунки, а потім переміщуючи повзунок виводу тесту для двигуна в першу позицію відключення від низу. - Правильне значення має зробити так, що мотор обертається негайно і надійно при пересуванні повзунка зі стану роззброєності до мінімуму. + Ви можете підтвердити, що мотор обертається мінімально (без пропеллерів) в [TestActuator](../config/actuators. d#actuator-testing), увімкнувши повзунки, а потім переміщуючи повзунок виводу тесту для двигуна в першу позицію відключення від низу. + Правильне значення має зробити так, що мотор обертається негайно і надійно при пересуванні повзунка зі стану роззброєності до мінімуму. - Щоб знайти «оптимальне» мінімальне значення, пересуньте повзунок вниз (режим роззброєності). - Потім збільшуйте значення PWM-виходу в режимі `роззброєності` невеликими інкрементами (наприклад, 1025 мкс, 1050 мкс і т. д.), доки мотор не почне надійно обертатися (краще бути трохи вище, ніж трохи нижче). - Введіть це значення в параметр «мінімум» для всіх вихідних PWM сигналів мотора, а вихідний сигнал `роззброєності` відновіть до `1100 мкс`. + Щоб знайти «оптимальне» мінімальне значення, пересуньте повзунок вниз (режим роззброєності). + Потім збільшуйте значення PWM-виходу в режимі `роззброєності` невеликими інкрементами (наприклад, 1025 мкс, 1050 мкс і т. д.), доки мотор не почне надійно обертатися (краще бути трохи вище, ніж трохи нижче). + Введіть це значення в параметр «мінімум» для всіх вихідних PWM сигналів мотора, а вихідний сигнал `роззброєності` відновіть до `1100 мкс`. - Максимальне значення для мотора (за замовчуванням: `1900 мкс`) слід вибрати так, щоб збільшення значення не зробило мотор обертатися швидше. - Ви можете підтвердити, що мотор обертається швидко при максимальному значенні у режимі [Тестування приводів](../config/actuators.md#actuator-testing), перемістивши пов'язаний слайдер випробування вверх. + Ви можете підтвердити, що мотор обертається швидко при максимальному значенні у режимі [Тестування приводів](../config/actuators.md#actuator-testing), перемістивши пов'язаний слайдер випробування вверх. - Щоб знайти "оптимальне" максимальне значення, спочатку перемістіть повзунок вниз (роззброєно). - Потім збільште налаштування вихідної потужності PWM `вимкненої` близько до максимального значення за замовчуванням (`1900`) - мотори повинні розганятися. - Слухайте тон мотора, коли збільшуєте максимальне значення PWM для виводу поетапно (наприклад, 1925 мкс, 1950 мкс і так далі). - Оптимальне значення визначається в той момент, коли звук моторів не змінюється при збільшенні значення виводу. - Введіть це значення в параметр `максимум` для всіх виводів ШІМ мотора, а також відновіть значення виводу `знято` на `1100 мкс`. + Щоб знайти "оптимальне" максимальне значення, спочатку перемістіть повзунок вниз (роззброєно). + Потім збільште налаштування вихідної потужності PWM `вимкненої` близько до максимального значення за замовчуванням (`1900`) - мотори повинні розганятися. + Слухайте тон мотора, коли збільшуєте максимальне значення PWM для виводу поетапно (наприклад, 1925 мкс, 1950 мкс і так далі). + Оптимальне значення визначається в той момент, коли звук моторів не змінюється при збільшенні значення виводу. + Введіть це значення в параметр `максимум` для всіх виводів ШІМ мотора, а також відновіть значення виводу `знято` на `1100 мкс`. - Значення виводу «знято» для мотора (за замовчуванням: `1000 мкс`) повинно зупиняти мотор і залишати його зупиненим. - Ви можете підтвердити це в розділі [Тестування виконавчих механізмів](../config/actuators.md#actuator-testing), перемістивши слайдер виводу тестування до фіксованого положення у нижній частині слайдера і спостерігаючи, що двигун не обертається. + Ви можете підтвердити це в розділі [Тестування виконавчих механізмів](../config/actuators.md#actuator-testing), перемістивши слайдер виводу тестування до фіксованого положення у нижній частині слайдера і спостерігаючи, що двигун не обертається. - Якщо ESC обертається за замовчуванням на значенні 1000 мкс, то ESC не правильно калібрується. - Якщо використовуєте ESC, який не може бути калібрований, вам слід зменшити значення виведення ШІМ для виводу до значення, коли мотор більше не обертається (наприклад, 950 мкс або 900 мкс). + Якщо ESC обертається за замовчуванням на значенні 1000 мкс, то ESC не правильно калібрується. + Якщо використовуєте ESC, який не може бути калібрований, вам слід зменшити значення виведення ШІМ для виводу до значення, коли мотор більше не обертається (наприклад, 950 мкс або 900 мкс). ::: info VTOL and fixed-wing motors do not need any special PWM configuration. diff --git a/docs/uk/advanced_config/ethernet_setup.md b/docs/uk/advanced_config/ethernet_setup.md index 87dacceeda..5366b53e2f 100644 --- a/docs/uk/advanced_config/ethernet_setup.md +++ b/docs/uk/advanced_config/ethernet_setup.md @@ -25,6 +25,7 @@ PX4 supports Ethernet connectivity on [Pixhawk 5X-standard](https://github.com/p Підтримувані автопілоти включають: +- [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) - [CUAV Pixhawk V6X](../flight_controller/cuav_pixhawk_v6x.md) - [Holybro Pixhawk 5X](../flight_controller/pixhawk5x.md) - [Holybro Pixhawk 6X](../flight_controller/pixhawk6x.md) @@ -87,14 +88,14 @@ DNS=10.41.10.254 3. Введіть команди "like" до наведених нижче у _Консоль MAVLink_ (щоб записати значення у файл конфігурації): - ```sh - echo DEVICE=eth0 > /fs/microsd/net.cfg - echo BOOTPROTO=fallback >> /fs/microsd/net.cfg - echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg - echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg - echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg - echo DNS=10.41.10.254 >>/fs/microsd/net.cfg - ``` + ```sh + echo DEVICE=eth0 > /fs/microsd/net.cfg + echo BOOTPROTO=fallback >> /fs/microsd/net.cfg + echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg + echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg + echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg + echo DNS=10.41.10.254 >>/fs/microsd/net.cfg + ``` 4. Після встановлення конфігурації мережі можна від’єднати кабель USB. @@ -113,36 +114,36 @@ Note that there are many more [examples](https://github.com/canonical/netplan/tr Для установки Ubuntu комп'ютера: 1. In a terminal, create and open a `netplan` configuration file: `/etc/netplan/01-network-manager-all.yaml` - Below we do this using the _nano_ text editor. + Below we do this using the _nano_ text editor. - ``` - sudo nano /etc/netplan/01-network-manager-all.yaml - ``` + ``` + sudo nano /etc/netplan/01-network-manager-all.yaml + ``` 2. Скопіюйте та вставте наступну конфігураційну інформацію у файл (зверніть увагу: відступи мають значення!): - ``` - network: - version: 2 - renderer: NetworkManager - ethernets: - enp2s0: - addresses: - - 10.41.10.1/24 - nameservers: - addresses: [10.41.10.1] - routes: - - to: 10.41.10.1 - via: 10.41.10.1 - ``` + ``` + network: + version: 2 + renderer: NetworkManager + ethernets: + enp2s0: + addresses: + - 10.41.10.1/24 + nameservers: + addresses: [10.41.10.1] + routes: + - to: 10.41.10.1 + via: 10.41.10.1 + ``` - Збережіть і закрийте файл. + Збережіть і закрийте файл. 3. Застосуйте конфігурацію _netplan_, введіть наступну команду в термінал Ubuntu. - ``` - sudo netplan apply - ``` + ``` + sudo netplan apply + ``` ### Комп’ютер-супутник Налаштування мережі Ethernet @@ -189,9 +190,9 @@ Assuming you have already [Set up the Ethernet Network](#setting-up-the-ethernet 3. Запустіть QGroundControl та [визначте комунікаційний канал](https://docs.qgroundcontrol.com/master/en/SettingsView/SettingsView.html) (**Налаштування додатка > Канали зв'язку**), вказавши _адресу сервера_ та порт як IP-адресу та порт, призначений в PX4, відповідно. - Припускаючи, що значення встановлені так, як описано в решті цієї теми, налаштування виглядатиме наступним чином: + Припускаючи, що значення встановлені так, як описано в решті цієї теми, налаштування виглядатиме наступним чином: - ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) + ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) 4. Після цього QGroundControl має підключитися, якщо ви виберете це посилання. @@ -205,14 +206,14 @@ Assuming you have already [Set up the Ethernet Network](#setting-up-the-ethernet 1. [Set up the Ethernet Network](#setting-up-the-ethernet-network) so your companion computer and PX4 run on the same network. 2. Modify the [PX4 Ethernet Port Configuration](#px4-ethernet-network-setup) to connect to a companion computer. - You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). + You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). 3. Дотримуйтесь інструкцій у [MAVSDK-python](https://github.com/mavlink/MAVSDK-Python), щоб установити та використовувати MAVSDK. - Наприклад, ваш код буде підключатися до PX4 за допомогою: + Наприклад, ваш код буде підключатися до PX4 за допомогою: - ```python - await drone.connect(system_address="udp://10.41.10.2:14540") - ``` + ```python + await drone.connect(system_address="udp://10.41.10.2:14540") + ``` :::info MAVSDK can connect to the PX4 on port `14550` if you don't modify the PX4 Ethernet port configuration. @@ -235,38 +236,38 @@ MAVSDK can connect to the PX4 on port `14550` if you don't modify the PX4 Ethern 1. Підключіть ваш автопілот і компаньйон комп'ютер за допомогою Ethernet. 2. [Start the uXRCE-DDS client on PX4](../middleware/uxrce_dds.md#starting-the-client), either manually or by customizing the system startup script. - Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). + Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). 3. [Start the micro XRCE-DDS agent on the companion computer](../middleware/uxrce_dds.md#starting-the-agent). - For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. + For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 4. Run a [listener node](../ros2/user_guide.md#running-the-example) in a new terminal to confirm the connection is established: - ```sh - source ~/ws_sensor_combined/install/setup.bash - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + source ~/ws_sensor_combined/install/setup.bash + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` - Якщо все налаштовано правильно, в терміналі повинен відображатися наступний вивід: + Якщо все налаштовано правильно, в терміналі повинен відображатися наступний вивід: - ```sh - RECEIVED SENSOR COMBINED DATA - ============================= - ts: 855801598 - gyro_rad[0]: -0.00339938 - gyro_rad[1]: 0.00440091 - gyro_rad[2]: 0.00513893 - gyro_integral_dt: 4997 - accelerometer_timestamp_relative: 0 - accelerometer_m_s2[0]: -0.0324082 - accelerometer_m_s2[1]: 0.0392213 - accelerometer_m_s2[2]: -9.77914 - accelerometer_integral_dt: 4997 - ``` + ```sh + RECEIVED SENSOR COMBINED DATA + ============================= + ts: 855801598 + gyro_rad[0]: -0.00339938 + gyro_rad[1]: 0.00440091 + gyro_rad[2]: 0.00513893 + gyro_integral_dt: 4997 + accelerometer_timestamp_relative: 0 + accelerometer_m_s2[0]: -0.0324082 + accelerometer_m_s2[1]: 0.0392213 + accelerometer_m_s2[2]: -9.77914 + accelerometer_integral_dt: 4997 + ``` ## Дивіться також diff --git a/docs/uk/advanced_config/prearm_arm_disarm.md b/docs/uk/advanced_config/prearm_arm_disarm.md index e59c5ae39a..56f2f5ab9e 100644 --- a/docs/uk/advanced_config/prearm_arm_disarm.md +++ b/docs/uk/advanced_config/prearm_arm_disarm.md @@ -54,19 +54,17 @@ RC controllers will use different sticks for throttle and yaw [based on their mo - _Озброєння:_ Ліва педаль вправо, права педаль вниз. - _Вимкнення:_ Ліва педаль вліво, права педаль вниз. -The required hold time can be configured using [COM_RC_ARM_HYST](#COM_RC_ARM_HYST). Note that by default ([COM_DISARM_MAN](#COM_DISARM_MAN)) you can also disarm in flight using gestures/buttons: you may choose to disable this to avoid accidental disarming. -| Параметр | Опис | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | -| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | -| [COM_RC_ARM_HYST](../advanced_config/parameter_reference.md#COM_RC_ARM_HYST) | Час, протягом якого педаль RC повинна бути утримана в позиції озброєння/вимкнення перед озброєнням/вимкненням (за замовчуванням: 1 секунда). | +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | +| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | ## Arming Button/Switch {#arm_disarm_switch} Кнопку _озброєння_ або "моментальний перемикач" можна налаштувати для спрацьовування озброєння/вимикання _замість_ [озброєння за допомогою жестів](#arm_disarm_gestures) (встановлення перемикача озброєння вимикає озброєння за допомогою жестів). -Кнопку слід утримувати натиснутою протягом ([зазвичай](#COM_RC_ARM_HYST)) однієї секунди, щоб озброїти (якщо вимкнено) або вимкнути (якщо озброєно). +The button should be held down for one second to arm (when disarmed) or disarm (when armed). Двопозиційний перемикач також може використовуватися для озброєння/вимикання, при цьому відповідні команди на озброєння/вимкнення надсилаються при _перемиканні_ перемикача. @@ -79,7 +77,7 @@ Note that by default ([COM_DISARM_MAN](#COM_DISARM_MAN)) you can also disarm in | Параметр | Опис | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [RC_MAP_ARM_SW](../advanced_config/parameter_reference.md#RC_MAP_ARM_SW) | Канал перемикача озброєння радіокерування (типове значення: 0 - не призначено). Якщо визначено, вказаний канал радіокерування (кнопка/перемикач) використовується для озброєння замість жесту палиці.
**Note:**
- This setting _disables the stick gesture_!
- This setting applies to RC controllers. It does not apply to Joystick controllers that are connected via _QGroundControl_. | -| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Перемикач озброєння є моментальною кнопкою.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a button or momentary button where the arm/disarm command ae sent after holding down button for set time ([COM_RC_ARM_HYST](#COM_RC_ARM_HYST)). | +| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Перемикач озброєння є моментальною кнопкою.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a momentary button where the arm/disarm command is sent after holding down the button for one second. | :::info Перемикач також можна налаштувати як частину конфігурації _QGroundControl_ для [Режиму польоту](../config/flight_mode.md). @@ -152,14 +150,14 @@ PX4 також видає підмножину інформації переві Типова послідовність запуску: 1. Увімкнення живлення. - - Усі приводи заблоковано у беззбройному(вимкненому) положенні - - Неможливо озброїти(збурити). + - Усі приводи заблоковано у беззбройному(вимкненому) положенні + - Неможливо озброїти(збурити). 2. Перемикання безпеки натиснуто. - - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). - - Безпека системи відключена: можливість озброєння(збурення). + - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). + - Безпека системи відключена: можливість озброєння(збурення). 3. Видається команда на озброєння(збурення). - - Система озброєна(збурена). - - Усі мотори та приводи можуть рухатися. + - Система озброєна(збурена). + - Усі мотори та приводи можуть рухатися. ### COM_PREARM_MODE=Disabled та Safety Switch @@ -169,14 +167,14 @@ PX4 також видає підмножину інформації переві Послідовність запуску така: 1. Увімкнення живлення. - - Усі приводи заблоковано у беззбройному(вимкненому) положенні - - Неможливо озброїти(збурити). + - Усі приводи заблоковано у беззбройному(вимкненому) положенні + - Неможливо озброїти(збурити). 2. Перемикання безпеки натиснуто. - - _All actuators stay locked into disarmed position (same as disarmed)._ - - Безпека системи відключена: можливість озброєння(збурення). + - _All actuators stay locked into disarmed position (same as disarmed)._ + - Безпека системи відключена: можливість озброєння(збурення). 3. Видається команда на озброєння(збурення). - - Система озброєна(збурена). - - Усі мотори та приводи можуть рухатися. + - Система озброєна(збурена). + - Усі мотори та приводи можуть рухатися. ### COM_PREARM_MODE=Always and Safety Switch @@ -187,13 +185,13 @@ PX4 також видає підмножину інформації переві Послідовність запуску така: 1. Увімкнення живлення. - - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). - - Неможливо озброїти(збурити). + - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). + - Неможливо озброїти(збурити). 2. Перемикання безпеки натиснуто. - - Безпека системи відключена: можливість озброєння(збурення). + - Безпека системи відключена: можливість озброєння(збурення). 3. Видається команда на озброєння(збурення). - - Система озброєна(збурена). - - Усі мотори та приводи можуть рухатися. + - Система озброєна(збурена). + - Усі мотори та приводи можуть рухатися. ### COM_PREARM_MODE=Safety(Безпека) або вимкнено(Disabled) та без перемикача безпеки(No Safety Switch) @@ -203,11 +201,11 @@ PX4 також видає підмножину інформації переві Послідовність запуску така: 1. Увімкнення живлення. - - Усі приводи заблоковано у беззбройному(вимкненому) положенні - - Безпека системи відключена: можливість озброєння(збурення). + - Усі приводи заблоковано у беззбройному(вимкненому) положенні + - Безпека системи відключена: можливість озброєння(збурення). 2. Видається команда на озброєння(збурення). - - Система озброєна(збурена). - - Усі мотори та приводи можуть рухатися. + - Система озброєна(збурена). + - Усі мотори та приводи можуть рухатися. ### COM_PREARM_MODE=Завжди і без зміни безпеки @@ -217,11 +215,11 @@ PX4 також видає підмножину інформації переві Послідовність запуску така: 1. Увімкнення живлення. - - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). - - Безпека системи відключена: можливість озброєння(збурення). + - Система зараз перевіряється перед збурюванням: актуатори без збурювання можуть рухатися (наприклад, елерони). + - Безпека системи відключена: можливість озброєння(збурення). 2. Видається команда на озброєння(збурення). - - Система озброєна(збурена). - - Усі мотори та приводи можуть рухатися. + - Система озброєна(збурена). + - Усі мотори та приводи можуть рухатися. ### Параметри diff --git a/docs/uk/advanced_config/sensor_thermal_calibration.md b/docs/uk/advanced_config/sensor_thermal_calibration.md index 2bb2ebe4ed..01464d59ec 100644 --- a/docs/uk/advanced_config/sensor_thermal_calibration.md +++ b/docs/uk/advanced_config/sensor_thermal_calibration.md @@ -94,11 +94,11 @@ PX4 підтримує два процедури калібрування: 9. Відкрийте вікно терміналу в каталозі **Firmware/Tools** і запустіть сценарій калібрування python: - ```sh - python process_sensor_caldata.py - ``` + ```sh + python process_sensor_caldata.py + ``` - Буде створено файл **.pdf**, у якому відображатимуться вимірювані дані та підгонка кривої для кожного датчика, а також файл **.params**, що містить параметри калібрування. + Буде створено файл **.pdf**, у якому відображатимуться вимірювані дані та підгонка кривої для кожного датчика, а також файл **.params**, що містить параметри калібрування. 10. Увімкніть плату, підключіть _QGroundControl_ та завантажте параметри зі створеного файлу **.params** на плату за допомогою _QGroundControl_. Відсоток виконання друкується на системній консолі під час калібрування. diff --git a/docs/uk/advanced_config/tuning_the_ecl_ekf.md b/docs/uk/advanced_config/tuning_the_ecl_ekf.md index 9974f16781..0755469343 100644 --- a/docs/uk/advanced_config/tuning_the_ecl_ekf.md +++ b/docs/uk/advanced_config/tuning_the_ecl_ekf.md @@ -152,29 +152,29 @@ Three axis body fixed magnetometer data at a minimum rate of 5Hz is required to Magnetometer data fusion can be configured using [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE): 0. Automatic: - - The magnetometer readings only affect the heading estimate before arming, and the whole attitude after arming. - - Heading and tilt errors are compensated when using this method. - - Incorrect magnetic field measurements can degrade the tilt estimate. - - The magnetometer biases are estimated whenever observable. + - The magnetometer readings only affect the heading estimate before arming, and the whole attitude after arming. + - Heading and tilt errors are compensated when using this method. + - Incorrect magnetic field measurements can degrade the tilt estimate. + - The magnetometer biases are estimated whenever observable. 1. Magnetic heading: - - Only the heading is corrected. - The tilt estimate is never affected by incorrect magnetic field measurements. - - Tilt errors that could arise when flying without velocity/position aiding are not corrected when using this method. - - The magnetometer biases are estimated whenever observable. + - Only the heading is corrected. + The tilt estimate is never affected by incorrect magnetic field measurements. + - Tilt errors that could arise when flying without velocity/position aiding are not corrected when using this method. + - The magnetometer biases are estimated whenever observable. 2. Deprecated 3. Deprecated 4. Deprecated 5. None: - - Magnetometer data is never used. - This is useful when the data can never be trusted (e.g.: high current close to the sensor, external anomalies). - - The estimator will use other sources of heading: [GPS heading](#yaw-measurements) or external vision. - - When using GPS measurements without another source of heading, the heading can only be initialized after sufficient horizontal acceleration. - See [Estimate yaw from vehicle movement](#yaw-from-gps-velocity) below. + - Magnetometer data is never used. + This is useful when the data can never be trusted (e.g.: high current close to the sensor, external anomalies). + - The estimator will use other sources of heading: [GPS heading](#yaw-measurements) or external vision. + - When using GPS measurements without another source of heading, the heading can only be initialized after sufficient horizontal acceleration. + See [Estimate yaw from vehicle movement](#yaw-from-gps-velocity) below. 6. Init only: - - Magnetometer data is only used to initialize the heading estimate. - This is useful when the data can be used before arming but not afterwards (e.g.: high current after the vehicle is armed). - - After initialization, the heading is constrained using other observations. - - Unlike mag type `None`, when combined with GPS measurements, this method allows position controlled modes to run directly during takeoff. + - Magnetometer data is only used to initialize the heading estimate. + This is useful when the data can be used before arming but not afterwards (e.g.: high current after the vehicle is armed). + - After initialization, the heading is constrained using other observations. + - Unlike mag type `None`, when combined with GPS measurements, this method allows position controlled modes to run directly during takeoff. The following selection tree can be used to select the right option: @@ -236,7 +236,7 @@ The following selection tree can be used to select the right option: 2. Витягніть `.ulg` файл журналу за допомогою, наприклад, [QGroundControl: Аналізувати > Завантажити журнал](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) - Той самий файл журналу можна використовувати для налаштування оцінювача вітру багатовертольотника [multirotor wind estimator](#mc_wind_estimation_using_drag). + Той самий файл журналу можна використовувати для налаштування оцінювача вітру багатовертольотника [multirotor wind estimator](#mc_wind_estimation_using_drag). ::: @@ -344,6 +344,60 @@ Weightings applied by the GSF to the individual 3-state EKF outputs are in the`w Зверніть увагу, що `ekf2_gps_drift` не зафіксовано! ::: +#### GNSS Fault Detection + +PX4's GNSS fault detection protects against malicious or erroneous GNSS signals using selective fusion control based on measurement validation. + +The fault detection logic depends on the GPS mode, and also operates differently for horizontal position and altitude measurements. +The mode is set using the [EKF2_GPS_MODE](../advanced_config/parameter_reference.md#EKF2_GPS_MODE) parameter: + +- **Automatic (`0`)** (Default): Assumes that GNSS is generally reliable and is likely to be recovered. + EKF2 resets on fusion timeouts if no other source of position is available. +- **Dead-reckoning (`1`)**: Assumes that GNSS might be lost indefinitely, so resets should be avoided while we have other estimates of position data. + EKF2 may reset if no other sources of position or velocity are available. + If GNSS altitude OR horizontal position data drifts, the system disables fusion of both measurements simultaneously (even if one would still pass validation) and avoids performing resets. + +##### Detection Logic + +Horizontal Position: + +- **Automatic mode**: Horizontal position resets to GNSS data if no other horizontal position source is currently being fused (e.g., Auxiliary Global Position - AGP). +- **Dead-reckoning mode**: Horizontal position resets to GNSS data only if no other horizontal position OR velocity source is currently being fused (e.g., AGP, airspeed, optical flow). + +Altitude: + +- The altitude logic is more complex due to the height reference sensor ([EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)) parameter, which is typically set to GNSS or baro in GNSS-denied scenarios. +- If height reference is set to baro, GNSS-based height resets are prevented (except when baro fusion fails completely and height reference automatically switches to GNSS). +- When height reference is set to GNSS: +- **Automatic mode**: Resets occur on drifting GNSS altitude measurements. +- **Dead-reckoning mode**: When validation starts failing, the system prevents GNSS altitude resets and labels the GNSS data as faulty. + +##### Faulty GNSS Data During Boot + +The system cannot automatically detect faulty GNSS data during vehicle boot as no baseline comparison exists. + +If GNSS fusion is enabled ([EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL)), operators will observe incorrect positions on maps and should disable GNSS fusion, then manually set the correct position via ground control station. +The global position gets corrected, and if [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) was enabled, baro offsets are automatically adjusted (through bias correction, not parameter changes). + +##### Enabling GNSS Fusion Mid-Flight + +With Faulty GNSS Data: + +- **Automatic mode**: Vehicle will reset to faulty position - potentially dangerous. +- **Dead-reckoning mode**: Large measurement differences cause GNSS rejection and fault detection activation. + +With Valid GNSS Data: + +- **Automatic mode**: Vehicle will reset to GNSS measurements. +- **Dead-reckoning mode**: If estimated position/altitude is close enough to measurements, fusion resumes; if too far apart, data gets labeled as faulty. + +##### Примітки + +- **Dual Detection**: Horizontal and altitude checks run completely separately but both lead to the same result when triggered - all GNSS fusion gets disabled. +- **Recovery**: Only the specific check that labeled data as invalid can re-enable fusion. +- **Alternative Sources**: Dead-reckoning mode provides enhanced protection by requiring absence of alternative navigation sources before allowing resets. +- **Boot Vulnerability**: Initial faulty GNSS data cannot be detected automatically; requires operator intervention and manual position correction. + ### Далекомір [Range finder](../sensor/rangefinders.md) distance to ground is used by a single state filter to estimate the vertical position of the terrain relative to the height datum. @@ -449,8 +503,8 @@ PX4 дозволяє постійно об'єднувати дальномер 1. Проведіть польоти один раз у режимі позиції [Position mode](../flight_modes_mc/position.md) повторно вперед/назад/ліворуч/праворуч/вгору/вниз між спокоєм і максимальною швидкістю (найкращі результати отримуються, коли цей тест проводиться в спокійних умовах). 2. Extract the **.ulg** log file using, for example, [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) - ::: info - The same **.ulg** log file can also be used to tune the [static pressure position error coefficients](#correction-for-static-pressure-position-error). + ::: info + The same **.ulg** log file can also be used to tune the [static pressure position error coefficients](#correction-for-static-pressure-position-error). ::: 3. Використовуйте журнал зі сценарієм Python [mc_wind_estimator_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/mc_wind_estimator), щоб отримати оптимальний набір параметрів. diff --git a/docs/uk/advanced_features/precland.md b/docs/uk/advanced_features/precland.md index 73bd09bed1..3081e1ef81 100644 --- a/docs/uk/advanced_features/precland.md +++ b/docs/uk/advanced_features/precland.md @@ -38,14 +38,14 @@ PX4 підтримує точне приземлення для _Multicopters_ Режим Точної посадки має три етапи: 1. **Горизонтальний підхід:** Транспортний засіб підходить до цілі горизонтально, утримуючи свою поточну висоту. - Як тільки положення цілі відносно транспортного засобу опускається нижче порогового значення ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), відбувається вхід до наступної фази. - Якщо ціль втрачається під час цієї фази (не видно довше, ніж [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), ініціюється процедура пошуку (під час необхідної точної посадки) або транспортний засіб робить звичайну посадку (під час можливої точної посадки). + Як тільки положення цілі відносно транспортного засобу опускається нижче порогового значення ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), відбувається вхід до наступної фази. + Якщо ціль втрачається під час цієї фази (не видно довше, ніж [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), ініціюється процедура пошуку (під час необхідної точної посадки) або транспортний засіб робить звичайну посадку (під час можливої точної посадки). 2. **Спуск над ціль:** Транспортний засіб спускається, залишаючись при цьому над ціллю. - Якщо ціль втрачається під час цієї фази (не видно довше, ніж `PLD_BTOUT`), ініціюється процедура пошуку (під час необхідної точної посадки) або транспортний засіб робить звичайну посадку (під час можливої точної посадки). + Якщо ціль втрачається під час цієї фази (не видно довше, ніж `PLD_BTOUT`), ініціюється процедура пошуку (під час необхідної точної посадки) або транспортний засіб робить звичайну посадку (під час можливої точної посадки). 3. **Останній підхід:** Коли транспортний засіб знаходиться близько до землі (ближче, ніж [PLD_FAPPR_ALT](../advanced_config/parameter_reference.md#PLD_FAPPR_ALT)), він спускається, залишаючись при цьому над ціллю. - Якщо ціль втрачається під час цієї фази, спуск продовжується незалежно від виду точної посадки. + Якщо ціль втрачається під час цієї фази, спуск продовжується незалежно від виду точної посадки. Процедури пошуку ініціюються на перших і других етапах і виконуються не більше [PLD_MAX_SRCH разів](../advanced_config/parameter_reference.md#PLD_MAX_SRCH). Діаграма потоку фаз посадки diff --git a/docs/uk/advanced_features/satcom_roadblock.md b/docs/uk/advanced_features/satcom_roadblock.md index c1c84a8dd4..91702bb349 100644 --- a/docs/uk/advanced_features/satcom_roadblock.md +++ b/docs/uk/advanced_features/satcom_roadblock.md @@ -54,19 +54,19 @@ To [switch between the two antennas modes](https://docs.groundcontrol.com/iot/ro Стандартна швидкість передачі даних модуля - 19200. However, the PX4 _iridiumsbd_ driver requires a baud rate of 115200 so it needs to be changed using the [AT commands](https://www.groundcontrol.com/wp-content/uploads/2022/02/IRDM_ISU_ATCommandReferenceMAN0009_Rev2.0_ATCOMM_Oct2012.pdf). 1. Connect to the module with using a 19200/8-N-1 setting and check if the communication is working using the command: `AT`. - Відповідь має бути: `OK`. + Відповідь має бути: `OK`. 2. Змінити швидкість передачі: - ``` - AT+IPR=9 - ``` + ``` + AT+IPR=9 + ``` 3. Знову підключіться до моделі з параметрами 115200/8-N-1 і збережіть конфігурацію за допомогою: - ``` - AT&W0 - ``` + ``` + AT&W0 + ``` Модуль тепер готовий до використання з PX4. @@ -101,55 +101,55 @@ drivers/telemetry/iridiumsbd Сервер relay має бути запущений або на Ubuntu 16.04 або 14.04 OS. 1. Сервер, який працює як ретранслятор повідомлень, повинен мати статичну IP-адресу та два загальнодоступних відкритих TCP-порти: - - `5672` для брокера повідомлень _RabbitMQ_ (можна змінити в налаштуваннях _rabbitmq_) - - `45679` для інтерфейсу HTTP POST (можна змінити у файлі **relay.cfg**) + - `5672` для брокера повідомлень _RabbitMQ_ (можна змінити в налаштуваннях _rabbitmq_) + - `45679` для інтерфейсу HTTP POST (можна змінити у файлі **relay.cfg**) 2. Встановіть необхідні модулі python: - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 3. Встановіть брокер повідомлень `rabbitmq`: - ```sh - sudo apt install rabbitmq-server - ``` + ```sh + sudo apt install rabbitmq-server + ``` 4. Налаштуйте облікові дані брокера (змініть PWD на ваш бажаний пароль): - ```sh - sudo rabbitmqctl add_user iridiumsbd PWD - sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" - ``` + ```sh + sudo rabbitmqctl add_user iridiumsbd PWD + sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" + ``` 5. Clone the [SatComInfrastructure](https://github.com/acfloria/SatComInfrastructure) repository: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 6. Перейдіть до розташування репозиторію _SatComInfrastructure_ і налаштуйте черги брокера: - ```sh - ./setup_rabbit.py localhost iridiumsbd PWD - ``` + ```sh + ./setup_rabbit.py localhost iridiumsbd PWD + ``` 7. Перевірте налаштування: - ```sh - sudo rabbitmqctl list_queues - ``` + ```sh + sudo rabbitmqctl list_queues + ``` - Це повинно дати вам список із 4 черг: `MO`, `MO_LOG`, `MT`, `MT_LOG` + Це повинно дати вам список із 4 черг: `MO`, `MO_LOG`, `MT`, `MT_LOG` 8. Edit the `relay.cfg` configuration file to reflect your settings. 9. Запустіть скрипт реле в режимі відокремленого виконання: - ```sh - screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py - ``` + ```sh + screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py + ``` Інші інструкції включають: @@ -177,15 +177,15 @@ drivers/telemetry/iridiumsbd 1. Встановіть необхідні модулі python: - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 2. Клонуйте репозиторій SatComInfrastructure: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 3. Відредагуйте конфігураційний файл **udp2rabbit.cfg**, щоб відображати ваші налаштування. @@ -193,20 +193,20 @@ drivers/telemetry/iridiumsbd 5. Додавайте UDP з'єднання в QGC з параметрами: - - Порт прослуховування: 10000 - - Цільові хости: 127.0.0.1:10001 - - Висока затримка: позначено + - Порт прослуховування: 10000 + - Цільові хости: 127.0.0.1:10001 + - Висока затримка: позначено - ![High Latency Link Settings](../../assets/satcom/linksettings.png) + ![High Latency Link Settings](../../assets/satcom/linksettings.png) ### Перевірка 1. Відкрийте термінал на комп'ютері наземної станції та перейдіть до розташування репозиторію _SatComInfrastructure_. - Потім запустіть скрипт **udp2rabbit.py**: + Потім запустіть скрипт **udp2rabbit.py**: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 2. Надішліть тестове повідомлення з облікового запису [RockBlock](https://rockblock.rock7.com/Operations) до створеної групи доставки на вкладці `Тестові групи доставки`. @@ -217,36 +217,36 @@ drivers/telemetry/iridiumsbd ## Запуск системи 1. Запустіть _QGroundControl_. - Спочатку вручну підключіть високо запізнюваний зв'язок, а потім звичайний телеметрійний зв'язок: + Спочатку вручну підключіть високо запізнюваний зв'язок, а потім звичайний телеметрійний зв'язок: - ![Connect the High Latency link](../../assets/satcom/linkconnect.png) + ![Connect the High Latency link](../../assets/satcom/linkconnect.png) 2. Відкрийте термінал на комп'ютері наземної станції та перейдіть до розташування репозиторію _SatComInfrastructure_. - Потім запустіть скрипт **udp2rabbit.py**: + Потім запустіть скрипт **udp2rabbit.py**: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 3. Увімкніть транспортний засіб. 4. Дочекайтеся, доки на QGC не буде отримано перше повідомлення `HIGH_LATENCY2`. - Це можна перевірити за допомогою віджету _Інспектора MAVLink_ або на панелі інструментів за допомогою _індикатора зв'язку(LinkIndicator)_. - Це можна перевірити за допомогою віджету _Інспектора MAVLink_ або на панелі інструментів за допомогою _індикатора зв'язку(LinkIndicator)_: + Це можна перевірити за допомогою віджету _Інспектора MAVLink_ або на панелі інструментів за допомогою _індикатора зв'язку(LinkIndicator)_. + Це можна перевірити за допомогою віджету _Інспектора MAVLink_ або на панелі інструментів за допомогою _індикатора зв'язку(LinkIndicator)_: - ![Link Toolbar](../../assets/satcom/linkindicator.jpg) + ![Link Toolbar](../../assets/satcom/linkindicator.jpg) - Індикатор зв'язку завжди показує назву пріоритетного зв'язку. + Індикатор зв'язку завжди показує назву пріоритетного зв'язку. 5. Супутникова система зв'язку тепер готова до використання. - Пріоритетний зв'язок, через який надсилаються команди, визначається наступними способами: - - Якщо користувач не вказав зв'язок, звичайний радіо телеметрійний зв'язок віддається перевагу перед високозапізнюваним зв'язком. - - Автопілот та QGC перехоплюватимуть звичайний радіо телеметрійний зв'язок на високозапізнюваний зв'язок, якщо транспортний засіб зброєний, а радіо телеметрійний зв'язок втрачений (не отримано жодного повідомлення MAVLink протягом певного часу). - Як тільки радіо телеметрійний зв'язок відновлюється, QGC та автопілот повертаються до нього. - - Користувач може вибрати пріоритетний зв'язок через індикатор зв'язку на панелі інструментів. - Це посилання зберігається як пріоритетне посилання, поки воно активне або користувач вибирає інше пріоритетне посилання: + Пріоритетний зв'язок, через який надсилаються команди, визначається наступними способами: + - Якщо користувач не вказав зв'язок, звичайний радіо телеметрійний зв'язок віддається перевагу перед високозапізнюваним зв'язком. + - Автопілот та QGC перехоплюватимуть звичайний радіо телеметрійний зв'язок на високозапізнюваний зв'язок, якщо транспортний засіб зброєний, а радіо телеметрійний зв'язок втрачений (не отримано жодного повідомлення MAVLink протягом певного часу). + Як тільки радіо телеметрійний зв'язок відновлюється, QGC та автопілот повертаються до нього. + - Користувач може вибрати пріоритетний зв'язок через індикатор зв'язку на панелі інструментів. + Це посилання зберігається як пріоритетне посилання, поки воно активне або користувач вибирає інше пріоритетне посилання: - ![Prioritylink Selection](../../assets/satcom/linkselection.png) + ![Prioritylink Selection](../../assets/satcom/linkselection.png) ## Усунення проблем diff --git a/docs/uk/airframes/airframe_reference.md b/docs/uk/airframes/airframe_reference.md index 73e677a2e3..c54f02eac1 100644 --- a/docs/uk/airframes/airframe_reference.md +++ b/docs/uk/airframes/airframe_reference.md @@ -615,6 +615,10 @@ div.frame_variant td, div.frame_variant th { Axial SCX10 2 Trail Honcho Підтримувач: John Doe <john@example.com>

SYS_AUTOSTART = 51001

+ + NXP B3RB Rover Ackermann + Підтримувач: John Doe <john@example.com>

SYS_AUTOSTART = 51002

+ Generic Rover Mecanum Підтримувач: John Doe <john@example.com>

SYS_AUTOSTART = 52000

@@ -628,7 +632,16 @@ div.frame_variant td, div.frame_variant th { ### Free-Flyer
- + + + + + + + + + +
Загальні виводи
  • Motor1: back left thruster, +x thrust
  • Motor2: front left thruster, -x thrust
  • Motor3: back right thruster, +x thrust
  • Motor4: front right thruster, -x thrust
  • Motor5: front left thruster, +y thrust
  • Motor6: front right thruster, -y thrust
  • Motor7: back left thruster, +y thrust
  • Motor8: back right thruster, -y thrust
@@ -638,7 +651,7 @@ div.frame_variant td, div.frame_variant th { - KTH-ATMOS + KTH-ATMOS Maintainer: DISCOWER

SYS_AUTOSTART = 70000

diff --git a/docs/uk/assembly/_assembly.md b/docs/uk/assembly/_assembly.md index bd458a8866..163acaf4f7 100644 --- a/docs/uk/assembly/_assembly.md +++ b/docs/uk/assembly/_assembly.md @@ -285,13 +285,13 @@ A particular vehicle might have more/fewer motors and actuators, but the wiring The following sections explain each part in more detail. :::tip -If you're using [DroneCAN ESC](../peripherals/esc_motors.md#dronecan) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. +If you're using [DroneCAN ESC](../dronecan/escs.md) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. ::: ### Flight Controller Power Pixhawk FCs require a regulated power supply that can supply at around 5V/3A continuous (check your specific FC)! -This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC transmitter, and low power telemetry radio, but not for motors, actuators, and other peripherals. +This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC receiver, and low power telemetry radio, but not for motors, actuators, and other peripherals. [Power modules](../power_module/index.md) are commonly used to "split off" this regulated power supply for the FC and also to provide measurements of the battery voltage and total current to the whole system — which PX4 can use to estimate power levels. The power module is connected to the FC power port, which is normally labeled `POWER` (or `POWER 1` or `POWER 2` for FCs that have redundant power supply). @@ -426,7 +426,6 @@ They recommend sensors, power systems, and other components from the same manufa - [Drone Components & Parts](../getting_started/px4_basic_concepts.md#drone-components-parts) (Basic Concepts) - [Payloads](../getting_started/px4_basic_concepts.md#payloads) (Basic Concepts) - [Hardware Selection & Setup](../hardware/drone_parts.md) — information about connecting and configuring specific flight controllers, sensors and other peripherals (e.g. airspeed sensor for planes). - - [Mounting the Flight Controller](../assembly/mount_and_orient_controller.md) - [Vibration Isolation](../assembly/vibration_isolation.md) - [Mounting a Compass](../assembly/mount_gps_compass.md) diff --git a/docs/uk/camera/fc_connected_camera.md b/docs/uk/camera/fc_connected_camera.md index f0efca7c45..648c29a108 100644 --- a/docs/uk/camera/fc_connected_camera.md +++ b/docs/uk/camera/fc_connected_camera.md @@ -188,16 +188,16 @@ PX4 видає повідомлення MAVLink [CAMERA_TRIGGER](https://mavlink 1. На консолі PX4: - ```shell - camera_trigger test - ``` + ```shell + camera_trigger test + ``` 2. Від _QGroundControl_: - Клацніть на **Запуск камери** на головній панелі інструментів. - Ці знімки не відображаються або не підраховуються для геотегування. + Клацніть на **Запуск камери** на головній панелі інструментів. + Ці знімки не відображаються або не підраховуються для геотегування. - ![QGC Тестова Камера](../../assets/camera/qgc_test_camera.png) + ![QGC Тестова Камера](../../assets/camera/qgc_test_camera.png) ## Приклад Sony QX-1 (Фотограметрія) diff --git a/docs/uk/camera/mavlink_v1_camera.md b/docs/uk/camera/mavlink_v1_camera.md index 75338d6c61..1321fc29ca 100644 --- a/docs/uk/camera/mavlink_v1_camera.md +++ b/docs/uk/camera/mavlink_v1_camera.md @@ -86,7 +86,7 @@ PX4 переістовує їх з тим самим ідентифікатор 1. Змініть невикористаний параметр `MAV_n_CONFIG`, такий як [MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG), щоб він був присвоєний порту, до якого підключена ваша камера. 2. Встановіть відповідний [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) на `2` (На борту). - Це забезпечує, що правильний набір повідомлень MAVLink випромінюється та пересилається. + Це забезпечує, що правильний набір повідомлень MAVLink випромінюється та пересилається. 3. Можливо, вам доведеться встановити деякі інші параметри, залежно від вашого з'єднання - наприклад, швидкість передачі даних. Підключіться та налаштуйте камеру, як рекомендовано в її посібнику користувача. diff --git a/docs/uk/camera/mavlink_v2_camera.md b/docs/uk/camera/mavlink_v2_camera.md index 29a58d2e96..c979c40845 100644 --- a/docs/uk/camera/mavlink_v2_camera.md +++ b/docs/uk/camera/mavlink_v2_camera.md @@ -112,7 +112,7 @@ PX4 видає команди [MAVLink Camera Protocol v2](https://mavlink.io/en 1. Змініть невикористаний параметр `MAV_n_CONFIG`, такий як [MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG), щоб він був присвоєний порту, до якого підключена ваша камера/компаньйонський комп'ютер. 2. Встановіть відповідний [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) на `2` (На борту). - Це забезпечує, що правильний набір повідомлень MAVLink випромінюється для супутнього комп'ютера (або камери). + Це забезпечує, що правильний набір повідомлень MAVLink випромінюється для супутнього комп'ютера (або камери). 3. Встановіть [MAV_2_FORWARD](../advanced_config/parameter_reference.md#MAV_2_FORWARD), щоб дозволити пересилання комунікацій з порту на інші порти, такі як той, що підключений до наземної станції. 4. Можливо, вам доведеться встановити деякі інші параметри, залежно від типу підключення та будь-яких конкретних вимог камери щодо очікуваної швидкості передачі даних і т. д. diff --git a/docs/uk/can/index.md b/docs/uk/can/index.md index 0c3707fc3a..14ebfa20ff 100644 --- a/docs/uk/can/index.md +++ b/docs/uk/can/index.md @@ -1,9 +1,19 @@ -# CAN +# CAN (DroneCAN & Cyphal) -[Мережа контролера (CAN)](https://en.wikipedia.org/wiki/CAN_bus) – це надійна дротова мережа, яка дозволяє компонентам дрона, таким як контролер польоту, ESC, датчики та інші периферійні пристрої, спілкуватися один з одним. -Так як він розроблений, щоб бути демократичним та використовує диференційну сигналізацію, він є дуже надійним навіть на довгих кабельних ділянках (на великих транспортних засобах) і уникне виникнення однієї точки відмови. +[Controller Area Network (CAN)](https://en.wikipedia.org/wiki/CAN_bus) is a robust wired network that allows drone components such as flight controller, ESCs, sensors, and other peripherals, to communicate with each other. + +It is particularly recommended on larger vehicles. + +## Загальний огляд + +CAN it is designed to be democratic and uses differential signaling. +For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN також дозволяє отримання зворотного зв'язку від периферійних пристроїв та зручне оновлення прошивки через шину. +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 підтримує два програмні протоколи для взаємодії з пристроями CAN: - [DroneCAN](../dronecan/README.md): PX4 рекомендує це для більшості типових налаштувань. @@ -18,29 +28,36 @@ PX4 підтримує два програмні протоколи для вз Відмінності між цими двома протоколами описані в [Cyphal vs. DroneCAN](https://forum.opencyphal.org/t/cyphal-vs-dronecan/1814). ::: -:::warning У PX4 немає підтримки інших програмних протоколів CAN для безпілотних літальних апаратів, таких як KDECAN (на момент написання). -::: ## Підключення Проводка для мереж CAN однакова як для DroneCAN, так і для Cyphal/CAN (фактично, для всіх мереж CAN). -Пристрої з'єднані у ланцюжку в будь-якому порядку. +Devices within a network are connected in a _daisy-chain_ in any order (this differs from UARTs peripherals, where you attach just one component per port). + +:::warning +Don't connect each CAN peripheral to a separate CAN port! +Unlike UARTs, CAN peripherals are designed to be daisy chained, with additional ports such as `CAN2` used for [redundancy](redundancy). +::: + На обох кінцях ланцюга між двома лініями передачі даних слід під’єднати термінальний резистор 120 Ом. Польотні контролери та деякі модулі GNSS мають вбудовані резистори завершення для зручності, тому їх слід розміщувати на протилежних кінцях ланцюга. В іншому випадку, ви можете використовувати резистор завершення, наприклад, [цей від Zubax Robotics](https://shop.zubax.com/products/uavcan-micro-termination-plug?variant=6007985111069), або припаяти його самостійно, якщо у вас є доступ до затискача JST-GH. Наступна діаграма показує приклад шини CAN, що з'єднує автопілот з 4 контролерами ESC CAN та GNSS. +It includes a redundant bus connected to `CAN 2`. ![CAN Wiring](../../assets/can/uavcan_wiring.svg) На схемі не показано електропроводку. Для підтвердження, чи компоненти потребують окремого живлення, чи можуть бути живлені від самої шини CAN, звертайтеся до інструкцій виробника. +:::info For more information, see [Cyphal/CAN device interconnection](https://wiki.zubax.com/public/cyphal/CyphalCAN-device-interconnection?pageId=2195476) (kb.zubax.com). Хоча стаття написана з урахуванням протоколу Cyphal, вона однаково стосується апаратного забезпечення DroneCAN і будь-яких інших налаштувань CAN. Для більш складних сценаріїв зверніться до розділу [Про топологію та термінацію шини CAN](https://forum.opencyphal.org/t/on-can-bus-topology-and-termination/1685). +::: ### З’єднання @@ -54,7 +71,30 @@ For more information, see [Cyphal/CAN device interconnection](https://wiki.zubax DroneCAN та Cyphal/CAN підтримують використання другого (резервного) інтерфейсу CAN. Це абсолютно необов'язково, але збільшує надійність підключення. -Всі контролери польоту Pixhawk мають 2 інтерфейси CAN; якщо ваші пристрої також підтримують 2 інтерфейси CAN, рекомендується підключити обидва для збільшення безпеки. + +Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +### Flight Controllers with Multiple CAN Ports + +[Flight Controllers](../flight_controller/index.md) may have up to three independent CAN ports, such as `CAN1`, `CAN2`, `CAN3` (neither DroneCAN or Cyphal support more than three). +Note that you can't have both DroneCAN and Cyphal running on PX4 at the same time. + +:::tip +You only _need_ one CAN port to support an arbitrary number of CAN devices using a particular CAN protocol. +Don't connect each CAN peripheral to a separate CAN port! +::: + +Generally you'll daisy all CAN peripherals off a single port, and if there is more than one CAN port, use the second one for [redundancy](redundancy). +If three are three ports, you might use the remaining network for devices that support another CAN protocol. + +The documentation for your flight controller should indicate which ports are supported/enabled. +At runtime you can check what DroneCAN ports are enabled and their status using the following command on the [MAVLink Shell](../debug/mavlink_shell.md) (or some other console): + +```sh +uavcan status +``` + +Note that you can also check the number of supported CAN interfaces for a board by searching for `CONFIG_BOARD_UAVCAN_INTERFACES` in its [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#) configuration file. ## Прошивка diff --git a/docs/uk/companion_computer/holybro_pixhawk_jetson_baseboard.md b/docs/uk/companion_computer/holybro_pixhawk_jetson_baseboard.md index 974ceb168a..97aa227df0 100644 --- a/docs/uk/companion_computer/holybro_pixhawk_jetson_baseboard.md +++ b/docs/uk/companion_computer/holybro_pixhawk_jetson_baseboard.md @@ -892,95 +892,95 @@ These instructions approximately mirror the [PX4 Ethernet setup](../advanced_con Next we modify the Jetson IP address to be on the same network as the Pixhawk: 1. Make sure `netplan` is installed. - You can check by running the following command: + You can check by running the following command: - ```sh - netplan -h - ``` + ```sh + netplan -h + ``` - If not, install it using the commands: + If not, install it using the commands: - ```sh - sudo apt update - sudo apt install netplan.io - ``` + ```sh + sudo apt update + sudo apt install netplan.io + ``` 2. Check `system_networkd` is running: - ```sh - sudo systemctl status systemd-networkd - ``` + ```sh + sudo systemctl status systemd-networkd + ``` - You should see output like below if it is active: + You should see output like below if it is active: - ```sh - ● systemd-networkd.service - Network Configuration - Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) - Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago - TriggeredBy: ● systemd-networkd.socket - Docs: man:systemd-networkd.service(8) - Main PID: 2452 (systemd-network) - Status: "Processing requests..." - Tasks: 1 (limit: 18457) - Memory: 2.7M - CPU: 157ms - CGroup: /system.slice/systemd-networkd.service - └─2452 /lib/systemd/systemd-networkd + ```sh + ● systemd-networkd.service - Network Configuration + Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) + Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago + TriggeredBy: ● systemd-networkd.socket + Docs: man:systemd-networkd.service(8) + Main PID: 2452 (systemd-network) + Status: "Processing requests..." + Tasks: 1 (limit: 18457) + Memory: 2.7M + CPU: 157ms + CGroup: /system.slice/systemd-networkd.service + └─2452 /lib/systemd/systemd-networkd - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed - Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - ``` + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed + Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + ``` - If `system_networkd` is not running, it can be enabled using: + If `system_networkd` is not running, it can be enabled using: - ```sh - sudo systemctl start systemd-networkd - sudo systemctl enable systemd-networkd - ``` + ```sh + sudo systemctl start systemd-networkd + sudo systemctl enable systemd-networkd + ``` 3. Open the Netplan configuration file (so we can set up a static IP for the Jetson). - The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). - Below we use `nano` to open the file, but you can use your preferred text editor: + The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). + Below we use `nano` to open the file, but you can use your preferred text editor: - ```sh - sudo nano /etc/netplan/01-netcfg.yaml - ``` + ```sh + sudo nano /etc/netplan/01-netcfg.yaml + ``` 4. Modify the yaml configuration, by overwriting the contents with the following information and then saving: - ```sh - network: - version: 2 - renderer: networkd - ethernets: - eth0: - dhcp4: no - addresses: - - 10.41.10.1/24 - routes: - - to: 0.0.0.0/0 - via: 10.41.10.254 - nameservers: - addresses: - - 10.41.10.254 - ``` + ```sh + network: + version: 2 + renderer: networkd + ethernets: + eth0: + dhcp4: no + addresses: + - 10.41.10.1/24 + routes: + - to: 0.0.0.0/0 + via: 10.41.10.254 + nameservers: + addresses: + - 10.41.10.254 + ``` - This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . + This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . 5. Apply the changes using the following command: - ```sh - sudo netplan apply - ``` + ```sh + sudo netplan apply + ``` The Pixhawk Ethernet address is set to `10.41.10.2` by default, which is on the same subnet. We can test our changes above by pinging the Pixhawk from within the Jetson terminal: diff --git a/docs/uk/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md b/docs/uk/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md index a9a506b734..7342bd079a 100644 --- a/docs/uk/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md +++ b/docs/uk/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md @@ -69,15 +69,15 @@ To install the RPi CM4 companion computer: 1. Disconnect the `FAN` wiring. - ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) + ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) 2. Видаліть ці 4 гвинти на задній стороні підлогової дошки. - ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) + ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) 3. Видаліть підставку корпусу, встановіть CM4 та використовуйте 4 гвинти для його кріплення (як показано): - ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) + ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) 4. Прикріпіть кришку знову. @@ -115,29 +115,29 @@ RPi CM4 та контролер польоту повинні бути живл 1. Switch Dip-Switch to `RPI`. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) 2. Підключіть комп'ютер до порту USB-C _CM4 Slave_, що використовується для живлення та прошивки RPi. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) 3. Отримайте `usbboot`, зберіть його та запустіть. - ```sh - sudo apt install libusb-1.0-0-dev - git clone --depth=1 https://github.com/raspberrypi/usbboot - cd usbboot - make - sudo ./rpiboot - ``` + ```sh + sudo apt install libusb-1.0-0-dev + git clone --depth=1 https://github.com/raspberrypi/usbboot + cd usbboot + make + sudo ./rpiboot + ``` 4. Тепер ви можете встановити свою перевагу Linux дистрибутив за допомогою `rpi-imager`. - Переконайтеся, що ви додали налаштування WiFi та SSH (приховані за символом шестерні / розширеним). + Переконайтеся, що ви додали налаштування WiFi та SSH (приховані за символом шестерні / розширеним). - ```sh - sudo apt install rpi-imager - rpi-imager - ``` + ```sh + sudo apt install rpi-imager + rpi-imager + ``` 5. Після завершення відключення USB-C CM4 Slave (це відмонтує томи та вимкне CM4). @@ -146,8 +146,8 @@ RPi CM4 та контролер польоту повинні бути живл 7. Увімкніть CM4, надаючи живлення через порт USB-C CM4 Slave. 8. Щоб перевірити, чи запускається/працює, ви можете або: - - Перевірте, чи є вихід HDMI - - Підключіться через SSH (якщо налаштовано в rpi-imager, і є доступ до WiFi). + - Перевірте, чи є вихід HDMI + - Підключіться через SSH (якщо налаштовано в rpi-imager, і є доступ до WiFi). ## Налаштуйте послідовне підключення PX4 до CM4 MAVLink @@ -167,13 +167,13 @@ FC повинен бути налаштований для підключенн 1. Підключіть комп'ютер, на якому працює QGroundControl, через порт USB Type C на базовій платі, позначеній як `FC` - ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) + ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) 2. [Встановіть параметри](../advanced_config/parameters.md): - - `MAV_1_CONFIG` = `102` - - `MAV_1_MODE = 2` - - `SER_TEL2_BAUD` = `921600` + - `MAV_1_CONFIG` = `102` + - `MAV_1_MODE = 2` + - `SER_TEL2_BAUD` = `921600` 3. Перезавантажте FC. @@ -185,13 +185,13 @@ FC повинен бути налаштований для підключенн 2. Увімкніть послідовний порт RPi, запустивши `RPi-config` - - Перейдіть до `3 Варіанти інтерфейсу`, потім `I6 Серійний порт`. - Потім введіть: - - `login shell accessible over serial → No` - - `serial port hardware enabled` → `Yes` + - Перейдіть до `3 Варіанти інтерфейсу`, потім `I6 Серійний порт`. + Потім введіть: + - `login shell accessible over serial → No` + - `serial port hardware enabled` → `Yes` 3. Завершіть і перезавантажте. - This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. + This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. 4. Тепер MAVLink-трафік повинен бути доступний на `/dev/serial0` з швидкістю передачі даних 921600. @@ -201,9 +201,9 @@ FC повинен бути налаштований для підключенн 2. Встановіть MAVSDK Python: - ```sh - python3 -m pip install mavsdk - ``` + ```sh + python3 -m pip install mavsdk + ``` 3. Скопіюйте приклад з [прикладів MAVSDK-Python](https://github.com/mavlink/MAVSDK-Python/tree/main/examples). diff --git a/docs/uk/companion_computer/pixhawk_rpi.md b/docs/uk/companion_computer/pixhawk_rpi.md index 0444585614..fc42ebb5ec 100644 --- a/docs/uk/companion_computer/pixhawk_rpi.md +++ b/docs/uk/companion_computer/pixhawk_rpi.md @@ -132,50 +132,50 @@ make px4_fmu-v6c_default upload 1. Встановіть `raspi-config`: - ```sh - sudo apt update - sudo apt upgrade - sudo apt-get install raspi-config - ``` + ```sh + sudo apt update + sudo apt upgrade + sudo apt-get install raspi-config + ``` 2. Open `raspi-config`: - ```sh - sudo raspi-config - ``` + ```sh + sudo raspi-config + ``` 3. Перейдіть до **Варіанти інтерфейсу**, а потім клацніть **Серійний порт**. - - Виберіть **No**, щоб вимкнути послідовний вхід у оболонку. - - Виберіть **Так**, щоб увімкнути послідовний інтерфейс. - - Клацніть **Завершити** та перезапустіть RPi. + - Виберіть **No**, щоб вимкнути послідовний вхід у оболонку. + - Виберіть **Так**, щоб увімкнути послідовний інтерфейс. + - Клацніть **Завершити** та перезапустіть RPi. 4. Відкрийте файл конфігурації завантаження прошивки в редакторі `nano` на RaPi: - ```sh - sudo nano /boot/firmware/config.txt - ``` + ```sh + sudo nano /boot/firmware/config.txt + ``` 5. Додайте наступний текст в кінець файлу (після останнього рядка): - ```sh - enable_uart=1 - dtoverlay=disable-bt - ``` + ```sh + enable_uart=1 + dtoverlay=disable-bt + ``` 6. Далі збережіть файл і перезапустіть RPi. - - У `nano` ви можете зберегти файл за допомогою такої послідовності комбінацій клавіш: **ctrl+x**, **ctrl+y**, **Enter**. + - У `nano` ви можете зберегти файл за допомогою такої послідовності комбінацій клавіш: **ctrl+x**, **ctrl+y**, **Enter**. 7. Перевірте, чи доступний послідовний порт. - В даному випадку ми використовуємо наступні команди для перегляду серійних пристроїв: + В даному випадку ми використовуємо наступні команди для перегляду серійних пристроїв: - ```sh - cd / - ls /dev/ttyAMA0 - ``` + ```sh + cd / + ls /dev/ttyAMA0 + ``` - Результат команди повинен містити підключення RX/TX `/dev/ttyAMA0` (зверніть увагу, що цей послідовний порт також доступний як `/dev/serial0`). + Результат команди повинен містити підключення RX/TX `/dev/ttyAMA0` (зверніть увагу, що цей послідовний порт також доступний як `/dev/serial0`). RPi наразі налаштований для роботи з RPi та зв'язку за допомогою послідовного порту `/dev/ttyAMA0`. Зверніть увагу, що ми встановимо додаткове програмне забезпечення в наступних розділах для роботи з MAVLink та ROS 2. @@ -199,38 +199,38 @@ PX4 рекомендує використовувати [MAVSDK](https://mavsdk. 2. Відкрийте QGroundControl (повинно з'єднатися з транспортним засобом). 3. [Перевірте/змініть наступні параметри](../advanced_config/parameters.md) в QGroundControl: - ```ini - MAV_1_CONFIG = TELEM2 - UXRCE_DDS_CFG = 0 (Disabled) - SER_TEL2_BAUD = 57600 - ``` + ```ini + MAV_1_CONFIG = TELEM2 + UXRCE_DDS_CFG = 0 (Disabled) + SER_TEL2_BAUD = 57600 + ``` - Зверніть увагу, що параметри можуть вже бути налаштовані належним чином. - Для отримання інформації про те, як працюють послідовні порти та конфігурація MAVLink, див. [Конфігурація послідовного порту](../peripherals/serial_configuration.md) та [Периферійні пристрої MAVLink](../peripherals/mavlink_peripherals.md). + Зверніть увагу, що параметри можуть вже бути налаштовані належним чином. + Для отримання інформації про те, як працюють послідовні порти та конфігурація MAVLink, див. [Конфігурація послідовного порту](../peripherals/serial_configuration.md) та [Периферійні пристрої MAVLink](../peripherals/mavlink_peripherals.md). Потім встановіть налаштування MAVProxy на RPi за допомогою наступних термінальних команд: 1. Встановіть MAVProxy: - ```sh - sudo apt install python3-pip - sudo pip3 install mavproxy - sudo apt remove modemmanager - ``` + ```sh + sudo apt install python3-pip + sudo pip3 install mavproxy + sudo apt remove modemmanager + ``` 2. Запустіть MAVProxy, встановивши порт для підключення до `/dev/ttyAMA0` та швидкість передачі даних, щоб відповідати PX4: - ```sh - sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 - ``` + ```sh + sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 + ``` - Зверніть увагу, що вище ми використовували `/dev/serial0`, але ми могли б так само добре використовувати `/dev/ttyAMA0`. - Якщо ми підключалися через USB, тоді ми замість цього встановили порт як `/dev/ttyACM0`: + Зверніть увагу, що вище ми використовували `/dev/serial0`, але ми могли б так само добре використовувати `/dev/ttyAMA0`. + Якщо ми підключалися через USB, тоді ми замість цього встановили порт як `/dev/ttyACM0`: - ```sh - sudo chmod a+rw /dev/ttyACM0 - sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 - ``` + ```sh + sudo chmod a+rw /dev/ttyACM0 + sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 + ``` ::: @@ -258,26 +258,26 @@ The [ROS 2 Guide](../ros2/user_guide.md) and [uXRCE-DDS](../middleware/uxrce_dds 2. [Перевірте/змініть наступні параметри](../advanced_config/parameters.md) в QGroundControl: - ```ini - MAV_1_CONFIG = 0 (Disabled) - UXRCE_DDS_CFG = 102 (TELEM2) - SER_TEL2_BAUD = 921600 - ``` + ```ini + MAV_1_CONFIG = 0 (Disabled) + UXRCE_DDS_CFG = 102 (TELEM2) + SER_TEL2_BAUD = 921600 + ``` - [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) та [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) вимикають MAVLink на TELEM2 та увімкнюють клієнт uXRCE-DDS на TELEM2, відповідно. - Швидкість `SER_TEL2_BAUD` встановлює швидкість передачі даних зв'язку.\ - Ви так само можете налаштувати підключення до `TELEM1`, використовуючи або `MAV_1_CONFIG`, або `MAV_0_CONFIG`. + [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) та [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) вимикають MAVLink на TELEM2 та увімкнюють клієнт uXRCE-DDS на TELEM2, відповідно. + Швидкість `SER_TEL2_BAUD` встановлює швидкість передачі даних зв'язку. + Ви так само можете налаштувати підключення до `TELEM1`, використовуючи або `MAV_1_CONFIG`, або `MAV_0_CONFIG`. - Вам потрібно перезавантажити керування польотом, щоб застосувати будь-які зміни до цих параметрів. + Вам потрібно перезавантажити керування польотом, щоб застосувати будь-які зміни до цих параметрів. ::: 3. Перевірте, що модуль [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) зараз працює. - Ви можете це зробити, запустивши наступну команду в QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): + Ви можете це зробити, запустивши наступну команду в QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - ```sh - uxrce_dds_client status - ``` + ```sh + uxrce_dds_client status + ``` :::info Якщо модуль клієнта не працює, ви можете запустити його вручну в консолі MAVLink: @@ -298,32 +298,32 @@ uxrce_dds_client start -t serial -d /dev/ttyS3 -b 921600 2. Встановіть git за допомогою терміналу RPi: - ```sh - sudo apt install git - ``` + ```sh + sudo apt install git + ``` 3. Встановіть агент uXRCE_DDS: - ```sh - git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` - Див. [uXRCE-DDS > Встановлення агента Micro XRCE-DDS](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) для альтернативних способів встановлення агента. + Див. [uXRCE-DDS > Встановлення агента Micro XRCE-DDS](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) для альтернативних способів встановлення агента. 4. Запустіть агента в терміналі RPi: - ```sh - sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 - ``` + ```sh + sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 + ``` - Зверніть увагу, як ми використовуємо раніше налаштований послідовний порт і ту саму швидкість передачі даних, що й для PX4. + Зверніть увагу, як ми використовуємо раніше налаштований послідовний порт і ту саму швидкість передачі даних, що й для PX4. Тепер, коли обидва агент та клієнт працюють, ви повинні бачити активність як на консолі MAVLink, так і на терміналі RPi. Ви можете переглянути доступні теми за допомогою наступної команди на RPi: diff --git a/docs/uk/companion_computer/video_streaming_wfb_ng_wifi.md b/docs/uk/companion_computer/video_streaming_wfb_ng_wifi.md index 2b4fd1a73d..9abe46e1a4 100644 --- a/docs/uk/companion_computer/video_streaming_wfb_ng_wifi.md +++ b/docs/uk/companion_computer/video_streaming_wfb_ng_wifi.md @@ -80,18 +80,18 @@ Alpha AWUS036ACH - це карта середньої потужності, як 5. Налаштуйте камерний канал. Відкрийте `/etc/systemd/system/fpv-camera.service` і розкоментуйте конвеєр відповідно до вашої камери (камера PI або камера Logitech) 6. Відкрийте `/etc/wifibroadcast.cfg` і налаштуйте канал WiFi відповідно до налаштувань вашої антени (або використовуйте замовчуваний #165 для 5.8GHz) 7. Налаштуйте PX4 на вивід потоку телеметрії зі швидкістю 1500 Кбіт/с (інші швидкості UART не добре відповідають дільникам частоти RPI). - Підключіть UART Pixhawk до UART Raspberry PI. - У розділі `/etc/wifibroadcast.cfg` файлу розкоментуйте `peer = 'serial:ttyS0:1500000'` секцію. + Підключіть UART Pixhawk до UART Raspberry PI. + У розділі `/etc/wifibroadcast.cfg` файлу розкоментуйте `peer = 'serial:ttyS0:1500000'` секцію. ### Використання ноутбука Linux як GCS (важче, ніж використання RasPi) 1. На **наземному** Linux комп'ютері розробки: - ```sh - sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted - git clone -b stable https://github.com/svpcom/wfb-ng.git - cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb - ``` + ```sh + sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted + git clone -b stable https://github.com/svpcom/wfb-ng.git + cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb + ``` 2. Слідуйте інструкції з [Setup HOWTO](https://github.com/svpcom/wfb-ng/wiki/Setup-HOWTO) для завершення встановлення diff --git a/docs/uk/complete_vehicles_mc/amov_F410_drone.md b/docs/uk/complete_vehicles_mc/amov_F410_drone.md index 9f7a98d6d2..e6a906bb4c 100644 --- a/docs/uk/complete_vehicles_mc/amov_F410_drone.md +++ b/docs/uk/complete_vehicles_mc/amov_F410_drone.md @@ -22,7 +22,7 @@ It is pre-installed with PX4 v1.15.4 at time of writing (a more recent version m - Compatibility with many different components, providing platform for loading other user sensors, preparing for functional model development. - Abundant power supply making it perfect for installing additional sensors and onboard computers (including 5 external output voltages, 3 channels of 5V, 2 channels of 12V). - Pc-SDK support. - This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! + This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! - The [documentation](https://docs.amovlab.com/f450-v6c-wiki/#/en/) shows many of the options. 7. Quasi-smart battery. The battery has a hard housing design that makes easy to install and remove. It provides accurate power estimates, but does not have some more advanced "smart battery" features. diff --git a/docs/uk/complete_vehicles_mc/crazyflie2.md b/docs/uk/complete_vehicles_mc/crazyflie2.md index f30f6bdc0c..369edb5a70 100644 --- a/docs/uk/complete_vehicles_mc/crazyflie2.md +++ b/docs/uk/complete_vehicles_mc/crazyflie2.md @@ -51,54 +51,54 @@ _Crazyflie 2.0_ було [припинено/замінено](../flight_control 1. Завантажте вихідний код завантажувача PX4: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git + ``` 2. Перейдіть до верхньої директорії вихідного коду та скомпілюйте його за допомогою: - ```sh - make crazyflie_bl - ``` + ```sh + make crazyflie_bl + ``` 3. Поставте Crazyflie 2.0 у режим DFU, виконавши ці кроки: - - Спочатку переконайтеся, що він знеструмлений. - - Утримуйте кнопку скидання (див. малюнок нижче...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Підключіть до USB-порту комп'ютера. - - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. - - Відпустіть кнопку. + - Спочатку переконайтеся, що він знеструмлений. + - Утримуйте кнопку скидання (див. малюнок нижче...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Підключіть до USB-порту комп'ютера. + - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. + - Відпустіть кнопку. 4. Встановіть _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Виконайте прошивку завантажувальника за допомогою _dfu-util_ та від'єднайте Crazyflie 2.0, коли це зроблено: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin + ``` - Коли увімкнено Crazyflie 2.0, жовтий світлодіод повинен мигати. + Коли увімкнено Crazyflie 2.0, жовтий світлодіод повинен мигати. 6. Завантажте вихідний код завантажувача автопілоту PX4: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Перейдіть до верхньої директорії вихідного коду та скомпілюйте його за допомогою: - ```sh - make bitcraze_crazyflie_default upload - ``` + ```sh + make bitcraze_crazyflie_default upload + ``` 8. Коли вас попросять підключити пристрій, підключіть Crazyflie 2.0. - Жовтий світлодіод повинен почати блимати, що вказує на режим завантажувача. - Потім червоний світлодіод повинен увімкнутися, що вказує на те, що процес мигання розпочався. + Жовтий світлодіод повинен почати блимати, що вказує на режим завантажувача. + Потім червоний світлодіод повинен увімкнутися, що вказує на те, що процес мигання розпочався. 9. Очікування завершення. diff --git a/docs/uk/complete_vehicles_mc/crazyflie21.md b/docs/uk/complete_vehicles_mc/crazyflie21.md index dc72e0b539..6b1e40dd18 100644 --- a/docs/uk/complete_vehicles_mc/crazyflie21.md +++ b/docs/uk/complete_vehicles_mc/crazyflie21.md @@ -64,56 +64,56 @@ An overview of the Crazyflie 2.1 can be [found here](https://www.bitcraze.io/pro 1. Завантажте вихідний код завантажувача PX4: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules + ``` 2. Перейдіть до верхньої директорії вихідного коду та скомпілюйте його за допомогою: - ```sh - make crazyflie21_bl - ``` + ```sh + make crazyflie21_bl + ``` 3. Поставте Crazyflie 2.1 у режим DFU, виконавши ці кроки: - - Спочатку переконайтеся, що він знеструмлений. - - Переконайтеся, що акумулятор від'єднаний. - - Утримуйте кнопку скидання (див. малюнок нижче...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Підключіть до USB-порту комп'ютера. - - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. - - Відпустіть кнопку. + - Спочатку переконайтеся, що він знеструмлений. + - Переконайтеся, що акумулятор від'єднаний. + - Утримуйте кнопку скидання (див. малюнок нижче...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Підключіть до USB-порту комп'ютера. + - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. + - Відпустіть кнопку. 4. Встановіть _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Виконайте прошивку завантажувальника за допомогою _dfu-util_ та від'єднайте Crazyflie 2.1, коли це зроблено: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin + ``` - Коли увімкнено Crazyflie 2.1, жовтий світлодіод повинен мигати. + Коли увімкнено Crazyflie 2.1, жовтий світлодіод повинен мигати. 6. Завантажте вихідний код завантажувача автопілоту PX4: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Перейдіть до верхньої директорії вихідного коду та скомпілюйте його за допомогою: - ```sh - cd PX4-Autopilot/ - make bitcraze_crazyflie21_default upload - ``` + ```sh + cd PX4-Autopilot/ + make bitcraze_crazyflie21_default upload + ``` 8. Коли вас попросять підключити пристрій, підключіть Crazyflie 2.1. - Жовтий світлодіод повинен почати блимати, що вказує на режим завантажувача. - Потім червоний світлодіод повинен увімкнутися, що вказує на те, що процес мигання розпочався. + Жовтий світлодіод повинен почати блимати, що вказує на режим завантажувача. + Потім червоний світлодіод повинен увімкнутися, що вказує на те, що процес мигання розпочався. 9. Очікування завершення. @@ -124,20 +124,20 @@ An overview of the Crazyflie 2.1 can be [found here](https://www.bitcraze.io/pro 1. Завантажте останній [завантажувач Crazyflie 2.1](https://github.com/bitcraze/crazyflie2-stm-bootloader/releases) 2. Поставте Crazyflie 2.1 у режим DFU, виконавши ці кроки: - - Спочатку переконайтеся, що він знеструмлений. - - Переконайтеся, що акумулятор від'єднаний. - - Утримуйте кнопку скидання. - - Підключіть до USB-порту комп'ютера. - - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. - - Відпустіть кнопку. + - Спочатку переконайтеся, що він знеструмлений. + - Переконайтеся, що акумулятор від'єднаний. + - Утримуйте кнопку скидання. + - Підключіть до USB-порту комп'ютера. + - Через секунду синій світлодіод повинен почати блимати, а через 5 секунд повинен почати блимати швидше. + - Відпустіть кнопку. 3. Виконайте прошивку завантажувальника за допомогою _dfu-util_ та від'єднайте Crazyflie 2.1, коли це зроблено: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin + ``` - Коли увімкнено Crazyflie 2.1, жовтий світлодіод повинен мигати. + Коли увімкнено Crazyflie 2.1, жовтий світлодіод повинен мигати. 4. Встановіть останнє програмне забезпечення для польоту Bitcraze Crazyflie 2.1, використовуючи [цей](https://www.bitcraze.io/documentation/tutorials/getting-started-with-crazyflie-2-x/#update-fw) посібник. diff --git a/docs/uk/complete_vehicles_mc/modalai_starling.md b/docs/uk/complete_vehicles_mc/modalai_starling.md index 4377709ef6..22e1583c33 100644 --- a/docs/uk/complete_vehicles_mc/modalai_starling.md +++ b/docs/uk/complete_vehicles_mc/modalai_starling.md @@ -1,127 +1,39 @@ -# ModalAI Starling (PX4 Autonomy Developer Kit) +# ModalAI Starling 2 -The [Starlings](https://www.modalai.com/pages/starlings) are SLAM development drones supercharged by [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -За допомогою автопілота Blue UAS Framework, VOXL 2, Starling важить всього 275 г і має вражаючі 30 хвилин автономного польоту в приміщенні. +The [Starlings](https://www.modalai.com/pages/starlings) are NDAA-compliant SLAM development drones based on the [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -![Огляд](../../assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg) +## Загальний огляд -The ModalAI PX4 Autonomy Developer Kit is a Starling-based development drone. -It houses a [VOXL 2](../flight_controller/modalai_voxl_2.md), which is a powerful companion computer and PX4 flight controller in one small package, image sensors, GPS, and connectivity modem, and is ready-to-fly out-of-the-box. -The Starling features ModalAI's [open SDK](https://docs.modalai.com/voxl-developer-bootcamp/) that has pre-configured autonomy models for computer vision assisted flight. -Цей розвивальний дрон призначений, щоб допомогти вам швидше вийти на ринок та прискорити розробку та прототипування вашої програми. +Starling drones house _VOXL 2_, which is a powerful companion computer, a PX4 flight controller, image sensors, GPS, and connectivity modem, in one small package. +The Starlings feature ModalAI's open source [VOXL SDK](https://gitlab.com/voxl-public/voxl-sdk) that has pre-configured autonomy models for computer vision assisted flight. -Цей посібник пояснює мінімальну додаткову настройку, необхідну для підготовки БПЛА до польоту. -Він також охоплює огляд апаратного забезпечення, перший польот, налаштування WiFi та інше. - -:::info -Для повного та регулярно оновлюваного документування відвідайте . -::: +These development drones are ready-to-fly out-of-the-box. +They are designed to help you get to market faster and accelerate your application development and prototyping. :::info Якщо ви новачок у VOXL, обов'язково ознайомтеся з основними функціями апаратного та програмного забезпечення VOXL, переглянувши [VOXL Bootcamp](https://docs.modalai.com/voxl-developer-bootcamp/). ::: +:::info +For complete and regularly updated documentation, please visit and . +::: + +## Starling 2 + +The [Starling 2](https://www.modalai.com/products/starling-2) is an NDAA-compliant development drone supercharged by the VOXL SDK and equipped with a new image sensor suite for precise, indoor visual navigation and SLAM. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 weighs 280g and boasts an impressive 40 minutes of autonomous flight time. + +![Image of the front of Starling 2](../../assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png) + +## Starling 2 Max + +The [Starling 2 Max](https://www.modalai.com/products/starling-2-max) is VOXL 2-powered, NDAA-compliant development drone supercharged by VOXL SDK specifically designed for computer vision-based, long-range dead reckoning with a 500g payload capacity. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 Max weighs 500g and boasts an impressive 55 minutes of autonomous flight time. + +![Image of front of a Starling 2 Max](../../assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png) + ## Де купити -[ModalAI PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit?variant=46969885950256) +[ModalAI Starling 2](https://www.modalai.com/products/starling-2) -## Налаштування обладнання - -![Огляд апаратної частини](../../assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg) - -| Callout | Опис | MPN | -| ------- | ------------------------------------------------------------ | ---------------- | -| A | VOXL 2 | MDK-M0054-1 | -| B | VOXL 4-in-1 ESC | MDK-M0117-1 | -| C | Заглушка для барометра | M10000533 | -| D | Датчик зображення ToF (PMD) | MDK-M0040 | -| E | Датчик відстеження зображень (OV7251) | M0014 | -| F | Датчик зображення високої якості (IMX214) | M0025-2 | -| G | AC600 WiFi Dongle | AWUS036EACS | -| H | Модуль GNSS GPS & Компас | M10-5883 | -| I | Приймач ELRS 915МГц | BetaFPV Nano RX | -| J | Роз'єм USB C на VOXL 2 (не відображено) | | -| K | Блок живлення VOXL | MCCA-M0041-5-B-T | -| L | 4726FM Пропелер | M10000302 | -| M | Мотор 1504 | | -| N | XT30 Конектор живлення | | - -## Документація - -### Характеристики - -| Компонент | Специфікація | -| ------------------------ | ------------------------------------------------------------------- | -| Автопілот | VOXL2 | -| Максимальна взлітна вага | 275г (172г без батареї) | -| Розмір по діагоналі | 211мм | -| Час польоту | 30 хвилин | -| Двигуни | 1504 | -| Пропелери | 120mm | -| Frame | Карбонове волокно 3мм | -| ESC | ModalAI VOXL 4-in-1 ESC V2 | -| GPS | UBlox M10 | -| Приймач радіокерування | 915мгц ELRS | -| Модуль живлення | Модуль живлення ModalAI v3 - 5V/6A | -| Батарея | Sony VTC6 3000mah 2S, або будь-яка 2S 18650 батарея з роз'ємом XT30 | -| Висота | 83мм | -| Ширина | 187мм (пропелери складені) | -| Довжина | 142мм (пропелери складені) | - -### Стандартна схема проводки - -![Огляд апаратної частини](../../assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg) - -## Посібники - -### ELRS Set Up - -Прив'язка вашого приймача ELRS (ExpressLRS) до передавача є важливим кроком у підготовці вашого набору розробника автономії PX4 Autonomy Developer Kit від ModalAI на базі VOXL 2 для польоту. -Цей процес забезпечує безпечне та відгукнуто з'єднання між вашим дроном та його системою керування. - -Дотримуйтесь цього керівництва, щоб прив'язати ваш приймач ELRS до вашого передавача. - -#### Налаштування відображення - -1. **Увімкніть приймач**: Як тільки ваш квадрокоптер увімкнено, ви помітите, що синій світлодіод приймача ELRS мигає. - Це свідчить про те, що отримувач увімкнений, але ще не встановив зв'язок з передавачем. - - ![Приймач Starling](../../assets/hardware/complete_vehicles/modalai_starling/starling-photo.png) - -2. **Увійдіть в режим зв'язку**: Для ініціювання зв'язку відкрийте термінал та виконайте команди `adb shell` та `voxl-elrs -bind`. - Ви побачите, що світлодіод приймача перемикається на миготливий в режимі миттєвого реагування, сигналізуючи, що тепер він у режимі зв'язку. - - ![Boot Screenshot](../../assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png) - -#### Налаштування передавача - -1. **Отримайте доступ до меню**: На вашому передавачі радіо Commando 8, включеному в комплект, натисніть ліву кнопку режиму, щоб відкрити систему меню. - - ![Натисніть Меню на ПДУ](../../assets/hardware/complete_vehicles/modalai_starling/radio-1.png) - -2. **Перейдіть до ExpressLRS**: Використовуйте праву кнопку, щоб вибрати перший пункт меню, який повинен бути "ExpressLRS." - -3. **Знайдіть опцію Bind**: Після вибору опції "ExpressLRS" прокрутіть вниз до нижньої частини меню, щоб знайти розділ "Bind". Це можна зробити, натиснувши праву кнопку донизу, поки ви не досягнете опцію "Прив'язка". - - ![Press Binding on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-2.png) - -4. **Ініціювати Прив'язку**: Виберіть "Прив'язати", щоб перевести передавач у режим прив'язки. Ви будете знати, що процес був успішним, коли передавач видасть сигнал, вказуючи на успішне зв'язування. - -#### Завершення процесу зв'язування - -Після того як передавач встановлено в режим зв'язку, приймач ELRS на дроні змінить свій світлодіод з миготливого на постійне світло, що свідчить про успішне підключення між приймачем та передавачем. - -- **Цикл живлення**: Після завершення процесу прив'язки обов'язково вимкніть живлення VOXL 2 перед спробою політів. - Це означає вимкнути VOXL 2, а потім увімкнути його знову. - Цей крок забезпечує, що всі налаштування правильно застосовані і система визнає новостворене з'єднання. - -Тепер ви повинні мати успішно прив'язаний приймач ELRS до вашого передавача, готовий до використання з набором автономії PX4 від ModalAI. -Безпечне підключення є важливим для надійної роботи вашого безпілотника, тому завжди підтверджуйте статус зв'язку перед польотом. - -### Відео - -- [Огляд апаратного забезпечення VOXL 2 Starling](https://youtu.be/M9OiMpbEYOg) -- [Посібник з першого польоту VOXL 2 Starling](https://youtu.be/Cpbbye3Z6co) -- [VOXL 2 Starling Налаштування ELRS](https://youtu.be/7OwGS-kcFVg) +[ModalAI Starling 2 Max](https://www.modalai.com/products/starling-2-max) diff --git a/docs/uk/complete_vehicles_mc/px4_vision_kit.md b/docs/uk/complete_vehicles_mc/px4_vision_kit.md index 23e34ce1b9..45f56e1c9d 100644 --- a/docs/uk/complete_vehicles_mc/px4_vision_kit.md +++ b/docs/uk/complete_vehicles_mc/px4_vision_kit.md @@ -42,17 +42,17 @@ This kit is still highly recommended for developing and testing vision solutions ## Попередження та сповіщення 1. Комплект призначений для проєктів комп'ютерного зору, які використовують камеру, спрямовану вперед (він не має камер глибини, спрямованих вниз або назад). - Consequently it can't be used (without modification) for testing features that require a downward-facing camera. + Consequently it can't be used (without modification) for testing features that require a downward-facing camera. 2. Уникання перешкод у місіях можна тестувати лише за наявності сигналу GPS (місії використовують GPS-координати). - Запобігання зіткненням можна перевірити в режимі позиціювання за умови, що є стійке захоплення позиції, отримане або з GPS, або з оптичного потоку. + Запобігання зіткненням можна перевірити в режимі позиціювання за умови, що є стійке захоплення позиції, отримане або з GPS, або з оптичного потоку. 3. Порт, позначений `USB1`, може глушити GPS, якщо його використовувати з периферійним пристроєм _USB3_ (вимкніть GPS-залежні функції, зокрема місії). - Саме тому образ завантаження постачається на флешці _USB2.0_. + Саме тому образ завантаження постачається на флешці _USB2.0_. 4. PX4 Vision v1 з ECN 010 або вище (несуча плата RC05 і вище), _UP Core_ може живитися як від розетки постійного струму, так і від акумулятора. - ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) + ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) 5. Всі PX4 Vision v1.5 _UP Core_ можна живити як від мережі постійного струму, так і від батареї. @@ -132,37 +132,37 @@ PX4 Vision DevKit містить наступні компоненти: ## Перший запуск 1. Підключіть [сумісний RC приймач](../getting_started/rc_transmitter_receiver.md#connecting-receivers) до транспортного засобу (не постачається в комплекті): - - Видаліть/відкрутіть верхню пластину (де йде батарея) за допомогою інструменту з головками шестигранника H2.0. - - [Підключіть приймач до контролера польоту](../assembly/quick_start_pixhawk4.md#radio-control). - - Прикріпіть знову верхню пластину. - - Встановіть RC-приймач на плату кар'єра _UP Core_ на задній частині транспортного засобу (використовуйте зажими або двосторонній скотч). - - Переконайтеся, що антени вільні від будь-яких перешкод і електрично ізольовані від рами (наприклад, закріпіть їх під платою або до рук або ніг транспортного засобу). + - Видаліть/відкрутіть верхню пластину (де йде батарея) за допомогою інструменту з головками шестигранника H2.0. + - [Підключіть приймач до контролера польоту](../assembly/quick_start_pixhawk4.md#radio-control). + - Прикріпіть знову верхню пластину. + - Встановіть RC-приймач на плату кар'єра _UP Core_ на задній частині транспортного засобу (використовуйте зажими або двосторонній скотч). + - Переконайтеся, що антени вільні від будь-яких перешкод і електрично ізольовані від рами (наприклад, закріпіть їх під платою або до рук або ніг транспортного засобу). 2. [Прив'яжіть](../getting_started/rc_transmitter_receiver.md#binding) земельні та повітряні блоки керування RC (якщо ще не зроблено). - Процедура прив'язки залежить від конкретної радіосистеми, яку використовують (прочитайте посібник користувача приймача). + Процедура прив'язки залежить від конкретної радіосистеми, яку використовують (прочитайте посібник користувача приймача). 3. Підніміть стійку GPS до вертикального положення та вкрутіть кришку на тримач на базовій пластині. (Не потрібно для v1.5) - ![Підніміть мачту GPS](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) + ![Підніміть мачту GPS](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) 4. Уставте попередньо зображену USB2.0-ручку зі набору в порт _UP Core_, позначений як `USB1` (виділено нижче). - ![UP Core: Порт USB1 ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) + ![UP Core: Порт USB1 ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) 5. Запустіть транспортний засіб з повністю зарядженою батареєю. - :::info - Переконайтеся, що гвинти від'єднані перед підключенням батареї. + :::info + Переконайтеся, що гвинти від'єднані перед підключенням батареї. ::: 6. Підключіть земельну станцію до мережі WiFi транспортного засобу (через кілька секунд) за допомогою наступних типових облікових даних: - - **SSID:** pixhawk4 - - **Пароль:** px4vision + - **SSID:** pixhawk4 + - **Пароль:** px4vision - :::tip - Ім'я мережі WiFi, пароль та інші облікові дані можуть бути змінені після підключення (за бажанням), використовуючи веб-переглядач для відкриття URL-адреси: `http://192.168.4.1`. - Швидкість передачі даних (baud rate) не повинна змінюватися з 921600. + :::tip + Ім'я мережі WiFi, пароль та інші облікові дані можуть бути змінені після підключення (за бажанням), використовуючи веб-переглядач для відкриття URL-адреси: `http://192.168.4.1`. + Швидкість передачі даних (baud rate) не повинна змінюватися з 921600. ::: @@ -170,39 +170,39 @@ PX4 Vision DevKit містить наступні компоненти: 8. [Налаштувати/калібрувати](../config/index.md) транспортний засіб: - :::info - Транспортний засіб повинен прибути попередньо каліброваним (наприклад, з вбудованим програмним забезпеченням, конструкцією корпусу, батареєю та датчиками, всі встановлені). - Проте вам все одно потрібно калібрувати радіосистему (яку ви щойно підключили), і часто варто повторно виконати калібрування компаса. + :::info + Транспортний засіб повинен прибути попередньо каліброваним (наприклад, з вбудованим програмним забезпеченням, конструкцією корпусу, батареєю та датчиками, всі встановлені). + Проте вам все одно потрібно калібрувати радіосистему (яку ви щойно підключили), і часто варто повторно виконати калібрування компаса. ::: - - [Калібрування Радісистеми](../config/radio.md) - - [Калібрувати Компас](../config/compass.md) + - [Калібрування Радісистеми](../config/radio.md) + - [Калібрувати Компас](../config/compass.md) 9. (Опціонально) Налаштуйте перемикач режиму польоту на пульті дистанційного керування, скориставшись [вибором режиму польоту](../config/flight_mode.md). - :::info - Режими також можна змінити за допомогою _QGroundControl_ + :::info + Режими також можна змінити за допомогою _QGroundControl_ ::: - Ми рекомендуємо визначити RC контролери для перемикачів: + Ми рекомендуємо визначити RC контролери для перемикачів: - - [Режим позиції](../flight_modes_mc/position.md) - безпечний ручний режим польоту, який можна використовувати для тестування запобігання зіткнень. - - [Режим місії](../flight_modes_mc/mission.md) - виконуйте місії та тестуйте уникання перешкод. - - [Режим повернення](../flight_modes_mc/return.md) - повернення транспортного засобу безпечно до точки запуску та посадка. + - [Режим позиції](../flight_modes_mc/position.md) - безпечний ручний режим польоту, який можна використовувати для тестування запобігання зіткнень. + - [Режим місії](../flight_modes_mc/mission.md) - виконуйте місії та тестуйте уникання перешкод. + - [Режим повернення](../flight_modes_mc/return.md) - повернення транспортного засобу безпечно до точки запуску та посадка. 10. Прикріпіть гвинти з обертанням, як показано: - ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) + ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) - - Напрямки гвинтів можна визначити за мітками: _6045_ (звичайний, проти годинникової стрілки) та _6045_**R** (обернений, за годинниковою стрілкою). + - Напрямки гвинтів можна визначити за мітками: _6045_ (звичайний, проти годинникової стрілки) та _6045_**R** (обернений, за годинниковою стрілкою). - ![Ідентифікація гвинта](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) + ![Ідентифікація гвинта](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) - - Закрутіть тісно за допомогою наданих гайок пропелера: + - Закрутіть тісно за допомогою наданих гайок пропелера: - ![Гайки гвинтів](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) + ![Гайки гвинтів](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) ## Політ дроном з униканням @@ -212,30 +212,30 @@ PX4 Vision DevKit містить наступні компоненти: 2. Зачекайте, доки завершиться послідовність завантаження та система уникання розпочне роботу (транспортний засіб відхилить команди на озброєння під час завантаження). - :::tip - Процес завантаження/початку роботи триває близько 1 хвилини з постачаної USB-флешки (або 30 секунд з [внутрішньої пам'яті](#install_image_mission_computer)). + :::tip + Процес завантаження/початку роботи триває близько 1 хвилини з постачаної USB-флешки (або 30 секунд з [внутрішньої пам'яті](#install_image_mission_computer)). ::: 3. Перевірте, що система уникання почала працювати належним чином: - - Журнал сповіщень _QGroundControl_ відображає повідомлення: **Підключена система уникнення**. + - Журнал сповіщень _QGroundControl_ відображає повідомлення: **Підключена система уникнення**. - ![QGC Журнал показує, що система уникання почалася](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) + ![QGC Журнал показує, що система уникання почалася](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) - - Червоний лазер видно на передній частині камери _Structure Core_. + - Червоний лазер видно на передній частині камери _Structure Core_. 4. Зачекайте, доки світлодіод GPS не засвітиться зеленим кольором. - Це означає, що у транспортного засобу є GPS фіксація і він готовий до польоту! + Це означає, що у транспортного засобу є GPS фіксація і він готовий до польоту! 5. Підключіть наземну станцію до мережі WiFi транспортного засобу. 6. Знайдіть безпечне зовнішнє місце для польоту, ідеально з деревом або якою-небудь іншою зручною перешкодою для тестування PX4 Vision. 7. Для тестування [попередження про зіткнення](../computer_vision/collision_prevention.md), увімкніть [Режим Позиції](../flight_modes_mc/position.md) та літайте вручну до перешкоди. - Транспортний засіб повинен сповільнити і зупинитися протягом 6м від перешкоди (відстань може бути [змінена](../advanced_config/parameters.md) за допомогою параметра [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST)). + Транспортний засіб повинен сповільнити і зупинитися протягом 6м від перешкоди (відстань може бути [змінена](../advanced_config/parameters.md) за допомогою параметра [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST)). 8. To test obstacle avoidance, create a mission where the path is blocked by an obstacle. - Потім перейдіть до [Режиму Місії](../flight_modes_mc/mission.md), щоб запустити місію, і спостерігайте, як транспортний засіб рухається навколо перешкоди, а потім повертається на запланований курс. + Потім перейдіть до [Режиму Місії](../flight_modes_mc/mission.md), щоб запустити місію, і спостерігайте, як транспортний засіб рухається навколо перешкоди, а потім повертається на запланований курс. ## Розробка за допомогою комплекту @@ -280,22 +280,22 @@ PX4 та супутниковий комп'ютер обмінюються да 2. [Увійдіть в супровідний комп'ютер](#login_mission_computer) (як описано вище). 3. Відкрийте термінал та виконайте наступну команду, щоб скопіювати зображення на внутрішню пам'ять (eMMC). - Термінал буде пропонувати ввести кількість відповідей під час процесу прошивки. + Термінал буде пропонувати ввести кількість відповідей під час процесу прошивки. - ```sh - cd ~/catkin_ws/src/px4vision_ros/tools - sudo ./flash_emmc.sh - ``` + ```sh + cd ~/catkin_ws/src/px4vision_ros/tools + sudo ./flash_emmc.sh + ``` - :::info - Всю інформацію, збережену в комп'ютері _UP Core_, буде видалено при виконанні цього сценарію. + :::info + Всю інформацію, збережену в комп'ютері _UP Core_, буде видалено при виконанні цього сценарію. ::: 4. Витягніть USB-флешку. 5. Перезавантажте пристрій. - Тепер ком'ютер _UP Core_ буде завантажений з внутрішньої пам'яті (eMMC). + Тепер ком'ютер _UP Core_ буде завантажений з внутрішньої пам'яті (eMMC). ### Запустіть супутній комп'ютер @@ -319,23 +319,23 @@ PX4 та супутниковий комп'ютер обмінюються да 1. Підключіть клавіатуру та мишу до _UP Core_ через порт `USB2`: - ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) + ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) - - Використовуйте кабель USB-JST з комплекту, щоб отримати роз'єм USB A + - Використовуйте кабель USB-JST з комплекту, щоб отримати роз'єм USB A - ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) + ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) - - До кабелю можна підключити USB хаб, якщо клавіатура та миша мають окремі роз'єми. + - До кабелю можна підключити USB хаб, якщо клавіатура та миша мають окремі роз'єми. 2. Підключіть монітор до порту HDMI _UP Core_. - ![UP Core: Порт HDMI](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) + ![UP Core: Порт HDMI](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) - Екран входу в Ubuntu повинен з'явитися на моніторі. + Екран входу в Ubuntu повинен з'явитися на моніторі. 3. Увійдіть в _UP Core_ за допомогою облікових даних: - - **Username:** px4vision - - **Password:** px4vision + - **Username:** px4vision + - **Password:** px4vision ### Розробка / Розширення уникнення PX4 @@ -350,39 +350,39 @@ PX4 та супутниковий комп'ютер обмінюються да 1. Вимкніть процес уникання за допомогою наступної команди: - ```sh - systemctl stop avoidance.service - ``` + ```sh + systemctl stop avoidance.service + ``` - Ви можете просто перезавантажити машину, щоб перезапустити службу. + Ви можете просто перезавантажити машину, щоб перезапустити службу. - Інші корисні команди підтримуються: + Інші корисні команди підтримуються: - ```sh - # restart service - systemctl start avoidance.service + ```sh + # restart service + systemctl start avoidance.service - # disable service (stop service and do not restart after boot) - systemctl disable avoidance.service + # disable service (stop service and do not restart after boot) + systemctl disable avoidance.service - # enable service (start service and enable restart after boot) - systemctl enable avoidance.service - ``` + # enable service (start service and enable restart after boot) + systemctl enable avoidance.service + ``` 2. Вихідний код пакету уникання перешкод можна знайти за адресою https://github.com/PX4/PX4-Avoidance, який розташований в `~/catkin_ws/src/avoidance`. 3. Внесіть зміни до коду! Щоб отримати останній код уникання, витягніть код з репозиторію уникання: - ```sh - git pull origin - git checkout origin/master - ``` + ```sh + git pull origin + git checkout origin/master + ``` 4. Побудуйте пакет - ```sh - catkin build local_planner - ``` + ```sh + catkin build local_planner + ``` Робоче середовище ROS розміщене в `~/catkin_ws`. For reference on developing in ROS and using the catkin workspace, see the [ROS catkin tutorials](https://wiki.ros.org/catkin/Tutorials). diff --git a/docs/uk/complete_vehicles_rover/aion_r1.md b/docs/uk/complete_vehicles_rover/aion_r1.md index 45072c8fb8..1eac40e8fe 100644 --- a/docs/uk/complete_vehicles_rover/aion_r1.md +++ b/docs/uk/complete_vehicles_rover/aion_r1.md @@ -54,15 +54,15 @@ RoboClaw повинен бути підключений до відповідн Спочатку налаштуйте послідовне з'єднання: 1. Перейдіть до розділу [Параметри](../advanced_config/parameters.md) в QGroundControl. - - Встановіть параметр [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) на послідовний порт, до якого підключений RoboClaw (наприклад, `GPS2`). - - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) визначає кількість лічильників енкодера, необхідних для одного оберту колеса. - Це значення повинно бути залишено на `1200` для протестованого `Контролера руху RoboClaw 2x15A`. - Відрегулюйте значення на основі вашого конкретного енкодера та налаштувань колеса. - - Контролери моторів RoboClaw повинні мати унікальну адресу на шині. - Стандартна адреса - 128, і вам не потрібно її змінювати (якщо ви це робите, оновіть параметр PX4 [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) відповідно). + - Встановіть параметр [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) на послідовний порт, до якого підключений RoboClaw (наприклад, `GPS2`). + - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) визначає кількість лічильників енкодера, необхідних для одного оберту колеса. + Це значення повинно бути залишено на `1200` для протестованого `Контролера руху RoboClaw 2x15A`. + Відрегулюйте значення на основі вашого конкретного енкодера та налаштувань колеса. + - Контролери моторів RoboClaw повинні мати унікальну адресу на шині. + Стандартна адреса - 128, і вам не потрібно її змінювати (якщо ви це робите, оновіть параметр PX4 [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) відповідно). - :::info - PX4 не підтримує кілька контролерів моторів RoboClaw у тому ж транспортному засобі — кожен контролер повинен мати унікальну адресу на шині, і є лише один параметр для встановлення адреси в PX4 (`RBCLW_ADDRESS`). + :::info + PX4 не підтримує кілька контролерів моторів RoboClaw у тому ж транспортному засобі — кожен контролер повинен мати унікальну адресу на шині, і є лише один параметр для встановлення адреси в PX4 (`RBCLW_ADDRESS`). ::: @@ -71,12 +71,12 @@ RoboClaw повинен бути підключений до відповідн 1. Перейдіть до [Конфігурації та тестування приводів](../config/actuators.md) в QGroundControl. 2. Виберіть драйвер RoboClaw зі списку _Виводів приводів_. - Для призначень каналу, роззброю, мінімальних та максимальних значень, будь ласка, звертайтеся до зображення нижче. + Для призначень каналу, роззброю, мінімальних та максимальних значень, будь ласка, звертайтеся до зображення нижче. - ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) + ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) - Для систем з більш ніж двома двигунами можливо призначити одну й ту ж функцію кільком двигунам. - Причина нестандартних значень можна знайти в [Користувацькому посібнику RoboClaw](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) під `Командами сумісності` для `Пакетної послідовної передачі даних`: + Для систем з більш ніж двома двигунами можливо призначити одну й ту ж функцію кільком двигунам. + Причина нестандартних значень можна знайти в [Користувацькому посібнику RoboClaw](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) під `Командами сумісності` для `Пакетної послідовної передачі даних`: ```plain Приводити двигун вперед. Діапазон дійсних даних - від 0 до 127. Значення 127 = повна швидкість вперед, 64 = diff --git a/docs/uk/computer_vision/collision_prevention.md b/docs/uk/computer_vision/collision_prevention.md index 23f70960ff..ba066177f5 100644 --- a/docs/uk/computer_vision/collision_prevention.md +++ b/docs/uk/computer_vision/collision_prevention.md @@ -203,85 +203,85 @@ The Lua script works by extracting the `obstacle_distance_fused` data at each ti 2. Configure PX4 to publish obstacle distance data (so that it is available to PlotJuggler): - Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: + Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: - ```sh - - topic: /fmu/out/obstacle_distance_fused - type: px4_msgs::msg::ObstacleDistance - ``` + ```sh + - topic: /fmu/out/obstacle_distance_fused + type: px4_msgs::msg::ObstacleDistance + ``` - For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. + For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. 3. Open PlotJuggler and navigate to the **Tools > Reactive Script Editor** section. - In the **Script Editor** tab, add following scripts in the appropriate sections: + In the **Script Editor** tab, add following scripts in the appropriate sections: - - **Global code, executed once:** + - **Global code, executed once:** - ```lua - obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") - obs_dist_min = Timeseries.new("obstacle_distance_minimum") - ``` + ```lua + obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") + obs_dist_min = Timeseries.new("obstacle_distance_minimum") + ``` - - **function(tracker_time)** + - **function(tracker_time)** - ```lua - obs_dist_fused_xy:clear() + ```lua + obs_dist_fused_xy:clear() - i = 0 - angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") - increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") - min_dist = 65535 + i = 0 + angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") + increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") + min_dist = 65535 - -- Cache increment and angle_offset values at tracker_time to avoid repeated calls - local angle_offset_value = angle_offset:atTime(tracker_time) - local increment_value = increment:atTime(tracker_time) + -- Cache increment and angle_offset values at tracker_time to avoid repeated calls + local angle_offset_value = angle_offset:atTime(tracker_time) + local increment_value = increment:atTime(tracker_time) - if increment_value == nil or increment_value <= 0 then - print("Invalid increment value: " .. tostring(increment_value)) - return - end + if increment_value == nil or increment_value <= 0 then + print("Invalid increment value: " .. tostring(increment_value)) + return + end - local max_steps = math.floor(360 / increment_value) + local max_steps = math.floor(360 / increment_value) - while i < max_steps do - local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) - local distance = TimeseriesView.find(str) - if distance == nil then - print("No distance data for: " .. str) - break - end + while i < max_steps do + local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) + local distance = TimeseriesView.find(str) + if distance == nil then + print("No distance data for: " .. str) + break + end - local dist = distance:atTime(tracker_time) - if dist ~= nil and dist < 65535 then - -- Calculate angle and Cartesian coordinates - local angle = angle_offset_value + i * increment_value - local y = dist * math.cos(math.rad(angle)) - local x = dist * math.sin(math.rad(angle)) + local dist = distance:atTime(tracker_time) + if dist ~= nil and dist < 65535 then + -- Calculate angle and Cartesian coordinates + local angle = angle_offset_value + i * increment_value + local y = dist * math.cos(math.rad(angle)) + local x = dist * math.sin(math.rad(angle)) - obs_dist_fused_xy:push_back(x, y) + obs_dist_fused_xy:push_back(x, y) - -- Update minimum distance - if dist < min_dist then - min_dist = dist - end - end + -- Update minimum distance + if dist < min_dist then + min_dist = dist + end + end - i = i + 1 - end + i = i + 1 + end - -- Push minimum distance once after the loop - if min_dist < 65535 then - obs_dist_min:push_back(tracker_time, min_dist) - else - print("No valid minimum distance found") - end - ``` + -- Push minimum distance once after the loop + if min_dist < 65535 then + obs_dist_min:push_back(tracker_time, min_dist) + else + print("No valid minimum distance found") + end + ``` 4. Enter a name for the script on the top right, and press **Save**. - Once saved, the script should appear in the _Active Scripts_ section. + Once saved, the script should appear in the _Active Scripts_ section. 5. Start streaming the data using the approach described in [Plotting uORB Topic Data in Real Time using PlotJuggler](../debug/plotting_realtime_uorb_data.md). - You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. + You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. Note that you have to press **Save** again to re-enable the scripts after loading a new log file or otherwise clearing data. diff --git a/docs/uk/computer_vision/visual_inertial_odometry.md b/docs/uk/computer_vision/visual_inertial_odometry.md index ba9156ba23..d2c2dfb0c5 100644 --- a/docs/uk/computer_vision/visual_inertial_odometry.md +++ b/docs/uk/computer_vision/visual_inertial_odometry.md @@ -125,15 +125,15 @@ For more detailed/additional information, see: [Using PX4's Navigation Filter (E Якщо ці кроки є послідовними, ви можете спробувати свій перший польот: 1. Покладіть літак на землю і почніть передавати зворотний зв'язок `ODOMETRY` (як вище). - Потягніть палицю газу вниз і зберметизуйте двигуни. + Потягніть палицю газу вниз і зберметизуйте двигуни. - На цьому етапі, зліва палиця на найнижчому положенні, перейдіть у режим позиціонного контролю. - Ви повинні побачити зелену лампочку. - Зелена лампочка свідчить про те, що доступний зворотний зв'язок позиції, і позиційний контроль активований. + На цьому етапі, зліва палиця на найнижчому положенні, перейдіть у режим позиціонного контролю. + Ви повинні побачити зелену лампочку. + Зелена лампочка свідчить про те, що доступний зворотний зв'язок позиції, і позиційний контроль активований. 2. Покладіть палицю газу в середину (мертву зону), щоб літак підтримував свою висоту. - Підняття палиці збільшить висоту посилки, тоді як зниження значення зменшить її. - Так само, інша палиця змінить положення над землею. + Підняття палиці збільшить висоту посилки, тоді як зниження значення зменшить її. + Так само, інша палиця змінить положення над землею. 3. Збільшуйте значення перемикача газу, і літак злетить. Відразу після цього поверніть його в середину. diff --git a/docs/uk/concept/flight_tasks.md b/docs/uk/concept/flight_tasks.md index 1752a20812..4753edcdd0 100644 --- a/docs/uk/concept/flight_tasks.md +++ b/docs/uk/concept/flight_tasks.md @@ -38,24 +38,24 @@ _Польотні завдання_ використовуються у [Реж - Оновіть відмітку про авторське право до поточного року - ```cmake - ############################################################################ - # - # Copyright (c) 2021 PX4 Development Team. All rights reserved. - # - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2021 PX4 Development Team. All rights reserved. + # + ``` - Модифікуйте код щоб він відповідав новому завданню, наприклад замініть `FlightTaskOrbit` на `FlightTaskMyTask`. - Код буде виглядати приблизно так: + Код буде виглядати приблизно так: - ```cmake - px4_add_library(FlightTaskMyTask - FlightTaskMyTask.cpp - ) + ```cmake + px4_add_library(FlightTaskMyTask + FlightTaskMyTask.cpp + ) - target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) - target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - ``` + target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) + target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + ``` 4. Оновіть файл заголовків (у цьому випадку **FlightTaskMyTask. pp**): Більшість завдань повторно реалізує віртуальні методи `activate()` і `update()`, в цьому прикладі ми також маємо приватну змінну. @@ -140,35 +140,35 @@ _Польотні завдання_ використовуються у [Реж - Оновіть `MPC_POS_MODE` ([multicopter_position_mode_params.](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_pos_control/multicopter_position_mode_params.c)), щоб додати варіант для вибору "MyTask", якщо параметр має раніше невикористане значення, наприклад 5: - ```c - ... - * @value 0 Direct velocity - * @value 3 Smoothed velocity - * @value 4 Acceleration based - * @value 5 My task - * @group Multicopter Position Control - */ - PARAM_DEFINE_INT32(MPC_POS_MODE, 5); - ``` + ```c + ... + * @value 0 Direct velocity + * @value 3 Smoothed velocity + * @value 4 Acceleration based + * @value 5 My task + * @group Multicopter Position Control + */ + PARAM_DEFINE_INT32(MPC_POS_MODE, 5); + ``` - Додайте мітку case для нового варіанту в операторі switch для параметра в [FlightModeManager.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/flight_mode_manager/FlightModeManager.cpp#L266-L285), щоб увімкнути завдання коли `_param_mpc_pos_mode` має відповідне значення. - ```cpp - ... - // manual position control - ... - switch (_param_mpc_pos_mode.get()) { - ... - case 3: - error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); - break; - case 5: // Add case for new task: MyTask - error = switchTask(FlightTaskIndex::MyTask); - break; - case 4: - .... - ... - ``` + ```cpp + ... + // manual position control + ... + switch (_param_mpc_pos_mode.get()) { + ... + case 3: + error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); + break; + case 5: // Add case for new task: MyTask + error = switchTask(FlightTaskIndex::MyTask); + break; + case 4: + .... + ... + ``` ## Перевірка нового польотного завдання diff --git a/docs/uk/concept/system_startup.md b/docs/uk/concept/system_startup.md index b4f0ae06ec..f94b70aa7c 100644 --- a/docs/uk/concept/system_startup.md +++ b/docs/uk/concept/system_startup.md @@ -1,7 +1,7 @@ # Запуск системи Запуск PX4 контрольований скриптами оболонки. -На NuttX вони знаходяться у директорії [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d), деякі з них також використовуються на Posix системах (Linux/MacOS). +On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/macOS). Скрипти які використовуються тільки на Posix системах знаходяться у [ROMFS/px4fmu_common/init.d-posix](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d-posix). Усі файли, які починаються з числа і підкреслення (наприклад, `10000_airaipl`) є попередньо визначеними конфігураціями планерів. @@ -13,9 +13,9 @@ They are exported at build-time into an `airframes.xml` file which is parsed by Наступні секції розділені відповідно до операційної системи, на яких виконується PX4. -## Posix (Linux/MacOS) +## POSIX (Linux/macOS) -На Posix системна оболонка використовується як інтерпретатор скриптів (наприклад, /bin/sh що є символьним посиланням на dash в Ubuntu). +On POSIX, the system shell is used as script interpreter (e.g. /bin/sh, being symlinked to dash on Ubuntu). Щоб це працювало потрібно кілька речей: - Модулі PX4 повинні виглядати для системи як окремі виконувані файли. @@ -59,7 +59,7 @@ cd /build/px4_sitl_default/bin ### Динамічні модулі Зазвичай всі модулі компілюються в єдиний виконуваний файл PX4. -Однак, на Posix системах, є можливість компіляції модуля в окремий файл, який можна завантажити в PX4 використовуючи команду `dyn`. +However, on POSIX, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. ```sh dyn ./test.px4mod @@ -95,6 +95,8 @@ NuttX має інтегрований інтерпретатор оболонк Найкращий спосіб змінити запуск системи - це ввести [нову конфігурацію планера](../dev_airframes/adding_a_new_frame.md). Файл конфігурації планеру може бути включений у прошивку або на SD карту. +#### Dynamic Customization + Якщо вам потрібно "підлаштувати" конфігурацію що існує, наприклад запустити один або більше застосунків або встановити значення кількох параметрів, можна вказати це створивши два файли у директорії `/etc/` на SD картці: - [/etc/config.txt](#customizing-the-configuration-config-txt): modify parameter values @@ -111,7 +113,7 @@ NuttX має інтегрований інтерпретатор оболонк Ці файли згадуються в коді PX4 як `/fs/microsd/etc/config.txt` та `/fs/microsd/etc/extras.txt`, де коренева директорія microSD карти визначається шляхом `/fs/microsd`. ::: -#### Налаштування конфігурації (config.txt) +##### Налаштування конфігурації (config.txt) Файл `config.txt` можна використовувати для зміни параметрів. Він завантажується після того, як головна система була налаштована та _перед тим_ як завантажена. @@ -123,7 +125,7 @@ param set-default PWM_MAIN_DIS3 1000 param set-default PWM_MAIN_MIN3 1120 ``` -#### Запуск додаткових застосунків (extras.txt) +##### Запуск додаткових застосунків (extras.txt) `extras.txt` можна використовувати для запуску додаткових застосунків після завантаження основної системи. Зазвичай це будуть контролери корисного навантаження або подібні необов'язкові користувацькі компоненти. @@ -150,3 +152,37 @@ param set-default PWM_MAIN_MIN3 1120 mandatory_app start # Will abort boot if mandatory_app is unknown or fails ``` + +#### Additional Init-File Customization + +In rare cases where the desired setup cannot be achieved through frame configuration or dynamic customization, you can add a script that will be compiled into the binary for a particular `make` target build variant. + +:::warning +In almost all cases, you should use a frame configuration. +This method should only be used for edge-cases such as customizing `cannode` based boards. +::: + +Кроки наступні: + +- Add a new init script in `boards///init` that will run during board startup. + Наприклад: + + ```sh + # File: boards///init/rc.additional + param set-default + ``` + +- Add a new board variant in `boards///.px4board` that includes the additional script. + Наприклад: + + ```sh + # File: boards///var.px4board + CONFIG_BOARD_ADDITIONAL_INIT="rc.additional" + ``` + +- Compile the firmware with your new variant by appending the variant name to the compile target. + Наприклад: + + ```sh + make _var + ``` diff --git a/docs/uk/config/_autotune.md b/docs/uk/config/_autotune.md index a372307923..a76a63832b 100644 --- a/docs/uk/config/_autotune.md +++ b/docs/uk/config/_autotune.md @@ -43,13 +43,13 @@ The airframe must fly well enough to handle moderate disturbances, and should be 2. Take off and
hover at 1m above ground in [Altitude mode](../flight_modes_mc/altitude.md) or [Stabilized mode](../flight_modes_mc/manual_stabilized.md)
fly at cruise speed in [Position mode](../flight_modes_fw/position.md) or [Altitude mode](../flight_modes_fw/altitude.md)
. 3. Use the RC transmitter roll stick to perform the following maneuver, tilting the vehicle just a few degrees: _roll left > roll right > center_ (The whole maneuver should take about 3 seconds). - Транспортний засіб повинен стабілізуватися протягом 2 коливань. + Транспортний засіб повинен стабілізуватися протягом 2 коливань. 4. Повторіть маневр, нахиляючись з більшими амплітудами при кожної спроби. - Якщо транспортний засіб може стабілізуватися протягом 2 коливань під кутом близько 20 градусів, перейдіть до наступного кроку. + Якщо транспортний засіб може стабілізуватися протягом 2 коливань під кутом близько 20 градусів, перейдіть до наступного кроку. 5. Повторіть ті ж маніпуляції, але по осі поля. - Як вище, почніть з невеликих кутів і підтвердіть, що транспортний засіб може стабілізуватися самостійно протягом 2 коливань, перш ніж збільшувати нахил. + Як вище, почніть з невеликих кутів і підтвердіть, що транспортний засіб може стабілізуватися самостійно протягом 2 коливань, перш ніж збільшувати нахил. If the drone can stabilize itself within 2 oscillations it is ready for the [auto-tuning procedure](#auto-tuning-procedure). @@ -72,41 +72,55 @@ The RC sticks cannot be used during autotuning (moving the sticks will stop the 1. Perform the [pre-tuning test](#pre-tuning-test). 2. Takeoff using RC control
in [Altitude mode](../flight_modes_mc/altitude.md). - Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
- Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). - This will guide the plane to fly in circle at constant altitude and speed.
+ Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
+ Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). + This will guide the plane to fly in circle at constant altitude and speed.
3. Enable autotune. -
-

TIP

+
+

TIP

- If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. + If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. -
+
- 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: + 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: - ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) + ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) - 2. Select either the _Rate Controller_ or _Attitude Controller_ tabs. + 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). + 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. - -4. Дрон спочатку почне виконувати швидкі рухи кочення, а потім рухи тангажу та рухи курсу. - The progress is shown in the progress bar, next to the _Autotune_ button. + 4. Read the warning popup and click on **OK** to start tuning.
+4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. + The progress is shown in the progress bar, next to the _Autotune_ button. + +
+ +4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. When [`FW_AT_SYSID_TYPE`](../advanced_config/parameter_reference.md#FW_AT_SYSID_TYPE) is set to linear/logarithmic sine sweep (recommended), the max rates reached during the maneuvers are 75% of the maximum configured roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. The progress is shown in the progress bar, next to the _Autotune_ button. + +
+
+ 5. Manually land and disarm to apply the new tuning parameters. - Takeoff carefully and manually test that the vehicle is stable. + Takeoff carefully and manually test that the vehicle is stable.
5. The tuning will be immediately/automatically be applied and tested in flight (by default). - PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + +The figure below shows how steps 4 and 5 might look in flight on the pitch axis. +The pitch rate gradually increases up until it reaches the target. +This amplitude is then held while the signal frequency is increased. +You can then see how the tuned system is able to follow the setpoint in the test signal. + +
@@ -174,9 +188,20 @@ Fast oscillations (more than 1 oscillation per second): this is because the gain ### Послідовність автоматичної настройки не вдається +
+ Якщо безпілотник не рухався достатньо під час автоматичного налаштування, алгоритм ідентифікації системи може мати проблеми з визначенням правильних коефіцієнтів. -Increase the
[MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP)
[FW_AT_SYSID_AMP](../advanced_config/parameter_reference.md#FW_AT_SYSID_AMP)
parameter by steps of 1 and trigger the auto-tune again. +Increase the [MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP) parameter by steps of 1 and trigger the auto-tune again. + +
+
+ +By default, the autotune maneuvers ensure that a sufficient angular rate is reached for system identification, corresponding to 75% of the configured maximum roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. + +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. + +
### The drone oscillates after auto-tuning diff --git a/docs/uk/config/actuators.md b/docs/uk/config/actuators.md index c11af3c04d..14f62d4ae3 100644 --- a/docs/uk/config/actuators.md +++ b/docs/uk/config/actuators.md @@ -161,6 +161,7 @@ Select the **Advanced** checkbox in the top right corner of the view to display [Generally you should use the default actuator value](#actuator-roll-pitch-and-yaw-scaling). - `Trim`: An offset added to the actuator so that it is centered without input. Це може бути визначено методом проб і помилок. + Prefer using the improved `PWM_CENT` instead: [PWM control surfaces](actuators.md#pwm-control-surfaces-that-move-both-directions-about-a-neutral-point). - (Advanced) `Slew Rate`: Limits the minimum time in which the motor/servo signal is allowed to pass through its full output range, in seconds. - Параметр обмежує швидкість зміни приводу (якщо не вказано, то обмеження швидкості не застосовується). It is intended for actuators that may be damaged or cause flight disturbance if they move too fast — such as the tilting actuators on a tiltrotor VTOL vehicle, or fast moving flaps, respectively. @@ -448,9 +449,9 @@ QGC потім автоматично обере наступний двигун 4. One motor will start spinning (click **Spin Motor Again** if it stops spinning too quickly to note.) - Виберіть відповідний двигун в розділі геометрії. + Виберіть відповідний двигун в розділі геометрії. - ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) + ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) 5. Після призначення всіх двигунів інструмент встановить правильне відображення двигунів для виходів, а потім вийде. @@ -467,15 +468,15 @@ Actuator outputs for both motors and servos can be _manually_ assigned using sli 1. First assign functions to the outputs that you think are _likely_ to be correct in the _Actuator Outputs_ section. 2. Toggle the **Enable sliders** switch in _Actuator Testing_ section. 3. Перемістіть повзунок для приводу, який ви хочете перевірити: - - Двигуни повинні бути переведені в положення мінімального тяги. - - Сервоприводи повинні бути переміщені близько до середнього положення. + - Двигуни повинні бути переведені в положення мінімального тяги. + - Сервоприводи повинні бути переміщені близько до середнього положення. 4. Перевірте, який привод рухається на транспортному засобі. - This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). - - Якщо правильний привод рухається, перейдіть до наступного кроку. - - Якщо неправильний привод рухається, поміняйте призначення виводу. - - Якщо нічого не рухається, то збільште регулятор наполовину діапазону, потім вище, якщо потрібно. - Якщо після цього нічого не рухається, вихід може бути не підключений, можливо, двигун не живиться або вихід може бути неправильно налаштований. - Вам потрібно буде вирішити проблему (можливо, спробуйте інші виходи виконавчих пристроїв, щоб побачити, чи "щось" рухається). + This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). + - Якщо правильний привод рухається, перейдіть до наступного кроку. + - Якщо неправильний привод рухається, поміняйте призначення виводу. + - Якщо нічого не рухається, то збільште регулятор наполовину діапазону, потім вище, якщо потрібно. + Якщо після цього нічого не рухається, вихід може бути не підключений, можливо, двигун не живиться або вихід може бути неправильно налаштований. + Вам потрібно буде вирішити проблему (можливо, спробуйте інші виходи виконавчих пристроїв, щоб побачити, чи "щось" рухається). 5. Поверніть слайдер у положення "роззброєно" (донизу для двигунів, по центру для сервоприводів). 6. Повторити для всіх приводів @@ -501,32 +502,32 @@ Remove propellers! Для кожного двигуна: 1. Тягніть слайдер мотора вниз, щоб він защелкнувся унизу. - In this position the motor is set to the outputs `disarmed` value. - - Перевірте, що двигун не обертається в цьому положенні. - - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. + In this position the motor is set to the outputs `disarmed` value. + - Перевірте, що двигун не обертається в цьому положенні. + - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. 2. Slowly move the slider up until it snaps to the _minimum_ position. - In this position the motor is set to the outputs `minimum` value. - - Перевірте, чи двигун обертається дуже повільно в цьому положенні. - - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. + In this position the motor is set to the outputs `minimum` value. + - Перевірте, чи двигун обертається дуже повільно в цьому положенні. + - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. - ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) - ::: info - For DShot output, this is not required. + ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) + ::: info + For DShot output, this is not required. ::: 3. Збільште значення слайдера до рівня, на якому ви можете перевірити, що двигун обертається в правильному напрямку і що він надасть позитивний тяговий потік в очікуваному напрямку. - - Очікувана напрямок тяги може відрізнятися в залежності від типу транспортного засобу. - Наприклад, у багатороторних літаках тяга завжди повинна вказувати вгору, тоді як у повітряному судні з фіксованим крилом тяга буде тягти судно вперед. - - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). - Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. - - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). + - Очікувана напрямок тяги може відрізнятися в залежності від типу транспортного засобу. + Наприклад, у багатороторних літаках тяга завжди повинна вказувати вгору, тоді як у повітряному судні з фіксованим крилом тяга буде тягти судно вперед. + - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). + Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. + - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). 4. Збільште значення слайдера до максимального значення, щоб двигун швидко обертався. - Reduce the value of the PWM output's `maximum` value just below the default. - Прослухайте тон моторів, коли ви збільшуєте значення малими (25us) інкрементами. - "Оптимальне" максимальне значення - це значення, при якому ви востаннє почули зміну тона. + Reduce the value of the PWM output's `maximum` value just below the default. + Прослухайте тон моторів, коли ви збільшуєте значення малими (25us) інкрементами. + "Оптимальне" максимальне значення - це значення, при якому ви востаннє почули зміну тона. ### Налаштування поверхонь керування @@ -542,40 +543,76 @@ You will almost certainly need to change the pulse rate from the default of 400H If a high rate servo is _really_ needed, DShot offers better value. ::: -#### Control surfaces that move both directions about a neutral point +##### PWM: Control surfaces that move both directions about a neutral point + +To facilitate setting the neutral point of the servos, a bilinear curve function can be defined using the following parameters `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` for each servo. This allows for unequal deflections in the positive and negative direction: + +![Asymmetric Servo Deflections](../../assets/config/actuators/servo_pwm_center.png) + +To set this up: + +1. Set all surface `Trim` to `0.00` for all surfaces: + + ![PWM Trimming](../../assets/config/actuators/control_surface_trim.png) + +2. Set the `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` value so that the surface will stay at the neutral (aligned with airfoil) position. + This is usually around `1500` for PWM servos (near the center of the servo range). + + ![Control Surface Trimming](../../assets/config/actuators/pwm_center_output.png) + +3. Gradually increase the `Maximum` for each servo until the desired deflection is reached. Check the deflection with a remote manual mode while [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) is set to `Always` or use the sliders. + +4. Gradually decrease the `Minimum` for each servo, until the desired deflection is reached. + +5. Set `Disarmed` value to the desired value. It is usually desirable to have it the same as the `Center` value. + +:::info +If you want to retain the linear behaviour of the servo after setting the `Center`, make sure to adjust the `Minimum` or `Maximum`, such that both intervals (`min` to `cent` & `cent` to `max`) are equally large. + +![Linear PWM Adjustment](../../assets/config/actuators/servo_pwm_linear.png) +::: + +#### Non-PWM: Control surfaces that move both directions about a neutral point Control surfaces that move either direction around a neutral point include: ailerons, elevons, V-tails, A-tails, and rudders. To set these up: -1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. - This is usually around `1500` for PWM servos (near the centre of the servo range). +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. - ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) +1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. + This is usually around `1500` for PWM servos (near the centre of the servo range). + + ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) 2. Move the slider for the surface upwards (positive command) and verify that it moves in the direction defined in the [Control Surface Convention](#control-surface-deflection-convention). - - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. - - Rudders and other "purely vertical" surfaces should move right. + - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. + - Rudders and other "purely vertical" surfaces should move right. - ::: tip - It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). + ::: tip + It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). ::: - If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. + If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. 3. Move the slider again to the middle and check if the Control Surfaces are aligned in the neutral position of the wing. - - If it is not aligned, you can set the **Trim** value for the control surface. - ::: info - This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". - ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) + - If it is not aligned, you can set the **Trim** value for the control surface. + + ::: info + This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". + ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) ::: - - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. - Підтвердіть, що поверхня знаходиться в нейтральному положенні. + - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. + Підтвердіть, що поверхня знаходиться в нейтральному положенні. + +:::tip +If any servo has a `PWM_MAIN_CENTx` or `PWM_AUX_CENTx` not set to default (-1), the system will automatically remove `Trim` from all surfaces. This is done to prevent mixing of old and new trimming tools. +::: :::info Another way to test without using the sliders would be to set the [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) parameter to `Always`: @@ -595,15 +632,17 @@ For a flap, that is when the flap is fully retracted and flush with the wing. One approach for setting these up is: +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. 1. Set values `Disarmed` to `1500`, `Min` to `1200`, `Max` to `1700` so that the values are around the centre of the servo range. 2. Move the corresponding slider up and check the control moves and that it is extending (moving away from the disarmed position). - If not, click on the `Rev Range` checkbox to reverse the range. + If not, click on the `Rev Range` checkbox to reverse the range. 3. Enable slider in the disarmed position, them change the value of the `Disarmed` signal until the control is retracted/flush with wing. - This may require that the `Disarmed` value is increased or decreased: - - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. - - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. + This may require that the `Disarmed` value is increased or decreased: + - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. + - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. 4. The value that you did _not_ set to match `Disarmed` controls the maximum amount that the control surface can extend. - Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. + Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. +5. (Only PWM servos) Set the `Center` value to the middle between `Min` and `Max`. :::info Special note for flaps In some vehicle builds, flaps may be configured such that both flaps are controlled from a single output. @@ -627,7 +666,7 @@ First set the _frame rate_ for the servos used in each group of outputs. 2. Position the slider for the servo in the lowest position, and verify that a positive value increase will point towards the `Angle at Min Tilt` (defined in the Geometry section). - ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) + ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) 3. Position the slider for the servo in the highest position, and verify that positive motor thrust will point towards the `Angle at Max Tilt` (as defined in the Geometry section). @@ -642,6 +681,11 @@ First set the _frame rate_ for the servos used in each group of outputs. - Стандартний VTOL: Двигуни, визначені як багатокоптерні двигуни, будуть вимкнені - Tiltrotors : Двигуни, які не мають пов'язаного сервоприводу нахилу, вимкнуться - Tailsitters не вимикають жодних двигунів у польоті з фіксованим крилом +- The following formula can be used to migrate from surface trim to PWM trim: + + ```plain + PWM_MAIN_CENTx = ((PWM_MAX - PWM_MIN) / 2) * CA_SV_CSx_TRIM + PWM_MIN + ((PWM_MAX - PWM_MIN) / 2) + ``` ### Реверсивні мотори diff --git a/docs/uk/config/airspeed.md b/docs/uk/config/airspeed.md index 270887595f..cca0eff115 100644 --- a/docs/uk/config/airspeed.md +++ b/docs/uk/config/airspeed.md @@ -27,18 +27,18 @@ Before calibration they must be [enabled via the corresponding parameter](../adv 4. Click the **Airspeed** sensor button. - ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) + ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) 5. Захистіть сенсор від вітру (тобто закрийте його рукою). - Пильнуйте, щоб не заблокувати жодного з отворів. + Пильнуйте, щоб не заблокувати жодного з отворів. 6. Click **OK** to start the calibration. 7. Після запиту, дмухніть у кінець труби пітота, щоб сигналізувати про завершення калібрування. - :::tip - Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. - Якщо вони будуть поміняні місцями, то датчик буде відображати великий від'ємний перепад тиску, коли ви дмухаєте в трубку, і калібрування завершиться з помилкою. + :::tip + Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. + Якщо вони будуть поміняні місцями, то датчик буде відображати великий від'ємний перепад тиску, коли ви дмухаєте в трубку, і калібрування завершиться з помилкою. ::: diff --git a/docs/uk/config/compass.md b/docs/uk/config/compass.md index 081febdeba..f17ff9b258 100644 --- a/docs/uk/config/compass.md +++ b/docs/uk/config/compass.md @@ -10,7 +10,7 @@ If you have [mounted the compass](../assembly/mount_gps_compass.md#compass-orien ## Загальний огляд -You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to recalibrate it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. +You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to [recalibrate](#recalibration) it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. :::tip Indications of a poor compass calibration include multicopter circling during hover, toilet bowling (circling at increasing radius/spiraling-out, usually constant altitude, leading to fly-way), or veering off-path when attempting to fly straight. @@ -20,13 +20,16 @@ _QGroundControl_ should also notify the error `mag sensors inconsistent`. The process calibrates all compasses and autodetects the orientation of any external compasses. If any external magnetometers are available, it then disables the internal magnetometers (these are primarily needed for automatic rotation detection of external magnetometers). +### Types of Calibration + Several types of compass calibration are available: 1. [Complete](#complete-calibration): This calibration is required after installing the autopilot on an airframe for the first time or when the configuration of the vehicle has changed significantly. - Воно компенсує впливи твердого та м'якого заліза, оцінюючи зміщення та коефіцієнт масштабу для кожної вісі. + Воно компенсує впливи твердого та м'якого заліза, оцінюючи зміщення та коефіцієнт масштабу для кожної вісі. 2. [Partial](#partial-quick-calibration): This calibration can be performed as a routine when preparing the vehicle for a flight, after changing the payload, or simply when the compass rose seems inaccurate. - Цей тип калібрування лише оцінює зміщення для компенсації ефекту твердого заліза. -3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. Цей тип калібрування лише оцінює зміщення для компенсації ефекту твердого заліза. + Цей тип калібрування лише оцінює зміщення для компенсації ефекту твердого заліза. +3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. + Цей тип калібрування лише оцінює зміщення для компенсації ефекту твердого заліза. ## Виконання калібрування @@ -35,13 +38,13 @@ Several types of compass calibration are available: Перед початком калібрування: 1. Виберіть місце подалеку від великих металевих об'єктів або магнітних полів. - :::tip - Metal is not always obvious! Уникайте калібрування на верхній частині офісного столу (часто містять металеві пластины) або поруч з транспортним засобом. - Калібрування може бути навіть уражено, якщо ви стоїте на бетонній плиті з нерівномірним розподілом арматури. + :::tip + Metal is not always obvious! Уникайте калібрування на верхній частині офісного столу (часто містять металеві пластины) або поруч з транспортним засобом. + Калібрування може бути навіть уражено, якщо ви стоїте на бетонній плиті з нерівномірним розподілом арматури. ::: 2. Підключайтесь за допомогою телеметричного радіо, а не через USB, якщо це взагалі можливо. - USB потенційно може викликати значне магнітне втручання. + USB потенційно може викликати значне магнітне втручання. 3. If using an external compass (or a combined GPS/compass module), make sure it is [mounted](../assembly/mount_gps_compass.md) as far as possible from other electronics in order to reduce magnetic interference, and in a _supported orientation_. ### Повне калібрування @@ -54,29 +57,33 @@ Several types of compass calibration are available: 3. Click the **Compass** sensor button. - ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) + ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) - ::: info - You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). Якщо ні, ви також можете встановити це тут. + ::: info + You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). + Якщо ні, ви також можете встановити це тут. ::: 4. Click **OK** to start the calibration. -5. Розмістіть транспортний засіб у будь-якому з показаних червоних орієнтацій (неповний) та утримуйте його нерухомим. Після запиту (орієнтаційне зображення стає жовтим) обертайте транспортний засіб навколо вказаної вісі в одному або обох напрямках. Після завершення калібрування для поточного орієнтації пов'язане зображення на екрані стане зеленим. +5. Розмістіть транспортний засіб у будь-якому з показаних червоних орієнтацій (неповний) та утримуйте його нерухомим. + Після запиту (орієнтаційне зображення стає жовтим) обертайте транспортний засіб навколо вказаної вісі в одному або обох напрямках. + Після завершення калібрування для поточного орієнтації пов'язане зображення на екрані стане зеленим. - ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) + ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) 6. Повторіть процес калібрування для всіх орієнтацій автомобіля. -Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). Ви можете потім перейти до наступного сенсора. +Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). +Ви можете потім перейти до наступного сенсора. ### Часткова "Швидка" Калібрування Ця калібровка схожа на відому калібровку компасу у вигляді восьмірки, виконану на смартфоні: 1. Утримуйте транспортний засіб перед собою та випадковим чином виконуйте часткові обертання по всіх його осях. - 2-3 коливань на кут близько 30 градусів у кожному напрямку зазвичай достатньо. + 2-3 коливань на кут близько 30 градусів у кожному напрямку зазвичай достатньо. 2. Зачекайте, поки оцінка заголовку стабілізується, і перевірте, що компас вказує в правильному напрямку (це може зайняти кілька секунд). Примітки: @@ -92,14 +99,15 @@ Once you've calibrated the vehicle in all the positions _QGroundControl_ will di This calibration process leverages external knowledge of vehicle's orientation and location, and a World Magnetic Model (WMM) to calibrate the hard iron biases. -1. Ensure GNSS Fix. This is required to find the expected Earth magnetic field in WMM tables. +1. Ensure GNSS Fix. + This is required to find the expected Earth magnetic field in WMM tables. 2. Align the vehicle to face True North. - Be as accurate as possible for best results. + Be as accurate as possible for best results. 3. Open the [QGroundControl MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) and send the following command: - ```sh - commander calibrate mag quick - ``` + ```sh + commander calibrate mag quick + ``` Примітки: @@ -112,6 +120,30 @@ This calibration process leverages external knowledge of vehicle's orientation a Після завершення калібрування перевірте, щоб індикатор напрямку та напрямок стрілки на карті були стабільними і відповідали орієнтації транспортного засобу при його повороті, наприклад, на головні сторони. +## Recalibration + +Recalibration is recommended whenever the magnetic environment of the vehicle has changed or when heading behavior appears unreliable. + +You can use either complete calibration or mag quick calibration depending on the size of the vehicle and your ability to rotate it through the required orientations. +Complete calibration provides the most accurate soft-iron compensation. + +Recalibrate the compass when: + +- _The compass module or its mounting orientation has changed._ + This includes replacing the GPS or mag unit, rotating the mast, or altering how the module is fixed to the airframe. +- _The vehicle has been exposed to a strong magnetic disturbance._ + Examples include transport or storage near large steel structures, welding operations near the airframe, or operation close to high-current equipment. +- _Structural, wiring, or payload changes may have altered the magnetic field around the sensors._ + New payloads, rerouted wires, additional batteries, or metal fasteners can introduce soft-iron effects that affect heading accuracy. +- _The vehicle is operated in a region with significantly different magnetic characteristics._ + Large changes in latitude, longitude, or magnetic inclination can require re-estimation of offsets. +- _QGroundControl reports magnetometer inconsistencies_. + For example, if you see the error `mag sensors inconsistent`. +- _Heading behavior does not match the vehicle’s observed orientation._ + Symptoms include drifting yaw, sudden heading jumps when attempting to fly straight, and toilet bowling +- _QGroundControl_ sends the error `mag sensors inconsistent`. + This indicates that multiple magnetometers are reporting different headings. + ## Додаткова калібрування/конфігурація The process above will autodetect, [set default rotations](../advanced_config/parameter_reference.md#SENS_MAG_AUTOROT), calibrate, and prioritise, all available magnetometers. diff --git a/docs/uk/config/firmware.md b/docs/uk/config/firmware.md index 3eb6f56b85..bd2f64af2f 100644 --- a/docs/uk/config/firmware.md +++ b/docs/uk/config/firmware.md @@ -61,10 +61,10 @@ Next you will need to specify the [vehicle airframe](../config/airframe.md) (and 2. Check **Advanced settings** and select the version from the dropdown list: - **Standard Version (stable):** The default version (i.e. no need to use advanced settings to install this!) - **Beta Testing (beta):** A beta/candidate release. - Лише доступно, коли готується новий реліз. + Лише доступно, коли готується новий реліз. - **Developer Build (master):** The latest build of PX4/PX4-Autopilot _main_ branch. - **Custom Firmware file...:** A custom firmware file (e.g. [that you have built locally](../dev_setup/building_px4.md)). - Якщо ви виберете це, вам доведеться вибрати власну прошивку з файлової системи на наступному кроці. + Якщо ви виберете це, вам доведеться вибрати власну прошивку з файлової системи на наступному кроці. Оновлення прошивки потім продовжується, як і раніше. diff --git a/docs/uk/config/flight_mode.md b/docs/uk/config/flight_mode.md index 3960ed8133..4b8f9d0d42 100644 --- a/docs/uk/config/flight_mode.md +++ b/docs/uk/config/flight_mode.md @@ -40,24 +40,24 @@ PX4 дозволяє вам вказати канал "режиму" та виб 3. Select **"Q" icon > Vehicle Setup > Flight Modes** (sidebar) to open _Flight Modes Setup_. - ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) + ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) 4. Specify _Flight Mode Settings_: - - Select the **Mode channel** (above this shown as Channel 5, but this will depend on your transmitter configuration). - - Перемістіть перемикач передавача (або перемикачі), які ви налаштували для вибору режиму, через доступні позиції. - 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 **Mode channel** (above this shown as Channel 5, but this will depend on your transmitter configuration). + - Перемістіть перемикач передавача (або перемикачі), які ви налаштували для вибору режиму, через доступні позиції. + 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. ::: - - Виберіть режим польоту, який ви хочете активувати для кожного положення перемикача. + - Виберіть режим польоту, який ви хочете активувати для кожного положення перемикача. 5. 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 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). 6. Перевірте, що режими відображаються на правильні перемикачі передавача: - - 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). Усі значення автоматично зберігаються після зміни. diff --git a/docs/uk/config/safety.md b/docs/uk/config/safety.md index 82b5b8e57c..271142256e 100644 --- a/docs/uk/config/safety.md +++ b/docs/uk/config/safety.md @@ -104,7 +104,7 @@ There are several other "battery related" failsafe mechanisms that may be config | Налаштування | Параметр | Опис | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe @@ -119,36 +119,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Нижче наведено додаткові (і базові) налаштування параметрів. | Параметр | Налаштування | Опис | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Аварійний режим втрати ручного керування Timeout | Час після отримання останньої встановленої точки від вибраного джерела керування вручну, після якого керування вважається втраченим. Це повинно бути коротким, оскільки транспортний засіб продовжуватиме літати за старими налаштуваннями керування вручну, поки не спрацює таймаут. | +| [COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Аварійний режим втрати ручного керування Timeout | Час після отримання останньої встановленої точки від вибраного джерела керування вручну, після якого керування вважається втраченим. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. | | [COM_FAIL_ACT_T](../advanced_config/parameter_reference.md#COM_FAIL_ACT_T) | Затримка відмови від дії | Delay in seconds between failsafe condition being triggered (`COM_RC_LOSS_T`) and failsafe action (RTL, Land, Hold). У цьому стані транспортний засіб очікує в режимі утримання на повторне підключення джерела керування вручну. Це може бути встановлено довше для довгих польотів, щоб втрата інтермітентного з'єднання не викликала негайного виклику аварійного режиму. Це може бути рівним нулю, щоб аварійний запобіжник спрацював негайно. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | Моделювання відмовостійкості | Вимкнути, Блукати, Повернутися, Приземлитися, Роззброїти, Завершити. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Виключення втрат RC | Встановіть режими, в яких втрата керування вручну ігнорується: Місія, Утримання, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | Виключення втрат RC | Set modes in which manual control loss is ignored. | ## Втрата каналу зв'язку Failsafe -Збій втрати втрати даних посилання (при переході через телеметрію (підключення до наземної станції) втрачено. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) Налаштування та вибрані параметри показані нижче. -| Налаштування | Параметр | Опис | -| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| Тайм-аут втрати каналу зв'язку | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Час після втрати з'єднання з даними перед тим, як спрацює запобіжник. | -| Моделювання відмовостійкості | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Вимкнути, Hold mode, Return mode, Land mode, Роззброїти, Завершити. | - -Також застосовуються наступні налаштування, але вони не відображаються в інтерфейсі QGC. - -| Налаштування | Параметр | Опис | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| Налаштування | Параметр | Опис | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| Тайм-аут втрати каналу зв'язку | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Час після втрати з'єднання з даними перед тим, як спрацює запобіжник. | +| Моделювання відмовостійкості | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Вимкнути, Hold mode, Return mode, Land mode, Роззброїти, Завершити. | +| 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. | ## Аварійний режим "обмеження зони політів" @@ -204,23 +200,13 @@ The relevant parameters shown below. ### Position Loss Failsafe Action -The failure action is controlled by [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL), based on whether RC control is assumed to be available (and altitude information): - -- `0`: Remote control available. - Switch to _Altitude mode_ if a height estimate is available, otherwise _Stabilized mode_. -- `1`: Remote control _not_ available. - Switch to _Descend mode_ if a height estimate is available, otherwise enter flight termination. - _Descend mode_ is a landing mode that does not require a position estimate. +Multicopters will switch to [Altitude mode](../flight_modes_mc/altitude.md) if a height estimate is available, otherwise [Stabilized mode](../flight_modes_mc/manual_stabilized.md). Fixed-wing planes, and VTOLs not configured to land in hover ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)), have a parameter ([FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT)) that defines how long they will loiter (circle with a constant roll angle ([FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R)) at the current altitude) after losing position before attempting to land. If VTOLs have are configured to switch to hover for landing ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)) then they will first transition and then descend. Відповідні параметри для всіх транспортних засобів наведено нижче. -| Параметр | Опис | -| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL) | Position control navigation loss response during mission. Values: `0` - assume use of RC, `1` - Assume no RC. | - Параметри, які впливають лише на повітряні судна з фіксованим крилом: | Параметр | Опис | @@ -284,12 +270,12 @@ The relevant parameters are listed in the table below. ## Виявлення відмов -Детектор відмов дозволяє автомобілю вжити захисних заходів, якщо він несподівано перевертається, або якщо йому повідомлено зовнішньою системою виявлення відмов. +The failure detector allows a vehicle to take protective actions if it unexpectedly flips, detects a motor failure, or if it is notified by an external failure detection system. During **flight**, the failure detector can be used to trigger [flight termination](../advanced_config/flight_termination.md) if failure conditions are met, which may then launch a [parachute](../peripherals/parachute.md) or perform some other action. :::info -Failure detection during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). +Acting on a detected failure during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). ::: During **takeoff** the failure detector [attitude trigger](#attitude-trigger) invokes the [disarm action](#act_disarm) if the vehicle flips (disarm kills the motors but, unlike flight termination, will not launch a parachute or perform other failure actions). @@ -311,6 +297,26 @@ The failure detector is active in all vehicle types and modes, except for those | [FD_FAIL_P_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_P_TTRI) | Time to exceed [FD_FAIL_P](#FD_FAIL_P) for failure detection (default 0.3s). | | [FD_FAIL_R_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_R_TTRI) | Time to exceed [FD_FAIL_R](#FD_FAIL_R) for failure detection (default 0.3s). | +### Motor Failure Trigger + +The failure detector can be configured to detect a motor failure while armed (and trigger an associated action) in the following conditions: + +- A 300 ms timeout occurs in telemetry from an ESC that was previously available. +- The input current in the telemetry of an ESC which was previously positive gets too low for more than [`FD_ACT_MOT_TOUT`](FD_ACT_MOT_TOUT) ms. + The "too low" condition is defined by: + + ```text + {esc current} < {parameter FD_ACT_MOT_C2T} * {motor command between 0 and 1} + ``` + +| Параметр | Опис | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [FD_ACT_EN](../advanced_config/parameter_reference.md#FD_ACT_EN) | Enable/disable the motor failure trigger completely. | +| [FD_ACT_MOT_THR](../advanced_config/parameter_reference.md#FD_ACT_MOT_THR) | Minimum normalized [0,1] motor command below which motor under current is ignored. | +| [FD_ACT_MOT_C2T](../advanced_config/parameter_reference.md#FD_ACT_MOT_C2T) | Scale between normalized [0,1] motor command and expected minimally reported currrent when the rotor is healthy. | +| [FD_ACT_MOT_TOUT](../advanced_config/parameter_reference.md#FD_ACT_MOT_TOUT) | Time in miliseconds for which the under current detection condition needs to stay true. | +| [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) | Configure to not only warn about a motor failure but remove the first motor that detects a failure from the allocation effectiveness which turns off the motor and tries to operate the vehicle without it until disarming the next time. | + ### Зовнішня автоматична система тригерування (ATS) The [failure detector](#failure-detector), if [enabled](#CBRK_FLIGHTTERM), can also be triggered by an external ATS system. diff --git a/docs/uk/config/safety_simulation.md b/docs/uk/config/safety_simulation.md index a58fe0928d..8905bb3f2c 100644 --- a/docs/uk/config/safety_simulation.md +++ b/docs/uk/config/safety_simulation.md @@ -14,7 +14,7 @@ Note that any delayed action (`COM_FAIL_ACT_T`) will also be delayed in the simu 2. Встановіть тип транспортного засобу 3. Set the other values in the **State** or any of the flags under **Conditions** - The **Intended Mode** corresponds to the commanded mode via RC or GCS (or external script). - Станова машина аварійного відновлення може перевизначити це у разі аварійного відновлення. + Станова машина аварійного відновлення може перевизначити це у разі аварійного відновлення. 4. Check the action under **Output** 5. Check what happens when changing mode or **Move the RC sticks** 6. Грайте з різними налаштуваннями та умовами! diff --git a/docs/uk/config_fw/airspeed_scale_handling.md b/docs/uk/config_fw/airspeed_scale_handling.md new file mode 100644 index 0000000000..02f745fc72 --- /dev/null +++ b/docs/uk/config_fw/airspeed_scale_handling.md @@ -0,0 +1,112 @@ +# Airspeed Scale Handling + +:::info +This section complements the existing [Airspeed Validation](../advanced_config/airspeed_validation.md) documentation. +::: + +The airspeed scale is used by PX4 to convert the measured airspeed (indicated airspeed) to the calibrated airspeed. +This scale can be set by [ASPD_SCALE_n](../advanced_config/parameter_reference.md#ASPD_SCALE_1) (where `n` is the sensor number), and logged in [AirspeedWind.msg](../msg_docs/AirspeedWind.md). + +Note that the airspeed scale is different from the airspeed sensor offset calibration done on the ground at 0 m/s. The airspeed scale accounts for errors in the airspeed measurement during flight, such as those caused by sensor placement or installation effects. + +This topic describes how to set an initial airspeed scale for a new fixed-wing vehicle during its first flight. Correct scale calibration ensures reliable airspeed data, accurate TAS calculation, robust PX4 airspeed validation, and consistent controller performance. + +## Airspeed in PX4 + +PX4 handles multiple types of airspeed: + +- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). +- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. +- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. + While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. +- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). + +The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. + +## CAS Scale Estimation + +PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. +To compute the final TAS, standard environment conversions are applied (CAS → TAS). + +:::warning +Important +A GNSS is required for scale estimation. +::: + +PX4 uses a two-stage approach to robustly estimate the scale: + +1. **Continuous EKF Estimation**: A wind estimator constantly compares your measured airspeed against what it expects based on ground velocity (from GNSS) and estimated wind. + If there's a consistent bias, it adjusts the scale estimate. + The estimated scale is logged in the `AirspeedWind.msg` as the `tas_scale_raw`. +2. **Validation**: To ensure robustness, PX4 collects airspeed and ground speed data across 12 different heading segments (every 30°). + This averages out wind estimation errors. + The validated scale is only updated when the new estimate demonstrably reduces the error between predicted and actual ground speeds across all headings. + The validated scale is logged in the `AirspeedWind.msg` as the `tas_scale_validated`. + +### Understanding the Scale: Physical Intuition + +The CAS scale is essentially a correction factor that accounts for systematic errors in your airspeed sensor installation. + +- A scale of 1.0 means your sensor reads perfectly (no correction needed) +- A scale > 1.0 (e.g., 1.1) means your sensor _under-reads_ by 10%, so measured airspeed (IAS) must be multiplied by 1.1 +- A scale < 1.0 (e.g., 0.9) means your sensor _over-reads_ by ~11%, so measured airspeed (IAS) must be multiplied by 0.9 + +### What Affects the Airspeed Scale + +The primary factor influencing the airspeed scale is **sensor placement**. + +Biased readings can be reflected in the scale estimate for pitot tubes installed: + +- In regions experiencing disturbed flow (commonly near blunt aircraft noses) +- Near propellers +- Under aerodynamic surfaces +- At an angle with respect to the airflow + +### Symptoms of Incorrect Scale + +Symptoms of an incorrectly scaled airspeed measurement include: + +- Stalling or overspeeding +- Persistent under- or overestimation of the TAS relative to wind-corrected groundspeed +- False positives or missed detections in [airspeed innovation checks](../advanced_config/airspeed_validation.md#innovation-check) +- Degraded tracking of the rate controllers + +## Recommended First Flight Process + +During the first flight of a new fixed-wing vehicle, allocate time for the CAS scale to converge to a reasonable initial estimate. +Follow these steps: + +1. **Set an Initial Scale** + + Set the CAS scale (`ASPD_SCALE_n`) to 1.0 (the default value). + When the scale is at exactly 1.0, PX4 automatically accelerates the learning process during the first 5 minutes of flight, allowing faster convergence to the correct scale value. + +2. **Perform a Flight** + + After takeoff, place the vehicle in loiter for about 15 minutes to allow the scale estimation to converge. + + ::: tip + Flying in circles (loiter/hold mode) is important as the scale-validation algorithm requires the aircraft to pass through multiple heading segments (12 segments covering all compass directions). + If these heading segments aren’t completed, PX4 cannot validate the estimated scale. + +::: + +3. **Check Scale Convergence** + + After the flight, review the estimated scale in logs. + Verify that: + + - `tas_scale_validated` in `AirspeedWind.msg` converged during flight. + - `true_airspeed_m_s` (TAS) in [AirspeedValidated.msg](../msg_docs/AirspeedValidated.md) is consistent with groundspeed corrected for wind. + +4. **Update the Airframe Configuration** + + If using an [airframe configuration file](../dev_airframes/adding_a_new_frame.md): update `ASPD_SCALE_n`with the estimated CAS scale for future flights. + For similar vehicles with similarly mounted sensors, this value is typically a reliable starting point. + +:::info +If you are not able to perform the steps outlined above ... + +For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). +The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for `ASPD_SCALE_n`. +::: diff --git a/docs/uk/config_fw/index.md b/docs/uk/config_fw/index.md index e66d40f837..4383423728 100644 --- a/docs/uk/config_fw/index.md +++ b/docs/uk/config_fw/index.md @@ -3,7 +3,7 @@ Fixed-wing configuration and calibration follows the same high level steps as other frames: selection of firmware, configuration of the frame including actuator/motor geometry and output mappings, sensor configuration and calibration, configuration of safety and other features, and finally tuning. :::info -This topic is the recommended entry point when performing first-time configuration and calibration of a new multicopter frame. +This topic is the recommended entry point when performing first-time configuration and calibration of a new fixed-wing frame. ::: Основними кроками є: @@ -20,3 +20,5 @@ This topic is the recommended entry point when performing first-time configurati - [Fixed-wing Altitude/Position Controller Tuning Guide](../config_fw/position_tuning_guide_fixedwing.md) - [Fixed-wing Trimming Guide](../config_fw/trimming_guide_fixedwing.md) + +- [Fixed-Wing Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md) diff --git a/docs/uk/config_fw/pid_tuning_guide_fixedwing.md b/docs/uk/config_fw/pid_tuning_guide_fixedwing.md index 9384cc76cd..be3043849a 100644 --- a/docs/uk/config_fw/pid_tuning_guide_fixedwing.md +++ b/docs/uk/config_fw/pid_tuning_guide_fixedwing.md @@ -17,6 +17,8 @@ - Надмірні виграші (і швидкий рух серводвигуна) можуть порушити максимальні сили вашої конструкції повітряного корпусу - збільшуйте виграші обережно. - Налаштування крену та тангажу слідують тій самій послідовності. The only difference is that pitch is more sensitive to trim offsets, so [trimming](../config_fw/trimming_guide_fixedwing.md) has to be done carefully and integrator gains need more attention to compensate this. +- Disable automatic [gain compression](../features_fw/gain_compression.md) ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)) to avoid over-tuning. + Remember to re-enable it when tuning is done. ## Встановлення базового каркасу повітряного корпусу diff --git a/docs/uk/config_fw/position_tuning_guide_fixedwing.md b/docs/uk/config_fw/position_tuning_guide_fixedwing.md index 0cf742894d..69e19aaa92 100644 --- a/docs/uk/config_fw/position_tuning_guide_fixedwing.md +++ b/docs/uk/config_fw/position_tuning_guide_fixedwing.md @@ -9,7 +9,7 @@ An incorrectly set gain during tuning can make altitude or heading control unsta ::: :::tip -All parameters are documented in the [Parameter Reference](../advanced_config/parameter_reference.md#fw-tecs). +All parameters are documented in the Parameter Reference [FW Performance](../advanced_config/parameter_reference.md#fw-performance) and [FW NPFG Control](../advanced_config/parameter_reference.md#fw-npfg-control) sections. Найважливіші параметри охоплені в цьому керівництві. ::: @@ -78,7 +78,7 @@ Furthermore, these two values define the height rate limits commanded by the use ### Налаштування контролю траєкторії FW (Позиція) -All path control parameters are described [here](../advanced_config/parameter_reference.md#fw-path-control). +All path control parameters are described in [FW NPFG Control (Parameter Reference)](../advanced_config/parameter_reference.md#fw-npfg-control). - [NPFG_PERIOD](../advanced_config/parameter_reference.md#NPFG_PERIOD) - This is the previously called L1 distance and defines the tracking point ahead of the aircraft it's following. Значення 10-20 метрів працює для більшості літаків. diff --git a/docs/uk/config_fw/trimming_guide_fixedwing.md b/docs/uk/config_fw/trimming_guide_fixedwing.md index bb46d70b28..89da7f115f 100644 --- a/docs/uk/config_fw/trimming_guide_fixedwing.md +++ b/docs/uk/config_fw/trimming_guide_fixedwing.md @@ -29,10 +29,10 @@ The [Advanced Trimming](#advanced-trimming) section introduces parameters that c 1. Trim the servos by physically adjusting the linkages lengths if possible and fine tune by trimming the PWM channels (use `PWM_MAIN/AUX_TRIMx`) on the bench to properly set the control surfaces to their theoretical position. 2. Fly in stabilized mode at cruise speed and set the pitch setpoint offset (`FW_PSP_OFF`) to desired angle of attack. - Необхідний кут атаки при крейсерській швидкості відповідає куту крена, який потрібно літаку летіти, щоб утримати постійну висоту під час польоту з вирівняним крилом. - If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). + Необхідний кут атаки при крейсерській швидкості відповідає куту крена, який потрібно літаку летіти, щоб утримати постійну висоту під час польоту з вирівняним крилом. + If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). 3. Look at the actuator controls in the log file (upload it to [Flight Review](https://logs.px4.io) and check the _Actuator Controls_ plot for example) and set the pitch trim (`TRIM_PITCH`). - Встановіть це значення на середнє зміщення сигналу тану під час польоту на рівні крила. + Встановіть це значення на середнє зміщення сигналу тану під час польоту на рівні крила. Крок 3 можна виконати перед кроком 2, якщо ви не хочете дивитися на журнал або якщо вам зручно керувати літаком вручну. You can then trim your remote (with the trim switches) and report the values to `TRIM_PITCH` (and remove the trims from your transmitter) or update `TRIM_PITCH` directly during flight via telemetry and QGC. diff --git a/docs/uk/config_heli/index.md b/docs/uk/config_heli/index.md index b61169f631..f98522d729 100644 --- a/docs/uk/config_heli/index.md +++ b/docs/uk/config_heli/index.md @@ -53,15 +53,15 @@ This section contains topics related to [helicopter](../frames_helicopter/index. Для кожного набору сервоприводів: - `Angle`: Clockwise angle in degree on the swash plate circle at which the servo arm is attached starting from `0` pointing forwards. - Приклад для типової настройки, де три сервопривода керують планкою рівномірно розподіленою по колу (360° / 3 =) по 120° кожен, що призводить до наступних кутів: + Приклад для типової настройки, де три сервопривода керують планкою рівномірно розподіленою по колу (360° / 3 =) по 120° кожен, що призводить до наступних кутів: - | # | Кут | - | ------- | ---- | - | Servo 1 | 60° | - | Servo 2 | 180° | - | Servo 3 | 300° | + | # | Кут | + | ------- | ---- | + | Servo 1 | 60° | + | Servo 2 | 180° | + | Servo 3 | 300° | - warning and requirement + warning and requirement - `Arm Length (relative to each other)`: Radius from the swash plate center (top view). Коротше плече означає, що та ж сама рух сервопривода зміщує плиту більше. Це дозволяє отримати компенсацію автопілоту. @@ -72,7 +72,7 @@ This section contains topics related to [helicopter](../frames_helicopter/index. - `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. - Більше значення може поліпшити зручність користувача. + Більше значення може поліпшити зручність користувача. 3. Видаліть лопаті ротора та пропелери diff --git a/docs/uk/config_mc/filter_tuning.md b/docs/uk/config_mc/filter_tuning.md index 716a307a0f..46d9e8bc99 100644 --- a/docs/uk/config_mc/filter_tuning.md +++ b/docs/uk/config_mc/filter_tuning.md @@ -70,7 +70,7 @@ Airframes with more than two frequency noise spikes typically clean the first tw Dynamic notch filters use ESC RPM feedback and/or the onboard FFT analysis. The ESC RPM feedback is used to track the rotor blade pass frequency and its harmonics, while the FFT analysis can be used to track a frequency of another vibration source, such as a fuel engine. -ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/esc_motors.md#dshot) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). +ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/dshot.md) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). Before enabling, make sure that the ESC RPM is correct. You might have to adjust the [pole count of the motors](../advanced_config/parameter_reference.md#MOT_POLE_COUNT). @@ -166,11 +166,11 @@ In this case you might use the settings: [IMU_GYRO_NF0_FRQ=32](../advanced_confi ## Додаткові поради 1. Прийнятна затримка залежить від розміру транспортного засобу та очікувань. - FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). - For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. + FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). + For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. 2. You can start tuning at higher `IMU_GYRO_CUTOFF` values (e.g. 100Hz), which might be desirable because the default tuning of `IMU_GYRO_CUTOFF` is set very low (30Hz). - Однак вам потрібно бути обізнаними з ризиками: - - Не літайте більше 20-30 секунд - - Перевірте, що двигуни не нагріваються занадто сильно - - Слухайте дивні звуки та симптоми надмірного шуму, як обговорено вище. + Однак вам потрібно бути обізнаними з ризиками: + - Не літайте більше 20-30 секунд + - Перевірте, що двигуни не нагріваються занадто сильно + - Слухайте дивні звуки та симптоми надмірного шуму, як обговорено вище. diff --git a/docs/uk/config_mc/pid_tuning_guide_multicopter_basic.md b/docs/uk/config_mc/pid_tuning_guide_multicopter_basic.md index 93fe689ca8..4ccd6f0e3e 100644 --- a/docs/uk/config_mc/pid_tuning_guide_multicopter_basic.md +++ b/docs/uk/config_mc/pid_tuning_guide_multicopter_basic.md @@ -72,7 +72,7 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 1. Arm the vehicle, takeoff, and hover (typically in [Position mode](../flight_modes_mc/position.md)). 2. Open _QGroundControl_ **Vehicle Setup > PID Tuning** - ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) + ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) 3. Select the **Rate Controller** tab. @@ -80,60 +80,60 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 5. Set the _Thrust curve_ value to: 0.3 (PWM, power-based controllers) or 1 (RPM-based ESCs) - ::: info - For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. - Як результат, оптимальне налаштування при потужності утримання може бути не ідеальним, коли транспортний засіб працює на вищій потужності. + ::: info + For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. + Як результат, оптимальне налаштування при потужності утримання може бути не ідеальним, коли транспортний засіб працює на вищій потужності. - Значення кривої тяги може бути використане для компенсації цієї нелинійності: + Значення кривої тяги може бути використане для компенсації цієї нелинійності: - - For PWM controllers, 0.3 is a good default (which may benefit from [further tuning](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve)). - - Для контролерів на основі RPM використовуйте 1 (додаткове налаштування не потрібно, оскільки вони мають квадратичну криву тяги). + - For PWM controllers, 0.3 is a good default (which may benefit from [further tuning](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve)). + - Для контролерів на основі RPM використовуйте 1 (додаткове налаштування не потрібно, оскільки вони мають квадратичну криву тяги). - For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). + For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). ::: 6. Set the _Select Tuning_ radio button to: **Roll**. 7. (Optionally) Select the **Automatic Flight Mode Switching** checkbox. - This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button + This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button 8. For rate controller tuning switch to _Acro mode_, _Stabilized mode_ or _Altitude mode_ (unless automatic switching is enabled). 9. Select the **Start** button in order to start tracking the setpoint and response curves. 10. Rapidly move the _roll stick_ full range and observe the step response on the plots. - :::tip - Stop tracking to enable easier inspection of the plots. - Це відбувається автоматично, коли ви збільшуєте/панорамуєте. - Use the **Start** button to restart the plots, and **Clear** to reset them. + :::tip + Stop tracking to enable easier inspection of the plots. + Це відбувається автоматично, коли ви збільшуєте/панорамуєте. + Use the **Start** button to restart the plots, and **Clear** to reset them. ::: 11. Modify the three PID values using the sliders (for roll rate-tuning these affect `MC_ROLLRATE_K`, `MC_ROLLRATE_I`, `MC_ROLLRATE_D`) and observe the step response again. - Значення зберігаються на транспортний засіб, як тільки переміщуються слайдери. - ::: info - The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). + Значення зберігаються на транспортний засіб, як тільки переміщуються слайдери. + ::: info + The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). ::: - The PID values can be adjusted as follows: - - P (пропорційне) або К підсилення: - - збільште це для більшої реакції - - зменшити, якщо відповідь перевищує і / або коливається (до певної міри збільшення значення D також допомагає). - - D (похідне) надходження: - - це можна збільшити, щоб заглушити перевищення та коливання - - збільшуйте це лише настільки, наскільки це потрібно, оскільки це підсилює шум (і може призвести до нагрітих моторів) - - I (інтегральний) коефіцієнт отримання: - - використовується для зменшення поміченої похибки стану рівноваги - - якщо значення занадто низьке, відповідь може ніколи не досягти заданої точки (наприклад, у вітрових умовах) - - якщо занадто високий, можуть виникнути повільні коливання + The PID values can be adjusted as follows: + - P (пропорційне) або К підсилення: + - збільште це для більшої реакції + - зменшити, якщо відповідь перевищує і / або коливається (до певної міри збільшення значення D також допомагає). + - D (похідне) надходження: + - це можна збільшити, щоб заглушити перевищення та коливання + - збільшуйте це лише настільки, наскільки це потрібно, оскільки це підсилює шум (і може призвести до нагрітих моторів) + - I (інтегральний) коефіцієнт отримання: + - використовується для зменшення поміченої похибки стану рівноваги + - якщо значення занадто низьке, відповідь може ніколи не досягти заданої точки (наприклад, у вітрових умовах) + - якщо занадто високий, можуть виникнути повільні коливання 12. Повторіть процес налаштування вище для крена та курсу: - - Use _Select Tuning_ radio button to select the axis to tune - - Перемістіть відповідні палички (тобто паличку крена для крена, паличку риштування для риштування). - - Для налаштування крену почніть з тих самих значень, що й для крену. - :::tip - Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. + - Use _Select Tuning_ radio button to select the axis to tune + - Перемістіть відповідні палички (тобто паличку крена для крена, паличку риштування для риштування). + - Для налаштування крену почніть з тих самих значень, що й для крену. + :::tip + Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. ::: @@ -141,10 +141,10 @@ Make sure to have assigned a [Kill switch](../config/safety.md#emergency-switche 14. Повторіть процес налаштування контролерів швидкості та позицій (на всіх осях). - - Використовуйте режим позиції при налаштуванні цих контролерів - - Select the **Simple position control** option in the _Position control mode ..._ selector (this allows direct control for the generation of step inputs) + - Використовуйте режим позиції при налаштуванні цих контролерів + - Select the **Simple position control** option in the _Position control mode ..._ selector (this allows direct control for the generation of step inputs) - ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) + ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) Готово! Пам'ятайте увімкнути повітряний режим перед виходом з налаштувань. diff --git a/docs/uk/config_rover/basic_setup.md b/docs/uk/config_rover/basic_setup.md index 08bde551a8..b01b5ebb0f 100644 --- a/docs/uk/config_rover/basic_setup.md +++ b/docs/uk/config_rover/basic_setup.md @@ -27,10 +27,18 @@ That is the minimum setup to use the rover in [Manual mode](../flight_modes_rover/manual.md#manual-mode). +:::info +The rest of the tuning on this page is not mandatory for [Manual mode](../flight_modes_rover/manual.md#manual-mode), but it will have an effect on the behaviour of the rover. +::: + +:::warning +Do not skip the rest of this setup if you intend to use more sophisticated modes! +All parameters will be mandatory for all subsequent modes, except those tagged as `(Optional)`. +::: + ## Geometric Parameters -Manual mode is also affected by (optional) acceleration/deceleration limits set using the geometric described below. -These limits are mandatory for all other modes. +First, we set up the geometric parameters of the rover: ![Geometric parameters](../../assets/config/rover/geometric_parameters.png) @@ -42,7 +50,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and 2. [RA_MAX_STR_ANG](#RA_MAX_STR_ANG) [deg]: Measure the maximum steering angle. 3. (Optional) [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) [deg/s]: Maximum steering rate you want to allow for your rover. - :::tip + ::: tip This value depends on your rover and use case. For bigger rovers there might be a mechanical limit that is easy to identify by steering the rover at a standstill and increasing [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) until you observe the steering rate to no longer be limited by the parameter. @@ -51,7 +59,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: - :::warning + ::: warning A low maximum steering rate makes the rover worse at tracking steering setpoints, which can lead to a poor performance in the subsequent modes. ::: @@ -85,7 +93,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and One approach to determine an appropriate value is: 1. From a standstill, give the rover full throttle until it reaches the maximum speed. - 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md). + 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md). 3. Divide the maximum speed by the time it took to reach it and set this as the value for [RO_ACCEL_LIM](#RO_ACCEL_LIM). Some RC rovers have enough torque to lift up if the maximum acceleration is not limited. @@ -109,6 +117,39 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: +## (Optional) Stick Input Mapping + +Input shaping can be used to adjust the default linear mapping from stick inputs $\in [-1, 1]$ to normalized setpoints $\in [-1, 1]$. Applying this specifically to the steering input, can provide a smoother driving experience, by enabling the user to make small adjustments when the stick is close to the center, but still send large inputs when moving them to the edges. +We provide this input shaping through the super exponential function: + +$$ +\delta = \frac{(f \cdot x^3 + x(1-f)) \cdot (1-g)}{1-g \cdot |x|} +$$ + +with: + +- $\delta \in [-1, 1]=$ Normalized steering setpoint. +- $x \in [-1, 1]=$ Normalized stick input. +- $f=$ [RO_YAW_EXPO](#RO_YAW_EXPO): `0` Purely linear input curve, `1` Purely cubic input curve. +- $g=$ [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO): `0` Pure Expo function, `0.7` reasonable shape enhancement for intuitive stick feel, `0.95` very strong bent input curve only near maxima have effect. + +In [Manual mode](../flight_modes_rover/manual.md#manual-mode) we can additionally scale $\delta$ with an additional parameter $r$: + +- Differential Rover: $r=$ [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)]. +- Mecanum Rover: $r=$ [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN)]. + +This scaling is useful to limit the normalized steering setpoint, if it is too aggresive for your rover in manual mode. + +You can experiment with the relationships graphically using the [PX4 SuperExpo Rover calculator](https://www.desmos.com/calculator/gwm8lrlanx). + +:::info +In [Acro](../flight_modes_rover/manual.md#acro-mode), [Stabilized](../flight_modes_rover/manual.md#stabilized-mode) and [Position](../flight_modes_rover/manual.md#position-mode) Mode, $\delta$ is instead scaled by $r=$ [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) for all rovers. This leads to a yaw rate setpoint $\dot{\psi} = \delta \cdot r \in$ [-[RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED), [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED)]. This parameter is setup during [rate tuning](rate_tuning.md). +::: + +:::info +The input shaping through [RO_YAW_EXPO](#RO_YAW_EXPO) and [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO) applies for all manual modes, while [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)/[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN) only affects full manual mode. +::: + You can now continue the configuration process with [rate tuning](rate_tuning.md). ## Огляд параметрів @@ -118,6 +159,8 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md | [RO_MAX_THR_SPEED](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) | Speed the rover drives at maximum throttle | $m/s$ | | [RO_ACCEL_LIM](../advanced_config/parameter_reference.md#RO_ACCEL_LIM) | (Optional) Maximum allowed acceleration | $m/s^2$ | | [RO_DECEL_LIM](../advanced_config/parameter_reference.md#RO_DECEL_LIM) | (Optional) Maximum allowed deceleration | $m/s^2$ | +| [RO_YAW_EXPO](../advanced_config/parameter_reference.md#RO_YAW_EXPO) | (Optional) Yaw rate expo factor | $-$ | +| [RO_YAW_SUPEXPO](../advanced_config/parameter_reference.md#RO_YAW_SUPEXPO) | (Optional) Yaw rate super expo factor | $-$ | ### Ackermann Specific @@ -129,12 +172,14 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md ### Differential Specific -| Параметр | Опис | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | m | +| Параметр | Опис | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | $m$ | +| [RD_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RD_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | ### Mecanum Specific -| Параметр | Опис | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | m | +| Параметр | Опис | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | $m$ | +| [RM_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RM_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | diff --git a/docs/uk/config_rover/index.md b/docs/uk/config_rover/index.md index f085188225..82c7a91bf4 100644 --- a/docs/uk/config_rover/index.md +++ b/docs/uk/config_rover/index.md @@ -25,18 +25,18 @@ Rovers use a custom build that must be flashed onto your flight controller inste 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: - ```sh - make px4_fmu-v6x_rover - ``` + ```sh + make px4_fmu-v6x_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)): - ```sh - CONFIG_MODULES_ROVER_ACKERMANN=y - CONFIG_MODULES_ROVER_DIFFERENTIAL=y - CONFIG_MODULES_ROVER_MECANUM=y - ``` + ```sh + CONFIG_MODULES_ROVER_ACKERMANN=y + CONFIG_MODULES_ROVER_DIFFERENTIAL=y + CONFIG_MODULES_ROVER_MECANUM=y + ``` 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). diff --git a/docs/uk/config_rover/position_tuning.md b/docs/uk/config_rover/position_tuning.md index 854d1ab9b9..139b3db7aa 100644 --- a/docs/uk/config_rover/position_tuning.md +++ b/docs/uk/config_rover/position_tuning.md @@ -43,7 +43,7 @@ To tune the position controller configure the [parameters](../advanced_config/pa ::: -3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. +3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. If the tracking of these setpoints is not satisfactory adjust the values for [RO_SPEED_P](../advanced_config/parameter_reference.md#RO_SPEED_P) and [RO_SPEED_I](../advanced_config/parameter_reference.md#RO_SPEED_I). ## Path Following diff --git a/docs/uk/config_rover/velocity_tuning.md b/docs/uk/config_rover/velocity_tuning.md index 6bb98876bd..b7800b1822 100644 --- a/docs/uk/config_rover/velocity_tuning.md +++ b/docs/uk/config_rover/velocity_tuning.md @@ -28,7 +28,7 @@ To tune the velocity controller configure the following [parameters](../advanced 1. Set [RO_SPEED_P](#RO_SPEED_P) and [RO_SPEED_I](#RO_SPEED_I) to zero. This way the speed is only controlled by the feed-forward term, which makes it easier to tune. 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and then move the left stick of your controller up and/or down and hold it at a few different levels for a couple of seconds each. - 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. + 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. 4. If the actual speed of the rover is higher than the speed setpoint, increase [RO_MAX_THR_SPEED](#RO_MAX_THR_SPEED). If it is the other way around decrease the parameter and repeat until you are satisfied with the setpoint tracking. @@ -94,7 +94,7 @@ These steps are only necessary if you are tuning/want to unlock the manual [Posi The rover is now ready to drive in [Position mode](../flight_modes_rover/manual.md#position-mode) and the configuration can be continued with [position tuning](position_tuning.md). -## Attitude Controller Structure (Info Only) +## Velocity Controller Structure (Info Only) This section provides additional information for developers and people with experience in control system design. diff --git a/docs/uk/config_vtol/index.md b/docs/uk/config_vtol/index.md index 0552c6a477..fc6d447a61 100644 --- a/docs/uk/config_vtol/index.md +++ b/docs/uk/config_vtol/index.md @@ -9,3 +9,4 @@ As part of this you should calibrate the [Airspeed sensor](../config/airspeed.md - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/uk/config_vtol/vtol_ice_shedding.md b/docs/uk/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..de94fb7e37 --- /dev/null +++ b/docs/uk/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,22 @@ +# VTOL Ice Shedding feature + +## Загальний огляд + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::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 + +::: diff --git a/docs/uk/config_vtol/vtol_quad_configuration.md b/docs/uk/config_vtol/vtol_quad_configuration.md index d089834fd1..0c8dc8c47a 100644 --- a/docs/uk/config_vtol/vtol_quad_configuration.md +++ b/docs/uk/config_vtol/vtol_quad_configuration.md @@ -11,7 +11,7 @@ For airframe specific documentation and build instructions see [VTOL Framebuilds 2. Flash the firmware for your current release or master (PX4 `main` branch build). 3. In the [Frame setup](../config/airframe.md) section select the appropriate VTOL airframe. - If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. + If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. ### Перемикач режимів польоту / переходу diff --git a/docs/uk/contribute/code.md b/docs/uk/contribute/code.md index dcd001e2e0..36fa4646e4 100644 --- a/docs/uk/contribute/code.md +++ b/docs/uk/contribute/code.md @@ -34,7 +34,7 @@ Not all PX4 source code matches the style guide, but any _new code_ that you wri ### Довжина рядка -- Максимальна довжина рядка становить 120 символів. +- Maximum line length is 140 characters. ### Розширення файлів diff --git a/docs/uk/contribute/docs.md b/docs/uk/contribute/docs.md index 082b21ae0e..e4bd6005ec 100644 --- a/docs/uk/contribute/docs.md +++ b/docs/uk/contribute/docs.md @@ -63,33 +63,33 @@ If you already have a clone of the [PX4-Autopilot](https://github.com/PX4/PX4-Au 4. Клонуйте ваш форкнутий репозиторій на локальний комп'ютер: - ```sh - cd ~/wherever/ - git clone https://github.com//PX4-Autopilot.git - ``` + ```sh + cd ~/wherever/ + git clone https://github.com//PX4-Autopilot.git + ``` - For example, to clone PX4 source fork for a user with Github account "john_citizen": + For example, to clone PX4 source fork for a user with Github account "john_citizen": - ```sh - git clone https://github.com/john_citizen/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/john_citizen/PX4-Autopilot.git + ``` 5. Перейдіть до свого локального сховища: - ```sh - cd ~/wherever/PX4-Autopilot - ``` + ```sh + cd ~/wherever/PX4-Autopilot + ``` 6. Add a _remote_ called "upstream" to point to the "official" PX4 version of the library: - ```sh - git remote add upstream https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git remote add upstream https://github.com/PX4/PX4-Autopilot.git + ``` - :::tip - A "remote" is a handle to a particular repository. - The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. - Above you create a new remote _upstream_ that points to the PX4 project version of the documents. + :::tip + A "remote" is a handle to a particular repository. + The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. + Above you create a new remote _upstream_ that points to the PX4 project version of the documents. ::: @@ -99,111 +99,111 @@ Within the repository you created above: 1. Bring your copy of the repository `main` branch up to date: - ```sh - git checkout main - git fetch upstream main - git pull upstream main - ``` + ```sh + git checkout main + git fetch upstream main + git pull upstream main + ``` 2. Create a new branch for your changes: - ```sh - git checkout -b - ``` + ```sh + git checkout -b + ``` - This creates a local branch on your computer named `your_feature_branch_name`. + This creates a local branch on your computer named `your_feature_branch_name`. 3. Внести зміни до документації за необхідною (загальний посібник по цьому в наступних розділах) 4. Коли ви будете задоволені своїми змінами, ви можете додати їх до вашої локальної гілки за допомогою "commit": - ```sh - git add - git commit -m "" - ``` + ```sh + git add + git commit -m "" + ``` - For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. + For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. 5. Натисніть "Push" вашу локальну гілку (включаючи додані до неї коміти) у вашу репозиторію-форк на Github. - ```sh - git push origin your_feature_branch_name - ``` + ```sh + git push origin your_feature_branch_name + ``` 6. Go to your forked repository on Github in a web browser, e.g.: `https://github.com//PX4-Autopilot.git`. - Там ви маєте побачити повідомлення, що нова гілка була відправлена у вашу репозиторію-форк. + Там ви маєте побачити повідомлення, що нова гілка була відправлена у вашу репозиторію-форк. 7. Створіть запит на витягнення (Pull Request, PR): - - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". - Натисніть на неї. - - Буде створено шаблон запиту на витягнення. - Він буде перераховувати ваші коміти, і ви можете (маєте) додати значущий заголовок (у випадку одного коміту PR, це зазвичай повідомлення про коміт) та повідомлення (поясніть, що ви зробили і для якої причини. . - Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). - - Add the "Documentation" label. + - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". + Натисніть на неї. + - Буде створено шаблон запиту на витягнення. + Він буде перераховувати ваші коміти, і ви можете (маєте) додати значущий заголовок (у випадку одного коміту PR, це зазвичай повідомлення про коміт) та повідомлення (поясніть, що ви зробили і для якої причини. . + Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). + - Add the "Documentation" label. 8. Готово! - Редактори PX4 User Guide зараз переглянуть вашу співпрацю і вирішать, чи хочуть вони інтегрувати її. - Періодично перевіряйте, чи є у них питання по вашим змінам. + Редактори PX4 User Guide зараз переглянуть вашу співпрацю і вирішать, чи хочуть вони інтегрувати її. + Періодично перевіряйте, чи є у них питання по вашим змінам. ### Побудова бібліотеки локально Побудуйте бібліотеку локально, щоб перевірити, що будь-які зміни, які ви внесли, відображені належним чином: 1. Install the [Vitepress prerequisites](https://vitepress.dev/guide/getting-started#prerequisites): - - [Nodejs 18+](https://nodejs.org/en) - - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) + - [Nodejs 18+](https://nodejs.org/en) + - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) 2. Navigate to your local repository and the `/docs` subdirectory: - ```sh - cd ~/wherever/PX4-Autopilot/docs - ``` + ```sh + cd ~/wherever/PX4-Autopilot/docs + ``` 3. Встановити залежності (включаючи Vuepress): - ```sh - yarn install - ``` + ```sh + yarn install + ``` 4. Попередній перегляд і обслуговування бібліотеки: - ```sh - yarn docs:dev - ``` + ```sh + yarn docs:dev + ``` - - Одного разу, коли сервер розробки / попереднього перегляду побудує бібліотеку (менше хвилини вперше), він покаже вам URL-адресу, за допомогою якої ви можете переглянути сайт. - This will be something like: `http://localhost:5173/px4_user_guide/`. - - Stop serving using **CTRL+C** in the terminal prompt. + - Одного разу, коли сервер розробки / попереднього перегляду побудує бібліотеку (менше хвилини вперше), він покаже вам URL-адресу, за допомогою якої ви можете переглянути сайт. + This will be something like: `http://localhost:5173/px4_user_guide/`. + - Stop serving using **CTRL+C** in the terminal prompt. 5. Open previewed pages in your local editor: - First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. - For example, you can enable VSCode as your default editor by entering: + First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. + For example, you can enable VSCode as your default editor by entering: - - Windows: + - Windows: - ```sh - set EDITOR=code - ``` + ```sh + set EDITOR=code + ``` - - Linux: + - Linux: - ```sh - export EDITOR=code - ``` + ```sh + export EDITOR=code + ``` - The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). + The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). 6. Побудуйте бібліотеку за допомогою: - ```sh - # Ubuntu - yarn docs:build + ```sh + # Ubuntu + yarn docs:build - # Windows - yarn docs:buildwin - ``` + # Windows + yarn docs:buildwin + ``` :::tip Use `yarn start` to preview changes _as you make them_ (documents are updated and served very quickly). @@ -256,38 +256,38 @@ When you add a new page you must also add it to `en/SUMMARY.md`! ## Інструкція зі стилістичного оформлення 1. Назви файлів/файлів - - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. - Не створюйте додаткових вкладених папок. - - Put new image files in an appropriate nested sub-folder of `/assets/`. - Deeper nesting is allowed/encouraged. - - Use descriptive names for folders and files. - In particular, image filenames should describe what they contain (don't name as "image1.png") - - Use lower case filenames and separate words using underscores (`_`). + - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. + Не створюйте додаткових вкладених папок. + - Put new image files in an appropriate nested sub-folder of `/assets/`. + Deeper nesting is allowed/encouraged. + - Use descriptive names for folders and files. + In particular, image filenames should describe what they contain (don't name as "image1.png") + - Use lower case filenames and separate words using underscores (`_`). 2. Зображення - - Використовуйте найменший розмір і найнижчу роздільну здатність, яка все ще робить зображення корисним (це зменшує вартість завантаження для користувачів із слабким інтернет-з'єднанням). - - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). - - SVG files are preferred for diagrams. - PNG files are preferred over JPG for screenshots. + - Використовуйте найменший розмір і найнижчу роздільну здатність, яка все ще робить зображення корисним (це зменшує вартість завантаження для користувачів із слабким інтернет-з'єднанням). + - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). + - SVG files are preferred for diagrams. + PNG files are preferred over JPG for screenshots. 3. Контент - - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). - - **Bold** for button presses and menu definitions. - - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. - - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. - - Headings and page titles should use "First Letter Capitalisation". - - The page title should be a first level heading (`#`). - All other headings should be h2 (`##`) or lower. - - Не додавати ніяких стилів до заголовків. - - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. - - Break lines on sentences by preference. - Don't break lines based on some arbitrary line length. - - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). + - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). + - **Bold** for button presses and menu definitions. + - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. + - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. + - Headings and page titles should use "First Letter Capitalisation". + - The page title should be a first level heading (`#`). + All other headings should be h2 (`##`) or lower. + - Не додавати ніяких стилів до заголовків. + - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. + - Break lines on sentences by preference. + Don't break lines based on some arbitrary line length. + - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). 4. Videos: - - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). - - Use instructional videos sparingly as they date badly, and are hard to maintain. - - Cool videos of airframes in flight are always welcome. + - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). + - Use instructional videos sparingly as they date badly, and are hard to maintain. + - Cool videos of airframes in flight are always welcome. ## Де я можу додати зміни? diff --git a/docs/uk/contribute/git_examples.md b/docs/uk/contribute/git_examples.md index 5fdd22d82f..37d211b180 100644 --- a/docs/uk/contribute/git_examples.md +++ b/docs/uk/contribute/git_examples.md @@ -109,23 +109,23 @@ We recommend using PX4 `make` commands to switch between source code branches. 1. Очистити поточну гілку, деініціалізувати підмодуль та видалити всі артефакти збірки: - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` 2. Switch to a new branch or tag (here we first fetch the fictional branch "PR_test_branch" from the `upstream` remote): - ```sh - git fetch upstream PR_test_branch - git checkout PR_test_branch - ``` + ```sh + git fetch upstream PR_test_branch + git checkout PR_test_branch + ``` 3. Отримати підмодулі для нової гілки: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` @@ -138,35 +138,35 @@ To get the source code for a _specific older release_ (tag): 1. Clone the PX4-Autopilot repo and navigate into _PX4-Autopilot_ directory: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + ``` - :::info + :::info - Ви можете повторно використовувати існуючий репозиторій, а не клонувати новий. - In this case clean the build environment (see [changing source trees](#changing-source-trees)): + Ви можете повторно використовувати існуючий репозиторій, а не клонувати новий. + In this case clean the build environment (see [changing source trees](#changing-source-trees)): - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` ::: 2. Код оформлення замовлення для конкретного тегу (наприклад, для мітки v1.13.0-beta2) - ```sh - git checkout v1.13.0-beta2 - ``` + ```sh + git checkout v1.13.0-beta2 + ``` 3. Оновити підмодулі: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` ## Щоб отримати гілку релізу diff --git a/docs/uk/debug/asset_tracking.md b/docs/uk/debug/asset_tracking.md new file mode 100644 index 0000000000..6ed230b97c --- /dev/null +++ b/docs/uk/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## Загальний огляд + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## Аналіз журналу польотів + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## Дивіться також + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/uk/debug/eclipse_jlink.md b/docs/uk/debug/eclipse_jlink.md index 834c3f7954..060d2732a3 100644 --- a/docs/uk/debug/eclipse_jlink.md +++ b/docs/uk/debug/eclipse_jlink.md @@ -53,17 +53,17 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal 7. Пакети з оновленнями: - Click the small icon on the top right called _Open Perspective_ and open the _Packs_ perspective. - ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) + ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) - Click the **update all** button. - :::tip - This takes a VERY LONG TIME (10 minutes). - Ігноруйте всі помилки про відсутні пакети. + :::tip + This takes a VERY LONG TIME (10 minutes). + Ігноруйте всі помилки про відсутні пакети. ::: - ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) + ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) - The STM32Fxx devices are found in the Keil folder, install by right-clicking and then selecting **install** on the according device for F4 and F7. @@ -79,24 +79,24 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal ![Eclipse: Debug config](../../assets/debug/eclipse_settings_debug_config.png) 10. Then select _GDB SEGGER J-Link Debugging_ and then the **New config** button on the top left. - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) 11. Налаштування конфігурації збірки: - - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. - - Choose _Disable Auto build_ + - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. + - Choose _Disable Auto build_ ::: info Remember that you must build the target from the command line before starting a debug session. ::: - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) 12. The _Debugger_ and _Startup_ tabs shouldn’t need any modifications (just verify your settings with the screenshots below) - ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) - ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) + ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) + ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) ## Відлагодження з урахуванням завдань SEGGER @@ -109,16 +109,16 @@ Task-aware debugging (also known as [thread-aware debugging](https://www.segger. - Відкрийте термінал у кореневій теці вихідного коду PX4-Autopilot - In the terminal, open `menuconfig` using the appropriate make target for the build. - Це виглядатиме приблизно так: + Це виглядатиме приблизно так: - ```sh - make px4_fmu-v5_default boardguiconfig - ``` + ```sh + make px4_fmu-v5_default boardguiconfig + ``` - (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). + (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). - Ensure that the _Enable TCBinfo struct for debug_ is selected as shown: - ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) + ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) 2. Compile the **jlink-nuttx.so** library in the terminal by running the following command in the terminal: `make jlink-nuttx` diff --git a/docs/uk/debug/failure_injection.md b/docs/uk/debug/failure_injection.md index 2cfc45ccad..1f17a35b64 100644 --- a/docs/uk/debug/failure_injection.md +++ b/docs/uk/debug/failure_injection.md @@ -9,7 +9,7 @@ Failure injection is disabled by default, and can be enabled using the [SYS_FAIL Failure injection still in development. На момент написання (PX4 v1.14): -- Це можна використовувати лише в симуляції (підтримка як для впровадження в реальному польоті запланована). +- Support may vary by failure type and between simulatiors and real vehicle. - Потребує підтримки в симуляторі. Це підтримується в Gazebo Classic - Багато типів відмов не широко реалізовані. @@ -19,7 +19,7 @@ Failure injection still in development. ## Команда системи збою -Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 console/shell, specifying both the target and type of the failure. +Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 [console/shell](../debug/consoles.md) (such as the [QGC MAVLink Console](../debug/mavlink_shell.md#qgroundcontrol-mavlink-console) or SITL _pxh shell_), specifying both the target and type of the failure. ### Синтаксис @@ -33,52 +33,68 @@ failure [-i ] - _component_: - Датчики: - - `gyro`: Gyro. - - `accel`: Accelerometer. + - `gyro`: Gyroscope + - `accel`: Accelerometer - `mag`: Magnetometer - `baro`: Barometer - - `gps`: GPS + - `gps`: Global navigation satellite system - `optical_flow`: Optical flow. - - `vio`: Visual inertial odometry. + - `vio`: Visual inertial odometry - `distance_sensor`: Distance sensor (rangefinder). - - `airspeed`: Airspeed sensor. + - `airspeed`: Airspeed sensor - Системи: - - `battery`: Battery. - - `motor`: Motor. - - `servo`: Servo. - - `avoidance`: Avoidance. - - `rc_signal`: RC Signal. - - `mavlink_signal`: MAVLink signal (data telemetry). + - `battery`: Battery + - `motor`: Motor + - `servo`: Servo + - `avoidance`: Avoidance + - `rc_signal`: RC Signal + - `mavlink_signal`: MAVLink data telemetry connection - _failure_type_: - - `ok`: Publish as normal (Disable failure injection). - - `off`: Stop publishing. - - `stuck`: Report same value every time (_could_ indicate a malfunctioning sensor). - - `garbage`: Publish random noise. Це схоже на читання неініціалізованої пам'яті. - - `wrong`: Publish invalid values (that still look reasonable/aren't "garbage"). - - `slow`: Publish at a reduced rate. - - `delayed`: Publish valid data with a significant delay. - - `intermittent`: Publish intermittently. + - `ok`: Publish as normal (Disable failure injection) + - `off`: Stop publishing + - `stuck`: Constantly report the same value which _can_ happen on a malfunctioning sensor + - `garbage`: Publish random noise. This looks like reading uninitialized memory + - `wrong`: Publish invalid values that still look reasonable/aren't "garbage" + - `slow`: Publish at a reduced rate + - `delayed`: Publish valid data with a significant delay + - `intermittent`: Publish intermittently - _instance number_ (optional): Instance number of affected sensor. 0 (за замовчуванням) вказує на всі сенсори вказаного типу. -### Example - -Щоб симулювати втрату сигналу RC без вимкнення вашого пульта керування RC: - -1. Enable the parameter [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN). -2. Enter the following commands on the MAVLink console or SITL _pxh shell_: - - ```sh - # Fail RC (turn publishing off) - failure rc_signal off - - # Restart RC publishing - failure rc_signal ok - ``` - ## MAVSDK відлагоджувальний плагін The [MAVSDK failure plugin](https://mavsdk.mavlink.io/main/en/cpp/api_reference/classmavsdk_1_1_failure.html) can be used to programmatically inject failures. It is used in [PX4 Integration Testing](../test_and_ci/integration_testing_mavsdk.md) to simulate failure cases (for example, see [PX4-Autopilot/test/mavsdk_tests/autopilot_tester.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/test/mavsdk_tests/autopilot_tester.cpp)). API плагіна - це пряме відображення команди збою, показаної вище, з деякими додатковими сигналами про помилки, пов'язані з підключенням. + +## Example: RC signal + +Щоб симулювати втрату сигналу RC без вимкнення вашого пульта керування RC: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Fail RC (turn publishing off) + failure rc_signal off + + # Restart RC publishing + failure rc_signal ok + ``` + +## Example: Motor + +To stop a motor mid-flight without the system anticipating it or excluding it from allocation effectiveness: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enable [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) parameter to allow turning off motors. +3. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Turn off first motor + failure motor off -i 1 + + # Turn it back on + failure motor ok -i 1 + ``` diff --git a/docs/uk/dev_airframes/adding_a_new_frame.md b/docs/uk/dev_airframes/adding_a_new_frame.md index 5977914bb8..534f06bdc9 100644 --- a/docs/uk/dev_airframes/adding_a_new_frame.md +++ b/docs/uk/dev_airframes/adding_a_new_frame.md @@ -37,8 +37,8 @@ Alternatively you can just append the modified parameters to the startup configu Як додати конфігурацію до прошивки: 1. Create a new config file in the [init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) folder. - - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). - - Оновіть файл з параметрами конфігурації та програмами (див. вище). + - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). + - Оновіть файл з параметрами конфігурації та програмами (див. вище). 2. Add the name of the new frame config file to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt) in the relevant section for the type of vehicle. 3. [Build and upload](../dev_setup/building_px4.md) the software. @@ -292,37 +292,37 @@ If the airframe is for a **new group** you additionally need to: 2. Add a mapping between the new group name and image filename in the [srcparser.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/px4airframes/srcparser.py) method `GetImageName()` (follow the pattern below): - ```python - def GetImageName(self): - """ - Get parameter group image base name (w/o extension) - """ - if (self.name == "Standard Plane"): - return "Plane" - elif (self.name == "Flying Wing"): - return "FlyingWing" - ... - ... - return "AirframeUnknown" - ``` + ```python + def GetImageName(self): + """ + Get parameter group image base name (w/o extension) + """ + if (self.name == "Standard Plane"): + return "Plane" + elif (self.name == "Flying Wing"): + return "FlyingWing" + ... + ... + return "AirframeUnknown" + ``` 3. 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: + - 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: - ```xml - - ... - src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg - src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg - src/AutoPilotPlugins/Common/Images/Boat.svg - src/AutoPilotPlugins/Common/Images/FlyingWing.svg - ... - ``` + ```xml + + ... + src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg + src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg + src/AutoPilotPlugins/Common/Images/Boat.svg + src/AutoPilotPlugins/Common/Images/FlyingWing.svg + ... + ``` - ::: info - The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). + ::: info + The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). ::: diff --git a/docs/uk/dev_log/log_encryption.md b/docs/uk/dev_log/log_encryption.md index a6f7f68b3c..82b519a857 100644 --- a/docs/uk/dev_log/log_encryption.md +++ b/docs/uk/dev_log/log_encryption.md @@ -30,7 +30,7 @@ If another algorithm is supported in future, the process is _likely_ to remain t The encryption process for each new ULog is: 1. A XChaCha20 symmetric key is generated and encrypted using an RSA2048 public key. - This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). + This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). 2. When a log is captured, the ULog data is encrypted with the unwrapped symmetric key and the resulting data is appended into the end of the `.ulge` file immediately after the wrapped key data. After the flight, the `.ulge` file containing both the wrapped symmetric key and the encrypted log data can be found on the SD card. @@ -356,26 +356,26 @@ This section explains how you might manually run the same steps as the script (s 2. Use OpenSSL to generate a RSA2048 private and public key: - ```sh - openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 - ``` + ```sh + openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 + ``` 3. Create a public key from this private key: - ```sh - # Convert private_key.pem to a DER file - openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der - # From the DER file, generate a public key in hex format, separated by commas - xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub - ``` + ```sh + # Convert private_key.pem to a DER file + openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der + # From the DER file, generate a public key in hex format, separated by commas + xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub + ``` 4. Copy the keys into the appropriate locations expected by the rest of the toolchain (as shown in previous section). 5. To use this key, modify your `.px4board` file to point `CONFIG_PUBLIC_KEY1` to the file location of `public_key.pub`. - ```sh - CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" - ``` + ```sh + CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" + ``` ## Flight Review & Encrypted logs @@ -397,10 +397,10 @@ This can use logs that you have downloaded and decrypted yourself, or you can in 3. Add this key location into the server config file: `flight_review/app/config_default.ini`. - The line to add should look something like this (for the file above): + The line to add should look something like this (for the file above): - ```sh - ulge_private_key = ../private_key/private_key.pem - ``` + ```sh + ulge_private_key = ../private_key/private_key.pem + ``` 4. Follow the Flight Review Instructions to start your server. diff --git a/docs/uk/dev_log/logging.md b/docs/uk/dev_log/logging.md index 600c0c3f1d..7b5da1b821 100644 --- a/docs/uk/dev_log/logging.md +++ b/docs/uk/dev_log/logging.md @@ -33,16 +33,17 @@ 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. Параметри, які ви найімовірніше зміните, перераховані нижче. -| Параметр | Опис | -| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [SDLOG_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Журналювання. Defines when logging starts and stops.
- `-1`: Logging disabled.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `4`: Log from first armed until shutdown. | -| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_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".
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_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Журналювання. Defines when logging starts and stops.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `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.
- bit `0`: SD card logging.
- bit `1`: Mavlink logging. | +| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_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".
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. | Корисні налаштування для конкретних випадків: - Raw sensor data for comparison: [SDLOG_MODE=1](../advanced_config/parameter_reference.md#SDLOG_MODE) and [SDLOG_PROFILE=64](../advanced_config/parameter_reference.md#SDLOG_PROFILE). -- Disabling logging altogether: [SDLOG_MODE=`-1`](../advanced_config/parameter_reference.md#SDLOG_MODE) +- Disabling logging altogether: [SDLOG_BACKEND=`0`](../advanced_config/parameter_reference.md#SDLOG_BACKEND) ### Модуль реєстрації @@ -159,7 +160,7 @@ If you have concerns about a particular card you can run the above test and repo - If log streaming does not start, make sure the `logger` is running (see above), and inspect the console output while starting. - Якщо це все ще не працює, переконайтеся, що використовується MAVLink 2. - Enforce it by setting `MAV_PROTO_VER` to 2. + `MAV_PROTO_VER` needs to be set to 2. - Log streaming uses a maximum of 70% of the configured MAVLink rate (`-r` parameter). Якщо потрібно більше, повідомлення видаляються. The currently used percentage can be inspected with `mavlink status` (1.8% is used in this example): diff --git a/docs/uk/dev_log/ulog_file_format.md b/docs/uk/dev_log/ulog_file_format.md index 212f3acdd5..f091e3af8c 100644 --- a/docs/uk/dev_log/ulog_file_format.md +++ b/docs/uk/dev_log/ulog_file_format.md @@ -218,7 +218,7 @@ A key defined in the Information message must be unique. Означає, що н | `char[value_len] ver_sw_branch` | git branch | "master" | | `uint32_t ver_sw_release` | Версія програмного забезпечення (див. нижче) | 0x010401ff | | `char[value_len] sys_os_name` | Назва операційної системи | "Linux" | -| `char[value_len] sys_os_ve`r | Версія ОС (git tag) | "9f82919" | +| `char[value_len] sys_os_ver` | Версія ОС (git tag) | "9f82919" | | `uint32_t ver_os_release` | Версія ОС (див. нижче) | 0x010401ff | | `char[value_len] sys_toolchain` | Назва набору інструментів | "GNU GCC" | | `char[value_len] sys_toolchain_ver` | Версія інструментального набору | "6.2.1" | @@ -491,6 +491,7 @@ struct message_dropout_s { - [replay module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/replay) - [hardfault_log module](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hardfault_log): append hardfault crash data. - [pyulog](https://github.com/PX4/pyulog): python, ULog reader and writer library with CLI scripts. + The project also has tools to convert ULog to rosbag and other formats. - [ulog_cpp](https://github.com/PX4/ulog_cpp): C++, ULog reader and writer library. - [FlightPlot](https://github.com/PX4/FlightPlot): Java, log plotter. - [MAVLink](https://github.com/mavlink/mavlink): Messages for ULog streaming via MAVLink (note that appending data is not supported, at least not for cut off messages). @@ -501,6 +502,7 @@ struct message_dropout_s { - [ulogreader](https://github.com/maxsun/ulogreader): Javascript, ULog reader and parser outputs log in JSON object format. - [Foxglove](https://foxglove.dev): an integrated visualization and diagnosis tool for robotics data that supports ULog files. - [TypeScript ULog parser](https://github.com/foxglove/ulog): TypeScript, ULog reader that outputs JS objects. +- [yule_log](https://crates.io/crates/yule_log): A streaming ULog parser written in Rust. ## Історія версій формату файлу diff --git a/docs/uk/dev_setup/dev_env.md b/docs/uk/dev_setup/dev_env.md index 46bcc54138..6a23af23fa 100644 --- a/docs/uk/dev_setup/dev_env.md +++ b/docs/uk/dev_setup/dev_env.md @@ -2,22 +2,22 @@ The _supported platforms_ for PX4 development are: -- [Ubuntu Linux (22.04/20.04/18.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended +- [Ubuntu Linux (24.04/22.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended - [Windows (10/11)](../dev_setup/dev_env_windows_wsl.md) — via WSL2 -- [Mac OS](../dev_setup/dev_env_mac.md) +- [macOS](../dev_setup/dev_env_mac.md) ## Цільові платформи що підтримуються Таблиця нижче показує, які цільові платформи PX4 можна побудувати на кожній ОС. -| Цільова платформа | Linux (Ubuntu) | Mac | 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 | ✓ | | ✓ | +| Цільова платформа | 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 | ✓ | | ✓ | Experienced Docker users can also build with the containers used by our continuous integration system: [Docker Containers](../test_and_ci/docker.md) diff --git a/docs/uk/dev_setup/dev_env_linux_ubuntu.md b/docs/uk/dev_setup/dev_env_linux_ubuntu.md index 7d8fd2f2a2..efe9dcce63 100644 --- a/docs/uk/dev_setup/dev_env_linux_ubuntu.md +++ b/docs/uk/dev_setup/dev_env_linux_ubuntu.md @@ -33,24 +33,24 @@ The script is intended to be run on _clean_ Ubuntu LTS installations, and may no 1. [Download PX4 Source Code](../dev_setup/building_px4.md): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 2. Run the **ubuntu.sh** with no arguments (in a bash shell) to install everything: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - - При появі підказки по ходу виконання скрипту підтвердить вибір. - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - При появі підказки по ходу виконання скрипту підтвердить вибір. + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. 3. If you need Gazebo Classic (Ubuntu 22.04 only) then you can manually remove Gazebo and install it by following the instructions in [Gazebo Classic > Installation](../sim_gazebo_classic/index.md#installation). diff --git a/docs/uk/dev_setup/dev_env_mac.md b/docs/uk/dev_setup/dev_env_mac.md index 83af592c2e..214f44b7f3 100644 --- a/docs/uk/dev_setup/dev_env_mac.md +++ b/docs/uk/dev_setup/dev_env_mac.md @@ -1,4 +1,4 @@ -# Середовище розробки MacOS +# macOS Development Environment Наступні інструкції для встановлення середовища розробки PX4 для macOS. Це середовище може бути використане для збірки PX4 для: @@ -22,8 +22,8 @@ To build other targets you will need to use a [different OS](../dev_setup/dev_en ### Налаштування середовища :::details -Apple Silicon Macbook users! -If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 by setting up an x86 terminal: +Apple Silicon MacBook users! +If you have an Apple M1, M2 etc. MacBook, make sure to run the terminal as x86 by setting up an x86 terminal: 1. Locate the Terminal application within the Utilities folder (**Finder > Go menu > Utilities**) 2. Select _Terminal.app_ and right-click on it, then choose **Duplicate**. @@ -38,21 +38,21 @@ If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 b 1. Enable more open files by appending the following line to the `~/.zshenv` file (creating it if necessary): - ```sh - echo ulimit -S -n 2048 >> ~/.zshenv - ``` + ```sh + echo ulimit -S -n 2048 >> ~/.zshenv + ``` - ::: info - If you don't do this, the build toolchain may report the error: `"LD: too many open files"` + ::: info + If you don't do this, the build toolchain may report the error: `"LD: too many open files"` ::: 2. Enforce Python 3 by appending the following lines to `~/.zshenv` - ```sh - # Point pip3 to MacOS system python 3 pip - alias pip3=/usr/bin/pip3 - ``` + ```sh + # Point pip3 to macOS system python 3 pip + alias pip3=/usr/bin/pip3 + ``` ### Загальні інструменти @@ -62,19 +62,19 @@ If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 b 2. Виконайте ці команди в командній оболонці для встановлення загальних інструментів: - ```sh - brew tap PX4/px4 - brew install px4-dev - ``` + ```sh + brew tap PX4/px4 + brew install px4-dev + ``` 3. Встановіть необхідні пакети Python: - ```sh - # install required packages using pip3 - python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - # if this fails with a permissions error, your Python install is in a system path - use this command instead: - sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - ``` + ```sh + # install required packages using pip3 + python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + # if this fails with a permissions error, your Python install is in a system path - use this command instead: + sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + ``` ## Симуляція Gazebo Classic @@ -82,35 +82,35 @@ To setup the environment for [Gazebo Classic](../sim_gazebo_classic/index.md) si 1. Виконайте наступні команди в командній оболонці: - ```sh - brew unlink tbb - sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb - brew install tbb@2020 - brew link tbb@2020 - ``` + ```sh + brew unlink tbb + sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb + brew install tbb@2020 + brew link tbb@2020 + ``` - ::: info - September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). - Вони можуть бути видалені після того, як вона буде виправлена (разом з цією нотаткою). + ::: info + September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). + Вони можуть бути видалені після того, як вона буде виправлена (разом з цією нотаткою). ::: 2. Для встановлення симуляції SITL з Gazebo Classic: - ```sh - brew install --cask temurin - brew install --cask xquartz - brew install px4-sim-gazebo - ``` + ```sh + brew install --cask temurin + brew install --cask xquartz + brew install px4-sim-gazebo + ``` 3. Run the macOS setup script: `PX4-Autopilot/Tools/setup/macos.sh` - The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: + The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - cd PX4-Autopilot/Tools/setup - sh macos.sh - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + cd PX4-Autopilot/Tools/setup + sh macos.sh + ``` ## Наступні кроки diff --git a/docs/uk/dev_setup/dev_env_windows_cygwin_packager_setup.md b/docs/uk/dev_setup/dev_env_windows_cygwin_packager_setup.md index b670ce7d51..c5c774c644 100644 --- a/docs/uk/dev_setup/dev_env_windows_cygwin_packager_setup.md +++ b/docs/uk/dev_setup/dev_env_windows_cygwin_packager_setup.md @@ -135,31 +135,31 @@ The toolchain gets maintained and hence these instructions might not cover every 10. Download [**Apache Ant**](https://ant.apache.org/bindownload.cgi) as zip archive of the binaries for Windows and unpack the content to the folder `C:\PX4\toolchain\apache-ant`. - :::tip - Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. + :::tip + Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. ::: - ::: info - This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). + ::: info + This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). ::: 11. Download, build and add _genromfs_ to the path: - - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with + - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with ```sh cd /c/toolchain/genromfs git clone https://github.com/chexum/genromfs.git genromfs-src ``` - - Скомпілюйте це: + - Скомпілюйте це: ```sh cd genromfs-src make all ``` - - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** + - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** 12. Make sure all the binary folders of all the installed components are correctly listed in the `PATH` variable configured by [**setup-environment.bat**](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/scripts/setup-environment.bat). diff --git a/docs/uk/dev_setup/dev_env_windows_vm.md b/docs/uk/dev_setup/dev_env_windows_vm.md index 26be70156b..93d09b3593 100644 --- a/docs/uk/dev_setup/dev_env_windows_vm.md +++ b/docs/uk/dev_setup/dev_env_windows_vm.md @@ -57,12 +57,12 @@ Allocate as many CPU cores and memory resources to the VM as possible. Запам'ятайте, всі налаштування потрібні тільки для використання у вашій основній операційній системі, тому можна вимкнути будь-який режим збереження екрана та функції безпеки локальні робочої станції, що не збільшують ризик мережевої атаки. 10. Once the new VM is booted up make sure you install _VMWare tools drivers and tools extension_ inside your guest system. - Це підвищить продуктивність та зручність користування віртуальною машиною: - - Значно поліпшена продуктивність графіки - - Належна підтримка використання апаратного забезпечення, наприклад розподілу портів USB (важливо для завантаження прошивок), прокручування коліщатком миші, підтримка звуку - - Адаптація роздільної здатності дисплею гостя до розміру вікна емулятора - - Спільний доступ до буфера обміну з основної ОС - - Спільний доступ до файлів з основної ОС + Це підвищить продуктивність та зручність користування віртуальною машиною: + - Значно поліпшена продуктивність графіки + - Належна підтримка використання апаратного забезпечення, наприклад розподілу портів USB (важливо для завантаження прошивок), прокручування коліщатком миші, підтримка звуку + - Адаптація роздільної здатності дисплею гостя до розміру вікна емулятора + - Спільний доступ до буфера обміну з основної ОС + - Спільний доступ до файлів з основної ОС 11. Continue with [PX4 environment setup for Linux](../dev_setup/dev_env_linux.md) @@ -96,11 +96,11 @@ One limitation of virtual machines is that you can't automatically connect to a 4. Add USB filters for the bootloader in VM: **VirtualBox > Settings > USB > Add new USB filter**. - Відкрийте меню і під'єднайте USB-кабель, підключений до автопілота. - Select the `...Bootloader` device when it appears in the UI. + Select the `...Bootloader` device when it appears in the UI. - ::: info - The bootloader device only appears for a few seconds after connecting USB. - Якщо він зникає до того як ви змогли обрати його, від'єднайте та повторно під'єднайте USB. + ::: info + The bootloader device only appears for a few seconds after connecting USB. + Якщо він зникає до того як ви змогли обрати його, від'єднайте та повторно під'єднайте USB. ::: diff --git a/docs/uk/dev_setup/dev_env_windows_wsl.md b/docs/uk/dev_setup/dev_env_windows_wsl.md index f11402c430..7d475f32f0 100644 --- a/docs/uk/dev_setup/dev_env_windows_wsl.md +++ b/docs/uk/dev_setup/dev_env_windows_wsl.md @@ -33,7 +33,7 @@ _QGroundControl for Windows_ is additionally required if you need to: Note that you can also use it to monitor a simulation, but you must manually [connect to the simulation running in WSL](#qgroundcontrol-on-windows). :::info -Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. +Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. ::: :::info @@ -48,38 +48,38 @@ The approach is similar to installing PX4 in your _own_ virtual machine, as desc Щоб встановити WSL2 з Ubuntu на новій установці Windows 10 або 11: 1. Переконайтеся, що функція віртуалізації увімкнена в BIOS вашого комп'ютера. - Зазвичай її називають "Virtualization Technology", "Intel VT-x" чи "AMD-V" відповідно. + Зазвичай її називають "Virtualization Technology", "Intel VT-x" чи "AMD-V" відповідно. 2. Open _cmd.exe_ as administrator. - This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. + This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. 3. Виконайте наступні команди для встановлення WSL2 та певної версії Ubuntu: - - Версія за замовчуванням (Ubuntu 22.04): + - Версія за замовчуванням (Ubuntu 22.04): - ```sh - wsl --install - ``` + ```sh + wsl --install + ``` - - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) + - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) - ```sh - wsl --install -d Ubuntu-20.04 - ``` + ```sh + wsl --install -d Ubuntu-20.04 + ``` - - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) + - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) - ```sh - wsl --install -d Ubuntu-22.04 - ``` + ```sh + wsl --install -d Ubuntu-22.04 + ``` - ::: info - You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: + ::: info + You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: ::: 4. WSL запитає про ім'я користувача та пароль для встановлення Ubuntu. - Запишіть ці облікові дані, оскільки вони знадобляться пізніше! + Запишіть ці облікові дані, оскільки вони знадобляться пізніше! Тепер командний рядок є терміналом в нововстановленому середовищі Ubuntu. @@ -94,26 +94,26 @@ If you're using [Windows Terminal](https://learn.microsoft.com/en-us/windows/ter Щоб відкрити оболонку WSL за допомогою командного рядка: 1. Відкрийте командний рядок: - - Press the Windows **Start** key. - - Type `cmd` and press **Enter** to open the prompt. + - Press the Windows **Start** key. + - Type `cmd` and press **Enter** to open the prompt. 2. Щоб запустити WSL і отримати доступ до WSL оболонки, виконайте команду: - ```sh - wsl -d - ``` + ```sh + wsl -d + ``` - Наприклад: + Наприклад: - ```sh - wsl -d Ubuntu - ``` + ```sh + wsl -d Ubuntu + ``` - ```sh - wsl -d Ubuntu-20.04 - ``` + ```sh + wsl -d Ubuntu-20.04 + ``` - If you only have one version of Ubuntu, you can just use `wsl`. + If you only have one version of Ubuntu, you can just use `wsl`. Введіть наступні команди, щоб спочатку закрити WSL оболонку, а потім завершити WSL: @@ -135,57 +135,57 @@ This will install the toolchain for Gazebo Classic simulation and Pixhawk/NuttX 2. Execute the command `cd ~` to switch to the home folder of WSL for the next steps. - :::warning - This is important! - Якщо ви працюєте за межами файлової системи WSL, то ви стикнетесь з такими проблемами, як дуже повільне виконання та помилки прав доступу/дозволів. + :::warning + This is important! + Якщо ви працюєте за межами файлової системи WSL, то ви стикнетесь з такими проблемами, як дуже повільне виконання та помилки прав доступу/дозволів. ::: 3. Download the PX4 source code using `git` (which is already installed in WSL2): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 4. Run the **ubuntu.sh** installer script and acknowledge any prompts as the script progresses: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - ::: info - This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: + ::: info + This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. - - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). ::: 5. Перезапустіть "комп'ютер WSL" після завершення скрипту (вийти з оболонки, вимкнути WSL та перезапустити WSL): - ```sh - exit - wsl --shutdown - wsl - ``` + ```sh + exit + wsl --shutdown + wsl + ``` 6. Перейдіть в репозиторій PX4 в домашній директорії WSL: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 7. Зберіть ціль PX4 SITL та перевірте середовище: - ```sh - make px4_sitl - ``` + ```sh + make px4_sitl + ``` For more build options see [Building PX4 Software](../dev_setup/building_px4.md). @@ -205,26 +205,26 @@ VS Code на Windows добре інтегрований з WSL. 5. У WSL оболонці перейдіть у директорію PX4: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 6. В оболонці WSL запустіть VS Code: - ```sh - code . - ``` + ```sh + code . + ``` - Це відкриє IDE повністю інтегроване в WSL оболонку. + Це відкриє IDE повністю інтегроване в WSL оболонку. - Переконайтеся, що ви завжди відкриваєте PX4 репозиторій у режимі Remote WSL. + Переконайтеся, що ви завжди відкриваєте PX4 репозиторій у режимі Remote WSL. 7. Next time you want to develop WSL2 you can very easily open it again in Remote WSL mode by selecting **Open Recent** (as shown below). - Це запустить WSL. + Це запустить WSL. - ![](../../assets/toolchain/vscode/vscode_wsl.png) + ![](../../assets/toolchain/vscode/vscode_wsl.png) - Зверніть увагу, що IP-адреса віртуальної машини WSL буде змінена, так що ви не зможете контролювати симуляцію з QGC для Windows (ви все ще можете використовувати QGC для Linux) + Зверніть увагу, що IP-адреса віртуальної машини WSL буде змінена, так що ви не зможете контролювати симуляцію з QGC для Windows (ви все ще можете використовувати QGC для Linux) ## QGroundControl @@ -240,21 +240,21 @@ If you need to [flash a flight control board](#flash-a-flight-control-board) wit 1. In a web browser, navigate to the QGC [Ubuntu download section](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#ubuntu) 2. Right-click on the **QGroundControl.AppImage** link, and select "Copy link address". - This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ + This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ 3. [Open a WSL shell](#opening-a-wsl-shell) and enter the following commands to download the appimage and make it executable (replace the AppImage URL where indicated): - ```sh - cd ~ - wget - chmod +x QGroundControl.AppImage - ``` + ```sh + cd ~ + wget + chmod +x QGroundControl.AppImage + ``` 4. Запустіть QGroundControl: - ```sh - ./QGroundControl.AppImage - ``` + ```sh + ./QGroundControl.AppImage + ``` QGroundControl запуститься та автоматично приєднається до запущеної симуляції, що дозволить вам спостерігати та контролювати ваші рухомі засоби. @@ -270,15 +270,15 @@ Install [QGroundControl on Windows](https://docs.qgroundcontrol.com/master/en/qg 2. Check the IP address of the WSL virtual machine by running the command `ip addr | grep eth0`: - ```sh - $ ip addr | grep eth0 + ```sh + $ ip addr | grep eth0 - 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 - inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 - ``` + 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 + ``` - Copy the first part of the `eth0` interface `inet` address to the clipboard. - In this case: `172.18.46.131`. + Copy the first part of the `eth0` interface `inet` address to the clipboard. + In this case: `172.18.46.131`. 3. In QGC go to **Q > Application Settings > Comm Links** @@ -304,14 +304,14 @@ Instead you connect [QGroundControl for Windows](#qgroundcontrol-on-windows) to 1. If you haven't already built the binary in WSL e.g. with a [WSL shell](dev_env_windows_wsl.md#opening-a-wsl-shell) and by running: - ```sh - cd ~/PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + cd ~/PX4-Autopilot + make px4_fmu-v5 + ``` - ::: tip - Use the correct `make` target for your board. - `px4_fmu-v5` can be used for a Pixhawk 4 board. + ::: tip + Use the correct `make` target for your board. + `px4_fmu-v5` can be used for a Pixhawk 4 board. ::: @@ -325,12 +325,12 @@ Instead you connect [QGroundControl for Windows](#qgroundcontrol-on-windows) to 6. Continue and select the firmware binary you just built in WSL. - У відкритому діалозі знайдіть розташування "Linux" з іконкою пінгвіна на лівій панелі. - Зазвичай, вона в самому низу. - Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` + У відкритому діалозі знайдіть розташування "Linux" з іконкою пінгвіна на лівій панелі. + Зазвичай, вона в самому низу. + Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` - ::: info - You can add the folder to the favourites to access it quickly next time. + ::: info + You can add the folder to the favourites to access it quickly next time. ::: @@ -349,3 +349,9 @@ sudo add-apt-repository ppa:kisak/kisak-mesa sudo apt update sudo apt upgrade ``` + +### QGroundControl not connecting to PX4 SITL + +- The connection between PX4 SITL on WSL2 and QGroundControl on Windows requires [broadcasting](../simulation/index.md#enable-udp-broadcasting) or [streaming to a specific address](../simulation/index.md#enable-streaming-to-specific-address) to be enabled. + Streaming to a specific address should be enabled by default, but is something to check if a connection can't be established. +- Network traffic might be blocked by firewall or antivirus on you system. diff --git a/docs/uk/dev_setup/vscode.md b/docs/uk/dev_setup/vscode.md index 89cca6f8e7..99b6ba7618 100644 --- a/docs/uk/dev_setup/vscode.md +++ b/docs/uk/dev_setup/vscode.md @@ -27,10 +27,10 @@ You must already have installed the command line [PX4 developer environment](../ - Select _Open folder ..._ option on the welcome page (or using the menu: **File > Open Folder**): - ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) + ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) - З'явиться діалогове вікно вибору файлу. - Select the **PX4-Autopilot** directory and then press **OK**. + Select the **PX4-Autopilot** directory and then press **OK**. The project files and configuration will then load into _VSCode_. @@ -49,9 +49,9 @@ You must already have installed the command line [PX4 developer environment](../ ::: - 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)). + - 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: - - Це ваш розсуд! Це забезпечує глибоку інтеграцію між Github та IDE, що може спростити ваш робочий процес. + - Це ваш розсуд! Це забезпечує глибоку інтеграцію між Github та IDE, що може спростити ваш робочий процес. - Інші підказки необов'язкові та можуть бути встановлені, якщо вважаються корисними. @@ -63,21 +63,21 @@ You must already have installed the command line [PX4 developer environment](../ 1. Оберіть свою ціль збірки ("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). - ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) + ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) - ::: info - The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). + ::: info + The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). ::: - Натисніть на ціль на панелі config, щоб показати інші параметри та вибрати ту, яка вам потрібна (це замінить обрану ціль). - _Cmake_ will then configure your project (see notification in bottom right). - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) - Зачекайте, поки налаштування завершиться. - When this is done the notification will disappear and you'll be shown the build location: - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). + When this is done the notification will disappear and you'll be shown the build location: + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). 2. You can then kick off a build from the config bar (select either **Build** or **Debug**). ![Run debug or build](../../assets/toolchain/vscode/run_debug_build.jpg) diff --git a/docs/uk/dronecan/ark_cannode.md b/docs/uk/dronecan/ark_cannode.md index 07b6da9458..69cc232ce6 100644 --- a/docs/uk/dronecan/ark_cannode.md +++ b/docs/uk/dronecan/ark_cannode.md @@ -83,9 +83,10 @@ This is done using the the parameters named like `UAVCAN_SUB_*` in the parameter На ARK CANnode вам може знадобитися налаштувати наступні параметри: -| Параметр | Опис | -| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | ## Значення LED індикаторів diff --git a/docs/uk/dronecan/ark_dist.md b/docs/uk/dronecan/ark_dist.md new file mode 100644 index 0000000000..831ab3f783 --- /dev/null +++ b/docs/uk/dronecan/ark_dist.md @@ -0,0 +1,98 @@ +# ARK DIST SR + +ARK DIST SR is a low range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). +It has an approximate range of between 8cm to 30m. + +![ARK DIST SR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-sr/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- Датчики + - [Broadcom AFBR-S50LV85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lv85d) + - Типовий діапазон відстані до 30м + - Інтегроване джерело світла лазера 850 нм + - Поле зору (FoV) 12,4° x 6,2° з 32 пікселями + - Робота в умовах 200 тис. люксів світла навколишнього середовища + - Reference Pixel for system health monitoring + - Добре працює на всіх поверхнях + - Трансмітер пучка 2° x 2° для підсвічування між 1 та 3 пікселями +- Два роз'єми стандарту CAN для Pixhawk (4 контакти JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Роз'єм для відлагодження стандарту Pixhawk (6 контактів JST SH) +- Малий форм-фактор + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED індикатори +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5v + - 84mA Average + - 86mA Max + +## Налаштування програмного забезпечення + +### Підключення + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Налаштування прошивки + +ARK DIST SR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## Конфігурація PX4 + +### DroneCAN + +#### Увімкнути DroneCAN + +Кроки наступні: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `30`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## Дивіться також + +- [ARK DIST SR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/uk/dronecan/ark_dist_mr.md b/docs/uk/dronecan/ark_dist_mr.md new file mode 100644 index 0000000000..442f95ef8f --- /dev/null +++ b/docs/uk/dronecan/ark_dist_mr.md @@ -0,0 +1,97 @@ +# ARK DIST MR + +ARK DIST MR is a mid range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). + +![ARK DIST MR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-mr/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- Датчики + - [Broadcom AFBR-S50LX85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lx85d) + - Typical distance range up to 50m + - Інтегроване джерело світла лазера 850 нм + - Поле зору (FoV) 12,4° x 6,2° з 32 пікселями + - Робота в умовах 200 тис. люксів світла навколишнього середовища + - Reference Pixel for system health monitoring + - Добре працює на всіх поверхнях + - Трансмітер пучка 2° x 2° для підсвічування між 1 та 3 пікселями +- Два роз'єми стандарту CAN для Pixhawk (4 контакти JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Роз'єм для відлагодження стандарту Pixhawk (6 контактів JST SH) +- Малий форм-фактор + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED індикатори +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5v + - 78mA Average + - 84mA Max + +## Налаштування програмного забезпечення + +### Підключення + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Налаштування прошивки + +ARK DIST MR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## Конфігурація PX4 + +### DroneCAN + +#### Увімкнути DroneCAN + +Кроки наступні: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `50`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## Дивіться також + +- [ARK DIST MR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/uk/dronecan/ark_flow.md b/docs/uk/dronecan/ark_flow.md index 9f17cc3100..9dedb670c7 100644 --- a/docs/uk/dronecan/ark_flow.md +++ b/docs/uk/dronecan/ark_flow.md @@ -94,6 +94,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -109,9 +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: -| Параметр | Опис | -| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | ## Значення LED індикаторів diff --git a/docs/uk/dronecan/ark_flow_mr.md b/docs/uk/dronecan/ark_flow_mr.md index 2b374b5b9f..8eefc718fb 100644 --- a/docs/uk/dronecan/ark_flow_mr.md +++ b/docs/uk/dronecan/ark_flow_mr.md @@ -91,6 +91,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -104,9 +105,10 @@ 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: -| Параметр | Опис | -| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. | ## Значення LED індикаторів diff --git a/docs/uk/dronecan/ark_g5_rtk_gps.md b/docs/uk/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..60bd410a64 --- /dev/null +++ b/docs/uk/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Характеристики обладнання + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Датчики + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Кнопка безпеки +- Зумер +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED індикатори + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5V + - 270mA +- Розміри + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Налаштування програмного забезпечення + +### Підключення + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Налаштування прошивки + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## Значення LED індикаторів + +The GPS status lights are located to the right of the connectors: + +- Миготіння зеленого - це фіксація GPS +- Миготіння синього - це отримані корекції та RTK Float +- Сталий синій - це RTK зафіксовано + +## Дивіться також + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/ark_g5_rtk_heading_gps.md b/docs/uk/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..80e1d471e6 --- /dev/null +++ b/docs/uk/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Характеристики обладнання + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- Датчики + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Кнопка безпеки +- Зумер +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED індикатори + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- NDAA Compliant +- Вимоги до живлення + - 5V + - 270mA +- Розміри + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## Налаштування програмного забезпечення + +### Підключення + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Налаштування прошивки + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## Значення LED індикаторів + +The GPS status lights are located to the right of the connectors: + +- Миготіння зеленого - це фіксація GPS +- Миготіння синього - це отримані корекції та RTK Float +- Сталий синій - це RTK зафіксовано + +## Дивіться також + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/ark_gps.md b/docs/uk/dronecan/ark_gps.md index 1320fb7057..3283dd252b 100644 --- a/docs/uk/dronecan/ark_gps.md +++ b/docs/uk/dronecan/ark_gps.md @@ -91,9 +91,17 @@ DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enablin - Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` if this is that last node on the CAN bus. - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK GPS from the vehicles centre of gravity. +### ARK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK GPS itself: + +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. Set to `1` if this is the last node on the CAN bus. | + ## Значення LED індикаторів Ви побачите зелені, сині та червоні світлодіоди на ARK GPS під час прошивки, а також мигаючий зелений світлодіод, якщо все працює належним чином. diff --git a/docs/uk/dronecan/ark_rtk_gps.md b/docs/uk/dronecan/ark_rtk_gps.md index 091365f591..7eb7c9b050 100644 --- a/docs/uk/dronecan/ark_rtk_gps.md +++ b/docs/uk/dronecan/ark_rtk_gps.md @@ -20,6 +20,7 @@ - Багатосмуговий RTK зі швидкими часами збіжності та надійною продуктивністю - Висока швидкість оновлення для високодинамічних додатків - Centimetre accuracy in a small and energy efficient module + - Moving Base for Heading - Bosch BMM150 Magnetometer - Bosch BMP388 Barometer - Invensense ICM-42688-P 6-Axis IMU @@ -27,7 +28,7 @@ - Кнопка безпеки - Зумер - Два роз'єми стандарту CAN для Pixhawk (4 контакти JST GH) -- Роз'єм F9P "UART 2" +- F9P `UART 2` Connector - 3-контактний JST-GH - TX, RX, GND - Роз'єм для відлагодження стандарту Pixhawk (6 контактів JST SH) @@ -85,7 +86,34 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if - Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS from the vehicles centre of gravity. -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` on the GPS if this it that last node on the CAN bus. + +### ARK RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS itself: + +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. Set to `1` if this is the last node on the CAN bus. | + +### Setting Up Rover and Fixed Base + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +Параметри PX4 DroneCAN: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. ### Setting Up Moving Baseline & GPS Heading @@ -128,10 +156,11 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if - On the _Moving Base_, set the following: - [GPS_UBX_MODE](../advanced_config/parameter_reference.md#GPS_UBX_MODE) to `2`. +For more information see [Rover and Moving Base](../dronecan/index.md#rover-and-moving-base) in the DroneCAN guide. + ## Значення LED індикаторів - Світлодіоди статусу GPS розташовані праворуч від роз'ємів - - Миготіння зеленого - це фіксація GPS - Миготіння синього - це отримані корекції та RTK Float - Сталий синій - це RTK зафіксовано diff --git a/docs/uk/dronecan/ark_rtk_gps_l1_l2.md b/docs/uk/dronecan/ark_rtk_gps_l1_l2.md new file mode 100644 index 0000000000..5d01c4f326 --- /dev/null +++ b/docs/uk/dronecan/ark_rtk_gps_l1_l2.md @@ -0,0 +1,163 @@ +# ARK RTK GPS L1 L5 + +[ARK RTK GPS L1 L5](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox F9P](https://www.u-blox.com/en/product/zed-f9p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK RTK GPS L1 L5](../../assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-rtk-gps-l1-l5/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- Датчики + - Ublox F9P GPS + - Multi-band GNSS receiver delivers centimetre level accuracy in seconds + - Одночасний прийом GPS, GLONASS, Galileo та BeiDou + - Багатосмуговий RTK зі швидкими часами збіжності та надійною продуктивністю + - Висока швидкість оновлення для високодинамічних додатків + - Centimetre accuracy in a small and energy efficient module + - Does not Support Moving Base for Heading + - Bosch BMM150 Magnetometer + - Bosch BMP388 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412CEU6 MCU +- Кнопка безпеки +- Зумер +- Два роз'єми стандарту CAN для Pixhawk (4 контакти JST GH) +- F9P `UART 2` Connector + - 3-контактний JST-GH + - TX, RX, GND +- Роз'єм для відлагодження стандарту Pixhawk (6 контактів JST SH) +- LED індикатори + - Індикатор безпеки + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- Вимоги до живлення + - 5V + - Середній струм 170мA + - 180мА Макс + +## Налаштування програмного забезпечення + +### Підключення + +The ARK RTK GPS L1 L5 is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Налаштування прошивки + +ARK RTK GPS L1 L5 runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK RTK GPS L1 L5 boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK RTK GPS L1 L5, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK RTK GPS L1 L5 CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. +Дані GPS повинні надходити з частотою 10 Гц. + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS L1 L5 from the vehicles centre of gravity. + +### ARK RTK GPS L1 L5 Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS L1 L5 itself: + +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. Set to `1` if this is the last node on the CAN bus. | + +### Setting Up Rover and Fixed Base + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +Параметри PX4 DroneCAN: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## Значення LED індикаторів + +- Світлодіоди статусу GPS розташовані праворуч від роз'ємів + - Миготіння зеленого - це фіксація GPS + - Миготіння синього - це отримані корекції та RTK Float + - Сталий синій - це RTK зафіксовано + +- Світлодіоди статусу CAN розташовані зверху ліворуч від роз'ємів + - Повільне блимання зеленого - чекає на підключення CAN + - Швидко блимаюче зелене світло - нормальна робота + - Повільне блимання зеленим і синім - перелік CAN + - Fast blinking blue and red is firmware update in progress + - Миготливий червоний - помилка + - Якщо ви бачите червоний світлодіод, це означає, що виникла помилка, і вам слід перевірити наступне + - Переконайтеся, що у польотному контролері встановлено SD-картку + - Make sure the ARK RTK GPS L1 L5 has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Видаліть бінарні файли з кореневих та ufw директорій SD-карти та спробуйте зібрати та знову прошити + +### Оновлення модуля Ublox F9P + +ARK RTK GPS L1 L5 comes with the Ublox F9P module up to date with version 1.13 or newer. Проте ви можете перевірити версію та оновити прошивку за бажанням. + +Кроки наступні: + +1. [Download u-center from u-blox.com](https://www.u-blox.com/en/product/u-center) and install on your PC (Windows only) +2. Open the [u-blox ZED-F9P website](https://www.u-blox.com/en/product/zed-f9p-module#tab-documentation-resources) +3. Прокрутіть вниз і клацніть на поле "Show Legacy Documents" +4. Прокрутіть вниз ще раз до Оновлення прошивки та завантажте потрібну прошивку (потрібна версія не нижче 1.13) +5. While holding down the safety switch on the ARK RTK GPS L1 L5, connect it to power via one of its CAN ports and hold until all 3 LEDs blink rapidly +6. Connect the ARK RTK GPS L1 L5 to your PC via its debug port with a cable such as the Black Magic Probe or an FTDI +7. Open u-center, select the COM port for the ARK RTK GPS L1 L5 and connect + ![U-Center Connect](../../assets/hardware/gps/ark/ark_rtk_gps_ucenter_connect.png) +8. Check the current firmware version by selecting View, Messages View, UBX, MON, VER + ![Check Version](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_version.png) +9. Для оновлення прошивки: + 1. Виберіть Tools, Firmware Update + 2. Поле зображення прошивки повинно бути файлом .bin, завантаженим зі сторінки веб-сайту u-blox ZED-F9P + 3. Поставте прапорець "Використовувати цю швидкість передачі для оновлення" та виберіть 115200 зі списку + 4. Переконайтеся, що інші прапорці відображаються так, як показано нижче + 5. Натисніть зелену кнопку GO внизу зліва + 6. "Firmware Update SUCCESS" should be displayed if it updated successfully + ![Firmware Update](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_f9p_firmware_update.png) + +## Дивіться також + +- [ARK RTK GPS L1 L5 Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/ark_x20_rtk_gps.md b/docs/uk/dronecan/ark_x20_rtk_gps.md new file mode 100644 index 0000000000..d4d6bf1654 --- /dev/null +++ b/docs/uk/dronecan/ark_x20_rtk_gps.md @@ -0,0 +1,141 @@ +# ARK X20 RTK GPS + +[ARK X20 RTK GPS](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox ZED-X20P all-band high precision GNSS module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK X20 RTK GPS](../../assets/hardware/gps/ark/ark_x20_rtk_gps.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-x20-rtk-gps/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- Датчики + - Ublox ZED-X20P + - All-band all constellation GNSS receiver + - Best position accuracy and availability in different environments + - RTK, PPP-RTK and PPP algorithms expanding the limits of performance + - Highest quality GNSS raw data + - u-blox end-to-end hardened security + - 25Hz update rate + - ST IIS2MDC Magnetometer + - Bosch BMP390 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412VGH6 MCU +- Кнопка безпеки +- Зумер +- Два роз'єми стандарту CAN для Pixhawk (4 контакти JST GH) +- X20 “UART 2” Connector + - 4-контактний JST-GH + - TX, RX, PPS, GND +- I2C Expansion Connector + - 4-контактний JST-GH + - 5.0V, SCL, SDA, GND +- Роз'єм для відлагодження стандарту Pixhawk (6 контактів JST SH) +- LED індикатори + - Індикатор безпеки + - GPS Fix + - Статус RTK + - RGB Статус системи +- USA Built +- Вимоги до живлення + - 5V + - 144mA Average + - 157mA Max + +## Налаштування програмного забезпечення + +### Підключення + +The ARK X20 RTK GPS is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Встановлення + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Налаштування прошивки + +ARK X20 RTK GPS runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK X20 RTK GPS boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Налаштування польотного контролера + +### Увімкнення DroneCAN + +In order to use the ARK X20 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +Кроки наступні: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK X20 RTK GPS CAN to the Pixhawk CAN. + +Після активації модуль буде виявлено при завантаженні. +Дані GPS повинні надходити з частотою 10 Гц. + +### Конфігурація PX4 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK X20 RTK GPS from the vehicles centre of gravity. + +### ARK X20 RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK X20 RTK GPS itself: + +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | Вбудована завершення шини CAN. Set to `1` if this is the last node on the CAN bus. | + +### Setting Up Rover and Fixed Base + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +Параметри PX4 DroneCAN: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## Значення LED індикаторів + +- Світлодіоди статусу GPS розташовані праворуч від роз'ємів + - Миготіння зеленого - це фіксація GPS + - Миготіння синього - це отримані корекції та RTK Float + - Сталий синій - це RTK зафіксовано + +- Світлодіоди статусу CAN розташовані зверху ліворуч від роз'ємів + - Повільне блимання зеленого - чекає на підключення CAN + - Швидко блимаюче зелене світло - нормальна робота + - Повільне блимання зеленим і синім - перелік CAN + - Fast blinking blue and red is firmware update in progress + - Миготливий червоний - помилка + - Якщо ви бачите червоний світлодіод, це означає, що виникла помилка, і вам слід перевірити наступне + - Переконайтеся, що у польотному контролері встановлено SD-картку + - Make sure the ARK X20 RTK GPS has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Видаліть бінарні файли з кореневих та ufw директорій SD-карти та спробуйте зібрати та знову прошити + +## Дивіться також + +- [ARK X20 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) (ARK Docs) diff --git a/docs/uk/dronecan/escs.md b/docs/uk/dronecan/escs.md index f37cd1a66b..9b1d1b748b 100644 --- a/docs/uk/dronecan/escs.md +++ b/docs/uk/dronecan/escs.md @@ -1,7 +1,14 @@ # DroneCAN ESCs -PX4 підтримує ESCs, які відповідають стандарту DroneCAN. -Для отримання додаткової інформації дивіться наступні статті для конкретного обладнання/прошивки: +PX4 supports DroneCAN compliant ESCs. + +## Supported ESC + +:::info +[Supported ESCs](../peripherals/esc_motors#supported-esc) in _ESCs & Motors_ may include additional devices that are not listed below. +::: + +The following articles have specific hardware/firmware information: - [PX4 Sapog ESC Firmware](sapog.md) - [Holybro Kotleta 20](holybro_kotleta.md) @@ -9,3 +16,18 @@ PX4 підтримує ESCs, які відповідають стандарту - [Vertiq](../peripherals/vertiq.md) (larger modules) - [VESC Project](../peripherals/vesc.md) - [RaccoonLab Cyphal and DroneCAN PWM nodes](raccoonlab_nodes.md) + +## Конфігурація апаратного забезпечення + +General DroneCAN hardware configuration is covered in [DroneCAN > Hardware Setup](../dronecan/index.md#hardware-setup). + +DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + +## Конфігурація PX4 + +DroneCAN peripherals are configured by following the procedure outlined in [DroneCAN](../dronecan/index.md). + +In addition to the general setup, such as setting `UAVCAN_ENABLE` to `3`: + +- Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +- Configure the [motor order and servo outputs](../config/actuators.md). diff --git a/docs/uk/dronecan/holybro_h_rtk_zed_f9p_gps.md b/docs/uk/dronecan/holybro_h_rtk_zed_f9p_gps.md index be65191b50..c164a5607a 100644 --- a/docs/uk/dronecan/holybro_h_rtk_zed_f9p_gps.md +++ b/docs/uk/dronecan/holybro_h_rtk_zed_f9p_gps.md @@ -64,10 +64,10 @@ To update the "AP Periph" firmware to the latest version: 1. [Download the latest binary](https://firmware.ardupilot.org/AP_Periph/latest/HolybroG4_GPS/). 2. Update the firmware using either of the following approaches: - - Using ArduPilot: - 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. - 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. - - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). + - Using ArduPilot: + 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. + 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. + - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). Remember to change the firmware on the flight controller back to PX4 afterwards. @@ -98,14 +98,14 @@ In order to use dual ZED-F9P GPS heading in PX4, follow these steps: 1. Open the QGroundControl parameters page. 2. On the left side next to the parameters list, double-click on the _System_ section (this hides the section). 3. Components should be visible on the left panel. - Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). + Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). 4. 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 - - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. - This is the local offset (FRD) with respect to the autopilot. + - `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 + - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. + This is the local offset (FRD) with respect to the autopilot. ![QGC Setup](../../assets/hardware/gps/holybro_h_rtk_zed_f9p_rover/holybro_f9p_gps_qgc_setup.png) diff --git a/docs/uk/dronecan/index.md b/docs/uk/dronecan/index.md index 25902f61fa..14d8abc6c1 100644 --- a/docs/uk/dronecan/index.md +++ b/docs/uk/dronecan/index.md @@ -27,6 +27,8 @@ DroneCAN was previously known as UAVCAN v0 (or just UAVCAN). - Проводка менше складна, оскільки ви можете мати один шину для підключення всіх ваших ESC і інших периферійних пристроїв DroneCAN. - Налаштування стає простіше, оскільки ви налаштовуєте нумерацію ESC, обертаючи кожен двигун вручну. - Це дозволяє користувачам налаштовувати та оновлювати прошивку всіх пристроїв, підключених через CAN, централізовано через PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## Підтримуване обладнання @@ -67,6 +69,8 @@ DroneCAN was previously known as UAVCAN v0 (or just UAVCAN). - [RaccoonLab RM3100 Magnetometer](https://docs.raccoonlab.co/guide/gps_mag_baro/mag_rm3100.html) - Датчики відстані + - [ARK Dist](ark_dist.md) + - [Ark Dist MR](ark_dist_mr.md) - [ARK Flow](ark_flow.md) - [Ark Flow MR](ark_flow_mr.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface](../dronecan/avanon_laser_interface.md) @@ -102,6 +106,10 @@ If you wish to disable the DNA completely, set `UAVCAN_ENABLE` to `1` and manual :::info The PX4 node ID can be configured using the [UAVCAN_NODE_ID](../advanced_config/parameter_reference.md#UAVCAN_NODE_ID) parameter. Параметр за замовчуванням встановлено на 1. + +Devices running the [PX4 DroneCAN firmware](px4_cannode_fw.md) (such as [ARK CANnode](ark_cannode.md)) can use the +[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter to set a static node ID. +Set it to 0 (default) for dynamic allocation, or to a value between 1-127 to use a specific static node ID. ::: :::warning @@ -276,6 +284,9 @@ If the rangefinder is connected via DroneCAN (whether inbuilt or separate), you [DroneCAN ESCs and servos](../dronecan/escs.md) require the [motor order and servo outputs](../config/actuators.md) to be configured. +Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +Note that DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + ## Налаштування параметрів CANNODE QGC QGroundControl може переглядати та змінювати параметри, що належать до пристроїв CAN, підключених до автопілота, за умови, що пристрої підключені до автопілота до запуску QGC. @@ -285,6 +296,11 @@ For example, the screenshot below shows the parameters for a CAN GPS with node i ![QGC Parameter showing selected DroneCAN node](../../assets/can/dronecan/qgc_can_parameters.png) +Common CANNODE parameters that you can configure include: + +- [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID): Set a static node ID (1-127) or use 0 for dynamic allocation. See [PX4 DroneCAN Firmware > Static Node ID](px4_cannode_fw.md#static-node-id) for more information. +- [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM): Enable CAN bus termination on the last node in the bus. + ## Налаштування пристрою Більшість вузлів DroneCAN не потребують додаткової настройки, якщо це не вказано у їх документації, специфічній для пристрою. @@ -313,7 +329,10 @@ If successful, the firmware binary will be removed from the root directory and t **Q**: The motors aren't spinning when armed. -**A**: Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +**A**: + +- Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +- Make sure `UAVCAN_ESC_IFACE` is set to enable the CAN interface(s) used for ESCs. --- diff --git a/docs/uk/dronecan/pomegranate_systems_pm.md b/docs/uk/dronecan/pomegranate_systems_pm.md index 9fb4005b6e..e0d75858ab 100644 --- a/docs/uk/dronecan/pomegranate_systems_pm.md +++ b/docs/uk/dronecan/pomegranate_systems_pm.md @@ -45,11 +45,11 @@ Source code and build instructions can be found on [the bitbucket](https://bitbu 1. Enable DroneCAN by setting the [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) parameter to `2` (Sensors Automatic Config) or `3`. 2. Enable DroneCAN battery monitoring by setting [UAVCAN_SUB_BAT](../advanced_config/parameter_reference.md#UAVCAN_SUB_BAT) to `1` or `2` ( depending on your battery). 3. Set the following module parameters using the [MAVLink console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - - Battery capacity in mAh: `battery_capacity_mAh` - - Battery voltage when _full_: `battery_full_V`, - - Battery voltage when _empty_: `battery_empty_V` - - Turn on current integration: `enable_current_track` - - (optional) Turn Off CANbus termination resistor :`enable_can_term` + - Battery capacity in mAh: `battery_capacity_mAh` + - Battery voltage when _full_: `battery_full_V`, + - Battery voltage when _empty_: `battery_empty_V` + - Turn on current integration: `enable_current_track` + - (optional) Turn Off CANbus termination resistor :`enable_can_term` **Example:** A Power Module with UAVCAN node id `125` connected to a `3S` LiPo with capacity of `5000mAh` can be configured with the following commands: diff --git a/docs/uk/dronecan/px4_cannode_fw.md b/docs/uk/dronecan/px4_cannode_fw.md index 12e6a028cf..83ffba7e03 100644 --- a/docs/uk/dronecan/px4_cannode_fw.md +++ b/docs/uk/dronecan/px4_cannode_fw.md @@ -20,6 +20,26 @@ make ark_can-flow_default This will create an output in **build/ark_can-flow_default** named **XX-X.X.XXXXXXXX.uavcan.bin**. Follow the instructions at [DroneCAN firmware update](index.md#firmware-update) to flash the firmware. +## Налаштування + +### Static Node ID + +By default, DroneCAN devices use [Dynamic Node Allocation (DNA)](index.md#node-id-allocation) to automatically obtain a unique node ID from the flight controller. +However, you can configure a static node ID using the [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter. + +To configure a static node ID: + +1. Set [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) to a value between 1-127 using [QGroundControl](index.md#qgc-cannode-parameter-configuration) +2. Reboot the device + +To return to dynamic allocation, set `CANNODE_NODE_ID` back to 0. +Note that when switching back to dynamic allocation, the flight controller will typically continue to allocate the same node ID that was previously used (this is normal DNA behavior). + +:::warning +When using static node IDs, you must ensure that each device on the CAN bus has a unique node ID. +Configuring two devices with the same ID will cause communication conflicts. +::: + ## Інформація для розробників Цей розділ містить інформацію, яка є актуальною для розробників, які хочуть додати підтримку нового апаратного забезпечення DroneCAN до автопілота PX4. diff --git a/docs/uk/dronecan/raccoonlab_power.md b/docs/uk/dronecan/raccoonlab_power.md index dba00914ee..7e903d0809 100644 --- a/docs/uk/dronecan/raccoonlab_power.md +++ b/docs/uk/dronecan/raccoonlab_power.md @@ -7,9 +7,9 @@ CAN power connectors are designed for light unmanned aerial (UAV) and other vehi There are two types of devices: 1. `CAN-MUX` devices provide power from XT30 connector to CAN. - There are 2 variation of this type of the device with different number of connectors. + There are 2 variation of this type of the device with different number of connectors. 2. `Power connector node` is designed to pass current (up to 60A) to power load and CAN, measure voltage and current on load. - It behaves as Cyphal/DroneCAN node. + It behaves as Cyphal/DroneCAN node. Please refer to the RaccoonLab docs [CAN Power Connectors](https://docs.raccoonlab.co/guide/pmu/power/) page. diff --git a/docs/uk/esc/ark_4in1_esc.md b/docs/uk/esc/ark_4in1_esc.md new file mode 100644 index 0000000000..bde32573bf --- /dev/null +++ b/docs/uk/esc/ark_4in1_esc.md @@ -0,0 +1,65 @@ +# ARK 4IN1 ESC (with/without Connectors) + +4 in 1 Electronic Speed Controller (ESC) that is made in the USA, NDAA compliant, and DIU Blue Framework listed. + +The ESC comes in variants without connectors that you can solder in place, and a variant that has built-in motor and battery connectors (no soldering required). + +![ARK 4IN1 ESC without connectors ](../../assets/hardware/esc/ark/ark_4_in_1_esc.jpg)![ARK 4IN1 ESC with connectors](../../assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg) + +## Де купити + +Замовте цей модуль з: + +- [4IN1 ESC (with connectors)](https://arkelectron.com/product/ark-4in1-esc/) (ARK Electronics - US) +- [ARK Electronics (without connectors)](https://arkelectron.com/product/ark-4in1-esc-cons/) (ARK Electronics US) + +## Характеристики обладнання + +- Battery Voltage: 3-8s + - 6V Minimum + - 65V Absolute Maximum + +- Current Rating: 50A Continuous, 75A Burst Per Motor + +- [STM32F0](https://www.st.com/en/microcontrollers-microprocessors/stm32f0-series.html) + +- [AM32 Firmware](https://github.com/am32-firmware/AM32/pull/27) + +- Onboard Current Sensor, Serial Telemetry + - 100V/A + +- Input Protocols + - DShot (300, 600) + - Bi-directional DShot + - KISS Serial Telemetry + - PWM + +- 8 Pin JST-SH Input/Output + +- 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 + +- Dimensions (without connectors) + - Size: 43.00mm x 40.50mm x 7.60mm + - Mounting Pattern: 30.5mm + - Weight: 14.5g + +Інше + +- Made in the USA +- Open source AM32 firmware +- [DIU Blue Framework Listed](https://www.diu.mil/blue-uas/framework) + +## Дивіться також + +- [ARK 4IN1 ESC CONS](https://docs.arkelectron.com/electronic-speed-controller/ark-4in1-esc) (ARK Docs) diff --git a/docs/uk/esc/esc_protocols.md b/docs/uk/esc/esc_protocols.md new file mode 100644 index 0000000000..930d436de6 --- /dev/null +++ b/docs/uk/esc/esc_protocols.md @@ -0,0 +1,66 @@ +# ESC Protocols + +This topic lists the main [Electronic Speed Controller (ESC)](../peripherals/esc_motors.md) protocols supported by PX4. + +## DShot + +[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduced latency, in particular racing multicopters, VTOL vehicles, and so on. + +It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). +In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can reverse motor spin directions. + +PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). +Selecting a higher rate DShot ESC in the UI results in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. + +## DroneCAN + +[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. +The PX4 implementation is currently limited to update rates of 200 Hz. + +DroneCAN shares many similar benefits to [DShot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. + +[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). + +## PWM + +[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). + +PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired speed. +The pulse width typically ranges between 1000 μs for zero power and 2000 μs for full power. +The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50 Hz and 490 Hz (the theoretical maximum being 500 Hz for a very small "off" cycle). +A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. +For PWM servos 50 Hz is usually sufficient, and many don't support higher rates. + +![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) + +In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the pulse widths representing low and high values can vary significantly. +Unlike [DShot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) +- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) + +## OneShot 125 + +[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. +They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). +There are a number of variants of the OneShot protocol, which support different rates. +PX4 only supports OneShot 125. + +OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125 μs to 250 μs for zero to full power). +This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. +For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. +The actual supported rate depends on the ESC used. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) diff --git a/docs/uk/features_fw/gain_compression.md b/docs/uk/features_fw/gain_compression.md new file mode 100644 index 0000000000..1e97f1eb18 --- /dev/null +++ b/docs/uk/features_fw/gain_compression.md @@ -0,0 +1,24 @@ +# Gain compression + + + +Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. +It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. + +This approach is a safe adaptive mechanism for stable aircraft: the PID gains remain unchanged when no oscillations are present, they are never increased beyond their nominal values, and they are bounded by a minimum limit. + +Gain compression can help prevent actuator damage and even loss of the vehicle in cases such as airspeed-sensor failure (loss of airspeed scaling) or in-flight changes in dynamics (e.g.: CG shifts, inertia changes), or other failures that could cause the angular-rate loop to become oscillatory. + +![Gain compression diagram](../../assets/config/fw/gain_compression_diagram.png) + +## Використання + +Gain compression is enabled by default ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)). + +It should be disabled during fixed wing [manual tuning](../config_fw/pid_tuning_guide_fixedwing.md) to avoid over-tuning. +It does not need to be disabled when autotuning. + +## Параметри + +- [FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN) +- [FW_GC_GAIN_MIN](../advanced_config/parameter_reference.md#FW_GC_GAIN_MIN) diff --git a/docs/uk/features_fw/index.md b/docs/uk/features_fw/index.md new file mode 100644 index 0000000000..7eab8e9c6c --- /dev/null +++ b/docs/uk/features_fw/index.md @@ -0,0 +1,5 @@ +# Fixedwing-Specific Features + +This section lists features that are specific to (or customised for) fixed-wings: + +- [Gain Compression](../features_fw/gain_compression.md) diff --git a/docs/uk/flight_controller/accton-godwit_ga1.md b/docs/uk/flight_controller/accton-godwit_ga1.md new file mode 100644 index 0000000000..5b014c8452 --- /dev/null +++ b/docs/uk/flight_controller/accton-godwit_ga1.md @@ -0,0 +1,153 @@ +# Accton Godwit G-A1 + +:::warning +PX4 не розробляє цей (або будь-який інший) автопілот. +Contact the [manufacturer](https://cubepilot.org/#/home) for hardware support or compliance issues. +::: + +The G-A1 is a state-of-the-art flight controller developed derived from the [Pixhawk Autopilot v6X Standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-012%20Pixhawk%20Autopilot%20v6X%20Standard.pdf). + +It includes an STM32H753 double-precision floating-point FMU processor and an STM32F103 IO coprocessor, multiple IMUs with 6-axis inertial sensors, two pressure/temperature sensors, and a geomagnetic sensor. +It also has independent buses and power supplies, and is designed for safety and rich expansion capabilities. + +With an integrated 10/100M Ethernet Physical Layer (PHY), the G-A1 can also communicate with a mission computer (airborne computer), high-end surveying and mapping cameras, and other UxV-mounted equipment for high-speed communications, meeting the needs of advanced UxV systems. + +:::tip +Visit [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) for more information. +::: + +![AccGodwitGA1](../../assets/flight_controller/accton-godwit/ga1/outlook.png "Accton Godwit G-A1") + +![AccGodwitGA1 Top View](../../assets/flight_controller/accton-godwit/ga1/orientation.png "Accton Godwit G-A1 Top View") + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## Характеристики + +### Процесор + +- STM32H753IIK (Arm® Cortex®-M7 480MHz) +- STM32F103 (Arm® Cortex®-M3, 72MHz) + +### Датчики + +- Bosch BMI088 (vibration isolated) +- TDK InvenSense ICM-42688-P x 2 (one vibration isolated) +- TDK Barometric Pressure and Temperature Sensor CP-20100 x 2 (one vibration isolated) +- PNI RM3100 Geomagnetic Sensor (vibration isolated) + +### Power + +- 4.6V to 5.7V + +### External ports + +- 2 CAN Buses (CAN1 and CAN2) +- 3 TELEM Ports (TELEM1, TELEM2 and TELEM3) +- 2 GPS Ports (GPS1 with safety switch, LED, buzzer, and GPS2) +- 1 PPM IN +- 1 SBUS OUT +- 2 USB Ports (1 TYPE-C and 1 JST GH1.25) +- 1 10/100Base-T Ethernet Port +- 1 DSM/SBUS RC +- 1 UART 4 +- 1 AD&IO Port +- 2 Debug Ports (1 IO Debug and 1 FMU Debug) +- 1 SPI6 Bus +- 4 Power Inputs (Power 1, Power 2, Power C1 and Power C2) +- 16 PWM Servo Outputs (A1-A8 from FMU and M1-M8 from IO) +- Micro SD Socket (supports SD 4.1 & SDIO 4.0 in two databus modes: 1 bit (default) and 4 bits) + +### Size and Dimensions + +- 92.2 (L) x 51.2 (W) x 28.3 (H) mm +- 77.6g (carrier board with IMU) + +## Де купити + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) + +## Схема розташування виводів + +![G-A1 Pin definition](../../assets/flight_controller/accton-godwit/ga1/pin_definition.png "G-A1 Pin definition") + +## UART Mapping + +| Serial# | Протокол | Порт | Примітки | +| ------- | --------- | ------ | ---------- | +| SERIAL1 | Telem1 | UART7 | /dev/ttyS6 | +| SERIAL2 | Telem2 | UART5 | /dev/ttyS4 | +| SERIAL3 | GPS1 | USART1 | /dev/ttyS0 | +| SERIAL4 | GPS2 | UART8 | /dev/ttyS7 | +| SERIAL5 | Telem3 | USART2 | /dev/ttyS1 | +| SERIAL6 | UART4 | UART4 | /dev/ttyS3 | +| SERIAL7 | FMU Debug | USART3 | | +| SERIAL8 | OTG2 | USB | | + +## Wiring Diagram + +![G-A1 Wiring](../../assets/flight_controller/accton-godwit/ga1/wiring.png "G-A1 Wiring") + +## PWM Output + +PWM M1-M8 (IO Main PWM), A1-A8(FMU PWM). +All these 16 support normal PWM output formats. +FMU PWM A1-A6 can support DShot and B-Directional DShot. +A1-A8(FMU PWM) are grouped as: + +- Group 1: A1, A2, A3, A4 +- Group 2: A5, A6 +- Group 3: A7, A8 + +The motor and servo system should be connected to these ports according to the order outlined in the fuselage reference for your carrier. + +![G-A1 PWM Motor Servo](../../assets/flight_controller/accton-godwit/ga1/motor_servo.png "G-A1 PWM Motor Servo") + +## RC-вхід + +For DSM/SBUS receivers, connect them to the DSM/SBUS interface which provides dedicated 3.3V and 5V power pins respectively, and check above "Pinout" for detailed pin definition. +PPM receivers should be connected to the PPM interface. And other RC systems can be connected via other spare telemetry ports. + +![G-A1 Radio](../../assets/flight_controller/accton-godwit/ga1/radio.png "G-A1 Radio") + +## GPS/компас + +The Godwit G-A1 has a built-in compass +Due to potential interference, the autopilot is usually used with an external I2C compass as part of a GPS/Compass combination. + +![G-A1 GPS](../../assets/flight_controller/accton-godwit/ga1/gps.png "G-A1 GPS") + +## Power Connection and Battery Monitor + +This universal controller features a CAN PMU module that supports 3 to 14s lithium batteries. +To ensure proper connection, attach the module's 6-pin connector to the flight control Power C1 and/or Power C2 interface. + +This universal controller does not provide power to the servos. +To power them, an external BEC must be connected to the positive and negative terminals of any A1–A8 or M1–M8 port. + +![G-A1 Power](../../assets/flight_controller/accton-godwit/ga1/power.png "G-A1 Power") + +## SD-карта + +The SD card is NOT included in the package, you need to prepare the SD card and insert it into the slot. + +![G-A1 SD Card](../../assets/flight_controller/accton-godwit/ga1/sdcard.png "G-A1 SD Card") + +## Прошивка + +The autopilot is compatible with PX4 firmware. And G-A1 can be detected by QGroundControl automatically. Users can also build it with target "accton-godwit_ga1" + +To [build PX4](../dev_setup/building_px4.md) for this target, open up the terminal and enter: + +```sh +make accton-godwit_ga1 +``` + +## More Information and Support + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) +- [support@accton-iot.com](mailto:support@accton-iot.com) diff --git a/docs/uk/flight_controller/autopilot_manufacturer_supported.md b/docs/uk/flight_controller/autopilot_manufacturer_supported.md index 189c41cb0e..9401665369 100644 --- a/docs/uk/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/uk/flight_controller/autopilot_manufacturer_supported.md @@ -12,6 +12,7 @@ This category includes boards that are not fully compliant with the pixhawk stan Плати цієї категорії: +- [Accton Godwit GA1](../flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](../flight_controller/mindpx.md) - [AirMind MindRacer](../flight_controller/mindracer.md) - [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) (and [ARK Electronics Pixhawk Autopilot Bus Carrier](../flight_controller/ark_pab.md)) @@ -29,9 +30,13 @@ This category includes boards that are not fully compliant with the pixhawk stan - [Holybro Kakute H7](../flight_controller/kakuteh7.md) - [Holybro Durandal](../flight_controller/durandal.md) - [Holybro Pix32 v5](../flight_controller/holybro_pix32_v5.md) +- [MicoAir H743 Lite](../flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](../flight_controller/modalai_voxl_2.md) - [mRo Control Zero](../flight_controller/mro_control_zero_f7.md) +- [Radiolink PIX6](../flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](../flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](../flight_controller/spracingh7extreme.md) +- [Svehicle E2](../flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](../flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](../flight_controller/thepeach_r1.md) +- [X-MAV AP-H743-R1](../flight_controller/x-mav_ap-h743r1.md) diff --git a/docs/uk/flight_controller/micoair743-lite.md b/docs/uk/flight_controller/micoair743-lite.md new file mode 100644 index 0000000000..d98d3a1d30 --- /dev/null +++ b/docs/uk/flight_controller/micoair743-lite.md @@ -0,0 +1,153 @@ +# MicoAir743-Lite + + + +:::warning +PX4 не розробляє цей (або будь-який інший) автопілот. +Contact the [manufacturer](https://micoair.com/) for hardware support or compliance issues. +::: + +MicoAir743-Lite is an ultra-high performance H743 flight controller with an unbeatable price, featuring the ICM45686 IMU sensor and integrated Bluetooth telemetry. + +![MicoAir743-Lite Front View](../../assets/flight_controller/micoair743_lite/front_view.png) + +Equipped with a high-performance H7 processor, the MicoAir743-Lite features a compact form factor with SH1.0 connectors (which are more suitable than Pixhawk-standard GH1.25 for this board size). +When paired with with Bluetooth telemetry, the board can be debugged with a phone or PC. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## MicoAir743-Lite (v1.1) + +![MicoAir743-Lite Back View](../../assets/flight_controller/micoair743_lite/back_view.png) + +## Короткий опис + +### Processors & Sensors + +- FMU Processor: STM32H743 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- Сенсори на платі + - Accel/Gyro: ICM-45686 (with BalancedGyro™ Technology) + - Barometer: SPA06 +- On-board Bluetooth Telemetry + - Connected to UART8 internally, baudrate 115200 + - Connecting to QGC (PC or Android phone) via Bluetooth +- Інші характеристики: + - Operating & storage temperature: -20 ~ 85°c + +### Інтерфейси + +- 8 UART (TELEM / GPS / RC) +- 14 PWM outputs (10 supports DShot) +- Support multiple RC inputs (SBUS / CRSF / DSM) +- 1 GPS port +- 1 I2C порт +- 2 ADC port2 (VBAT, Current) +- 1 DJI O3/O4 VTX connector +- 1 MicroSD Card Slot +- 1 USB Type-C + +### Електричні дані + +- VBAT Input: + - 2\~6S (6\~27V) +- USB Power Input: + - 4.75\~5.25V +- BEC Output: + - 5V 2A (for controller, receiver, GPS, optical flow or other devices) + - 9V 2A (for video transmitter, camera) + +### Механічні характеристики + +- Mounting: 30.5 x 30.5mm, Φ4mm +- Dimensions: 36 x 36 x 8 mm +- Weight: 10g + +![MicoAir743-Lite Size](../../assets/flight_controller/micoair743_lite/size.png) + +## Де купити + +Order from [MicoAir Tech Store](https://store.micoair.com/product/micoair743-lite/). + +## Схема розташування виводів + +Pinouts definition can be found in the [MicoAir743-Lite_pinout.xlsx](https://raw.githubusercontent.com/PX4/PX4-Autopilot/refs/heads/main/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx) file. + +## Налаштування послідовного порту + +| UART | Пристрій | Порт | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | TELEM1 | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | GPS1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART5 | /dev/ttyS4 | TELEM3 | +| USART6 | /dev/ttyS5 | RC | +| UART7 | /dev/ttyS6 | URT6 | +| UART8 | /dev/ttyS7 | TELEM4 | + +## Interfaces Diagram + +:::note +All the connectors used on the board are SH1.0 +::: + +![MicoAir743-Lite Interface Diagram](../../assets/flight_controller/micoair743_lite/interfaces_diagram.png) + +## Зразок схеми з'єднань + +![MicoAir743-Lite Wiring Diagram](../../assets/flight_controller/micoair743_lite/wiring_diagram.png) + +## Збірка прошивки + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make micoair_h743-lite_default +``` + +## Встановлення прошивки PX4 + +Прошивку можна встановити будь-якими звичайними способами: + +- Збудуйте та завантажте джерело + + ```sh + make micoair_h743-lite_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + Ви можете використовувати або готове вбудоване програмне забезпечення, або власне користувацьке програмне забезпечення. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## Радіоуправління + +A [Radio Control (RC) system](../getting_started/rc_transmitter_receiver.md) is required if you want to manually control your vehicle (PX4 does not require a radio system for autonomous flight modes). + +The RC port is connected to the FMU and you can attach a receiver that uses the protocols `DSM`, `SBUS`, `CSRF`, `GHST`, or other protocol listed in [Radio Control modules](../modules/modules_driver_radio_control.md). +You will need to enable the protocol by setting the corresponding parameter `RC_xxxx_PRT_CFG`, such as [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) for a [CRSF receiver](../telemetry/crsf_telemetry.md). + +## Підтримувані платформи / Конструкції + +Будь-який мультикоптер / літак / наземна платформа / човен, який може керуватися звичайними RC сервоприводами або сервоприводами Futaba S-Bus. +The complete set of supported configurations can be seen in the [Airframes Reference](../airframes/airframe_reference.md). + +## Периферійні пристрої + +- [MicoAir Telemetry Radio Modules](https://micoair.com/radio_telemetry/) +- [MicoAir Optical & Range Sensor](https://micoair.com/optical_range_sensor/) +- [MicoAir GPS](https://micoair.com/gps/) +- [MicoAir ESC Modules](https://micoair.com/esc/) + +## Подальша інформація + +- [MicoAir Tech.](https://micoair.com/) +- [Details about MicoAir743-Lite](https://micoair.com/flightcontroller_micoair743lite/) +- [QGroundControl Download and Install](https://docs.qgroundcontrol.com/Stable_V5.0/en/qgc-user-guide/getting_started/download_and_install.html) diff --git a/docs/uk/flight_controller/modalai_voxl_2.md b/docs/uk/flight_controller/modalai_voxl_2.md index 36605f9784..0e4743b0d9 100644 --- a/docs/uk/flight_controller/modalai_voxl_2.md +++ b/docs/uk/flight_controller/modalai_voxl_2.md @@ -74,7 +74,6 @@ PX4 mainline supports VOXL 2 (board documentation [here](https://github.com/PX4/ ## Доступність -- [PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit) - [Starling 2](https://www.modalai.com/products/starling-2) - [Starling 2 MAX](https://www.modalai.com/products/starling-2-max) - [Sentinel Development Drone powered by VOXL 2](https://www.modalai.com/pages/sentinel) diff --git a/docs/uk/flight_controller/pixhawk_series.md b/docs/uk/flight_controller/pixhawk_series.md index 0753bcb5f8..81cece0209 100644 --- a/docs/uk/flight_controller/pixhawk_series.md +++ b/docs/uk/flight_controller/pixhawk_series.md @@ -100,6 +100,24 @@ PX4 _developers_ need to know the FMU version of their board, as this is require +### FMUv6 Comparison + +| Характеристика | **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× | + ### Ліцензування та товарні знаки Pixhawk project schematics and reference designs are licensed under [CC BY-SA 3](https://creativecommons.org/licenses/by-sa/3.0/legalcode). diff --git a/docs/uk/flight_controller/radiolink_pix6.md b/docs/uk/flight_controller/radiolink_pix6.md new file mode 100644 index 0000000000..b7475d5202 --- /dev/null +++ b/docs/uk/flight_controller/radiolink_pix6.md @@ -0,0 +1,347 @@ +# RadiolinkPIX6 Flight Controller + + + +:::warning +PX4 не розробляє цей (або будь-який інший) автопілот. +Contact the [manufacturer](https://radiolink.com.cn/) for hardware support or compliance issues. +::: + +Автопілот рекомендується для комерційної системної інтеграції, але також підходить для академічних досліджень і будь-якого іншого використання. + +![RadiolinkPIX6](http://www.radiolink.com.cn/firmware/wiki/RadiolinkPIX6/RadiolinkPIX6.png) + +The Radiolink PIX6 is a high-performance flight controller. +Featuring STM32F7 CPU, vibration isolation of IMUs, redundant IMUs, integrated OSD chip, IMU heating, and DShot. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## Короткий опис + +- Процесор + - 32-bit ARM Cortex M7 core with DPFPU - STM32F765VIT6 + - 216 MHz/512 KB RAM/2 MB Flash + - 32-bit IOMCU co-processor - STM32F100 + - 32KB FRAM - FM25V02A + - AT7456E OSD +- Датчики + - Bosh BMI088 IMU (accel, gyro) + - InvenSense ICM-42688 IMU (accel, gyro) + - SPA06 barometer + - IST8310 magnetometer +- Power + - SMBUS/I2C Power Module Inputs (I2C) + - voltage and current monitor inputs (Analog) +- Інтерфейси + - 16 PWM Outputs with independent power rail for external power source + - 5x UART serial ports, 2 with HW flow control + - Camera Input and Video Output + - PPM/SBUS input, DSM/SBUS input + - Вхід RSSI (ШІМ або напруга) + - I2C, SPI, 2x CAN, USB + - 3.3V and 6.6V ADC inputs + - Звуковий сигнал і захисний вимикач + - microSD card +- Вага та розміри: + - Weight 80g + - Size 94mm x 51.5mm x 14.5mm + +## Де купити + +[Radiolink Amazon](https://www.radiolink.com.cn/pix6_where_to_buy)(International users) + +[Radiolink Taobao](https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bNMdSqV&ft=t&id=815993357068&skuId=5515756705284)(China Mainland user) + +## Призначення конекторів + +### Top View + +![Pix6 top view](../../assets/flight_controller/radiolink_pix6/top_view.png) + +### Left View + +![Pix6 left view](../../assets/flight_controller/radiolink_pix6/left_view.png) + +### Right View + +![Pix6 right view](../../assets/flight_controller/radiolink_pix6/right_view.png) + +### Rear View + +![Pix6 rear view](../../assets/flight_controller/radiolink_pix6/rear_view.png) + +## Схема розташування виводів + +Якщо не вказано інше, всі конектори - це JST GH. + +### TELEM1, TELEM2 порти + +| Pin | Сигнал | Вольтаж | +| --- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | CTS | +3.3V | +| 5 | RTS | +3.3V | +| 6 | GND | GND | + +### OSD + +| Pin | Сигнал | Вольтаж | +| --- | ------ | --------------------- | +| 1 | GND | GND | +| 2 | VOUT | +3.3V | +| 3 | VCC | +5V | +| 4 | GND | GND | +| 5 | VCC | +5V | +| 6 | VIN | +3.3V | + +### I2C port + +| Pin | Сигнал | Вольтаж | +| --- | ------ | -------------------------------------------------- | +| 1 | VCC | +5V | +| 2 | SCL | +3.3V (pullups) | +| 3 | SDA | +3.3V (pullups) | +| 4 | GND | GND | + +### CAN1, CAN2 ports + +| Pin | Сигнал | Вольтаж | +| --- | -------------------------- | ------- | +| 1 | VCC | +5V | +| 2 | CAN_H | +12V | +| 3 | CAN_L | +12V | +| 4 | GND | GND | + +### GPS1 порт + +| Pin | Сигнал | Вольтаж | +| --- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### GPS2 Port + +| Pin | Сигнал | Вольтаж | +| --- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### SPI + +| Pin | Сигнал | Вольтаж | +| --- | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | SPI_SCK | +3.3V | +| 3 | SPI_MISO | +3.3V | +| 4 | SPI_MOSI | +3.3V | +| 5 | !SPI_NSS1 | +3.3V | +| 6 | !SPI_NSS2 | +3.3V | +| 7 | DRDY | +3.3V | +| 8 | GND | GND | + +### POWER1 (HY2.0-6P) + +Port for analog power monitors. + +| Pin | Сигнал | Вольтаж | +| --- | ------- | ------------------------ | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | CURRENT | до +3.3V | +| 4 | VOLTAGE | до +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### POWER2 (HY2.0-6P) + +Port for digital (I2C) power monitor. + +| Pin | Сигнал | Вольтаж | +| --- | ------ | --------------------- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | SCL | +3.3V | +| 4 | SDA | +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### ADC 3.3V + +| Pin | Сигнал | Вольтаж | +| --- | ------- | --------------------------- | +| 1 | VCC | +5V | +| 2 | ADC IN1 | до +3.3V | +| 3 | GND | GND | +| 4 | ADC IN2 | up to +3.3v | +| 5 | GND | GND | + +### ADC 6.6V + +| Pin | Сигнал | Вольтаж | +| --- | ------ | -------------------------- | +| 1 | VCC | +5V | +| 2 | ADC IN | up to 6.6V | +| 3 | GND | GND | + +### USB remote port + +| Pin | Сигнал | Вольтаж | +| --- | ------- | --------------------- | +| 1 | USB VDD | +5V | +| 2 | DM | +3.3V | +| 3 | DP | +3.3V | +| 4 | GND | GND | + +### SWITCH + +| Pin | Сигнал | Вольтаж | +| --- | -------------------------------------------------------- | --------------------- | +| 1 | VCC | +3.3V | +| 2 | !IO_LED_SAFETY | GND | +| 3 | SAFETY | GND | + +### Buzzer port + +| Pin | Сигнал | Вольтаж | +| --- | ------- | ------- | +| 1 | VCC | +5V | +| 2 | BUZZER- | +5V | + +### Spektrum/DSM Port (PH1.25-3P) + +| Pin | Сигнал | Вольтаж | +| --- | ------ | --------------------- | +| 1 | VCC | +3.3V | +| 2 | GND | GND | +| 3 | Сигнал | +3.3V | + +### Debug port (SH1.0-8P) + +| Pin | Сигнал | Вольтаж | +| --- | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | FMU_SWCLK | +3.3V | +| 3 | FMU_SWDIO | +3.3V | +| 4 | TX(UART7) | +3.3V | +| 5 | RX(UART7) | +3.3V | +| 6 | IO_SWCLK | +3.3V | +| 7 | IO_SWDIO | +3.3V | +| 8 | GND | GND | + +## Збірка прошивки + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make radiolink_PIX6_default +``` + +## Встановлення прошивки PX4 + +Прошивку можна встановити будь-якими звичайними способами: + +- Збудуйте та завантажте джерело + + ```sh + make radiolink_PIX6_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + Ви можете використовувати або готове вбудоване програмне забезпечення, або власне користувацьке програмне забезпечення. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## Конфігурація PX4 + +In addition to the [basic configuration](../config/index.md), the following parameters are important: + +| Параметр | Налаштування | +| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG) | Це має бути вимкнено, оскільки у платі немає внутрішнього магніту. Ви можете активувати це, якщо приєднаєте зовнішній магніт. | + +### Powering the PIX6 + +The PIX6 has 2 dedicated power monitor ports, each with a 6 pin connector. +One is the Analog power monitor (`POWER1`), and the others is the I2C power monitor (`POWER2`). + +The power module that comes with the flight controller with a wide voltage input range of 2-12S (7.4-50.4V), a maximum detection current of 90A (single ESC maximum detection current is 22.5A), a BEC output voltage of 5.3±0.2V, and a BEC output current of 2A. + +![Radiolink power modules MODULES](../../assets/flight_controller/radiolink_pix6/radiolink_power_modules.png) + +The PIX6 also supports power modules from other manufacturers, such as [holybro_pm02d](../power_module/holybro_pm02d.md). + +## Recommended Accessories + +### GPS Modules + +Radiolink manufactures a variety of high-performance GPS,Dual Anti-interference Technology Worry-free of UAV High-power Image Transmission, High-Voltage Lines, or Other Strong Signal Interference. + +The PIX6 has 2 dedicated GPS ports, `GPS1` and `GPS2`, each with a 6 pin connector. + +Recommended modules include: + +- [Radiolink SE100](https://radiolink.com.cn/se100) +- [Radiolink TS100](https://radiolink.com.cn/ts100v2) +- [Radiolink RTK F9P](https://radiolink.com.cn/rtk_f9p) + +## Налаштування послідовного порту + +| UART | Пристрій | Порт | +| ------ | ---------- | --------------------------------------------- | +| UART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM1 (керування потоком) | +| USART3 | /dev/ttyS2 | TELEM2 (керування потоком) | +| UART4 | /dev/ttyS3 | GPS2 | +| UART7 | /dev/ttyS4 | Debug Console | +| UART8 | /dev/ttyS5 | PX4IO | + +## Analog inputs + +The Radiolink PIX6 has 3 analog inputs, one 6V tolerant and two 3.3V tolerant. + +- ADC Pin12 -> ADC 6.6V Sense +- ADC Pin4 -> ADC IN1 3.3V Sense +- ADC Pin13 -> ADC IN2 3.3V Sense + +## Радіоуправління + +A [Radio Control (RC)](../getting_started/rc_transmitter_receiver.md) system is required if you want to _manually_ control your vehicle (PX4 does not require a radio system for autonomous flight modes). + +Вам потрібно [вибрати сумісний передавач/приймач](../getting_started/rc_transmitter_receiver.md) і _зв'язати_ їх таким чином, щоб вони взаємодіяли (ознайомтеся з інструкціями, що додаються до вашого конкретного передавача/приймача). + +- Spektrum/DSM receivers connect to the **DSM/SBUS RC** input. +- PPM or SBUS receivers connect to the **RC IN** input port. +- CRSF receiver must be wired to a spare port (UART) on the Flight Controller. + Then you can bind the transmitter and receiver together. + +#### CRSF Parameter Configuration + +[Find and set](../advanced_config/parameters.md) the following parameters: + +1. Set [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) to the port that is connected to the CRSF receiver (such as `TELEM1`). + + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + + Немає потреби встановлювати швидкість передачі для порту, оскільки це налаштовано драйвером. + +2. Enable [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) to activate Crossfire telemetry. + +Для отримання додаткової інформації про вибір радіосистеми, сумісність приймача та зв'язок вашої передавача/приймача, див. статтю: [Пульт керування передавачів & приймачів](../getting_started/rc_transmitter_receiver.md). diff --git a/docs/uk/flight_controller/svehicle_e2.md b/docs/uk/flight_controller/svehicle_e2.md new file mode 100644 index 0000000000..5d3a4aa9a1 --- /dev/null +++ b/docs/uk/flight_controller/svehicle_e2.md @@ -0,0 +1,176 @@ +# S-Vehicle E2 + +:::warning +PX4 не розробляє цей (або будь-який інший) автопілот. +::: + +The _E2_ is an advanced autopilot manufactured by S-Vehicle®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![SVehicle-E2](../../assets/flight_controller/svehicle_e2/main.png) + +:::info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H753IIK6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- Сенсори на платі + - Акселератор/гіроскоп: BMI088 + - Accel/Gyro: ICM-42688-P + - Accel/Gyro: ICM-20649 + - Mag: RM3100 + - Барометр: 2x ICP-20100 + +### Інтерфейси + +- 14x PWM Servo Outputs +- 1x Dedicated R/C Input for Spektrum / DSM and S.Bus +- 1x Analog/PWM RSSI Input +- 2x TELEM Ports (with full flow control) +- 1x UART4 Port +- 2x GPS Ports + - 1x Full GPS plus Safety Switch Port (GPS1) + - 1x Basic GPS Port (with I2C, GPS2) +- 1x USB Port (TYPE-C) +- 1x Ethernet Port + - Transformerless application + - 100Mbps +- 3x I2C Bus Ports +- 1x SPI Bus + - 1x Chip Select Line + - 1x Data Ready Line + - 1x SPI Reset Line +- 2x CAN Ports +- 3x Power Input Ports + - ADC Power Input + - I2C Power Input + - DroneCAN/UAVCAN Power Input +- 2x AD Ports + - Analog Input (3.3V) + - Analog Input (6.6V - not supported by PX4) +- 1x Dedicated Debug Port + - FMU Debug + +## Purchase Channels + +Order from [S-Vehicle](https://svehicle.cn/). + +## Радіоуправління + +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). + +Вам буде потрібно вибрати сумісний передавач/приймач та потім зв'язати їх, щоб вони взаємодіяли (прочитайте інструкції, що додаються до вашого конкретного передавача/приймача). + +Spektrum/DSM receivers connect to the DSM/SBUS RC input. +PPM or SBUS receivers connect to the RC IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## Налаштування послідовного порту + +| UART | Пристрій | Порт | +| ------ | ---------- | ------------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | Debug Console | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | PX4IO/RC | +| UART7 | /dev/ttyS6 | TELEM1 | +| UART8 | /dev/ttyS7 | GPS2 | + +## PWM Output + +The E2-Plus flight controller supports up to 14 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 6 outputs (labelled 9 to 14) are the "auxiliary" outputs. +These are directly attached to the STM32H753 FMU controller . + +The 14 PWM outputs are: + +M1 - M8 are connected to the IOMCU +A1 - A6 are connected to the FMU + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 6 FMU PWM outputs are in 2 groups: + +A1 - A4 are in one group. +A5, A6 are in a 2nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Електричні дані + +- Номінальна напруга: + - Максимальна вхідна напруга: 5,7 В + - Вхід USB Power: 4.75~5.25V + - Вхід на серворейку: 0\~9.9В +- Номінальний струм: + - Комбінований обмежувач вихідного струму TELEM1 і GPS2: 1,5 А + - Комбінований обмежувач вихідного струму всіх інших портів: 1.5A + +## Battery Monitoring + +The board has connectors for 3 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN +- POWER3 -- I2C + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor and I2C defaults configured which is enabled. + +The default PDB included with the E2+ is analog and must be connected to `POWER1`. + +## Збірка прошивки + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make svehicle_e2_default +``` + +## Відладочний порт + +The [PX4 System Console](../debug/system_console.md) and [SWD Interface](../debug/swd_debug.md) operate on the **FMU Debug** port. + +| Pin | Сигнал | Вольтаж | +| -------------------------- | --------------------------------- | --------------------- | +| 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 | + +Інформацію про використання цього порту див: + +- [SWD Debug Port](../debug/swd_debug.md) +- [PX4 System Console](../debug/system_console.md) (Note, the FMU console maps to USART3). +- All ports use GH1.25 ,power ports use ports on E2 uses the 6 circuit [2.00mm Pitch CLIK-Mate Wire-to-Board PCB Receptacle](https://www.molex.com/en-us/products/part-detail/5024430670). + +## Схема розташування виводів + +![SVehicle-E2 Top Down Photo](../../assets/flight_controller/svehicle_e2/top.png) + +![SVehicle-E2 Bottom Photo](../../assets/flight_controller/svehicle_e2/back.jpeg) + +![SVehicle-E2 left Photo](../../assets/flight_controller/svehicle_e2/left.png) + +![SVehicle-E2 right Photo](../../assets/flight_controller/svehicle_e2/right.png) + +## Підтримувані платформи / Конструкції + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). diff --git a/docs/uk/flight_controller/x-mav_ap-h743r1.md b/docs/uk/flight_controller/x-mav_ap-h743r1.md new file mode 100644 index 0000000000..03f01f3ffd --- /dev/null +++ b/docs/uk/flight_controller/x-mav_ap-h743r1.md @@ -0,0 +1,147 @@ +# AP-H743-R1 Flight Controller + + + +:::warning +PX4 не розробляє цей (або будь-який інший) автопілот. +::: + +The AP-H743-R1 is an advanced autopilot manufactured by X-MAV®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png) + +:::info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H743VIT6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- Сенсори на платі + - Accel/Gyro: ICM-42688-P\*2(Version1), BMI270\*2(Version2) + - Mag: QMC5883P + - Barometer: DPS310(Version1),SPL06(Version2) + +### Інтерфейси + +- 15x PWM Servo Outputs +- 1x Dedicated S.Bus Input +- 3x TELEM Ports +- 1x SERIAL4 Port +- 2x GPS Ports +- 1x USB Port (TYPE-C) +- 3x I2C Bus Ports +- 2x CAN Ports +- 2x Power Input Ports + - ADC Power Input + - DroneCAN/UAVCAN Power Input +- 2x Dedicated Debug Port + - FMU Debug + - IO Debug + +## Purchase Channels + +Order from [X-MAV](https://www.x-mav.cn/). + +## Радіоуправління + +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). + +Вам буде потрібно вибрати сумісний передавач/приймач та потім зв'язати їх, щоб вони взаємодіяли (прочитайте інструкції, що додаються до вашого конкретного передавача/приймача). + +SBUS receivers connect to the SBUS-IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## Налаштування послідовного порту + +| UART | Пристрій | Порт | +| ------ | ---------- | ------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | TELEM1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART7 | /dev/ttyS4 | TELEM3 | +| UART8 | /dev/ttyS5 | SERIAL4 | + +## PWM Output + +The AP-H743-R1 flight controller supports up to 15 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 7 outputs (labelled A1 to A7) are the "auxiliary" outputs. +These are directly attached to the STM32H743 FMU controller . + +The 15 PWM outputs are: + +M1 - M8 are connected to the IOMCU. +A1 - A7 are connected to the FMU. + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 7 FMU PWM outputs are in 3 groups: + +- A1 - A4 are in one group. +- A5, A6 are in a 2nd group. +- A7 is in a 3nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Електричні дані + +- Номінальна напруга: + - Max input voltage: 5.4V + - Вхід USB Power: 4.75~5.25V + - Вхід на серворейку: 0\~9.9В + +## Battery Monitoring + +The board has connectors for 2 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor configured which is enabled. + +## Збірка прошивки + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make x-mav_ap-h743r1_default +``` + +## Pinouts and Size + +![AP-H743-R1 pinouts](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png) + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png) + +## Підтримувані платформи / Конструкції + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). + +## Відладочний порт + +### SWD + +The [SWD interface](../debug/swd_debug.md) operate on the **FMU-DEBUG** port (`FMU-DEBUG`). + +The debug port (`FMU-DEBUG`) uses a [JST SM04B-GHS-TB](https://www.digikey.com/en/products/detail/jst-sales-america-inc/SM04B-GHS-TB/807788) connector and has the following pinout: + +| Pin | Сигнал | Вольтаж | +| -------------------------- | ------------------------------ | --------------------- | +| 1 (red) | 5V+ | +5V | +| 2 (blk) | FMU_SWDIO | +3.3V | +| 3 (blk) | FMU_SWCLK | +3.3V | +| 4 (blk) | GND | GND | diff --git a/docs/uk/flight_modes/offboard.md b/docs/uk/flight_modes/offboard.md index c9d04c0255..e2c100783d 100644 --- a/docs/uk/flight_modes/offboard.md +++ b/docs/uk/flight_modes/offboard.md @@ -62,6 +62,11 @@ bool thrust_and_torque bool direct_actuator ``` +:::warning +The following list shows the `OffboardControlMode` options for copter, fixed-wing, and VTOL. +For rovers see the [rover section](#rover). +::: + The fields are ordered in terms of priority such that `position` takes precedence over `velocity` and later fields, `velocity` takes precedence over `acceleration`, and so on. Перше поле, яке має ненульове значення (зверху вниз), визначає, яка допустима оцінка необхідна для використання режиму безпілотного керування, а також повідомлення заданих значень, які можуть бути використані. For example, if the `acceleration` field is the first non-zero value, then PX4 requires a valid `velocity estimate`, and the setpoint must be specified using the `TrajectorySetpoint` message. @@ -90,20 +95,93 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - Velocity setpoint (`velocity` different from `NaN` and `position` set to `NaN`). Non-`NaN` values acceleration are used as feedforward terms for the inner loop controllers. - Acceleration setpoint (`acceleration` different from `NaN` and `position` and `velocity` set to `NaN`) - - Всі значення інтерпретуються в NED (Nord, East, Down) координатну систему і одиниці вимірювання, є \[m/s\] і \[m/s^2\] для позиції, швидкості і прискорення, відповідно. + - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are `[m]`, `[m/s]` and `[m/s^2]` for position, velocity and acceleration, respectively. - [px4_msgs::msg::VehicleAttitudeSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) - Підтримується наступна комбінація введення: - quaternion `q_d` + thrust setpoint `thrust_body`. - Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in \[rad/s\]. + Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in `[rad/s]`. - - Кватерніон представляє обертання між корпусом дрона у системі координат FRD (перед, праворуч, вниз) та системою координат NED. Тяга у корпусі дрона виражена у системі координат FRD та у нормалізованих значеннях. + - Кватерніон представляє обертання між корпусом дрона у системі координат FRD (перед, праворуч, вниз) та системою координат NED. + Тяга у корпусі дрона виражена у системі координат FRD та у нормалізованих значеннях. - [px4_msgs::msg::VehicleRatesSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) - Підтримується наступна комбінація введення: - `roll`, `pitch`, `yaw` and `thrust_body`. - - Всі значення подані в для дрона в системі FRD. Значення в \[rad/s\] і thrust_body нормалізовано в \[-1, 1\]. + - Всі значення подані в для дрона в системі FRD. + The rates are in `[rad/s]` while thrust_body is normalized in `[-1, 1]`. + +### Ровер + +Rover modules must set the control mode using `OffboardControlMode` and use the appropriate messages to configure the corresponding setpoints. +The approach is similar to other vehicle types, but the allowed control mode combinations and setpoints are different: + +| Category | Використання | Setpoints | +| -------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| (Recommended) [Rover Setpoints](#rover-setpoints) | General rover control | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md), [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md), [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md), [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md), [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md), [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| [Actuator Setpoints](#actuator-setpoints) | Direct actuator control | [ActuatorMotors](../msg_docs/ActuatorMotors.md), [ActuatorServos](../msg_docs/ActuatorServos.md) | +| (Deprecated) [Trajectory Setpoint](#deprecated-trajectory-setpoint) | General vehicle control | [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) | + +#### Rover Setpoints + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). + All combinations of "left" and "right" setpoints are valid. + +The following are all valid setpoint combinations and their respective control flags that must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md) (set all others to _false_). +Additionally, for some combinations we require certain setpoints to be published with `NAN` values so that the setpoints of interest are not overridden by the rover module (due to the hierarchy above). +✓ are the relevant setpoints we publish, and ✗ are the setpoint that need to be published with `NAN` values. + +| Setpoint Combination | Control Flag | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| -------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | +| Положення | положення | ✓ | | | | | | +| Speed + Attitude | швидкість | | ✓ | | ✓ | | | +| Speed + Rate | швидкість | | ✓ | | ✗ | ✓ | | +| Speed + Steering | швидкість | | ✓ | | ✗ | ✗ | ✓ | +| Throttle + Attitude | attitude | | | ✓ | ✓ | | | +| Throttle + Rate | body_rate | | | ✓ | | ✓ | | +| Throttle + Steering | thrust_and_torque | | | ✓ | | | ✓ | + +:::info +If you intend to use the rover setpoints, we recommend using the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) instead since it simplifies the publishing of these setpoints. +::: + +#### Actuator Setpoints + +Instead of controlling the vehicle using position, speed, rate and other setpoints, you can directly control the motors and actuators using [ActuatorMotors](../msg_docs/ActuatorMotors.md) and [ActuatorServos](../msg_docs/ActuatorServos.md). +In [OffboardControlMode](../msg_docs/OffboardControlMode.md) set `direct_actuator` to _true_ and all other flags to _false_. + +:::info +This bypasses the rover modules including any limits on steering rates or accelerations and the inverse kinematics step. +We recommend using [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) and [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) instead for low level control (see [Rover Setpoints](#rover-setpoints)). +::: + +#### (Deprecated) Trajectory Setpoint + +:::warning +The [Rover Setpoints](#rover-setpoints) are a replacement for the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) and we highly recommend using those instead as they have a well defined behaviour and offer more flexibility. +::: + +The rover modules support the _position_, _velocity_ and _yaw_ fields of the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md). +However, only one of the fields is active at a time and is defined by the flags of [OffboardControlMode](../msg_docs/OffboardControlMode.md): + +| Control Mode Flag | Active Trajectory Setpoint Field | +| ----------------- | -------------------------------- | +| положення | положення | +| швидкість | швидкість | +| attitude | yaw | + +:::info +Ackermann rovers do not support the yaw setpoint. +::: ### Універсальний апарат @@ -116,8 +194,10 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - [px4_msgs::msg::ActuatorMotors](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) + [px4_msgs::msg::ActuatorServos](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) - Ви безпосередньо керуєте вихідними сигналами моторів та/або сервоприводів. - - Currently works at lower level than then `control_allocator` module. Do not publish these messages when not in offboard mode. - - Усі значення нормалізовані у діапазоні \[-1, 1\]. For outputs that do not support negative values, negative entries map to `NaN`. + - Currently works at lower level than then `control_allocator` module. + Do not publish these messages when not in offboard mode. + - All the values normalized in `[-1, 1]`. + For outputs that do not support negative values, negative entries map to `NaN`. - `NaN` maps to disarmed. ## Повідомлення MAVLink @@ -206,41 +286,7 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding ### Ровер -- [SET_POSITION_TARGET_LOCAL_NED](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `x`, `y`, `z`) - - Specify the _type_ of the setpoint in `type_mask`: - - ::: info - The _setpoint type_ values below are not part of the MAVLink standard for the `type_mask` field. - :: - - Значення: - - - 12288: задане значення Loiter (пристрій зупиняється, коли вже достатньо близько, щоб встановити точку). - - - Velocity setpoint (only `vx`, `vy`, `vz`) - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) and [MAV_FRAME_BODY_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_BODY_NED). - -- [SET_POSITION_TARGET_GLOBAL_INT](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_GLOBAL_INT) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `lat_int`, `lon_int`, `alt`) - - - Specify the _type_ of the setpoint in `type_mask` (not part of the MAVLink standard). - Значення: - - Якщо наступні біти не встановлені, то виконується звичайна поведінка. - - 12288: задане значення Loiter (пристрій зупиняється, коли вже достатньо близько, щоб встановити точку). - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL). - -- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET) - - Підтримуються наступні вхідні комбінації: - - Attitude/orientation (`SET_ATTITUDE_TARGET.q`) with thrust setpoint (`SET_ATTITUDE_TARGET.thrust`). - ::: info - Only the yaw setting is actually used/extracted. - -::: +Rover does not support a MAVLink offboard API (ROS2 is supported). ## Параметри для відключення diff --git a/docs/uk/flight_modes_fw/hold.md b/docs/uk/flight_modes_fw/hold.md index 04e59fd4e6..7477482f66 100644 --- a/docs/uk/flight_modes_fw/hold.md +++ b/docs/uk/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -Зазвичай він активується за допомогою наперед заданого перемикача. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ _Hold mode_ can be used to pause a mission or to help you regain control of a ve ::: -## Технічний підсумок +## Loiter modes -Літак кружляє навколо позиції утримання GPS на поточній висоті. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -Рух стіків радіокерування ігнорується. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### Параметри +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## Параметри Поведінку режиму утримання можна налаштувати за допомогою наведених нижче параметрів. | Параметр | Опис | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | Радіус кола обертання. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | Радіус кола обертання. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Мінімальна висота для режиму очікування (транспортний засіб підніметься на цю висоту, якщо режим увімкнуто на меншій висоті). | +## MAVLink Commands + +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + ## Дивіться також -[Hold Mode (MC)](../flight_modes_mc/hold.md) +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/uk/flight_modes_fw/index.md b/docs/uk/flight_modes_fw/index.md index d9acb980ac..3a0799a7de 100644 --- a/docs/uk/flight_modes_fw/index.md +++ b/docs/uk/flight_modes_fw/index.md @@ -17,6 +17,8 @@ Manual-Easy: Швидкість активно контролюється, якщо встановлений датчик швидкості. - [Режим висоти](../flight_modes_fw/altitude.md) — Найпростіший і найбезпечніший _непідтримуваний GPS_ ручний режим. Єдина відмінність порівняно з _Режимом положення_ полягає в тому, що пілот завжди безпосередньо керує кутом кочення літака і немає автоматичного утримання курсу. +- 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). - [Режим стабілізації](../flight_modes_fw/stabilized.md) — Пілот напряму керує кутом крену та тангажу, і апарат зберігає задану точку до тих пір, поки стіки знову не будуть переміщені. Тяга безпосередньо встановлюється пілотом. Координація повороту все ще обробляється контролером. diff --git a/docs/uk/flight_modes_fw/mission.md b/docs/uk/flight_modes_fw/mission.md index 31bb5be940..57ce4be8f6 100644 --- a/docs/uk/flight_modes_fw/mission.md +++ b/docs/uk/flight_modes_fw/mission.md @@ -29,32 +29,32 @@ _Режим місії_ змушує транспортний засіб вик 1. Якщо місія не збережена, або якщо PX4 завершив виконання всіх команд місії, або якщо [місія не є можливою](#mission-feasibility-checks): - - Якщо літає транспортний засіб, він буде марнувати час. - - Якщо посадять транспортний засіб, він буде "чекати". + - Якщо літає транспортний засіб, він буде марнувати час. + - Якщо посадять транспортний засіб, він буде "чекати". 2. Якщо місія збережена, а PX4 летить, вона виконає [місію / план польоту](../flying/missions.md) з поточного кроку. - - Пункт відправлення буде розглядатися як звичайна точка місії. + - Пункт відправлення буде розглядатися як звичайна точка місії. 3. Якщо місія збережена, а транспортний засіб приземлений, він злетить лише у випадку, якщо активна точка маршруту - це 'Зльот'. - Якщо налаштовано для запуску з катапульта, транспортний засіб також повинен бути запущений (див. [Зліт/посадка FW у місії](#mission-takeoff)). + Якщо налаштовано для запуску з катапульта, транспортний засіб також повинен бути запущений (див. [Зліт/посадка FW у місії](#mission-takeoff)). 4. Якщо жодне завдання не збережено, або якщо PX4 завершив виконання всіх команд місії: - - Якщо літає транспортний засіб, він буде марнувати час. - - Якщо посадять транспортний засіб, він буде "чекати". + - Якщо літає транспортний засіб, він буде марнувати час. + - Якщо посадять транспортний засіб, він буде "чекати". 5. Ви можете вручну змінити поточну команду місії, вибравши її в _QGroundControl_. - :::info - Якщо у вас є команда _Перейти до елементу_ в місії, переміщення до іншого елементу **не** скине лічильник циклу. - Однією з наслідків є те, що якщо ви зміните поточну команду місії на 1, це не призведе до "повного перезапуску" місії. + :::info + Якщо у вас є команда _Перейти до елементу_ в місії, переміщення до іншого елементу **не** скине лічильник циклу. + Однією з наслідків є те, що якщо ви зміните поточну команду місії на 1, це не призведе до "повного перезапуску" місії. ::: 6. Місія скине тільки тоді, коли транспортний засіб буде роззброєний або коли буде завантажена нова місія. - :::tip - Щоб автоматично роззброїти транспортний засіб після посадки, у _QGroundControl_ перейдіть до [Налаштування Транспортного Засобу > Безпека](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), перейдіть до _Налаштувань Режиму Посадки_ та позначте прапорець _Роззброювати після_. - Введіть час очікування після посадки перед відброюванням транспортного засобу. + :::tip + Щоб автоматично роззброїти транспортний засіб після посадки, у _QGroundControl_ перейдіть до [Налаштування Транспортного Засобу > Безпека](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), перейдіть до _Налаштувань Режиму Посадки_ та позначте прапорець _Роззброювати після_. + Введіть час очікування після посадки перед відброюванням транспортного засобу. ::: @@ -167,6 +167,10 @@ PX4 "приймає" наступні команди місії MAVLink у ре - [MAV_CMD_OBLIQUE_SURVEY](https://mavlink.io/en/messages/common.html#MAV_CMD_OBLIQUE_SURVEY) - [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. Визначення GeoFence @@ -261,7 +265,7 @@ A fixed-wing mission requires a `Takeoff` mission item to takeoff; if however th 1. **Літайте до місця посадки**: Літак летить на поточній висоті до точки обертання. 2. **Опускаючись на орбіту для наближення до висоти**: При досягненні радіусу утримання точки шляху, транспортний засіб виконує опускаючу орбіту до досягнення "висоти наближення" (висота точки утримання). - Транспортний засіб продовжує обертатися на цій висоті до тих пір, поки він не матиме тангенціальну траєкторію до пункту наземної точки, після чого ініціюється посадковий захід. + Транспортний засіб продовжує обертатися на цій висоті до тих пір, поки він не матиме тангенціальну траєкторію до пункту наземної точки, після чого ініціюється посадковий захід. 3. **Приземлення**: Літак слідує нахилу під час приземлення до точки на землі до досягнення висоти флеру. 4. **Світло**: Транспортний засіб світиться, доки не сідає на землю. diff --git a/docs/uk/flight_modes_fw/takeoff.md b/docs/uk/flight_modes_fw/takeoff.md index aa6e3cd22e..9edfa564da 100644 --- a/docs/uk/flight_modes_fw/takeoff.md +++ b/docs/uk/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: @@ -93,7 +93,7 @@ Once it reaches [MIS_TAKEOFF_ALT](#MIS_TAKEOFF_ALT) it will automatically switch 1. Увімкніть дрон 2. Put the vehicle into _Takeoff mode_ 3. Запустіть / киньте транспортний засіб (міцно) безпосередньо у вітер. - Ви також можете спершу потрясти транспортний засіб, зачекати, поки рушить двигун, а потім кинути його + Ви також можете спершу потрясти транспортний засіб, зачекати, поки рушить двигун, а потім кинути його ### Параметри (виявник запуску) diff --git a/docs/uk/flight_modes_mc/altitude.md b/docs/uk/flight_modes_mc/altitude.md index c758cfb10b..51dfb83d58 100644 --- a/docs/uk/flight_modes_mc/altitude.md +++ b/docs/uk/flight_modes_mc/altitude.md @@ -21,7 +21,7 @@ The diagram below shows the mode behaviour visually (for a [mode 2 transmitter]( RC/manual mode like [Stabilized mode](../flight_modes_mc/manual_stabilized.md) but with _altitude stabilization_ (centred sticks level vehicle and hold it to fixed altitude). Горизонтальне положення транспортного засобу може змінюватися через вплив вітру (або наявного імпульсу). -- Центровані палиці (в межах дедбенду): +- Centered sticks: - Рівень RPY прикріплюється до транспортного засобу. - Дросель (~50%) утримує поточну висоту стабільно проти вітру. - Зовнішній центр: @@ -43,9 +43,8 @@ RC/manual mode like [Stabilized mode](../flight_modes_mc/manual_stabilized.md) b Режим впливає на наступні параметри: -| Параметр | Опис | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Максимальна швидкість вертикального підйому. За замовчуванням: 3 м/с. | -| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Максимальна швидкість вертикального спуску. За замовчуванням: 1 m/s. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | -| `MPC_XXXX` | Більшість параметрів MPC_xxx впливають на поведінку польоту в цьому режимі (принаймні до певної міри). For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | +| Параметр | Опис | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Максимальна швидкість вертикального підйому. За замовчуванням: 3 м/с. | +| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Максимальна швидкість вертикального спуску. За замовчуванням: 1 m/s. | +| `MPC_XXXX` | Більшість параметрів MPC_xxx впливають на поведінку польоту в цьому режимі (принаймні до певної міри). For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | diff --git a/docs/uk/flight_modes_mc/altitude_cruise.md b/docs/uk/flight_modes_mc/altitude_cruise.md new file mode 100644 index 0000000000..52533d0852 --- /dev/null +++ b/docs/uk/flight_modes_mc/altitude_cruise.md @@ -0,0 +1,45 @@ +# Altitude Cruise Mode (Multicopter) + +   + +_Altitude Cruise mode_ is a _relatively_ easy-to-fly manual control mode in which roll and pitch sticks control vehicle movement in the left-right and forward-back directions (relative to the "front" of the vehicle), yaw stick controls rate of rotation over the horizontal plane, and throttle controls speed of ascent-descent. + +When the sticks are released/centered the vehicle will keep the current tilt and heading angle and maintain the current _altitude_. +If moving in the horizontal plane the vehicle will accelerate until the wind resistance equals the acceleration caused by the set tilt angle. +The vehicle will then continue to move with a constant velocity (unlike for Altitude mode, in which the vehicle will eventually slow down and stop). +If the wind blows the aircraft will drift in the direction of the wind even if flying perfectly level. + +:::tip +_Altitude Cruise mode_ is intended for long distance flights where the same tilt angle is kept for a long period of time. It is just like [Altitude](../flight_modes_mc/altitude.md) mode but does not go back to level tilt when the sticks are released. +::: + +The diagram below shows the mode behaviour visually (for a [mode 2 transmitter](../getting_started/rc_transmitter_receiver.md#transmitter_modes)). + +![Altitude Control MC - Mode2 RC Controller](../../assets/flight_modes/altitude_mc.png) + +## Технічний підсумок + +A manual mode that is similar to [Altitude mode](../flight_modes_mc/altitude.md) but with different interpretation of roll and pitch sticks. + +- Centered sticks: + - Roll/Pitch sticks: the current tilt is kept. + - Yaw: the current heading is kept. + - Throttle (~50%) holds current altitude. +- Зовнішній центр: + - Roll/Pitch sticks control the rate of change of the tilt angle, resulting in corresponding left-right and forward-back movement. A maximum stick deflection results in a tilting rate setpoint to go from level to max tilt within 0.5 seconds. + - Yaw stick deflection rotates the tilt angle either left or right, causing the vehicle to change course. It is _not_ causing a direct rotation around the body yaw axis like in [Acro mode](../flight_modes_mc/acro.md). + - Ручка дроселя керує швидкістю вгору/вниз з попередньо визначеною максимальною швидкістю (та швидкістю руху в інших осях). +- Зліт: + - Після посадки транспортний засіб злетить, якщо важіль керування газом підніметься вище 62.5% від повного діапазону (від низу). +- Manual control input is required (such as RC control, joystick) to enter this mode. Other than in all other manual modes, it's though possible to disable the manual control loss failsafe by setting the corresponding flag in [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT). In that case the current altitude, tilt and heading 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, and to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT). + +## Параметри + +Most of the relevant parameters are already covered in the corresponding section in the [Altitude mode](../flight_modes_mc/altitude.md). Here a list of parameters of particular importance for Altitude Cruise. + +| Параметр | Опис | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | The manual control failsafe can be disabled for Altitude Cruise by setting the corresponding bit in this parameter. | +| [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Data link lost failsafe action. Recommended to set if the manual control failsafe is disabled to avoid fly-aways. | +| [MPC_MAN_TILT_MAX](../advanced_config/parameter_reference.md#MPC_MAN_TILT_MAX) | The maximum tilt angle the vehicle will go to. At max stick deflection, it will take 0.5 seconds from level flight to this tilt angle. | diff --git a/docs/uk/flight_modes_mc/follow_me.md b/docs/uk/flight_modes_mc/follow_me.md index 9f770f7aa5..fae197203d 100644 --- a/docs/uk/flight_modes_mc/follow_me.md +++ b/docs/uk/flight_modes_mc/follow_me.md @@ -151,19 +151,19 @@ The follow-me behavior can be configured using the following parameters: 1. Set the [follow distance](#FLW_TGT_DST) to more than 12 meters (8 meters is a "recommended minimum"). - Існує вроджений вплив позиції (3 ~ 5 метрів) між цільовим об'єктом та GPS-датчиком дрона, що змушує дрон слідувати 'примарній цілі' десь поблизу фактичної цілі. - Це стає більш очевидним, коли відстань слідування дуже мала. - Ми рекомендуємо встановити достатньо велику відстань, щоб відхилення GPS не було значним. + Існує вроджений вплив позиції (3 ~ 5 метрів) між цільовим об'єктом та GPS-датчиком дрона, що змушує дрон слідувати 'примарній цілі' десь поблизу фактичної цілі. + Це стає більш очевидним, коли відстань слідування дуже мала. + Ми рекомендуємо встановити достатньо велику відстань, щоб відхилення GPS не було значним. 2. The speed at which you can change the follow angle depends on the [maximum tangential velocity](#FLW_TGT_MAX_VEL) setting. - Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. + Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. 3. Використовуючи коригування RC для висоти, відстані та кута, ви можете отримати деякі креативні знімки камери. - + - This video demonstrates a Google-Earth view perspective, by adjusting the height to around 50 meters (high), distance to 1 meter (close). Що дозволяє перспективу, як знято з супутника. + This video demonstrates a Google-Earth view perspective, by adjusting the height to around 50 meters (high), distance to 1 meter (close). Що дозволяє перспективу, як знято з супутника. ## Відомі проблеми diff --git a/docs/uk/flight_modes_mc/index.md b/docs/uk/flight_modes_mc/index.md index 45d354a960..333dc5917e 100644 --- a/docs/uk/flight_modes_mc/index.md +++ b/docs/uk/flight_modes_mc/index.md @@ -21,10 +21,12 @@ Manual-Easy: - [Stabilized mode](../flight_modes_mc/manual_stabilized.md) — Releasing the sticks levels and maintains the vehicle horizontal posture (but not altitude or position). Транспортний засіб продовжить рухатися з імпульсом, і як висота, так і горизонтальна позиція можуть бути піддані впливу вітру. This mode is also used if "Manual mode" is selected in a ground station. +- [Altitude Cruise mode](../flight_modes_mc/altitude_cruise.md) — Very similar to _Altitude mode_, with the difference that when the roll and pitch sticks are released the vehicle does not level out but keeps the tilt until further inputs are given. + Additionally it is possible to disable the manual control failsafe for this mode, having the vehicle continue on it's set path even if there are no new control inputs. Manual-Acrobatic -- [Acro](../flight_modes_mc/acro.md) — Ручний режим для виконання акробатичних маневрів, таких як креніння та петлі. +- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic manoeuvrers, such as rolls and loops. Відпускання палиць призупиняє обертання транспортного засобу в площині крена, тангажу та розвороту, але іншим чином не стабілізує транспортний засіб. Автономний: diff --git a/docs/uk/flight_modes_mc/manual_stabilized.md b/docs/uk/flight_modes_mc/manual_stabilized.md index a3fe372f1d..f51b9663e5 100644 --- a/docs/uk/flight_modes_mc/manual_stabilized.md +++ b/docs/uk/flight_modes_mc/manual_stabilized.md @@ -31,7 +31,7 @@ Throttle is rescaled (see [below](#params)) and passed directly to control alloc Автопілот контролює положення, це означає що він регулює кути крену та тангажу до нуля коли органи керування пульту РК центровані всередині мертвої зони контролера (як наслідок вирівнюючи положення). Автопілот не компенсує дрейф через вітер (або інші джерела). -- Центровані палиці (в межах дедбенду): +- Centered sticks: - Рівень ковзання/крена прикріплюється до транспортного засобу. - Зовнішній центр: - Палиці кочення/крену керують кутом нахилу у цих орієнтаціях, що призводить до відповідного руху ліворуч-праворуч та вперед-назад. diff --git a/docs/uk/flight_modes_mc/mission.md b/docs/uk/flight_modes_mc/mission.md index 0393ad7f2a..1743800936 100644 --- a/docs/uk/flight_modes_mc/mission.md +++ b/docs/uk/flight_modes_mc/mission.md @@ -31,33 +31,33 @@ They may also be created by a MAVLink API such as [MAVSDK](../robotics/mavsdk.md 1. Якщо місія не збережена, або якщо PX4 завершив виконання всіх команд місії, або якщо [місія не є можливою](#mission-feasibility-checks): - - Якщо літає транспортний засіб, він буде утримувати. - - Якщо посадять транспортний засіб, він буде "чекати". + - Якщо літає транспортний засіб, він буде утримувати. + - Якщо посадять транспортний засіб, він буде "чекати". 2. Якщо місія збережена, а PX4 летить, вона виконає [місію / план польоту](../flying/missions.md) з поточного кроку. - - Пункт `TAKEOFF` трактується як звичайна точка місії. + - Пункт `TAKEOFF` трактується як звичайна точка місії. 3. Якщо місія збережена і PX4 приземлився: - - PX4 виконає [місію/план польоту](../flying/missions.md). - - Якщо місія не має пункту `TAKEOFF`, то PX4 підніме транспортний засіб на мінімальну висоту перед виконанням решти польотного плану з поточного кроку. + - PX4 виконає [місію/план польоту](../flying/missions.md). + - Якщо місія не має пункту `TAKEOFF`, то PX4 підніме транспортний засіб на мінімальну висоту перед виконанням решти польотного плану з поточного кроку. 4. Якщо жодне завдання не збережено, або якщо PX4 завершив виконання всіх команд місії: - - Якщо літає транспортний засіб, він буде утримувати. - - Якщо посадять транспортний засіб, він буде "чекати". + - Якщо літає транспортний засіб, він буде утримувати. + - Якщо посадять транспортний засіб, він буде "чекати". 5. Ви можете вручну змінити поточну команду місії, вибравши її в _QGroundControl_. - :::info - Якщо у вас є команда _Перейти до елементу_ в місії, переміщення до іншого елементу **не** скине лічильник циклу. - Однією з наслідків є те, що якщо ви зміните поточну команду місії на 1, це не призведе до "повного перезапуску" місії. + :::info + Якщо у вас є команда _Перейти до елементу_ в місії, переміщення до іншого елементу **не** скине лічильник циклу. + Однією з наслідків є те, що якщо ви зміните поточну команду місії на 1, це не призведе до "повного перезапуску" місії. ::: 6. Місія скине тільки тоді, коли транспортний засіб буде роззброєний або коли буде завантажена нова місія. - :::tip - Щоб автоматично роззброїти транспортний засіб після посадки, у _QGroundControl_ перейдіть до [Налаштування Транспортного Засобу > Безпека](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), перейдіть до _Налаштувань Режиму Посадки_ та позначте прапорець _Роззброювати після_. - Введіть час очікування після посадки перед відброюванням транспортного засобу. + :::tip + Щоб автоматично роззброїти транспортний засіб після посадки, у _QGroundControl_ перейдіть до [Налаштування Транспортного Засобу > Безпека](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), перейдіть до _Налаштувань Режиму Посадки_ та позначте прапорець _Роззброювати після_. + Введіть час очікування після посадки перед відброюванням транспортного засобу. ::: @@ -171,6 +171,9 @@ PX4 "приймає" наступні команди місії MAVLink у ре - [MAV_CMD_NAV_VTOL_TAKEOFF](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_VTOL_TAKEOFF) - `MAV_CMD_NAV_VTOL_TAKEOFF.param2` (заголовок переходу) ігнорується. Замість цього напрямок до наступної маршрутної точки використовується для переходу. +- [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) . Визначення GeoFence diff --git a/docs/uk/flight_modes_mc/position.md b/docs/uk/flight_modes_mc/position.md index 2323cbd341..51abfe20f2 100644 --- a/docs/uk/flight_modes_mc/position.md +++ b/docs/uk/flight_modes_mc/position.md @@ -43,7 +43,7 @@ While very rare on a well calibrated vehicle, sometimes there may be problems wi Режим RC, де рульові, кренові, керування газом (RPT) керують рухом у відповідних осях/напрямках. Центральні палиці рівняють транспортний засіб і утримують його на фіксованій висоті та позиції проти вітру. -- Centered roll, pitch, throttle sticks (within RC deadzone [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ)) hold x, y, z position steady against any disturbance like wind. +- Centered roll, pitch, throttle sticks (within RC deadzone [MAN_DEADZONE](#MAN_DEADZONE)) hold x, y, z position steady against any disturbance like wind. - Зовнішній центр: - Ручки кочення/крена керують горизонтальним прискоренням над землею у ліво-правому та передньо-задньому напрямках транспортного засобу (відповідно). - Палиця дросельного клапана контролює швидкість підйому-спуску. @@ -62,12 +62,11 @@ All the parameters in the [Multicopter Position Control](../advanced_config/para | Параметр | Опис | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ) | Мертва зона палиць, де активовано утримання позиції. За замовчуванням: 0.1 (10% від повного діапазону палиці). | +| [MAN_DEADZONE](../advanced_config/parameter_reference.md#MAN_DEADZONE) | Мертва зона палиць, де активовано утримання позиції. За замовчуванням: 0.1 (10% від повного діапазону палиці). | | [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Максимальна швидкість вертикального підйому. За замовчуванням: 3 м/с. | | [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Максимальна швидкість вертикального спуску. За замовчуванням: 1 m/s. | | [MPC_LAND_ALT1](../advanced_config/parameter_reference.md#MPC_LAND_ALT1) | Висота для спрацювання першої фази повільної посадки. Below this altitude descending velocity gets limited to a value between [MPC_Z_VEL_MAX_DN](#MPC_Z_VEL_MAX_DN) (or `MPC_Z_V_AUTO_DN`) and [MPC_LAND_SPEED](#MPC_LAND_SPEED). Value needs to be higher than [MPC_LAND_ALT2](#MPC_LAND_ALT2). За замовчуванням 10м. | | [MPC_LAND_ALT2](../advanced_config/parameter_reference.md#MPC_LAND_ALT2) | Висота для другої фази повільної посадки. Below this altitude descending velocity gets limited to [`MPC_LAND_SPEED`](#MPC_LAND_SPEED). Значення повинно бути нижче, ніж "MPC_LAND_ALT1". Значення за замовчуванням: 5m. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | | `MPC_XXXX` | Більшість параметрів MPC_xxx впливають на поведінку польоту в цьому режимі (принаймні до певної міри). For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | | [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Стратегія перекладу введення на рух. From PX4 v1.12 the default (`Acceleration based`) is that stick position controls acceleration (in a similar way to a car accelerator pedal). Інші параметри дозволяють відхилення палиці безпосередньо контролювати швидкість над землею, з і без згладжування та обмежень прискорення. | | [MPC_ACC_HOR_MAX](../advanced_config/parameter_reference.md#MPC_ACC_HOR_MAX) | Максимальне горизонтальне прискорення. | diff --git a/docs/uk/flight_modes_mc/throw_launch.md b/docs/uk/flight_modes_mc/throw_launch.md index 7e990f5db3..33477986ec 100644 --- a/docs/uk/flight_modes_mc/throw_launch.md +++ b/docs/uk/flight_modes_mc/throw_launch.md @@ -43,16 +43,16 @@ When throw launch is enabled, the vehicle is initially armed in a "lockdown" sta Окрім того: 1. Носіть засоби безпеки. - Захист для очей та рукавички для роботи рекомендовані. + Захист для очей та рукавички для роботи рекомендовані. 2. Маєте легкий доступний та протестований [вимикач вимкнення](../config/safety.md#kill-switch). - Нагадайте оператору бути уважним та використовувати вимикач аварійного вимкнення за потреби. - Пілоти часто забувають, що транспортні засоби можна замінити, але вони - ні! + Нагадайте оператору бути уважним та використовувати вимикач аварійного вимкнення за потреби. + Пілоти часто забувають, що транспортні засоби можна замінити, але вони - ні! 3. Тестуйте якомога більше без гвинтів. - Утримуйте інструменти для зняття гвинтів пропелерів поруч/легкодоступними. + Утримуйте інструменти для зняття гвинтів пропелерів поруч/легкодоступними. 4. Перевірте цю функцію з принаймні двома людьми — один керує літаком, інший — пультом дистанційного керування. 5. Пам'ятайте, що після кидка точна поведінка літака може бути важко передбачити, оскільки вона сильно залежить від способу кидка. - Іноді воно залишатиметься на місці ідеально, але іноді (наприклад, через великий кочення), воно може відхилятися в один бік під час стабілізації. - Дотримуйтеся безпечної відстані! + Іноді воно залишатиметься на місці ідеально, але іноді (наприклад, через великий кочення), воно може відхилятися в один бік під час стабілізації. + Дотримуйтеся безпечної відстані! Під час першого польоту нового транспортного засобу ми рекомендуємо виконати [Тест запуску без гвинтів (Throw Launch test without propellers)](#throw-launch-pretest) (див. нижче). @@ -65,13 +65,13 @@ When throw launch is enabled, the vehicle is initially armed in a "lockdown" sta 1. Демонтуйте пропелери. 2. Встановіть [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) на `Увімкнено`. 3. Озброїте літак. - Двигуни не повинні крутитися, але транспортний засіб повинен бути збройований і продовжувати відтворювати мелодію зброювання. + Двигуни не повинні крутитися, але транспортний засіб повинен бути збройований і продовжувати відтворювати мелодію зброювання. 4. Киньте літак приблизно на 2 м у повітря. - Якщо літак не буде кидати достатньо високо, двигуни не ввімкнуться. + Якщо літак не буде кидати достатньо високо, двигуни не ввімкнуться. 5. Двигуни повинні запуститися одразу після перетинання вершини. 6. Увімкніть вимикач вбивства (ідеально, щоб це робив друга особа, яка керує RC). 7. Спіймай дрон. - Не забувайте використовувати захисні рукавички! + Не забувайте використовувати захисні рукавички! ## Запуск з катапульти чи підкиданням @@ -79,12 +79,12 @@ When throw launch is enabled, the vehicle is initially armed in a "lockdown" sta 1. Встановіть [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) на `Увімкнено`. 2. Озброїте літак. - Пропелери не повинні обертатися, але транспортний засіб повинен бути збройований і продовжувати відтворювати мелодію зброювання. + Пропелери не повинні обертатися, але транспортний засіб повинен бути збройований і продовжувати відтворювати мелодію зброювання. 3. Викиньте літак від себе, вперед і вгору (рекомендується близько 2 м відстані та 2 м вгору). - - Транспортний засіб повинен досягти швидкості [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED), щоб виявити запуск, яка за замовчуванням встановлена на 5 м/с. - Якщо цю швидкість не досягнуто, двигуни не запустяться, і літак впаде на землю. - - Спробуйте уникати надмірного обертання під час кидка, оскільки це може призвести до відмови дрона або непередбачуваної поведінки. - Точне значення "надмірного обертання" залежить від платформи: наприклад, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md), яка використовувалася для тестування, все ще вдалося відновитися після 2-3 повних обертань. + - Транспортний засіб повинен досягти швидкості [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED), щоб виявити запуск, яка за замовчуванням встановлена на 5 м/с. + Якщо цю швидкість не досягнуто, двигуни не запустяться, і літак впаде на землю. + - Спробуйте уникати надмірного обертання під час кидка, оскільки це може призвести до відмови дрона або непередбачуваної поведінки. + Точне значення "надмірного обертання" залежить від платформи: наприклад, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md), яка використовувалася для тестування, все ще вдалося відновитися після 2-3 повних обертань. 4. Після виявлення швидкості вниз (транспортний засіб досягає свого апексу і починає падати), мотори повинні увімкнутися, і транспортний засіб почне летіти в поточному режимі. ## Параметри diff --git a/docs/uk/flight_modes_rover/api.md b/docs/uk/flight_modes_rover/api.md new file mode 100644 index 0000000000..e32de3e8ee --- /dev/null +++ b/docs/uk/flight_modes_rover/api.md @@ -0,0 +1,29 @@ +# Apps & API + +The rover modules have been tested and integrated with a subset of the available [Apps & API](../middleware/index.md) methods. +We specifically provide guides for using [ROS 2](../ros2/index.md) to interface a companion computer with PX4 via [uXRCE-DDS](../middleware/uxrce_dds.md). + +| Method | Опис | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [PX4 ROS 2 Interface](#px4-ros-2-interface) (Recommended) | Register a custom mode and publish [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). | +| [ROS 2 Offboard Control](#ros-2-offboard-control) | Use the PX4 internal [Offboard Mode](../flight_modes/offboard.md) and publish messages defined in [dds_topics.yaml](../middleware/dds_topics.md). | + +## PX4 ROS 2 Interface + +We recommend the use of the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) which allows you to register a custom drive mode and exposes [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). + +By using these setpoints (instead of the PX4 internal rover setpoints), you are guaranteed to send valid control inputs to your vehicle and the control flags for the setpoints you are using are automatically set for you. +Registering a custom drive mode instead of using [ROS 2 Offboard Control](#ros-2-offboard-control) additionally provides the advantages listed [here](../concept/flight_modes.md#internal-vs-external-modes). + +To get familiar with this method, read through the guide for the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) where we also provide an example app for rover. + +## ROS 2 Offboard Control + +[ROS 2 Offboard Control](../ros2/offboard_control.md) uses the PX4 internal [Offboard Mode](../flight_modes/offboard.md). + +While you can subscribe/publish to all topics specified in [dds_topics.yaml](../middleware/dds_topics.md), not all rover modules support all of these topics (see [Supported Setpoints](../flight_modes/offboard.md#rover)). +Unlike the [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints) exposed through the [PX4 ROS 2 Interface](#px4-ros-2-interface), there is no guarantee that the published setpoints lead to a valid control input. + +In addition, the correct control mode flags must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md). +This requires a deeper understanding of PX4 and the structure of the rover modules. +For general information on setting up offboard mode read through [Offboard Mode](../flight_modes/offboard.md) and then consult [Supported Setpoints](../flight_modes/offboard.md#rover). diff --git a/docs/uk/flying/geofence.md b/docs/uk/flying/geofence.md index cb3b8138cf..213f80f993 100644 --- a/docs/uk/flying/geofence.md +++ b/docs/uk/flying/geofence.md @@ -43,7 +43,7 @@ Geofence planning is fully documented in [Plan View > GeoFence](https://docs.qgr - Маркер центру зони може бути використаний для переміщення зони у правильне положення. - Маркер на межі кругової зони може бути використаний для зміни радіуса. - Маркери на кутах (вершинах) можуть бути використані для зміни геометрії полігону. - Додаткові вершини створюються шляхом натискання на середину ліній між наявними маркерами. + Додаткові вершини створюються шляхом натискання на середину ліній між наявними маркерами. 5. Use the _Geofence Editor_ to set a fence as an inclusion or exclusion, and to select a fence to edit (**Edit** radio button) or Delete (**Del** button). 6. Додайте стільки зон, скільки забажаєте. 7. Once finished, click on the **Upload** button (top right) to send the fence (along with rally points and mission) to the vehicle. diff --git a/docs/uk/flying/package_delivery_mission.md b/docs/uk/flying/package_delivery_mission.md index 3ff4a91c57..a5d2e0020f 100644 --- a/docs/uk/flying/package_delivery_mission.md +++ b/docs/uk/flying/package_delivery_mission.md @@ -37,9 +37,9 @@ Note that if landed, the next mission item after deployment should be another `W - Щоб скинути посилку під час польоту, установіть відповідну висоту для маршрутної точки (і переконайтеся, що маршрутна точка знаходиться в безпечному місці для скидання посилки). - If you'd like to land the vehicle to make the delivery you will need to change the `Waypoint` to a `Land` mission item. - Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. + Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. - ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) + ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) 3. Додайте маршрутну точку на карті (у будь-якому місці) для вивільнення захвату. To change this to a `Gripper Mechanism` select the "Waypoint" heading, and in the popup changing the group to "Advanced", then selecting `Gripper Mechanism`. diff --git a/docs/uk/frames_multicopter/dji_f450_cuav_5nano.md b/docs/uk/frames_multicopter/dji_f450_cuav_5nano.md index 6459c1d75a..f6311a3b29 100644 --- a/docs/uk/frames_multicopter/dji_f450_cuav_5nano.md +++ b/docs/uk/frames_multicopter/dji_f450_cuav_5nano.md @@ -106,52 +106,52 @@ This topic provides full instructions for building the kit and configuring PX4 u 1. Прикріпіть 4 ніжки до нижньої пластини за допомогою наданих гвинтів. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) 2. Припаяйте ЕСК (електронний регулятор швидкості) до плати, позитивний (червоний) та негативний (чорний). - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) 3. Припаяйте модуль живлення, позитивний (червоний) та негативний (чорний). - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) 4. Підключіть двигуни до ESC відповідно до їхніх позицій. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) 5. Прикріпіть двигуни до відповідних рук. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) 6. Додайте верхню дошку (прикрутіть до верхньої частини ніг). - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) 7. Add damping foam to the _CUAV V5 nano_ flight controller. - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) 8. Прикріпіть приймач FrSky до нижньої плати за допомогою двосторонньої стрічки. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) 9. Прикріпіть телеметричний модуль до нижньої плати транспортного засобу за допомогою двосторонньої стрічки. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) 10. Поставте алюмінієві опори на платформу кнопок і прикріпіть GPS. - ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) + ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) 11. Plug in Telemetry (`TELEM1`), GPS module (`GPS/SAFETY`), RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/uk/frames_multicopter/dji_f450_cuav_5plus.md b/docs/uk/frames_multicopter/dji_f450_cuav_5plus.md index 0e9d05a9cb..b29a2f70ea 100644 --- a/docs/uk/frames_multicopter/dji_f450_cuav_5plus.md +++ b/docs/uk/frames_multicopter/dji_f450_cuav_5plus.md @@ -108,53 +108,53 @@ This topic provides full instructions for building the kit and configuring PX4 u 1. Прикріпіть 4 ніжки до нижньої пластини за допомогою наданих гвинтів. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) 2. Припаяйте ЕСК (електронний регулятор швидкості) до плати, позитивний (червоний) та негативний (чорний). - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) 3. Припаяйте модуль живлення, позитивний (червоний) та негативний (чорний). - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) 4. Підключіть двигуни до ESC відповідно до їхніх позицій. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) 5. Прикріпіть двигуни до відповідних рук. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) 6. Додайте верхню дошку (прикрутіть до верхньої частини ніг). - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) 7. Додайте двосторонній скотч (3M) до контролера польоту CUAV V5+ (він має внутрішнє гасіння вібрацій, тому використовувати піну не потрібно). - ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) + ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) 8. Прикріпіть приймач FrSky до нижньої плати за допомогою двосторонньої стрічки. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) 9. Прикріпіть телеметричний модуль до нижньої плати транспортного засобу за допомогою двосторонньої стрічки. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) 10. Поставте алюмінієві опори на платформу кнопок. 11. Plug in Telemetry (`TELEM1`) and GPS module (`GPS/SAFETY`) to the flight controller. - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) 12. Plug in the RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/uk/frames_multicopter/holybro_qav250_pixhawk4_mini.md b/docs/uk/frames_multicopter/holybro_qav250_pixhawk4_mini.md index 7b7b54ed99..37a4d5bcd7 100644 --- a/docs/uk/frames_multicopter/holybro_qav250_pixhawk4_mini.md +++ b/docs/uk/frames_multicopter/holybro_qav250_pixhawk4_mini.md @@ -103,78 +103,78 @@ Estimated time to assemble frame is 2 hours and 1.5 hours installing the autopil 1. Прикріпіть руки до плати кнопки за допомогою гвинтів довжиною 15 мм, як показано: - ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) + ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) 2. Покладіть коротку пластину над руками - ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) + ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) 3. Покладіть гайки на відносно 15 мм гвинти (показано в наступному кроці) 4. Insert the plastic screws into the indicated holes (note that this part of the frame faces down when the vehicle is complete). - ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) + ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) 5. Add the plastic nuts to the screws (turn over, as shown) - ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) + ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) 6. Lower the power module over the plastic screws and then add the plastics standoffs - ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) + ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) 7. Put the flight controller plate on the standoffs (over the power module) - ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) + ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) 8. Підключіть двигуни. Двигуни мають стрілку, що показує напрямок обертання. - ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) + ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) 9. Use double sided tape from kit to attach the _Pixhawk 4 Mini_ to the flight controller plate. - ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) + ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) 10. Connect the power module's "power" cable to _Pixhawk 4 mini_. - ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) + ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) 11. Attach the aluminium standoffs to the button plate - ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) + ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) 12. Підключіть ESC з моторами та утримуйте. На цьому зображенні показаний порядок розташування двигунів та напрямок обертання. - ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) + ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) - Підключіть двигуни на ESC, переконайтеся, що двигуни обертаються у правильному напрямку, якщо двигун обертається у протилежний бік, змініть кабель A на плату C та C на плату A ESC. + Підключіть двигуни на ESC, переконайтеся, що двигуни обертаються у правильному напрямку, якщо двигун обертається у протилежний бік, змініть кабель A на плату C та C на плату A ESC. - :::warning - Test motor directions with propellers removed. + :::warning + Test motor directions with propellers removed. ::: - ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) + ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) 13. Підключіть кабелі сигналу ESC до виходів PWM Pixhawk у правильному порядку (див. попереднє зображення) - ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) + ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) 14. Підключіть приймач. - - Якщо використовуєте приймач PPM, підключіть його до порту PPM. + - Якщо використовуєте приймач PPM, підключіть його до порту PPM. - ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) + ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) - - Якщо використовується приймач SBUS, підключіть його до порту RC IN + - Якщо використовується приймач SBUS, підключіть його до порту RC IN - ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) + ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) 15. Підключіть модуль телеметрії. Вставте модуль за допомогою двостворчастої стрічки та підключіть його до порту телеметрії. - ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) + ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) 16. Підключіть модуль GPS - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) - Прикріпіть модуль на верхню плату (використовуючи наданий стрічку 3M, або пастою). Потім покладіть верхню плиту на стойки, як показано + Прикріпіть модуль на верхню плату (використовуючи наданий стрічку 3M, або пастою). Потім покладіть верхню плиту на стойки, як показано - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) 17. Останнім "обов'язковим" кроком зборки є додавання липучки для утримання батареї - ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) + ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) The "basic" frame build is now complete (though if you need them, you can find more information about connecting components in the [Pixhawk 4 Wiring Quickstart](../assembly/quick_start_pixhawk4.md)). @@ -189,17 +189,17 @@ If you have the "basic" version of the kit, you can now jump ahead to instructio Кроки для встановлення комплекту: 1. Install the camera bracket on the frame - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) 2. Install the camera on the bracket - ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) + ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) 3. The power module on the complete kit comes with wiring ready to connect the Video Transmitter and Camera: - ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) - - Attach the camera connector - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) - The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. - - Connect the Video Transmitter (VTX) connector - ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) - The wires are: yellow=video out, black=ground, red=+voltage. + ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) + - Attach the camera connector + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) + The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. + - Connect the Video Transmitter (VTX) connector + ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) + The wires are: yellow=video out, black=ground, red=+voltage. 4. Закріпіть відеопередавач і плату OSD на рамку за допомогою стрічки. :::info diff --git a/docs/uk/frames_multicopter/holybro_s500_v2_pixhawk4.md b/docs/uk/frames_multicopter/holybro_s500_v2_pixhawk4.md index 22cf0615c3..f649cb2b4e 100644 --- a/docs/uk/frames_multicopter/holybro_s500_v2_pixhawk4.md +++ b/docs/uk/frames_multicopter/holybro_s500_v2_pixhawk4.md @@ -115,11 +115,11 @@ No LiPo battery is included. Оцінкований час для збирання - 90 хвилин, близько 45 хвилин на збірку рами та 45 хвилин на встановлення та налаштування автопілота в QGroundControl. 1. Збірка шасі. - Ми збираємося почати зі складання шасі на вертикальний стовп. Відкрутіть гвинти стійки посадки та вставте вертикальний стовп, як показано нижче. + Ми збираємося почати зі складання шасі на вертикальний стовп. Відкрутіть гвинти стійки посадки та вставте вертикальний стовп, як показано нижче. - ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) + ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) - ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) + ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) 2. Зібрати плату управління живленням до стільникового шасі. Закрутіть шасі з вертикальним полем на повністю зібрану плату управління живленням. @@ -132,132 +132,132 @@ No LiPo battery is included. ![Figure 4](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig4.jpg) 1. Зберігайте зброю на плату керування живленням. - Прикріпіть руку до плати управління живленням. + Прикріпіть руку до плати управління живленням. - ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) + ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) - ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) + ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) - Використовуйте гвинти M2 5X6 по 2 штуки в кожній руці. - Вставте гвинти знизу пластини. + Використовуйте гвинти M2 5X6 по 2 штуки в кожній руці. + Вставте гвинти знизу пластини. - ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) + ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) - Переконайтеся, що кабелі ESC прокладені через середину руки. + Переконайтеся, що кабелі ESC прокладені через середину руки. - ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) + ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) 2. Assemble the 8_3 2.54mm pitch Horizontal Pin to the 10 to 10 pin cable (PWM) to the Power Management Board. - Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. + Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. - ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) + ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) - Виріжте шматок стрічки 3M та прикріпіть його до нижньої частини горизонтального штиря: + Виріжте шматок стрічки 3M та прикріпіть його до нижньої частини горизонтального штиря: - ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) + ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) - Stick the Horizontal Pin to the Power Management Board: + Stick the Horizontal Pin to the Power Management Board: - ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) + ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) - ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) + ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) 3. Зберіть двигуни на руки. Для цього нам знадобляться 16 шурупів M3X7, 4 мотори та 4 руки. - Встановіть двигуни в кожну руку, пропустіть гвинт через дно руки: + Встановіть двигуни в кожну руку, пропустіть гвинт через дно руки: - ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) + ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) - ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) + ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) - Після того, як 4 мотори встановлені на руку, візьміть кабелі (червоний, синій, чорний) і пропустіть їх через різьбу руки. - 3 кабелі, які мають колірну маркування, підключаються до ESC. + Після того, як 4 мотори встановлені на руку, візьміть кабелі (червоний, синій, чорний) і пропустіть їх через різьбу руки. + 3 кабелі, які мають колірну маркування, підключаються до ESC. - ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) + ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) - ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) + ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) 4. Монтаж GPS на рамці. - Для цього нам знадобиться GPS Pixhawk 4 та монтажна плита. + Для цього нам знадобиться GPS Pixhawk 4 та монтажна плита. - ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) + ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) - Встановіть мачту GPS на задню частину дошки, використовуйте 4 гвинти: + Встановіть мачту GPS на задню частину дошки, використовуйте 4 гвинти: - ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) + ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) - ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) + ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) - Використовуйте стрічку та приклейте GPS на верх мачти GPS: + Використовуйте стрічку та приклейте GPS на верх мачти GPS: - ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) + ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) 5. Вставте FrSky на дошку. Наклейте FrSky за допомогою двосторонньої стрічки (3M) на нижню плату. - Прикріпіть FrSky до рами: + Прикріпіть FrSky до рами: - ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) + ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) - ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) + ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) 6. Прикріпіть телеметрію до рами. - Наступним кроком є взяти телеметричне радіо Holybro та прикріпити його до рами, використовуйте стрічку 3M. + Наступним кроком є взяти телеметричне радіо Holybro та прикріпити його до рами, використовуйте стрічку 3M. - ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) + ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) - ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) + ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) - Цей збірний вузол прикріплений всередину рами, спрямований на зовнішню сторону вперед автомобіля. - На нижче наведеному зображенні показано радіо, яке знаходиться всередині нижньої частини рами. + Цей збірний вузол прикріплений всередину рами, спрямований на зовнішню сторону вперед автомобіля. + На нижче наведеному зображенні показано радіо, яке знаходиться всередині нижньої частини рами. - ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) + ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) 7. Монтаж Pixhawk 4 на плату. - Використовуйте двосторонній скотч для кріплення Pixhawk 4 до центральної пластини: + Використовуйте двосторонній скотч для кріплення Pixhawk 4 до центральної пластини: - ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) + ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) - ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) + ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) - ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) + ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) - Наступним кроком є монтаж Pixhawk 4 на плату до рами. - Для цього нам знадобляться винти M2 5X6. - Вирівняйте пластину з рамою та вставте гвинти. - Перед тим як встановлювати плату, ми рекомендуємо накласти стрічку на модуль живлення (таким чином він буде щільно фіксуватися). + Наступним кроком є монтаж Pixhawk 4 на плату до рами. + Для цього нам знадобляться винти M2 5X6. + Вирівняйте пластину з рамою та вставте гвинти. + Перед тим як встановлювати плату, ми рекомендуємо накласти стрічку на модуль живлення (таким чином він буде щільно фіксуватися). - ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) + ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) - ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) + ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) 8. Збирання кронштейну батареї до рами. - Для цього нам знадобляться винти M2 5X6 та кріплення батареї: + Для цього нам знадобляться винти M2 5X6 та кріплення батареї: - ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) + ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) - Вставте довгі важі в маленькі кільця: + Вставте довгі важі в маленькі кільця: - ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) + ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) - ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) + ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) - Додайте це до рами, переконайтеся, що всі чотири сторони вирівняні для вставки гвинтів: + Додайте це до рами, переконайтеся, що всі чотири сторони вирівняні для вставки гвинтів: - ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) + ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) - Зберіть маленьку пластину до ніг та відкрутіть по всіх чотирьох сторонах. + Зберіть маленьку пластину до ніг та відкрутіть по всіх чотирьох сторонах. - ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) + ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) - Останнім кроком є закріплення плати: + Останнім кроком є закріплення плати: - ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) + ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) 9. Підключення Pixhawk 4. Pixhawk 4, який має кілька різних дротів та з'єднань з ним. - Нижче наведено зображення кожного дроту, який потрібен з Pixhawk, і його вигляд підключення. + Нижче наведено зображення кожного дроту, який потрібен з Pixhawk, і його вигляд підключення. 10. Підключіть модуль телеметрії та GPS до контролера польоту, як показано на рисунку 37; підключіть RC приймач, всі 4 ESC до контролера польоту, а також модуль живлення. - ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) + ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) Після повної збірки комплект виглядає як показано нижче: diff --git a/docs/uk/frames_multicopter/holybro_x500V2_pixhawk5x.md b/docs/uk/frames_multicopter/holybro_x500V2_pixhawk5x.md index d0156e13bb..4a822bd2ff 100644 --- a/docs/uk/frames_multicopter/holybro_x500V2_pixhawk5x.md +++ b/docs/uk/frames_multicopter/holybro_x500V2_pixhawk5x.md @@ -93,92 +93,92 @@ _Figure 1_: X500 V2 ARF Kit what's inside Орієнтовний час збірки - 55 хвилин (25 хвилин на раму, 30 хвилин на встановлення/налаштування автопілота) 1. Start by assembling the payload & battery holder. - Втисніть гумки в захоплювачі (не використовуйте гострі предмети, щоб їх втиснути в них!). - Далі пропустіть тримачі через планки тримача з основами тримача батарей, як показано на рисунку 3. + Втисніть гумки в захоплювачі (не використовуйте гострі предмети, щоб їх втиснути в них!). + Далі пропустіть тримачі через планки тримача з основами тримача батарей, як показано на рисунку 3. - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) - _Figure 2_: Payload holder components + _Figure 2_: Payload holder components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) - _Figure 3_: Payload holder assembled + _Figure 3_: Payload holder assembled 2. Наступним кроком буде прикріплення нижньої пластини до тримача вантажу. - Вам знадобляться деталі, як показано на рисунку 4. - Потім встановіть основу для розподільної плати живлення, використовуючи нейлонові гайки, як зображено на Рис. 5. - Нарешті, використовуючи 8 шестигранних гвинтів, ви можете приєднати нижню пластину до тримача навантаження (Рисунок 7) + Вам знадобляться деталі, як показано на рисунку 4. + Потім встановіть основу для розподільної плати живлення, використовуючи нейлонові гайки, як зображено на Рис. 5. + Нарешті, використовуючи 8 шестигранних гвинтів, ви можете приєднати нижню пластину до тримача навантаження (Рисунок 7) - ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) + ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) - _Figure 4_: Needed Materials + _Figure 4_: Needed Materials - ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) + ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) - _Figure 5_: PDB mount base + _Figure 5_: PDB mount base - ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) + ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) - _Figure 6_: Mounted pdb with nylon nuts + _Figure 6_: Mounted pdb with nylon nuts - ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) + ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) - _Figure 7_: Mounted Plate on payload holder + _Figure 7_: Mounted Plate on payload holder 3. Давайте зберемо речі, необхідні для монтажу посадкового шасі, як на рисунку 8. - Використовуйте гвинти, щоб приєднати посадкові шасі до нижньої пластини. - Також потрібно відкрити три шестигранних гвинти на кожній з ніжок, щоб ви могли вставити їх у вуглецеві труби. - Не забудьте знову їх затягнути. + Використовуйте гвинти, щоб приєднати посадкові шасі до нижньої пластини. + Також потрібно відкрити три шестигранних гвинти на кожній з ніжок, щоб ви могли вставити їх у вуглецеві труби. + Не забудьте знову їх затягнути. - ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) + ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) - _Figure 8_: Required parts for landing gear attachment + _Figure 8_: Required parts for landing gear attachment - ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) + ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) - _Figure 9_: Landing gear attachment to the body + _Figure 9_: Landing gear attachment to the body 4. Зараз ми зберемо все оснащення, щоб встановити верхню пластину. - Прошу звернути увагу, що номери моторів на кронштейнах відповідають тим, що згадані на верхній платі. - На щастя, мотори встановлені, а ESCs були з'єднані заздалегідь. - Почніть, проходячи через всі гвинти, так як ви зафіксували кронштейни на їхніх власних місцях (Вони мають направляючий елемент, як показано на рисунку 11, щоб переконатися, що вони на місці), і трохи підтягніть всі нейлонові гайки. - Потім ви зможете підключити роз'єми живлення XT30 до плати живлення. - Пам'ятайте, що дроти сигналу повинні бути проведені через верхню пластину так, що ми зможемо пізніше їх підключити до Pixhawk. + Прошу звернути увагу, що номери моторів на кронштейнах відповідають тим, що згадані на верхній платі. + На щастя, мотори встановлені, а ESCs були з'єднані заздалегідь. + Почніть, проходячи через всі гвинти, так як ви зафіксували кронштейни на їхніх власних місцях (Вони мають направляючий елемент, як показано на рисунку 11, щоб переконатися, що вони на місці), і трохи підтягніть всі нейлонові гайки. + Потім ви зможете підключити роз'єми живлення XT30 до плати живлення. + Пам'ятайте, що дроти сигналу повинні бути проведені через верхню пластину так, що ми зможемо пізніше їх підключити до Pixhawk. - + - _Figure 10_: Connecting arms needed materials. + _Figure 10_: Connecting arms needed materials. - + - _Figure 11_: Guide for the arms mount + _Figure 11_: Guide for the arms mount 5. Для затягування всіх 16 гвинтів і гайок використовуйте як шестигранний ключ, так і гайковий ключ. - ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) + ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) - _Figure 12_: Mounted top plate + _Figure 12_: Mounted top plate 6. Наступним кроком ви можете закріпити свій pixhawk на верхній плиті, використовуючи наклейки. - Рекомендується мати напрямок стрілки вашого Pixhawk таким же, як зазначено на верхній плиті. + Рекомендується мати напрямок стрілки вашого Pixhawk таким же, як зазначено на верхній плиті. - ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) + ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) - _Figure 13_: Sticker tapes on Pixhawk + _Figure 13_: Sticker tapes on Pixhawk 7. Якщо ви хочете встановити GPS на плату компаньйона-комп'ютера, тепер ви можете закріпити кріплення GPS на ній за допомогою 4 гвинтів і гайок. - + - _Figure 14_: Secure GPS mount onto companion plate + _Figure 14_: Secure GPS mount onto companion plate 8. За допомогою скотча приклейте GPS до верхньої частини GPS-щогли і встановіть її на щоглу. - Переконайтеся, що стрілка на gps вказує вперед (зображення 15). + Переконайтеся, що стрілка на gps вказує вперед (зображення 15). - + - _Figure 15_: GPS and mast + _Figure 15_: GPS and mast 9. Наразі ви можете підключити інтерфейси Pixhawk, такі як телеметрійне радіо до 'TELEM1' та відповідно кабелі сигналів для моторів. diff --git a/docs/uk/frames_multicopter/holybro_x500_pixhawk4.md b/docs/uk/frames_multicopter/holybro_x500_pixhawk4.md index 60ab2730a5..3cf16c139d 100644 --- a/docs/uk/frames_multicopter/holybro_x500_pixhawk4.md +++ b/docs/uk/frames_multicopter/holybro_x500_pixhawk4.md @@ -81,125 +81,125 @@ Additionally you will need a battery and receiver ([compatible radio system](../ Час збірки (приблизно): 3.75 години (180 хвилин на раму, 45 хвилин на встановлення/налаштування автопілота) 1. Почніть зі збирання шасі. - Відкрутіть гвинти шасі і вставте вертикальну стійку (зобр. 1 і 2). + Відкрутіть гвинти шасі і вставте вертикальну стійку (зобр. 1 і 2). - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) - _Figure 2_: Landing gear components + _Figure 2_: Landing gear components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) - _Figure 2_: Landing gear assembled + _Figure 2_: Landing gear assembled 2. Потім просуньте 4 кронштейни через 4 основи двигуна, як показано на малюнку 3. - Переконайтеся, що штанги злегка виступають з основи і є однаковими на всіх 4-х плечах, а також переконайтеся, що дроти електродвигуна спрямовані назовні. + Переконайтеся, що штанги злегка виступають з основи і є однаковими на всіх 4-х плечах, а також переконайтеся, що дроти електродвигуна спрямовані назовні. - ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) + ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) - _Figure 3_: Attach arms to motor bases + _Figure 3_: Attach arms to motor bases 3. Вставте 4 нейлонові гвинти та нейлонові стійки і прикріпіть модуль живлення PM07 до нижньої панелі за допомогою 4 нейлонових гайок, як показано на зображенні 4. - ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) + ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) - _Figure 4_: Attach power module + _Figure 4_: Attach power module 4. Протягніть 4 двигуни ESC через кожне з кронштейнів і підключіть трижильні дроти до двигунів, як показано на зображенні 5. - + - _Figure 5_: Connect motors + _Figure 5_: Connect motors 5. Connect the ESCs power wires onto the power module PM07, black->black and red->red, ESC PWM signal wires goes to "FMU-PWM-Out". - Переконайтеся, що ви підключили дроти ШІМ ESC двигуна в правильному порядку. - Номер двигуна повітряного корпусу дивіться на зображенні 7 і підключіть його до відповідного номера на платі PM07. + Переконайтеся, що ви підключили дроти ШІМ ESC двигуна в правильному порядку. + Номер двигуна повітряного корпусу дивіться на зображенні 7 і підключіть його до відповідного номера на платі PM07. - ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) - _Figure 7_: ESC power module and signal wiring + ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) + _Figure 7_: ESC power module and signal wiring - Колір на верхній частині двигуна вказує на напрямок обертання (зображення 7-1), чорний кінчик - за годинниковою стрілкою, а білий - проти годинникової стрілки. - Переконайтеся, що при виборі напрямку двигуна ви дотримуєтесь орієнтира px4 quadrotor x airframe (зображення 7-2). + Колір на верхній частині двигуна вказує на напрямок обертання (зображення 7-1), чорний кінчик - за годинниковою стрілкою, а білий - проти годинникової стрілки. + Переконайтеся, що при виборі напрямку двигуна ви дотримуєтесь орієнтира px4 quadrotor x airframe (зображення 7-2). - + - _Figure 7_: Motor order/direction diagram + _Figure 7_: Motor order/direction diagram - + - _Figure 7-1_: Motor direction + _Figure 7-1_: Motor direction 6. Підключіть 10-контактні кабелі до FMU-PWM-in, а 6-контактні - до PWR1 на модулі живлення PM07. - ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) + ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) - _Figure 8_: Power module PWM and power wiring + _Figure 8_: Power module PWM and power wiring 7. Якщо ви хочете встановити GPS на верхній панелі, то тепер ви можете закріпити кріплення GPS на верхній панелі за допомогою 4 гвинтів і гайок. - + - _Figure 9_: Secure GPS mount onto top plate + _Figure 9_: Secure GPS mount onto top plate 8. Протягніть кабелі PM07 через верхню пластину. - З'єднайте верхню і нижню пластини за допомогою 4 U-подібних нейлонових ременів, гвинтів і гайок з кожного боку, переконайтеся, що кабелі ESC двигуна знаходяться всередині U-подібних нейлонових ременів, як показано на зображенні 10, гайки не затягуйте. + З'єднайте верхню і нижню пластини за допомогою 4 U-подібних нейлонових ременів, гвинтів і гайок з кожного боку, переконайтеся, що кабелі ESC двигуна знаходяться всередині U-подібних нейлонових ременів, як показано на зображенні 10, гайки не затягуйте. - + - _Figure 10-1_: Feed power module cables through top plate + _Figure 10-1_: Feed power module cables through top plate - + - _Figure 10-2_: Connecting top and bottom plate + _Figure 10-2_: Connecting top and bottom plate 9. Трохи всуньте трубки кронштейнів у раму і переконайтеся, що величина виступу (червоний квадрат на зображенні 11) є однаковою на всіх 4-х кронштейнах. - Переконайтеся, що всі двигуни спрямовані прямо вгору, а потім затягніть усі гайки та гвинти. + Переконайтеся, що всі двигуни спрямовані прямо вгору, а потім затягніть усі гайки та гвинти. - ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) + ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) 10. Вставте прокладки для підвісів у 4 підвіси та закріпіть їх на нижній пластині за допомогою 8 шестигранних гвинтів (Зображення 11). - Отвори для гвинтів позначені білою стрілкою на зображенні 12. - Ми рекомендуємо нахилити дрон убік, щоб полегшити встановлення. + Отвори для гвинтів позначені білою стрілкою на зображенні 12. + Ми рекомендуємо нахилити дрон убік, щоб полегшити встановлення. - + - _Figure 11_: Hanger gaskets + _Figure 11_: Hanger gaskets - ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) + ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) - _Figure 12_: Screw holes + _Figure 12_: Screw holes 11. Вставте направляючі планки на кільця кріплення (зображення 13). - Зберіть кріплення для батареї та плату платформи і встановіть їх на направляючі, як показано на зображенні 14. + Зберіть кріплення для батареї та плату платформи і встановіть їх на направляючі, як показано на зображенні 14. - ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) + ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) - _Figure 13_: Slide bars + _Figure 13_: Slide bars - + - _Figure 14_: Battery mount on slide bars + _Figure 14_: Battery mount on slide bars 12. Встановіть шасі на нижню пластину. - Ми рекомендуємо нахилити дрон убік, щоб полегшити встановлення. + Ми рекомендуємо нахилити дрон убік, щоб полегшити встановлення. - ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) + ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) - _Figure 15_: Landing Gear + _Figure 15_: Landing Gear 13. За допомогою скотча приклейте GPS до верхньої частини GPS-щогли і встановіть її на щоглу. - Переконайтеся, що стрілка на gps вказує вперед (зображення 16). + Переконайтеся, що стрілка на gps вказує вперед (зображення 16). - + - _Figure 16_: GPS and mast + _Figure 16_: GPS and mast 14. Встановіть телеметричну радіостанцію на верхню пластину. - Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. - Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. + Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. + Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. - ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) + ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) - _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. + _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. Please refer to [Pixhawk 4 Quick Start](../assembly/quick_start_pixhawk4.md) for more information. diff --git a/docs/uk/frames_multicopter/holybro_x500v2_pixhawk6c.md b/docs/uk/frames_multicopter/holybro_x500v2_pixhawk6c.md index da28900651..8e20beecd5 100644 --- a/docs/uk/frames_multicopter/holybro_x500v2_pixhawk6c.md +++ b/docs/uk/frames_multicopter/holybro_x500v2_pixhawk6c.md @@ -18,21 +18,21 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] **Screw**- Sunk Screw M2.5\*6 12pcs 1. Вставте резинове кільце підвіски-висувки в кожну з їхніх відповідних підвісок. - Не використовуйте гострi предмети для натискання резинок всередині. + Не використовуйте гострi предмети для натискання резинок всередині. - [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) + [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) 2. Take the battery mounting board and screw it with the slide bar clip using the Sunk Screw M2.5\*6. - [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) + [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) 3. Screw 4 hangers to the Platform Board using Sunk Screw M2.5\*6. - [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) + [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) 4. Візьміть зациклювальну планку та вставте 4 вісця, щоб прикрутити до нижньої плати пізніше. - [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) + [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) 5. Now insert the battery holder and payload holders assembled in step 2 & 3 @@ -44,11 +44,11 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. Take the bottom plate and insert 4 M3\*14 screws and fasten the nylon standoffs on the same. - [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) + [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) 2. Розмістіть Планку розподілу живлення та використовуйте гайки-самостопорювачі для їх збирання. Модуль живлення PM02 (для Pixhawk 6C) буде живити цю плату - [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) + [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) 3. Use Socket Cap Screws M2.5\*6 and screw the bottom plate on the 4 hangers (that we inserted in the 2 bars on the 3rd step of the payload holder assembly) @@ -56,15 +56,15 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. Для збирання станції шасі відкрутіть заздалегідь складені винти шасі - перекрестна стрічка та вставте шасі - вертикальний стовп і затягніть той же. - [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) + [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) - [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) + [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) 2. Use the Socket Cap Screw M3\*8 to screw the landing gears to the bottom plate - [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) + [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) - [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) + [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) Оскільки важко вставити проводи після того, як верхня плита складена, зробіть проводку заздалегідь. Хоча дизайн добре спроектований таким чином, що ви зможете зробити це пізніше також. @@ -92,28 +92,28 @@ Pixhawk 6C запитується за допомогою плати живле 1. Поставити руки досить просто, оскільки двигуни поставляються вже зібраними. - - Переконайтесь, що у вас є правильна пронумерована рука з мотором на відповідному боці. + - Переконайтесь, що у вас є правильна пронумерована рука з мотором на відповідному боці. - [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) + [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) - :::tip - Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. + :::tip + Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. ::: 2. Возьміть одну руку та вставте прямокутний виступ всередину прямокутного порожнини на нижній плиті. - [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) + [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) 3. While inserting the top plate on top of this the 3 piece assembly (bottom plate, top plate & arms) have to screwed using Socket Cap Screw M3\*38 and Flange Locknut M3. 4. Утримуйте одну сторону, використовуючи міні-гайковий ключ, який надається у розробницькому комплекті. - [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) + [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) 5. Не зав'язуйте жодних болтів, поки всі 3 мотори не будуть на місці, оскільки це може зробити складним збирання 3-го та 4-го моторів. - [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) + [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) ### Пропелери @@ -132,13 +132,13 @@ Pixhawk 6C запитується за допомогою плати живле 1. Зберіть GPS, дотримуючись відео. - [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) + [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) - У цьому посібнику використовується місце кріплення GPS, запропоноване в посібнику Holybro. + У цьому посібнику використовується місце кріплення GPS, запропоноване в посібнику Holybro. 2. Screw the GPS mount’s bottom end on the payload holder side using Locknut M3 & Screw M3\*10 - [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) + [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) ### Pixhawk 6C diff --git a/docs/uk/frames_rover/index.md b/docs/uk/frames_rover/index.md index 39f404f32c..f2d7e9e4b7 100644 --- a/docs/uk/frames_rover/index.md +++ b/docs/uk/frames_rover/index.md @@ -57,15 +57,17 @@ Each wheel is driven by its own motor, and by controlling the speed and directio ## Дивіться також -- [Drive Modes](../flight_modes_rover/index.md). +- [Drive Modes](../flight_modes_rover/index.md) - [Configuration/Tuning](../config_rover/index.md) +- [Apps & API](../flight_modes_rover/api.md) - [Complete Vehicles](../complete_vehicles_rover/index.md) ## Симуляція -[Gazebo](../sim_gazebo_gz/index.md) provides simulations for ackermann and differential rovers: +PX4 provides synthetic simulation models for [Gazebo](../sim_gazebo_gz/index.md) of all three rover types to test the software and validate changes and new features: - [Ackermann rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) - [Differential rover](../sim_gazebo_gz/vehicles.md#differential-rover) +- [Mecanum rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) ![Rover gazebo simulation](../../assets/airframes/rover/rover_simulation.png) diff --git a/docs/uk/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md b/docs/uk/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md index 60d91fbff4..e21f612731 100644 --- a/docs/uk/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md +++ b/docs/uk/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md @@ -67,45 +67,45 @@ The _Falcon Vertigo Hybrid VTOL_ is a quadplane VTOL aircraft that has been desi 1. Нанесіть клей Gorilla всередину кронштейнів крила, як показано. - ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) + ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) 2. Вкріпіть карбонову трубку в держаки. Для вирівнювання піддона та трубки слід використовувати білу позначку (як показано на зображенні). - ::: info - This is very important because the white mark indicates the center of gravity. + ::: info + This is very important because the white mark indicates the center of gravity. ::: - + 3. Наступні зображення показують вирівнювання стержнів з інших точок зору: - ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) - ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) + ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) + ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) ### Крок 2: Прикріпіть крила 1. Вставте обидві вуглецеві труби в фюзеляж. - + 2. Нанесіть клей gorilla між двома білими позначками на кожну трубку (вказано червоними стрілками). Білий знак по центру (синя стрілка) буде розміщений в центрі фюзеляжу, а інші знаки - по боках. - + 3. Після того, як вуглецеві трубки знаходяться всередині фюзеляжу, розподіліть клей gorilla на решту трубки та прикріпіть крила. 4. Фюзеляж має два отвори для кабелів двигуна та сервоприводів. Пропустіть кабелі через отвори, а потім приєднайте крила до фюзеляжу. - + 5. Усередині фюзеляжу під'єднайте сигнальні кабелі, які ви щойно прокинули з крил до регулятора ESC, використовуючи надані роз'єми. Регулятори швидкості ESC вже підключені до двигунів і налаштовані на обертання в правильному порядку (вам потрібно буде підключити ESC PDB до модуля живлення на пізнішому етапі). - + 6. Так само, як і з ESC, сервопристосування вже встановлені. Підключіть сигнальний кабель з крила (проходить через фюзеляж) до контролера польоту. - + 7. Повторіть ці кроки для іньшого крила. @@ -123,11 +123,11 @@ General information about connecting Dropix can be found in [Dropix Flight Contr 1. Підключіть ЕСС до модуля живлення за допомогою роз'єму XT60 - + 2. Передайте кабелі сигналів до контролера польоту - + #### Підключення двигуна @@ -162,7 +162,7 @@ The geometry and output assignment can be configured in the [Actuators Configura 3. Підключіть кабель сигналу двигуна дроселя від ESC до відповідного допоміжного порту контролера польоту. Підключіть ESC до регулятора газу. - + 4. Підключіть приймач (RC IN). @@ -176,7 +176,7 @@ The geometry and output assignment can be configured in the [Actuators Configura 1. Підключіть телеметрію, датчик швидкості, GPS, гудок та безпечний перемикач, як показано. - + #### Контролер польоту: Підключіть модуль живлення та зовнішній USB @@ -184,7 +184,7 @@ The geometry and output assignment can be configured in the [Actuators Configura 1. Підключіть живлення та USB, як показано - + :::tip The external USB is optional. @@ -201,27 +201,27 @@ It is important that nothing obstructs airflow to the Pitot tube. Це крит 1. Встановіть трубку Піто у передній частині літака - + 2. Зафіксуйте з'єднуючі трубки та переконайтеся, що вони не зігнуті / пом'яті. - + 3. Підключіть трубки до датчика швидкості. - + #### Встановлення/підключення приймача та модуля телеметрії 1. Вставте приймач та телеметричний модуль на зовнішню сторону рами транспортного засобу. - + 2. Connect the receiver to the RC IN port on the _back_ of the dropix, as shown above (also see the [flight controller instructions](#dropix_back)). 3. Connect the telemetry module to the _front_ of the flight controller as shown below (see the [flight controller instructions](#dropix_front) for more detail on the pins). - + @@ -237,7 +237,7 @@ It is important that nothing obstructs airflow to the Pitot tube. Це крит 1. Встановіть орієнтацію вашого політ контролеру на 270 градусів. - + 2. Закріпіть контролер на місці за допомогою піни для поглинання вібрації. @@ -247,21 +247,21 @@ It is important that nothing obstructs airflow to the Pitot tube. Це крит 1. Перевірте, що двигуни обертаються у правильних напрямках (як у діаграмі QuadX нижче). - + - ::: info - If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). + ::: info + If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). ::: 2. Перевірте, чи транспортний засіб збалансований навколо очікуваного центру мас - - Утримуйте транспортний засіб пальцями у центрі ваги та переконайтеся, що транспортний засіб залишається стабільним. + - Утримуйте транспортний засіб пальцями у центрі ваги та переконайтеся, що транспортний засіб залишається стабільним. - ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) + ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) - - Якщо транспортний засіб нахиляється вперед або назад, перемістіть двигуни, щоб утримати рівновагу. + - Якщо транспортний засіб нахиляється вперед або назад, перемістіть двигуни, щоб утримати рівновагу. - ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) + ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) ## Налаштування @@ -271,7 +271,7 @@ Perform the normal [Basic Configuration](../config/index.md). 1. For [Airframe](../config/airframe.md) select the vehicle group/type as _Standard VTOL_ and the specific vehicle as [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) as shown below. - ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) + ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) 2. Set the [Autopilot Orientation](../config/flight_controller_orientation.md) to `ROTATION_YAW_270` as the autopilot is mounted [sideways](#flight_controller_orientation) with respect to the front of the vehicle. The compass is oriented forward, so you can leave that at the default (`ROTATION_NONE`). diff --git a/docs/uk/frames_vtol/vtol_quadplane_foxtech_loong_2160.md b/docs/uk/frames_vtol/vtol_quadplane_foxtech_loong_2160.md index aa5f8a1af4..8bd9b58c2d 100644 --- a/docs/uk/frames_vtol/vtol_quadplane_foxtech_loong_2160.md +++ b/docs/uk/frames_vtol/vtol_quadplane_foxtech_loong_2160.md @@ -99,33 +99,33 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот 1. Вставте 10x різьбових вкладок M3 в піддон, як показано на малюнку: - ![Основна плита з різбленими вставками](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) + ![Основна плита з різбленими вставками](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) 2. Вставте 2x різьбові вставки M3 в пристрій для накладання, як показано на зображенні нижче: - ![Фіксатор стекла з нарізними вкладками](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) + ![Фіксатор стекла з нарізними вкладками](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) 3. Вставте 2x різьбові вкладки M4 в кріплення вентилятора та кріплення радіо, як показано на малюнку нижче. - ![Кріплення радіо](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) + ![Кріплення радіо](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) - Якщо ви хочете додати 40-мм вентилятор з напругою 5 В на кріплення вентилятора, вставте 4x вставки M3. + Якщо ви хочете додати 40-мм вентилятор з напругою 5 В на кріплення вентилятора, вставте 4x вставки M3. - ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) + ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) 4. Змініть кабельний роз'єм на роз'єм для сервоприводу, щоб його можна було вставити в шину сервоприводу для живлення. - ::: info - Можливо знадобиться вентилятор, якщо використовується потужне радіо. + ::: info + Можливо знадобиться вентилятор, якщо використовується потужне радіо. ::: - ![Кріплення вентилятора](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) + ![Кріплення вентилятора](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) 5. Вилучіть оригінальну кронштейнну пластину з автомобіля. - Приклейте кабелі до зовнішньої частини фюзеляжу. + Приклейте кабелі до зовнішньої частини фюзеляжу. - ![Порожнє фюзеляж](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) + ![Порожнє фюзеляж](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) 6. Перемістіть підставку в транспортний засіб. @@ -142,9 +142,9 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот 1. Вилучіть корпус з 40A PM. 2. Зафіксуйте ПМ з 2x M2x6mm до нижньої пластини. 3. Створіть кабель для подовження роз'єму XT60 до XT30, який закріплений на базовій платі. - З цим, живлення від акумулятора 6S може бути підключено безпосередньо до роз'єму XT30 за допомогою попередньо налаштованого кабелю, що поставляється з транспортним засобом. + З цим, живлення від акумулятора 6S може бути підключено безпосередньо до роз'єму XT30 за допомогою попередньо налаштованого кабелю, що поставляється з транспортним засобом. - ![Встановлення модуля живлення 40A](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) + ![Встановлення модуля живлення 40A](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) Якщо потрібно, вихід 10V з радіопорту на PM також може бути викладений через XT30, який може бути встановлений поруч зі входом батареї 6S XT60. @@ -153,17 +153,17 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот #### Трубка Піто 1. Датчик може бути встановлений за допомогою 2x винтів M3x16мм в передньому правому куті підставки. - Піклуйтесь, щоб конектор був звернутий у бік центру фюзеляжу. + Піклуйтесь, щоб конектор був звернутий у бік центру фюзеляжу. - ![Встановлений датчик швидкості повітря](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) + ![Встановлений датчик швидкості повітря](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) - Лише передню трубу (не так, як показано на картинці) використовується; іншу трубу можна видалити, оскільки наш досвід показав, що тиск всередині фюзеляжу достатній як статичний тиск. + Лише передню трубу (не так, як показано на картинці) використовується; іншу трубу можна видалити, оскільки наш досвід показав, що тиск всередині фюзеляжу достатній як статичний тиск. 2. Коли стек встановлено всередині фюзеляжу, труба, що йде з крила, та труба, що йде з датчика швидкості повітря, повинні бути з'єднані разом. - Використовуйте трохи слини (це найлегший спосіб) щоб з'єднати їх разом, а потім використовуйте термоусадочну трубку, щоб посилити з'єднання. + Використовуйте трохи слини (це найлегший спосіб) щоб з'єднати їх разом, а потім використовуйте термоусадочну трубку, щоб посилити з'єднання. - :::warning - Використовуйте джерело тепла обережно, оскільки піна починаєтся танути при високих температурах. + :::warning + Використовуйте джерело тепла обережно, оскільки піна починаєтся танути при високих температурах. ::: @@ -175,22 +175,22 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот ::: 1. Позначте місце для встановлення лідару за допомогою скотчу або ручки. - Виріжте отвір всередині оболонки з ПВХ та піни, щоб лідар вміщувався на місце. + Виріжте отвір всередині оболонки з ПВХ та піни, щоб лідар вміщувався на місце. - ![Підготоване отвір лідару](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) + ![Підготоване отвір лідару](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) 2. Закріпіть лідар з гарячим клеєм. - ![Встановлений лідар](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) + ![Встановлений лідар](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) #### GPS/компас 1. Використовуйте двосторонній скотч для кріплення GPS на задній частині транспортного засобу під задньою засувкою. - ![Встановлений GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) + ![Встановлений GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) - Стрілка на GPS для орієнтації може бути проігнорована. - Орієнтацію буде визначено під час калібрування автопілота. + Стрілка на GPS для орієнтації може бути проігнорована. + Орієнтацію буде визначено під час калібрування автопілота. ### Політний контролер @@ -203,15 +203,15 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот #### Skynode 1. Використовуйте 4x гвинти M3x8 для кріплення Skynode до підстави. - Переконайтеся, що верхня частина "A" спрямована вперед транспортного засобу. + Переконайтеся, що верхня частина "A" спрямована вперед транспортного засобу. 2. Вставте 40-амперний модуль живлення в верхній з двох роз'ємів живлення. 3. Вставте один (або якщо потрібно, два) USB адаптери в 4-контактні роз'єми JST-GH на задній частині Skynode та прокладіть їх до передньої панелі. - Виправте кабелі за допомогою хомутів-ґудзиків на місці. + Виправте кабелі за допомогою хомутів-ґудзиків на місці. 4. Приклейте розгалужувач I2C до правої передньої сторони підставки (Розгалужувач може бути використаний для підключення пристроїв ETH, таких як радіозв'язок.) 5. Підключіть розгалужувач I2C до порту ETH на задній панелі Skynode. 6. Вставте два 40-контактних кабелі у передню частину Skynode. 7. Підключіть USB-C кабель подовження та згинайте його впереду. - Згин повинен бути дуже тугим, щоб пластина влізла в дрон. + Згин повинен бути дуже тугим, щоб пластина влізла в дрон. ![Встановлений Skynode](../../assets/airframes/vtol/foxtech_loong_2160/15-skynode.jpg) @@ -223,17 +223,17 @@ Foxtech Loong 2160 VTOL - це легкий у монтажі майже гот 1. Приклейте антени Skynode LTE до боку фюзеляжу, як показано на зображенні: - ![Антени LTE](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) + ![Антени LTE](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) 2. Якщо ви використовуєте модуль радіотелеметрії, ви можете встановити антени на верх фюзеляжу. - Зверху ви можете прямо встановити кабель подовження антени. + Зверху ви можете прямо встановити кабель подовження антени. - ![WIFI-Антени-Фронтальні](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) + ![WIFI-Антени-Фронтальні](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) - На задній частині ви можете використовувати адаптер антени з використанням технології 3D-друку. - Адаптер можна склеювати на місці гарячим клеєм. + На задній частині ви можете використовувати адаптер антени з використанням технології 3D-друку. + Адаптер можна склеювати на місці гарячим клеєм. - ![Задня WIFI антена](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) + ![Задня WIFI антена](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) ### Модуль потужності 12S diff --git a/docs/uk/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md b/docs/uk/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md index 5fc3ce782c..3ceb129558 100644 --- a/docs/uk/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md +++ b/docs/uk/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md @@ -93,7 +93,7 @@ ZMO FPV в його початковому стані. ### ESC регулятори швидкості 1. Відпаяйте сигнальні контакти PWM та контакти заземлення ESC регулятора швидкості та припаяйте до контактів подовжувач сервоприводу. - Кабель повинен бути достатньо довгим, щоб підключити дріт до контактів FMU плати керування польотом. + Кабель повинен бути достатньо довгим, щоб підключити дріт до контактів FMU плати керування польотом. 2. Розпаяйте 3 роз’єми «банан» заднього двигуна (може не знадобитися для інтеграції Pixhawk 6). @@ -103,17 +103,17 @@ ZMO FPV в його початковому стані. 5. Припаяйте сигнальні та GND-дроти до входу PWM ESC регулятора швидкості. - ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) + ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) 6. Зніміть гніздову вилку на ESC. - Це надасть вам більше місця для встановлення польотного контролера. + Це надасть вам більше місця для встановлення польотного контролера. - ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) + ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) 7. Припаяйте проводи заднього двигуна до ESC регулятора швидкості. - Переконайтеся, що підключаєте так, щоб двигун обертався у правильному напрямку. + Переконайтеся, що підключаєте так, щоб двигун обертався у правильному напрямку. - ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) + ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) ### З'єднувач крила @@ -122,9 +122,9 @@ ZMO FPV в його початковому стані. 1. Приклейте з'єднувачі крила до деталі, надрукованої на 3D-принтері, гарячим клеєм або 5 хвилинною епоксидною смолою. 2. Приклейте 3D-друковану частину разом із з'єднувачем у фюзеляж. - Переконайтеся, що правильно вирівняли з'єднувач, поки клей сохне. + Переконайтеся, що правильно вирівняли з'єднувач, поки клей сохне. - Найпростіший спосіб вирівняти роз'єм - встановити крило, поки клей застигає, але переконайтеся, що клей не потрапив між фюзеляжем і крилом, інакше крило може застрягти. + Найпростіший спосіб вирівняти роз'єм - встановити крило, поки клей застигає, але переконайтеся, що клей не потрапив між фюзеляжем і крилом, інакше крило може застрягти. Роз'єм, вклеєний у 3D-друковану частину @@ -137,58 +137,58 @@ ZMO FPV в його початковому стані. ### Плати адаптерів Pixhawk та BEC 1. Виріжте пінопласт, як показано на малюнках, щоб створити простір для кріплення адаптерних плат Pixhawk і BEC двостороннім скотчем. - Плата FMU розміщується зліва (у напрямку польоту) від фюзеляжу. - Зпаяйте серво конектор та кабель для напруги батареї до BEC. + Плата FMU розміщується зліва (у напрямку польоту) від фюзеляжу. + Зпаяйте серво конектор та кабель для напруги батареї до BEC. - ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) - ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) + ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) + ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) 2. Підготуйте BEC для підключення до IO плати та батареї. - BEC також можна припаяти безпосередньо до акумуляторних колодок ESC. + BEC також можна припаяти безпосередньо до акумуляторних колодок ESC. - ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) + ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) 3. Закріпіть BEC двостороннім скотчем. - ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) + ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) ### Кабелі 1. Відріжте роз’єми від сервоприводів і припаяйте подовжувачі сервоприводів до кабелів. - Переконайтеся, що кабелі достатньо довгі, щоб дістатися до адаптерної плати Pixhawk. - Якщо у вас є обтискний інструмент, ви також можете безпосередньо додати роз’єми без пайки. + Переконайтеся, що кабелі достатньо довгі, щоб дістатися до адаптерної плати Pixhawk. + Якщо у вас є обтискний інструмент, ви також можете безпосередньо додати роз’єми без пайки. 2. Під'єднайте кабелі сервоприводу до IO плати адаптера в такому порядку: - - 1 - Aileron left - - 2 - Aileron right - - 3 - V-Tail left - - 4 - V-Tail right - - 5 - Tilt left - - 6 - Tilt right + - 1 - Aileron left + - 2 - Aileron right + - 3 - V-Tail left + - 4 - V-Tail right + - 5 - Tilt left + - 6 - Tilt right 3. Під'єднайте сигнальні кабелі мотора до адаптерної плати FMU у такому порядку: - - 1 - Передній лівий - - 2 - Передній правий - - 3 - Задній + - 1 - Передній лівий + - 2 - Передній правий + - 3 - Задній ### Датчики #### Трубка Піто 1. Спочатку перевірте, чи трубка Піто влазить у кріплення, надруковане на 3D-принтері. - Якщо це так, то приклейте трубку Піто на місце у кріплення. + Якщо це так, то приклейте трубку Піто на місце у кріплення. - Щоб вирівняти трубку пропустіть її через другий отвір праворуч від передньої пластини FPV. - Кріплення дозволить вам вдавити трубку назад у фюзеляж, щоб захистити її під час транспортування та обробки. - Датчик може бути встановлений зверху на кріпленні, надрукованому на 3D-принтері, за допомогою двостороннього скотчу. + Щоб вирівняти трубку пропустіть її через другий отвір праворуч від передньої пластини FPV. + Кріплення дозволить вам вдавити трубку назад у фюзеляж, щоб захистити її під час транспортування та обробки. + Датчик може бути встановлений зверху на кріпленні, надрукованому на 3D-принтері, за допомогою двостороннього скотчу. 2. Приклейте кріплення, надруковане на 3D-принтері, на місце. - ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) + ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) 3. Датчик може бути встановлений зверху на кріпленні, надрукованому на 3D-принтері. - ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) + ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) #### Лідар @@ -209,9 +209,9 @@ ZMO FPV в його початковому стані. 2. Вийміть GPS із пластикового корпусу та від’єднайте роз’єм. 3. Протягніть кабель через вуглецевий лонжерон. 4. Glue the 3D-Printed part with 5 min epoxy in place. - ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) + ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) 5. After the glue has cured, screw the GPS with 4x M2.5x10 screws to the plate. - ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) + ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) #### USB Камера @@ -219,9 +219,9 @@ ZMO FPV в його початковому стані. 2. Відріжте кабель USB-адаптера на 25 см і спаяйте два кабелі між собою. 3. Для встановлення камери потрібно вирізати отвір у пінопласті перегородки. - ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) + ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) - Потім ви можете закріпити камеру на перегородці за допомогою двостороннього скотча. + Потім ви можете закріпити камеру на перегородці за допомогою двостороннього скотча. ### Політний контролер @@ -237,7 +237,7 @@ ZMO FPV в його початковому стані. 1. Помістіть його на верхню частину ESC і позначте 2 задніх місця кріплення на литій пластиковій частині ZMO. 2. Remove the Skynode from the vehicle and drill 2 holes with a 2.8 mm drill bit into the plastic part. - ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) + ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) 3. Встановіть Skynode на місце і прикрутіть його 2-ма гвинтами M3x10. Інший варіант - додати в отвори різьбові вставки. @@ -245,9 +245,9 @@ ZMO FPV в його початковому стані. 1. Прикрутіть переднє кріплення Skynode 2-ма гвинтами M3x10 до Skynode. 2. Потім додайте трохи епоксидного клею на 5 хвилин в нижню частину кріплення і покладіть вантаж зверху на Skynode, поки клей не затвердіє. - Щоб отримати доступ до 2 кріпильних гвинтів спереду, проткніть 2 отвори зверху через пінопласт. + Щоб отримати доступ до 2 кріпильних гвинтів спереду, проткніть 2 отвори зверху через пінопласт. - ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) + ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) ### Антени та RC приймач @@ -258,14 +258,14 @@ An inexpensive example would be a [SiK Telemetry Radio](../telemetry/sik_radio.m ::: 1. Одна антена LTE може бути встановлена в нижній частині транспортного засобу. - Для цього ви можете протягнути дріт антени через отвір для радіатора ESC. + Для цього ви можете протягнути дріт антени через отвір для радіатора ESC. - ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) + ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) 2. Другу антену можна встановити всередині транспортного засобу з лівого боку акумуляторного відсіку. - Пульт дистанційного керування також можна розмістити з лівого боку батарейного відсіку. + Пульт дистанційного керування також можна розмістити з лівого боку батарейного відсіку. - ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) + ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) ## Налаштування програмного забезпечення @@ -332,9 +332,9 @@ The airspeed sensor can be enabled in the [Parameters](../advanced_config/parame 1. Switch the vehicle into manual mode (either via the flight mode switch or type `commander mode manual` into the MAVLink shell). 2. Перевірте, чи двигуни спрямовані вгору. - Якщо двигуни спрямовані вперед, то пов'язані з ними сервоприводи нахилу потрібно змінити на протилежні (встановіть прапорець біля кожного сервоприводу). + Якщо двигуни спрямовані вперед, то пов'язані з ними сервоприводи нахилу потрібно змінити на протилежні (встановіть прапорець біля кожного сервоприводу). - ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) + ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) 3. Adjust the minimum (or, if revesed: maximum) value such that the rotor thrust can point backward (needed for proper yaw allocation in Multicopter mode). diff --git a/docs/uk/gps_compass/ark_dan_gps.md b/docs/uk/gps_compass/ark_dan_gps.md new file mode 100644 index 0000000000..2f43a0ae45 --- /dev/null +++ b/docs/uk/gps_compass/ark_dan_gps.md @@ -0,0 +1,62 @@ +# ARK DAN GPS + +[ARK DAN GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox DAN-F10N GPS and industrial magnetometer. + +![ARK DAN GPS](../../assets/hardware/gps/ark/ark_dan_gps.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-dan-gps/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DAN_GPS) +- Датчики + - [u-blox DAN-F10N](https://www.u-blox.com/en/product/dan-f10n-module) + - L1/L5/E5a/B2a bands + - Consistently strong performance regardless of installation + - Integrated SAW-LNA-SAW for exceptional out-of-band jamming immunity + - u-blox F10 proprietary dual-band multipath mitigation technology + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Вимоги до живлення + - 5V + - 25mA Average + - 44mA Max +- LED індикатори + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## Налаштування обладнання + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## Конфігурація PX4 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## Схема розташування виводів + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Напруга | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## Дивіться також + +- [ARK DAN GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) (ARK Docs) diff --git a/docs/uk/gps_compass/ark_sam_gps.md b/docs/uk/gps_compass/ark_sam_gps.md index 1c2dd46535..245e039c73 100644 --- a/docs/uk/gps_compass/ark_sam_gps.md +++ b/docs/uk/gps_compass/ark_sam_gps.md @@ -1,6 +1,6 @@ # ARK SAM GPS -[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps>) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. +[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. ![ARK SAM GPS](../../assets/hardware/gps/ark/ark_sam_gps.jpg) diff --git a/docs/uk/gps_compass/ark_sam_gps_mini.md b/docs/uk/gps_compass/ark_sam_gps_mini.md new file mode 100644 index 0000000000..937ae659d1 --- /dev/null +++ b/docs/uk/gps_compass/ark_sam_gps_mini.md @@ -0,0 +1,61 @@ +# ARK SAM GPS MINI + +[ARK SAM GPS MINI](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. + +![ARK SAM GPS MINI](../../assets/hardware/gps/ark/ark_sam_gps_mini.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-sam-gps-mini/) (US) + +## Характеристики обладнання + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_SAM_GPS/tree/main) +- Датчики + - [u-blox SAM-M10Q](https://www.u-blox.com/en/product/sam-m10q-module) + - Less than 38 mW power consumption without compromising GNSS performance + - Maximum position availability with 4 concurrent GNSS reception + - Просунуте виявлення підробки сигналу та перешкод + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Вимоги до живлення + - 5V + - 15mA Average + - 20mA Max +- LED індикатори + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## Налаштування обладнання + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## Конфігурація PX4 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## Схема розташування виводів + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Напруга | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## Дивіться також + +- [ARK SAM GPS MINI Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) (ARK Docs) diff --git a/docs/uk/gps_compass/index.md b/docs/uk/gps_compass/index.md index e1c2339a67..722af9a4e5 100644 --- a/docs/uk/gps_compass/index.md +++ b/docs/uk/gps_compass/index.md @@ -25,7 +25,9 @@ PX4 повинен працювати з будь-яким пристроєм, | Пристрій | GPS | Компас | [CAN](../dronecan/index.md) | Buzzer / SafeSw / LED | Примітки | | :----------------------------------------------------------- | :---------: | :-----------------------: | :-------------------------: | :-------------------: | :------------------------------------------------------------- | | [ARK GPS](../dronecan/ark_gps.md) | M9N | BMM150 | ✓ | ✓ | + Baro, IMU | +| [ARK DAN GPS](../gps_compass/ark_dan_gps.md) | DAN-F10N | IIS2MDC | | ✓ | | | [ARK SAM GPS](../gps_compass/ark_sam_gps.md) | SAM-M10Q | IIS2MDC | | ✓ | | +| [ARK SAM GPS MINI ](../gps_compass/ark_sam_gps_mini.md) | SAM-M10Q | IIS2MDC | | ✓ | | | [ARK TESEO GPS](../dronecan/ark_teseo_gps.md) | Teseo-LIV4F | BMM150 | ✓ | ✓ | + Baro, IMU | | [Avionics Anonymous UAVCAN GNSS/Mag][avionics_anon_can_gnss] | SAM-M8Q | MMC5983MA | ✓ | ✘ | | | [CUAV NEO 3 GPS](../gps_compass/gps_cuav_neo_3.md) | M9N | IST8310 | | ✓ | | @@ -145,21 +147,21 @@ To ensure the port is set up correctly perform a [Serial Port Configuration](../ The following steps show how to configure a secondary GPS on the `GPS 2` port in _QGroundControl_: 1. [Find and set](../advanced_config/parameters.md) the parameter [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) to **GPS 2**. - - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. - - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. + - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. + - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. - ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) + ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) 2. Перезавантажте апарат, щоб побачити інші параметри. 3. Select the **Serial** tab, and open the [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD) parameter (`GPS 2` port baud rate): set it to _Auto_ (or 115200 for the Trimble). - ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) + ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) Після налаштування другого GPS-порту: 1. Налаштуйте обчислювач ECL/EKF2, щоб об'єднати дані з обох GPS-систем. - For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). + For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). ### DroneCAN GNSS Configuration @@ -197,11 +199,21 @@ It is possible to have low DOP (good satellite geometry) but still have high EPH EPH/EPV values therefore provide a more immediate and practical estimate of the actual GPS accuracy you can expect under current conditions. +### GNSS Position Fusion + +GNSS position fusion will not begin until yaw alignment is established. +If a magnetometer is available, the EKF aligns yaw using the magnetic heading, allowing GPS position fusion to start soon after boot. +If no magnetometer is present, the system must rely on GPS yaw (from a dual-antenna setup) or movement-based yaw estimation. +Until one of these provides a valid heading, the EKF will not start GPS position fusion, and the vehicle will remain in a “no position” state even though attitude data is valid. +This behavior prevents large position errors that could occur when the yaw reference is uncertain. + ## Інформація для розробників - GPS/RTK-GPS - [RTK-GPS](../advanced/rtk_gps.md) + - [PPS Time Synchronization](../advanced/pps_time_sync.md) - [GPS driver](../modules/modules_driver.md#gps) + - [PPS driver](../modules/modules_driver.md#pps-capture) - [DroneCAN Example](../dronecan/index.md) - Компас - [Driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/magnetometer) (Compasses) diff --git a/docs/uk/gps_compass/magnetometer.md b/docs/uk/gps_compass/magnetometer.md index f7f12e2026..42d0d72b4e 100644 --- a/docs/uk/gps_compass/magnetometer.md +++ b/docs/uk/gps_compass/magnetometer.md @@ -40,6 +40,7 @@ PX4 можна використовувати з багатьма деталям | Пристрій | Компас | DroneCan | | :-------------------------------------------------------------------------------------------------------------- | :----: | :------: | +| [ARK MAG](https://arkelectron.com/product/ark-mag/) | RM3100 | ✓ | | [Магнітометр UAVCAN Avionics Anonymous](https://www.tindie.com/products/avionicsanonymous/uavcan-magnetometer/) | ? | | | [Компас/Магнітометр Holybro DroneCAN RM3100](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | | [RaccoonLab DroneCAN/Cyphal Magnetometer RM3100](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | diff --git a/docs/uk/gps_compass/rtk_gps.md b/docs/uk/gps_compass/rtk_gps.md index ff709d76a0..4366911cb5 100644 --- a/docs/uk/gps_compass/rtk_gps.md +++ b/docs/uk/gps_compass/rtk_gps.md @@ -20,50 +20,59 @@ PX4 supports the [u-blox M8P](https://www.u-blox.com/en/product/neo-m8p), [u-blo Таблиця вказує пристрої, які також виводять курсову відмітку, а також можуть надавати курсову відмітку, коли використовуються дві одиниці на транспортному засобі. Він також відзначає пристрої, які підключаються через CAN шину, та ті, які підтримують PPK (пост-процесуальну кінематику). -| Пристрій | GPS | Компас | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :------: | :------------------------------: | :-----------------------------------------------: | :-: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| Пристрій | GPS | Компас | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :--------: | :---------------------------------: | :-: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK Примітки: @@ -122,35 +131,36 @@ This should be set by default, but if not, follow the [MAVLink2 configuration in Підключення RTK GPS насправді просте: 1. Start _QGroundControl_ and attach the base RTK GPS via USB to the ground station. - Пристрій визнається автоматично. + Пристрій визнається автоматично. 2. Start the vehicle and make sure it is connected to _QGroundControl_. - :::tip - _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). - Іконка червона, поки налаштовується RTK, а потім змінюється на білу, коли RTK GPS активний. - Ви можете натиснути на піктограму, щоб побачити поточний стан та точність RTK. + :::tip + _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). + Іконка червона, поки налаштовується RTK, а потім змінюється на білу, коли RTK GPS активний. + Ви можете натиснути на піктограму, щоб побачити поточний стан та точність RTK. ::: 3. _QGroundControl_ then starts the RTK setup process (known as "Survey-In"). - Survey-In - це процедура запуску для отримання точної оцінки положення базової станції. - The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). + Survey-In - це процедура запуску для отримання точної оцінки положення базової станції. + The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). - Ви можете відстежити прогрес, натиснувши на піктограму стану RTK GPS. + Ви можете відстежити прогрес, натиснувши на піктограму стану RTK GPS. - ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) + ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. Після завершення опитування: - - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - - Транспортний GPS переходить у режим RTK. - The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) - ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) + - Транспортний GPS переходить у режим RTK. + The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + + ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) ### Налаштування GPS як Джерело розділення/Курсування @@ -205,7 +215,7 @@ You can save and reuse a base position in order to save time: perform Survey-In Для забезпечення використання MAVLink2: - Update the telemetry module firmware to the latest version (see [QGroundControl > Setup > Firmware](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/firmware.html)). -- Set [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) +- Ensure [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) is set to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) #### Вдосконалення diff --git a/docs/uk/hardware/board_support_guide.md b/docs/uk/hardware/board_support_guide.md index b1b0aeb4a5..9d1f1854db 100644 --- a/docs/uk/hardware/board_support_guide.md +++ b/docs/uk/hardware/board_support_guide.md @@ -33,8 +33,8 @@ Boards that are not compliant with the requirements are [unsupported](#unsupport 6. Достатня документація, яка включає, але не обмежується: - Повний підключення, яке стало доступним для громадськості, яке відображає PX4 визначення контактів на: - 1. Піни мікроконтролера - 2. Фізичні зовнішні роз'ємники + 1. Піни мікроконтролера + 2. Фізичні зовнішні роз'ємники - A block diagram or full schematic of the main components (sensors, power supply, etc.) that allows to infer software requirements and boot order - Посібник з використання готового продукту diff --git a/docs/uk/hardware/porting_guide_nuttx.md b/docs/uk/hardware/porting_guide_nuttx.md index 38b250b741..ab4a1afa0e 100644 --- a/docs/uk/hardware/porting_guide_nuttx.md +++ b/docs/uk/hardware/porting_guide_nuttx.md @@ -62,30 +62,30 @@ To run `qconfig` you may need to install additional Qt dependencies. 2. Завантажте вихідний код і переконайтеся, що ви можете зібрати існуючу ціль: - ```sh - git clone --recursive https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + git clone --recursive https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + make px4_fmu-v5 + ``` 3. Знаходьте існуючу ціль, яка використовує той самий (або тісно пов'язаний) тип ЦП, і скопіюйте її. - Наприклад для STM32F7: + Наприклад для STM32F7: - ```sh - mkdir boards/manufacturer - cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 - ``` + ```sh + mkdir boards/manufacturer + cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 + ``` - Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. + Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. Next you need to go through all files under **boards/manufacturer/my-target-v1** and update them according to your board. 1. **firmware.prototype**: update the board ID and name 2. **default.px4board**: update the **VENDOR** and **MODEL** to match the directory names (**my-target-v1**). - Налаштування послідовних портів. + Налаштування послідовних портів. 3. Configure NuttX (**defconfig**) via `make manufacturer_my-target-v1 menuconfig`: Adjust the CPU and chip, configure the peripherals (UART's, SPI, I2C, ADC). 4. **nuttx-config/include/board.h**: Configure the NuttX pins. - Для всіх зовнішніх пристроїв з кількома варіантами контактів, NuttX повинен знати контакт. - They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). + Для всіх зовнішніх пристроїв з кількома варіантами контактів, NuttX повинен знати контакт. + They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). 5. **src**: go through all files under **src** and update them as needed, in particular **board_config.h**. 6. **init/rc.board_sensors**: start the sensors that are attached to the board. diff --git a/docs/uk/index.md b/docs/uk/index.md index 6bba5ae0dc..b0ec59c754 100644 --- a/docs/uk/index.md +++ b/docs/uk/index.md @@ -1,3 +1,8 @@ + +
# Посібник користувача автопілота PX4 @@ -8,17 +13,22 @@ PX4 is the _Professional Autopilot_. Розроблений розробниками світового класу з дрон індустрії та наукових закладів і активно підтримується спільнотою у світі. Він дозволяє працювати з різними типами безпілотних транспортних засобів від гоночних, вантажних дронів до сухопутних автомобілів та надводних човнів. :::tip -This guide contains everything you need to assemble, configure, and safely fly a PX4-based vehicle. Хочете зробити внесок? Check out the [Development](development/development.md) section. - +This guide contains everything you need to assemble, configure, and safely fly a PX4-based vehicle. +Хочете зробити внесок? Check out the [Development](development/development.md) section. ::: +
+ :::warning + This guide is for the _development_ version of PX4 (`main` branch). Use the **Version** selector to find the current _stable_ version. Documented changes since the stable release are captured in the evolving [release note](releases/main.md). ::: +
+ ## Як почати? [Basic Concepts](getting_started/px4_basic_concepts.md) should be read by all users! diff --git a/docs/uk/mavlink/standard_modes.md b/docs/uk/mavlink/standard_modes.md index 404e8e97c8..f04314dafd 100644 --- a/docs/uk/mavlink/standard_modes.md +++ b/docs/uk/mavlink/standard_modes.md @@ -2,7 +2,7 @@ -PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.md) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). +PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.html) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). The protocol allows you to discover all flight modes available to the vehicle, including PX4 External modes created using the [PX4 ROS 2 Control Interface](../ros2/px4_ros2_control_interface.md), and get or set the current mode. diff --git a/docs/uk/middleware/dds_topics.md b/docs/uk/middleware/dds_topics.md index 1feef1a6b1..02481cb7d5 100644 --- a/docs/uk/middleware/dds_topics.md +++ b/docs/uk/middleware/dds_topics.md @@ -10,32 +10,35 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git ## Publications -| Topic | Тип | Rate Limit | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | -| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | -| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | -| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | -| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | -| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | -| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | -| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | -| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | -| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | -| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | -| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | -| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | -| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | | -| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | -| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | -| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | -| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | -| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | -| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | | -| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | -| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | -| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | -| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| Topic | Тип | Rate Limit | +| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | +| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | +| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | +| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | +| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | +| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | +| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | +| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | +| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | +| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | +| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | +| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | +| `/fmu/out/transponder_report` | [px4_msgs::msg::TransponderReport](../msg_docs/TransponderReport.md) | | +| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | +| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | 50.0 | +| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | +| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | +| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | +| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | +| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | +| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | 100.0 | +| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | +| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | +| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | +| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| `/fmu/out/wind` | [px4_msgs::msg::Wind](../msg_docs/Wind.md) | 1.0 | +| `/fmu/out/gimbal_device_attitude_status` | [px4_msgs::msg::GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) | 20.0 | ## Subscriptions @@ -72,6 +75,13 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git | /fmu/in/fixed_wing_lateral_setpoint | [px4_msgs::msg::FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) | | /fmu/in/longitudinal_control_configuration | [px4_msgs::msg::LongitudinalControlConfiguration](../msg_docs/LongitudinalControlConfiguration.md) | | /fmu/in/lateral_control_configuration | [px4_msgs::msg::LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) | +| /fmu/in/rover_position_setpoint | [px4_msgs::msg::RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | +| /fmu/in/rover_speed_setpoint | [px4_msgs::msg::RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | +| /fmu/in/rover_attitude_setpoint | [px4_msgs::msg::RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | +| /fmu/in/rover_rate_setpoint | [px4_msgs::msg::RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | +| /fmu/in/rover_throttle_setpoint | [px4_msgs::msg::RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | +| /fmu/in/rover_steering_setpoint | [px4_msgs::msg::RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| /fmu/in/landing_gear | [px4_msgs::msg::LandingGear](../msg_docs/LandingGear.md) | ## Subscriptions Multi @@ -85,193 +95,192 @@ They are not build into the module, and hence are neither published or subscribe :::details See messages -- [SensorCorrection](../msg_docs/SensorCorrection.md) -- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) -- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) -- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) -- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) -- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) -- [Px4ioStatus](../msg_docs/Px4ioStatus.md) -- [SatelliteInfo](../msg_docs/SatelliteInfo.md) -- [GeofenceResult](../msg_docs/GeofenceResult.md) -- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) -- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) -- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) -- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) -- [EventV0](../msg_docs/EventV0.md) -- [QshellRetval](../msg_docs/QshellRetval.md) -- [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) -- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) -- [RcChannels](../msg_docs/RcChannels.md) -- [SensorAccel](../msg_docs/SensorAccel.md) -- [GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) -- [EscStatus](../msg_docs/EscStatus.md) -- [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) -- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) -- [AirspeedWind](../msg_docs/AirspeedWind.md) -- [InputRc](../msg_docs/InputRc.md) -- [GpioIn](../msg_docs/GpioIn.md) -- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) -- [VehicleImu](../msg_docs/VehicleImu.md) -- [Event](../msg_docs/Event.md) -- [SensorUwb](../msg_docs/SensorUwb.md) -- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) -- [DatamanResponse](../msg_docs/DatamanResponse.md) -- [OrbTest](../msg_docs/OrbTest.md) -- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) -- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) -- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) -- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) -- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [BatteryInfo](../msg_docs/BatteryInfo.md) - [TakeoffStatus](../msg_docs/TakeoffStatus.md) -- [UlogStreamAck](../msg_docs/UlogStreamAck.md) -- [OrbTestLarge](../msg_docs/OrbTestLarge.md) -- [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) +- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md) +- [Airspeed](../msg_docs/Airspeed.md) +- [PpsCapture](../msg_docs/PpsCapture.md) +- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) - [CameraCapture](../msg_docs/CameraCapture.md) -- [VehicleRoi](../msg_docs/VehicleRoi.md) -- [ActuatorArmed](../msg_docs/ActuatorArmed.md) -- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) -- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) -- [GeofenceStatus](../msg_docs/GeofenceStatus.md) -- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) -- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) -- [PowerMonitor](../msg_docs/PowerMonitor.md) -- [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) -- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) -- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) -- [TecsStatus](../msg_docs/TecsStatus.md) -- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) -- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) -- [Ping](../msg_docs/Ping.md) -- [LedControl](../msg_docs/LedControl.md) -- [Wind](../msg_docs/Wind.md) -- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) -- [ActuatorTest](../msg_docs/ActuatorTest.md) -- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) -- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) -- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) -- [Gripper](../msg_docs/Gripper.md) -- [SensorMag](../msg_docs/SensorMag.md) -- [DebugValue](../msg_docs/DebugValue.md) -- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) -- [RcParameterMap](../msg_docs/RcParameterMap.md) -- [LandingGear](../msg_docs/LandingGear.md) -- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) +- [Px4ioStatus](../msg_docs/Px4ioStatus.md) +- [FuelTankStatus](../msg_docs/FuelTankStatus.md) +- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) - [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md) -- [UlogStream](../msg_docs/UlogStream.md) -- [GimbalControls](../msg_docs/GimbalControls.md) -- [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) -- [LogMessage](../msg_docs/LogMessage.md) -- [RoverVelocitySetpoint](../msg_docs/RoverVelocitySetpoint.md) +- [AirspeedWind](../msg_docs/AirspeedWind.md) +- [OrbTest](../msg_docs/OrbTest.md) +- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) - [GpioOut](../msg_docs/GpioOut.md) -- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) +- [Gripper](../msg_docs/Gripper.md) +- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [TuneControl](../msg_docs/TuneControl.md) +- [DebugVect](../msg_docs/DebugVect.md) +- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) +- [HomePositionV0](../msg_docs/HomePositionV0.md) +- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) +- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) +- [EstimatorBias](../msg_docs/EstimatorBias.md) +- [GpioConfig](../msg_docs/GpioConfig.md) +- [SystemPower](../msg_docs/SystemPower.md) +- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) +- [MissionResult](../msg_docs/MissionResult.md) +- [PowerButtonState](../msg_docs/PowerButtonState.md) +- [EscStatus](../msg_docs/EscStatus.md) +- [HealthReport](../msg_docs/HealthReport.md) +- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) +- [SensorGyro](../msg_docs/SensorGyro.md) +- [GpioRequest](../msg_docs/GpioRequest.md) +- [DebugKeyValue](../msg_docs/DebugKeyValue.md) +- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) +- [ParameterUpdate](../msg_docs/ParameterUpdate.md) +- [SensorAirflow](../msg_docs/SensorAirflow.md) +- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) +- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) +- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) +- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) +- [ActionRequest](../msg_docs/ActionRequest.md) +- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) +- [PwmInput](../msg_docs/PwmInput.md) +- [PowerMonitor](../msg_docs/PowerMonitor.md) +- [Mission](../msg_docs/Mission.md) +- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) +- [FigureEightStatus](../msg_docs/FigureEightStatus.md) +- [RadioStatus](../msg_docs/RadioStatus.md) +- [VehicleRoi](../msg_docs/VehicleRoi.md) +- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) +- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) +- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) +- [Rpm](../msg_docs/Rpm.md) +- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) +- [Ping](../msg_docs/Ping.md) +- [QshellReq](../msg_docs/QshellReq.md) +- [SensorMag](../msg_docs/SensorMag.md) +- [EstimatorStates](../msg_docs/EstimatorStates.md) +- [SensorUwb](../msg_docs/SensorUwb.md) +- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) +- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) +- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) +- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) +- [SensorHygrometer](../msg_docs/SensorHygrometer.md) +- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) +- [AdcReport](../msg_docs/AdcReport.md) +- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md) +- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) +- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) +- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) +- [SensorCorrection](../msg_docs/SensorCorrection.md) +- [UlogStream](../msg_docs/UlogStream.md) +- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) +- [GpsInjectData](../msg_docs/GpsInjectData.md) +- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) +- [LoggerStatus](../msg_docs/LoggerStatus.md) +- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) +- [SensorBaro](../msg_docs/SensorBaro.md) +- [OrbTestMedium](../msg_docs/OrbTestMedium.md) +- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) +- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) +- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) +- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) +- [UlogStreamAck](../msg_docs/UlogStreamAck.md) +- [DatamanRequest](../msg_docs/DatamanRequest.md) +- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) +- [PositionSetpoint](../msg_docs/PositionSetpoint.md) +- [DatamanResponse](../msg_docs/DatamanResponse.md) +- [LedControl](../msg_docs/LedControl.md) +- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) +- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md) +- [Event](../msg_docs/Event.md) +- [ActuatorArmed](../msg_docs/ActuatorArmed.md) +- [GpioIn](../msg_docs/GpioIn.md) +- [SensorGyroFft](../msg_docs/SensorGyroFft.md) +- [SensorAccel](../msg_docs/SensorAccel.md) +- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) +- [GeneratorStatus](../msg_docs/GeneratorStatus.md) +- [DifferentialPressure](../msg_docs/DifferentialPressure.md) +- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) +- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) +- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) +- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) +- [RoverRateStatus](../msg_docs/RoverRateStatus.md) +- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) +- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) - [VelocityLimits](../msg_docs/VelocityLimits.md) - [MagWorkerData](../msg_docs/MagWorkerData.md) -- [ParameterUpdate](../msg_docs/ParameterUpdate.md) -- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) -- [SensorBaro](../msg_docs/SensorBaro.md) -- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) -- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) -- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) -- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) -- [Rpm](../msg_docs/Rpm.md) -- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) -- [MountOrientation](../msg_docs/MountOrientation.md) -- [ActionRequest](../msg_docs/ActionRequest.md) -- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) -- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) -- [LoggerStatus](../msg_docs/LoggerStatus.md) -- [GeneratorStatus](../msg_docs/GeneratorStatus.md) -- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) -- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) -- [LandingTargetPose](../msg_docs/LandingTargetPose.md) -- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) -- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) -- [OrbitStatus](../msg_docs/OrbitStatus.md) -- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) -- [EstimatorStatus](../msg_docs/EstimatorStatus.md) -- [DatamanRequest](../msg_docs/DatamanRequest.md) -- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) -- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) -- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) - [Cpuload](../msg_docs/Cpuload.md) -- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) -- [RoverRateStatus](../msg_docs/RoverRateStatus.md) -- [EscReport](../msg_docs/EscReport.md) -- [DebugArray](../msg_docs/DebugArray.md) -- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) -- [SensorHygrometer](../msg_docs/SensorHygrometer.md) -- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) -- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) -- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) -- [QshellReq](../msg_docs/QshellReq.md) -- [CameraStatus](../msg_docs/CameraStatus.md) -- [GpsInjectData](../msg_docs/GpsInjectData.md) -- [FigureEightStatus](../msg_docs/FigureEightStatus.md) -- [TransponderReport](../msg_docs/TransponderReport.md) -- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) +- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) - [MavlinkLog](../msg_docs/MavlinkLog.md) -- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) -- [FuelTankStatus](../msg_docs/FuelTankStatus.md) -- [Mission](../msg_docs/Mission.md) -- [PositionSetpoint](../msg_docs/PositionSetpoint.md) -- [MissionResult](../msg_docs/MissionResult.md) -- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) -- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) -- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) -- [DifferentialPressure](../msg_docs/DifferentialPressure.md) -- [CellularStatus](../msg_docs/CellularStatus.md) -- [GpsDump](../msg_docs/GpsDump.md) -- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) -- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) -- [NavigatorStatus](../msg_docs/NavigatorStatus.md) -- [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) -- [FollowTarget](../msg_docs/FollowTarget.md) -- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) -- [EstimatorStates](../msg_docs/EstimatorStates.md) -- [SensorGyro](../msg_docs/SensorGyro.md) -- [SensorAirflow](../msg_docs/SensorAirflow.md) -- [ButtonEvent](../msg_docs/ButtonEvent.md) -- [DebugKeyValue](../msg_docs/DebugKeyValue.md) -- [GpioConfig](../msg_docs/GpioConfig.md) -- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [SensorTemp](../msg_docs/SensorTemp.md) - [LandingGearWheel](../msg_docs/LandingGearWheel.md) -- [VehicleConstraints](../msg_docs/VehicleConstraints.md) -- [HealthReport](../msg_docs/HealthReport.md) -- [PowerButtonState](../msg_docs/PowerButtonState.md) -- [RadioStatus](../msg_docs/RadioStatus.md) -- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) -- [EstimatorBias](../msg_docs/EstimatorBias.md) -- [DebugVect](../msg_docs/DebugVect.md) -- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) -- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) -- [PpsCapture](../msg_docs/PpsCapture.md) -- [SensorSelection](../msg_docs/SensorSelection.md) -- [SystemPower](../msg_docs/SystemPower.md) -- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) -- [SensorGyroFft](../msg_docs/SensorGyroFft.md) -- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [OrbTestLarge](../msg_docs/OrbTestLarge.md) - [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md) -- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) -- [GpioRequest](../msg_docs/GpioRequest.md) -- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) -- [RtlStatus](../msg_docs/RtlStatus.md) -- [Airspeed](../msg_docs/Airspeed.md) -- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) -- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) -- [IrlockReport](../msg_docs/IrlockReport.md) -- [HeaterStatus](../msg_docs/HeaterStatus.md) -- [AdcReport](../msg_docs/AdcReport.md) -- [PwmInput](../msg_docs/PwmInput.md) -- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) -- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) -- [OrbTestMedium](../msg_docs/OrbTestMedium.md) -- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) -- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) -- [TuneControl](../msg_docs/TuneControl.md) -- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [CellularStatus](../msg_docs/CellularStatus.md) +- [QshellRetval](../msg_docs/QshellRetval.md) +- [OrbitStatus](../msg_docs/OrbitStatus.md) +- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) +- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) +- [LogMessage](../msg_docs/LogMessage.md) +- [SatelliteInfo](../msg_docs/SatelliteInfo.md) +- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) +- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) +- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) +- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md) +- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) +- [EstimatorStatus](../msg_docs/EstimatorStatus.md) +- [NeuralControl](../msg_docs/NeuralControl.md) +- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [RcParameterMap](../msg_docs/RcParameterMap.md) +- [SensorSelection](../msg_docs/SensorSelection.md) +- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) +- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) +- [ActuatorTest](../msg_docs/ActuatorTest.md) +- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) +- [MountOrientation](../msg_docs/MountOrientation.md) +- [CameraStatus](../msg_docs/CameraStatus.md) - [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md) -- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) -- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [FollowTarget](../msg_docs/FollowTarget.md) +- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) +- [ButtonEvent](../msg_docs/ButtonEvent.md) +- [DebugArray](../msg_docs/DebugArray.md) +- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) +- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) +- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) +- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) +- [VehicleImu](../msg_docs/VehicleImu.md) +- [GpsDump](../msg_docs/GpsDump.md) +- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) +- [DebugValue](../msg_docs/DebugValue.md) +- [LandingTargetPose](../msg_docs/LandingTargetPose.md) +- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) +- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) +- [RtlStatus](../msg_docs/RtlStatus.md) +- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) +- [GimbalControls](../msg_docs/GimbalControls.md) +- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) +- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) +- [HeaterStatus](../msg_docs/HeaterStatus.md) +- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [RcChannels](../msg_docs/RcChannels.md) +- [TecsStatus](../msg_docs/TecsStatus.md) +- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) +- [InputRc](../msg_docs/InputRc.md) +- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) +- [GeofenceResult](../msg_docs/GeofenceResult.md) +- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) +- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) +- [NavigatorStatus](../msg_docs/NavigatorStatus.md) +- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [EscReport](../msg_docs/EscReport.md) +- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) +- [GeofenceStatus](../msg_docs/GeofenceStatus.md) +- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) +- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) +- [EventV0](../msg_docs/EventV0.md) +- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md) +- [VehicleConstraints](../msg_docs/VehicleConstraints.md) +- [IrlockReport](../msg_docs/IrlockReport.md) ::: diff --git a/docs/uk/middleware/uorb.md b/docs/uk/middleware/uorb.md index f2682e9798..4e3300ce5f 100644 --- a/docs/uk/middleware/uorb.md +++ b/docs/uk/middleware/uorb.md @@ -280,6 +280,8 @@ For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggl ## Дивіться також +- [uORB Documentation Standard](../uorb/uorb_documentation.md) + - _PX4 uORB Explained_ Blog series - [Part 1](https://px4.io/px4-uorb-explained-part-1/) - [Part 2](https://px4.io/px4-uorb-explained-part-2/) diff --git a/docs/uk/middleware/uxrce_dds.md b/docs/uk/middleware/uxrce_dds.md index dc42bc881f..9fe31af33d 100644 --- a/docs/uk/middleware/uxrce_dds.md +++ b/docs/uk/middleware/uxrce_dds.md @@ -65,7 +65,7 @@ PX4 Micro XRCE-DDS Client is based on version `v2.x` which is not compatible wit В Ubuntu ви можете зібрати з вихідного коду і встановити Агент окремо за допомогою наступних команд: ```sh -git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git +git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build @@ -106,90 +106,146 @@ The development version, fetched using `--edge` above, does work. ### Збірка/Запуск у межах робочого простору ROS 2 -Агент може бути створений і запущений в робочому просторі ROS 2 (або створений окремо і запущений з робочого простору. +The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace). You must already have installed ROS 2 following the instructions in: [ROS 2 User Guide > Install ROS 2](../ros2/user_guide.md#install-ros-2). :::warning This approach will use the existing ROS 2 versions of the Agent dependencies, such as `fastcdr` and `fastdds`. -This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones. +This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones: + +| ROS 2 version | Micro-XRCE-DDS-Agent version | +| ------------- | -------------------------------------- | +| Foxy | v2.4.2 | +| Humble | v2.4.2 | +| Jazzy | v2.4.3 | + ::: Створити агента в межах ROS: 1. Створіть директорію робочого простору для агента: - ```sh - mkdir -p ~/px4_ros_uxrce_dds_ws/src - ``` + ```sh + mkdir -p ~/px4_ros_uxrce_dds_ws/src + ``` 2. Clone the source code for the eProsima [Micro-XRCE-DDS-Agent](https://github.com/eProsima/Micro-XRCE-DDS-Agent) to the `/src` directory (the `main` branch is cloned by default): - ```sh - cd ~/px4_ros_uxrce_dds_ws/src - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - ``` + ::::tabs + + ::: tab jazzy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab humble + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab foxy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + :::: 3. Source the ROS 2 development environment, and compile the workspace using `colcon`: - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + source /opt/ros/jazzy/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - :::: + ::: tab foxy - This builds all the folders under `/src` using the sourced toolchain. + ```sh + source /opt/ros/foxy/setup.bash + colcon build + ``` + + +::: + + :::: + + This builds all the folders under `/src` using the sourced toolchain. Для запуску агента micro XRCE-DDS в робочому просторі: 1. Source the `local_setup.bash` to make the executables available in the terminal (also `setup.bash` if using a new terminal). - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/jazzy/setup.bash + source install/local_setup.bash + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/humble/setup.bash + source install/local_setup.bash + ``` ::: - :::: + ::: tab foxy + + ```sh + source /opt/ros/foxy/setup.bash + source install/local_setup.bash + ``` + + +::: + + :::: 1) Запустіть агента з налаштуваннями для підключення до клієнта uXRCE-DDS, який працює на симуляторі: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` ## Запуск агента та клієнта @@ -235,7 +291,6 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_CFG](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG): Set the port to connect on, such as `TELEM2`, `Ethernet`, or `Wifi`. - Якщо використовується Ethernet-підключення: - - [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT): Use this to specify the agent UDP listening port. The default value is `8888`. @@ -259,14 +314,12 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi ``` - Якщо використовується послідовне підключення: - - [SER_TEL2_BAUD](../advanced_config/parameter_reference.md#SER_TEL2_BAUD), [SER_URT6_BAUD](../advanced_config/parameter_reference.md#SER_URT6_BAUD) (and so on): Use the `_BAUD` parameter associated with the serial port to set the baud rate. For example, you'd set a value for `SER_TEL2_BAUD` if you are connecting to the companion using `TELEM2`. For more information see [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration). - Деякі налаштування можуть також потребувати встановлення цих параметрів: - - [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): The uXRCE-DDS key. Якщо ви працюєте в мультиклієнтській конфігурації з одним агентом, кожен клієнт повинен мати унікальний ненульовий ключ. Це насамперед важливо для симуляцій з кількома транспортними засобами, де всі клієнти під'єднані до UDP одного агента. @@ -279,6 +332,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. Клієнтський модуль uXRCE-DDS може синхронізувати мітку часу повідомлень, якими обмінюються через міст. Це стандартна конфігурація. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. + Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. + See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -354,7 +412,7 @@ Note that all the messages from PX4 source code are present in the repository, b ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)) or at runtime (which is useful for multi vehicle operations): +Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)), at runtime, or through a parameter (which is useful for multi vehicle operations): - One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. Ця техніка може бути використана як у симуляторах, так і на реальних транспортних засобах. @@ -383,6 +441,23 @@ PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500 ::: +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. + This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. + This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. + +:::info +PX4 parameters cannot carry rich text strings. +Therefore, you cannot use [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to automatically start a client with an arbitrary message namespace through PX4. +You can however specify a namespace when starting the client, using the `-n` argument: + +```sh +# In etc/extras.txt on the MicroSD card +uxrce_dds_client start -n fancy_uav +``` + +This can be included in `etc/extras.txt` as part of a custom [System Startup](../concept/system_startup.md). +::: + ## PX4 ROS 2 QoS Settings PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers. @@ -443,6 +518,11 @@ publications: - topic: /fmu/out/vehicle_trajectory_waypoint_desired type: px4_msgs::msg::VehicleTrajectoryWaypoint + - topic: /fmu/out/vehicle_imu + type: px4_msgs::msg::VehicleImu + rate_limit: 50. + instance: 1 # OPTIONAL + subscriptions: - topic: /fmu/in/offboard_control_mode @@ -466,15 +546,18 @@ Each (`topic`,`type`) pairs defines: 1. A new `publication`, `subscription`, or `subscriptions_multi`, depending on the list to which it is added. 2. The topic _base name_, which **must** coincide with the desired uORB topic name that you want to publish/subscribe. - It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. - `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. + It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. + `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. 3. The topic [namespace](https://design.ros2.org/articles/topic_and_service_names.html#namespaces). - By default it is set to: - - `/fmu/out/` for topics that are _published_ by PX4. - - `/fmu/in/` for topics that are _subscribed_ by PX4. + By default it is set to: + - `/fmu/out/` for topics that are _published_ by PX4. + - `/fmu/in/` for topics that are _subscribed_ by PX4. 4. The message type (`VehicleOdometry`, `VehicleStatus`, `OffboardControlMode`, etc.) and the ROS 2 package (`px4_msgs`) that is expected to provide the message definition. 5. **(Optional)**: An additional `rate_limit` field (only for publication entries), which specifies the maximum rate (Hz) at which messages will be published on this topic by PX4 to ROS 2. - If left unspecified, the maximum publication rate limit is set to 100 Hz. + If left unspecified, the maximum publication rate limit is set to 100 Hz. +6. **(Optional)**: An additional `instance` field (only for publication entries), which lets you select which instance of a [multi-instance topic](./uorb.md#multi-instance) you want to be published to ROS 2. + If provided, this option changes the ROS 2 topic name of the advertised uORB topic appending the instance number: `fmu/out/[uorb topic name][instance]` (plus eventual namespace and message version). + In the example above the final topic name would be `/fmu/out/vehicle_imu1`. `subscriptions` and `subscriptions_multi` allow us to choose the uORB topic instance that ROS 2 topics are routed to: either a shared instance that may also be getting updates from internal PX4 uORB publishers, or a separate instance that is reserved for ROS2 publications, respectively. Without this mechanism all ROS 2 messages would be routed to the _same_ uORB topic instance (because ROS 2 does not have the concept of [multiple topic instances](../middleware/uorb.md#multi-instance)), and it would not be possible for PX4 subscribers to differentiate between streams from ROS 2 or PX4 publishers. diff --git a/docs/uk/middleware/zenoh.md b/docs/uk/middleware/zenoh.md new file mode 100644 index 0000000000..800d0b5fae --- /dev/null +++ b/docs/uk/middleware/zenoh.md @@ -0,0 +1,201 @@ +# Zenoh (PX4 ROS 2 rmw_zenoh) + + + +:::warning +Експериментальні налаштування +At the time of writing, PX4 Zenoh-pico is experimental, and hence subject to change. +::: + +PX4 supports Zenoh as an alternative mechanism (to DDS) for bridging uORB topics to [ROS 2](../ros2/user_guide.md) (via the ROS 2 [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh) middleware). +This allows uORB messages to be published and subscribed on a companion computer as though they were ROS 2 topics. +It provides a fast and lightweight way to connect PX4 to ROS 2, making it easier for applications to access vehicle telemetry and send control commands. + +The following guide describes the architecture and various options for setting up the Zenoh client and router. +In particular, it covers the options that are most important to PX4 users exploring Zenoh as an alternative communication layer for ROS 2. + +## Архітектура + +The Zenoh-based middleware consists of a client running on PX4 and a Zenoh router running on the companion computer, with bi-directional data exchange between them over a UART, TCP, UDP, or multicast-UDP link. +The router acts as a broker and discovery service, enabling PX4 to publish and subscribe to topics in the global Zenoh data space. +This allows seamless integration with ROS 2 nodes using [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh), and supports flexible deployment across distributed systems. + +![Architecture PX4 Zenoh-Pico with ROS 2](../../assets/middleware/zenoh/architecture-px4-zenoh.svg) + +The client is the _PX4 Zenoh-Pico Node_ referred to above, which is implemented in the [PX4 `zenoh` module](../modules/modules_driver.md#zenoh). +This is based on Zenoh-Pico, a minimalistic version of [Eclipse Zenoh](https://zenoh.io/) (a data-centric protocol designed for real-time, distributed, and resource-constrained environments). + +The router suggested above is [zenohd](https://github.com/eclipse-zenoh/zenoh/tree/main/zenohd). + +:::info +UART is supported by Zenoh but has not yet implemented in the PX4 Zenoh-Pico node. +::: + +## ROS 2 Zenoh Bring-up on Linux Companion + +In order for PX4 uORB topics to be shared with ROS 2 applications, you will need the PX4 Zenoh-Pico Node client running on your FMU, connected to a Zenoh router running on the companion computer (or elsewhere in the network). + +First select Zenoh as the ROS 2 transport by setting the `RMW_IMPLEMENTATION` environment variable as shown: + +```sh +export RMW_IMPLEMENTATION=rmw_zenoh_cpp +``` + +Then start the Zenoh router using the command: + +```sh +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +For more information about the Zenoh Router see the [rmw_zenoh](https://github.com/ros2/rmw_zenoh?tab=readme-ov-file#start-the-zenoh-router) documentation. + +## PX4 Zenoh-Pico Node Setup + +### PX4 Firmware + +Before setting up the Zenoh communication, first make sure that your firmware contains the driver that implements the [`zenoh` driver](../modules/modules_driver.md#zenoh), which provides the implementation of the _PX4 Zenoh-Pico Node_. + +You can check if the module is present on your board by searching for the key `CONFIG_MODULES_ZENOH=y` in your board's `default.px4board` KConfig file. +For example, you can see that the module is present in `px4_fmu-v6xrt` build targets from [/boards/px4/fmu-v6xrt/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#L91). + +If `CONFIG_MODULES_ZENOH=y` is not preset you can add this key to your board configuration and rebuild. +Note that due to flash constraints you may need to remove other components in order to include the module (such as the [`uxrce_dds_client` module](../modules/modules_system.md#uxrce-dds-client), which you will not need if you are using Zenoh). + +The table below shows some of the PX4 targets that include Zenoh by default. + +| PX4 Target | Примітки | +| ---------------------- | -------------------------------------------------------------------------------------------------------------- | +| `px4_fmu-v6xrt` | For [FMUv6X-RT](../flight_controller/nxp_mr_vmu_rt1176.md) (reference platform for testing) | +| `nxp_tropic-community` | | +| `nxp_mr-tropic` | | +| `nxp_mr-canhubk344` | | +| `px4_sitl_zenoh` | Zenoh-enabled simulation build | +| `px4_fmu-v6x_zenoh` | Zenoh-enabled firmware for FMUv6X | + +Zenoh is not included in the default `px4_fmu-` targets for any firmware other than `px4_fmu-v6xrt` (`px4_sitl_zenoh` and `px4_fmu-v6x_zenoh` [are build variants](../dev_setup/building_px4.md#px4-make-build-targets)). + +:::tip +You can check if Zenoh is present at runtime by using QGroundControl to [find the parameter](../advanced_config/parameters.md#finding-a-parameter) [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE). +If present, the module is installed. +::: + +### Enable Zenoh on PX4 Startup + +Set the [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE) parameter to `1` to enable Zenoh on PX4 startup. + +### Configure Zenoh Network + +Set up PX4 to connect to the companion computer running `zenohd`. + +PX4's default IP address of the Zenoh daemon host is `10.41.10.1`. +If you're using a different IP for the Zenoh daemon, run the following command (replacing the address) in a PX4 shell and then reboot: + +```sh +zenoh config net client tcp/10.41.10.1:7447#iface=eth0 +``` + +Note that for the simulation target with Zeroh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. + +:::warning +Any changes to the network configuration require a PX4 system reboot to take effect. +::: + +:::tip +See [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) for more information about Ethernet configuration. +::: + +### PX4 Zenoh-pico Node configuration + +The **default configuration** is auto-generated from the [dds_topics.yaml](../middleware/dds_topics.md) file in the PX4 repository. +This file specifies which uORB message definitions are to be published/subscribed by ROS 2 applications, and hence (indirectly) which topics are compiled into the zenoh module. + +To inspect the current Zenoh configuration: + +```sh +zenoh config +``` + +The PX4 Zenoh-pico node stores its configuration on the **SD card** under the `zenoh` folder. +This folder contains three key files: + +- **`net.txt`** – Defines the **Zenoh network configuration**. +- **`pub.csv`** – Maps **uORB topics to ROS2 topics** (used for publishing). +- **`sub.csv`** – Maps **ROS2 topics to uORB topics** (used for subscribing). + +### 4. Modifying Topic Mappings + +Zenoh topic mappings define how data flows between PX4's internal uORB topics and external ROS2 topics via Zenoh. +These mappings are stored in `pub.csv` and `sub.csv` on the SD card, and can be modified at runtime using the `zenoh config` CLI tool. + +:::warning +Any changes to the topic mappings require a PX4 system reboot to take effect. +::: + +There are two types of mappings you can modify: + +- **Publisher mappings**: Forward data from a uORB topic to a Zenoh topic. +- **Subscriber mappings**: Receive data from a Zenoh topic and publish it to a uORB topic. + +The main operations and their commands are: + +- Publish a uORB topic to a Zenoh topic: + + ```sh + zenoh config add publisher [uorb_instance] + ``` + +- Subscribe to a Zenoh topic and forward it to a uORB topic: + + ```sh + zenoh config add subscriber [uorb_instance] + ``` + +- Remove existing mappings: + + ```sh + zenoh config delete publisher + zenoh config delete subscriber + ``` + +After modifying the mappings, reboot PX4 to apply the changes. +The updated configuration will be loaded from the SD card during startup. + +## Communicating with PX4 from ROS 2 via Zenoh + +Once your PX4 FMU is publishing data into ROS 2, you can inspect the available topics and their contents using standard ROS 2 CLI tools: + +```sh +ros2 topic list +``` + +Check topic type and publishers/subscribers: + +```sh +ros2 topic info -v /fmu/out/vehicle_status +Type: px4_msgs/msg/VehicleStatus + +Publisher count: 1 + +Node name: px4_aabbcc00000000000000000000000000 +Node namespace: / +Topic type: px4_msgs/msg/VehicleStatus +Topic type hash: RIHS01_828bddbb7d4c2aa6ad93757955f6893be1ec5d8f11885ec7715bcdd76b5226c9 +Endpoint type: PUBLISHER +GID: 82.99.74.2c.b6.7d.93.44.91.4d.fe.14.93.58.40.16 +QoS profile: + Reliability: RELIABLE + History (Depth): KEEP_LAST (7) + Durability: VOLATILE + Lifespan: Infinite + Deadline: Infinite + Liveliness: AUTOMATIC + Liveliness lease duration: Infinite + +Subscription count: 0 +``` + +### PX4 ROS 2 Interface with Zenoh + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) works out of the box with Zenoh as a transport backend. +This means you can publish and subscribe to PX4 topics over Zenoh without changing your ROS 2 nodes or dealing with DDS configuration. +For setup details and supported message types, refer to the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). diff --git a/docs/uk/modules/hello_sky.md b/docs/uk/modules/hello_sky.md index 93be69de26..6f87812019 100644 --- a/docs/uk/modules/hello_sky.md +++ b/docs/uk/modules/hello_sky.md @@ -28,151 +28,155 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 1. Create a new directory **PX4-Autopilot/src/examples/px4_simple_app**. 2. Create a new C file in that directory named **px4_simple_app.c**: - - Скопіюйте заголовок за замовчуванням у верхній частині сторінки. - Це повинно бути присутнім у всіх розміщених файлах! + - Скопіюйте заголовок за замовчуванням у верхній частині сторінки. + Це повинно бути присутнім у всіх розміщених файлах! - ```c - /**************************************************************************** - * - * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - ``` + ```c + /**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + ``` - - Скопіюйте наступний код під заголовком за замовчуванням. - Це повинно бути присутнім у всіх розміщених файлах! + - Скопіюйте наступний код під заголовком за замовчуванням. + Це повинно бути присутнім у всіх розміщених файлах! - ```c - /** - * @file px4_simple_app.c - * Minimal application example for PX4 autopilot - * - * @author Example User - */ + ```c + /** + * @file px4_simple_app.c + * Minimal application example for PX4 autopilot + * + * @author Example User + */ - #include + #include - __EXPORT int px4_simple_app_main(int argc, char *argv[]); + __EXPORT int px4_simple_app_main(int argc, char *argv[]); - int px4_simple_app_main(int argc, char *argv[]) - { - PX4_INFO("Hello Sky!"); - return OK; - } - ``` + int px4_simple_app_main(int argc, char *argv[]) + { + PX4_INFO("Hello Sky!"); + return OK; + } + ``` + + :::tip + + The main function must be named `_main` and exported from the module as shown. - :::tip - The main function must be named `_main` and exported from the module as shown. ::: - :::tip - `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). - There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. - Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + :::tip + + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). + There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. + Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 3. Create and open a new _cmake_ definition file named **CMakeLists.txt**. - Скопіюйте текст нижче: + Скопіюйте текст нижче: - ```cmake - ############################################################################ - # - # Copyright (c) 2015 PX4 Development Team. All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions - # are met: - # - # 1. Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # 2. Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in - # the documentation and/or other materials provided with the - # distribution. - # 3. Neither the name PX4 nor the names of its contributors may be - # used to endorse or promote products derived from this software - # without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - # POSSIBILITY OF SUCH DAMAGE. - # - ############################################################################ - px4_add_module( - MODULE examples__px4_simple_app - MAIN px4_simple_app - STACK_MAIN 2000 - SRCS - px4_simple_app.c - DEPENDS - ) - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2015 PX4 Development Team. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in + # the documentation and/or other materials provided with the + # distribution. + # 3. Neither the name PX4 nor the names of its contributors may be + # used to endorse or promote products derived from this software + # without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + ############################################################################ + px4_add_module( + MODULE examples__px4_simple_app + MAIN px4_simple_app + STACK_MAIN 2000 + SRCS + px4_simple_app.c + DEPENDS + ) + ``` - The `px4_add_module()` method builds a static library from a module description. + The `px4_add_module()` method builds a static library from a module description. - - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). - - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. + - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). + - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. - :::tip - The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). + :::tip + The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). ::: - ::: info - If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). - Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. - You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` + ::: info + If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). + Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. + You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` ::: 4. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). - Скопіюйте текст нижче: + Скопіюйте текст нижче: - ``` - menuconfig EXAMPLES_PX4_SIMPLE_APP - bool "px4_simple_app" - default n - ---help--- - Enable support for px4_simple_app - ``` + ```text + menuconfig EXAMPLES_PX4_SIMPLE_APP + bool "px4_simple_app" + default n + ---help--- + Enable support for px4_simple_app + ``` ## Побудуйте Програму/прошивку @@ -440,6 +444,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e */ #include +#include #include #include #include diff --git a/docs/uk/modules/module_template.md b/docs/uk/modules/module_template.md index c2cb88599f..93ed9e86de 100644 --- a/docs/uk/modules/module_template.md +++ b/docs/uk/modules/module_template.md @@ -22,27 +22,27 @@ PX4-Autopilot contains a template for writing a new application (module) that ru Підсумовуючи: 1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)): - ``` - ... - DEPENDS - px4_work_queue - ``` + ``` + ... + DEPENDS + px4_work_queue + ``` 2. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp)) 3. Вкажіть чергу, до якої додати завдання у конструкторі ініціалізації. - The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: + The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: - ```cpp - WorkItemExample::WorkItemExample() : - ModuleParams(nullptr), - ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) - { - } - ``` + ```cpp + WorkItemExample::WorkItemExample() : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) + { + } + ``` - ::: info - The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). + ::: info + The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). ::: diff --git a/docs/uk/modules/modules_driver.md b/docs/uk/modules/modules_driver.md index c3ba2a16c1..b87be5aec8 100644 --- a/docs/uk/modules/modules_driver.md +++ b/docs/uk/modules/modules_driver.md @@ -2,6 +2,7 @@ Підкатегорії: +- [Adc](modules_driver_adc.md) - [Airspeed Sensor](modules_driver_airspeed_sensor.md) - [Baro](modules_driver_baro.md) - [Camera](modules_driver_camera.md) @@ -14,98 +15,6 @@ - [Rpm Sensor](modules_driver_rpm_sensor.md) - [Transponder](modules_driver_transponder.md) -## MCP23009 - -Source: [drivers/gpio/mcp23009](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/gpio/mcp23009) - -### Usage {#MCP23009_usage} - -``` -MCP23009 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 37 - [-D ] Direction - default: 0 - [-O ] Output - default: 0 - [-P ] Pullups - default: 0 - [-U ] Update Interval [ms] - default: 0 - - stop - - status print status info -``` - -## adc - -Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) - -### Опис - -ADC driver. - -### Usage {#adc_usage} - -``` -adc [arguments...] - Commands: - start - - test - [-n] Do not publish ADC report, only system power - - stop - - status print status info -``` - -## ads1115 - -Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) - -### Опис - -Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. - -The driver is included by default in firmware for boards that do not have an internal analog to digital converter, -such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) -(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). - -It is enabled/disabled using the -[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) -parameter, and is disabled by default. -If enabled, internal ADCs are not used. - -### Usage {#ads1115_usage} - -``` -ads1115 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 72 - - stop - - status print status info -``` - ## atxxxx Source: [drivers/osd/atxxxx](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/atxxxx) @@ -808,6 +717,64 @@ lsm303agr [arguments...] status print status info ``` +## mcp230xx + +Source: [lib/drivers/mcp_common](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/mcp_common) + +### Usage {#mcp230xx_usage} + +``` +mcp230xx [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 39 + [-D ] Direction (1=Input, 0=Output) + default: 0 + [-O ] Output + default: 0 + [-P ] Pullups + default: 0 + [-U ] Update Interval [ms] + default: 0 + [-M ] First minor number + default: 0 + + stop + + status print status info +``` + +## mcp9808 + +Source: [drivers/temperature_sensor/mcp9808](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/temperature_sensor/mcp9808) + +### Usage {#mcp9808_usage} + +``` +mcp9808 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 24 + + stop + + status print status info +``` + ## msp_osd Source: [drivers/osd/msp_osd](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/msp_osd) diff --git a/docs/uk/modules/modules_driver_adc.md b/docs/uk/modules/modules_driver_adc.md new file mode 100644 index 0000000000..a7d153ef43 --- /dev/null +++ b/docs/uk/modules/modules_driver_adc.md @@ -0,0 +1,107 @@ +# Modules Reference: Adc (Driver) + +## TLA2528 + +Source: [drivers/adc/tla2528](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/tla2528) + +### Usage {#TLA2528_usage} + +``` +TLA2528 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` + +## adc + +Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) + +### Опис + +ADC driver. + +### Usage {#adc_usage} + +``` +adc [arguments...] + Commands: + start + + test + [-n] Do not publish ADC report, only system power + + stop + + status print status info +``` + +## ads1115 + +Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) + +### Опис + +Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. + +The driver is included by default in firmware for boards that do not have an internal analog to digital converter, +such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) +(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). + +It is enabled/disabled using the +[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) +parameter, and is disabled by default. +If enabled, internal ADCs are not used. + +### Usage {#ads1115_usage} + +``` +ads1115 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 72 + + stop + + status print status info +``` + +## ads7953 + +Source: [drivers/adc/ads7953](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads7953) + +### Usage {#ads7953_usage} + +``` +ads7953 [arguments...] + Commands: + start + [-s] Internal SPI bus(es) + [-S] External SPI bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-c ] chip-select pin (for internal SPI) or index (for external SPI) + [-m ] SPI mode + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` diff --git a/docs/uk/modules/modules_driver_distance_sensor.md b/docs/uk/modules/modules_driver_distance_sensor.md index 249776c2ca..4ed7caf5f7 100644 --- a/docs/uk/modules/modules_driver_distance_sensor.md +++ b/docs/uk/modules/modules_driver_distance_sensor.md @@ -104,7 +104,7 @@ Source: [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4 ### Опис -I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20. +I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20, SF30/d. Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html diff --git a/docs/uk/modules/modules_driver_ins.md b/docs/uk/modules/modules_driver_ins.md index d0a35f7acb..0385004203 100644 --- a/docs/uk/modules/modules_driver_ins.md +++ b/docs/uk/modules/modules_driver_ins.md @@ -45,6 +45,41 @@ MicroStrain [arguments...] status Driver status ``` +## eulernav_bahrs + +Source: [drivers/ins/eulernav_bahrs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/eulernav_bahrs) + +### Опис + +Serial bus driver for the EULER-NAV Baro-Inertial AHRS. + +### Приклади + +Attempt to start driver on a specified serial device. + +``` +eulernav_bahrs start -d /dev/ttyS1 +``` + +Stop driver + +``` +eulernav_bahrs stop +``` + +### Usage {#eulernav_bahrs_usage} + +``` +eulernav_bahrs [arguments...] + Commands: + start Start driver + -d Serial device + + status Print driver status + + stop Stop driver +``` + ## ilabs Source: [drivers/ins/ilabs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/ilabs) @@ -90,6 +125,31 @@ ilabs [arguments...] status Print driver status ``` +## sbgecom + +Source: [drivers/ins/sbgecom](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/sbgecom) + +Description du module + +### Usage {#sbgecom_usage} + +``` +sbgecom [arguments...] + Commands: + start Start driver + [-d ] Serial device + default: /dev/ttyS0 + [-b ] Baudrate device + default: 921600 + [-f ] Config JSON file path + default: /etc/extras/sbg_settings\.json + [-s ] Config JSON string + + status Driver status + + stop Stop driver +``` + ## vectornav Source: [drivers/ins/vectornav](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/vectornav) diff --git a/docs/uk/modules/modules_driver_radio_control.md b/docs/uk/modules/modules_driver_radio_control.md index 473c70c11f..7f0365daec 100644 --- a/docs/uk/modules/modules_driver_radio_control.md +++ b/docs/uk/modules/modules_driver_radio_control.md @@ -17,6 +17,8 @@ crsf_rc [arguments...] [-d ] RC device values: , default: /dev/ttyS3 + inject Inject frame data bytes (for testing) + stop status print status info diff --git a/docs/uk/modules/modules_system.md b/docs/uk/modules/modules_system.md index 339d94e1c9..ef5cd50c40 100644 --- a/docs/uk/modules/modules_system.md +++ b/docs/uk/modules/modules_system.md @@ -127,6 +127,10 @@ commander [arguments...] check Run preflight checks + safety Change prearm safety state + on|off [on] to activate safety, [off] to deactivate safety and allow + control surface movements + arm [-f] Force arming (do not run preflight checks) @@ -140,9 +144,9 @@ commander [arguments...] transition VTOL transition mode Change flight mode - manual|acro|offboard|stabilized|altctl|posctl|position:slow|auto:mission|au - to:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1 - Flight mode + manual|acro|offboard|stabilized|altctl|posctl|altitude_cruise|position:slow + |auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto: + precland|ext1 Flight mode pair @@ -154,6 +158,9 @@ commander [arguments...] lat|lon|alt Origin latitude longitude altitude + set_heading Set current heading + heading degrees from True North [0 360] + poweroff Power off board (if supported) stop @@ -1062,7 +1069,9 @@ uxrce_dds_client [arguments...] values: [-p ] Agent listening port. If not provided, defaults to UXRCE_DDS_PRT - [-n ] Client DDS namespace + [-n ] Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is + between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will + be used stop diff --git a/docs/uk/msg_docs/ActionRequest.md b/docs/uk/msg_docs/ActionRequest.md index b18cf24d07..584b06d718 100644 --- a/docs/uk/msg_docs/ActionRequest.md +++ b/docs/uk/msg_docs/ActionRequest.md @@ -15,25 +15,25 @@ Request are published by `manual_control` and subscribed by the `commander` and # It allows mapping triggers from various external interfaces like RC channels or MAVLink to cause an action. # Request are published by `manual_control` and subscribed by the `commander` and `vtol_att_control` modules. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint8 action # [@enum ACTION] Requested action -uint8 ACTION_DISARM = 0 # Disarm vehicle -uint8 ACTION_ARM = 1 # Arm vehicle -uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming -uint8 ACTION_UNKILL = 3 # Revert a kill action -uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) -uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. -uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight -uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight -uint8 ACTION_TERMINATION = 8 # Irreversably output failsafe values on all outputs, trigger parachute +uint8 action # [@enum ACTION] Requested action +uint8 ACTION_DISARM = 0 # Disarm vehicle +uint8 ACTION_ARM = 1 # Arm vehicle +uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming +uint8 ACTION_UNKILL = 3 # Revert a kill action +uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) +uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. +uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight +uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight +uint8 ACTION_TERMINATION = 8 # Irreversibly output failsafe values on all outputs, trigger parachute -uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture -uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position -uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position -uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held -uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism +uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture +uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position +uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position +uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held +uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism -uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. +uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. ``` diff --git a/docs/uk/msg_docs/ActuatorMotors.md b/docs/uk/msg_docs/ActuatorMotors.md index dfce383e9c..f9b6a826f2 100644 --- a/docs/uk/msg_docs/ActuatorMotors.md +++ b/docs/uk/msg_docs/ActuatorMotors.md @@ -15,14 +15,14 @@ Published by the vehicle's allocation and consumed by the ESC protocol drivers e uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint16 reversible_flags # Bitset indicating which motors are configured to be reversible +uint16 reversible_flags # [-] Bitset indicating which motors are configured to be reversible -uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 # -uint8 NUM_CONTROLS = 12 -float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) +uint8 NUM_CONTROLS = 12 # +float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) ``` diff --git a/docs/uk/msg_docs/ActuatorServos.md b/docs/uk/msg_docs/ActuatorServos.md index fcbb45d0b1..6dfe1ddd7a 100644 --- a/docs/uk/msg_docs/ActuatorServos.md +++ b/docs/uk/msg_docs/ActuatorServos.md @@ -15,10 +15,10 @@ Published by the vehicle's allocation and consumed by the actuator output driver uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint8 NUM_CONTROLS = 8 -float32[8] control # [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. +uint8 NUM_CONTROLS = 8 # +float32[8] control # [-] [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. ``` diff --git a/docs/uk/msg_docs/AdcReport.md b/docs/uk/msg_docs/AdcReport.md index b7faec43a2..0865953206 100644 --- a/docs/uk/msg_docs/AdcReport.md +++ b/docs/uk/msg_docs/AdcReport.md @@ -1,13 +1,21 @@ # AdcReport (повідомлення UORB) +ADC raw data. + +Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AdcReport.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint32 device_id # unique device ID for the sensor that does not change between power cycles -int16[12] channel_id # ADC channel IDs, negative for non-existent, TODO: should be kept same as array index -int32[12] raw_data # ADC channel raw value, accept negative value, valid if channel ID is positive -uint32 resolution # ADC channel resolution -float32 v_ref # ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) +# ADC raw data. +# +# Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + +uint64 timestamp # [us] Time since system start +uint32 device_id # [-] unique device ID for the sensor that does not change between power cycles +int16[16] channel_id # [-] ADC channel IDs, negative for non-existent, TODO: should be kept same as array index +int32[16] raw_data # [-] ADC channel raw value, accept negative value, valid if channel ID is positive +uint32 resolution # [-] ADC channel resolution +float32 v_ref # [V] ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) ``` diff --git a/docs/uk/msg_docs/Airspeed.md b/docs/uk/msg_docs/Airspeed.md index 3748e60b12..8717f30d78 100644 --- a/docs/uk/msg_docs/Airspeed.md +++ b/docs/uk/msg_docs/Airspeed.md @@ -13,10 +13,10 @@ It is subscribed by the airspeed selector module, which validates the data from # This is published by airspeed sensor drivers, CAN airspeed sensors, simulators. # It is subscribed by the airspeed selector module, which validates the data from multiple sensors and passes on a single estimation to the EKF, controllers and telemetry providers. -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Timestamp of the raw data -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed -float32 true_airspeed_m_s # [m/s] True airspeed -float32 confidence # [@range 0,1] Confidence value for this sensor +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +float32 indicated_airspeed_m_s # [m/s] Indicated airspeed +float32 true_airspeed_m_s # [m/s] True airspeed +float32 confidence # [@range 0,1] Confidence value for this sensor ``` diff --git a/docs/uk/msg_docs/AirspeedValidated.md b/docs/uk/msg_docs/AirspeedValidated.md index 41bfe31f09..1aa9bdbd02 100644 --- a/docs/uk/msg_docs/AirspeedValidated.md +++ b/docs/uk/msg_docs/AirspeedValidated.md @@ -1,29 +1,39 @@ # AirspeedValidated (повідомлення UORB) +Validated airspeed + +Provides information about airspeed (indicated, true, calibrated) and the source of the data. +Used by controllers, estimators and for airspeed reporting to operator. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/AirspeedValidated.msg) ```c +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + + uint32 MESSAGE_VERSION = 1 -uint64 timestamp # time since system start (microseconds) +uint64 timestamp # [us] Time since system start -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed (IAS), set to NAN if invalid -float32 calibrated_airspeed_m_s # [m/s] Calibrated airspeed (CAS), set to NAN if invalid -float32 true_airspeed_m_s # [m/s] True airspeed (TAS), set to NAN if invalid +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) -int8 airspeed_source # Source of currently published airspeed values -int8 DISABLED = -1 -int8 GROUND_MINUS_WIND = 0 -int8 SENSOR_1 = 1 -int8 SENSOR_2 = 2 -int8 SENSOR_3 = 3 -int8 SYNTHETIC = 4 +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed -# debug states -float32 calibrated_ground_minus_wind_m_s # CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid -float32 calibraded_airspeed_synth_m_s # synthetic airspeed in m/s, set to NAN if invalid -float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] -float32 throttle_filtered # filtered fixed-wing throttle [-] -float32 pitch_filtered # filtered pitch [rad] +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch ``` diff --git a/docs/uk/msg_docs/ArmingCheckReply.md b/docs/uk/msg_docs/ArmingCheckReply.md index c6d4ff02b7..d1e79e5a49 100644 --- a/docs/uk/msg_docs/ArmingCheckReply.md +++ b/docs/uk/msg_docs/ArmingCheckReply.md @@ -1,6 +1,6 @@ # ArmingCheckReply (повідомлення UORB) -Arming check reply. +Arming check reply This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -12,7 +12,7 @@ The message is not used by internal/FMU components, as their mode requirements a [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckReply.msg) ```c -# Arming check reply. +# Arming check reply # # This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. # The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -21,39 +21,39 @@ The message is not used by internal/FMU components, as their mode requirements a # Note that the external component is identified by its registration_id, which is allocated to the component during registration (arming_check_id in RegisterExtComponentReply). # The message is not used by internal/FMU components, as their mode requirements are known at compile time. -uint32 MESSAGE_VERSION = 1 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # [us] Time since system start. -uint8 request_id # Id of ArmingCheckRequest for which this is a response. -uint8 registration_id # Id of external component emitting this response. +uint8 request_id # [-] Id of ArmingCheckRequest for which this is a response +uint8 registration_id # [-] Id of external component emitting this response -uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies. +uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies -uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] -bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json). +uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] +bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json) -bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed. +bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed -uint8 num_events # Number of queued failure messages (Event) in the events field. +uint8 num_events # Number of queued failure messages (Event) in the events field -Event[5] events # Arming failure reasons (Queue of events to report to GCS). +Event[5] events # Arming failure reasons (Queue of events to report to GCS) # Mode requirements -bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope). -bool mode_req_attitude # Requires an attitude estimate. -bool mode_req_local_alt # Requires a local altitude estimate. -bool mode_req_local_position # Requires a local position estimate. -bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate. -bool mode_req_global_position # Requires a global position estimate. -bool mode_req_global_position_relaxed # Requires a relaxed global position estimate. -bool mode_req_mission # Requires an uploaded mission. -bool mode_req_home_position # Requires a home position (such as RTL/Return mode). -bool mode_req_prevent_arming # Prevent arming (such as in Land mode). -bool mode_req_manual_control # Requires a manual controller +bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope) +bool mode_req_attitude # Requires an attitude estimate +bool mode_req_local_alt # Requires a local altitude estimate +bool mode_req_local_position # Requires a local position estimate +bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate +bool mode_req_global_position # Requires a global position estimate +bool mode_req_global_position_relaxed # Requires a relaxed global position estimate +bool mode_req_mission # Requires an uploaded mission +bool mode_req_home_position # Requires a home position (such as RTL/Return mode) +bool mode_req_prevent_arming # Prevent arming (such as in Land mode) +bool mode_req_manual_control # Requires a manual controller -uint8 ORB_QUEUE_LENGTH = 4 # +uint8 ORB_QUEUE_LENGTH = 4 ``` diff --git a/docs/uk/msg_docs/ArmingCheckRequest.md b/docs/uk/msg_docs/ArmingCheckRequest.md index 07ab3706a3..45fd9a48f4 100644 --- a/docs/uk/msg_docs/ArmingCheckRequest.md +++ b/docs/uk/msg_docs/ArmingCheckRequest.md @@ -1,6 +1,6 @@ # ArmingCheckRequest (повідомлення UORB) -Arming check request. +Arming check request Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -12,7 +12,7 @@ The reply will also include the registration_id for each external component, pro [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckRequest.msg) ```c -# Arming check request. +# Arming check request # # Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. # All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -21,10 +21,12 @@ The reply will also include the registration_id for each external component, pro # The reply will include the published request_id, allowing correlation of all arming check information for a particular request. # The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 -uint64 timestamp # [us] Time since system start. +uint64 timestamp # [us] Time since system start -uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint8 request_id # [-] Id of this request. Allows correlation with associated ArmingCheckReply messages. + +uint32 valid_registrations_mask # [-] Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) ``` diff --git a/docs/uk/msg_docs/ArmingCheckRequestV0.md b/docs/uk/msg_docs/ArmingCheckRequestV0.md new file mode 100644 index 0000000000..f5680c11f2 --- /dev/null +++ b/docs/uk/msg_docs/ArmingCheckRequestV0.md @@ -0,0 +1,30 @@ +# ArmingCheckRequestV0 (UORB message) + +Arming check request. + +Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. + +The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckRequestV0.msg) + +```c +# Arming check request. +# +# Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +# All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +# The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. +# +# The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +# The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start. + +uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. + +``` diff --git a/docs/uk/msg_docs/AutotuneAttitudeControlStatus.md b/docs/uk/msg_docs/AutotuneAttitudeControlStatus.md index a8d88537a4..afda316aa2 100644 --- a/docs/uk/msg_docs/AutotuneAttitudeControlStatus.md +++ b/docs/uk/msg_docs/AutotuneAttitudeControlStatus.md @@ -1,42 +1,59 @@ # AutotuneAttitudeControlStatus (повідомлення UORB) +Autotune attitude control status + +This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +and is subscribed to by the respective attitude controllers to command rate setpoints. + +The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AutotuneAttitudeControlStatus.msg) ```c -uint64 timestamp # time since system start (microseconds) +# Autotune attitude control status +# +# This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +# and is subscribed to by the respective attitude controllers to command rate setpoints. +# +# The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. -float32[5] coeff # coefficients of the identified discrete-time model -float32[5] coeff_var # coefficients' variance of the identified discrete-time model -float32 fitness # fitness of the parameter estimate -float32 innov -float32 dt_model +uint64 timestamp # [us] Time since system start -float32 kc -float32 ki -float32 kd -float32 kff -float32 att_p +float32[5] coeff # [-] Coefficients of the identified discrete-time model +float32[5] coeff_var # [-] Coefficients' variance of the identified discrete-time model +float32 fitness # [-] Fitness of the parameter estimate +float32 innov # [rad/s] Innovation (residual error between model and measured output) +float32 dt_model # [s] Model sample time used for identification -float32[3] rate_sp -float32 u_filt -float32 y_filt +float32 kc # [-] Proportional rate-loop gain (ideal form) +float32 ki # [-] Integral rate-loop gain (ideal form) +float32 kd # [-] Derivative rate-loop gain (ideal form) +float32 kff # [-] Feedforward rate-loop gain +float32 att_p # [-] Proportional attitude gain -uint8 STATE_IDLE = 0 -uint8 STATE_INIT = 1 -uint8 STATE_ROLL = 2 -uint8 STATE_ROLL_PAUSE = 3 -uint8 STATE_PITCH = 4 -uint8 STATE_PITCH_PAUSE = 5 -uint8 STATE_YAW = 6 -uint8 STATE_YAW_PAUSE = 7 -uint8 STATE_VERIFICATION = 8 -uint8 STATE_APPLY = 9 -uint8 STATE_TEST = 10 -uint8 STATE_COMPLETE = 11 -uint8 STATE_FAIL = 12 -uint8 STATE_WAIT_FOR_DISARM = 13 +float32[3] rate_sp # [rad/s] Rate setpoint commanded to the attitude controller. -uint8 state +float32 u_filt # [-] Filtered input signal (normalized torque setpoint) used in system identification. +float32 y_filt # [rad/s] Filtered output signal (angular velocity) used in system identification. + +uint8 state # [@enum STATE] Current state of the autotune procedure. +uint8 STATE_IDLE = 0 # Idle (not running) +uint8 STATE_INIT = 1 # Initialize filters and setup +uint8 STATE_ROLL_AMPLITUDE_DETECTION = 2 # FW only: determine required excitation amplitude (roll) +uint8 STATE_ROLL = 3 # Roll-axis excitation and model identification +uint8 STATE_ROLL_PAUSE = 4 # Pause to return to level flight +uint8 STATE_PITCH_AMPLITUDE_DETECTION = 5 # FW only: determine required excitation amplitude (pitch) +uint8 STATE_PITCH = 6 # Pitch-axis excitation and model identification +uint8 STATE_PITCH_PAUSE = 7 # Pause to return to level flight +uint8 STATE_YAW_AMPLITUDE_DETECTION = 8 # FW only: determine required excitation amplitude (yaw) +uint8 STATE_YAW = 9 # Yaw-axis excitation and model identification +uint8 STATE_YAW_PAUSE = 10 # Pause to return to level flight +uint8 STATE_VERIFICATION = 11 # Verify model and candidate gains +uint8 STATE_APPLY = 12 # Apply gains +uint8 STATE_TEST = 13 # Test gains in closed-loop +uint8 STATE_COMPLETE = 14 # Tuning completed successfully +uint8 STATE_FAIL = 15 # Tuning failed (model invalid or controller unstable) +uint8 STATE_WAIT_FOR_DISARM = 16 # Waiting for disarm before finalizing ``` diff --git a/docs/uk/msg_docs/BatteryStatus.md b/docs/uk/msg_docs/BatteryStatus.md index fdbc766cf6..df35417e0f 100644 --- a/docs/uk/msg_docs/BatteryStatus.md +++ b/docs/uk/msg_docs/BatteryStatus.md @@ -2,7 +2,7 @@ Battery status -Battery status information for up to 4 battery instances. +Battery status information for up to 3 battery instances. These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. Battery instance information is also logged and streamed in MAVLink telemetry. @@ -11,81 +11,82 @@ Battery instance information is also logged and streamed in MAVLink telemetry. ```c # Battery status # -# Battery status information for up to 4 battery instances. +# Battery status information for up to 3 battery instances. # These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. # Battery instance information is also logged and streamed in MAVLink telemetry. uint32 MESSAGE_VERSION = 1 -uint8 MAX_INSTANCES = 4 +uint8 MAX_INSTANCES = 3 -uint64 timestamp # [us] Time since system start -bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. -float32 voltage_v # [V] [@invalid 0] Battery voltage -float32 current_a # [A] [@invalid -1] Battery current -float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) -float32 discharged_mah # [mAh] [@invalid -1] Discharged amount -float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity -float32 scale # [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag -float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load -float32 temperature # [°C] [@invalid NaN] Temperature of the battery -uint8 cell_count # [@invalid 0] Number of cells +uint64 timestamp # [us] Time since system start + +bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. +float32 voltage_v # [V] [@invalid 0] Battery voltage +float32 current_a # [A] [@invalid -1] Battery current +float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) +float32 discharged_mah # [mAh] [@invalid -1] Discharged amount +float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity +float32 scale # [-] [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag +float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load +float32 temperature # [°C] [@invalid NaN] Temperature of the battery +uint8 cell_count # [-] [@invalid 0] Number of cells -uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 source # [@enum SOURCE] Battery source +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) -uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 -uint16 capacity # [mAh] Capacity of the battery when fully charged -uint16 cycle_count # Number of discharge cycles the battery has experienced -uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge -uint16 manufacture_date # Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 -uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity -uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation -uint8 id # ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed -uint16 interface_error # Interface error counter +uint8 priority # [-] Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 +uint16 capacity # [mAh] Capacity of the battery when fully charged +uint16 cycle_count # [-] Number of discharge cycles the battery has experienced +uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge +uint16 manufacture_date # [-] Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 +uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity +uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation +uint8 id # [-] ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed +uint16 interface_error # [-] Interface error counter -float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages -float32 max_cell_voltage_delta # Max difference between individual cell voltages +float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages +float32 max_cell_voltage_delta # [V] Max difference between individual cell voltages -bool is_powering_off # Power off event imminent indication, false if unknown -bool is_required # Set if the battery is explicitly required before arming +bool is_powering_off # Power off event imminent indication, false if unknown +bool is_required # Set if the battery is explicitly required before arming -uint8 warning # [@enum WARNING STATE] Current battery warning -uint8 WARNING_NONE = 0 # No battery low voltage warning active -uint8 WARNING_LOW = 1 # Low voltage warning -uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately -uint8 WARNING_EMERGENCY = 3 # Immediate landing required -uint8 WARNING_FAILED = 4 # Battery has failed completely -uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field -uint8 STATE_CHARGING = 7 # Battery is charging +uint8 warning # [@enum WARNING STATE] Current battery warning +uint8 WARNING_NONE = 0 # No battery low voltage warning active +uint8 WARNING_LOW = 1 # Low voltage warning +uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately +uint8 WARNING_EMERGENCY = 3 # Immediate landing required +uint8 WARNING_FAILED = 4 # Battery has failed completely +uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field +uint8 STATE_CHARGING = 7 # Battery is charging -uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication -uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged -uint8 FAULT_SPIKES = 1 # Voltage spikes -uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed -uint8 FAULT_OVER_CURRENT = 3 # Over-current -uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature -uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault -uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) -uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware -uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system -uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem -uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming -uint8 FAULT_COUNT = 11 # Counter. Keep this as last element +uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication +uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged +uint8 FAULT_SPIKES = 1 # Voltage spikes +uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed +uint8 FAULT_OVER_CURRENT = 3 # Over-current +uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature +uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault +uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) +uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware +uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system +uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem +uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming +uint8 FAULT_COUNT = 11 # Counter. Keep this as last element -float32 full_charge_capacity_wh # [Wh] Compensated battery capacity -float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining -uint16 over_discharge_count # Number of battery overdischarge -float32 nominal_voltage # [V] Nominal voltage of the battery pack +float32 full_charge_capacity_wh # [Wh] Compensated battery capacity +float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining +uint16 over_discharge_count # [-] Number of battery overdischarge +float32 nominal_voltage # [V] Nominal voltage of the battery pack -float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate -float32 ocv_estimate # [V] Open circuit voltage estimate -float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate -float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of charge estimate -float32 voltage_prediction # [V] Predicted voltage -float32 prediction_error # [V] Prediction error -float32 estimation_covariance_norm # Norm of the covariance matrix +float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate +float32 ocv_estimate # [V] Open circuit voltage estimate +float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate +float32 volt_based_soc_estimate # [-] [@range 0, 1] Normalized volt based state of charge estimate +float32 voltage_prediction # [V] Predicted voltage +float32 prediction_error # [V] Prediction error +float32 estimation_covariance_norm # [-] Norm of the covariance matrix ``` diff --git a/docs/uk/msg_docs/BatteryStatusV0.md b/docs/uk/msg_docs/BatteryStatusV0.md index 86500d17a6..cd900a1f17 100644 --- a/docs/uk/msg_docs/BatteryStatusV0.md +++ b/docs/uk/msg_docs/BatteryStatusV0.md @@ -32,9 +32,9 @@ uint8 cell_count # [@invalid 0] Number of cells uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 uint16 capacity # [mAh] Capacity of the battery when fully charged diff --git a/docs/uk/msg_docs/CellularStatus.md b/docs/uk/msg_docs/CellularStatus.md index 1bf03491d9..9ba5a00378 100644 --- a/docs/uk/msg_docs/CellularStatus.md +++ b/docs/uk/msg_docs/CellularStatus.md @@ -11,39 +11,39 @@ This is currently used only for logging cell status from MAVLink. # # This is currently used only for logging cell status from MAVLink. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint16 status # [@enum STATUS_FLAG] Status bitmap -uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable -uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable -uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized -uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked -uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down -uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state -uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state -uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections -uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register -uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use -uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated -uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered -uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected +uint16 status # [@enum STATUS_FLAG] Status bitmap +uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable +uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable +uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized +uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked +uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down +uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state +uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state +uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections +uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register +uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use +uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated +uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered +uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected -uint8 failure_reason # [@enum FAILURE_REASON] Failure reason -uint8 FAILURE_REASON_NONE = 0 # No error -uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown -uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing -uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection +uint8 failure_reason # [@enum FAILURE_REASON] Failure reason +uint8 FAILURE_REASON_NONE = 0 # No error +uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown +uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing +uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection -uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type -uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None -uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM -uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE +uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type +uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None +uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM +uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE -uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value -uint16 mcc # [@invalid UINT16_MAX] Mobile country code -uint16 mnc # [@invalid UINT16_MAX] Mobile network code -uint16 lac # [@invalid 0] Location area code +uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value +uint16 mcc # [@invalid UINT16_MAX] Mobile country code +uint16 mnc # [@invalid UINT16_MAX] Mobile network code +uint16 lac # [@invalid 0] Location area code ``` diff --git a/docs/uk/msg_docs/ConfigOverrides.md b/docs/uk/msg_docs/ConfigOverrides.md index 0497137606..ac8abc1b26 100644 --- a/docs/uk/msg_docs/ConfigOverrides.md +++ b/docs/uk/msg_docs/ConfigOverrides.md @@ -7,7 +7,7 @@ ```c # Configurable overrides by (external) modes or mode executors -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -15,7 +15,7 @@ bool disable_auto_disarm # Prevent the drone from automatically disarmin bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout - +bool disable_auto_set_home # Prevent the drone from automatically setting the home position on arm or takeoff int8 SOURCE_TYPE_MODE = 0 int8 SOURCE_TYPE_MODE_EXECUTOR = 1 diff --git a/docs/uk/msg_docs/ConfigOverridesV0.md b/docs/uk/msg_docs/ConfigOverridesV0.md new file mode 100644 index 0000000000..b9bda0d3a9 --- /dev/null +++ b/docs/uk/msg_docs/ConfigOverridesV0.md @@ -0,0 +1,30 @@ +# ConfigOverridesV0 (UORB message) + +Конфігуровані перевизначення (зовнішніми) режимами або виконавцями режимів + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ConfigOverridesV0.msg) + +```c +# Configurable overrides by (external) modes or mode executors + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +bool disable_auto_disarm # Prevent the drone from automatically disarming after landing (if configured) + +bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) +int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout + + +int8 SOURCE_TYPE_MODE = 0 +int8 SOURCE_TYPE_MODE_EXECUTOR = 1 +int8 source_type + +uint8 source_id # ID depending on source_type + +uint8 ORB_QUEUE_LENGTH = 4 + +# TOPICS config_overrides config_overrides_request + +``` diff --git a/docs/uk/msg_docs/ControlAllocatorStatus.md b/docs/uk/msg_docs/ControlAllocatorStatus.md index f93715bdc6..eb6cb73385 100644 --- a/docs/uk/msg_docs/ControlAllocatorStatus.md +++ b/docs/uk/msg_docs/ControlAllocatorStatus.md @@ -24,5 +24,6 @@ int8[16] actuator_saturation # Indicates actuator saturation status. # Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value. uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/uk/msg_docs/DeviceInformation.md b/docs/uk/msg_docs/DeviceInformation.md new file mode 100644 index 0000000000..d415461f94 --- /dev/null +++ b/docs/uk/msg_docs/DeviceInformation.md @@ -0,0 +1,45 @@ +# DeviceInformation (UORB message) + +Device information + +Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +as well as tracking of the used firmware versions on the devices. + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DeviceInformation.msg) + +```c +# Device information +# +# Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +# as well as tracking of the used firmware versions on the devices. + +uint64 timestamp # time since system start (microseconds) + +uint8 device_type # [@enum DEVICE_TYPE] Type of the device. Matches MAVLink DEVICE_TYPE enum + +uint8 DEVICE_TYPE_GENERIC = 0 # Generic/unknown sensor +uint8 DEVICE_TYPE_AIRSPEED = 1 # Airspeed sensor +uint8 DEVICE_TYPE_ESC = 2 # ESC +uint8 DEVICE_TYPE_SERVO = 3 # Servo +uint8 DEVICE_TYPE_GPS = 4 # GPS +uint8 DEVICE_TYPE_MAGNETOMETER = 5 # Magnetometer +uint8 DEVICE_TYPE_PARACHUTE = 6 # Parachute +uint8 DEVICE_TYPE_RANGEFINDER = 7 # Rangefinder +uint8 DEVICE_TYPE_WINCH = 8 # Winch +uint8 DEVICE_TYPE_BAROMETER = 9 # Barometer +uint8 DEVICE_TYPE_OPTICAL_FLOW = 10 # Optical flow +uint8 DEVICE_TYPE_ACCELEROMETER = 11 # Accelerometer +uint8 DEVICE_TYPE_GYROSCOPE = 12 # Gyroscope +uint8 DEVICE_TYPE_DIFFERENTIAL_PRESSURE = 13 # Differential pressure +uint8 DEVICE_TYPE_BATTERY = 14 # Battery +uint8 DEVICE_TYPE_HYGROMETER = 15 # Hygrometer + +char[32] vendor_name # Name of the device vendor +char[32] model_name # Name of the device model + +uint32 device_id # [-] [@invalid 0 if not available] Unique device ID for the sensor. Does not change between power cycles. +char[24] firmware_version # [-] [@invalid empty if not available] Firmware version. +char[24] hardware_version # [-] [@invalid empty if not available] Hardware version. +char[33] serial_number # [-] [@invalid empty if not available] Device serial number or unique identifier. + +``` diff --git a/docs/uk/msg_docs/DifferentialPressure.md b/docs/uk/msg_docs/DifferentialPressure.md index 33e950a107..66963b01f5 100644 --- a/docs/uk/msg_docs/DifferentialPressure.md +++ b/docs/uk/msg_docs/DifferentialPressure.md @@ -1,17 +1,24 @@ # DifferentialPressure (повідомлення UORB) +Differential-pressure (airspeed) sensor + +This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DifferentialPressure.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Differential-pressure (airspeed) sensor +# +# This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 differential_pressure_pa # differential pressure reading in Pascals (may be negative) - -float32 temperature # Temperature provided by sensor in degrees Celsius, NAN if unknown - -uint32 error_count # Number of errors detected by driver +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 differential_pressure_pa # [Pa] Differential pressure reading (may be negative) +float32 temperature # [degC] [@invalid NaN if unknown] Temperature +uint32 error_count # [-] Number of errors detected by driver ``` diff --git a/docs/uk/msg_docs/EscReport.md b/docs/uk/msg_docs/EscReport.md index 8106bb4dc6..29ba577826 100644 --- a/docs/uk/msg_docs/EscReport.md +++ b/docs/uk/msg_docs/EscReport.md @@ -16,6 +16,19 @@ uint8 esc_state # State of ESC - depend on Vendor uint8 actuator_function # actuator output function (one of Motor1...MotorN) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR2 = 102 +uint8 ACTUATOR_FUNCTION_MOTOR3 = 103 +uint8 ACTUATOR_FUNCTION_MOTOR4 = 104 +uint8 ACTUATOR_FUNCTION_MOTOR5 = 105 +uint8 ACTUATOR_FUNCTION_MOTOR6 = 106 +uint8 ACTUATOR_FUNCTION_MOTOR7 = 107 +uint8 ACTUATOR_FUNCTION_MOTOR8 = 108 +uint8 ACTUATOR_FUNCTION_MOTOR9 = 109 +uint8 ACTUATOR_FUNCTION_MOTOR10 = 110 +uint8 ACTUATOR_FUNCTION_MOTOR11 = 111 +uint8 ACTUATOR_FUNCTION_MOTOR12 = 112 + uint16 failures # Bitmask to indicate the internal ESC faults int8 esc_power # Applied power 0-100 in % (negative values reserved) diff --git a/docs/uk/msg_docs/EstimatorStatus.md b/docs/uk/msg_docs/EstimatorStatus.md index 8fb0122c74..95b8227483 100644 --- a/docs/uk/msg_docs/EstimatorStatus.md +++ b/docs/uk/msg_docs/EstimatorStatus.md @@ -21,6 +21,7 @@ uint8 GPS_CHECK_FAIL_MAX_VERT_DRIFT = 7 # 7 : maximum allowed vertical position uint8 GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR = 8 # 8 : maximum allowed horizontal speed fail - requires stationary vehicle uint8 GPS_CHECK_FAIL_MAX_VERT_SPD_ERR = 9 # 9 : maximum allowed vertical velocity discrepancy fail uint8 GPS_CHECK_FAIL_SPOOFED = 10 # 10 : GPS signal is spoofed +uint8 GPS_CHECK_FAIL_JAMMED = 11 # 11 : GPS signal is jammed uint64 control_mode_flags # Bitmask to indicate EKF logic state uint8 CS_TILT_ALIGN = 0 # 0 - true if the filter tilt alignment is complete @@ -52,7 +53,9 @@ uint8 CS_SYNTHETIC_MAG_Z = 25 # 25 - true when we are using a synthesized measur uint8 CS_VEHICLE_AT_REST = 26 # 26 - true when the vehicle is at rest uint8 CS_GPS_YAW_FAULT = 27 # 27 - true when the GNSS heading has been declared faulty and is no longer being used uint8 CS_RNG_FAULT = 28 # 28 - true when the range finder has been declared faulty and is no longer being used -uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurements are being fused +uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurement fusion is intended +uint8 CS_GNSS_FAULT = 45 # 45 - true if GNSS measurements have been declared faulty and are no longer used +uint8 CS_YAW_MANUAL = 46 # 46 - true if yaw has been set manually uint32 filter_fault_flags # Bitmask to indicate EKF internal faults # 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error diff --git a/docs/uk/msg_docs/EstimatorStatusFlags.md b/docs/uk/msg_docs/EstimatorStatusFlags.md index 947c67bf60..af4ee8c081 100644 --- a/docs/uk/msg_docs/EstimatorStatusFlags.md +++ b/docs/uk/msg_docs/EstimatorStatusFlags.md @@ -54,6 +54,9 @@ bool cs_valid_fake_pos # 41 - true if a valid constant position is bein bool cs_constant_pos # 42 - true if the vehicle is at a constant position bool cs_baro_fault # 43 - true when the current baro has been declared faulty and is no longer being used bool cs_gnss_vel # 44 - true if GNSS velocity measurement fusion is intended +bool cs_gnss_fault # 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty +bool cs_yaw_manual # 46 - true if yaw has been set manually +bool cs_gnss_hgt_fault # 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty # fault status uint32 fault_status_changes # number of filter fault status (fs) changes diff --git a/docs/uk/msg_docs/FailureDetectorStatus.md b/docs/uk/msg_docs/FailureDetectorStatus.md index b74da3ec41..111bd96b78 100644 --- a/docs/uk/msg_docs/FailureDetectorStatus.md +++ b/docs/uk/msg_docs/FailureDetectorStatus.md @@ -17,5 +17,6 @@ bool fd_motor float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed) uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/uk/msg_docs/GainCompression.md b/docs/uk/msg_docs/GainCompression.md new file mode 100644 index 0000000000..e26c1e8fcc --- /dev/null +++ b/docs/uk/msg_docs/GainCompression.md @@ -0,0 +1,12 @@ +# GainCompression (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GainCompression.msg) + +```c +uint64 timestamp # Time since system start (microseconds) + +float32[3] compression_gains # [-] [@frame FRD] [@range 0, 1] Multiplicative gain to modify the output of the controller per axis +float32[3] spectral_damper_hpf # [-] [@frame FRD] Squared output of spectral damper high-pass filter +float32[3] spectral_damper_out # [-] [@frame FRD] Spectral damper output squared + +``` diff --git a/docs/uk/msg_docs/GimbalDeviceAttitudeStatus.md b/docs/uk/msg_docs/GimbalDeviceAttitudeStatus.md index a47faa3574..032a3876ee 100644 --- a/docs/uk/msg_docs/GimbalDeviceAttitudeStatus.md +++ b/docs/uk/msg_docs/GimbalDeviceAttitudeStatus.md @@ -14,6 +14,9 @@ uint16 DEVICE_FLAGS_NEUTRAL = 2 uint16 DEVICE_FLAGS_ROLL_LOCK = 4 uint16 DEVICE_FLAGS_PITCH_LOCK = 8 uint16 DEVICE_FLAGS_YAW_LOCK = 16 +uint16 DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32 +uint16 DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64 + float32[4] q float32 angular_velocity_x diff --git a/docs/uk/msg_docs/GpioIn.md b/docs/uk/msg_docs/GpioIn.md index ae4d3c2029..668b6ba865 100644 --- a/docs/uk/msg_docs/GpioIn.md +++ b/docs/uk/msg_docs/GpioIn.md @@ -6,6 +6,7 @@ ```c # GPIO mask and state +uint8 MAX_INSTANCES = 8 uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id diff --git a/docs/uk/msg_docs/GpsDump.md b/docs/uk/msg_docs/GpsDump.md index 7b7e3a776f..f42a2d9638 100644 --- a/docs/uk/msg_docs/GpsDump.md +++ b/docs/uk/msg_docs/GpsDump.md @@ -9,11 +9,15 @@ This message is used to dump the raw gps communication to the log. uint64 timestamp # time since system start (microseconds) +uint8 INSTANCE_MAIN = 0 +uint8 INSTANCE_SECONDARY = 1 + uint8 instance # Instance of GNSS receiver +uint32 device_id uint8 len # length of data, MSB bit set = message to the gps device, # clear = message from the device uint8[79] data # data to write to the log -uint8 ORB_QUEUE_LENGTH = 8 +uint8 ORB_QUEUE_LENGTH = 16 ``` diff --git a/docs/uk/msg_docs/InputRc.md b/docs/uk/msg_docs/InputRc.md index 7982c24d97..f874bbd1ee 100644 --- a/docs/uk/msg_docs/InputRc.md +++ b/docs/uk/msg_docs/InputRc.md @@ -37,11 +37,13 @@ bool rc_lost # RC receiver connection status: True,if no frame has arrived in uint16 rc_lost_frame_count # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_total_frame_count # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_ppm_frame_length # Length of a single PPM frame. Zero for non-PPM systems +uint16 rc_frame_rate # RC frame rate in msg/second. 0 = invalid uint8 input_source # Input source uint16[18] values # measured pulse widths for each of the supported channels int8 link_quality # link quality. Percentage 0-100%. -1 = invalid float32 rssi_dbm # Actual rssi in units of dBm. NaN = invalid +int8 link_snr # link signal to noise ratio in units of dB. -1 = invalid ``` diff --git a/docs/uk/msg_docs/PurePursuitStatus.md b/docs/uk/msg_docs/PurePursuitStatus.md index 96577a0220..8d54ba473e 100644 --- a/docs/uk/msg_docs/PurePursuitStatus.md +++ b/docs/uk/msg_docs/PurePursuitStatus.md @@ -7,11 +7,11 @@ Pure pursuit status ```c # Pure pursuit status -uint64 timestamp # [us] Time since system start -float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller -float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller -float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path -float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint -float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint +uint64 timestamp # [us] Time since system start +float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller +float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller +float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path +float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint +float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint ``` diff --git a/docs/uk/msg_docs/RegisterExtComponentReply.md b/docs/uk/msg_docs/RegisterExtComponentReply.md index 860fa6ecb5..119703472a 100644 --- a/docs/uk/msg_docs/RegisterExtComponentReply.md +++ b/docs/uk/msg_docs/RegisterExtComponentReply.md @@ -3,7 +3,7 @@ [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentReply.msg) ```c -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -17,6 +17,8 @@ int8 arming_check_id # arming check registration ID (-1 if invalid) int8 mode_id # assigned mode ID (-1 if invalid) int8 mode_executor_id # assigned mode executor ID (-1 if invalid) +bool not_user_selectable # mode cannot be selected by the user + uint8 ORB_QUEUE_LENGTH = 2 ``` diff --git a/docs/uk/msg_docs/RegisterExtComponentReplyV0.md b/docs/uk/msg_docs/RegisterExtComponentReplyV0.md new file mode 100644 index 0000000000..cceec88d5c --- /dev/null +++ b/docs/uk/msg_docs/RegisterExtComponentReplyV0.md @@ -0,0 +1,22 @@ +# RegisterExtComponentReplyV0 (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg) + +```c +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID from the request +char[25] name # name from the request + +uint16 px4_ros2_api_version + +bool success +int8 arming_check_id # arming check registration ID (-1 if invalid) +int8 mode_id # assigned mode ID (-1 if invalid) +int8 mode_executor_id # assigned mode executor ID (-1 if invalid) + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/uk/msg_docs/RegisterExtComponentRequest.md b/docs/uk/msg_docs/RegisterExtComponentRequest.md index 9725a579de..7897117efd 100644 --- a/docs/uk/msg_docs/RegisterExtComponentRequest.md +++ b/docs/uk/msg_docs/RegisterExtComponentRequest.md @@ -7,7 +7,7 @@ ```c # Request to register an external component -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -26,7 +26,7 @@ bool register_mode_executor # registering an executor also requires a mod bool enable_replace_internal_mode # set to true if an internal mode should be replaced uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) - +bool not_user_selectable # mode cannot be selected by the user uint8 ORB_QUEUE_LENGTH = 2 diff --git a/docs/uk/msg_docs/RegisterExtComponentRequestV0.md b/docs/uk/msg_docs/RegisterExtComponentRequestV0.md new file mode 100644 index 0000000000..1c49343ff6 --- /dev/null +++ b/docs/uk/msg_docs/RegisterExtComponentRequestV0.md @@ -0,0 +1,33 @@ +# RegisterExtComponentRequestV0 (UORB message) + +Запит на реєстрацію зовнішнього компонента + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg) + +```c +# Request to register an external component + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID, set this to a random value +char[25] name # either the requested mode name, or component name + +uint16 LATEST_PX4_ROS2_API_VERSION = 1 # API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. + +uint16 px4_ros2_api_version # Set to LATEST_PX4_ROS2_API_VERSION + +# Components to be registered +bool register_arming_check +bool register_mode # registering a mode also requires arming_check to be set +bool register_mode_executor # registering an executor also requires a mode to be registered (which is the owned mode by the executor) + +bool enable_replace_internal_mode # set to true if an internal mode should be replaced +uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* +bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) + + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/uk/msg_docs/RoverAttitudeSetpoint.md b/docs/uk/msg_docs/RoverAttitudeSetpoint.md index bd436278ca..ca75a6e3e2 100644 --- a/docs/uk/msg_docs/RoverAttitudeSetpoint.md +++ b/docs/uk/msg_docs/RoverAttitudeSetpoint.md @@ -7,7 +7,7 @@ Rover Attitude Setpoint ```c # Rover Attitude Setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint ``` diff --git a/docs/uk/msg_docs/RoverAttitudeStatus.md b/docs/uk/msg_docs/RoverAttitudeStatus.md index e6df929abd..f5a9ce1f02 100644 --- a/docs/uk/msg_docs/RoverAttitudeStatus.md +++ b/docs/uk/msg_docs/RoverAttitudeStatus.md @@ -7,8 +7,8 @@ Rover Attitude Status ```c # Rover Attitude Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw -float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) +uint64 timestamp # [us] Time since system start +float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw +float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) ``` diff --git a/docs/uk/msg_docs/RoverPositionSetpoint.md b/docs/uk/msg_docs/RoverPositionSetpoint.md index b45aa0515f..751536e7f9 100644 --- a/docs/uk/msg_docs/RoverPositionSetpoint.md +++ b/docs/uk/msg_docs/RoverPositionSetpoint.md @@ -7,11 +7,11 @@ Rover Position Setpoint ```c # Rover Position Setpoint -uint64 timestamp # [us] Time since system start -float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position -float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track -float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed -float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with -float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel +uint64 timestamp # [us] Time since system start +float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position +float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track +float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed +float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with +float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel ``` diff --git a/docs/uk/msg_docs/RoverRateSetpoint.md b/docs/uk/msg_docs/RoverRateSetpoint.md index 9bffa41b80..9bb844e802 100644 --- a/docs/uk/msg_docs/RoverRateSetpoint.md +++ b/docs/uk/msg_docs/RoverRateSetpoint.md @@ -7,7 +7,7 @@ Rover Rate setpoint ```c # Rover Rate setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint ``` diff --git a/docs/uk/msg_docs/RoverRateStatus.md b/docs/uk/msg_docs/RoverRateStatus.md index 684e4c458a..70345fe315 100644 --- a/docs/uk/msg_docs/RoverRateStatus.md +++ b/docs/uk/msg_docs/RoverRateStatus.md @@ -7,9 +7,9 @@ Rover Rate Status ```c # Rover Rate Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate -float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) -float32 pid_yaw_rate_integral # [] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller +uint64 timestamp # [us] Time since system start +float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate +float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) +float32 pid_yaw_rate_integral # [-] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller ``` diff --git a/docs/uk/msg_docs/RoverSpeedSetpoint.md b/docs/uk/msg_docs/RoverSpeedSetpoint.md new file mode 100644 index 0000000000..84176cd1c3 --- /dev/null +++ b/docs/uk/msg_docs/RoverSpeedSetpoint.md @@ -0,0 +1,14 @@ +# RoverSpeedSetpoint (UORB message) + +Rover Speed Setpoint + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedSetpoint.msg) + +```c +# Rover Speed Setpoint + +uint64 timestamp # [us] Time since system start +float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction +float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction + +``` diff --git a/docs/uk/msg_docs/RoverSpeedStatus.md b/docs/uk/msg_docs/RoverSpeedStatus.md new file mode 100644 index 0000000000..4213e1e5df --- /dev/null +++ b/docs/uk/msg_docs/RoverSpeedStatus.md @@ -0,0 +1,18 @@ +# RoverSpeedStatus (UORB message) + +Rover Velocity Status + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedStatus.msg) + +```c +# Rover Velocity Status + +uint64 timestamp # [us] Time since system start +float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction +float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_x_integral # [-] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction +float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction +float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_y_integral # [-] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction + +``` diff --git a/docs/uk/msg_docs/RoverSteeringSetpoint.md b/docs/uk/msg_docs/RoverSteeringSetpoint.md index 3e40a3986b..974f3fc4c9 100644 --- a/docs/uk/msg_docs/RoverSteeringSetpoint.md +++ b/docs/uk/msg_docs/RoverSteeringSetpoint.md @@ -7,7 +7,7 @@ Rover Steering setpoint ```c # Rover Steering setpoint -uint64 timestamp # [us] Time since system start -float32 normalized_steering_setpoint # [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels +uint64 timestamp # [us] Time since system start +float32 normalized_steering_setpoint # [-] [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels ``` diff --git a/docs/uk/msg_docs/RoverThrottleSetpoint.md b/docs/uk/msg_docs/RoverThrottleSetpoint.md index f1c4f7f653..bd5ee93d55 100644 --- a/docs/uk/msg_docs/RoverThrottleSetpoint.md +++ b/docs/uk/msg_docs/RoverThrottleSetpoint.md @@ -7,8 +7,8 @@ Rover Throttle setpoint ```c # Rover Throttle setpoint -uint64 timestamp # [us] Time since system start -float32 throttle_body_x # [] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis -float32 throttle_body_y # [] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis +uint64 timestamp # [us] Time since system start +float32 throttle_body_x # [-] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis +float32 throttle_body_y # [-] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis ``` diff --git a/docs/uk/msg_docs/RoverVelocitySetpoint.md b/docs/uk/msg_docs/RoverVelocitySetpoint.md deleted file mode 100644 index 65103082b8..0000000000 --- a/docs/uk/msg_docs/RoverVelocitySetpoint.md +++ /dev/null @@ -1,15 +0,0 @@ -# RoverVelocitySetpoint (UORB message) - -Rover Velocity Setpoint - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocitySetpoint.msg) - -```c -# Rover Velocity Setpoint - -uint64 timestamp # [us] Time since system start -float32 speed # [m/s] [@range -inf (Backwards), inf (Forwards)] Speed setpoint -float32 bearing # [rad] [@range -pi,pi] [@frame NED] [@invalid: NaN, speed is defined in body x direction] Bearing setpoint -float32 yaw # [rad] [@range -pi, pi] [@frame NED] [@invalid NaN, Defaults to vehicle yaw] Mecanum only: Yaw setpoint - -``` diff --git a/docs/uk/msg_docs/RoverVelocityStatus.md b/docs/uk/msg_docs/RoverVelocityStatus.md deleted file mode 100644 index dfd7756afa..0000000000 --- a/docs/uk/msg_docs/RoverVelocityStatus.md +++ /dev/null @@ -1,18 +0,0 @@ -# RoverVelocityStatus (UORB message) - -Rover Velocity Status - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocityStatus.msg) - -```c -# Rover Velocity Status - -uint64 timestamp # [us] Time since system start -float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction -float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_x_integral # [] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction -float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction -float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_y_integral # [] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction - -``` diff --git a/docs/uk/msg_docs/SensorBaro.md b/docs/uk/msg_docs/SensorBaro.md index cf834ccf36..ef4d7a8f28 100644 --- a/docs/uk/msg_docs/SensorBaro.md +++ b/docs/uk/msg_docs/SensorBaro.md @@ -1,18 +1,25 @@ # SensorBaro (UORB message) +Barometer sensor + +This is populated by barometer drivers and used by the EKF2 estimator. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorBaro.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Barometer sensor +# +# This is populated by barometer drivers and used by the EKF2 estimator. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 pressure # static pressure measurement in Pascals - -float32 temperature # temperature in degrees Celsius - -uint32 error_count +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 pressure # [Pa] Static pressure measurement +float32 temperature # [degC] Temperature. +uint32 error_count # [-] Number of errors detected by driver. uint8 ORB_QUEUE_LENGTH = 4 diff --git a/docs/uk/msg_docs/SensorGnssStatus.md b/docs/uk/msg_docs/SensorGnssStatus.md new file mode 100644 index 0000000000..70602b85fc --- /dev/null +++ b/docs/uk/msg_docs/SensorGnssStatus.md @@ -0,0 +1,19 @@ +# SensorGnssStatus (UORB message) + +Gnss quality indicators + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssStatus.msg) + +```c +# Gnss quality indicators + +uint64 timestamp # time since system start (microseconds) +uint32 device_id # unique device ID for the sensor that does not change between power cycles + +bool quality_available # Set to true if quality indicators are available +uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available +uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available +uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available +uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available + +``` diff --git a/docs/uk/msg_docs/SensorGps.md b/docs/uk/msg_docs/SensorGps.md index 8cb9d3d304..e451e98aaa 100644 --- a/docs/uk/msg_docs/SensorGps.md +++ b/docs/uk/msg_docs/SensorGps.md @@ -38,18 +38,26 @@ float32 vdop # Vertical dilution of precision int32 noise_per_ms # GPS noise per millisecond uint16 automatic_gain_control # Automatic gain control monitor -uint8 JAMMING_STATE_UNKNOWN = 0 -uint8 JAMMING_STATE_OK = 1 -uint8 JAMMING_STATE_WARNING = 2 -uint8 JAMMING_STATE_CRITICAL = 3 -uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical -int32 jamming_indicator # indicates jamming is occurring +uint8 JAMMING_STATE_UNKNOWN = 0 #default +uint8 JAMMING_STATE_OK = 1 +uint8 JAMMING_STATE_MITIGATED = 2 +uint8 JAMMING_STATE_DETECTED = 3 +uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected +int32 jamming_indicator # indicates jamming is occurring -uint8 SPOOFING_STATE_UNKNOWN = 0 -uint8 SPOOFING_STATE_NONE = 1 -uint8 SPOOFING_STATE_INDICATED = 2 -uint8 SPOOFING_STATE_MULTIPLE = 3 -uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical +uint8 SPOOFING_STATE_UNKNOWN = 0 #default +uint8 SPOOFING_STATE_OK = 1 +uint8 SPOOFING_STATE_MITIGATED = 2 +uint8 SPOOFING_STATE_DETECTED = 3 +uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected + +# Combined authentication state (e.g. Galileo OSNMA) +uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default +uint8 AUTHENTICATION_STATE_INITIALIZING = 1 +uint8 AUTHENTICATION_STATE_ERROR = 2 +uint8 AUTHENTICATION_STATE_OK = 3 +uint8 AUTHENTICATION_STATE_DISABLED = 4 +uint8 authentication_state # GPS signal authentication state float32 vel_m_s # GPS ground speed, (metres/sec) float32 vel_n_m_s # GPS North velocity, (metres/sec) @@ -63,6 +71,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi uint8 satellites_used # Number of satellites used +uint32 SYSTEM_ERROR_OK = 0 #default +uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1 +uint32 SYSTEM_ERROR_CONFIGURATION = 2 +uint32 SYSTEM_ERROR_SOFTWARE = 4 +uint32 SYSTEM_ERROR_ANTENNA = 8 +uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16 +uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32 +uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64 +uint32 system_error # General errors with the connected GPS receiver + float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) float32 heading_accuracy # heading accuracy (rad, [0, 2PI]) diff --git a/docs/uk/msg_docs/SensorPreflightMag.md b/docs/uk/msg_docs/SensorPreflightMag.md index 6321333071..767acf66ce 100644 --- a/docs/uk/msg_docs/SensorPreflightMag.md +++ b/docs/uk/msg_docs/SensorPreflightMag.md @@ -1,7 +1,7 @@ # SensorPreflightMag (UORB message) Метрики перевірки сенсорів перед польотом. -Тема не буде оновлена, коли транспортний засіб зброєний +The topic will not be updated when the vehicle is armed [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorPreflightMag.msg) diff --git a/docs/uk/msg_docs/SensorSelection.md b/docs/uk/msg_docs/SensorSelection.md index 810f632d29..562b44d504 100644 --- a/docs/uk/msg_docs/SensorSelection.md +++ b/docs/uk/msg_docs/SensorSelection.md @@ -1,7 +1,7 @@ # SensorSelection (UORB повідомлення) Ідентифікатори датчиків для вибраних датчиків, виведених на темі sensor_combined. -Буде оновлено при запуску модуля датчика та при зміні вибору датчика +Will be updated on startup of the sensor module and when sensor selection changes [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorSelection.msg) diff --git a/docs/uk/msg_docs/SensorTemp.md b/docs/uk/msg_docs/SensorTemp.md new file mode 100644 index 0000000000..5ed50541fe --- /dev/null +++ b/docs/uk/msg_docs/SensorTemp.md @@ -0,0 +1,11 @@ +# SensorTemp (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorTemp.msg) + +```c +uint64 timestamp # time since system start (microseconds) + +uint32 device_id # unique device ID for the sensor that does not change between power cycles +float32 temperature # Temperature provided by sensor (Celsius) + +``` diff --git a/docs/uk/msg_docs/VehicleAirData.md b/docs/uk/msg_docs/VehicleAirData.md index add8c771a8..738f52402e 100644 --- a/docs/uk/msg_docs/VehicleAirData.md +++ b/docs/uk/msg_docs/VehicleAirData.md @@ -1,22 +1,26 @@ # VehicleAirData (повідомлення UORB) +Vehicle air data + +Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +Includes calculated data such as barometric altitude and air density. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAirData.msg) ```c +# Vehicle air data +# +# Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +# Includes calculated data such as barometric altitude and air density. -uint64 timestamp # time since system start (microseconds) - -uint64 timestamp_sample # the timestamp of the raw data (microseconds) - -uint32 baro_device_id # unique device ID for the selected barometer - -float32 baro_alt_meter # Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH. -float32 baro_pressure_pa # Absolute pressure in Pascals -float32 ambient_temperature # Abient temperature in degrees Celsius -uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed - -float32 rho # air density - -uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +uint32 baro_device_id # Unique device ID for the selected barometer +float32 baro_alt_meter # [m] [@frame MSL] Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH +float32 baro_pressure_pa # [Pa] Absolute pressure +float32 ambient_temperature # [degC] Ambient temperature +uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed +float32 rho # [kg/m^3] Air density +uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. ``` diff --git a/docs/uk/msg_docs/VehicleCommand.md b/docs/uk/msg_docs/VehicleCommand.md index 00848d8e4b..71314eb864 100644 --- a/docs/uk/msg_docs/VehicleCommand.md +++ b/docs/uk/msg_docs/VehicleCommand.md @@ -28,7 +28,7 @@ uint16 VEHICLE_CMD_DO_ORBIT = 34 # Start orbiting on the circumference of a circ uint16 VEHICLE_CMD_DO_FIGUREEIGHT = 35 # Start flying on the outline of a figure eight defined by the parameters. |[m] Major radius|[m] Minor radius|[m/s] Velocity|Orientation|Latitude/X|Longitude/Y|Altitude/Z| uint16 VEHICLE_CMD_NAV_ROI = 80 # Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |[@enum VEHICLE_ROI] Region of interest mode.|MISSION index/ target ID.|ROI index (allows a vehicle to manage multiple ROI's)|Unused|x the location of the fixed ROI (see MAV_FRAME)|y|z| uint16 VEHICLE_CMD_NAV_PATHPLANNING = 81 # Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning|0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid|Unused|[deg] [@range 0, 360] Yaw angle at goal, in compass degrees|Latitude/X of goal|Longitude/Y of goal|Altitude/Z of goal| -uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Unused|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| +uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Transition heading, 0: Default, 3: Use specified transition heading|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_VTOL_LAND = 85 # Transition to MC and land at location. |Unused|Unused|Unused|Desired yaw angle.|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_GUIDED_LIMITS = 90 # Set limits for external control. |[s] Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout|[m] Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit|[m] Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit|[m] Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit|Unused|Unused|Unused| uint16 VEHICLE_CMD_NAV_GUIDED_MASTER = 91 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -69,6 +69,7 @@ uint16 VEHICLE_CMD_DO_PARACHUTE=208 # Mission command to trigger a parachute. |a uint16 VEHICLE_CMD_DO_MOTOR_TEST=209 # Motor test command. |Instance (@range 1, )|throttle type|throttle|timeout [s]|Motor count|Test order|Unused| uint16 VEHICLE_CMD_DO_INVERTED_FLIGHT=210 # Change to/from inverted flight. |inverted (0=normal, 1=inverted)|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GRIPPER = 211 # Command to operate a gripper. +uint16 VEHICLE_CMD_DO_AUTOTUNE_ENABLE = 212 # Enable autotune module. |1 to enable|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL=214 # Mission command to set TRIG_INTERVAL for this flight. |[m] Camera trigger distance|Shutter integration time (ms)|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT=220 # Mission command to control a camera or antenna mount, using a quaternion as reference. |q1 - quaternion param #1, w (1 in null-rotation)|q2 - quaternion param #2, x (0 in null-rotation)|q3 - quaternion param #3, y (0 in null-rotation)|q4 - quaternion param #4, z (0 in null-rotation)|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GUIDED_MASTER=221 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -96,6 +97,7 @@ uint16 VEHICLE_CMD_REQUEST_CAMERA_INFORMATION = 521 # Request camera information uint16 VEHICLE_CMD_SET_CAMERA_MODE = 530 # Set camera capture mode (photo, video, etc.). uint16 VEHICLE_CMD_SET_CAMERA_ZOOM = 531 # Set camera zoom. uint16 VEHICLE_CMD_SET_CAMERA_FOCUS = 532 +uint16 VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE = 620 # Set an external estimate of vehicle attitude in degrees. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000 # Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE = 1001 # Gimbal configuration to set which sysid/compid is in primary and secondary control. uint16 VEHICLE_CMD_IMAGE_START_CAPTURE = 2000 # Start image capture sequence. @@ -106,6 +108,7 @@ uint16 VEHICLE_CMD_LOGGING_START = 2510 # Start streaming ULog data. uint16 VEHICLE_CMD_LOGGING_STOP = 2511 # Stop streaming ULog data. uint16 VEHICLE_CMD_CONTROL_HIGH_LATENCY = 2600 # Control starting/stopping transmitting data over the high latency link. uint16 VEHICLE_CMD_DO_VTOL_TRANSITION = 3000 # Command VTOL transition. +uint16 VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE = 5300 # Command safety on/off. |1 to activate safety, 0 to deactivate safety and allow control surface movements|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST = 3001 # Request arm authorization. uint16 VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY = 30001 # Prepare a payload deployment in the flight plan. uint16 VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY = 30002 # Control a pre-programmed payload deployment. @@ -185,6 +188,10 @@ int8 ARMING_ACTION_ARM = 1 uint8 GRIPPER_ACTION_RELEASE = 0 uint8 GRIPPER_ACTION_GRAB = 1 +# Used as param1 in DO_SET_SAFETY_SWITCH_STATE command. +uint8 SAFETY_OFF = 0 +uint8 SAFETY_ON = 1 + uint8 ORB_QUEUE_LENGTH = 8 float32 param1 # Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. diff --git a/docs/uk/msg_docs/VehicleLocalPositionSetpoint.md b/docs/uk/msg_docs/VehicleLocalPositionSetpoint.md index f993f280f6..2309a238a2 100644 --- a/docs/uk/msg_docs/VehicleLocalPositionSetpoint.md +++ b/docs/uk/msg_docs/VehicleLocalPositionSetpoint.md @@ -2,7 +2,7 @@ Місцева позиція задана в рамці NED Телеметрія контролера позиції PID для відстеження. -NaN означає, що стан не був контрольований +NaN means the state was not controlled [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleLocalPositionSetpoint.msg) diff --git a/docs/uk/msg_docs/VehicleOdometry.md b/docs/uk/msg_docs/VehicleOdometry.md index 7dce09ab10..c7abbc98c4 100644 --- a/docs/uk/msg_docs/VehicleOdometry.md +++ b/docs/uk/msg_docs/VehicleOdometry.md @@ -1,41 +1,44 @@ # VehicleOdometry (повідомлення UORB) -Дані odometry Техніки. Fits ROS REP 147 for aerial vehicles +Vehicle odometry data + +Fits ROS REP 147 for aerial vehicles [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleOdometry.msg) ```c -# Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +# Vehicle odometry data +# +# Fits ROS REP 147 for aerial vehicles uint32 MESSAGE_VERSION = 0 -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp sample -uint8 POSE_FRAME_UNKNOWN = 0 -uint8 POSE_FRAME_NED = 1 # NED earth-fixed frame -uint8 POSE_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 pose_frame # Position and orientation frame of reference +uint8 pose_frame # [@enum POSE_FRAME] Position and orientation frame of reference +uint8 POSE_FRAME_UNKNOWN = 0 # Unknown frame +uint8 POSE_FRAME_NED = 1 # North-East-Down (NED) navigation frame. Aligned with True North. +uint8 POSE_FRAME_FRD = 2 # Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. -float32[3] position # Position in meters. Frame of reference defined by local_frame. NaN if invalid/unknown -float32[4] q # Quaternion rotation from FRD body frame to reference frame. First value NaN if invalid/unknown +float32[3] position # [m] [@frame local frame] [@invalid NaN If invalid/unknown] Position. Origin is position of GC at startup. +float32[4] q # [-] [@invalid NaN First value if invalid/unknown] Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) -uint8 VELOCITY_FRAME_UNKNOWN = 0 -uint8 VELOCITY_FRAME_NED = 1 # NED earth-fixed frame -uint8 VELOCITY_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -uint8 velocity_frame # Reference frame of the velocity data +uint8 velocity_frame # [@enum VELOCITY_FRAME] Reference frame of the velocity data +uint8 VELOCITY_FRAME_UNKNOWN = 0 # Unknown frame +uint8 VELOCITY_FRAME_NED = 1 # NED navigation frame at current position. +uint8 VELOCITY_FRAME_FRD = 2 # FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. +uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -float32[3] velocity # Velocity in meters/sec. Frame of reference defined by velocity_frame variable. NaN if invalid/unknown +float32[3] velocity # [m/s] [@frame @velocity_frame] [@invalid NaN If invalid/unknown] Velocity. +float32[3] angular_velocity # [rad/s] [@frame @VELOCITY_FRAME_BODY_FRD] [@invalid NaN If invalid/unknown] Angular velocity in body-fixed frame -float32[3] angular_velocity # Angular velocity in body-fixed frame (rad/s). NaN if invalid/unknown +float32[3] position_variance # [m^2] Variance of position error +float32[3] orientation_variance # [rad^2] Variance of orientation/attitude error (expressed in body frame) +float32[3] velocity_variance # [m^2/s^2] Variance of velocity error -float32[3] position_variance -float32[3] orientation_variance -float32[3] velocity_variance - -uint8 reset_counter -int8 quality +uint8 reset_counter # [-] Reset counter. Counts reset events on attitude, velocity and position. +int8 quality # [-] [@invalid 0] Quality. Unused. # TOPICS vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry # TOPICS estimator_odometry diff --git a/docs/uk/msg_docs/VehicleStatus.md b/docs/uk/msg_docs/VehicleStatus.md index eb32a77eb5..63192fceb7 100644 --- a/docs/uk/msg_docs/VehicleStatus.md +++ b/docs/uk/msg_docs/VehicleStatus.md @@ -20,20 +20,16 @@ uint8 ARMING_STATE_ARMED = 2 uint8 latest_arming_reason uint8 latest_disarming_reason -uint8 ARM_DISARM_REASON_TRANSITION_TO_STANDBY = 0 uint8 ARM_DISARM_REASON_STICK_GESTURE = 1 uint8 ARM_DISARM_REASON_RC_SWITCH = 2 uint8 ARM_DISARM_REASON_COMMAND_INTERNAL = 3 uint8 ARM_DISARM_REASON_COMMAND_EXTERNAL = 4 uint8 ARM_DISARM_REASON_MISSION_START = 5 -uint8 ARM_DISARM_REASON_SAFETY_BUTTON = 6 -uint8 ARM_DISARM_REASON_AUTO_DISARM_LAND = 7 -uint8 ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT = 8 -uint8 ARM_DISARM_REASON_KILL_SWITCH = 9 -uint8 ARM_DISARM_REASON_LOCKDOWN = 10 -uint8 ARM_DISARM_REASON_FAILURE_DETECTOR = 11 -uint8 ARM_DISARM_REASON_SHUTDOWN = 12 -uint8 ARM_DISARM_REASON_UNIT_TEST = 13 +uint8 ARM_DISARM_REASON_LANDING = 6 +uint8 ARM_DISARM_REASON_PREFLIGHT_INACTION = 7 +uint8 ARM_DISARM_REASON_KILL_SWITCH = 8 +uint8 ARM_DISARM_REASON_RC_BUTTON = 13 +uint8 ARM_DISARM_REASON_FAILSAFE = 14 uint64 nav_state_timestamp # time when current nav_state activated @@ -48,7 +44,7 @@ uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode uint8 NAVIGATION_STATE_POSITION_SLOW = 6 uint8 NAVIGATION_STATE_FREE5 = 7 -uint8 NAVIGATION_STATE_FREE4 = 8 +uint8 NAVIGATION_STATE_ALTITUDE_CRUISE = 8 # Altitude with Cruise mode uint8 NAVIGATION_STATE_FREE3 = 9 uint8 NAVIGATION_STATE_ACRO = 10 # Acro mode uint8 NAVIGATION_STATE_FREE2 = 11 diff --git a/docs/uk/msg_docs/index.md b/docs/uk/msg_docs/index.md index 3d2a4443c1..3bc682a23c 100644 --- a/docs/uk/msg_docs/index.md +++ b/docs/uk/msg_docs/index.md @@ -15,9 +15,9 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorMotors](ActuatorMotors.md) — Motor control message - [ActuatorServos](ActuatorServos.md) — Servo control message -- [AirspeedValidated](AirspeedValidated.md) -- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply. -- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request. +- [AirspeedValidated](AirspeedValidated.md) — Validated airspeed +- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply +- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request - [BatteryStatus](BatteryStatus.md) — Battery status - [ConfigOverrides](ConfigOverrides.md) — Configurable overrides by (external) modes or mode executors - [Event](Event.md) — Events interface @@ -70,7 +70,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [VehicleLandDetected](VehicleLandDetected.md) - [VehicleLocalPosition](VehicleLocalPosition.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data - [VehicleRatesSetpoint](VehicleRatesSetpoint.md) - [VehicleStatus](VehicleStatus.md) — Encodes the system state of the vehicle published by commander - [VtolVehicleStatus](VtolVehicleStatus.md) — VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE @@ -84,10 +84,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorOutputs](ActuatorOutputs.md) - [ActuatorServosTrim](ActuatorServosTrim.md) — Servo trims, added as offset to servo outputs - [ActuatorTest](ActuatorTest.md) -- [AdcReport](AdcReport.md) +- [AdcReport](AdcReport.md) — ADC raw data. - [Airspeed](Airspeed.md) — Airspeed data from sensors - [AirspeedWind](AirspeedWind.md) — Wind estimate (from airspeed_selector) -- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) +- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) — Autotune attitude control status - [BatteryInfo](BatteryInfo.md) — Battery information - [ButtonEvent](ButtonEvent.md) - [CameraCapture](CameraCapture.md) @@ -105,7 +105,8 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [DebugKeyValue](DebugKeyValue.md) - [DebugValue](DebugValue.md) - [DebugVect](DebugVect.md) -- [DifferentialPressure](DifferentialPressure.md) +- [DeviceInformation](DeviceInformation.md) — Device information +- [DifferentialPressure](DifferentialPressure.md) — Differential-pressure (airspeed) sensor - [DistanceSensor](DistanceSensor.md) — DISTANCE_SENSOR message data - [DistanceSensorModeChangeRequest](DistanceSensorModeChangeRequest.md) - [DronecanNodeStatus](DronecanNodeStatus.md) @@ -140,6 +141,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [FollowTargetEstimator](FollowTargetEstimator.md) - [FollowTargetStatus](FollowTargetStatus.md) - [FuelTankStatus](FuelTankStatus.md) +- [GainCompression](GainCompression.md) - [GeneratorStatus](GeneratorStatus.md) - [GeofenceResult](GeofenceResult.md) - [GeofenceStatus](GeofenceStatus.md) @@ -229,10 +231,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [RoverPositionSetpoint](RoverPositionSetpoint.md) — Rover Position Setpoint - [RoverRateSetpoint](RoverRateSetpoint.md) — Rover Rate setpoint - [RoverRateStatus](RoverRateStatus.md) — Rover Rate Status +- [RoverSpeedSetpoint](RoverSpeedSetpoint.md) — Rover Speed Setpoint +- [RoverSpeedStatus](RoverSpeedStatus.md) — Rover Velocity Status - [RoverSteeringSetpoint](RoverSteeringSetpoint.md) — Rover Steering setpoint - [RoverThrottleSetpoint](RoverThrottleSetpoint.md) — Rover Throttle setpoint -- [RoverVelocitySetpoint](RoverVelocitySetpoint.md) — Rover Velocity Setpoint -- [RoverVelocityStatus](RoverVelocityStatus.md) — Rover Velocity Status - [Rpm](Rpm.md) - [RtlStatus](RtlStatus.md) - [RtlTimeEstimate](RtlTimeEstimate.md) @@ -240,12 +242,13 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [SensorAccel](SensorAccel.md) - [SensorAccelFifo](SensorAccelFifo.md) - [SensorAirflow](SensorAirflow.md) -- [SensorBaro](SensorBaro.md) +- [SensorBaro](SensorBaro.md) — Barometer sensor - [SensorCombined](SensorCombined.md) — Sensor readings in SI-unit form. These fields are scaled and offset-compensated where possible and do not change with board revisions and sensor updates. - [SensorCorrection](SensorCorrection.md) — Sensor corrections in SI-unit form for the voted sensor - [SensorGnssRelative](SensorGnssRelative.md) — GNSS relative positioning information in NED frame. NED кадр визначається як локальна топологічна система на задній станції. +- [SensorGnssStatus](SensorGnssStatus.md) — Gnss quality indicators - [SensorGps](SensorGps.md) — GPS position in WGS84 coordinates. the field 'timestamp' is for the position & velocity (microseconds) - [SensorGyro](SensorGyro.md) @@ -255,9 +258,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [SensorMag](SensorMag.md) - [SensorOpticalFlow](SensorOpticalFlow.md) - [SensorPreflightMag](SensorPreflightMag.md) — Pre-flight sensor check metrics. - Тема не буде оновлена, коли транспортний засіб зброєний + The topic will not be updated when the vehicle is armed - [SensorSelection](SensorSelection.md) — Sensor ID's for the voted sensors output on the sensor_combined topic. - Буде оновлено при запуску модуля датчика та при зміні вибору датчика + Will be updated on startup of the sensor module and when sensor selection changes +- [SensorTemp](SensorTemp.md) - [SensorUwb](SensorUwb.md) — UWB distance contains the distance information measured by an ultra-wideband positioning system, such as Pozyx or NXP Rddrone. - [SensorsStatus](SensorsStatus.md) — Sensor check metrics. Це значення буде нульовим для датчика, який є первинним або незаповненим. @@ -281,7 +285,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [UlogStreamAck](UlogStreamAck.md) — Ack a previously sent ulog_stream message that had the NEED_ACK flag set - [VehicleAcceleration](VehicleAcceleration.md) -- [VehicleAirData](VehicleAirData.md) +- [VehicleAirData](VehicleAirData.md) — Vehicle air data - [VehicleAngularAccelerationSetpoint](VehicleAngularAccelerationSetpoint.md) - [VehicleConstraints](VehicleConstraints.md) — Local setpoint constraints in NED frame setting something to NaN means that no limit is provided @@ -289,7 +293,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [VehicleImuStatus](VehicleImuStatus.md) - [VehicleLocalPositionSetpoint](VehicleLocalPositionSetpoint.md) — Local position setpoint in NED frame Telemetry of PID position controller to monitor tracking. - NaN означає, що стан не був контрольований + NaN means the state was not controlled - [VehicleMagnetometer](VehicleMagnetometer.md) - [VehicleOpticalFlow](VehicleOpticalFlow.md) — Optical flow in XYZ body frame in SI units. - [VehicleOpticalFlowVel](VehicleOpticalFlowVel.md) @@ -301,10 +305,14 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [YawEstimatorStatus](YawEstimatorStatus.md) - [AirspeedValidatedV0](AirspeedValidatedV0.md) - [ArmingCheckReplyV0](ArmingCheckReplyV0.md) +- [ArmingCheckRequestV0](ArmingCheckRequestV0.md) — Arming check request. - [BatteryStatusV0](BatteryStatusV0.md) — Battery status +- [ConfigOverridesV0](ConfigOverridesV0.md) — Configurable overrides by (external) modes or mode executors - [EventV0](EventV0.md) — this message is required here in the msg_old folder because other msg are depending on it Events interface - [HomePositionV0](HomePositionV0.md) — GPS home position in WGS84 coordinates. +- [RegisterExtComponentReplyV0](RegisterExtComponentReplyV0.md) +- [RegisterExtComponentRequestV0](RegisterExtComponentRequestV0.md) — Request to register an external component - [VehicleAttitudeSetpointV0](VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](VehicleLocalPositionV0.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. diff --git a/docs/uk/neural_networks/index.md b/docs/uk/neural_networks/index.md new file mode 100644 index 0000000000..016a8cbe0e --- /dev/null +++ b/docs/uk/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/uk/neural_networks/mc_neural_network_control.md b/docs/uk/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..53339f5ee3 --- /dev/null +++ b/docs/uk/neural_networks/mc_neural_network_control.md @@ -0,0 +1,123 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +:::tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Вхід + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### Output + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/uk/neural_networks/nn_module_utilities.md b/docs/uk/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..c41a520cf6 --- /dev/null +++ b/docs/uk/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## Автозавантаження + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## Логування + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/uk/neural_networks/raptor.md b/docs/uk/neural_networks/raptor.md new file mode 100644 index 0000000000..5568790267 --- /dev/null +++ b/docs/uk/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## Загальний огляд + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## Структура + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## Функції + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## Використання + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### Установка + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### Усунення проблем + +#### Логування + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/uk/neural_networks/tflm.md b/docs/uk/neural_networks/tflm.md new file mode 100644 index 0000000000..85b61cb840 --- /dev/null +++ b/docs/uk/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### Вхідні дані + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### Виводи + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/uk/payloads/generic_actuator_control.md b/docs/uk/payloads/generic_actuator_control.md index 17f9c27b0c..4d1f9c6e66 100644 --- a/docs/uk/payloads/generic_actuator_control.md +++ b/docs/uk/payloads/generic_actuator_control.md @@ -60,7 +60,7 @@ - Виберіть заголовок у редакторі маршрутної точки місії, щоб відкрити редактор **Select Mission Command**. - Виберіть категорію **Advanced**, а потім пункт **Set actuator** (якщо елемента немає, спробуйте новішу версію _QGroundControl_ або щоденну збірку). - Це змінить тип елемента місії на «Set actuator». + Це змінить тип елемента місії на «Set actuator». 3. Виберіть підключені приводи та встановіть їхні значення (вони нормалізовані між -1 і 1). diff --git a/docs/uk/peripherals/adsb_flarm.md b/docs/uk/peripherals/adsb_flarm.md index 223e1f250e..5a6c9d8c01 100644 --- a/docs/uk/peripherals/adsb_flarm.md +++ b/docs/uk/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder Було протестовано з наступними пристроями: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## Налаштування програмного забезпечення diff --git a/docs/uk/peripherals/dshot.md b/docs/uk/peripherals/dshot.md index e493119df4..711bfca89d 100644 --- a/docs/uk/peripherals/dshot.md +++ b/docs/uk/peripherals/dshot.md @@ -11,6 +11,10 @@ DShot is an alternative ESC protocol that has several advantages over [PWM](../p Ця тема показує, як підключити та налаштувати DShot ESC. +## Supported ESC + +[ESCs & Motors > Supported ESCs](../peripherals/esc_motors#supported-esc) has a list of supported ESC (check "Protocols" column for DShot ESC). + ## Wiring/Connections {#wiring} DShot ESC are wired the same way as [PWM ESCs](pwm_escs_and_servo.md). diff --git a/docs/uk/peripherals/esc_motors.md b/docs/uk/peripherals/esc_motors.md index 0df5c439b5..6fb60c6709 100644 --- a/docs/uk/peripherals/esc_motors.md +++ b/docs/uk/peripherals/esc_motors.md @@ -3,80 +3,44 @@ Багато дронів PX4 використовують безшовні двигуни, які керуються контролером польотів через електронний контролер швидкості (ESC). ESC бере сигнал від контролера польоту і використовує його для встановлення рівня потужності, яка постачається до двигуна. -PX4 supports a number of common protocols for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). +PX4 supports a number of [common protocols](../esc/esc_protocols.md) for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). + +## Supported ESC + +The following list is non-exhaustive. + +| ESC Device | Протоколи | Firmwares | Примітки | +| ------------------------------ | ------------------------------------ | ------------------------ | ----------------------------------------------------- | +| [ARK 4IN1 ESC] | [Dshot], [PWM] | [AM32] | Has versions with/without connnectors | +| [Holybro Kotleta 20] | [DroneCAN], [PWM] | [PX4 Sapog ESC Firmware] | | +| [Vertiq Motor & ESC modules] | [Dshot], [OneShot], Multishot, [PWM] | Vertiq firmware | Larger modules support DroneCAN, ESC and Motor in one | +| [RaccoonLab CAN PWM ESC nodes] | [DroneCAN], Cyphal | | Cyphal and DroneCAN notes for PWM ESC | +| [VESC ESCs] | [DroneCAN], [PWM] | VESC project firmware | | +| [Zubax Telega] | [DroneCAN], [PWM] | Telega-based | ESC and Motor in one | + + + +[ARK 4IN1 ESC]: ../esc/ark_4in1_esc.md +[AM32]: https://am32.ca/ +[PX4 Sapog ESC Firmware]: ../dronecan/sapog.md +[VESC ESCs]: ../peripherals/vesc.md +[DroneCAN]: ../dronecan/escs.md +[Dshot]: ../peripherals/dshot.md +[OneShot]: ../peripherals/oneshot.md +[PWM]: ../peripherals/pwm_escs_and_servo.md +[Holybro Kotleta 20]: ../dronecan/holybro_kotleta.md +[Vertiq Motor & ESC modules]: ../peripherals/vertiq.md +[RaccoonLab CAN PWM ESC nodes]: ../dronecan/raccoonlab_nodes.md +[Zubax Telega]: ../dronecan/zubax_telega.md + +## Дивіться також Для додаткової інформації дивіться: +- [ESC Protocols](../esc/esc_protocols.md) — overview of main ESC/Servo protocols supported by PX4 - [PWM ESCs and Servos](../peripherals/pwm_escs_and_servo.md) - [OneShot ESCs and Servos](../peripherals/oneshot.md) - [DShot](../peripherals/dshot.md) - [DroneCAN ESCs](../dronecan/escs.md) - [ESC Calibration](../advanced_config/esc_calibration.md) - [ESC Firmware and Protocols Overview](https://oscarliang.com/esc-firmware-protocols/) (oscarliang.com) - -Огляд високого рівня основних протоколів ESC/Servo, які підтримуються PX4, наведено нижче. - -## Протоколи ESC - -### PWM - -[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). - -PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired power level. -Ширина імпульсу зазвичай коливається між 1000 мкс для нульової потужності та 2000 мкс для повної потужності. -Періодична частота кадру сигналу залежить від можливості ESC і зазвичай коливається від 50 Гц до 490 Гц (теоретичний максимум становить 500 Гц для дуже малого циклу "вимкнено"). -Вища швидкість є кращою для ЕСК, особливо коли потрібна швидка реакція на зміни встановленої точки. -Для серводвигунів з ШІМ зазвичай достатньо 50 Гц, і багато з них не підтримують вищі частоти. - -![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) - -In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the range values representing low and high values can vary significantly. -Unlike [dshot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. - -Установка: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) -- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### Oneshot 125 - -[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. -They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). -Існує кілька варіантів протоколу OneShot, які підтримують різні швидкості. -PX4 підтримує лише OneShot 125. - -OneShot 125 - це те саме, що і PWM, але використовує ширину імпульсів, яка в 8 разів коротша (від 125 мкс до 250 мкс для нуля до повної потужності). -Це дозволяє ESC OneShot 125 мати набагато коротший цикл роботи / вищу швидкість. -Для PWM теоретичний максимум становить близько 500 Гц, тоді як для OneShot він наближається до 4 кГц. -Фактична підтримувана швидкість залежить від використаного ESC. - -Установка: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### DShot - -[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduce latency, in particular racing multicopters, VTOL vehicles, and so on. - -It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). -Крім того, для його роботи не потрібна калібрування ESC, телеметрія доступна з деяких ESCs, і ви можете змінити напрямок обертання двигуна - -PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). -Вибір ESC DShot з вищою швидкістю в інтерфейсі призводить до зниження затримки, але нижчі швидкості є більш надійними (і, отже, більш підходять для великих літаків з довшими проводами); деякі ESC підтримують лише нижчі швидкості (див. технічні характеристики для отримання інформації). - -Установка: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. - -### DroneCAN - -[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. -Реалізація PX4 наразі обмежена частотами оновлення 200 Гц. - -DroneCAN shares many similar benefits to [Dshot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. - -[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). diff --git a/docs/uk/peripherals/gripper.md b/docs/uk/peripherals/gripper.md index 0982b2f9fb..26c3d3bc35 100644 --- a/docs/uk/peripherals/gripper.md +++ b/docs/uk/peripherals/gripper.md @@ -75,13 +75,13 @@ For grippers that do not provide sensor-based feedback of their state, which is - Run the `payload_deliverer` test in the QGC [MAVLink Shell](../debug/mavlink_shell.md): - ```sh - > payload_deliverer gripper_test - ``` + ```sh + > payload_deliverer gripper_test + ``` - ::: info - If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. - You might also run the `payload_deliverer start` command in the Nuttx shell. + ::: info + If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. + You might also run the `payload_deliverer start` command in the Nuttx shell. ::: diff --git a/docs/uk/peripherals/remote_id.md b/docs/uk/peripherals/remote_id.md index dd5714d51a..c2673dae23 100644 --- a/docs/uk/peripherals/remote_id.md +++ b/docs/uk/peripherals/remote_id.md @@ -245,11 +245,11 @@ If the Remote ID CAN node is present and the messages are not being received, th 2. Navigate to the [Application settings](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/general.html): **Application Settings > General > Miscellaneous**. 3. Select `Enable Remote ID`. - The Remote ID tab should appear. + The Remote ID tab should appear. - ::: info - If this option is not present you may be in a very recent version of QGC. - In that case, open the view at: **Application Settings > Remote ID**. + ::: info + If this option is not present you may be in a very recent version of QGC. + In that case, open the view at: **Application Settings > Remote ID**. ::: diff --git a/docs/uk/power_module/ark_12s_payload_power_module.md b/docs/uk/power_module/ark_12s_payload_power_module.md new file mode 100644 index 0000000000..d629156a40 --- /dev/null +++ b/docs/uk/power_module/ark_12s_payload_power_module.md @@ -0,0 +1,56 @@ +# ARK 12S Payload Power Module + +The [ARK 12S Payload Power Module](https://arkelectron.com/product/ark-12s-payload-power-module/) is a dual 5V 6A and 12V 6A power supply and digital power monitor designed for the Pixhawk Autopilot Bus Carrier boards. + +This is similar to the [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) except that the additional 12V 6A supply allows easier powering of a payload. + +![ARK 12S Payload Power Module](../../assets/hardware/power_module/ark_power_modules//ark_12s_payload_power.jpg) + +## Де купити + +Замовте цей модуль з: + +- [ARK Electronics](https://arkelectron.com/product/ark-12s-payload-power-module/) (US) + +## Характеристики обладнання + +- **TI INA238 Digital Power Monitor** + - 0.0001 Ohm Shunt + - I2C Interface + +- **5.2V 6A Step-Down Regulator** + - 10V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **12.0V 6A Step-Down Regulator** + - 15V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **75V Maximum Input Voltage** + +- **Connections** + - Solder Pads Battery Input + - Solder Pads Battery Output + - 6 Pin Molex CLIK-Mate Output + - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) + - 4 Pin Molex CLIK-Mate 12V Output + +- **Other** + - USA Built + - Includes 6 Pin Molex CLIK-Mate Cable + +- **Additional Information** + - Weight: 20.5 g + - Dimensions: 3.7 cm x 3.5 cm x 1.3 cm + +## Налаштування PX4 + +- Disable the `SENS_EN_INA226` parameter if it is enabled. +- Enable the `SENS_EN_INA238` parameter. +- Reboot the flight controller. +- Set the `INA238_SHUNT` parameter to 0.0001. +- Reboot the flight controller. + +## Дивіться також + +- [ARK 12S Payload Power Module Documentation](https://docs.arkelectron.com/power/ark-12s-payload-power-module) (ARK Docs) diff --git a/docs/uk/power_module/ark_pab_power_module.md b/docs/uk/power_module/ark_pab_power_module.md index 16865d68e0..353b88bfe9 100644 --- a/docs/uk/power_module/ark_pab_power_module.md +++ b/docs/uk/power_module/ark_pab_power_module.md @@ -6,35 +6,36 @@ Note that at 60A and 20°C without cooling, the 5V regulator is de-rated to a 3A ![ARK PAB Power Module](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_module.jpg) +This power module is also available without connectors: + +![ARK PAB Power Module No Connector](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_no_connector.jpg) + ## Де купити Замовте цей модуль з: -- [ARK Electronics](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module No Connector](https://arkelectron.com/product/ark-pab-power-module-no-connector/) (US) ## Характеристики обладнання - **TI INA226 Digital Power Monitor** - - 0.0005 Ohm Shunt - I2C Interface - **5.2V 6A Step-Down Regulator** - - 33V Maximum Input Voltage - 5.8V Minimum Input Voltage at 6A Out - Output Over-Voltage Protection - Output Over-Current Protection - **Connections** - - - XT60 Battery Input - - XT60 Battery Output + - XT60 Battery Input / Solder Pad Battery Input (No Connector version) + - XT60 Battery Output / Solder Pad Battery Output (No Connector version) - 6 Pin Molex CLIK-Mate Output - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) - **Other** - - USA Built - FCC Compliant - Includes 6 Pin Molex CLIK-Mate Cable diff --git a/docs/uk/power_module/index.md b/docs/uk/power_module/index.md index 0c45c5548d..b79d5e4d60 100644 --- a/docs/uk/power_module/index.md +++ b/docs/uk/power_module/index.md @@ -27,6 +27,7 @@ This section provides information about a number of power modules and power dist - Цифрові (I2C) модулі напруги та поточного живлення (для контролерів, похідних від Pixhawk FMUv6X та FMUv5X): - [ARK PAB Power Module](../power_module/ark_pab_power_module.md) - [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](../power_module/ark_12s_payload_power_module.md) - [Holybro PM02D](../power_module/holybro_pm02d.md) - [Holybro PM03D](../power_module/holybro_pm03d.md) - [DroneCAN](../dronecan/index.md) power modules diff --git a/docs/uk/releases/1.14.md b/docs/uk/releases/1.14.md index 8bcf3d1dff..0118ab0be6 100644 --- a/docs/uk/releases/1.14.md +++ b/docs/uk/releases/1.14.md @@ -72,18 +72,18 @@ For users upgrading from previous versions, please take a moment to review the f 1. Для змін актуатора необхідно перевірити геометрію автомобіля та зв'язки моторів/сервоприводів з вашим автомобілем. In QGC, find the [Actuator Configuration Dashboard](../config/actuators.md), and make sure to confirm the airframe geometry matches actuals from your vehicle, as well as update motor and ensure motors and servos are mapped to outputs as they are wired to the frame and with the correct ESC type specified. Примітка: скористайтеся повзунками в користувацькому інтерфейсі. Вони можуть бути використані для підтвердження з'єднання моторів. - We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). + We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). - Калібрування є критичним, якщо ви використовуєте власний файл змішувача або повітряну конструкцію, яку ви призначили в попередній версії, немає в PX4 v1.14. + Калібрування є критичним, якщо ви використовуєте власний файл змішувача або повітряну конструкцію, яку ви призначили в попередній версії, немає в PX4 v1.14. - However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. + However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. 2. Змінено значення вимкненого PWM за замовчуванням з 900 мкс на 1000 мкс. - Перевірте, чи ви раніше використовували значення роззброєння PWM за замовчуванням і якщо зміни впливають на вашу настройку. - For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. + Перевірте, чи ви раніше використовували значення роззброєння PWM за замовчуванням і якщо зміни впливають на вашу настройку. + For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. 3. Користувачам Fast-RTPS потрібно перенести свій код на новий інтерфейс uXRCE-DDS. - Код програми повинен вимагати лише незначних модифікацій. Це включає (мінімально): + Код програми повинен вимагати лише незначних модифікацій. Це включає (мінімально): Modifying topic names to match the new naming pattern, which changed from `fmu//out` to `fmu/out/`, and [Adusting the QoS settings](../ros2/user_guide.md#ros-2-subscriber-qos-settings). diff --git a/docs/uk/releases/1.16.md b/docs/uk/releases/1.16.md index 024c3e2fff..a60af13c90 100644 --- a/docs/uk/releases/1.16.md +++ b/docs/uk/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/uk/releases/1.17.md b/docs/uk/releases/1.17.md new file mode 100644 index 0000000000..5b388e69e0 --- /dev/null +++ b/docs/uk/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Прочитайте перед оновленням + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Основні зміни + +- Уточнюється + +## Інструкції для оновлення + +## Інші зміни + +### Підтримка обладнання + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### Управління + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Оцінки + +- Уточнюється + + + +### Симуляція + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- Уточнюється + +### Ethernet + +- Уточнюється + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- Уточнюється + + + +### VTOL + +- Уточнюється + +### Літак з фіксованим крилом + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### Ровер + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- Уточнюється diff --git a/docs/uk/releases/index.md b/docs/uk/releases/index.md index 32ee1a8d77..260fd67bc7 100644 --- a/docs/uk/releases/index.md +++ b/docs/uk/releases/index.md @@ -2,7 +2,8 @@ Перелік PX4 реліз, вони містять список змін, що відбулися в кожному релізі, пояснення включених функцій, виправлень, застарілих та оновлень. -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/uk/releases/main.md b/docs/uk/releases/main.md index a3472a434f..835589598a 100644 --- a/docs/uk/releases/main.md +++ b/docs/uk/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Прочитайте перед оновленням -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -44,7 +44,8 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Управління -- Уточнюється +- Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Оцінки @@ -52,27 +53,52 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Датчики -- Уточнюється +- Add [sbgECom INS driver](../sensor/sbgecom.md) ([PX4-Autopilot#24137](https://github.com/PX4/PX4-Autopilot/pull/24137)) +- Quick magnetometer calibration now supports specifying an arbitrary initial heading ([PX4-Autopilot#24637](https://github.com/PX4/PX4-Autopilot/pull/24637)) ### Симуляція - Уточнюється + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - Уточнюється -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- Уточнюється + + ### MAVLink - Уточнюється +### RC + +- Parse ELRS Status and Link Statistics TX messages in the CRSF parser. + ### Мульти-Ротор -- Уточнюється +- Removed parameters `MPC_{XY/Z/YAW}_MAN_EXPO` and use default value instead, as they were not deemed necessary anymore. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). +- Renamed `MPC_HOLD_DZ` to `MAN_DEADZONE` to have it globally available in modes that allow for a dead zone. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### VTOL @@ -80,12 +106,25 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Літак з фіксованим крилом +- Уточнюється + + ### Ровер +- Уточнюється + + ### ROS 2 diff --git a/docs/uk/ros/mavros_custom_messages.md b/docs/uk/ros/mavros_custom_messages.md index 253bffbb45..23fb6960f1 100644 --- a/docs/uk/ros/mavros_custom_messages.md +++ b/docs/uk/ros/mavros_custom_messages.md @@ -110,7 +110,7 @@ Follow _Source Installation_ instructions from [mavlink/mavros](https://github.c - `PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0` - `workspace/src/mavlink/message_definitions/v1.0` - are exactly the same. + are exactly the same. ::: diff --git a/docs/uk/ros/mavros_installation.md b/docs/uk/ros/mavros_installation.md index 840d1a8102..b486ce151e 100644 --- a/docs/uk/ros/mavros_installation.md +++ b/docs/uk/ros/mavros_installation.md @@ -148,21 +148,21 @@ $ wstool init ~/catkin_ws/src 2. Встановити MAVROS з джерела, використовуючи як випущену, так і останню версію: - Випущений реліз/стабільний - ```sh - rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall + ``` - Найновіше джерело - ```sh - rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall + ``` - ```sh - # For fetching all the dependencies into your catkin_ws, - # just add '--deps' to the above scripts, E.g.: - # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall - ``` + ```sh + # For fetching all the dependencies into your catkin_ws, + # just add '--deps' to the above scripts, E.g.: + # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall + ``` 3. Create workspace & deps diff --git a/docs/uk/ros/offboard_control.md b/docs/uk/ros/offboard_control.md index aead2313e2..4908421e29 100644 --- a/docs/uk/ros/offboard_control.md +++ b/docs/uk/ros/offboard_control.md @@ -38,9 +38,9 @@ Enable MAVLink on the serial port that you connect to the companion computer (se 1. Один підключений до UART порту автопілота 2. Один підключений до наземної станції - Приклад радіомодулів включає: + Приклад радіомодулів включає: - - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) + - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) [![Mermaid graph: mavlink channel](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9) diff --git a/docs/uk/ros2/offboard_control.md b/docs/uk/ros2/offboard_control.md index 142c9931cb..2a6b62079d 100644 --- a/docs/uk/ros2/offboard_control.md +++ b/docs/uk/ros2/offboard_control.md @@ -1,6 +1,6 @@ # ROS 2 Offboard Control Приклад -The following C++ example shows how to do position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. +The following C++ example shows how to do multicopter position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. Приклад починає відправляти установочні точки, входить у режим offboard, озброюється, піднімається на 5 метрів і чекає. Незважаючи на простоту, він демонструє основні принципи використання offboard control і способи надсилання команд транспортному засобу. @@ -22,7 +22,7 @@ To subscribe to data coming from nodes that publish in a different frame (for ex ## Випробування -Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the simulator, install ROS 2, and start the XRCE-DDS Agent. +Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the multicopter simulator, install ROS 2, and start the XRCE-DDS Agent. After that we can follow a similar set of steps to those in [ROS 2 User Guide > Build ROS 2 Workspace](../ros2/user_guide.md#build-ros-2-workspace) to run the example. diff --git a/docs/uk/ros2/px4_ros2_control_interface.md b/docs/uk/ros2/px4_ros2_control_interface.md index 8c3fb9e5f6..8597ea0532 100644 --- a/docs/uk/ros2/px4_ros2_control_interface.md +++ b/docs/uk/ros2/px4_ros2_control_interface.md @@ -14,7 +14,7 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta ::: -[PX4 ROS 2 Interface бібліотека](../ros2/px4_ros2_interface_lib.md) - це бібліотека C++++, яка спрощує контроль PX4 з ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. Розробники використовують бібліотеку для створення і динамічної реєстрації режимів, написаних за допомогою ROS 2. Ці режими динамічно реєструються в PX4 і здаються частиною PX4 для наземної станції або іншої зовнішньої системи. @@ -26,6 +26,12 @@ At the time of writing, parts of the PX4 ROS 2 Control Interface are experimenta PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +:::tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: + ## Загальний огляд Ця діаграма надає концептуального уявлення про те, як режими інтерфейсу і режими керування будуть взаємодіяти з PX4. @@ -109,92 +115,92 @@ Unless the mode is safety-critical, requires strict timing or very high update r 2. Клонуйте репозиторій в робочий простір: - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - :::info - Для забезпечення сумісності, використовуйте останні _main_ гілки для PX4, _px4_msgs_ та бібліотеки. - Дивіться також [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + :::info + Для забезпечення сумісності, використовуйте останні _main_ гілки для PX4, _px4_msgs_ та бібліотеки. + Дивіться також [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). ::: 3. Побудуйте робочий простір: - ```sh - cd .. - colcon build - source install/setup.bash - ``` + ```sh + cd .. + colcon build + source install/setup.bash + ``` 4. У іншій оболонці запустіть PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (тут ми використовуємо Gazebo-Classic, але ви можете використовувати будь-яку модель або симулятор) + (тут ми використовуємо Gazebo-Classic, але ви можете використовувати будь-яку модель або симулятор) 5. Запустіть агента micro XRCE в новій оболонці (після цього ви можете залишити його запущеним): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 6. Запустіть QGroundControl. - :::info - Використовуйте QGroundControl Daily, яка підтримує динамічне оновлення списку режимів. + :::info + Використовуйте QGroundControl Daily, яка підтримує динамічне оновлення списку режимів. ::: 7. Повернутись до терміналу 2 ROS, запустити один із прикладів: - ```sh - ros2 run example_mode_manual_cpp example_mode_manual - ``` + ```sh + ros2 run example_mode_manual_cpp example_mode_manual + ``` - Ви повинні отримати на виході режим 'Мій ручний режим' зареєстрований: + Ви повинні отримати на виході режим 'Мій ручний режим' зареєстрований: - ```sh - [DEBUG] [example_mode_manual]: Checking message compatibility... - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply - [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) - ``` + ```sh + [DEBUG] [example_mode_manual]: Checking message compatibility... + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply + [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) + ``` 8. На PX4 оболонці ви можете перевірити, що PX4 зареєстрував новий режим: - ```sh - commander status - ``` + ```sh + commander status + ``` - Вихід має містити: + Вихід має містити: - ```plain - INFO [commander] Disarmed - INFO [commander] navigation mode: Position - INFO [commander] user intended navigation mode: Position - INFO [commander] in failsafe: no - INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode - ``` + ```plain + INFO [commander] Disarmed + INFO [commander] navigation mode: Position + INFO [commander] user intended navigation mode: Position + INFO [commander] in failsafe: no + INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode + ``` 9. У цій точці ви також повинні побачити режим в QGroundControl : 10. Виберіть режим, переконайтеся, що у вас є ручне джерело управління (фізичний або віртуальний джойстик), та озброєння транспорту. - Тоді режим активується, і він має вивести наступний вивід: + Тоді режим активується, і він має вивести наступний вивід: - ```sh - [DEBUG] [example_mode_manual]: Mode 'My Manual Mode' activated - ``` + ```sh + [DEBUG] [example_mode_manual]: Mode 'My Manual Mode' activated + ``` 11. Тепер ви готові створити свій власний режим. @@ -267,9 +273,9 @@ private: class MyModeExecutor : public px4_ros2::ModeExecutorBase // [1] { public: - MyModeExecutor(rclcpp::Node & node, px4_ros2::ModeBase & owned_mode) // [2] - : ModeExecutorBase(node, px4_ros2::ModeExecutorBase::Settings{}, owned_mode), - _node(node) + MyModeExecutor(px4_ros2::ModeBase & owned_mode) // [2] + : ModeExecutorBase(px4_ros2::ModeExecutorBase::Settings{}, owned_mode), + _node(owned_mode.node()) { } enum class State // [3] @@ -345,9 +351,10 @@ private: Наступні розділи надають список підтримуваних типів установок: -- GotoSetpointType: Плавне позиціонування та (за бажанням) керування курсом -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): Smooth position and (optionally) heading control +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics - DirectActuatorsSetpointType: Пряме керування моторами та установками сервоприводів польотних поверхонь +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). @@ -355,14 +362,20 @@ The other setpoint types are currently experimental, and can be found in: [px4_r Ви можете додати свої власні типи установок, додавши клас, який успадковується від px4_ros2::SetpointBase, встановлює прапорці конфігурації відповідно до того, що вимагає установка, а потім публікує будь-яку тему, що містить установку ::: -#### Установка "перейти до" (GotoSetpointType) +#### Go-to Setpoint (MulticopterGotoSetpointType) + + + + :::info -Цей тип установки наразі підтримується лише для багтрикоптерів. +This setpoint type is currently only supported for multicopters. ::: -Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::GotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/goto.hpp) setpoint type. -Тип установки транслюється до плавних позиційних та курсових вирівнювачів на основі FMU, сформульованих з оптимальним за часом, максимальною швидкістю зміни прискорення, з обмеженнями швидкості та прискорення. +Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::MulticopterGotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) setpoint type. +The setpoint type is streamed to FMU based position and heading smoothers formulated with time-optimal, maximum-jerk trajectories, with velocity and acceleration constraints. + +There is also a [`px4_ros2::MulticopterGotoGlobalSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) class that allows to send setpoints in global coordinates. Найбільш тривіальне використання полягає в простому введенні 3D-позиції в метод оновлення: @@ -408,7 +421,7 @@ _goto_setpoint->update( #### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) - + :::info This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. @@ -420,7 +433,7 @@ This setpoint is streamed to the PX4 [_FwLateralLongitudinalControl_ module](../ To control the vehicle, at least one lateral **and** one longitudinal setpoint must be provided: 1. Of the longitudinal inputs: either `altitude` or `height_rate` must be finite to control vertical motion. - If both are set to `NAN`, the vehicle will maintain its current altitude. + If both are set to `NAN`, the vehicle will maintain its current altitude. 2. Of the lateral inputs: at least one of `course`, `airspeed_direction`, or `lateral_acceleration` must be finite. For a detailed description of the controllable parameters, please refer to message definitions ([FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) and [FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md)). @@ -548,13 +561,47 @@ and [`FW_THR_MAX`](../advanced_config/parameter_reference.md#FW_THR_MAX). Якщо ви хочете керувати клапаном, який не контролює рух транспортного засобу, але, наприклад, сервопривід навантаження, подивіться нижче. ::: +#### Rover Setpoints + + + +The rover modules use a hierarchical structure to propagate setpoints: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +:::info +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (Overriding them!). +With this hierarchy there are clear rules for providing a valid control input: + +- Provide a position setpoint, **or** +- One of the setpoints on the "left" (speed **or** throttle) **and** one of the setpoints on the "right" (attitude, rate **or** steering). All combinations of "left" and "right" setpoints are valid. + +For ease of use we expose these valid combinations as new SetpointTypes. +::: + +The RoverSetpointTypes exposed through the control interface are combinations of these setpoints that lead to a valid control input: + +| SetpointType | Положення | Speed | Тяга | Attitude | Rate | Steering | Control Flags | +| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------ | +| [RoverPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverPositionSetpointType.html#details) | ✓ | (✓) | (✓) | (✓) | (✓) | (✓) | Position, Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedAttitudeSetpointType.html) | | ✓ | (✓) | ✓ | (✓) | (✓) | Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedRateSetpointType.html) | | ✓ | (✓) | | ✓ | (✓) | Velocity, Rate, Control Allocation | +| [RoverSpeedSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedSteeringSetpointType.html) | | ✓ | (✓) | | | ✓ | Velocity, Control Allocation | +| [RoverThrottleAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleAttitudeSetpointType.html) | | | ✓ | ✓ | (✓) | (✓) | Attitude, Rate, Control Allocation | +| [RoverThrottleRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleRateSetpointType.html) | | | ✓ | | ✓ | (✓) | Rate, Control Allocation | +| [RoverThrottleSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleSteeringSetpointType.html) | | | ✓ | | | ✓ | Control Allocation | + +✓ are the setpoints we publish, and (✓) are generated internally by the PX4 rover modules according to the hierarchy above. + +An example for a rover specific drive mode using the `RoverSpeedAttitudeSetpointType` is provided [here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/rover_velocity). + ### Controlling a VTOL - + To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: -- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`GotoSetpointType`](#go-to-setpoint-gotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). +- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`MulticopterGotoSetpointType`](#go-to-setpoint-multicoptergotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). - Fixed-wing mode: Use the [`FwLateralLongitudinalSetpointType`](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype). As long as the VTOL remains in either multicopter or fixed-wing mode throughout the external mode, no additional handling is required. @@ -569,24 +616,24 @@ Commanding transitions externally makes the user partially responsible for ensur 3. To command a transition, you can use the `toMulticopter()` or `toFixedwing()` methods on your VTOL object to set the desired state. 4. During transition, send the following combination of setpoints: - ```cpp - // Assuming the instance of the px4_ros2::VTOL object is called vtol + ```cpp + // Assuming the instance of the px4_ros2::VTOL object is called vtol - // Send TrajectorySetpointType as follows: - Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); - Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; + // Send TrajectorySetpointType as follows: + Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); + Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; - _trajectory_setpoint->update(velocity_sp, acceleration_sp); + _trajectory_setpoint->update(velocity_sp, acceleration_sp); - // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired + // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired - float course_sp = 0.F; // North + float course_sp = 0.F; // North - _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) - ``` + _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) + ``` - This will ensure that the transition is handled properly within PX4. - You can optionally pass a deceleration setpoint to `computeAccelerationSetpointDuringTransition()` to be used during back-transitions. + This will ensure that the transition is handled properly within PX4. + You can optionally pass a deceleration setpoint to `computeAccelerationSetpointDuringTransition()` to be used during back-transitions. To check the current state of the vehicle, use the `getCurrentState()` method on your `px4_ros2::VTOL` object. @@ -599,7 +646,7 @@ See [this external flight mode implementation](https://github.com/Auterion/px4-r 1. [Configure the output](../payloads/generic_actuator_control.md#generic-actuator-control-with-mavlink). 2. Створіть екземпляр px4_ros2::PeripheralActuatorControls у конструкторі вашого режиму. 3. Викличте метод set(), щоб керувати клапаном(-ами). - Це може бути зроблено незалежно від будь-яких активних встановлень. + Це може бути зроблено незалежно від будь-яких активних встановлень. ### Телеметрія diff --git a/docs/uk/ros2/px4_ros2_interface_lib.md b/docs/uk/ros2/px4_ros2_interface_lib.md index 1829bd5d64..821c9b554b 100644 --- a/docs/uk/ros2/px4_ros2_interface_lib.md +++ b/docs/uk/ros2/px4_ros2_interface_lib.md @@ -7,17 +7,14 @@ На момент написання цієї статті, деякі частини бібліотеки інтерфейсу PX4 ROS 2 є експериментальними і, отже, можуть бути змінені. ::: -[PX4 ROS 2 Інтерфейс бібліотеки](https://github.com/Auterion/px4-ros2-interface-lib) є бібліотекою C+++, яка спрощує контроль і взаємодіє з PX4 з ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. -Бібліотека надає два інтерфейси високого рівня для розробників: +The library provides three high-level interfaces for developers: 1. [Control Interface](./px4_ros2_interface.md) дозволяє розробникам створювати та динамічно реєструвати режими, написані з використанням ROS 2. Бібліотека також надає класи для надсилання різних типів налаштувань, починаючи від багаторівневих навігаційних завдань на високому рівні аж до прямого контролю приводу. 2. [Навігаційний інтерфейс](./px4_ros2_navigation_interface.md) дозволяє надсилати позицію автомобіля з позиції PX4 з ROS 2 додатків, таких як система VIO. - - +3. [Waypoint Missions](./px4_ros2_waypoint_missions.md) allows waypoint missions to run entirely in ROS 2. ## Встановлення в робочому просторі ROS 2 diff --git a/docs/uk/ros2/px4_ros2_msg_translation_node.md b/docs/uk/ros2/px4_ros2_msg_translation_node.md index 7ad1c15295..5407586db8 100644 --- a/docs/uk/ros2/px4_ros2_msg_translation_node.md +++ b/docs/uk/ros2/px4_ros2_msg_translation_node.md @@ -27,36 +27,36 @@ The following steps describe how to install and run the translation node on your 1. (Optional) Create a new ROS 2 workspace in which to build the message translation node and its dependencies: - ```sh - mkdir -p /path/to/ros_ws/src - ``` + ```sh + mkdir -p /path/to/ros_ws/src + ``` 2. Run the following helper script to copy the message definitions and translation node into your ROS workspace directory. - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` 3. Build and source the workspace. - ```sh - colcon build - source /path/to/ros_ws/install/setup.bash - ``` + ```sh + colcon build + source /path/to/ros_ws/install/setup.bash + ``` 4. Finally, run the translation node. - ```sh - ros2 run translation_node translation_node_bin - ``` + ```sh + ros2 run translation_node translation_node_bin + ``` - You should see an output similar to: + You should see an output similar to: - ```sh - [INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: - [INFO] [1734525720.729594413] [translation_node]: Registered services and versions: - ``` + ```sh + [INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: + [INFO] [1734525720.729594413] [translation_node]: Registered services and versions: + ``` With the translation node running, any simultaneously running ROS 2 application designed to communicate with PX4 can do so, as long as it uses message versions recognized by the node. The translation node will print a warning if it encounters an unknown topic version. @@ -295,111 +295,111 @@ The example describes the process of updating the `VehicleAttitude` message defi 1. **Create an Archived Definition of the Current Versioned Message** - Copy the versioned `.msg` topic message file (or `.srv` service message file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`), and append its message version to the file name. + Copy the versioned `.msg` topic message file (or `.srv` service message file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`), and append its message version to the file name. - For example:
- Copy `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` + For example:
+ Copy `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` 2. **Update Translation References to the Archived Definition** - Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. + Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. - For example, update references in those files:
+ For example, update references in those files:
- - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` - - Replace `#include ` → `#include ` + - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` + - Replace `#include ` → `#include ` 3. **Update the Versioned Definition** - Update the versioned `.msg` topic message file (or `.srv` service message file) with required changes. + Update the versioned `.msg` topic message file (or `.srv` service message file) with required changes. - First increment the `MESSAGE_VERSION` field. - Then update the message fields that prompted the version change. + First increment the `MESSAGE_VERSION` field. + Then update the message fields that prompted the version change. - For example, update `msg/versioned/VehicleAttitude.msg` from: + For example, update `msg/versioned/VehicleAttitude.msg` from: - ```txt - uint32 MESSAGE_VERSION = 3 - uint64 timestamp - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 3 + uint64 timestamp + ... + ``` - to + to - ```txt - uint32 MESSAGE_VERSION = 4 # Increment - uint64 timestamp - float32 new_field # Make definition changes - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 4 # Increment + uint64 timestamp + float32 new_field # Make definition changes + ... + ``` 4. **Add a New Translation Header** - Add a new version translation to bridge the archived version and the updated current version, by creating a new translation header. + Add a new version translation to bridge the archived version and the updated current version, by creating a new translation header. - For example, create a direct translation header `translation_node/translations/translation_vehicle_attitude_v4.h`: + For example, create a direct translation header `translation_node/translations/translation_vehicle_attitude_v4.h`: - ```c++ - // Translate VehicleAttitude v3 <--> v4 - #include - #include + ```c++ + // Translate VehicleAttitude v3 <--> v4 + #include + #include - class VehicleAttitudeV4Translation { - public: - using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; - static_assert(MessageOlder::MESSAGE_VERSION == 3); + class VehicleAttitudeV4Translation { + public: + using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; + static_assert(MessageOlder::MESSAGE_VERSION == 3); - using MessageNewer = px4_msgs::msg::VehicleAttitude; - static_assert(MessageNewer::MESSAGE_VERSION == 4); + using MessageNewer = px4_msgs::msg::VehicleAttitude; + static_assert(MessageNewer::MESSAGE_VERSION == 4); - static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; + static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; - static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { - msg_newer.timestamp = msg_older.timestamp; - msg_newer.timestamp_sample = msg_older.timestamp_sample; - msg_newer.q[0] = msg_older.q[0]; - msg_newer.q[1] = msg_older.q[1]; - msg_newer.q[2] = msg_older.q[2]; - msg_newer.q[3] = msg_older.q[3]; - msg_newer.delta_q_reset = msg_older.delta_q_reset; - msg_newer.quat_reset_counter = msg_older.quat_reset_counter; + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.timestamp_sample = msg_older.timestamp_sample; + msg_newer.q[0] = msg_older.q[0]; + msg_newer.q[1] = msg_older.q[1]; + msg_newer.q[2] = msg_older.q[2]; + msg_newer.q[3] = msg_older.q[3]; + msg_newer.delta_q_reset = msg_older.delta_q_reset; + msg_newer.quat_reset_counter = msg_older.quat_reset_counter; - // Populate `new_field` with some value - msg_newer.new_field = -1; - } + // Populate `new_field` with some value + msg_newer.new_field = -1; + } - static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { - msg_older.timestamp = msg_newer.timestamp; - msg_older.timestamp_sample = msg_newer.timestamp_sample; - msg_older.q[0] = msg_newer.q[0]; - msg_older.q[1] = msg_newer.q[1]; - msg_older.q[2] = msg_newer.q[2]; - msg_older.q[3] = msg_newer.q[3]; - msg_older.delta_q_reset = msg_newer.delta_q_reset; - msg_older.quat_reset_counter = msg_newer.quat_reset_counter; + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.timestamp_sample = msg_newer.timestamp_sample; + msg_older.q[0] = msg_newer.q[0]; + msg_older.q[1] = msg_newer.q[1]; + msg_older.q[2] = msg_newer.q[2]; + msg_older.q[3] = msg_newer.q[3]; + msg_older.delta_q_reset = msg_newer.delta_q_reset; + msg_older.quat_reset_counter = msg_newer.quat_reset_counter; - // Discards `new_field` from MessageNewer - } - }; + // Discards `new_field` from MessageNewer + } + }; - REGISTER_TOPIC_TRANSLATION_DIRECT(VehicleAttitudeV4Translation); - ``` + REGISTER_TOPIC_TRANSLATION_DIRECT(VehicleAttitudeV4Translation); + ``` - Version translation templates are provided here: + Version translation templates are provided here: - - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) - - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) - - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) + - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) + - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) + - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) 5. **Include New Headers in `all_translations.h`** - Add all newly created headers to [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h) so that the translation node can find them. + Add all newly created headers to [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h) so that the translation node can find them. - For example, append the following line to `all_translation.h`: + For example, append the following line to `all_translation.h`: - ```c++ - #include "translation_vehicle_attitude_v4.h" - ``` + ```c++ + #include "translation_vehicle_attitude_v4.h" + ``` Note that in the example above and in most cases, step 4 only requires the developer to create a direct translation for the definition change. This is because the changes only involved a single message. diff --git a/docs/uk/ros2/px4_ros2_navigation_interface.md b/docs/uk/ros2/px4_ros2_navigation_interface.md index 003cf8c43a..a946973966 100644 --- a/docs/uk/ros2/px4_ros2_navigation_interface.md +++ b/docs/uk/ros2/px4_ros2_navigation_interface.md @@ -22,80 +22,80 @@ 2. Клонуйте репозиторій в робочий простір: - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - :::info - Для забезпечення сумісності, використовуйте останні _main_ гілки для PX4, _px4_msgs_ та бібліотеки. - Дивіться також [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + :::info + Для забезпечення сумісності, використовуйте останні _main_ гілки для PX4, _px4_msgs_ та бібліотеки. + Дивіться також [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). ::: 3. Побудуйте робочий простір: - ```sh - cd .. - colcon build - ``` + ```sh + cd .. + colcon build + ``` 4. У іншій оболонці запустіть PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (тут ми використовуємо Gazebo-Classic, але ви можете використовувати будь-яку модель або симулятор) + (тут ми використовуємо Gazebo-Classic, але ви можете використовувати будь-яку модель або симулятор) 5. У іншій оболонці запустіть агента micro XRCE (ви можете залишити його запущеним після цього): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 6. Поверніться до терміналу ROS 2, створіть робочу область, яку ви щойно створили (у кроці 3), і запустіть приклад [global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation/global_navigation), який періодично надсилає фіктивні оновлення глобальної позиції: - ```sh - source install/setup.bash - ros2 run example_global_navigation_cpp example_global_navigation - ``` + ```sh + source install/setup.bash + ros2 run example_global_navigation_cpp example_global_navigation + ``` - Ви повинні отримати вивід, подібний до цього, що показує, що глобальний інтерфейс успішно надсилає оновлення позиції: + Ви повинні отримати вивід, подібний до цього, що показує, що глобальний інтерфейс успішно надсилає оновлення позиції: - ```sh - [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! - [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. - [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. - ``` + ```sh + [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! + [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. + [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. + ``` 7. У PX4 оболонці можна перевірити, що PX4 отримує глобальні оновлення позиції: - ```sh - listener aux_global_position - ``` + ```sh + listener aux_global_position + ``` - Вихід має містити: + Вихід має містити: - ```sh - TOPIC: aux_global_position - aux_global_position - timestamp: 46916000 (0.528000 seconds ago) - timestamp_sample: 46916000 (0 us before timestamp) - lat: 12.343210 - lon: 23.454320 - alt: 12.40000 - alt_ellipsoid: 0.00000 - delta_alt: 0.00000 - eph: 0.31623 - epv: 0.44721 - terrain_alt: 0.00000 - lat_lon_reset_counter: 0 - alt_reset_counter: 0 - terrain_alt_valid: False - dead_reckoning: False - ``` + ```sh + TOPIC: aux_global_position + aux_global_position + timestamp: 46916000 (0.528000 seconds ago) + timestamp_sample: 46916000 (0 us before timestamp) + lat: 12.343210 + lon: 23.454320 + alt: 12.40000 + alt_ellipsoid: 0.00000 + delta_alt: 0.00000 + eph: 0.31623 + epv: 0.44721 + terrain_alt: 0.00000 + lat_lon_reset_counter: 0 + alt_reset_counter: 0 + terrain_alt_valid: False + dead_reckoning: False + ``` 8. Тепер ви готові використовувати навігаційний інтерфейс для надсилання своїх оновлень. diff --git a/docs/uk/ros2/px4_ros2_waypoint_missions.md b/docs/uk/ros2/px4_ros2_waypoint_missions.md new file mode 100644 index 0000000000..c6d6f7caff --- /dev/null +++ b/docs/uk/ros2/px4_ros2_waypoint_missions.md @@ -0,0 +1,190 @@ +# PX4 ROS 2 Waypoint Missions + + + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) provides a high-level interface for executing ROS-based waypoint missions in ROS 2. +The main use-case is for creating missions where a custom behavior is required, such as a pickup action within a mission. + +:::warning +ROS 2 missions are not compatible with MAVLink mission definitions, plan files, or ground stations. +They completely bypass the existing PX4 mission mode and waypoint logic, and cannot be planned or displayed within a ground station. +::: + +ROS 2 waypoint missions are effectively special PX4 ROS 2 custom modes that are run based on the content of a [JSON mission definition](#mission-definition). +Mission definitions can contain actions that reference existing PX4 modes, such as Takeoff mode or RTL, and can also be extended with arbitrary custom actions written in ROS. +A [mode executor](px4_ros2_control_interface.md#mode-executor) is used to schedule the modes. + +Mission definitions can be hard coded in the custom mission mode (either in code or statically loaded from a JSON string), or directly generated within the application. +They can also be dynamically loaded based on modification of a particular JSON file — this allows for building a more generic mission framework with a fixed set of custom actions. +The file can then be written by any other application, for example a HTTP or MAVFTP server. + +The current implementation only supports multicopters but is designed to be extendable to any other vehicle type. + +## Comparison to PX4/MAVLink Missions + +There are some benefits and drawbacks to using ROS-based missions, which are provided in the following paragraphs. + +### Переваги + +- Allows to extend mission capabilities by registering custom actions. +- More control over how the mission is executed. + A custom trajectory executor can be implemented, which can use any of the existing PX4 setpoint types to track the trajectory. +- Reduced complexity on the flight controller side by running non-safety-critical and non-real-time code on a more high-level companion computer. +- It can be extended to support other trajectory types, like Bezier or Dubin curves. + +### Drawbacks + +- QGroundControl currently does not display the mission or progress during execution, and cannot upload or download a mission. + Therefore you will need another mechanism to provide a mission, such as from a web server, a custom GCS, or by generating it directly inside the application. +- The current implementation only supports multicopters (it uses the [GotoSetpointType](../ros2/px4_ros2_control_interface.md#go-to-setpoint-multicoptergotosetpointtype), which only works for multicopters, and VTOL in MC mode). + It is designed to be extendable to any other vehicle type. + +## Загальний огляд + +This diagram provides a conceptual overview of the main classes and their interactions: + +![Waypoint missions overview diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg) + + + +Missions can be defined in [JSON](#mission-definition), either as a file, or directly inside the application. +There is a file change monitor (`MissionFileMonitor`), that can be used to automatically load a mission from a specific file whenever it is created by another application (e.g. upload via MAVFTP or a cloud service). + +The **`MissionExecutor`** class contains the state machine to progress the mission index, and is at the core of the implementation: + +- Internally, it builds on top of the [Modes and Mode Executors](px4_ros2_control_interface.md#overview) and registers itself through a custom mode and executor with PX4. +- It handles switching in and out of missions: it gets activated when the user switches to the custom mode that represents the mission and the vehicle is armed. + The mode name can be customized (`My Mission` in the example below). + The mission can be paused, which makes the vehicle switch into _Hold mode_. + To resume the mission, the custom mode has to be selected again. +- When an action switches into another mode (for example Takeoff), QGroundControl will display this mode until it is completed. + The mission executor will then automatically continue. +- Custom actions can be registered. +- The mission can be set. + It then checks that all the actions which the mission defines are available and can be run. +- The state can be stored persistently by providing a file name, allowing for battery swapping. + +The **`ActionInterface`** is an interface class for custom actions. +They are identified by a name, and any number of these can be registered with the `MissionExecutor`. +A custom action is then run whenever a mission item with matching name is executed, and any extra arguments from the JSON definition are passed as arguments (for example an altitude for a takeoff action). +Actions can call other actions, run any mode (PX4 or external by its ID), run a trajectory, or run any other external action before deciding when to continue the mission. + +There is a set of default actions, for example for RTL, Land, etc. +These simply trigger the corresponding PX4 mode. +They can be disabled or replaced with custom implementations. +There are also some special actions (which can be replaced as well): + +- `OnFailure`: this is called in case of a failure, e.g. a mode switch failed, a non-existing action is called (by another action) or by an explicit call to `MissionExecutor::abort()`. + The default is to run RTL, with fallback to Land. +- `OnResume`: this is called when resuming a mission (either from the ground or in-air). + It handles a number of cases: + - when called with an argument `action="storeState"`: this can be used to store the current position when the mission is deactivated, so it can be resumed from the same position. + Currently it does not store anything. + - otherwise, when called without a valid mission index or 0, it directly continues. + - otherwise, when called while in-air, it also directly continues. + - otherwise, if landed and if the current mission item is an action that supports resuming from landed, it continues to let the action handle the resuming. + - otherwise, if landed, it finds the takeoff action from the mission, runs it, and then flies to the previous waypoint from the current index to continue the mission. +- `ChangeSettings`: this can be used to change the mission settings, such as the velocity. + The settings are applied to all following items in the mission. + +The **`TrajectoryExecutorInterface`** is an interface class to execute segments of a trajectory. +It can use any setpoint that PX4 and the current vehicle supports for tracking the trajectory. +This class is vehicle-type specific. +The current default implementation (`multicopter::WaypointTrajectoryExecutor`) uses a Goto setpoint (and thus is limited to multicopters). +The default can be replaced with a custom implementation. + +## Використання + +The following provides a small example. +It defines a custom action and a mission that uses it. + +```c++ +class CustomAction : public px4_ros2::ActionInterface { +public: + CustomAction(px4_ros2::ModeBase & mode) : _node(mode.node()) { } + + std::string name() const override {return "customAction";} + + void run( + const std::shared_ptr & handler, + const px4_ros2::ActionArguments & arguments, + const std::function & on_completed) override + { + RCLCPP_INFO(_node.get_logger(), "Running custom action"); + // Do something... + + on_completed(); + } +private: + rclcpp::Node & _node; +}; + +class MyMission { +public: + MyMission(const std::shared_ptr & node) : _node(node) + { + const auto mission = px4_ros2::Mission(nlohmann::json::parse(R"( + { + "version": 1, + "mission": { + "items": [ + { + "type": "takeoff" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.3977419, + "y": 8.5455939, + "z": 500, + "frame": "global" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.39791657, + "y": 8.54595214, + "z": 500, + "frame": "global" + }, + { + "type": "customAction" + }, + { + "type": "rtl" + } + ] + } + } +)")); + _mission_executor = std::make_unique("My Mission", + px4_ros2::MissionExecutor::Configuration().addCustomAction(), *node); + + if (!_mission_executor->doRegister()) { + throw std::runtime_error("Failed to register mission executor"); + } + _mission_executor->setMission(mission); + + _mission_executor->onProgressUpdate([&](int current_index) { + RCLCPP_INFO(_node->get_logger(), "Current mission index: %i", current_index); + }); + _mission_executor->onCompleted([&] { + RCLCPP_INFO(_node->get_logger(), "Mission completed callback"); + }); + } + +private: + std::shared_ptr _node; + std::unique_ptr _mission_executor; +}; +``` + +A full example with a few custom actions can be found under [github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include). + +## Mission Definition + +The mission JSON file can contain mission defaults and a list of mission items, including user-defined types with custom arguments. +Waypoint coordinates currently need to be defined in global frame, and other frame types might be added in future. + +The schema can be found under [github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml). +It provides more details and can be used to validate a JSON file. diff --git a/docs/uk/ros2/user_guide.md b/docs/uk/ros2/user_guide.md index 47683eb4ec..2f5ff0d4c0 100644 --- a/docs/uk/ros2/user_guide.md +++ b/docs/uk/ros2/user_guide.md @@ -97,48 +97,48 @@ To install ROS 2 and its dependencies: 1. Встановлення ROS 2. - :::: tabs + :::: tabs - ::: tab humble - To install ROS 2 "Humble" on Ubuntu 22.04: + ::: tab humble + To install ROS 2 "Humble" on Ubuntu 22.04: - ```sh - sudo apt update && sudo apt install locales - sudo locale-gen en_US en_US.UTF-8 - sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 - export LANG=en_US.UTF-8 - sudo apt install software-properties-common - sudo add-apt-repository universe - sudo apt update && sudo apt install curl -y - sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null - sudo apt update && sudo apt upgrade -y - sudo apt install ros-humble-desktop - sudo apt install ros-dev-tools - source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc - ``` + ```sh + sudo apt update && sudo apt install locales + sudo locale-gen en_US en_US.UTF-8 + sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + export LANG=en_US.UTF-8 + sudo apt install software-properties-common + sudo add-apt-repository universe + sudo apt update && sudo apt install curl -y + sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null + sudo apt update && sudo apt upgrade -y + sudo apt install ros-humble-desktop + sudo apt install ros-dev-tools + source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc + ``` - The instructions above are reproduced from the official installation guide: [Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). + The instructions above are reproduced from the official installation guide: [Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). + You can install _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - ::: tab foxy - To install ROS 2 "Foxy" on Ubuntu 20.04: + ::: tab foxy + To install ROS 2 "Foxy" on Ubuntu 20.04: - - Follow the official installation guide: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). + - Follow the official installation guide: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). + You can install _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - :::: + :::: 2. Some Python dependencies must also be installed (using **`pip`** or **`apt`**): - ```sh - pip install --user -U empy==3.3.4 pyros-genmsg setuptools - ``` + ```sh + pip install --user -U empy==3.3.4 pyros-genmsg setuptools + ``` ### Setup Micro XRCE-DDS Agent & Client @@ -155,22 +155,22 @@ To setup and start the agent: 2. Введіть наступні команди для витягування та побудови агента з вихідного коду: - ```sh - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` 3. Запустіть агента з налаштуваннями для підключення до клієнта uXRCE-DDS, який працює на симуляторі: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` The agent is now running, but you won't see much until we start PX4 (in the next step). @@ -187,31 +187,31 @@ To start the simulator (and client): 1. Open a new terminal in the root of the **PX4 Autopilot** repo that was installed above. - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - - Start a PX4 [Gazebo](../sim_gazebo_gz/index.md) simulation using: + - Start a PX4 [Gazebo](../sim_gazebo_gz/index.md) simulation using: - ```sh - make px4_sitl gz_x500 - ``` + ```sh + make px4_sitl gz_x500 + ``` ::: - ::: tab foxy + ::: tab foxy - - Start a PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) simulation using: + - Start a PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) simulation using: - ```sh - make px4_sitl gazebo-classic - ``` + ```sh + make px4_sitl gazebo-classic + ``` ::: - :::: + :::: The agent and client are now running they should connect. @@ -261,52 +261,52 @@ To create and build the workspace: 2. Створіть новий каталог робочого простору та перейдіть до нього за допомогою: - ```sh - mkdir -p ~/ws_sensor_combined/src/ - cd ~/ws_sensor_combined/src/ - ``` + ```sh + mkdir -p ~/ws_sensor_combined/src/ + cd ~/ws_sensor_combined/src/ + ``` - ::: info - A naming convention for workspace folders can make it easier to manage workspaces. + ::: info + A naming convention for workspace folders can make it easier to manage workspaces. ::: 3. Clone the example repository and [px4_msgs](https://github.com/PX4/px4_msgs) to the `/src` directory (the `main` branch is cloned by default, which corresponds to the version of PX4 we are running): - ```sh - git clone https://github.com/PX4/px4_msgs.git - git clone https://github.com/PX4/px4_ros_com.git - ``` + ```sh + git clone https://github.com/PX4/px4_msgs.git + git clone https://github.com/PX4/px4_ros_com.git + ``` 4. Source the ROS 2 development environment into the current terminal and compile the workspace using `colcon`: - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd .. - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd .. - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/foxy/setup.bash + colcon build + ``` ::: - :::: + :::: - This builds all the folders under `/src` using the sourced toolchain. + This builds all the folders under `/src` using the sourced toolchain. #### Запуск прикладу @@ -322,42 +322,42 @@ In a new terminal: 1. Перейдіть на верхній рівень каталогу вашого робочого простору та джерело середовища ROS 2 (у цьому випадку "Humble"): - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/humble/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/humble/setup.bash + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/foxy/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/foxy/setup.bash + ``` ::: - :::: + :::: 2. Source the `local_setup.bash`. - ```sh - source install/local_setup.bash - ``` + ```sh + source install/local_setup.bash + ``` 3. Тепер запустіть приклад. - Note here that we use `ros2 launch`, which is described below. + Note here that we use `ros2 launch`, which is described below. - ```sh - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` If this is working you should see data being printed on the terminal/console where you launched the ROS listener: @@ -385,18 +385,18 @@ If you were to use incompatible [message versions](../middleware/uorb.md#message 1. Include the [Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) into the example workspace or a separate workspace by running the following script: - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` 2. Build and run the translation node: - ```sh - colcon build - source install/local_setup.bash - ros2 run translation_node translation_node_bin - ``` + ```sh + colcon build + source install/local_setup.bash + ros2 run translation_node translation_node_bin + ``` ## Керування Транспортним Засобом diff --git a/docs/uk/sensor/accelerometer.md b/docs/uk/sensor/accelerometer.md index 285e121abd..92c15ba7c8 100644 --- a/docs/uk/sensor/accelerometer.md +++ b/docs/uk/sensor/accelerometer.md @@ -5,7 +5,7 @@ PX4 використовує дані акселерометра для оцін Вам не потрібно прикріплювати акселерометр як окремий зовнішній пристрій: - Більшість польотних контролерів, таких, як в [Pixhawk Series](/flight_controller/pixhawk_series.md), включають в себе акселерометр як частину польот контролеру [Inertial Motion (IMU)](https://en.wikipedia.org/wiki/Inertial_measurement_unit). -- Гіроскопи присутні як частина зовнішньої системи інерціальної навігації, ARHS або системи підвищеної точності глобальної навігації INS (../sensor/inertial_navigation_systems.md). +- Gyroscopes are present as part of an [external INS, AHRS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). Потрібно відкалібрувати акселерометр перед першим використанням безпілотника: diff --git a/docs/uk/sensor/barometer.md b/docs/uk/sensor/barometer.md index 20ad975355..93f7563901 100644 --- a/docs/uk/sensor/barometer.md +++ b/docs/uk/sensor/barometer.md @@ -30,17 +30,51 @@ Note that the supported barometer part numbers can be inferred from the driver n - Change the selection order of barometers using the [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) parameters for each barometer. - Disable a barometer by setting its [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) value to `0`. -## Калібрування +## Baro Auto-Calibration (Developers) -Барометри не потребують калібрування. +:::tip +This section documents the automated calibration mechanisms that ensure accurate altitude measurements throughout flight operations. +It is intended primarily for a developer audience who want to understand the underlying mechanisms. +::: - +The system implements two complementary calibration approaches that work together to maintain altitude measurement precision. +Both calibrations are initiated at the beginning after a system boot. +Relative calibration is performed first, followed by GNSS-barometric calibration. -## Інформація для розробників +### Relative Calibration + +Relative baro calibration is **always enabled** and operates automatically during system initialization. +This calibration establishes offset corrections for all secondary baro sensors relative to the primary (selected) sensor. + +This calibration: + +- Eliminates altitude jumps when switching between baro sensors during flight. +- Ensures consistent altitude readings across all available baro sensors. +- Maintains seamless sensor redundancy and failover capability. + +### GNSS-Baro Calibration + +:::info +GNSS-baro calibration requires an operational GNSS receiver with vertical accuracy (EPV) ≤ 8 meters. +Relative calibration must already have completed. +::: + +GNSS-baro calibration adjusts baro sensor offsets to align with absolute altitude measurements from the GNSS receiver. +This calibration is controlled by the [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) parameter (enabled by default). + +The algorithm monitors GNSS quality, collects altitude differences over a 2-second filtered window, and verifies stability within 4m tolerance. +Once stable, it uses binary search to calculate pressure offsets that align baro altitude with GNSS altitude (0.1m precision), then applies the offset to all sensors and saves the parameters. + +Примітки: + +- **EKF Independence**: GNSS-baro calibration operates independently of EKF2 altitude fusion settings. +- **Execution Timing**: Calibration runs even when [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) altitude fusion is disabled. +- **One-Time Process**: Each calibration session completes once per system startup. +- **Persistence**: Calibration offsets are saved to parameters and persist across reboots. +- **Faulty GNSS Vulnerability**: If GNSS data is faulty during boot, the calibration will use incorrect altitude reference. + See [Faulty GNSS Data During Boot](../advanced_config/tuning_the_ecl_ekf.md#faulty-gnss-data-during-boot) for mitigation strategies. + +## Дивіться також - [Baro driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer) - [Modules Reference: Baro (Driver)](../modules/modules_driver_baro.md) documentation. diff --git a/docs/uk/sensor/inertial_navigation_systems.md b/docs/uk/sensor/inertial_navigation_systems.md index 4703c5ab10..6dd786584c 100644 --- a/docs/uk/sensor/inertial_navigation_systems.md +++ b/docs/uk/sensor/inertial_navigation_systems.md @@ -2,13 +2,34 @@ PX4 зазвичай працює на контролерах польоту, які включають в себе ІВП, такі як серія Pixhawk, і об'єднує дані датчиків разом із інформацією ССН (супутникова система навігації) в оцінювачі EKF2 для визначення орієнтації, напрямку, позиції та швидкості транспортного засобу. -However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing the EKF. +However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing EKF2. -Системи, які можуть бути використані у такий спосіб, включають в себе: +## Supported INS Systems + +INS systems that can be used as a replacement for EKF2 in PX4: - [InertialLabs](../sensor/inertiallabs.md) +- [MicroStrain](../sensor/microstrain.md): Includes VRU, AHRS, INS, and GNSS/INS devices. +- [SBG Systems](../sensor/sbgecom.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. - [VectorNav](../sensor/vectornav.md): ІВП/AHRS, ССН/INS, Dual GNSS/INS системи, котрі можуть бути використані як зовнішній INS, або джерело вхідної інформації датчиків. +## PX4 Firmware + +The driver module for your INS system may not be included in the PX4 firmware for your flight controller by default. + +You can check by searching the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6c/default.px4board#L25) configuration file for your target board for either: + +- `CONFIG_COMMON_INS`, which includes drivers for [all INS systems](https://github.com/PX4/PX4-Autopilot/blob/main/src/drivers/ins/Kconfig). +- The key for the particular INS system you are using, such as: + - `CONFIG_DRIVERS_INS_ILABS` + - `CONFIG_DRIVERS_INS_MICROSTRAIN` + - `CONFIG_DRIVERS_INS_VECTORNAV` + +If the required key is not present you can include the module in firmware by adding the key to the `default.px4board` file, or using the [kconfig board configuration tool](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) and then select the driver you want (`Drivers -> INS`). +Note that if you're working on a flight controller where flash memory is limited, you're better off installing just the modules you need. + +You will then need to rebuild the firmware. + ## Словник ### Інерційний вимірювальний пристрій (ІВП) diff --git a/docs/uk/sensor/inertiallabs.md b/docs/uk/sensor/inertiallabs.md index d5dcdd0b53..e7e3c6e4b3 100644 --- a/docs/uk/sensor/inertiallabs.md +++ b/docs/uk/sensor/inertiallabs.md @@ -57,11 +57,11 @@ To use the Inertial Labs driver: - For external INS, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `INS`. - For raw inertial sensors, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `Sensors Only`. - You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). + You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). - ::: tip - In most cases the external IMU is the highest-numbered. - Ви можете отримати список доступних компонентів IMU, використовуючи [`uorb top -1`](../middleware/uorb.md#uorb-top-command), ви можете відрізняти їх за допомогою команди [`listener`](../modules/modules_command.md#listener) та розглядаючи дані чи просто швидкості. + ::: tip + In most cases the external IMU is the highest-numbered. + Ви можете отримати список доступних компонентів IMU, використовуючи [`uorb top -1`](../middleware/uorb.md#uorb-top-command), ви можете відрізняти їх за допомогою команди [`listener`](../modules/modules_command.md#listener) та розглядаючи дані чи просто швидкості. ::: diff --git a/docs/uk/sensor/microstrain.md b/docs/uk/sensor/microstrain.md new file mode 100644 index 0000000000..6a78dc6895 --- /dev/null +++ b/docs/uk/sensor/microstrain.md @@ -0,0 +1,219 @@ +# MicroStrain (INS, IMU, VRU, AHRS) + +MicroStrain by HBK provides high-performance inertial sensors engineered for reliability and precision in challenging environments. +Widely used across industries like aerospace, robotics, industrial automation, and research, MicroStrain sensors are optimized for real-time, accurate motion tracking and orientation data. + +![CV7](../../assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png) + +The driver currently supports the following hardware: + +- [`MicroStrain CV7-AR`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/vertical-reference-units--vru-/3dm-cv7-ar): Inertial Measurement Unit (IMU) and Vertical Reference Unit (VRU) +- [`MicroStrain CV7-AHRS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/attitude-and-heading-reference-systems--ahrs-/3dm-cv7-ahrs): Inertial Measurement Unit (IMU) and Attitude Heading Reference System (AHRS) +- [`MicroStrain CV7-INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS). +- [`MicroStrain CV7-GNSS/INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-gnss-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS) combined with dual multiband (GNSS) receivers. + +PX4 can use these sensors to provide raw IMU data for EKF2 or to replace EKF2 as an external INS. +For more information, including user manuals and datasheets, please refer to the sensors product page. + +## Де купити + +MicroStrain sensors can be purchased through HBK's official [MicroStrain product page](https://www.hbkworld.com/en/products/transducers/inertial-sensors) or through authorized distributors globally. +For large orders, custom requirements, or technical inquiries, reach out directly to [sales](https://www.hbkworld.com/en/contact-us/contact-sales-microstrain) + +## Налаштування програмного забезпечення + +### Підключення + +Connect the main UART port of the MicroStrain sensor to any unused serial port on the flight controller. +This port needs to be specified while starting the device. + +### Встановлення + +The MicroStrain sensor can be mounted in any orientation. +The default coordinate system uses X for the front, Y for the right, and Z for down, with directions marked on the device. + +## Конфігурація прошивки + +### Конфігурація PX4 + +To use the MicroStrain driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_MICROSTRAIN` or `CONFIG_COMMON_INS`. + +2. Configure the driver mode by setting [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) + + - To use the MicroStrain sensor to provide raw IMU data to EKF2 + + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 0 + 2. Update the [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) parameter to account for the added MicroStrain sensor. + 3. Enable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 1 + 4. To prioritize MicroStrain sensor output, adjust the priority level of individual sensors from 0-100 using the following parameters: + + - [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO) + - [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO) + - [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO) + - [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) + + where `n` corresponds to the index of the corresponding sensor. + + ::: tip + Sensors can be identified by their device id, which can be found by checking the parameters: + + - [CAL_ACCn_ID](../advanced_config/parameter_reference.md#CAL_ACC0_ID) + - [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) + - [CAL_MAGn_ID](../advanced_config/parameter_reference.md#CAL_MAG0_ID) + - [CAL_BAROn_ID](../advanced_config/parameter_reference.md#CAL_BARO0_ID) + + +::: + + - To use the MicroStrain sensor as an external INS + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 1 + 2. Disable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 0 + +3. Reboot and start the driver + - `microstrain start -d ` + - To start the driver automatically when the flight controller powers on, set [SENS_MS_CFG](../advanced_config/parameter_reference.md#SENS_MS_CFG) to the sensor’s connected port. + +## MicroStrain Configuration + +1. Rates: + + - By default, accel and gyro data are published at 500 Hz, magnetometer at 50 Hz, and barometric pressure at 50 Hz. + This can be changed by adjusting the following parameters: + + - [MS_IMU_RATE_HZ](../advanced_config/parameter_reference.md#MS_IMU_RATE_HZ) + - [MS_MAG_RATE_HZ](../advanced_config/parameter_reference.md#MS_MAG_RATE_HZ) + - [MS_BARO_RATE_HZ](../advanced_config/parameter_reference.md#MS_BARO_RATE_HZ) + + - Global position, local position, attitude and odometry will be published at 250 Hz by default. + This can be configured via: + + - [MS_FILT_RATE_HZ](../advanced_config/parameter_reference.md#MS_FILT_RATE_HZ) + + - For the CV7-GNSS/INS, the GNSS receiver 1 and 2 will publish data at 5Hz by default. + This can be changed using: + + - [MS_GNSS_RATE_HZ](../advanced_config/parameter_reference.md#MS_GNSS_RATE_HZ) + + - The driver will automatically configure data outputs based on the specific sensor model and available data streams. + + - The driver is scheduled to run at twice the fastest configured data rate. + +2. Aiding measurements: + + - If supported, GNSS position and velocity aiding are always enabled. + + - Internal/external magnetometer and heading aiding, as well as optical flow aiding, are disabled by default. They can be enabled using the following parameters: + + - [MS_INT_MAG_EN](../advanced_config/parameter_reference.md#MS_INT_MAG_EN) + - [MS_INT_HEAD_EN](../advanced_config/parameter_reference.md#MS_INT_HEAD_EN) + - [MS_EXT_HEAD_EN](../advanced_config/parameter_reference.md#MS_EXT_HEAD_EN) + - [MS_EXT_MAG_EN](../advanced_config/parameter_reference.md#MS_EXT_MAG_EN) + - [MS_OPT_FLOW_EN](../advanced_config/parameter_reference.md#MS_OPT_FLOW_EN) + + - The aiding frames for external sources can be configured using the following parameters: + + - [MS_EHEAD_YAW](../advanced_config/parameter_reference.md#MS_EHEAD_YAW) + - [MS_EMAG_ROLL](../advanced_config/parameter_reference.md#MS_EMAG_ROLL) + - [MS_EMAG_PTCH](../advanced_config/parameter_reference.md#MS_EMAG_PTCH) + - [MS_EMAG_YAW](../advanced_config/parameter_reference.md#MS_EMAG_YAW) + - [MS_OFLW_OFF_X](../advanced_config/parameter_reference.md#MS_OFLW_OFF_X) + - [MS_OFLW_OFF_Y](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Y) + - [MS_OFLW_OFF_Z](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Z) + - [SENS_FLOW_ROT](../advanced_config/parameter_reference.md#SENS_FLOW_ROT) + + - The uncertainty for optical flow and external magnetometer aiding must be specified using the following parameters: + + - [MS_EMAG_UNCERT](../advanced_config/parameter_reference.md#MS_EMAG_UNCERT) + - [MS_OFLW_UNCERT](../advanced_config/parameter_reference.md#MS_OFLW_UNCERT) + + ::: tip + + 1. When optical flow aiding is enabled, the sensor uses the `vehicle_optical_flow_vel` output from the flight controller as a body-frame velocity aiding measurement. + 2. If the MicroStrain sensor does not support these aiding sources but they are enabled, sensor initialization will fail. + + +::: + +3. Initial heading alignment: + + - Initial heading alignment is set to kinematic by default. This can be changed by adjusting + + - [MS_ALIGNMENT](../advanced_config/parameter_reference.md#MS_ALIGNMENT) + +4. GNSS Aiding Source Control (GNSS/INS only) + + - The Source of the GNSS aiding data can be configured using: + + - [MS_GNSS_AID_SRC](../advanced_config/parameter_reference.md#MS_GNSS_AID_SRC) + +5. Sensor to vehicle transform: + + - If the sensor is mounted in an orientation different from the vehicle frame. A sensor to vehicle transform can be enabled using + + - [MS_SVT_EN](../advanced_config/parameter_reference.md#MS_SVT_EN) + + - The transform is defined using the following parameters + + - [MS_SENSOR_ROLL](../advanced_config/parameter_reference.md#MS_SENSOR_ROLL) + - [MS_SENSOR_PTCH](../advanced_config/parameter_reference.md#MS_SENSOR_PTCH) + - [MS_SENSOR_YAW](../advanced_config/parameter_reference.md#MS_SENSOR_YAW) + +6. IMU ranges: + + - The accelerometer and gyroscope ranges on the device are configurable using: + + - [MS_ACCEL_RANGE](../advanced_config/parameter_reference.md#MS_ACCEL_RANGE) + - [MS_GYRO_RANGE](../advanced_config/parameter_reference.md#MS_GYRO_RANGE) + + ::: tip + Available range settings depend on the specific [sensor](https://www.hbkworld.com/en/products/transducers/inertial-sensors) and can be found in the corresponding user manual. + By default, the ranges are not changed. + + +::: + +7. GNSS Lever arm offsets: + + - The lever arm offset for the external GNSS receiver can be configured using: + + - [MS_GNSS_OFF1_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_X) + - [MS_GNSS_OFF1_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Y) + - [MS_GNSS_OFF1_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Z) + + - For dual-antenna configurations, the second GNSS receiver’s offset is configured using: + + - [MS_GNSS_OFF2_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_X) + - [MS_GNSS_OFF2_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Y) + - [MS_GNSS_OFF2_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Z) + +## Опубліковані дані + +The MicroStrain driver continuously publishes sensor data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [датчик_гіроскопа](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) +- [sensor_baro](../msg_docs/SensorBaro.md) + +For GNSS/INS devices, GPS data is also published to: + +- [sensor_gps](../msg_docs/SensorGps.md) + +If used as an external INS replacing EKF2, it publishes: + +- [vehicle_global_position](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) +- [vehicle_odometry](../msg_docs/VehicleOdometry.md) + +otherwise the same data is published to the following topics + +- `external_ins_global_position` +- `external_ins_attitude` +- `external_ins_local_position` + +:::tip +Опубліковані теми можна переглянути за допомогою команди `listener`. +::: diff --git a/docs/uk/sensor/rangefinders.md b/docs/uk/sensor/rangefinders.md index a25b799444..e5280bf30a 100644 --- a/docs/uk/sensor/rangefinders.md +++ b/docs/uk/sensor/rangefinders.md @@ -15,11 +15,69 @@ This is a subset of the rangefinders that can be used with PX4. There may also be other DroneCAN rangefinders than those listed here. ::: -### ARK Flow & AKR Flow MR +| Rangefinder | Technology | Range (min – max) | З'єднання | NDAA | Примітки | +| ------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------- | ------------------------------------------------------ | +| [Ainstein US-D1 Standard Radar Altimeter] | Microwave radar | ~50 m | UART | ✔️ | | +| [ARK DIST SR] | ToF (850 nm IR) | 8 cm to ~30 m | DroneCAN, UART | ✔️ | | +| [ARK DIST MR] | ToF (IR) | 8 cm to ~50 m | DroneCAN, UART | ✔️ | | +| [Benewake TFmini] | ToF (IR laser) | ~12 m | UART | ~ | | +| [Holybro ST VL53L1X Lidar] | ToF (IR) | up to ~4 m | I2C | ~ | | +| [LeddarOne] | ToF (IR) | 1 cm – 40 m | UART | ~ | | +| [Lidar-Lite] | ToF (IR laser) | 5 cm – 40 m | I2C, PWM | ~ | | +| [LightWare SF11/C] | ToF (IR laser) | up to ~120 m | UART, I2C | ~ | | +| [LightWare LW20/C] | ToF (IR laser) | up to ~100 m | I2C | ~ | Waterproof (IP67) + servo | +| [LightWare SF45/B] | ToF (IR laser) | ~50 m | UART | ~ | Rotary lidar (collision prevention) | +| [MaxBotix I2CXL-MaxSonar-EZ] | Ultrasonic | | I2C | ~ | | +| [RaccoonLab Cyphal & DroneCAN µRANGEFINDER] | ToF (IR) | ~0.1 m – ~8 m | DroneCAN, Cyphal | ~ | | +| [TeraRanger Evo 60 m] | ToF (IR) | 0.5 m – 60 m | I2C | ~ | | +| [TeraRanger Evo 600Hz] | ToF (IR) | 0.75 m – 8 m | I2C | ~ | High update rate (600 Hz) | +| [LightWare SF02] _(disc.)_ | ToF (IR laser) | ~50 m | UART | ~ | Discontinued | +| [LightWare SF10/A] _(disc.)_ | ToF (IR laser) | ~25 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/B] _(disc.)_ | ToF (IR laser) | ~50 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/C] _(disc.)_ | ToF (IR laser) | ~100 m | UART, I2C | ~ | Discontinued | +| [Lanbao PSK-CM8JL65-CC5] _(disc.)_ | ToF (IR) | 0.17 m – 8 m | UART | ✖️ | Discontinued | +| [TeraRanger One] _(disc.)_ | ToF (IR) | ~0.2 m – ~14 m (typical) | I2C (adapter required) | ~ | Discontinued | -[ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md) are open-source Time-of-Flight (ToF) and optical flow sensor modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. -Він може бути підключений до контролера польоту через свій порт CAN1, що дозволяє підключати додаткові датчики через свій порт CAN2. -It supports [DroneCAN](../dronecan/index.md), runs [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and is packed into a tiny form factor. +[Ainstein US-D1 Standard Radar Altimeter]: ../sensor/ulanding_radar.md +[ARK DIST SR]: ../dronecan/ark_dist.md +[ARK DIST MR]: ../dronecan/ark_dist_mr.md +[Benewake TFmini]: ../sensor/tfmini.md +[Holybro ST VL53L1X Lidar]: #holybro-st-vl53l1x-lidar +[Lanbao PSK-CM8JL65-CC5]: ../sensor/cm8jl65_ir_distance_sensor.md +[LeddarOne]: ../sensor/leddar_one.md +[Lidar-Lite]: ../sensor/lidar_lite.md +[LightWare Lidar]: ../sensor/sfxx_lidar.md +[LightWare SF11/C]: ../sensor/sfxx_lidar.md +[LightWare LW20/C]: ../sensor/sfxx_lidar.md +[LightWare SF45/B]: ../sensor/sfxx_lidar.md +[LightWare SF02]: ../sensor/sfxx_lidar.md +[LightWare SF10/A]: ../sensor/sfxx_lidar.md +[LightWare SF10/B]: ../sensor/sfxx_lidar.md +[LightWare SF10/C]: ../sensor/sfxx_lidar.md +[MaxBotix I2CXL-MaxSonar-EZ]: #maxbotix-i2cxl-maxsonar-ez +[TeraRanger Evo 60 m]: ../sensor/teraranger.md +[TeraRanger Evo 600Hz]: ../sensor/teraranger.md +[TeraRanger One]: ../sensor/teraranger.md + +These adaptors allows you to connect a non-CAN rangefinder via the CAN interface. +Note that the range depends on the connected rangefinder + +| Adaptor | З'єднання | NDAA | +| ------------------------------------------------------- | ---------------- | ----------------- | +| **Avionics Anonymous UAVCAN Laser Altimeter Interface** | DroneCAN | ~ | +| [RaccoonLab Cyphal & DroneCAN Rangefinder Adapter] | DroneCAN, Cyphal | ~ | + +[RaccoonLab Cyphal & DroneCAN µRANGEFINDER]: #raccoonlab-cyphal-and-dronecan-μrangefinder +[RaccoonLab Cyphal & DroneCAN Rangefinder Adapter]: #raccoonlab-cyphal-and-dronecan-rangefinder-adapter + +Note that some [Optical Flow](../sensor/optical_flow.md) sensors also include a rangefinder, such as [ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md). + +### ARK DIST SR & ARK DIST MR + +[ARK DIST SR](../dronecan/ark_dist.md) and [ARK DIST MR](../dronecan/ark_dist_mr.md) are open-source Time-of-Flight (ToF) rangefinder modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. + +The sensors support [DroneCAN](../dronecan/index.md), run [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and are packed into a tiny form factor. +They can be connected to a flight controller via its `CAN1` port, allowing additional sensors to connected through the `CAN2` port. ### Лідар Holybro ST VL53L1X @@ -146,11 +204,11 @@ To view the rangefinder output: 1. Open the menu **Q > Select Tool > Analyze Tools**: - ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) + ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) 2. Select the message `DISTANCE_SENSOR`, and then check the plot checkbox against `current_distance`. - The tool will then plot the result: - ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) + The tool will then plot the result: + ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) ### QGroundControl MAVLink Console diff --git a/docs/uk/sensor/sbgecom.md b/docs/uk/sensor/sbgecom.md new file mode 100644 index 0000000000..706c96b1b2 --- /dev/null +++ b/docs/uk/sensor/sbgecom.md @@ -0,0 +1,157 @@ +# SBG Systems INS/AHRS (Pulse, Ellipse, etc.) + +[SBG-Systems](https://www.sbg-systems.com/) designs, manufactures, and support an extensive range of state-of-the-art inertial sensors such as Inertial Measurement Units (IMU), Attitude and Heading Reference Systems (AHRS), Inertial Navigation Systems with embedded GNSS (INS/GNSS), and so on. + +PX4 supports [all SBG Systems products](https://www.sbg-systems.com/products/) and can use these as an [external INS](../sensor/inertial_navigation_systems.md) (bypassing/replacing the EKF2 estimator), or as a source of raw sensor data provided to the navigation estimator. + +![Ellipse](../../assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png) + +## Загальний огляд + +SBG Systems products provide a range of benefits to PX4 users and can be integrated for: + +- Вища точність оцінки напрямку, крену та кочення +- Більш надійна геоприв'язка GNSS +- Покращена точність позиціонування та установки під час конфлікту супутникового зв'язку +- Продуктивність при динамічних умовах (наприклад, запуски катапультою, операції VTOL, високі g або високі операції з великою кутовою швидкістю) + +The sbgECom PX4 driver is streamlined to provide a simple plug-and-play architecture, removing engineering obstacles and allowing the acceleration of the design, development, and launch of platforms to keep pace with the rapid rate of innovation. + +The driver supports [all SBG Systems products](https://www.sbg-systems.com/products/). +Зокрема, рекомендуємо наступні системи: + +- **Pulse:** Recommended for fixed-wing systems without hovering, where static heading is not necessary. +- **Ellipse:** Recommended for multicopter systems where hovering and low dynamics requires the use of static heading. + +## Де купити + +SBG Systems solutions are available directly from [MySBG](https://my.sbg-systems.com) (FR) or through their Global Sales Representatives. For more information on their solutions or for international orders, please contact contact@sbg-systems.com. + +## Налаштування програмного забезпечення + +### Підключення + +Connect any unused flight controller serial interface, such as a spare `GPS` or `TELEM` port, to the SBG Systems product MAIN port (required by PX4). + +### Встановлення + +The SBG Systems product sensor can be mounted in any orientation, in any position on the vehicle, without regard to center of gravity. +All SBG Systems product sensors default to a coordinate system of x-forward, y-right, and z-down, making the default mounting as connector-back, base down. +This can be changed to any rigid rotation using the sbgECom Reference Frame Rotation register. + +Якщо використовується продукт з підтримкою GNSS, антена GNSS повинна бути жорстко монтуватися щодо інерційного датчика та мати необмежений вид на небо. If using a dual-GNSS-enabled product (Ellipse-D), the secondary antenna must be mounted rigidly with respect to the primary antenna and the inertial sensor with an unobstructed sky view. + +For more mounting and configuration requirements and recommendations, see the relevant [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +## Конфігурація прошивки + +### Конфігурація PX4 + +To use the sbgECom driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_SBGECOM` or `CONFIG_COMMON_INS`. + +2. [Set the parameter](../advanced_config/parameters.md) [SENS_SBG_CFG](../advanced_config/parameter_reference.md#SENS_SBG_CFG) to the hardware port connected to the SBG Systems product (for more information see [Serial Port Configuration](../peripherals/serial_configuration.md)). + + ::: warning + Disable or change port of other sensors that are using the same one, for example [GPS_1_CONFIG](../advanced_config/parameter_reference.md#GPS_1_CONFIG) if using GPS1 port. + +::: + +3. Set [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) to the desired default baudrate value. + +4. Allow the sbgECom driver to initialize by restarting PX4. + +5. Configure driver to provide IMU data, GNSS data and INS : + + 1. Set [SBG_MODE](../advanced_config/parameter_reference.md#SBG_MODE) to the desired mode. + 2. Make sensor module select sensors by enabling [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE). + 3. Prioritize SBG Systems sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + + ::: tip + In most cases the external IMU (SBG) is the highest-numbered. + Ви можете отримати список доступних компонентів IMU, використовуючи [`uorb top -1`](../middleware/uorb.md#uorb-top-command), ви можете відрізняти їх за допомогою команди [`listener`](../modules/modules_command.md#listener) та розглядаючи дані чи просто швидкості. + + За потреби ви можете перевірити [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID), щоб побачити ідентифікатор пристрою. + Пріоритет становить 0-255, де 0 абсолютно вимкнено, а 255 - найвищий пріоритет. + +::: + + ::: warning + When configuring both SBG Systems and Pixhawk sensors to have non-zero priority, if the selected sensor is errored (timeout), it can change during operation without being notified. + In this case, MAVLink messages will be updated with the newly selected sensor. + + If you don't want to have this fallback mechanism, you must disable unwanted sensors. + +::: + 4. If using the sbgECom as an INS, disable EKF2 using [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN). + +6. Перезавантажте PX4. + +Після активації модуль буде виявлено при завантаженні. +IMU data should be published at 200Hz. + +## SBG Systems Configuration + +All High Performance and Ellipse 3.0 and higher SBG Systems INS can be configured directly from PX4 firmware: + +1. Enable [SBG_CONFIGURE_EN](../advanced_config/parameter_reference.md#SBG_CONFIGURE_EN). + +2. Provide a JSON file `sbg_settings.json` containing SBG Systems INS settings to be applied in your PX4 board `extras` directory (ex: `boards/px4/fmu-v5/extras`). The settings JSON file will be installed in `/etc/extras/sbg_settings.json` on the board. + + ::: tip + The settings can be retrieved using [sbgEComAPI](https://github.com/SBG-Systems/sbgECom/tree/main/tools/sbgEComApi) or [sbgInsRestApi](https://developer.sbg-systems.com/sbgInsRestApi/1.3/#tag/Settings) and then modified as a JSON file. + +::: + + ::: tip + The settings file can be provided in the SD card in q`/fs/microsd/etc/extras/sbg_settings.json` to avoid rebuilding a new firmware to change JSON settings file. + +::: + +3. For testing purpose, it's also possible to modify SBG Systems INS settings on the fly: + - By passing a JSON file path as argument when starting sbgecom driver (ex: `sbgecom start -f /fs/microsd/new_sbg_settings.json`) + - By passing a JSON string as argument when starting sbgecom driver: (ex: `sbgecom start -s {"output":{"comA":{"messages":{"airData":"onChange"}}}}`) + +For older Ellipse SBG Systems INS or to configure any SBG Systems INS directly, all commands and registers can be found in the [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +:::warning +If the baudrate of the serial port on the INS product (used to communicate with PX4) is changed, the parameter [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) must be changed to match. +::: + +## Опубліковані дані + +При ініціалізації водій повинен надрукувати наступну інформацію до консолі (надруковано за допомогою `PX4_INFO`) + +- Номер моделі блока +- Версія апаратної одиниці +- Номер серійного номеру блока +- Номер прошивки одиниці + +Цей текст має бути доступний за допомогою команди [`dmesg`](../modules/modules_system.md#dmesg). + +The sbgECom driver always publishes the unit's data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [датчик_гіроскопа](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) + +if configured as a GNSS, publishes: + +- [sensor_gps](../msg_docs/SensorGps.md) + +and, if configured as an INS, publishes: + +- [estimator_status](../msg_docs/EstimatorStatus.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_global_positon](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) + +:::tip +Опубліковані теми можна переглянути за допомогою команди `listener`. +::: + +## Характеристики обладнання + +- [Product Briefs](https://www.sbg-systems.com/products/) +- [Datasheets](https://www.sbg-systems.com/contact/#products) diff --git a/docs/uk/sensor/sfxx_lidar.md b/docs/uk/sensor/sfxx_lidar.md index 8621a5c2b1..5bfe0c7f8a 100644 --- a/docs/uk/sensor/sfxx_lidar.md +++ b/docs/uk/sensor/sfxx_lidar.md @@ -9,11 +9,12 @@ LightWare розробляє широкий спектр легких, зага Наступні моделі підтримуються PX4 та можуть бути підключені до шини I2C або Serial (таблиці нижче показують, яку шину можна використовувати для кожної моделі). -| Модель | Range (m) | Шина | Опис | -| ---------------------------------------------------------- | ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- | -| [SF11/C](https://lightwarelidar.com/products/sf11-c-100-m) | 100 | Серійна або I2C шина | | -| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | Шина I2C | Водонепроникний (IP67) з сервоприводом для додатків з детекцією та уникненням перешкод | -| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Серія | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| Модель | Range (m) | Шина | Опис | +| ------------------------------------------------------- | ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- | +| [SF11/C](https://lightwarelidar.com/shop/sf11-c-100-m/) | 100 | Серійна або I2C шина | | +| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | Шина I2C | Водонепроникний (IP67) з сервоприводом для додатків з детекцією та уникненням перешкод | +| [SF30/D](https://lightwarelidar.com/shop/sf30-d-200-m/) | 200 | Шина I2C | Waterproofed (IP67) | +| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Серія | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | :::details Discontinued diff --git a/docs/uk/sensor/vectornav.md b/docs/uk/sensor/vectornav.md index 0cf39e2905..6fd363bed1 100644 --- a/docs/uk/sensor/vectornav.md +++ b/docs/uk/sensor/vectornav.md @@ -61,18 +61,18 @@ PX4 може використовувати це як [зовнішній INS] ( 5. Налаштуйте водія як зовнішній INS або надайте сирові дані: - Якщо використовувати VectorNav як зовнішній INS, встановіть [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) на `INS`. - Це вимикає EKF2. + Це вимикає EKF2. - Якщо використовувати VectorNav як зовнішні інерційні сенсори: - 1. Встановіть [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) на `Sensors Only` - 2. Якщо внутрішні датчики увімкнені, пріоритетом є датчики VectorNav за допомогою [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), де _n_ - це номер екземпляра компонента ІМП (0, 1 і т.д.). + 1. Встановіть [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) на `Sensors Only` + 2. Якщо внутрішні датчики увімкнені, пріоритетом є датчики VectorNav за допомогою [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), де _n_ - це номер екземпляра компонента ІМП (0, 1 і т.д.). - :::tip - У більшості випадків зовнішній IMU (VN) має найвищий номер. - Ви можете отримати список доступних компонентів IMU, використовуючи [`uorb top -1`](../middleware/uorb.md#uorb-top-command), ви можете відрізняти їх за допомогою команди [`listener`](../modules/modules_command.md#listener) та розглядаючи дані чи просто швидкості. + :::tip + У більшості випадків зовнішній IMU (VN) має найвищий номер. + Ви можете отримати список доступних компонентів IMU, використовуючи [`uorb top -1`](../middleware/uorb.md#uorb-top-command), ви можете відрізняти їх за допомогою команди [`listener`](../modules/modules_command.md#listener) та розглядаючи дані чи просто швидкості. - За потреби ви можете перевірити [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID), щоб побачити ідентифікатор пристрою. - Пріоритет становить 0-255, де 0 абсолютно вимкнено, а 255 - найвищий пріоритет. + За потреби ви можете перевірити [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID), щоб побачити ідентифікатор пристрою. + Пріоритет становить 0-255, де 0 абсолютно вимкнено, а 255 - найвищий пріоритет. ::: diff --git a/docs/uk/sim_flightgear/index.md b/docs/uk/sim_flightgear/index.md index 98998fa199..f637d8ad8b 100644 --- a/docs/uk/sim_flightgear/index.md +++ b/docs/uk/sim_flightgear/index.md @@ -40,33 +40,33 @@ These instructions were tested on Ubuntu 18.04 2. Встановити FlightGear: - ```sh - sudo add-apt-repository ppa:saiarcot895/flightgear - sudo apt update - sudo apt install flightgear - ``` + ```sh + sudo add-apt-repository ppa:saiarcot895/flightgear + sudo apt update + sudo apt install flightgear + ``` - Це встановить останню стабільну версію FlightGear зі сховища PAA разом із пакетом FGdata. + Це встановить останню стабільну версію FlightGear зі сховища PAA разом із пакетом FGdata. - :::tip - For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. - Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). + :::tip + For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. + Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). ::: 3. Перевірте, що ви можете запустити FlightGear: - ```sh - fgfs --launcher - ``` + ```sh + fgfs --launcher + ``` 4. Set write permissions to the **Protocols** folder in the FlightGear installation directory: - ```sh - sudo chmod a+w /usr/share/games/flightgear/Protocol - ``` + ```sh + sudo chmod a+w /usr/share/games/flightgear/Protocol + ``` - Налаштування дозволів потрібне, оскільки PX4-FlightGear-Bridge розміщує тут файл визначення зв’язку. + Налаштування дозволів потрібне, оскільки PX4-FlightGear-Bridge розміщує тут файл визначення зв’язку. Additional installation instructions can be found on [FlightGear wiki](https://wiki.flightgear.org/Howto:Install_Flightgear_from_a_PPA). diff --git a/docs/uk/sim_gazebo_classic/index.md b/docs/uk/sim_gazebo_classic/index.md index 37b64ee8ce..d4a131c6ae 100644 --- a/docs/uk/sim_gazebo_classic/index.md +++ b/docs/uk/sim_gazebo_classic/index.md @@ -249,14 +249,14 @@ It is enabled by default in many vehicle SDF files: **solo.sdf**, **iris.sdf**, To enable/disable GPS noise: 1. Build any gazebo target in order to generate SDF files (for all vehicles). - Наприклад: + Наприклад: - ```sh - make px4_sitl gazebo-classic_iris - ``` + ```sh + make px4_sitl gazebo-classic_iris + ``` - :::tip - The SDF files are not overwritten on subsequent builds. + :::tip + The SDF files are not overwritten on subsequent builds. ::: @@ -264,17 +264,17 @@ To enable/disable GPS noise: 3. Search for the `gpsNoise` element: - ```xml - - - true - - ``` + ```xml + + + true + + ``` - - If it is present, GPS is enabled. - You can disable it by deleting the line: `true` - - If it is not present, GPS is disabled. - You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). + - If it is present, GPS is enabled. + You can disable it by deleting the line: `true` + - If it is not present, GPS is disabled. + You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). The next time you build/restart Gazebo Classic it will use the new GPS noise setting. diff --git a/docs/uk/sim_gazebo_classic/multi_vehicle_simulation.md b/docs/uk/sim_gazebo_classic/multi_vehicle_simulation.md index a198f4a006..db344edaae 100644 --- a/docs/uk/sim_gazebo_classic/multi_vehicle_simulation.md +++ b/docs/uk/sim_gazebo_classic/multi_vehicle_simulation.md @@ -68,36 +68,36 @@ For more information see: [ROS 2 User Guide (PX4-ROS 2 Bridge)](../ros2/user_gui 1. Клонуйте код PX4/Прошивки і зберіть код SITL: - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl gazebo-classic + ``` 2. Build the `micro xrce-dds agent` and the interface package following the [instructions here](../ros2/user_guide.md). 3. Run `Tools/simulation/gazebo-classic/sitl_multiple_run.sh`. - Наприклад, для відтворення 4 рухомих засобів виконайте: + Наприклад, для відтворення 4 рухомих засобів виконайте: - ```sh - ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 - ``` + ```sh + ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 + ``` - ::: info - Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). - Системний ідентифікатор MAVLink 1 пропускається. + ::: info + Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). + Системний ідентифікатор MAVLink 1 пропускається. ::: 4. Run `MicroXRCEAgent`. - Він автоматично під'єднається до усіх чотирьох рухомих засобів: + Він автоматично під'єднається до усіх чотирьох рухомих засобів: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` - ::: info - The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. + ::: info + The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. ::: @@ -117,27 +117,27 @@ You can then control the vehicles with _QGroundControl_ and MAVROS in a similar 1. Клонуйте код PX4/PX4-Autopilot і зберіть код SITL - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl_default gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl_default gazebo-classic + ``` 2. Виконайте команду source у вашому середовищі: - ```sh - source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default - export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo - ``` + ```sh + source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default + export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo + ``` 3. Виконайте файл запуску: - ```sh - roslaunch px4 multi_uav_mavros_sitl.launch - ``` + ```sh + roslaunch px4 multi_uav_mavros_sitl.launch + ``` - ::: info - You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. + ::: info + You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. ::: @@ -253,45 +253,45 @@ The launch file `multi_uav_mavros_sitl.launch`does the following, 1. Install _xmlstarlet_ from your Linux terminal: - ```sh - sudo apt install xmlstarlet - ``` + ```sh + sudo apt install xmlstarlet + ``` 2. Use _roslaunch_ with the **multi_uav_mavros_sitl_sdf.launch** launch file: - ````sh - roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= - ``` + ````sh + roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= + ``` - ::: info - Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. + ::: info + Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. ::: - ```` + ```` This method is similar to using the xacro except that the SITL/Gazebo Classic port number is automatically inserted by _xmstarlet_ for each spawned vehicle, and does not need to be specified in the SDF file. Щоб додати новий рухомий засіб, вам потрібно переконатися, що модель можна знайти (для відтворення у Gazebo Classic) та PX4 повинен мати відповідний скрипт запуску. 1. Можна обрати зробити щось одне з: - - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: + - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: - ```sh - $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf - ``` + ```sh + $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf + ``` - ::: info - Ensure you set the `vehicle` argument even if you hardcode the path to your model. + ::: info + Ensure you set the `vehicle` argument even if you hardcode the path to your model. ::: - - скопіювати свою модель в директорію, позначену вище (дотримуючись тих же правил шляху). + - скопіювати свою модель в директорію, позначену вище (дотримуючись тих же правил шляху). 2. The `vehicle` argument is used to set the `PX4_SIM_MODEL` environment variable, which is used by the default rcS (startup script) to find the corresponding startup settings file for the model. - Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. - For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). - For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). - For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. + Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. + For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). + For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). + For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. ## Додаткові ресурси diff --git a/docs/uk/sim_gazebo_gz/gazebo_models.md b/docs/uk/sim_gazebo_gz/gazebo_models.md index f55f30ba24..0bbaa35775 100644 --- a/docs/uk/sim_gazebo_gz/gazebo_models.md +++ b/docs/uk/sim_gazebo_gz/gazebo_models.md @@ -101,15 +101,15 @@ python simulation-gazebo --overwrite 1. В одному терміналі запустіть - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 + ``` 2. У вікні другого терміналу запустіть: - ```sh - python3 /path/to/simulation-gazebo --world windy - ``` + ```sh + python3 /path/to/simulation-gazebo --world windy + ``` Не потрібно передавати додаткових параметрів скрипту simulation-gazebo щоб цей приклад працював, оскільки усі вузли Gazebo виконуються на одному комп'ютері. Дивіться приклад складнішого сценарію з різними комп'ютерами нижче. diff --git a/docs/uk/sim_gazebo_gz/index.md b/docs/uk/sim_gazebo_gz/index.md index 8b9c17d00f..a05e18c158 100644 --- a/docs/uk/sim_gazebo_gz/index.md +++ b/docs/uk/sim_gazebo_gz/index.md @@ -20,6 +20,8 @@ See [Simulation](../simulation/index.md) for general information about simulator Gazebo Harmonic is installed by default on Ubuntu 22.04 as part of the normal [development environment setup](../dev_setup/dev_env_linux_ubuntu.md#simulation-and-nuttx-pixhawk-targets). +Gazebo versions Harmonic, Ionic, and Jetty are supported on Ubuntu 24.04. The latest installed Gazebo release is used by default. + :::info The PX4 installation scripts are based on the instructions: [Binary Installation on Ubuntu](https://gazebosim.org/docs/harmonic/install_ubuntu/) (gazebosim.org). ::: @@ -48,22 +50,23 @@ make px4_sitl gz_x500 The supported vehicles and `make` commands are listed below. Note that all gazebo make targets have the prefix `gz_`. -| Транспортний засіб | Команда | `PX4_SYS_AUTOSTART` | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------- | -| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | -| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | -| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | -| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | -| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | -| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | -| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | -| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | -| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | -| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | -| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_r1_rover` | 4009 | -| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 4012 | -| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | -| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| Транспортний засіб | Команда | `PX4_SYS_AUTOSTART` | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------------------- | +| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4001 | +| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | +| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | +| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | +| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | +| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | +| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | +| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | +| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | +| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | +| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | +| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_rover_differential` | 50000 | +| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 51000 | +| [Mecanum Rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) | `make px4_sitl gz_rover_mecanum` | 52000 | All [vehicle models](../sim_gazebo_gz/vehicles.md) (and [worlds](#specify-world)) are included as a submodule from the [Gazebo Models Repository](../sim_gazebo_gz/gazebo_models.md) repository. @@ -316,33 +319,33 @@ The PX4 Gazebo worlds and and models databases [can be found on GitHub here](htt 1. **Start simulator + default world + spawn vehicle at default pose** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 2. **Start simulator + default world + spawn vehicle at custom pose (y=2m)** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 3. **Start simulator + default world + link to existing vehicle** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 + ``` 4. **Start simulator in standalone mode + connect to Gazebo instance running default world** - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` - В окремому терміналі запустіть: + В окремому терміналі запустіть: - ```sh - python /path/to/simulation-gazebo - ``` + ```sh + python /path/to/simulation-gazebo + ``` ## Додавання нових світів та моделей @@ -358,38 +361,38 @@ SDF files, mesh files, textures and anything else to do with the functionality a 2. Define the default parameters for Gazebo in the airframe configuration file (this example is from [x500 quadcopter](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/4001_gz_x500)): - ```ini - PX4_SIMULATOR=${PX4_SIMULATOR:=gz} - PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} - PX4_SIM_MODEL=${PX4_SIM_MODEL:=} - ``` + ```ini + PX4_SIMULATOR=${PX4_SIMULATOR:=gz} + PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} + PX4_SIM_MODEL=${PX4_SIM_MODEL:=} + ``` - - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. + - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. - - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. + - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. - - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: + - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: - ```sh - PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 + ``` 3. Add CMake Target for the [airframe](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt). - - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. - - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` + - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. + - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` - Ви звичайно також можете використовувати обидва варіанти. + Ви звичайно також можете використовувати обидва варіанти. ### Додавання світу Щоб додати новий світ: 1. Add your world to the list of worlds found in the [`CMakeLists.txt` here](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/CMakeLists.txt). - This is required in order to allow `CMake` to generate correct targets. + This is required in order to allow `CMake` to generate correct targets. - - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. - - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` + - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. + - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` :::info As long as the world file and the model file are in the Gazebo search path (`GZ_SIM_RESOURCE_PATH`) it is not necessary to add them to the PX4 world and model directories. diff --git a/docs/uk/sim_gazebo_gz/plugins.md b/docs/uk/sim_gazebo_gz/plugins.md index 9723f44177..0f48c53db8 100644 --- a/docs/uk/sim_gazebo_gz/plugins.md +++ b/docs/uk/sim_gazebo_gz/plugins.md @@ -43,8 +43,8 @@ When developing new plugins: 1. **Follow the plugin architecture** - Implement desired interfaces. - You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. - The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). + You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. + The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). 2. **Register your plugin** - Add it to [server.config](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/server.config) for discovery. diff --git a/docs/uk/sim_gazebo_gz/tools_avl_automation.md b/docs/uk/sim_gazebo_gz/tools_avl_automation.md index ced2df2610..80e32b4bb8 100644 --- a/docs/uk/sim_gazebo_gz/tools_avl_automation.md +++ b/docs/uk/sim_gazebo_gz/tools_avl_automation.md @@ -11,26 +11,26 @@ Щоб налаштувати інструмент: 1. Завантажте AVL 3.36 з . - Файл AVL для версії 3.36 можна знайти приблизно посередині сторінки. + Файл AVL для версії 3.36 можна знайти приблизно посередині сторінки. 2. Після завантаження розпакуйте AVL та перемістіть його в домашню директорію за допомогою: - ```sh - sudo tar -xf avl3.36.tgz - mv ./Avl /home/ - ``` + ```sh + sudo tar -xf avl3.36.tgz + mv ./Avl /home/ + ``` 3. Дотримуйтесь **index.md**, що знаходиться у `./Avl` щоб завершити процес встановлення AVL (вимагає встановлення бібліотек `plotlib` та `eispack`). - Ми рекомендуємо використовувати варіант компіляції "gfortran", який може далі вимагати, щоб ви встановили "gfortran". - На Ubuntu це можна зробити виконавши: + Ми рекомендуємо використовувати варіант компіляції "gfortran", який може далі вимагати, щоб ви встановили "gfortran". + На Ubuntu це можна зробити виконавши: - ```sh - sudo apt update - sudo apt install gfortran - ``` + ```sh + sudo apt update + sudo apt install gfortran + ``` - При запуску Makefile для AVL, ви можливо зіткнетесь з повідомленням `Error 1`, яке стверджує що відсутня якась директорія. - Це не завадить AVL працювати для нашої мети. + При запуску Makefile для AVL, ви можливо зіткнетесь з повідомленням `Error 1`, яке стверджує що відсутня якась директорія. + Це не завадить AVL працювати для нашої мети. Як тільки процес, описаний в AVL README буде завершений, AVL готовий до використання. Зі сторони AVL та інструменту більше ніяких налаштувань не потрібно. @@ -49,16 +49,16 @@ 2. Запустіть інструмент на вашому yml-файлі: - ```sh - python input_avl.py .yml - ``` + ```sh + python input_avl.py .yml + ``` - Зверніть увагу, що пакети `yaml` та `argparse` повинні бути присутні в середовищі Python. + Зверніть увагу, що пакети `yaml` та `argparse` повинні бути присутні в середовищі Python. 3. Інструмент очікує діапазон певних параметрів рухомого засобу, які потрібні щоб вказати геометрію та фізичні властивості літака. - Ви можете або: - - обрати попередньо визначений шаблон моделі (наприклад Cessna або ВЗІП), який має відому кількість поверхонь керування і просто змінити деяки фізичні властивості, або - - визначити повністю довільну модель + Ви можете або: + - обрати попередньо визначений шаблон моделі (наприклад Cessna або ВЗІП), який має відому кількість поверхонь керування і просто змінити деяки фізичні властивості, або + - визначити повністю довільну модель Після виконання скрипту, згенеровані файли `.avl`, `.sdf` та креслення пропонованих поверхонь керування можна знайти у директорії ``. Файл sdf - це згенерований плагін Advanced Lift Drag який може бути скопійовано і вставлено у файл model.sdf, який потім можна запустити у Gazebo. diff --git a/docs/uk/sim_gazebo_gz/vehicles.md b/docs/uk/sim_gazebo_gz/vehicles.md index 25a52f2447..1660045bed 100644 --- a/docs/uk/sim_gazebo_gz/vehicles.md +++ b/docs/uk/sim_gazebo_gz/vehicles.md @@ -185,7 +185,7 @@ make px4_sitl gz_tiltrotor [Differential Rover](../frames_rover/index.md#differential) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. ```sh -make px4_sitl gz_r1_rover +make px4_sitl gz_rover_differential ``` ![Differential Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_differential.png) @@ -199,3 +199,13 @@ make px4_sitl gz_rover_ackermann ``` ![Ackermann Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_ackermann.png) + +### Mecanum Rover + +[Mecanum Rover](../frames_rover/index.md#mecanum) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. + +```sh +make px4_sitl gz_rover_mecanum +``` + +![Mecanum Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_mecanum.png) diff --git a/docs/uk/sim_jmavsim/index.md b/docs/uk/sim_jmavsim/index.md index 92d65c2f9c..2b92535f04 100644 --- a/docs/uk/sim_jmavsim/index.md +++ b/docs/uk/sim_jmavsim/index.md @@ -30,23 +30,23 @@ Follow the instructions below to install jMAVSim on macOS. To setup the environment for [jMAVSim](../sim_jmavsim/index.md) simulation: 1. Install a recent version of Java (e.g. Java 15). - You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): + You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): - ```sh - brew install --cask temurin - ``` + ```sh + brew install --cask temurin + ``` 2. Install jMAVSim: - ```sh - brew install px4-sim-jmavsim - ``` + ```sh + brew install px4-sim-jmavsim + ``` - :::warning - PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. + :::warning + PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. - For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. - You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). + For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. + You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). ::: diff --git a/docs/uk/sim_sih/index.md b/docs/uk/sim_sih/index.md index bc2d323650..e94df82509 100644 --- a/docs/uk/sim_sih/index.md +++ b/docs/uk/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH як SITL (без апаратного забезпечення) з версії PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Переваги @@ -71,24 +71,24 @@ To check that these are present on your flight controller: 3. Enter the following commands in the console: - ```sh - pwm_out_sim status - ``` + ```sh + pwm_out_sim status + ``` - ```sh - sensor_baro_sim status - ``` + ```sh + sensor_baro_sim status + ``` - ```sh - sensor_gps_sim status - ``` + ```sh + sensor_gps_sim status + ``` - ```sh - sensor_mag_sim status - ``` + ```sh + sensor_mag_sim status + ``` - ::: tip - Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). + ::: tip + Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). ::: @@ -141,12 +141,12 @@ To set up/start SIH: 1. Connect the flight controller to the desktop computer with a USB cable. 2. Відкрийте QGroundControl і зачекайте, поки контролер польоту також завантажиться та підключиться. 3. Open [Vehicle Setup > Airframe](../config/airframe.md) then select the desired frame: - - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) - - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). - - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) - - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) - - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) - - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) + - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) + - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). + - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) + - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) + - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) + - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) Потім автопілот перезавантажиться. The `sih` module is started on reboot, and the vehicle should be displayed on the ground control station map. @@ -172,19 +172,19 @@ SIH does not _need_ a visualiser — you can connect with QGroundControl and fly 3. Start jMAVSim by calling the script **jmavsim_run.sh** from a terminal: - ```sh - ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o - ``` + ```sh + ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o + ``` - де прапорці такі: + де прапорці такі: - - `-q` to allow the communication to _QGroundControl_ (optional). - - `-d` to start the serial device `/dev/ttyACM0` on Linux. - On macOS this would be `/dev/tty.usbmodem1`. - - `-b` to set the serial baud rate to `2000000`. - - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). - - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. - Якщо цей прапорець не вказаний, за замовчуванням відображатиметься квадрокоптер. + - `-q` to allow the communication to _QGroundControl_ (optional). + - `-d` to start the serial device `/dev/ttyACM0` on Linux. + On macOS this would be `/dev/tty.usbmodem1`. + - `-b` to set the serial baud rate to `2000000`. + - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). + - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. + Якщо цей прапорець не вказаний, за замовчуванням відображатиметься квадрокоптер. 4. After few seconds, _QGroundControl_ can be opened again. @@ -201,41 +201,41 @@ In this case you don't need the flight controller hardware. 1. Install the [PX4 Development toolchain](../dev_setup/dev_env.md). 2. Виконайте відповідну команду make для кожного типу транспортного засобу (в корені репозиторію PX4-Autopilot): - - Quadcopter + - Quadcopter - ```sh - make px4_sitl sihsim_quadx - ``` + ```sh + make px4_sitl sihsim_quadx + ``` - - Hexacopter + - Hexacopter - ```sh - make px4_sitl sihsim_hex - ``` + ```sh + make px4_sitl sihsim_hex + ``` - - Fixed-wing (plane) + - Fixed-wing (plane) - ```sh - make px4_sitl sihsim_airplane - ``` + ```sh + make px4_sitl sihsim_airplane + ``` - - XVert VTOL tailsitter + - XVert VTOL tailsitter - ```sh - make px4_sitl sihsim_xvert - ``` + ```sh + make px4_sitl sihsim_xvert + ``` - - Standard VTOL + - Standard VTOL - ```sh - make px4_sitl sihsim_standard_vtol - ``` + ```sh + make px4_sitl sihsim_standard_vtol + ``` - - Ackermann Rover + - Ackermann Rover - ```sh - make px4_sitl sihsim_rover_ackermann - ``` + ```sh + make px4_sitl sihsim_rover_ackermann + ``` ### Зміна швидкості симуляції @@ -328,6 +328,44 @@ For SIH as SITL (no FC): For specific examples see the `_sihsim_` airframes in [ROMFS/px4fmu_common/init.d-posix/airframes](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/) (SIH as SITL) and [ROMFS/px4fmu_common/init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) (SIH on FC). +## Controlling Actuators in SIH + +:::warning +If you want to control throttling actuators in SIH, make sure to remove propellers for safety. +::: + +In some scenarios, it may be useful to control an actuator while running SIH. For example, you might want to verify that winches or grippers are functioning correctly by checking the servo responses. + +To enable actuator control in SIH: + +1. Configure PWM parameters in the airframe file: + +Ensure your airframe file includes the necessary parameters to map PWM outputs to the correct channels. + +For example, if a servo is connected to MAIN 3 and you want to map it to AUX1 on your RC, use the following command: + +`param set-default PWM_MAIN_FUNC3 407` + +You can find a full list of available values for `PWM_MAIN_FUNCn` [here](../advanced_config/parameter_reference.md#PWM_MAIN_FUNC1). In this case, `407` maps the MAIN 3 output to AUX1 on the RC. + +Alternatively, you can use the [`PWM_AUX_FUNCn`](../advanced_config/parameter_reference.md#PWM_AUX_FUNC1) parameters. + +You may also configure the output as desired: + +- Disarmed PWM: ([`PWM_MAIN_DISn`](../advanced_config/parameter_reference.md#PWM_MAIN_DIS1) / [`PWM_AUX_DIS1`](../advanced_config/parameter_reference.md#PWM_AUX_DIS1)) +- Minimum PWM ([`PWM_MAIN_MINn`](../advanced_config/parameter_reference.md#PWM_MAIN_MIN1) / [`PWM_AUX_MINn`](../advanced_config/parameter_reference.md#PWM_AUX_MIN1)) +- Maximum PWM ([`PWM_MAIN_MAXn`](../advanced_config/parameter_reference.md#PWM_MAIN_MAX1) / [`PWM_AUX_MAXn`](../advanced_config/parameter_reference.md#PWM_AUX_MAX1)) + +2. Manually start the PWM output driver + +For safety, the PWM driver is not started automatically in SIH. To enable it, run the following command in the MAVLink shell: + +`pwm_out start` + +And to disable it again: + +`pwm_out stop` + ## Dynamic Models Динамічні моделі для різних транспортних засобів: diff --git a/docs/uk/simulation/index.md b/docs/uk/simulation/index.md index e9a85d3c41..2f0e51f38f 100644 --- a/docs/uk/simulation/index.md +++ b/docs/uk/simulation/index.md @@ -217,20 +217,20 @@ The simulated camera is a gazebo classic plugin that implements the [MAVLink Cam PX4 connects/integrates with this camera in _exactly the same way_ as it would with any other MAVLink camera: 1. [TRIG_INTERFACE](../advanced_config/parameter_reference.md#TRIG_INTERFACE) must be set to `3` to configure the camera trigger driver for use with a MAVLink camera - :::tip - In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. - For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). + :::tip + In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. + For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). ::: 2. PX4 повинен перенаправляти всі команди камери між GCS і (симулятором) MAVLink Camera. - You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. + You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. - ```sh - mavlink start -u 14558 -o 14530 -r 4000 -f -m camera - ``` + ```sh + mavlink start -u 14558 -o 14530 -r 4000 -f -m camera + ``` - ::: info - More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. + ::: info + More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. ::: diff --git a/docs/uk/smart_batteries/rotoye_batmon.md b/docs/uk/smart_batteries/rotoye_batmon.md index 011c485a52..9050fe7efd 100644 --- a/docs/uk/smart_batteries/rotoye_batmon.md +++ b/docs/uk/smart_batteries/rotoye_batmon.md @@ -3,11 +3,6 @@ [Rotoye Batmon](https://rotoye.com/batmon/) is a kit for adding smart battery functionality to off-the-shelf Lithium-Ion and LiPo batteries. Його можна придбати як самостійний пристрій або як частину заводсько зібраної розумної батареї. -:::info -At time of writing you can only use Batmon by [building a custom branch of PX4](#build-px4-firmware). -Support in the codeline is pending [PR approval](https://github.com/PX4/PX4-Autopilot/pull/16723). -::: - ![Rotoye Batmon Board](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye.jpg) ![Pre-assembled Rotoye smart battery](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye-pack.jpg) diff --git a/docs/uk/telemetry/crsf_telemetry.md b/docs/uk/telemetry/crsf_telemetry.md index 484f0f04f0..8cef4b1675 100644 --- a/docs/uk/telemetry/crsf_telemetry.md +++ b/docs/uk/telemetry/crsf_telemetry.md @@ -77,36 +77,36 @@ To use this feature you must build and upload custom firmware that includes [crs 1. [Setup a development environment](../dev_setup/dev_env.md) for building PX4. - As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. + As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. 2. Open a terminal and `cd` into the `PX4-Autopilot` directory. - ```sh - cd PX4-Autopilot - ``` + ```sh + cd PX4-Autopilot + ``` 3. Launch the [PX4 board config tool (`menuconfig`)](../hardware/porting_guide_config.md#px4-menuconfig-setup) for your `make` target using the `boardconfig` option (here the target is the [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) flight controller): - ```sh - make ark_fmu-v6x_default boardconfig - ``` + ```sh + make ark_fmu-v6x_default boardconfig + ``` 4. У інструменті конфігурації плати PX4: - - Disable the default `rc_input` module - 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. - 2. Use the enter key to remove the `*` from `rc_input` checkbox. - - Enable the `crsf_rc` module - 1. Scroll to highlight the `RC` submenu, then press enter to open it. - 2. Scroll to highlight `crsf_rc` and press enter to enable it. + - Disable the default `rc_input` module + 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. + 2. Use the enter key to remove the `*` from `rc_input` checkbox. + - Enable the `crsf_rc` module + 1. Scroll to highlight the `RC` submenu, then press enter to open it. + 2. Scroll to highlight `crsf_rc` and press enter to enable it. - Збережіть і вийдіть з інструменту конфігурації плати PX4. + Збережіть і вийдіть з інструменту конфігурації плати PX4. 5. [Build the PX4 source code](../dev_setup/building_px4.md) with your changes (again assuming you are using ARKV6X): - ```sh - make ark_fmu-v6x_default - ``` + ```sh + make ark_fmu-v6x_default + ``` Це побудує вашу власну прошивку, яку зараз потрібно завантажити на ваш контролер польоту. @@ -128,11 +128,11 @@ Alternatively you can use QGroundControl to install the firmware, as described i 1. [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) — Set to the port that is connected to the CRSF receiver (such as `TELEM1`). - This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. - Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. - For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. - Немає потреби встановлювати швидкість передачі для порту, оскільки це налаштовано драйвером. + Немає потреби встановлювати швидкість передачі для порту, оскільки це налаштовано драйвером. 2. [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) — Enable to activate Crossfire telemetry. diff --git a/docs/uk/telemetry/jfi_telemetry.md b/docs/uk/telemetry/jfi_telemetry.md index decce61a0d..d6ec2f083c 100644 --- a/docs/uk/telemetry/jfi_telemetry.md +++ b/docs/uk/telemetry/jfi_telemetry.md @@ -111,9 +111,9 @@ However if you change the baud rate from 57600 you will need to create and use a 1. Disable SiK Radio in QGC (**Application Settings → General → AutoConnect**). 2. Create a new link configuration: - - Go to **Application Settings → Comms Links**. - - Click **Add**. - - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. + - Go to **Application Settings → Comms Links**. + - Click **Add**. + - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. 3. Select **Connect** to connect with the new configuration. ## J.Fi Configuration diff --git a/docs/uk/telemetry/telemetry_wifi.md b/docs/uk/telemetry/telemetry_wifi.md index 4bcbeb7a21..e7ce53174f 100644 --- a/docs/uk/telemetry/telemetry_wifi.md +++ b/docs/uk/telemetry/telemetry_wifi.md @@ -1,6 +1,6 @@ # WiFi Телеметрійне радіо -WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS.\ +WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS. WiFi typically offers shorter range than a normal telemetry radio, but supports higher data rates, and makes it easier to support FPV/video feeds. Зазвичай для транспортного засобу потрібен лише один радіоприймач (з умовою, що наземна станція вже має WiFi). diff --git a/docs/uk/test_and_ci/fuzz_tests.md b/docs/uk/test_and_ci/fuzz_tests.md index 8215c18d8c..94db42eb4b 100644 --- a/docs/uk/test_and_ci/fuzz_tests.md +++ b/docs/uk/test_and_ci/fuzz_tests.md @@ -15,14 +15,14 @@ To write a fuzz test: 1. Start by writing a "normal" [functional test](../test_and_ci/unit_tests.md#functional-test). 2. Make sure the file name contains `fuzz` (lower case). - For example `my_driver_fuzz_tests.cpp`. + For example `my_driver_fuzz_tests.cpp`. 3. Add one or more fuzz tests to the file. - Наприклад: + Наприклад: ```cpp #include #include - + void myDriverNeverCrashes(const std::string& s) { MyDriver driver; driver.handleInput(s); diff --git a/docs/uk/test_and_ci/index.md b/docs/uk/test_and_ci/index.md index 570eeedba5..57cd0ba411 100644 --- a/docs/uk/test_and_ci/index.md +++ b/docs/uk/test_and_ci/index.md @@ -9,8 +9,8 @@ PX4 широко протестовано за допомогою модульн - [Unit Tests](../test_and_ci/unit_tests.md) - [Continuous Integration (CI)](../test_and_ci/continous_integration.md) - [Integration Testing](../test_and_ci/integration_testing.md) - - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) - - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) - - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) + - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) + - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) + - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) - [Docker](../test_and_ci/docker.md) - [Maintenance](../test_and_ci/maintenance.md) diff --git a/docs/uk/test_and_ci/integration_testing_ros1_mavros.md b/docs/uk/test_and_ci/integration_testing_ros1_mavros.md index 8a1272c79c..4ca05494ec 100644 --- a/docs/uk/test_and_ci/integration_testing_ros1_mavros.md +++ b/docs/uk/test_and_ci/integration_testing_ros1_mavros.md @@ -65,73 +65,73 @@ To write a new test: 1. Create a new test script by copying the empty test skeleton below: - ```python - #!/usr/bin/env python - # [... LICENSE ...] - - # - # @author Example Author - # - PKG = 'px4' - - import unittest - import rospy - import rosbag - - from sensor_msgs.msg import NavSatFix - - class MavrosNewTest(unittest.TestCase): - """ - Test description - """ - - def setUp(self): - rospy.init_node('test_node', anonymous=True) - rospy.wait_for_service('mavros/cmd/arming', 30) - - rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) - self.rate = rospy.Rate(10) # 10hz - self.has_global_pos = False - - def tearDown(self): - pass - - # - # General callback functions used in tests - # - def global_position_callback(self, data): - self.has_global_pos = True - - def test_method(self): - """Test method description""" - - # FIXME: hack to wait for simulation to be ready - while not self.has_global_pos: - self.rate.sleep() - - # TODO: execute test - - if __name__ == '__main__': - import rostest - rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) - ``` + ```python + #!/usr/bin/env python + # [... LICENSE ...] + + # + # @author Example Author + # + PKG = 'px4' + + import unittest + import rospy + import rosbag + + from sensor_msgs.msg import NavSatFix + + class MavrosNewTest(unittest.TestCase): + """ + Test description + """ + + def setUp(self): + rospy.init_node('test_node', anonymous=True) + rospy.wait_for_service('mavros/cmd/arming', 30) + + rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) + self.rate = rospy.Rate(10) # 10hz + self.has_global_pos = False + + def tearDown(self): + pass + + # + # General callback functions used in tests + # + def global_position_callback(self, data): + self.has_global_pos = True + + def test_method(self): + """Test method description""" + + # FIXME: hack to wait for simulation to be ready + while not self.has_global_pos: + self.rate.sleep() + + # TODO: execute test + + if __name__ == '__main__': + import rostest + rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) + ``` 2. Run the new test only - Start the simulator: - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - roslaunch launch/mavros_posix_sitl.launch - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + roslaunch launch/mavros_posix_sitl.launch + ``` - Run test (in a new shell): - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - rosrun px4 mavros_new_test.py - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + rosrun px4 mavros_new_test.py + ``` 3. Add new test node to a launch file - In `test/` create a new `.test` ROS launch file. @@ -145,9 +145,9 @@ To write a new test: Наприклад: - ```sh - tests_: rostest - @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test - ``` + ```sh + tests_: rostest + @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test + ``` Run the tests as described above. diff --git a/docs/uk/test_and_ci/test_flights.md b/docs/uk/test_and_ci/test_flights.md index 3bfc25e517..103549e361 100644 --- a/docs/uk/test_and_ci/test_flights.md +++ b/docs/uk/test_and_ci/test_flights.md @@ -28,3 +28,7 @@ When submitting [Pull Requests](../contribute/code.md#pull-requests) for new fun - [MC_04 - Failsafe Testing](../test_cards/mc_04_failsafe_testing.md) - [MC_05 - Indoor Flight (Manual Modes)](../test_cards/mc_05_indoor_flight_manual_modes.md) - [MC_06 - Indoor Flight (Optical Flow)](../test_cards/mc_06_optical_flow.md) +- [MC_07 - Optical Flow Low Mount](../test_cards/mc_07_optical_flow_low_mount.md) +- [MC_08 - DSHOT ESC](../test_cards/mc_08_dshot.md) +- [MC_09 - VIO (Visual-Inertial Odometry)](../test_cards/mc_09_vio.md) +- [MC_10 - Optical Flow / GPS Mixed](../test_cards/mc_10_optical_flow_gps_mixed.md) diff --git a/docs/uk/test_and_ci/unit_tests.md b/docs/uk/test_and_ci/unit_tests.md index e06d7f0b8a..f72444d986 100644 --- a/docs/uk/test_and_ci/unit_tests.md +++ b/docs/uk/test_and_ci/unit_tests.md @@ -126,34 +126,34 @@ It can be run directly in a debugger, however be careful to only run one test pe 10. Within [tests_main.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.h) define the new test: - ```cpp - extern int test_[description](int argc, char *argv[]); - ``` + ```cpp + extern int test_[description](int argc, char *argv[]); + ``` 11. Within [tests_main.c](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.c) add description name, test function and option: - ```cpp - ... - } tests[] = { - {... - {"[description]", test_[description], OPTION}, - ... - } - ``` + ```cpp + ... + } tests[] = { + {... + {"[description]", test_[description], OPTION}, + ... + } + ``` - `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: + `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: - ```sh - pxh> tests all - ``` + ```sh + pxh> tests all + ``` - або + або - ```sh - pxh> tests jig - ``` + ```sh + pxh> tests jig + ``` - If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. + If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. 12. Add the test `test_[description].cpp` to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/CMakeLists.txt). diff --git a/docs/uk/test_cards/mc_04_failsafe_testing.md b/docs/uk/test_cards/mc_04_failsafe_testing.md index d22a331772..e21b52750b 100644 --- a/docs/uk/test_cards/mc_04_failsafe_testing.md +++ b/docs/uk/test_cards/mc_04_failsafe_testing.md @@ -9,10 +9,10 @@ Test RC loss, data link loss, and low battery failsafes. - Verify RC Loss action is Return to Land - Verify Data Link Loss action is Return to Land and the timeout is 10 seconds - Verify Battery failsafe - - Action is Return to Land - - Battery Warn Level is 25% - - Battery Failsafe Level is 20% - - Battery Emergency Level is 15% + - Action is Return to Land + - Battery Warn Level is 25% + - Battery Failsafe Level is 20% + - Battery Emergency Level is 15% ## Flight Tests diff --git a/docs/uk/test_cards/mc_06_optical_flow.md b/docs/uk/test_cards/mc_06_optical_flow.md index 410c1a4674..3ade1bd015 100644 --- a/docs/uk/test_cards/mc_06_optical_flow.md +++ b/docs/uk/test_cards/mc_06_optical_flow.md @@ -2,17 +2,23 @@ ## Objective -To test that optical flow / external vision work as expected +Test that optical flow works as expected ## Preflight -Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation ([setup information here](../sensor/optical_flow.md)) -Ensure that the drone can go into Altitude / Position flight mode while still on the ground +Ensure there are no other sources of positioning besides optical flow: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into Altitude / Position mode while still on the ground ## Flight Tests -❏ Altitude flight mode +❏ [Altitude mode](../flight_modes_mc/altitude.md)     ❏ Vertical position should hold current value with stick centered @@ -20,7 +26,7 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Throttle response set to climb/descent rate -❏ Position flight mode +❏ [Position mode](../flight_modes_mc/position.md)     ❏ Horizontal position should hold current value with stick centered @@ -30,6 +36,16 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates +❏ Varying height terrain + +    ❏ Put boxes on the ground to create varying heights in terrain + +    ❏ Take off in position mode and fly over the boxes such that the downward facing rangefinder varies in value + +    ❏ Do a few passes with varying amounts of time over the boxes (1-30 seconds if possible) + +    ❏ Drone should not raise in height when flying over boxes + ## Посадка ❏ Land in either Position or Altitude mode with the throttle below 40% @@ -39,5 +55,8 @@ Ensure that the drone can go into Altitude / Position flight mode while still on ## Очікувані результати - Зліт повинен бути плавним, коли газ піднято +- Drone should hold altitude in Altitude mode without wandering (over surface with many features) +- Drone should hold position within 1 meter in Position mode without pilot moving sticks - Немає коливання в жодному з перерахованих режимів польоту +- Drone should not raise in height when flying over boxes - Після посадки, коптер не повинен підскакувати на землі diff --git a/docs/uk/test_cards/mc_07_optical_flow_low_mount.md b/docs/uk/test_cards/mc_07_optical_flow_low_mount.md new file mode 100644 index 0000000000..1679a2c8d4 --- /dev/null +++ b/docs/uk/test_cards/mc_07_optical_flow_low_mount.md @@ -0,0 +1,45 @@ +# Test MC_07 - Optical Flow Low Sensor + +## Objective + +Test that optical flow works as expected with a low mounted optical flow sensor + +## Preflight + +Ensure that the drone's optical flow sensor is mounted more than an inch off of the ground + +Ensure that [MPC_THR_MIN](../advanced_config/parameter_reference.md#MPC_THR_MIN) is tuned correctly for landing + +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +([Setup Information here](../sensor/optical_flow.md)) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into [Position mode](../flight_modes_mc/position.md) while still on the ground + +## Flight Tests + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Посадка + +❏ Land in Position mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Очікувані результати + +- Зліт повинен бути плавним, коли газ піднято +- Drone should stay in Position mode, NOT fall into [altitude](../flight_modes_mc/altitude.md) mode diff --git a/docs/uk/test_cards/mc_07_vio.md b/docs/uk/test_cards/mc_07_vio.md new file mode 100644 index 0000000000..a6fea1b762 --- /dev/null +++ b/docs/uk/test_cards/mc_07_vio.md @@ -0,0 +1,52 @@ +# Test MC_07 - VIO (Visual-Inertial Odometry) + +## Objective + +To test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into Altitude / Position flight mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ Altitude flight mode + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ Position flight mode + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Посадка + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Очікувані результати + +- Зліт повинен бути плавним, коли газ піднято +- Drone should hold altitude in Altitude Flight mode without wandering +- Drone should hold position within 1 meter in Position Flight mode without pilot moving sticks +- Немає коливання в жодному з перерахованих режимів польоту +- Після посадки, коптер не повинен підскакувати на землі diff --git a/docs/uk/test_cards/mc_08_dshot.md b/docs/uk/test_cards/mc_08_dshot.md new file mode 100644 index 0000000000..148534cae8 --- /dev/null +++ b/docs/uk/test_cards/mc_08_dshot.md @@ -0,0 +1,46 @@ +# Test MC_08 - DSHOT ESC + +## Objective + +Regression test for DSHOT working with PX4 + +## Preflight + +- Ensure vehicle is using a DSHOT ESC +- Parameter [DSHOT_BIDIR_EN](../advanced_config/parameter_reference.md#DSHOT_BIDIR_EN) is enabled +- Parameter [DSHOT_TEL_CFG](../advanced_config/parameter_reference.md#DSHOT_TEL_CFG) is configured (if ESC supports telemetry) +- Parameter [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) has Debug (`5`) checked + +## Flight Tests + +❏ [Stabilized mode](../flight_modes_mc/manual_stabilized.md) + +    ❏ Takeoff in stabilized mode to ensure correct motor spin + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response 1:1 + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Посадка + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Очікувані результати + +- Download flight logs +- Load into Data Plot Juggler +- Ensure data is logged for `esc_status`/`esc.0x`/`esc_rpm` + + ![Reference frames](../../assets/test_cards/dshot_log_output.png) diff --git a/docs/uk/test_cards/mc_09_vio.md b/docs/uk/test_cards/mc_09_vio.md new file mode 100644 index 0000000000..29ab4a0253 --- /dev/null +++ b/docs/uk/test_cards/mc_09_vio.md @@ -0,0 +1,52 @@ +# Test MC_09 - VIO (Visual-Inertial Odometry) + +## Objective + +Test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## Посадка + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## Очікувані результати + +- Зліт повинен бути плавним, коли газ піднято +- Drone should hold altitude in Altitude mode without wandering +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- Немає коливання в жодному з перерахованих режимів польоту +- Після посадки, коптер не повинен підскакувати на землі diff --git a/docs/uk/test_cards/mc_10_optical_flow_gps_mixed.md b/docs/uk/test_cards/mc_10_optical_flow_gps_mixed.md new file mode 100644 index 0000000000..a1a165e322 --- /dev/null +++ b/docs/uk/test_cards/mc_10_optical_flow_gps_mixed.md @@ -0,0 +1,74 @@ +# Test MC_10 - Optical Flow / GPS Mixed + +## Objective + +Test that optical flow mixed with GPS works as expected + +## Preflight + +[Setup optical flow and GPS](../sensor/optical_flow.md) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `7` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `1` +- [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF): `1` (GPS) + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +❏ GPS Cutout + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Open QGC and navigate to MAVLink Console + +    ❏ Type `gps off` to disable GPS + +    ❏ Drone should maintain position hold via optical flow + +❏ GPS Degredation + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Fly under a metal surface (or other GPS blocking structure) + +    ❏ Ensure drone does not lose position hold or start drifting + +    ❏ Fly out of metal structure to regain GPS + +❏ GPS Acquisition + +    ❏ Takeoff in position mode in non-GPS environment + +    ❏ Fly into a GPS rich environment (outdoors) + +    ❏ Ensure drone acquires GPS position + +## Очікувані результати + +- Зліт повинен бути плавним, коли газ піднято +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- Drone should hold position in GPS rich environment as well as non-GPS environment +- Немає коливання в жодному з перерахованих режимів польоту diff --git a/docs/uk/uart/user_configurable_serial_driver.md b/docs/uk/uart/user_configurable_serial_driver.md index 812f3561b0..4164dfbf84 100644 --- a/docs/uk/uart/user_configurable_serial_driver.md +++ b/docs/uk/uart/user_configurable_serial_driver.md @@ -26,33 +26,33 @@ 1. Створіть конфігураційний файл модуля YAML: - - Add a new file in the driver's source directory named **module.yaml** - - Вставте наступний текст і підлаштуйте за потреби: + - Add a new file in the driver's source directory named **module.yaml** + - Вставте наступний текст і підлаштуйте за потреби: - ```cmake - module_name: uLanding Radar - serial_config: - - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} - port_config_param: - name: SENS_ULAND_CFG - group: Sensors - ``` + ```cmake + module_name: uLanding Radar + serial_config: + - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} + port_config_param: + name: SENS_ULAND_CFG + group: Sensors + ``` - ::: info - The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. - Це також використовується для перевірки всіх файлів конфігурації в CI. + ::: info + The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. + Це також використовується для перевірки всіх файлів конфігурації в CI. ::: 2. Add the module configuration to the **CMakeLists.txt** file for the driver module: - ```cmake - px4_add_module( - MODULE drivers__ulanding - MAIN ulanding_radar - SRCS - ulanding.cpp - MODULE_CONFIG - module.yaml - ) - ``` + ```cmake + px4_add_module( + MODULE drivers__ulanding + MAIN ulanding_radar + SRCS + ulanding.cpp + MODULE_CONFIG + module.yaml + ) + ``` diff --git a/docs/uk/uorb/uorb_documentation.md b/docs/uk/uorb/uorb_documentation.md new file mode 100644 index 0000000000..ce802342b4 --- /dev/null +++ b/docs/uk/uorb/uorb_documentation.md @@ -0,0 +1,170 @@ +# uORB Documentation Standard + +This topic demonstrates and explains how to document uORB messages. + +:::info +At time of writing many topics have not been updated. +::: + +## Загальний огляд + +The [AirspeedValidated](../msg_docs/AirspeedValidated.md) message shown below is a good example of a uORB topic that has been documented to the current standard. + +```py +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + +uint32 MESSAGE_VERSION = 1 + +uint64 timestamp # [us] Time since system start + +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) + +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed + +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch +``` + +The main things to note are: + +- Documentation is added using formatted uORB comments. + Any text on a line after the `#` character is a comment, except for lines that start with the text `# TOPIC` (which indicates a multi-topic message). +- The message starts with a comment block consisting of short description (mandatory), followed by a longer description and then a space. +- Field and constants almost all have comments. + The comments are added on the same line as the field/constant, separated by one space. +- Fields: + - Comments are all on the same line as the field (extra lines become internal comments). + - Comments start with metadata, such as the units (`[m/s]`, `[rad/s]`) or allowed values (`[@enum SOURCE]`), and can also list invalid values (`[@invalid NaN]`) and allowed ranges (`[@range min, max]`). + - Units are required except for boolean fields or for fields with an enum value. + `[-]` is used to indicate unitless fields. + - Comments follow the metadata after a space. + The line should not be terminated in a full stop. +- Constants: + - Don't have metadata: the description follows the comment marker after one space. + - Some constants, such as `MESSAGE_VERSION`, don't need documentation because they are standardized. + - Constants with the same name prefix are grouped together as enums after the associated field. + +The following sections expand on the allowed formats. + +## Message Description + +Every message should start with a comment block that describes the message: + +```py +# Short description (mandatory) +# +# Longer description for the message if needed. +# Can be multiline, and should have punctuation. +# Should be followed by an empty line. +``` + +This consists of a mandatory short description, optionally followed by an empty comment line, and then a longer description. + +Short description (mandatory): + +- A succinct explanation for the purpose of the message. +- Usually just one line without a terminating full stop. +- Minimally it may just mirror the message name. +- For example, [`AirspeedValidated`](../msg_docs/AirspeedValidated.md) above has the short description `Validated airspeed`. + +Long description (Optional): + +- Additional context required to understand how the message is used. +- In particular this should be anything that can't be inferred from the name, fields or constants, such as the publishers and expected consumers. + It might also cover whether the message is only used for a particular frame type or mode. +- The message is often multiline and contains punctuation. +- May include comment lines that are empty, in order to indicate paragraphs. + +Both short and long descriptions may be multi-line. +Single line descriptions should not include a terminating full stop, but multiline comments should do so. + +The message description block ends at the first non-comment line, which should be an empty line, but might be a field or constant. +Any subsequent comment lines are considered "internal comments". + +### Fields + +A typical field comment looks like this: + +```py +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +``` + +Field comments must all be on the same line as the field, and consist of optional metadata followed by a description: + +- `metadata` (Optional) + - Information about the field units and allowed values: + - `[]` + - The unit of measurement inside square brackets (note, no `@` delineator indicates a unit), such as `[m]` for metres. + - Allowed units include: `m`, `m/s`, `m/s^2`, `rad`, `rad/s`, `rpm`, `V`, `A`, `mA`, `mAh`, `W`, `dBm`, `s`, `ms`, `us`, `Ohm`, `MB`, `Kb/s`, `degC`, `Pa`. + - Units are required unless clearly invalid, such as when the field is a boolean, or is an enum value. + - Unitless values should be specified as `[-]`. + Note though that units are not required for boolean fields or enum fields. + - `[@enum ]` + - The `enum_name` gives the prefix of constant values in the message that can be assigned to the field. + Note that enums in uORB are just a naming convention: they are not explicitly declared. + Multiple enum names allowed for a field indicates a possible error in the field design. + - `[@range , ]` + - The allowed range of the field, specified as a `lower_value` and/or an `upper_value`. + Either value can be omitted to indicate an unbounded upper or lower value. + For example `[@range 0, 3]`, `[@range 5.3, ]`, `[@range , 3]`. + - `[@invalid ]` + - The `value` to set the field to indicate that the field doesn't contain valid data, such as `[@invalid NaN]`. + The `description` is optional, and might be used to indicate the conditions under which data is invalid. + - `[@frame ]` + - The `frame` in which the field is set, such as `[@frame NED]` or `[@frame Body]`. +- `description` + - A concise description of the purpose of the field, and including any important information that can't be inferred from the name! + Use a capital first letter, and omit the full stop if the description is a single sentence. + Multiple sentences may also omit the final full stop. + +### Constants + +Constants follow the documentation conventions as fields except they only have a description (no metadata). +Documentation for a constant might look like this: + +```py +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +``` + +Constants are often grouped together following a field as enum values. +Note below how the prefix `SOURCE` for the values is specified as an enum against the _field_. + +```py +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +... +``` + +A small number of constants have a standardised meaning and do not require documentation. +These are: + +- `ORB_QUEUE_LENGTH` +- `MESSAGE_VERSION` + +### `# TOPICS` + +The prefix `# TOPICS` is used to indicate topic names for multi-topic messages. +For example, the [VehicleGlobalPosition.msg](../msg_docs/VehicleGlobalPosition.md) message definition is used to define the topic ids as shown: + +```text +# TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position +# TOPICS estimator_global_position +# TOPICS aux_global_position +``` + +At time of writing there is no format for documenting these. diff --git a/docs/uk/vtx/index.md b/docs/uk/vtx/index.md new file mode 100644 index 0000000000..8206293080 --- /dev/null +++ b/docs/uk/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## Початок роботи + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Параметри: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Налаштування параметрів + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). diff --git a/docs/yarn.lock b/docs/yarn.lock index 28f60812e2..dfc5867a57 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1205,9 +1205,9 @@ mathjax-full@^3.2.0: speech-rule-engine "^4.0.6" mdast-util-to-hast@^13.0.0: - version "13.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" - integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + version "13.2.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz#d7ff84ca499a57e2c060ae67548ad950e689a053" + integrity sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA== dependencies: "@types/hast" "^3.0.0" "@types/mdast" "^4.0.0" @@ -1398,6 +1398,11 @@ preact@^10.0.0: resolved "https://registry.yarnpkg.com/preact/-/preact-10.26.9.tgz#b3898d1b65140640799062ad73b89846c293b6a7" integrity sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA== +prettier@^3.2.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.8.1.tgz#edf48977cf991558f4fcbd8a3ba6015ba2a3a173" + integrity sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg== + pretty-ms@^9.2.0: version "9.2.0" resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.2.0.tgz#e14c0aad6493b69ed63114442a84133d7e560ef0" @@ -1643,9 +1648,9 @@ vfile@^6.0.0: vfile-message "^4.0.0" vite@^5.4.14: - version "5.4.19" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.19.tgz#20efd060410044b3ed555049418a5e7d1998f959" - integrity sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA== + version "5.4.21" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.21.tgz#84a4f7c5d860b071676d39ba513c0d598fdc7027" + integrity sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw== dependencies: esbuild "^0.21.3" postcss "^8.4.43" diff --git a/docs/zh/SUMMARY.md b/docs/zh/SUMMARY.md index 13288443e8..ad7cdcd297 100644 --- a/docs/zh/SUMMARY.md +++ b/docs/zh/SUMMARY.md @@ -1,40 +1,41 @@ -- [Introduction](index.md) +- [概述](index.md) - [基本概念](getting_started/px4_basic_concepts.md) - [多旋翼](frames_multicopter/index.md) - - [Features](features_mc/index.md) + - [特征](features_mc/index.md) - [飞行模式](flight_modes_mc/index.md) - [位置模式(多旋翼)](flight_modes_mc/position.md) - - [Position Slow Mode (MC)](flight_modes_mc/position_slow.md) + - [低速的位置模式(多旋翼)](flight_modes_mc/position_slow.md) - [高度模式(多旋翼)](flight_modes_mc/altitude.md) - - [Stabilized Mode (MC)](flight_modes_mc/manual_stabilized.md) + - [定高模式(多旋翼)](flight_modes_mc/altitude_cruise.md) + - [姿态稳定模式/新手模式(多旋翼)](flight_modes_mc/manual_stabilized.md) - [特技模式(多旋翼)](flight_modes_mc/acro.md) - [环绕模式(多旋翼)](flight_modes_mc/orbit.md) - - [Takeoff Mode (MC)](flight_modes_mc/takeoff.md) - - [Land Mode (MC)](flight_modes_mc/land.md) - - [Hold Mode (MC)](flight_modes_mc/hold.md) - - [Follow Me Mode (MC)](flight_modes_mc/follow_me.md) - - [Mission Mode (MC)](flight_modes_mc/mission.md) - - [Return Mode (MC)](flight_modes_mc/return.md) - - [Offboard Mode (MC)](flight_modes_mc/offboard.md) - - [Collision Prevention](computer_vision/collision_prevention.md) + - [自动起飞模式(多旋翼)](flight_modes_mc/takeoff.md) + - [自动降落模式(多旋翼)](flight_modes_mc/land.md) + - [定点模式(多旋翼)](flight_modes_mc/hold.md) + - [跟随模式(多旋翼)](flight_modes_mc/follow_me.md) + - [自主任务模式 (多旋翼)](flight_modes_mc/mission.md) + - [返航模式(多旋翼)](flight_modes_mc/return.md) + - [外部控制模式(多旋翼)](flight_modes_mc/offboard.md) + - [碰撞预防](computer_vision/collision_prevention.md) - [地形跟随/保持](flying/terrain_following_holding.md) - - [Terrain Following/Holding](flying/terrain_following_holding.md) - - [Throw Launch](flight_modes_mc/throw_launch.md) + - [地形跟随/保持](flying/terrain_following_holding.md) + - [抛飞启动](flight_modes_mc/throw_launch.md) - [Assembly](assembly/assembly_mc.md) - - [Configuration/Tuning](config_mc/index.md) - - [Auto-tune](config/autotune_mc.md) - - [Filter/Control Latency Tuning](config_mc/filter_tuning.md) - - [PID Tuning (Manual/Basic)](config_mc/pid_tuning_guide_multicopter_basic.md) - - [PID Tuning Guide (Manual/Advanced)](config_mc/pid_tuning_guide_multicopter.md) - - [Setpoint Tuning (Trajectory Generator)](config_mc/mc_trajectory_tuning.md) - - [Jerk-limited Type Trajectory](config_mc/mc_jerk_limited_type_trajectory.md) - - [Racer Setup](config_mc/racer_setup.md) + - [配置/调参](config_mc/index.md) + - [自动调优](config/autotune_mc.md) + - [滤波/控制延迟调整](config_mc/filter_tuning.md) + - [PID配置(手动/基本)](config_mc/pid_tuning_guide_multicopter_basic.md) + - [PID配置引导(手动/基本)](config_mc/pid_tuning_guide_multicopter.md) + - [定点配置 (轨迹生成)](config_mc/mc_trajectory_tuning.md) + - [限速型轨迹](config_mc/mc_jerk_limited_type_trajectory.md) + - [竞速设置](config_mc/racer_setup.md) - [着陆探测器配置](advanced_config/land_detector.md) - [静态压力生成](advanced_config/static_pressure_buildup.md) - - [Flying (Basics)](flying/basic_flying_mc.md) + - [飞行(基本)](flying/basic_flying_mc.md) - [整机](complete_vehicles_mc/index.md) - - [ModalAI Starling (PX4 Dev Kit)](complete_vehicles_mc/modalai_starling.md) + - [多场景AI无人机——ModalAI Starling](complete_vehicles_mc/modalai_starling.md) - [PX4 视觉套件](complete_vehicles_mc/px4_vision_kit.md) - [MindRacer BNF & RTF](complete_vehicles_mc/mindracer_BNF_RTF.md) - [MindRacer 210](complete_vehicles_mc/mindracer210.md) @@ -48,18 +49,21 @@ - [X500 (Pixhawk 4)](frames_multicopter/holybro_x500_pixhawk4.md) - [S500 V2 (Pixhawk 4)](frames_multicopter/holybro_s500_v2_pixhawk4.md) - [Lumenier QAV-R 5" Racer (Pixracer)](frames_multicopter/qav_r_5_kiss_esc_racer.md) - - [QAV250 (Pixhawk4 Mini) - Discontinued](frames_multicopter/holybro_qav250_pixhawk4_mini.md) + - [QAV250 (Pixhawk4 Mini) - 停产](frames_multicopter/holybro_qav250_pixhawk4_mini.md) - [DIY Builds](frames_multicopter/diy_builds.md) - [Omnicopter](frames_multicopter/omnicopter.md) - [DJI F450 (CUAV v5+)](frames_multicopter/dji_f450_cuav_5plus.md) - [DJI F450 (CUAV v5 nano)](frames_multicopter/dji_f450_cuav_5nano.md) -- [Planes (Fixed-Wing)](frames_plane/index.md) +- [飞机(固定翼)](frames_plane/index.md) + - [特性](features_fw/index.md) + - [Gain compression](features_fw/gain_compression.md) - [Assembly](assembly/assembly_fw.md) - - [Config/Tuning](config_fw/index.md) - - [Auto-tune](config/autotune_fw.md) + - [配置/调参](config_fw/index.md) + - [自动调优](config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](flying/basic_flying_fw.md) @@ -89,6 +93,7 @@ - [VTOL后转换调参](config_vtol/vtol_back_transition_tuning.md) - [没有空速传感器的VTOL ](config_vtol/vtol_without_airspeed_sensor.md) - [垂直起降风向仪](config_vtol/vtol_weathervane.md) + - [VTOL Ice Shedding](config_vtol/vtol_ice_shedding.md) - [飞行模式](flight_modes_vtol/index.md) - [Mission Mode (VTOL)](flight_modes_vtol/mission.md) - [Return Mode (VTOL)](flight_modes_vtol/return.md) @@ -124,6 +129,7 @@ - [LED灯含义](getting_started/led_meanings.md) - [声调/声音含义](getting_started/tunes.md) - [QGroundControl Flight-Readiness Status](flying/pre_flight_checks.md) + - [Asset Tracking](debug/asset_tracking.md) - [Hardware Selection & Setup](hardware/drone_parts.md) - [飞行控制器(Autopilots)](flight_controller/index.md) @@ -157,6 +163,7 @@ - [mRo (3DR) Pixhawk Wiring Quickstart](assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](flight_controller/mindpx.md) - [AirMind MindRacer](flight_controller/mindracer.md) - [ARK Electronics ARKV6X](flight_controller/ark_v6x.md) @@ -180,12 +187,16 @@ - [Wiring Quickstart](assembly/quick_start_durandal.md) - [Holybro Pix32 v5](flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](assembly/quick_start_holybro_pix32_v5.md) + - [MicoAir H743 Lite](flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](flight_controller/modalai_voxl_2.md) - [mRo Control Zero F7](flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](flight_controller/spracingh7extreme.md) + - [SVehicle E2](flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](flight_controller/thepeach_r1.md) + - [AP-H743-R1](flight_controller/x-mav_ap-h743r1.md) - [Experimental Autopilots](flight_controller/autopilot_experimental.md) - [BeagleBone Blue](flight_controller/beaglebone_blue.md) - [Raspberry Pi 2/3 Navio2](flight_controller/raspberry_pi_navio2.md) @@ -238,18 +249,22 @@ - [TFSlot Airspeed Sensor](sensor/airspeed_tfslot.md) - [Barometers](sensor/barometer.md) - [距离传感器 \(测距仪\)](sensor/rangefinders.md) + - [Ainstein US-D1 标准雷达高度计](sensor/ulanding_radar.md) + - [ARK DIST SR (CAN/UART)](dronecan/ark_dist.md) + - [ARK DIST MR (CAN/UART)](dronecan/ark_dist_mr.md) + - [北醒 TFmini 激光雷达](sensor/tfmini.md) + - [LeddarOne 激光雷达](sensor/leddar_one.md) + - [Lidar-Lite](sensor/lidar_lite.md) - [Lightware Lidars (SF/LW)](sensor/sfxx_lidar.md) - [Lightware SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md) - - [Ainstein US-D1 标准雷达高度计](sensor/ulanding_radar.md) - - [LeddarOne 激光雷达](sensor/leddar_one.md) - - [北醒 TFmini 激光雷达](sensor/tfmini.md) - - [Lidar-Lite](sensor/lidar_lite.md) - [TeraRanger](sensor/teraranger.md) - [✘ Lanbao PSK-CM8JL65-CC5](sensor/cm8jl65_ir_distance_sensor.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface (CAN)](dronecan/avanon_laser_interface.md) - [GNSS (GPS)](gps_compass/index.md) - [ARK GPS (CAN)](dronecan/ark_gps.md) + - [ARK DAN GPS](gps_compass/ark_dan_gps.md) - [ARK SAM GPS](gps_compass/ark_sam_gps.md) + - [ARK SAM GPS MINI](gps_compass/ark_sam_gps_mini.md) - [ARK TESEO GPS](dronecan/ark_teseo_gps.md) - [CUAV NEO 3 GPS](gps_compass/gps_cuav_neo_3.md) - [CUAV NEO 3 Pro GPS (CAN)](gps_compass/gps_cuav_neo_3pro.md) @@ -260,7 +275,11 @@ - [Holybro M8N & M9N GPS](gps_compass/gps_holybro_m8n_m9n.md) - [Sky-Drones SmartAP GPS](gps_compass/gps_smartap.md) - [RTK GNSS](gps_compass/rtk_gps.md) + - [ARK G5 RTK GPS](dronecan/ark_g5_rtk_gps.md) + - [ARK G5 RTK HEADING GPS](dronecan/ark_g5_rtk_heading_gps.md) - [ARK RTK GPS (CAN)](dronecan/ark_rtk_gps.md) + - [ARK RTK GPS L1 L5 (CAN)](dronecan/ark_rtk_gps_l1_l2.md) + - [ARK X20 RTK GPS (CAN)](dronecan/ark_x20_rtk_gps.md) - [ARK MOSAIC-X5 RTK GPS (CAN)](dronecan/ark_mosaic__rtk_gps.md) - [RTK GPS Heading with Dual u-blox F9P](gps_compass/u-blox_f9p_heading.md) - [CUAV C-RTK](gps_compass/rtk_gps_cuav_c-rtk.md) @@ -283,6 +302,8 @@ - [CubePilot Here+ (Discontined)](gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](sensor/inertial_navigation_systems.md) - [InertialLabs](sensor/inertiallabs.md) + - [MicroStrain](sensor/microstrain.md) + - [sbgECom](sensor/sbgecom.md) - [VectorNav](sensor/vectornav.md) - [光流](sensor/optical_flow.md) - [ARK 光流](dronecan/ark_flow.md) @@ -298,15 +319,17 @@ - [ADSB/FLARM (空中防撞)](config/actuators.md) - [电调(ESC)校准](advanced_config/esc_calibration.md) - [电调 & 电机](peripherals/esc_motors.md) + - [ESC Protocols](esc/esc_protocols.md) - [PWM 电调和伺服系统](peripherals/pwm_escs_and_servo.md) - [DShot 电调](peripherals/dshot.md) - [OneShot 电调和伺服系统](peripherals/oneshot.md) - [DroneCAN ESCs](dronecan/escs.md) - - [Zubax Telega](dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](dronecan/sapog.md) - - [Holybro Kotleta](dronecan/holybro_kotleta.md) - - [Vertiq](peripherals/vertiq.md) - - [VESC](peripherals/vesc.md) + - [ARK 4IN1 ESC](esc/ark_4in1_esc.md) + - [Holybro Kotleta](dronecan/holybro_kotleta.md) + - [Vertiq Motor/ESC Modules](peripherals/vertiq.md) + - [VESC Project ESCs](peripherals/vesc.md) + - [Zubax Telega ESCs](dronecan/zubax_telega.md) - [Radio Control (RC)](getting_started/rc_transmitter_receiver.md) - [无线电系统设置](config/radio.md) @@ -339,17 +362,20 @@ - [Satellite Comms (Iridium/RockBlock)](advanced_features/satcom_roadblock.md) + - [Analog Video Transmitters](vtx/index.md) + - [Power Systems](power_systems/index.md) - [Battery Estimation Tuning](config/battery.md) - [Battery Chemistry Overview](power_systems/battery_chemistry.md) - [Power Modules/PDB](power_module/index.md) + - [ARK PAB Power Module](power_module/ark_pab_power_module.md) + - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](power_module/ark_12s_payload_power_module.md) - [雷迅 HV pm](power_module/cuav_hv_pm.md) - [雷迅 CAN PMU](dronecan/cuav_can_pmu.md) - [Holybro PM02](power_module/holybro_pm02.md) - [Holybro PM07](power_module/holybro_pm07_pixhawk4_power_module.md) - [Holybro PM06 V2](power_module/holybro_pm06_pixhawk4mini_power_module.md) - - [ARK PAB Power Module](power_module/ark_pab_power_module.md) - - [ARK 12S PAB Power Module](power_module/ark_12s_pab_power_module.md) - [Holybro PM02D (digital)](power_module/holybro_pm02d.md) - [Holybro PM03D (digital)](power_module/holybro_pm03d.md) - [Pomegranate Systems Power Module](dronecan/pomegranate_systems_pm.md) @@ -432,6 +458,7 @@ - [Attitude Tuning](config_rover/attitude_tuning.md) - [Velocity Tuning](config_rover/velocity_tuning.md) - [Position Tuning](config_rover/position_tuning.md) + - [Apps & API](flight_modes_rover/api.md) - [Complete Vehicles](complete_vehicles_rover/index.md) - [Aion Robotics R1](complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](frames_sub/index.md) @@ -497,8 +524,10 @@ - [UART/串口](uart/index.md) - [可配置的串口驱动](uart/user_configurable_serial_driver.md) - [RTK GPS (集成)](advanced/rtk_gps.md) + - [PPS Time Synchronization](advanced/pps_time_sync.md) - [中间件](middleware/index.md) - [uORB 通讯](middleware/uorb.md) + - [uORB Docs Standard](uorb/uorb_documentation.md) - [uORB 图](middleware/uorb_graph.md) - [uORB 消息参考](msg_docs/index.md) - [Versioned](msg_docs/versioned_messages.md) @@ -561,6 +590,7 @@ - [DebugKeyValue](msg_docs/DebugKeyValue.md) - [DebugValue](msg_docs/DebugValue.md) - [DebugVect](msg_docs/DebugVect.md) + - [DeviceInformation](msg_docs/DeviceInformation.md) - [DifferentialPressure](msg_docs/DifferentialPressure.md) - [DistanceSensor](msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](msg_docs/DistanceSensorModeChangeRequest.md) @@ -593,6 +623,7 @@ - [FollowTargetEstimator](msg_docs/FollowTargetEstimator.md) - [FollowTargetStatus](msg_docs/FollowTargetStatus.md) - [FuelTankStatus](msg_docs/FuelTankStatus.md) + - [GainCompression](msg_docs/GainCompression.md) - [GeneratorStatus](msg_docs/GeneratorStatus.md) - [GeofenceResult](msg_docs/GeofenceResult.md) - [GeofenceStatus](msg_docs/GeofenceStatus.md) @@ -679,10 +710,10 @@ - [RoverPositionSetpoint](msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](msg_docs/RoverVelocityStatus.md) - [Rpm](msg_docs/Rpm.md) - [RtlStatus](msg_docs/RtlStatus.md) - [RtlTimeEstimate](msg_docs/RtlTimeEstimate.md) @@ -694,6 +725,7 @@ - [SensorCombined](msg_docs/SensorCombined.md) - [SensorCorrection](msg_docs/SensorCorrection.md) - [SensorGnssRelative](msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](msg_docs/SensorGnssStatus.md) - [SensorGps](msg_docs/SensorGps.md) - [SensorGyro](msg_docs/SensorGyro.md) - [SensorGyroFft](msg_docs/SensorGyroFft.md) @@ -703,6 +735,7 @@ - [SensorOpticalFlow](msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](msg_docs/SensorPreflightMag.md) - [SensorSelection](msg_docs/SensorSelection.md) + - [SensorTemp](msg_docs/SensorTemp.md) - [SensorUwb](msg_docs/SensorUwb.md) - [SensorsStatus](msg_docs/SensorsStatus.md) - [SensorsStatusImu](msg_docs/SensorsStatusImu.md) @@ -739,9 +772,13 @@ - [YawEstimatorStatus](msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](msg_docs/AirspeedValidatedV0.md) - [ArmingCheckReplyV0](msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](msg_docs/ArmingCheckRequestV0.md) - [BatteryStatusV0](msg_docs/BatteryStatusV0.md) + - [ConfigOverridesV0](msg_docs/ConfigOverridesV0.md) - [EventV0](msg_docs/EventV0.md) - [HomePositionV0](msg_docs/HomePositionV0.md) + - [RegisterExtComponentReplyV0](msg_docs/RegisterExtComponentReplyV0.md) + - [RegisterExtComponentRequestV0](msg_docs/RegisterExtComponentRequestV0.md) - [VehicleAttitudeSetpointV0](msg_docs/VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](msg_docs/VehicleStatusV0.md) @@ -754,6 +791,7 @@ - [Standard Modes Protocol](mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](middleware/uxrce_dds.md) - [UORB Bridged to ROS 2](middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](middleware/zenoh.md) - [模块 & 命令](modules/modules_main.md) - [自动调参](modules/modules_autotune.md) - [命令](modules/modules_command.md) @@ -771,6 +809,7 @@ - [Rpm Sensor](modules/modules_driver_rpm_sensor.md) - [Radio Control](modules/modules_driver_radio_control.md) - [Transponder](modules/modules_driver_transponder.md) + - [adc](modules/modules_driver_adc.md) - [估计器](modules/modules_estimator.md) - [仿真](modules/modules_simulation.md) - [系统](modules/modules_system.md) @@ -807,9 +846,11 @@ - [Camera Integration/Architecture](camera/camera_architecture.md) - [机器视觉](advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](tutorials/motion-capture.md) - - [Neural Networks](advanced/neural_networks.md) - - [Neural Network Module Utilities](advanced/nn_module_utilities.md) - - [TensorFlow Lite Micro (TFLM)](advanced/tflm.md) + - [Neural Networks](neural_networks/index.md) + - [MC NN Control Module (Generic)](neural_networks/mc_neural_network_control.md) + - [Neural Network Module Utilities](neural_networks/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](neural_networks/tflm.md) + - [RAPTOR Adaptive RL NN Module](neural_networks/raptor.md) - [安装英特尔 RealSense R200 的驱动程序](advanced/realsense_intel_driver.md) - [切换状态估计器](advanced/switching_state_estimators.md) - [外部模块](advanced/out_of_tree_modules.md) @@ -843,6 +884,10 @@ - [测试 MC_04 -故障安全测试](test_cards/mc_04_failsafe_testing.md) - [Test MC_05 - Manual Modes (Inside)](test_cards/mc_05_indoor_flight_manual_modes.md) - [Test MC_06 - Optical Flow (Inside)](test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](test_cards/mc_10_optical_flow_gps_mixed.md) - [单元测试](test_and_ci/unit_tests.md) - [Fuzz Tests](test_and_ci/fuzz_tests.md) - [持续集成](test_and_ci/continous_integration.md) @@ -863,6 +908,7 @@ - [PX4 ROS 2 Interface Library](ros2/px4_ros2_interface_lib.md) - [Control Interface](ros2/px4_ros2_control_interface.md) - [Navigation Interface](ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](ros/ros1.md) - [ROS/MAVROS安装指南](ros/mavros_installation.md) @@ -887,6 +933,7 @@ - [版本发布](releases/index.md) - [main (alpha)](releases/main.md) + - [1.17 (alpha)](releases/1.17.md) - [1.16 (stable)](releases/1.16.md) - [1.15](releases/1.15.md) - [1.14](releases/1.14.md) diff --git a/docs/zh/_sidebar.md b/docs/zh/_sidebar.md index 6938152abc..29cb23eca6 100644 --- a/docs/zh/_sidebar.md +++ b/docs/zh/_sidebar.md @@ -1,15 +1,14 @@ - [Introduction](/index.md) - - [基本概念](/getting_started/px4_basic_concepts.md) - [多旋翼](/frames_multicopter/index.md) - - [Features](/features_mc/index.md) - [飞行模式](/flight_modes_mc/index.md) - [位置模式(多旋翼)](/flight_modes_mc/position.md) - [Position Slow Mode (MC)](/flight_modes_mc/position_slow.md) - [高度模式(多旋翼)](/flight_modes_mc/altitude.md) + - [Altitude Cruise Mode (MC)](/flight_modes_mc/altitude_cruise.md) - [Stabilized Mode (MC)](/flight_modes_mc/manual_stabilized.md) - [特技模式(多旋翼)](/flight_modes_mc/acro.md) - [环绕模式(多旋翼)](/flight_modes_mc/orbit.md) @@ -37,7 +36,7 @@ - [静态压力生成](/advanced_config/static_pressure_buildup.md) - [Flying (Basics)](/flying/basic_flying_mc.md) - [整机](/complete_vehicles_mc/index.md) - - [ModalAI Starling](/complete_vehicles_mc/modalai_starling.md) + - [ModalAI Starling (PX4 Dev Kit)](/complete_vehicles_mc/modalai_starling.md) - [PX4 视觉套件](/complete_vehicles_mc/px4_vision_kit.md) - [MindRacer BNF & RTF](/complete_vehicles_mc/mindracer_BNF_RTF.md) - [MindRacer 210](/complete_vehicles_mc/mindracer210.md) @@ -58,12 +57,14 @@ - [DJI F450 (CUAV v5 nano)](/frames_multicopter/dji_f450_cuav_5nano.md) - [Planes (Fixed-Wing)](/frames_plane/index.md) - + - [Features](/features_fw/index.md) + - [Gain compression](/features_fw/gain_compression.md) - [Assembly](/assembly/assembly_fw.md) - [Config/Tuning](/config_fw/index.md) - [Auto-tune](/config/autotune_fw.md) - [Rate/Attitude Controller Tuning Guide](/config_fw/pid_tuning_guide_fixedwing.md) - [Altitude/Position Controller Tuning Guide](/config_fw/position_tuning_guide_fixedwing.md) + - [Airspeed Scale Estimate Handling](/config_fw/airspeed_scale_handling.md) - [Weight & Altitude Tuning](/config_fw/weight_and_altitude_tuning.md) - [Trimming Guide](/config_fw/trimming_guide_fixedwing.md) - [Flying (Basics)](/flying/basic_flying_fw.md) @@ -86,7 +87,6 @@ - [Wing Wing Z84 (Pixracer)](/frames_plane/wing_wing_z84.md) - [垂直起降](/frames_vtol/index.md) - - [Assembly](/assembly/assembly_vtol.md) - [垂直起降配置/调试](/config_vtol/index.md) - [Auto-tune](/config/autotune_vtol.md) @@ -111,7 +111,6 @@ - [Complete Vehicles](/complete_vehicles_vtol/index.md) - [Operations](/config/operations.md) - - [安全性](/config/safety_intro.md) - [Safety Configuration (Failsafes)](/config/safety.md) - [Failsafe Simulation](/config/safety_simulation.md) @@ -132,7 +131,6 @@ - [QGroundControl Flight-Readiness Status](/flying/pre_flight_checks.md) - [Hardware Selection & Setup](/hardware/drone_parts.md) - - [飞行控制器(Autopilots)](/flight_controller/index.md) - [Flight Controller Selection](/getting_started/flight_controller_selection.md) - [Pixhawk Series](/flight_controller/pixhawk_series.md) @@ -164,18 +162,18 @@ - [mRo (3DR) Pixhawk Wiring Quickstart](/assembly/quick_start_pixhawk.md) - [Holybro Pixhawk Mini (FMUv3) - Discontinued](/flight_controller/pixhawk_mini.md) - [Manufacturer-Supported Autopilots](/flight_controller/autopilot_manufacturer_supported.md) + - [Accton Godwit GA1](/flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](/flight_controller/mindpx.md) - [AirMind MindRacer](/flight_controller/mindracer.md) - [ARK Electronics ARKV6X](/flight_controller/ark_v6x.md) - [ARK FPV Flight Controller](/flight_controller/ark_fpv.md) - [ARK Pi6X Flow Flight Controller](/flight_controller/ark_pi6x.md) - - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV Nora](/flight_controller/cuav_nora.md) - [CUAV V5+ (FMUv5)](/flight_controller/cuav_v5_plus.md) - [Wiring Quickstart](/assembly/quick_start_cuav_v5_plus.md) - [CUAV V5 nano (FMUv5)](/flight_controller/cuav_v5_nano.md) - [CUAV V5 nano Wiring Quickstart](/assembly/quick_start_cuav_v5_nano.md) - - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) + - [CUAV X25 EVO](/flight_controller/cuav_x25-evo.md) - [CubePilot Cube Orange+ (CubePilot)](/flight_controller/cubepilot_cube_orangeplus.md) - [CubePilot Cube Orange (CubePilot)](/flight_controller/cubepilot_cube_orange.md) - [CubePilot Cube Yellow (CubePilot)](/flight_controller/cubepilot_cube_yellow.md) @@ -188,13 +186,13 @@ - [Wiring Quickstart](/assembly/quick_start_durandal.md) - [Holybro Pix32 v5](/flight_controller/holybro_pix32_v5.md) - [Wiring Quickstart](/assembly/quick_start_holybro_pix32_v5.md) - - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) - - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [MicoAir H743 Lite](/flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](/flight_controller/modalai_voxl_2.md) - - [mRobotics-X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - - [mRo Control Zero F7)](/flight_controller/mro_control_zero_f7.md) + - [mRo Control Zero F7](/flight_controller/mro_control_zero_f7.md) + - [Radiolink PIX6](/flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](/flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](/flight_controller/spracingh7extreme.md) + - [SVehicle E2](/flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](/flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](/flight_controller/thepeach_r1.md) - [Experimental Autopilots](/flight_controller/autopilot_experimental.md) @@ -206,18 +204,20 @@ - [Discontinued Autopilots/Vehicles](/flight_controller/autopilot_discontinued.md) - [Drotek Dropix (FMUv2)](/flight_controller/dropix.md) - [Omnibus F4 SD](/flight_controller/omnibus_f4_sd.md) - - [BetaFPV Beta75X 2S Brushless Whoop](/complete_vehicles_mc/betafpv_beta75x.md) - [Bitcraze Crazyflie 2.0 ](/complete_vehicles_mc/crazyflie2.md) - [Aerotenna OcPoC-Zynq Mini](/flight_controller/ocpoc_zynq.md) + - [CUAV X7](/flight_controller/cuav_x7.md) - [CUAV v5](/flight_controller/cuav_v5.md) + - [CUAV Pixhack v3 (FMUv3)](/flight_controller/pixhack_v3.md) - [Holybro Kakute F7](/flight_controller/kakutef7.md) - [Holybro Pixfalcon](/flight_controller/pixfalcon.md) - [Holybro pix32 (FMUv2)](/flight_controller/holybro_pix32.md) + - [ModalAI Flight Core v1](/flight_controller/modalai_fc_v1.md) + - [ModalAI VOXL Flight](/flight_controller/modalai_voxl_flight.md) + - [mRo X2.1 (FMUv2)](/flight_controller/mro_x2.1.md) - [mRo AUAV-X2](/flight_controller/auav_x2.md) - [NXP RDDRONE-FMUK66 FMU](/flight_controller/nxp_rddrone_fmuk66.md) - [3DR Pixhawk 1](/flight_controller/pixhawk.md) - - [Snapdragon Flight](/flight_controller/snapdragon_flight.md) - - [Intel® Aero RTF Drone](/complete_vehicles_mc/intel_aero.md) - [Pixhawk Autopilot Bus (PAB) & Carriers](/flight_controller/pixhawk_autopilot_bus.md) - [ARK Electronics Pixhawk Autopilot Bus Carrier](/flight_controller/ark_pab.md) - [Mounting the Flight Controller](/assembly/mount_and_orient_controller.md) @@ -229,7 +229,9 @@ - [Bootloader Update](/advanced_config/bootloader_update.md) - [Bootloader Update FMUv6X-RT via USB](/advanced_config/bootloader_update_v6xrt.md) - [Bootloader Flashing onto Betaflight Systems](/advanced_config/bootloader_update_from_betaflight.md) + - [Airframe Selection](/config/airframe.md) + - [传感器](/sensor/index.md) - [加速度计](/sensor/accelerometer.md) - [Calibration](/config/accelerometer.md) @@ -241,6 +243,7 @@ - [指南针动力补偿](/advanced_config/compass_power_compensation.md) - [空速传感器](/sensor/airspeed.md) - [Calibration](/config/airspeed.md) + - [Airspeed Validation](/advanced_config/airspeed_validation.md) - [TFSlot Airspeed Sensor](/sensor/airspeed_tfslot.md) - [Barometers](/sensor/barometer.md) - [距离传感器 \(测距仪\)](/sensor/rangefinders.md) @@ -272,6 +275,7 @@ - [CUAV C-RTK](/gps_compass/rtk_gps_cuav_c-rtk.md) - [CUAV C-RTK2 PPK/RTK GNSS](/gps_compass/rtk_gps_cuav_c-rtk2.md) - [CUAV C-RTK 9Ps](/gps_compass/rtk_gps_cuav_c-rtk-9ps.md) + - [DATAGNSS NANO HRTK GNSS](/gps_compass/rtk_gps_datagnss_nano_hrtk.md) - [DATAGNSS GEM1305 RTK GNSS](/gps_compass/rtk_gps_gem1305.md) - [Femtones MINI2 Receiver](/gps_compass/rtk_gps_fem_mini2.md) - [Freefly RTK GPS](/gps_compass/rtk_gps_freefly.md) @@ -287,6 +291,9 @@ - [Trimble MB-Two](/gps_compass/rtk_gps_trimble_mb_two.md) - [CubePilot Here+ (Discontined)](/gps_compass/rtk_gps_hex_hereplus.md) - [INS (Inertial Navigation/GNSS)](/sensor/inertial_navigation_systems.md) + - [InertialLabs](/sensor/inertiallabs.md) + - [MicroStrain](/sensor/microstrain.md) + - [sbgECom](/sensor/sbgecom.md) - [VectorNav](/sensor/vectornav.md) - [光流](/sensor/optical_flow.md) - [ARK 光流](/dronecan/ark_flow.md) @@ -297,6 +304,7 @@ - [ThunderFly TFRPM01 转速传感器](/sensor/thunderfly_tachometer.md) - [IMU Factory Calibration](/advanced_config/imu_factory_calibration.md) - [传感器热补偿](/advanced_config/sensor_thermal_calibration.md) + - [执行器](/actuators/index.md) - [ADSB/FLARM (空中防撞)](/config/actuators.md) - [电调(ESC)校准](/advanced_config/esc_calibration.md) @@ -308,19 +316,22 @@ - [Zubax Telega](/dronecan/zubax_telega.md) - [PX4 Sapog ESC Firmware](/dronecan/sapog.md) - [Holybro Kotleta](/dronecan/holybro_kotleta.md) - - [Zubax Orel](/dronecan/zubax_orel.md) - [Vertiq](/peripherals/vertiq.md) - [VESC](/peripherals/vesc.md) + - [Radio Control (RC)](/getting_started/rc_transmitter_receiver.md) - [无线电系统设置](/config/radio.md) - [飞行模式](/config/flight_mode.md) + - [Joysticks](/config/joystick.md) + - [Data Links](/data_links/index.md) - [MAVLink 回传(OSD/GCS)](/peripherals/mavlink_peripherals.md) - [数传电台](/telemetry/index.md) - [SiK 电台](/telemetry/sik_radio.md) - [RFD900 (SiK) 数传电台](/telemetry/rfd900_telemetry.md) + - [ThunderFly TFSIK01 Telemetry Radio](/telemetry/tfsik_telemetry.md) - [HolyBro (SIK) 数传电台](/telemetry/holybro_sik_radio.md) - [WiFi 数传](/telemetry/telemetry_wifi.md) - [ESP8266 WiFi 模块](/telemetry/esp8266_wifi_module.md) @@ -338,6 +349,7 @@ - [TBS Crossfire (CRSF) Telemetry](/telemetry/crsf_telemetry.md) - [Satellite Comms (Iridium/RockBlock)](/advanced_features/satcom_roadblock.md) + - [Power Systems](/power_systems/index.md) - [Battery Estimation Tuning](/config/battery.md) - [Battery Chemistry Overview](/power_systems/battery_chemistry.md) @@ -356,6 +368,7 @@ - [Sky-Drones SmartAP PDB](/power_module/sky-drones_smartap-pdb.md) - [Smart/MAVLink Batteries](/smart_batteries/index.md) - [Rotoye Batmon 电池智能套装](/smart_batteries/rotoye_batmon.md) + - [载荷 & 相机](/payloads/index.md) - [Use Cases](/payloads/use_cases.md) - [Package Delivery Mission](/flying/package_delivery_mission.md) @@ -367,19 +380,25 @@ - [Gimbal \(Mount\) Configuration](/advanced/gimbal_control.md) - [Grippers](/peripherals/gripper.md) - [Servo Gripper](/peripherals/gripper_servo.md) + - [Peripherals](/peripherals/index.md) - [ADSB/FLARM/UTM (Traffic Avoidance)](/peripherals/adsb_flarm.md) - [降落伞](/peripherals/parachute.md) - [Remote ID](/peripherals/remote_id.md) + - [I2C Peripherals](/sensor_bus/i2c_general.md) - [I2C bus accelerators](/sensor_bus/i2c_general.md#i2c-bus-accelerators) - [TFI2CADT01 I2C address translator](/sensor_bus/translator_tfi2cadt.md) + - [CAN Peripherals](/can/index.md) + - [DroneCAN Peripherals](/dronecan/index.md) - [PX4 DroneCAN Firmware](/dronecan/px4_cannode_fw.md) - [ARK CANnode](/dronecan/ark_cannode.md) - [RaccoonLab CAN Nodes](/dronecan/raccoonlab_nodes.md) + - [Cable Wiring](/assembly/cable_wiring.md) + - [机载电脑](/companion_computer/index.md) - [Pixhawk + Companion Setup](/companion_computer/pixhawk_companion.md) - [RPi Pixhawk Companion](/companion_computer/pixhawk_rpi.md) @@ -395,16 +414,19 @@ - [Realsense T265 跟踪相机 (VIO)](/camera/camera_intel_realsense_t265_vio.md) - [视频流](/companion_computer/video_streaming.md) - [Video Streaming using WFB-ng Wifi (Long range)](/companion_computer/video_streaming_wfb_ng_wifi.md) + - [串口配置](/peripherals/serial_configuration.md) + - [PX4 Ethernet Setup](/advanced_config/ethernet_setup.md) + - [Standard Configuration](/config/index.md) + - [高级配置](/advanced_config/index.md) - [Using PX4's Navigation Filter (EKF2)](/advanced_config/tuning_the_ecl_ekf.md) - [查找/更新参数](/advanced_config/parameters.md) - [Full Parameter Reference](/advanced_config/parameter_reference.md) - [Other Vehicles](/airframes/index.md) - - [Airships (experimental)](/frames_airship/index.md) - [Autogyros (experimental)](/frames_autogyro/index.md) - [ThunderFly Auto-G2 (Holybro pix32)](/frames_autogyro/thunderfly_auto_g2.md) @@ -412,17 +434,18 @@ - [Helicopter (experimental)](/frames_helicopter/index.md) - [Helicopter Config/Tuning](/config_heli/index.md) - [Rovers (experimental)](/frames_rover/index.md) - - [Ackermann Rovers](/frames_rover/ackermann.md) - - [Drive Modes](/flight_modes_rover/ackermann.md) - - [Configuration/Tuning](/config_rover/ackermann.md) - - [Differential Rovers](/frames_rover/differential.md) - - [Drive Modes](/flight_modes_rover/differential.md) - - [Configuration/Tuning](/config_rover/differential.md) - - [Aion Robotics R1](/frames_rover/aion_r1.md) - - [Mecanum Rovers](/frames_rover/mecanum.md) - - [Drive Modes](/flight_modes_rover/mecanum.md) - - [Configuration/Tuning](/config_rover/mecanum.md) - - [(Deprecated) Rover Position Control](/frames_rover/rover_position_control.md) + - [Drive Modes](/flight_modes_rover/index.md) + - [Manual](/flight_modes_rover/manual.md) + - [Auto](/flight_modes_rover/auto.md) + - [Configuration/Tuning](/config_rover/index.md) + - [Basic Setup](/config_rover/basic_setup.md) + - [Rate Tuning](/config_rover/rate_tuning.md) + - [Attitude Tuning](/config_rover/attitude_tuning.md) + - [Velocity Tuning](/config_rover/velocity_tuning.md) + - [Position Tuning](/config_rover/position_tuning.md) + - [Apps & API](/flight_modes_rover/api.md) + - [Complete Vehicles](/complete_vehicles_rover/index.md) + - [Aion Robotics R1](/complete_vehicles_rover/aion_r1.md) - [Submarines (experimental)](/frames_sub/index.md) - [BlueROV2](/frames_sub/bluerov2.md) - [机架参考](/airframes/airframe_reference.md) @@ -486,6 +509,7 @@ - [UART/串口](/uart/index.md) - [可配置的串口驱动](/uart/user_configurable_serial_driver.md) - [RTK GPS (集成)](/advanced/rtk_gps.md) + - [PPS Time Synchronization](/advanced/pps_time_sync.md) - [中间件](/middleware/index.md) - [uORB 通讯](/middleware/uorb.md) - [uORB 图](/middleware/uorb_graph.md) @@ -534,6 +558,7 @@ - [Airspeed](/msg_docs/Airspeed.md) - [AirspeedWind](/msg_docs/AirspeedWind.md) - [AutotuneAttitudeControlStatus](/msg_docs/AutotuneAttitudeControlStatus.md) + - [BatteryInfo](/msg_docs/BatteryInfo.md) - [ButtonEvent](/msg_docs/ButtonEvent.md) - [CameraCapture](/msg_docs/CameraCapture.md) - [CameraStatus](/msg_docs/CameraStatus.md) @@ -552,6 +577,7 @@ - [DifferentialPressure](/msg_docs/DifferentialPressure.md) - [DistanceSensor](/msg_docs/DistanceSensor.md) - [DistanceSensorModeChangeRequest](/msg_docs/DistanceSensorModeChangeRequest.md) + - [DronecanNodeStatus](/msg_docs/DronecanNodeStatus.md) - [Ekf2Timestamps](/msg_docs/Ekf2Timestamps.md) - [EscReport](/msg_docs/EscReport.md) - [EscStatus](/msg_docs/EscStatus.md) @@ -626,6 +652,7 @@ - [MountOrientation](/msg_docs/MountOrientation.md) - [NavigatorMissionItem](/msg_docs/NavigatorMissionItem.md) - [NavigatorStatus](/msg_docs/NavigatorStatus.md) + - [NeuralControl](/msg_docs/NeuralControl.md) - [NormalizedUnsignedSetpoint](/msg_docs/NormalizedUnsignedSetpoint.md) - [ObstacleDistance](/msg_docs/ObstacleDistance.md) - [OffboardControlMode](/msg_docs/OffboardControlMode.md) @@ -665,10 +692,10 @@ - [RoverPositionSetpoint](/msg_docs/RoverPositionSetpoint.md) - [RoverRateSetpoint](/msg_docs/RoverRateSetpoint.md) - [RoverRateStatus](/msg_docs/RoverRateStatus.md) + - [RoverSpeedSetpoint](/msg_docs/RoverSpeedSetpoint.md) + - [RoverSpeedStatus](/msg_docs/RoverSpeedStatus.md) - [RoverSteeringSetpoint](/msg_docs/RoverSteeringSetpoint.md) - [RoverThrottleSetpoint](/msg_docs/RoverThrottleSetpoint.md) - - [RoverVelocitySetpoint](/msg_docs/RoverVelocitySetpoint.md) - - [RoverVelocityStatus](/msg_docs/RoverVelocityStatus.md) - [Rpm](/msg_docs/Rpm.md) - [RtlStatus](/msg_docs/RtlStatus.md) - [RtlTimeEstimate](/msg_docs/RtlTimeEstimate.md) @@ -680,6 +707,7 @@ - [SensorCombined](/msg_docs/SensorCombined.md) - [SensorCorrection](/msg_docs/SensorCorrection.md) - [SensorGnssRelative](/msg_docs/SensorGnssRelative.md) + - [SensorGnssStatus](/msg_docs/SensorGnssStatus.md) - [SensorGps](/msg_docs/SensorGps.md) - [SensorGyro](/msg_docs/SensorGyro.md) - [SensorGyroFft](/msg_docs/SensorGyroFft.md) @@ -689,6 +717,7 @@ - [SensorOpticalFlow](/msg_docs/SensorOpticalFlow.md) - [SensorPreflightMag](/msg_docs/SensorPreflightMag.md) - [SensorSelection](/msg_docs/SensorSelection.md) + - [SensorTemp](/msg_docs/SensorTemp.md) - [SensorUwb](/msg_docs/SensorUwb.md) - [SensorsStatus](/msg_docs/SensorsStatus.md) - [SensorsStatusImu](/msg_docs/SensorsStatusImu.md) @@ -724,7 +753,13 @@ - [Wind](/msg_docs/Wind.md) - [YawEstimatorStatus](/msg_docs/YawEstimatorStatus.md) - [AirspeedValidatedV0](/msg_docs/AirspeedValidatedV0.md) + - [ArmingCheckReplyV0](/msg_docs/ArmingCheckReplyV0.md) + - [ArmingCheckRequestV0](/msg_docs/ArmingCheckRequestV0.md) + - [BatteryStatusV0](/msg_docs/BatteryStatusV0.md) + - [EventV0](/msg_docs/EventV0.md) + - [HomePositionV0](/msg_docs/HomePositionV0.md) - [VehicleAttitudeSetpointV0](/msg_docs/VehicleAttitudeSetpointV0.md) + - [VehicleLocalPositionV0](/msg_docs/VehicleLocalPositionV0.md) - [VehicleStatusV0](/msg_docs/VehicleStatusV0.md) - [MAVLink Messaging](/mavlink/index.md) - [Adding Messages](/mavlink/adding_messages.md) @@ -734,6 +769,8 @@ - [Protocols/Microservices](/mavlink/protocols.md) - [Standard Modes Protocol](/mavlink/standard_modes.md) - [uXRCE-DDS (PX4-ROS 2/DDS Bridge)](/middleware/uxrce_dds.md) + - [UORB Bridged to ROS 2](/middleware/dds_topics.md) + - [Zenoh (PX4 ROS 2)](/middleware/zenoh.md) - [模块 & 命令](/modules/modules_main.md) - [自动调参](/modules/modules_autotune.md) - [命令](/modules/modules_command.md) @@ -751,6 +788,7 @@ - [Rpm Sensor](/modules/modules_driver_rpm_sensor.md) - [Radio Control](/modules/modules_driver_radio_control.md) - [Transponder](/modules/modules_driver_transponder.md) + - [adc](/modules/modules_driver_adc.md) - [估计器](/modules/modules_estimator.md) - [仿真](/modules/modules_simulation.md) - [系统](/modules/modules_system.md) @@ -763,7 +801,7 @@ - [Debugging with GDB](/debug/gdb_debugging.md) - [SWD Debug Port](/debug/swd_debug.md) - [JLink Probe](/debug/probe_jlink.md) - - [Black Magic/DroneCode Probe](/debug/probe_bmp.md) + - [Black Magic/Zubax BugFace BF1 Probe](/debug/probe_bmp.md) - [STLink Probe](/debug/probe_stlink.md) - [MCU-Link Probe](/debug/probe_mculink.md) - [Hardfault Debugging](/debug/gdb_hardfault.md) @@ -787,6 +825,9 @@ - [Camera Integration/Architecture](/camera/camera_architecture.md) - [机器视觉](/advanced/computer_vision.md) - [Motion Capture (VICON, Optitrack, NOKOV)](/tutorials/motion-capture.md) + - [Neural Networks](/advanced/neural_networks.md) + - [Neural Network Module Utilities](/advanced/nn_module_utilities.md) + - [TensorFlow Lite Micro (TFLM)](/advanced/tflm.md) - [安装英特尔 RealSense R200 的驱动程序](/advanced/realsense_intel_driver.md) - [切换状态估计器](/advanced/switching_state_estimators.md) - [外部模块](/advanced/out_of_tree_modules.md) @@ -818,8 +859,14 @@ - [测试 MC_02-完全自主](/test_cards/mc_02_full_autonomous.md) - [测试 MC_03 - 自动手动混合](/test_cards/mc_03_auto_manual_mix.md) - [测试 MC_04 -故障安全测试](/test_cards/mc_04_failsafe_testing.md) - - [测试 MC_05-室内飞行(手动模式)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_05 - Manual Modes (Inside)](/test_cards/mc_05_indoor_flight_manual_modes.md) + - [Test MC_06 - Optical Flow (Inside)](/test_cards/mc_06_optical_flow.md) + - [Test MC_07 - Optical Flow Low Mount](/test_cards/mc_07_optical_flow_low_mount.md) + - [Test MC_08 - DSHOT ESC](/test_cards/mc_08_dshot.md) + - [Test MC_09 - VIO (Visual-Inertial Odometry)](/test_cards/mc_09_vio.md) + - [Test MC_10 - Optical Flow / GPS Mixed](/test_cards/mc_10_optical_flow_gps_mixed.md) - [单元测试](/test_and_ci/unit_tests.md) + - [Fuzz Tests](/test_and_ci/fuzz_tests.md) - [持续集成](/test_and_ci/continous_integration.md) - [Integration Testing](/test_and_ci/integration_testing.md) - [MAVSDK集成测试](/test_and_ci/integration_testing_mavsdk.md) @@ -838,6 +885,7 @@ - [PX4 ROS 2 Interface Library](/ros2/px4_ros2_interface_lib.md) - [Control Interface](/ros2/px4_ros2_control_interface.md) - [Navigation Interface](/ros2/px4_ros2_navigation_interface.md) + - [Waypoint Missions](/ros2/px4_ros2_waypoint_missions.md) - [ROS 2 Message Translation Node](/ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](/ros/ros1.md) - [ROS/MAVROS安装指南](/ros/mavros_installation.md) @@ -862,8 +910,8 @@ - [版本发布](/releases/index.md) - [main (alpha)](/releases/main.md) - - [1.16 (release candidate)](/releases/1.16.md) - - [1.15 (stable)](/releases/1.15.md) + - [1.16 (stable)](/releases/1.16.md) + - [1.15](/releases/1.15.md) - [1.14](/releases/1.14.md) - [1.13](/releases/1.13.md) - [1.12](/releases/1.12.md) diff --git a/docs/zh/actuators/index.md b/docs/zh/actuators/index.md index 71f11b5a05..60b3dac4d0 100644 --- a/docs/zh/actuators/index.md +++ b/docs/zh/actuators/index.md @@ -8,6 +8,6 @@ - [电调校准](../advanced_config/esc_calibration.md) — PWM 电调的校准 (DShot/CAN 电调/舵机不需要) 。 -## See Also +## 另见 - [外设](../peripherals/index.md) - 包括非核心执行器,如夹具, 降落伞等。 diff --git a/docs/zh/advanced/gimbal_control.md b/docs/zh/advanced/gimbal_control.md index 5965f81264..234dfcd2ff 100644 --- a/docs/zh/advanced/gimbal_control.md +++ b/docs/zh/advanced/gimbal_control.md @@ -74,7 +74,7 @@ The output pins that are used to control the gimbal are set in the [Acuator Conf ![Gimbal Actuator config](../../assets/config/actuators/qgc_actuators_gimbal.png) -The PWM values to use for the disarmed, maximum and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low and high position in the slider. +The PWM values to use for the disarmed, maximum, center and minimum values can be determined in the same way as other servo, using the [Actuator Test sliders](../config/actuators.md#actuator-testing) to confirm that each slider moves the appropriate axis, and changing the values so that the gimbal is in the appropriate position at the disarmed, low, center and high position in the slider. 这些数值也可以在云台文档中提供。 ## Gimbal Control in Missions @@ -131,7 +131,7 @@ The on-screen gimbal control can be used to move/test a connected MAVLink camera 2. Open QGroundControl and enable the on-screen camera control (Application settings). - ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) + ![Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../../assets/qgc/fly/gimbal_control_x500gz.png) 3. Make sure the vehicle is armed and flying, e.g. by entering with `commander takeoff`. diff --git a/docs/zh/advanced/neural_networks.md b/docs/zh/advanced/neural_networks.md index 92ceacef9c..039259fd5f 100644 --- a/docs/zh/advanced/neural_networks.md +++ b/docs/zh/advanced/neural_networks.md @@ -1,115 +1 @@ -# Neural Networks - - - -:::warning -This is an experimental module. -Use at your own risk. -::: - -The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. -It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. - -The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](../advanced/tflm.md) module. -The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. -While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. -Note that after training the network you will need to update and rebuild PX4. - -TLFM is a mature inference library intended for use on embedded devices. -It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. -If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). - -This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. -The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. - -If you are looking for more resources to learn about the module, a website has been created with links to a youtube video and a workshop paper. A full master's thesis will be added later. [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/). - -## Neural Network PX4 Firmware - -The module has been tested on a number of configurations, which can be build locally using the commands: - -```sh -make px4_sitl_neural -``` - -```sh -make px4_fmu-v6c_neural -``` - -```sh -make mro_pixracerpro_neural -``` - -You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: - -```sh -CONFIG_LIB_TFLM=y -CONFIG_MODULES_MC_NN_CONTROL=y -``` - -:::tip -The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. -::: - -## Example Module Overview - -The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: - -![neural_control](../../assets/advanced/neural_control.png) - -In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. -We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. -We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) - -### Input - -The input can be changed to whatever you want. -Set up the input you want to use during training and then provide the same input in PX4. -In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: - -- [3] Local position error. (goal position - current position) -- [6] The first 2 rows of a 3 dimensional rotation matrix. -- [3] Linear velocity -- [3] Angular velocity - -All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. -PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. -Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. - -![ENU-NED](../../assets/advanced/ENU-NED.png) - -ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. - -### 输出 - -The output consists of 4 values, the motor forces, one for each motor. -These are transformed in the `RescaleActions()` function. -This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. -So the output from the network needs to be normalized before they can be sent to the motors in PX4. - -The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. -The publishing is handled in `PublishOutput(float* command_actions)` function. - -:::tip -If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. -Decrease it for more thrust. -::: - -## Training your own Network - -The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). -But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. - -Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. -If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). - -You should do one system identification flight for this and get an approximate inertia matrix for your platform. -On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). - -Then do the following steps: - -- Do a hover flight -- Read of the logs what RPM is required for the drone to hover. -- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. -- Insert these values into the Aerial Gym configuration and train your network. -- Convert the network as explained in [TFLM](tflm.md). + diff --git a/docs/zh/advanced/pps_time_sync.md b/docs/zh/advanced/pps_time_sync.md new file mode 100644 index 0000000000..6679279b60 --- /dev/null +++ b/docs/zh/advanced/pps_time_sync.md @@ -0,0 +1,135 @@ +# PPS Time Synchronization (PX4 Integration) + +[Pulse Per Second](https://en.wikipedia.org/wiki/Pulse-per-second_signal) (PPS) time synchronization provides high-precision timing for GNSS receivers. +This page explains how PPS is integrated into PX4 and how to configure it. + +## 综述 + +PPS (Pulse Per Second) is a timing signal provided by GNSS receivers that outputs an electrical pulse once per second, synchronized to UTC time. +The PPS signal provides a highly accurate timing reference that PX4 can use to: + +- Refine GNSS time measurements and compensate for clock drift +- Provide precise UTC timestamps for camera capture events (for photogrammetry and mapping applications) +- Enable offline position refinement through accurate time correlation + +## 支持的硬件 + +PPS time synchronization can be supported on flight controllers that have a hardware timer input pin that can be configured for PPS capture, by [enabling the PPS capture driver](#enable-pps-driver-in-board-configuration) in the board configuration. + +Supported boards include (at time of writing): + +- [Ark FMUv6x](../flight_controller/ark_v6x.md) +- Auterion FMUv6x +- Auterion FMUv6s + +## 设置 + +### Enable PPS Driver in Board Configuration + +The [PPS capture driver](../modules/modules_driver.md#pps-capture) must be enabled in the board configuration. +This is done by adding the following to your board's configuration: + +```ini +CONFIG_DRIVERS_PPS_CAPTURE=y +``` + +### Configure PPS Parameters + +The configuration varies depending on your flight controller hardware. + +#### FMUv6X + +For FMUv6X-based flight controllers, configure PWM AUX Timer 3 and Function 9: + +```sh +param set PWM_AUX_TIM3 -2 +param set PWM_AUX_FUNC9 2064 +param set PPS_CAP_ENABLE 1 +``` + +#### FMUv6S + +For FMUv6S-based flight controllers, configure PWM MAIN Timer 3 and Function 10: + +```sh +param set PWM_MAIN_TIM3 -2 +param set PWM_MAIN_FUNC10 2064 +param set PPS_CAP_ENABLE 1 +``` + +### 布线 + +The wiring configuration depends on your specific flight controller. + +#### Skynode X (FMUv6x) + +Connect the PPS signal from your GNSS module to the flight controller using the 11-pin or 6-pin GPS connector: + +For detailed pinout information, refer to: + +- [Skynode GPS Peripherals - Pinouts](https://docs.auterion.com/hardware-integration/skynode/peripherals/gps#pinouts) + +#### Skynode S (FMUv6S) + +For FMUv6S, you need to route the PPS signal separately: + +1. Connect your GNSS module using the standard 6-pin GPS connector: [Skynode S GPS Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#gps) +2. Connect the PPS signal from your GNSS module to the **PPM_IN** pin: [Skynode S Extras 1 Interface](https://docs.auterion.com/hardware-integration/skynode-s/interfaces#extras-1) + +#### ARK Jetson Carrier Board (FMUv6x) + +For ARK FMUv6X on the Jetson carrier board: + +1. Connect your GNSS module using either the 10-pin or 6-pin GPS connector: [ARK PAB GPS1 Interface](../flight_controller/ark_pab#gps1) +2. Connect the PPS signal to the **FMU_CAP** pin: [ARK PAB ADIO Interface](../flight_controller/ark_pab.md#adio) + +## 验证 + +After configuring PPS, you can verify that it is working correctly: + +1. Connect to the [PX4 System Console](../debug/system_console.md) (via MAVLink shell or serial console). + +2. Wait for GNSS fix. + +3. Check the PPS capture status to confirm it is up and running: + + ```sh + pps_capture status + ``` + +4. You can also check the [PpsCapture](../msg_docs/PpsCapture.md) uORB topic + + ```sh + listener pps_capture + ``` + + Where you should see: `timestamp`, `rtc_timestamp`, and `pps_rate_exceeded_counter`. + +### PPS Capture Driver + +The PPS capture driver is located in `src/drivers/pps_capture` and uses hardware timer input capture to precisely measure the arrival time of each PPS pulse. + +主要特性: + +- Sub-microsecond pulse capture precision (hardware-dependent) +- Automatic drift calculation and compensation +- Integration with the GNSS driver for refined time stamping + +See also: + +- [PPS Capture Driver Documentation](../modules/modules_driver.md#pps-capture) +- [PpsCapture Message](../msg_docs/PpsCapture.md) + +### Time Synchronization Flow + +1. GNSS module sends position/time data at ~1-20 Hz. +2. GNSS module outputs PPS pulse at 1 Hz, precisely aligned to UTC second boundary. +3. PPS capture driver measures the exact time of the PPS pulse arrival using hardware timer. +4. Driver calculates the offset between GNSS time (from UART data) and autopilot clock (from PPS measurement). +5. This offset is used to correct GNSS timestamps and improve sensor fusion accuracy. + +The PPS signal provides much higher temporal precision than the transmitted time data, which has latency and jitter from serial communication. + +:::warning +If the PPS driver does not sending any data for 5 seconds (despite having `PPS_CAP_ENABLE` set to 1), the `EKF2_GPS_DELAY` will be used instead for estimating the latency. +::: diff --git a/docs/zh/advanced/system_tunes.md b/docs/zh/advanced/system_tunes.md index 3feb974a11..70548c0b22 100644 --- a/docs/zh/advanced/system_tunes.md +++ b/docs/zh/advanced/system_tunes.md @@ -52,7 +52,7 @@ On Windows, one option is to use _Melody Master_ within _Dosbox_. 7. 当您准备好时保存音乐: - Press **F2** to give the tune a name and save it in the _/Music_ sub folder of your Melody Master installation. - Press **F7**, the scroll down the list of output formats on the right to get to ANSI. - The file will be exported to the _root_ of the Melody Master directory (with the same name and a file-type specific extension). + The file will be exported to the _root_ of the Melody Master directory (with the same name and a file-type specific extension). 8. 打开文件。 输出可能看起来像这样: diff --git a/docs/zh/advanced_config/advanced_flight_controller_orientation_leveling.md b/docs/zh/advanced_config/advanced_flight_controller_orientation_leveling.md index 4deace6e1d..763c210c77 100644 --- a/docs/zh/advanced_config/advanced_flight_controller_orientation_leveling.md +++ b/docs/zh/advanced_config/advanced_flight_controller_orientation_leveling.md @@ -23,7 +23,7 @@ You can locate the parameters in QGroundControl as shown below: 1. Open QGroundControl menu: **Settings > Parameters > Sensor Calibration**. 2. The parameters as located in the section as shown below (or you can search for them): - ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) + ![FC Orientation QGC v2](../../assets/qgc/setup/sensor/fc_orientation_qgc_v2.png) ## Parameter Summary diff --git a/docs/zh/advanced_config/airspeed_validation.md b/docs/zh/advanced_config/airspeed_validation.md index d1bcda1d87..1bbfb850ea 100644 --- a/docs/zh/advanced_config/airspeed_validation.md +++ b/docs/zh/advanced_config/airspeed_validation.md @@ -10,36 +10,13 @@ By default, the [Missing Data](#missing-data-check), [Data Stuck](#data-stuck-ch You can configure which checks are active using the [ASPD_DO_CHECKS](#aspd_do_checks_table) parameter. ::: -## Airspeed in PX4 - -PX4 handles multiple types of airspeed: - -- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). - -- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. - -- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. - While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. - -- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). - -The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. - ## CAS Scale Estimation -PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. -To compute the final TAS, standard environment conversions are applied (CAS → TAS). - -This CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. +Calibrated Airspeed (CAS) is the measured Indicated Airspeed (IAS) scaled to correct for sensor-specific and installation-related errors. +CAS scaling plays an important role in keeping the [innovation check](#innovation-check) reliable, since a well-estimated CAS is key to spotting inconsistencies between measured and predicted airspeed. If the estimated CAS scale is inaccurate, it can mask real airspeed faults or trigger false positives. -If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, you can manually set it using [ASPD_SCALE_n](#aspd_scale_n_table) (where `n` is the sensor number). -[ASPD_SCALE_APPLY](#aspd_scale_apply_table) can be used to configure when/if the estimated scale is applied. - -:::info -For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). -The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for [ASPD_SCALE_n](#aspd_scale_n_table). -::: +If you observe that the CAS scale estimate is consistently off, or if it is converging too slowly, follow the steps outlined in [Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md#recommended-first-flight-process). ## Validation Checks diff --git a/docs/zh/advanced_config/bootloader_update.md b/docs/zh/advanced_config/bootloader_update.md index 0820bdcb0c..70cb5689af 100644 --- a/docs/zh/advanced_config/bootloader_update.md +++ b/docs/zh/advanced_config/bootloader_update.md @@ -37,8 +37,8 @@ You can enable this key in your own custom firmware if needed. 2. [Update the Firmware](../config/firmware.md#custom) with an image containing the new/desired bootloader. - ::: info - The updated bootloader might be included the default firmware for your board or supplied in custom firmware. + ::: info + The updated bootloader might be included the default firmware for your board or supplied in custom firmware. ::: @@ -47,7 +47,7 @@ You can enable this key in your own custom firmware if needed. 4. [Find and enable](../advanced_config/parameters.md) the parameter [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 5. 重新启动(断开/重新连接飞控板)。 - Bootloader 更新只需要几秒钟即可完成。 + Bootloader 更新只需要几秒钟即可完成。 Generally at this point you may then want to [update the firmware](../config/firmware.md) again using the correct/newly installed bootloader. @@ -89,80 +89,80 @@ The following steps explain how you can "manually" update the bootloader using a 1. Get a binary containing the bootloader (either from dev team or [build it yourself](#building-the-px4-bootloader)). 2. Get a [Debug Probe](../debug/swd_debug.md#debug-probes-for-px4-hardware). - Connect the probe your PC via USB and setup the `gdbserver`. + Connect the probe your PC via USB and setup the `gdbserver`. 3. Go into the directory containing the binary and run the command for your target bootloader in the terminal: - - FMUv6X + - FMUv6X - ```sh - arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6x_bootloader.elf + ``` - - FMUv6X-RT + - FMUv6X-RT - ```sh - arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf - ``` + ```sh + arm-none-eabi-gdb px4_fmu-v6xrt_bootloader.elf + ``` - - FMUv5 + - FMUv5 - ```sh - ``` + ```sh + ``` - ::: info - H7 Bootloaders from [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) are named with pattern `*._bootloader.elf`. - Bootloaders from [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) are named with the pattern `*_bl.elf`. + ::: info + H7 Bootloaders from [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) are named with pattern `*._bootloader.elf`. + Bootloaders from [PX4/PX4-Bootloader](https://github.com/PX4/PX4-Bootloader) are named with the pattern `*_bl.elf`. ::: 4. The _gdb terminal_ appears and it should display (something like) the following output: - ```sh - GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git - Copyright (C) 2017 Free Software Foundation, Inc. - License GPLv3+: GNU GPL version 3 or later - This is free software: you are free to change and redistribute it. - There is NO WARRANTY, to the extent permitted by law. - Type "show copying" and "show warranty" for details. - This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". - Type "show configuration" for configuration details. - For bug reporting instructions, please see: - . - Find the GDB manual and other documentation resources online at: - . - For help, type "help". - Type "apropos word" to search for commands related to "word"... - Reading symbols from px4fmuv5_bl.elf...done. - ``` + ```sh + GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git + Copyright (C) 2017 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from px4fmuv5_bl.elf...done. + ``` 5. Find your `` by running an `ls` command in the **/dev/serial/by-id** directory. 6. Now connect to the debug probe with the following command: - ```sh - tar ext /dev/serial/by-id/ - ``` + ```sh + tar ext /dev/serial/by-id/ + ``` 7. Power on the Pixhawk with another USB cable and connect the probe to the `FMU-DEBUG` port. - ::: info - If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). + ::: info + If using a Zubax BugFace BF1 you may need to remove the case in order to connect to the `FMU-DEBUG` port (e.g. on Pixhawk 4 you would do this using a T6 Torx screwdriver). ::: 8. Use the following command to scan for the Pixhawk\`s SWD and connect to it: - ```sh - (gdb) mon swdp_scan - (gdb) attach 1 - ``` + ```sh + (gdb) mon swdp_scan + (gdb) attach 1 + ``` 9. 将二进制文件加载到 Pixhawk 中 : - ```sh - (gdb) load - ``` + ```sh + (gdb) load + ``` After the bootloader has updated you can [Load PX4 Firmware](../config/firmware.md) using _QGroundControl_. @@ -181,25 +181,25 @@ Early FMUv2 [Pixhawk-series](../flight_controller/pixhawk_series.md#fmu_versions 1. 插入 SD 卡(使能引导日志记录,便于调试任何可能的问题)。 2. [Update the Firmware](../config/firmware.md) to PX4 _master_ version (when updating the firmware, check **Advanced settings** and then select **Developer Build (master)** from the dropdown list). - _QGroundControl_ will automatically detect that the hardware supports FMUv2 and install the appropriate Firmware. + _QGroundControl_ will automatically detect that the hardware supports FMUv2 and install the appropriate Firmware. - ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) + ![FMUv2 update](../../assets/qgc/setup/firmware/bootloader_update.jpg) - 等待飞控重启。 + 等待飞控重启。 3. [Find and enable](../advanced_config/parameters.md) the parameter [SYS_BL_UPDATE](../advanced_config/parameter_reference.md#SYS_BL_UPDATE). 4. 重新启动(断开/重新连接飞控板)。 - Bootloader 更新只需要几秒钟即可完成。 + Bootloader 更新只需要几秒钟即可完成。 5. Then [Update the Firmware](../config/firmware.md) again. - This time _QGroundControl_ should autodetect the hardware as FMUv3 and update the Firmware appropriately. + This time _QGroundControl_ should autodetect the hardware as FMUv3 and update the Firmware appropriately. - ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) + ![FMUv3 update](../../assets/qgc/setup/firmware/bootloader_fmu_v3_update.jpg) - ::: info - If the hardware has the [Silicon Errata](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata) it will still be detected as FMUv2 and you will see that FMUv2 was re-installed (in console). - 在这种情况下,您将无法安装 FMUv3 硬件。 + ::: info + If the hardware has the [Silicon Errata](../flight_controller/silicon_errata.md#fmuv2-pixhawk-silicon-errata) it will still be detected as FMUv2 and you will see that FMUv2 was re-installed (in console). + 在这种情况下,您将无法安装 FMUv3 硬件。 ::: diff --git a/docs/zh/advanced_config/bootloader_update_from_betaflight.md b/docs/zh/advanced_config/bootloader_update_from_betaflight.md index 3094cc3830..4d37bdbfe0 100644 --- a/docs/zh/advanced_config/bootloader_update_from_betaflight.md +++ b/docs/zh/advanced_config/bootloader_update_from_betaflight.md @@ -89,7 +89,7 @@ Flight controllers that have bootloader PX4-Autopilot `make` targets, can build The list of controllers for which this applies can be obtained by running the following `make` command, and noting the `make` targets that end in `_bootloader` ``` -$make list_config_targets +$ make list_config_targets ... cuav_nora_bootloader diff --git a/docs/zh/advanced_config/compass_power_compensation.md b/docs/zh/advanced_config/compass_power_compensation.md index 35b987cde5..e5dcdbdaa0 100644 --- a/docs/zh/advanced_config/compass_power_compensation.md +++ b/docs/zh/advanced_config/compass_power_compensation.md @@ -44,7 +44,7 @@ The process is demonstrated for a multicopter, but is equally valid for other ve - 解锁无人机,然后缓缓将油门推到最大。 - 慢慢将油门降到0 - 给无人机加锁 - > Note 谨慎地进行测试,并密切注意振动情况。 + > Note 谨慎地进行测试,并密切注意振动情况。 ::: info Perform the test carefully and closely monitor the vibrations. diff --git a/docs/zh/advanced_config/esc_calibration.md b/docs/zh/advanced_config/esc_calibration.md index 36d417a5d9..27bda2805d 100644 --- a/docs/zh/advanced_config/esc_calibration.md +++ b/docs/zh/advanced_config/esc_calibration.md @@ -94,29 +94,29 @@ Flight control systems that can't power the autopilot via USB will need a [diffe - 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. - 当你将滑块从解锁到最小值时,正确的值应该使电机立即和可靠地旋转。 + 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. + 当你将滑块从解锁到最小值时,正确的值应该使电机立即和可靠地旋转。 - 要找到“最佳”最小值,请将滑块移动到底部(禁用)。 - Then increase the PWM output's `disarmed` setting in small increments (e.g. 1025us, 1050us, etc), until the motor starts to spin reliably (it is better to be a little too high than a little too low). - Enter this value into the `minimum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. + 要找到“最佳”最小值,请将滑块移动到底部(禁用)。 + Then increase the PWM output's `disarmed` setting in small increments (e.g. 1025us, 1050us, etc), until the motor starts to spin reliably (it is better to be a little too high than a little too low). + Enter this value into the `minimum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. - The maximum value for a motor (default: `1900us`) should be chosen such that increasing the value doesn't make the motor spin any faster. - You can confirm that the motor spins quickly at the maximum setting in [Actuator Testing](../config/actuators.md#actuator-testing), by moving the associated test output slider to the top position. + You can confirm that the motor spins quickly at the maximum setting in [Actuator Testing](../config/actuators.md#actuator-testing), by moving the associated test output slider to the top position. - To find the "optimal" maximum value, first move the slider to the bottom (disarmed). - Then increase the PWM output's `disarmed` setting to near the default maximum (`1900`) - the motors should spin up. - Listen to the tone of the motor as you increase the PWM maximum value for the output in increments (e.g. 1925us, 1950us, etc). - The optimal value is found at the point when the sound of the motors does not change as you increase the value of the output. - Enter this value into the `maximum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. + To find the "optimal" maximum value, first move the slider to the bottom (disarmed). + Then increase the PWM output's `disarmed` setting to near the default maximum (`1900`) - the motors should spin up. + Listen to the tone of the motor as you increase the PWM maximum value for the output in increments (e.g. 1925us, 1950us, etc). + The optimal value is found at the point when the sound of the motors does not change as you increase the value of the output. + Enter this value into the `maximum` setting for all the motor PWM outputs, and restore the `disarmed` output to `1100us`. - The disarmed value for a motor (default: `1000us`) should make the motor stop and stay stopped. - You can confirm this in [Actuator Testing](../config/actuators.md#actuator-testing) by moving the test output slider to the snap position at the bottom of the slider and observing that the motor does not spin. + You can confirm this in [Actuator Testing](../config/actuators.md#actuator-testing) by moving the test output slider to the snap position at the bottom of the slider and observing that the motor does not spin. - If the ESC spins with the default value of 1000us then the ESC is not properly calibrated. - If using an ESC that can't be calibrated, you should reduce the PWM output value for the output to below where the motor does not spin anymore (such as 950us or 900us). + If the ESC spins with the default value of 1000us then the ESC is not properly calibrated. + If using an ESC that can't be calibrated, you should reduce the PWM output value for the output to below where the motor does not spin anymore (such as 950us or 900us). ::: info VTOL and fixed-wing motors do not need any special PWM configuration. diff --git a/docs/zh/advanced_config/ethernet_setup.md b/docs/zh/advanced_config/ethernet_setup.md index 077421a3db..db82bdd8be 100644 --- a/docs/zh/advanced_config/ethernet_setup.md +++ b/docs/zh/advanced_config/ethernet_setup.md @@ -25,6 +25,7 @@ PX4 supports Ethernet connectivity on [Pixhawk 5X-standard](https://github.com/p 支持的飞行控制器包括: +- [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) - [CUAV Pixhawk V6X](../flight_controller/cuav_pixhawk_v6x.md) - [Holybro Pixhawk 5X](../flight_controller/pixhawk5x.md) - [Holybro Pixhawk 6X](../flight_controller/pixhawk6x.md) @@ -87,14 +88,14 @@ To set the above "example" configuration using the _QGroundControl_: 3. Enter commands "like" the ones below into the _MAVLink Console_ (to write the values to the configuration file): - ```sh - echo DEVICE=eth0 > /fs/microsd/net.cfg - echo BOOTPROTO=fallback >> /fs/microsd/net.cfg - echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg - echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg - echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg - echo DNS=10.41.10.254 >>/fs/microsd/net.cfg - ``` + ```sh + echo DEVICE=eth0 > /fs/microsd/net.cfg + echo BOOTPROTO=fallback >> /fs/microsd/net.cfg + echo IPADDR=10.41.10.2 >> /fs/microsd/net.cfg + echo NETMASK=255.255.255.0 >>/fs/microsd/net.cfg + echo ROUTER=10.41.10.254 >>/fs/microsd/net.cfg + echo DNS=10.41.10.254 >>/fs/microsd/net.cfg + ``` 4. 一旦设置了网络配置,您可以断开 USB 电缆。 @@ -113,36 +114,36 @@ Note that there are many more [examples](https://github.com/canonical/netplan/tr 设置Ubuntu计算机: 1. In a terminal, create and open a `netplan` configuration file: `/etc/netplan/01-network-manager-all.yaml` - Below we do this using the _nano_ text editor. + Below we do this using the _nano_ text editor. - ``` - sudo nano /etc/netplan/01-network-manager-all.yaml - ``` + ``` + sudo nano /etc/netplan/01-network-manager-all.yaml + ``` 2. 将以下配置信息复制并粘贴到文件中(注意:缩进很重要!): - ``` - network: - version: 2 - renderer: NetworkManager - ethernets: - enp2s0: - addresses: - - 10.41.10.1/24 - nameservers: - addresses: [10.41.10.1] - routes: - - to: 10.41.10.1 - via: 10.41.10.1 - ``` + ``` + network: + version: 2 + renderer: NetworkManager + ethernets: + enp2s0: + addresses: + - 10.41.10.1/24 + nameservers: + addresses: [10.41.10.1] + routes: + - to: 10.41.10.1 + via: 10.41.10.1 + ``` - 保存并退出编辑器。 + 保存并退出编辑器。 3. Apply the _netplan_ configuration by entering the following command into the Ubuntu terminal. - ``` - sudo netplan apply - ``` + ``` + sudo netplan apply + ``` ### 机载计算机以太网网络设置 @@ -189,9 +190,9 @@ Assuming you have already [Set up the Ethernet Network](#setting-up-the-ethernet 3. Start QGroundControl and [define a comm link](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/settings_view.html) (**Application Settings > Comm Links**) specifying the _server address_ and port as the IP address and port assigned in PX4, respectively. - 假设值已按本主题其余部分所述设置,设置将如下所示: + 假设值已按本主题其余部分所述设置,设置将如下所示: - ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) + ![QGC comm link for ethernet setup](../../assets/qgc/settings/comm_link/px4_ethernet_link_config.png) 4. 如果你选择这个链接,QGroundControl 应该会连接。 @@ -205,14 +206,14 @@ Assuming you have already [Set up the Ethernet Network](#setting-up-the-ethernet 1. [Set up the Ethernet Network](#setting-up-the-ethernet-network) so your companion computer and PX4 run on the same network. 2. Modify the [PX4 Ethernet Port Configuration](#px4-ethernet-network-setup) to connect to a companion computer. - You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). + You might change the parameters [MAV_2_REMOTE_PRT](../advanced_config/parameter_reference.md#MAV_2_REMOTE_PRT) and [MAV_2_UDP_PRT](../advanced_config/parameter_reference.md#MAV_2_UDP_PRT) to `14540`, and [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) to `2` (Onboard). 3. Follow the instructions in [MAVSDK-python](https://github.com/mavlink/MAVSDK-Python) to install and use MAVSDK. - 例如,您的代码将使用以下方式连接到PX4: + 例如,您的代码将使用以下方式连接到PX4: - ```python - await drone.connect(system_address="udp://10.41.10.2:14540") - ``` + ```python + await drone.connect(system_address="udp://10.41.10.2:14540") + ``` :::info MAVSDK can connect to the PX4 on port `14550` if you don't modify the PX4 Ethernet port configuration. @@ -235,40 +236,40 @@ MAVSDK can connect to the PX4 on port `14550` if you don't modify the PX4 Ethern 1. 通过以太网连接您的飞行控制器和机载计算机。 2. [Start the uXRCE-DDS client on PX4](../middleware/uxrce_dds.md#starting-the-client), either manually or by customizing the system startup script. - Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). + Note that you must use the IP address of the companion computer and the UDP port on which the agent is listening (the example configuration above sets the companion IP address to `10.41.10.1`, and the agent UDP port is set to `8888` in the next step). 3. [Start the micro XRCE-DDS agent on the companion computer](../middleware/uxrce_dds.md#starting-the-agent). - For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. + For example, enter the following command in a terminal to start the agent listening on UDP port `8888`. - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` 4. Run a [listener node](../ros2/user_guide.md#running-the-example) in a new terminal to confirm the connection is established: - ```sh - source ~/ws_sensor_combined/install/setup.bash - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + source ~/ws_sensor_combined/install/setup.bash + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` - 如果所有设置都正确,终端应显示如下输出: + 如果所有设置都正确,终端应显示如下输出: - ```sh - RECEIVED SENSOR COMBINED DATA - ============================= - ts: 855801598 - gyro_rad[0]: -0.00339938 - gyro_rad[1]: 0.00440091 - gyro_rad[2]: 0.00513893 - gyro_integral_dt: 4997 - accelerometer_timestamp_relative: 0 - accelerometer_m_s2[0]: -0.0324082 - accelerometer_m_s2[1]: 0.0392213 - accelerometer_m_s2[2]: -9.77914 - accelerometer_integral_dt: 4997 - ``` + ```sh + RECEIVED SENSOR COMBINED DATA + ============================= + ts: 855801598 + gyro_rad[0]: -0.00339938 + gyro_rad[1]: 0.00440091 + gyro_rad[2]: 0.00513893 + gyro_integral_dt: 4997 + accelerometer_timestamp_relative: 0 + accelerometer_m_s2[0]: -0.0324082 + accelerometer_m_s2[1]: 0.0392213 + accelerometer_m_s2[2]: -9.77914 + accelerometer_integral_dt: 4997 + ``` -## See Also +## 另见 - [Get The Pixhawk Raspberry Pi CM4 Baseboard By Holybro Talking With PX4](https://px4.io/get-the-pixhawk-raspberry-pi-cm4-baseboard-by-holybro-talking-with-px4/) (px4.io blog): - 展示如何通过有线以太网连接 Pixhawk 6X + Raspberry Pi 到 CM4 主板。 diff --git a/docs/zh/advanced_config/index.md b/docs/zh/advanced_config/index.md index b41f62561a..f498841274 100644 --- a/docs/zh/advanced_config/index.md +++ b/docs/zh/advanced_config/index.md @@ -24,16 +24,16 @@ ## 串口/以太网配置 -- [Serial Port Configuration](../peripherals/serial_configuration.md) +- [串口配置](../peripherals/serial_configuration.md) - [MAVLink Telemetry (OSD/GCS)](../peripherals/mavlink_peripherals.md) -- [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) +- [PX4 以太网设置](../advanced_config/ethernet_setup.md) ## 其它选项 - [Bootloader 更新](../advanced_config/bootloader_update.md) - [通过 USB 更新 FMUv6X-RT bootloader](../advanced_config/bootloader_update_v6xrt.md) -## See Also +## 另见 - [标准配置](../config/index.md) - 大多数 PX4 机体所需要的基本传感器/功能配置。 - [飞控外设](../peripherals/index.md) - 设置特定传感器、可选传感器、执行器等。 diff --git a/docs/zh/advanced_config/prearm_arm_disarm.md b/docs/zh/advanced_config/prearm_arm_disarm.md index 71ac176329..9be6a3347b 100644 --- a/docs/zh/advanced_config/prearm_arm_disarm.md +++ b/docs/zh/advanced_config/prearm_arm_disarm.md @@ -55,19 +55,17 @@ RC controllers will use different sticks for throttle and yaw [based on their mo - _Arm:_ Left-stick to right, right-stick to bottom. - _Disarm:_ Left-stick to left, right-stick to the bottom. -The required hold time can be configured using [COM_RC_ARM_HYST](#COM_RC_ARM_HYST). Note that by default ([COM_DISARM_MAN](#COM_DISARM_MAN)) you can also disarm in flight using gestures/buttons: you may choose to disable this to avoid accidental disarming. -| 参数 | 描述 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | -| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | -| [COM_RC_ARM_HYST](../advanced_config/parameter_reference.md#COM_RC_ARM_HYST) | Time that RC stick must be held in arm/disarm position before arming/disarming occurs (default: `1` second). | +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MAN_ARM_GESTURE](../advanced_config/parameter_reference.md#MAN_ARM_GESTURE) | Enable arm/disarm stick guesture. `0`: Disabled, `1`: Enabled (default). | +| [COM_DISARM_MAN](../advanced_config/parameter_reference.md#COM_DISARM_MAN) | Enable disarming in flight via switch/stick/button in MC manual thrust modes. `0`: Disabled, `1`: Enabled (default). | ## Arming Button/Switch {#arm_disarm_switch} An _arming button_ or "momentary switch" can be configured to trigger arm/disarm _instead_ of [gesture-based arming](#arm_disarm_gestures) (setting an arming switch disables arming gestures). -The button should be held down for ([nominally](#COM_RC_ARM_HYST)) one second to arm (when disarmed) or disarm (when armed). +The button should be held down for one second to arm (when disarmed) or disarm (when armed). A two-position switch can also be used for arming/disarming, where the respective arm/disarm commands are sent on switch _transitions_. @@ -80,7 +78,7 @@ The switch or button is assigned (and enabled) using [RC_MAP_ARM_SW](#RC_MAP_ARM | 参数 | 描述 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [RC_MAP_ARM_SW](../advanced_config/parameter_reference.md#RC_MAP_ARM_SW) | RC arm switch channel (default: 0 - unassigned). If defined, the specified RC channel (button/switch) is used for arming instead of a stick gesture.
**Note:**
- This setting _disables the stick gesture_!
- This setting applies to RC controllers. It does not apply to Joystick controllers that are connected via _QGroundControl_. | -| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Arm switch is a momentary button.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a button or momentary button where the arm/disarm command ae sent after holding down button for set time ([COM_RC_ARM_HYST](#COM_RC_ARM_HYST)). | +| [COM_ARM_SWISBTN](../advanced_config/parameter_reference.md#COM_ARM_SWISBTN) | Arm switch is a momentary button.
- `0`: Arm switch is a 2-position switch where arm/disarm commands are sent on switch transitions.
-`1`: Arm switch is a momentary button where the arm/disarm command is sent after holding down the button for one second. | :::info The switch can also be set as part of _QGroundControl_ [Flight Mode](../config/flight_mode.md) configuration. @@ -153,14 +151,14 @@ It corresponds to: [COM_PREARM_MODE=1](#COM_PREARM_MODE) (safety switch) and [CB The default startup sequence is: 1. Power-up. - - All actuators locked into disarmed position - - Not possible to arm. + - All actuators locked into disarmed position + - Not possible to arm. 2. Safety switch is pressed. - - System now prearmed: non-throttling actuators can move (e.g. ailerons). - - System safety is off: Arming possible. + - System now prearmed: non-throttling actuators can move (e.g. ailerons). + - System safety is off: Arming possible. 3. Arm command is issued. - - The system is armed. - - All motors and actuators can move. + - The system is armed. + - All motors and actuators can move. ### COM_PREARM_MODE=Disabled and Safety Switch @@ -170,14 +168,14 @@ This corresponds to [COM_PREARM_MODE=0](#COM_PREARM_MODE) (Disabled) and [CBRK_I The startup sequence is: 1. Power-up. - - All actuators locked into disarmed position - - Not possible to arm. + - All actuators locked into disarmed position + - Not possible to arm. 2. Safety switch is pressed. - - _All actuators stay locked into disarmed position (same as disarmed)._ - - System safety is off: Arming possible. + - _All actuators stay locked into disarmed position (same as disarmed)._ + - System safety is off: Arming possible. 3. Arm command is issued. - - The system is armed. - - All motors and actuators can move. + - The system is armed. + - All motors and actuators can move. ### COM_PREARM_MODE=Always and Safety Switch @@ -188,13 +186,13 @@ This corresponds to [COM_PREARM_MODE=2](#COM_PREARM_MODE) (Always) and [CBRK_IO_ The startup sequence is: 1. Power-up. - - System now prearmed: non-throttling actuators can move (e.g. ailerons). - - Not possible to arm. + - System now prearmed: non-throttling actuators can move (e.g. ailerons). + - Not possible to arm. 2. Safety switch is pressed. - - System safety is off: Arming possible. + - System safety is off: Arming possible. 3. Arm command is issued. - - The system is armed. - - All motors and actuators can move. + - The system is armed. + - All motors and actuators can move. ### COM_PREARM_MODE=Safety or Disabled and No Safety Switch @@ -204,11 +202,11 @@ This corresponds to [COM_PREARM_MODE=0 or 1](#COM_PREARM_MODE) (Disabled/Safety The startup sequence is: 1. Power-up. - - All actuators locked into disarmed position - - System safety is off: Arming possible. + - All actuators locked into disarmed position + - System safety is off: Arming possible. 2. Arm command is issued. - - The system is armed. - - All motors and actuators can move. + - The system is armed. + - All motors and actuators can move. ### COM_PREARM_MODE=Always and No Safety Switch @@ -218,11 +216,11 @@ This corresponds to [COM_PREARM_MODE=2](#COM_PREARM_MODE) (Always) and [CBRK_IO_ The startup sequence is: 1. Power-up. - - System now prearmed: non-throttling actuators can move (e.g. ailerons). - - System safety is off: Arming possible. + - System now prearmed: non-throttling actuators can move (e.g. ailerons). + - System safety is off: Arming possible. 2. Arm command is issued. - - The system is armed. - - All motors and actuators can move. + - The system is armed. + - All motors and actuators can move. ### 参数 diff --git a/docs/zh/advanced_config/sensor_thermal_calibration.md b/docs/zh/advanced_config/sensor_thermal_calibration.md index 3a43b02555..f5f4be91a1 100644 --- a/docs/zh/advanced_config/sensor_thermal_calibration.md +++ b/docs/zh/advanced_config/sensor_thermal_calibration.md @@ -94,11 +94,11 @@ To perform an offboard calibration: 9. Open a terminal window in the **Firmware/Tools** directory and run the python calibration script: - ```sh - python process_sensor_caldata.py - ``` + ```sh + python process_sensor_caldata.py + ``` - This will generate a **.pdf** file showing the measured data and curve fits for each sensor, and a **.params** file containing the calibration parameters. + This will generate a **.pdf** file showing the measured data and curve fits for each sensor, and a **.params** file containing the calibration parameters. 10. Power the board, connect _QGroundControl_ and load the parameter from the generated **.params** file onto the board using _QGroundControl_. 由于参数的数量,加载它们可能需要一些时间。 diff --git a/docs/zh/advanced_config/tuning_the_ecl_ekf.md b/docs/zh/advanced_config/tuning_the_ecl_ekf.md index ba875b161b..bd1dd5481d 100644 --- a/docs/zh/advanced_config/tuning_the_ecl_ekf.md +++ b/docs/zh/advanced_config/tuning_the_ecl_ekf.md @@ -1,254 +1,253 @@ -# Using PX4's Navigation Filter (EKF2) +# 使用 PX4 的导航滤波器(EKF2) -This tutorial answers common questions about use of the EKF algorithm used for navigation. +本教程回答了关于使用 EKF 算法进行导航的常见问题。 :::tip -The [PX4 State Estimation Overview](https://youtu.be/HkYRJJoyBwQ) video from the _PX4 Developer Summit 2019_ (Dr. Paul Riseborough) provides an overview of the estimator, and additionally describes both the major changes from 2018/2019, major changes and improvements were added since then. +来自 _PX4 开发者峰会 2019_ 的 [PX4 状态估计概述](https://youtu.be/HkYRJJoyBwQ) 视频 (Dr. Paul Riseborough) 提供了估计器的概述,并额外描述了 2018/2019 年的主要变化,自那时起又增加了许多重大变更和改进。 ::: ## 综述 -PX4's Navigation filter uses an Extended Kalman Filter (EKF) algorithm to process sensor measurements and provide an estimate of the following states: +PX4 的导航滤波器使用扩展卡尔曼滤波 (EKF) 算法来处理传感器测量数据,并提供以下状态的估计值: -- Quaternion defining the rotation from North, East, Down local navigation frame to X, Y, Z body frame -- IMU 处的速度 - 北,东,地 \(m/s) -- Position at the IMU - Latitude (rad), Longitude (rad), Altitude (m) -- IMU gyro bias estimates - X, Y, Z (rad/s) -- IMU accelerometer bias estimates - X, Y, Z (m/s2) -- 地球磁场组分 - 北,东,地 \(gauss\) -- 飞行器机体坐标系磁场偏差 - X, Y, Z \(gauss\) -- 风速-北, 东\(m/s\) -- Terrain altitude (m) +- 定义从北、东、地 (NED) 局部导航坐标系到 X、Y、Z 机体坐标系旋转的四元数 +- IMU 处的速度 - 北,东,地 (m/s) +- IMU 处的位置 - 纬度 (rad)、经度 (rad)、高度 (m) +- IMU 陀螺仪零偏估计 - X、Y、Z (rad/s) +- IMU 加速度计零偏估计 - X、Y、Z (m/s2) +- 地磁场分量 - 北、东、地 (gauss) +- 载具机体坐标系磁场零偏 - X、Y、Z (gauss) +- 风速 - 北、东 (m/s) +- 地形高度 (m) -To improve stability, an "error-state" formulation is implemented -This is especially relevant when estimating the uncertainty of a rotation which is a 3D vector (tangent space of SO(3)). +为了提高稳定性,实施了“误差状态 (error-state)”表述, +这在估计旋转(即 3D 向量,SO(3) 的切空间)的不确定性时尤为重要。 -EKF 在延迟的“融合时间范围”上运行,以允许相对于 IMU 的每次测量的不同时间延迟。 -为了保证所有传感器数据都能在正确的时间内使用,每个传感器的数据都是按照先入先出(FIFO)队列进行缓存,并由EKF从缓存区中读取。 -The delay compensation for each sensor is controlled by the [EKF2\_\*\_DELAY](../advanced_config/parameter_reference.md#ekf2) parameters. +EKF 在延迟的“融合时域 (fusion time horizon)”上运行,以允许每个测量值相对于 IMU 存在不同的时间延迟。 +每个传感器的数据都经过 FIFO 缓冲,并由 EKF 从缓冲区中检索,以便在正确的时间使用。 +每个传感器的延迟补偿由 [EKF2\_\*\_DELAY](../advanced_config/parameter_reference.md#ekf2) 参数控制。 -互补滤波器用于使用缓冲的 IMU 数据将状态从“融合时间范围”向前传播到当前时间。 -The time constant for this filter is controlled by the [EKF2_TAU_VEL](../advanced_config/parameter_reference.md#EKF2_TAU_VEL) and [EKF2_TAU_POS](../advanced_config/parameter_reference.md#EKF2_TAU_POS) parameters. +互补滤波器用于使用缓冲的 IMU 数据将状态从“融合时域”向前传播到当前时间。 +该滤波器的时间常数由 [EKF2_TAU_VEL](../advanced_config/parameter_reference.md#EKF2_TAU_VEL) 和 [EKF2_TAU_POS](../advanced_config/parameter_reference.md#EKF2_TAU_POS) 参数控制。 :::info -The 'fusion time horizon' delay and length of the buffers is determined by [EKF2_DELAY_MAX](../advanced_config/parameter_reference.md#EKF2_DELAY_MAX). -This value should be at least as large as the longest delay `EKF2\_\*\_DELAY`. -减少“融合时间范围”延迟减少了用于将状态向前传播到当前时间的互补滤波器中的误差。 +缓冲区的“融合时域”延迟和长度由 [EKF2_DELAY_MAX](../advanced_config/parameter_reference.md#EKF2_DELAY_MAX) 决定。 +该值应至少与最长的 `EKF2\_\*\_DELAY` 延迟一样大。 +减小“融合时域”延迟会减少用于将状态向前传播到当前时间的互补滤波器的误差。 ::: -EKF仅将IMU数据用于状态预测。 -在EKF推导中,IMU数据不作为观测值使用。 -The algebraic equations for the covariance prediction and measurement jacobians are derived using [SymForce](https://symforce.org/) and can be found here: [Symbolic Derivation](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/python/ekf_derivation/derivation.py). -Covariance update is done using the [Joseph Stabilized form](https://en.wikipedia.org/wiki/Kalman_filter#Deriving_the_posteriori_estimate_covariance_matrix) to improve numerical stability and allow conditional update of independent states. +EKF 仅将 IMU 数据用于状态预测。 +IMU 数据不作为观测值用于 EKF 推导。 +协方差预测和测量雅可比矩阵的代数方程是使用 [SymForce](https://symforce.org/) 推导的,可以在这里找到:[符号推导](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/ekf2/EKF/python/ekf_derivation/derivation.py)。 +协方差更新使用 [约瑟夫稳定形式 (Joseph Stabilized form)](https://en.wikipedia.org/wiki/Kalman_filter#Deriving_the_posteriori_estimate_covariance_matrix) 完成,以提高数值稳定性并允许独立状态的条件更新。 -### Precisions about the position output +### 关于位置输出的精度 -The position is estimated as latitude, longitude and altitude and the INS integration is performed using the WGS84 ellipsoid mode. -However, the position uncertainty is defined in the local navigation frame at the current position (i.e.: NED error in meters). +位置是以纬度、经度和高度估算的,INS(惯性导航系统)积分是使用 WGS84 椭球模型执行的。然而,位置不确定性是在当前位置的局部导航坐标系中定义的(即:NED 误差,单位为米)。 -位置及速度状态变量在输出至控制回路之前会根据IMU与机体坐标系之间的偏差量进行修正。 +位置和速度状态在输出到控制回路之前,会根据 IMU 和机体坐标系之间的偏移量进行调整。 -The position of the IMU relative to the body frame is set by the `EKF2_IMU_POS_X,Y,Z` parameters. +IMU 相对于机体坐标系的位置由 `EKF2_IMU_POS_X,Y,Z` 参数设置。 -In addition to the global position estimate in latitude/longitude/altitude, the filter also provides a local position estimate (NED in meters) by projecting the global position estimate using an [azimuthal_equidistant_projection](https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection) centred on an arbitrary origin. -This origin is automatically set when global position measurements are fused but can also be specified manually. -If no global position information is provided, only the local position is available and the INS integration is performed on a spherical Earth. +除了纬度/经度/高度的全局位置估计外,滤波器还通过使用以任意原点为中心的 [等距方位投影 (azimuthal_equidistant_projection)](https://en.wikipedia.org/wiki/Azimuthal_equidistant_projection) 投影全局位置估计值,提供局部位置估计(以米为单位的 NED)。 +当融合全局位置测量值时,会自动设置此原点,也可以手动指定。 +如果未提供全局位置信息,则只有局部位置可用,并且 INS 积分是在球形地球模型上执行的。 -## 运行单个EKF实例 +## 运行单个 EKF 实例 -The _default behaviour_ is to run a single instance of the EKF. -在这种情况下,在EKF收到数据之前执行传感器选择和故障切换。 -这为防止有限数量的传感器故障,如数据丢失等,提供了保护。 但不能防止传感器提供的不准确数据超过EKF和控制循环的补偿能力。 +_默认行为_ 是运行单个 EKF 实例。 +在这种情况下,传感器选择和故障转移是在数据被 EKF 接收之前执行的。 +这针对有限数量的传感器故障(例如数据丢失)提供了保护,但无法防止传感器提供超出 EKF 和控制回路补偿能力的不准确数据。 -运行单个EKF实例的参数设置为: +运行单个 EKF 实例的参数设置如下: - [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) = 0 - [EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG) = 0 - [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE) = 1 - [SENS_MAG_MODE](../advanced_config/parameter_reference.md#SENS_MAG_MODE) = 1 -## 运行多个EKF实例 +## 运行多个 EKF 实例 -根据IMU和磁强计的数量以及自动驾驶仪的CPU能力,EKF可以运行多个实例。 -这提供了一系列更广泛的传感器错误的保护,每个EKF实例使用不同的传感器组合实现了这一点。 -通过比较每个EKF实例的内部一致性,EKF选择器能够确定具有最佳数据一致性的EKF和传感器组合。 -这样可以检测和隔离IMU偏差、饱和或数据卡住等故障。 +根据 IMU 和磁力计的数量以及飞控的 CPU 能力,可以运行多个 EKF 实例。 +这针对更广泛的传感器误差提供了保护,并通过每个 EKF 实例使用不同的传感器组合来实现。 +通过比较每个 EKF 实例的内部一致性,EKF 选择器能够确定具有最佳数据一致性的 EKF 和传感器组合。 +这使得可以检测并隔离诸如 IMU 零偏突变、饱和或数据卡死等故障。 -The total number of EKF instances is the product of the number of IMU's and number of magnetometers selected by [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) and [EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG) and is given by the following formula: +EKF 实例的总数是 [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) 和 [EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG) 选择的 IMU 数量和磁力计数量的乘积,由以下公式给出: > N_instances = MAX([EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) , 1) x MAX([EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG) , 1) -例如,一个带有 2 个IMU和 2 个磁强计的自动化驾驶仪可以在 EKF2_MULTI_IMU = 2 和 EKF2_MULTI_MAG = 2 的情况下运行,总共 4 个EKF实例,其中每个实例使用以下传感器组合: +例如,具有 2 个 IMU 和 2 个磁力计的飞控可以运行 EKF2_MULTI_IMU = 2 和 EKF2_MULTI_MAG = 2,总共 4 个 EKF 实例,其中每个实例使用以下传感器组合: -- EKF instance 1 : IMU 1, magnetometer 1 -- EKF instance 2 : IMU 1, magnetometer 2 -- EKF instance 3 : IMU 2, magnetometer 1 -- EKF instance 4 : IMU 2, magnetometer 2 +- EKF 实例 1 : IMU 1, 磁力计 1 +- EKF 实例 2 : IMU 1, 磁力计 2 +- EKF 实例 3 : IMU 2, 磁力计 1 +- EKF 实例 4 : IMU 2, 磁力计 2 -可处理的IMU或磁强计传感器的最大数量为每种传感器有4个,因此理论上最大有 4 x 4 = 16 个EKF实例。 -实际上,这种做法受到现有计算资源的限制。 -在开发这一功能的过程中,使用基于STM32F7的硬件的CPU进行测试,结果显示 4 个EKF实例具有可接受的处理负载和内存利用率裕度。 +可以处理的 IMU 或磁力计传感器的最大数量各为 4 个,理论最大值为 4 x 4 = 16 个 EKF 实例。 +实际上,这受到可用计算资源的限制。 +在此功能的开发过程中,使用基于 STM32F7 CPU 的硬件进行的测试表明,4 个 EKF 实例具有可接受的处理负载和内存利用率余量。 :::warning -Ground based testing to check CPU and memory utilisation should be performed before flying. +飞行前应进行地面测试以检查 CPU 和内存利用率。 ::: -If [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) >= 3, then the failover time for large rate gyro errors is further reduced because the EKF selector is able to apply a median select strategy for faster isolation of the faulty IMU. +如果 [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) >= 3,则针对大速率陀螺仪误差的故障转移时间将进一步缩短,因为 EKF 选择器能够应用中值选择策略以更快地隔离故障 IMU。 -多EKF实例的设置由以下参数控制: +多 EKF 实例的设置由以下参数控制: - [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE): - Set to 0 if running multiple EKF instances with IMU sensor diversity, ie [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) > 1. + 如果是以 IMU 传感器多样性运行多个 EKF 实例,即 [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) > 1,则设置为 0。 - 当设置为 1 (单个EKF 操作默认值)时,传感器模块选择EKF使用的IMU 数据。 - 这种保护可防止来自传感器的数据丢失,但并不能防止不良的传感器数据。 + 当设置为 1(单个 EKF 的默认值)时,传感器模块选择 EKF 使用的 IMU 数据。 + 这提供了针对传感器数据丢失的保护,但不提供针对错误传感器数据的保护。 当设置为 0 时,传感器模块不进行选择。 - [SENS_MAG_MODE](../advanced_config/parameter_reference.md#SENS_MAG_MODE): - Set to 0 if running multiple EKF instances with magnetometer sensor diversity, ie [EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG) > 1. + 如果是以磁力计传感器多样性运行多个 EKF 实例,即 [EKF2_MULTI_MAG](../ + advanced_config/parameter_reference.md#EKF2_MULTI_MAG) > 1,则设置为 0。 - 当设置为 1 (单个EKF 操作默认值)时,传感器模块选择EKF使用的磁强计数据。 - 这种保护可防止来自传感器的数据丢失,但并不能防止不良的传感器数据。 + 当设置为 1(单个 EKF 的默认值)时,传感器模块选择 EKF 使用的磁力计数据。 + 这提供了针对传感器数据丢失的保护,但不提供针对错误传感器数据的保护。 当设置为 0 时,传感器模块不进行选择。 - [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU): - This parameter specifies the number of IMU sensors used by the multiple EKF's. - If `EKF2_MULTI_IMU` <= 1, then only the first IMU sensor will be used. - When [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE) = 1, this will be the sensor selected by the sensor module. - If `EKF2_MULTI_IMU` >= 2, then a separate EKF instance will run for the specified number of IMU sensors up to the lesser of 4 or the number of IMU's present. + 此参数指定多个 EKF 使用的 IMU 传感器数量。 + 如果 `EKF2_MULTI_IMU` <= 1,则仅使用第一个 IMU 传感器。 + 当 [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE) = 1 时,这将是传感器模块选择的传感器。 + 如果 `EKF2_MULTI_IMU` >= 2,那么将为指定数量的 IMU 传感器运行独立的 EKF 实例,最多支持 4 个或实际存在的 IMU 数量(取两者中的较小值)。 - [EKF2_MULTI_MAG](../advanced_config/parameter_reference.md#EKF2_MULTI_MAG): - This parameter specifies the number of magnetometer sensors used by the multiple EKF's - If `EKF2_MULTI_MAG` <= 1, then only the first magnetometer sensor will be used. - When [SENS_MAG_MODE](../advanced_config/parameter_reference.md#SENS_MAG_MODE) = 1, this will be the sensor selected by the sensor module. - If `EKF2_MULTI_MAG` >= 2, then a separate EKF instance will run for the specified number of magnetometer sensors up to the lesser of 4 or the number of magnetometers present. + 此参数指定多个 EKF 使用的磁力计传感器数量。 + 如果 `EKF2_MULTI_MAG` <= 1,则仅使用第一个磁力计传感器。 + 当 [SENS_MAG_MODE](../advanced_config/parameter_reference.md#SENS_MAG_MODE) = 1 时,这将是传感器模块选择的传感器。 + 如果 `EKF2_MULTI_MAG` >= 2,那么将为指定数量的磁力计传感器运行独立的 EKF 实例,最多支持 4 个或实际存在的磁力计数量(取两者中的较小值)。 :::info -The recording and [EKF2 replay](../debug/system_wide_replay.md#ekf2-replay) of flight logs with multiple EKF instances is not supported. -To enable recording for EKF replay you must set the parameters to enable a [single EKF instance](#running-a-single-ekf-instance). +不支持多 EKF 实例飞行日志的记录和 [EKF2 回放](../debug/system_wide_replay.md#ekf2-replay)。 +要启用 EKF 回放记录,必须设置参数以启用 [单个 EKF 实例](#running-a-single-ekf-instance)。 ::: -## 它使用什么传感器测量值? +## 它使用哪些传感器测量? -EKF 具有不同的操作模式,以允许不同的传感器测量组合。 -滤波器在启动时会检查传感器的最小可行组合,并且在完成初始倾斜,偏航和高度对准之后,进入提供旋转,垂直速度,垂直位置,IMU 增量角度偏差和 IMU 增量速度偏差估计的模式。 +EKF 具有不同的操作模式,允许不同的传感器测量组合。 +启动时,滤波器会检查传感器的最小可用组合,并在初始倾斜、偏航和高度对准完成后,进入提供旋转、垂直速度、垂直位置、IMU 角度增量零偏和 IMU 速度增量零偏估计的模式。 -此模式需要 IMU 数据,一个偏航源(磁力计或外部视觉)和一个高度数据源。 -所有EKF操作模式都需要这个最小数据集。 -在此基础上可以使用其它传感器数据来估计额外的状态变量。 +此模式需要 IMU 数据、偏航源(磁力计或外部视觉)和高度数据源。 +所有 EKF 工作模式都需要此最小数据集。 +其他传感器数据可用于估计额外状态。 ### IMU -- 三轴机体固连惯性测量单元,以最小100Hz的频率获取增量角度和增量速度数据 。 - 注意:在 EKF 使用它们之前,应该使用圆锥校正算法校正 IMU 增量角度数据。 +- 固定在机体上的三轴 IMU,以至少100Hz的频率获取增量角度和角速度数据 。 + 注意:在 EKF 使用 IMU 角度增量数据之前,应该使用圆锥校正算法校正。 -### 磁罗盘 +### 磁力计 -Three axis body fixed magnetometer data at a minimum rate of 5Hz is required to be considered by the estimator. +固定在机体上的三轴磁力计数据,至少以 5Hz 提供数据才会被估计器用于估计。 ::: info -- The magnetometer **biases** are only observable while the drone is rotating -- The true heading is observable when the vehicle is accelerating (linear acceleration) while absolute position or velocity measurements are fused (e.g. GPS). - This means that magnetometer heading measurements are optional after initialization if those conditions are met often enough to constrain the heading drift (caused by gyro bias). +- 磁力计 **零偏 (biases)** 仅在无人机旋转时可观测。 +- 当载具处于加速状态(线性加速度)时,可通过融合绝对位置或速度测量数据(例如GPS)来观测真实航向。 + 这意味着在初始化后,如果满足上述条件且频率足够高以约束(由陀螺仪偏置引起的)航向漂移,则磁力计航向测量是可选的。 ::: -Magnetometer data fusion can be configured using [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE): +磁力计数据融合可以使用 [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE) 进行配置: -0. Automatic: - - The magnetometer readings only affect the heading estimate before arming, and the whole attitude after arming. - - Heading and tilt errors are compensated when using this method. - - Incorrect magnetic field measurements can degrade the tilt estimate. - - The magnetometer biases are estimated whenever observable. -1. Magnetic heading: - - Only the heading is corrected. - The tilt estimate is never affected by incorrect magnetic field measurements. - - Tilt errors that could arise when flying without velocity/position aiding are not corrected when using this method. - - The magnetometer biases are estimated whenever observable. -2. Deprecated -3. Deprecated -4. Deprecated -5. None: - - Magnetometer data is never used. - This is useful when the data can never be trusted (e.g.: high current close to the sensor, external anomalies). - - The estimator will use other sources of heading: [GPS heading](#yaw-measurements) or external vision. - - When using GPS measurements without another source of heading, the heading can only be initialized after sufficient horizontal acceleration. - See [Estimate yaw from vehicle movement](#yaw-from-gps-velocity) below. -6. Init only: - - Magnetometer data is only used to initialize the heading estimate. - This is useful when the data can be used before arming but not afterwards (e.g.: high current after the vehicle is armed). - - After initialization, the heading is constrained using other observations. - - Unlike mag type `None`, when combined with GPS measurements, this method allows position controlled modes to run directly during takeoff. +0. 自动 (Automatic): + - 磁力计读数仅在解锁前影响航向估计,解锁后影响整个姿态。 + - 使用此方法时会补偿航向和倾斜误差。 + - 不正确的磁场测量会降低倾斜估计的质量。 + - 磁力计零偏会在可观测时被估计。 +1. 磁航向 (Magnetic heading): + - 仅修正航向。 + 倾斜估计永远不会受到不正确磁场测量的影响。 + - 使用此方法时,不会修正因没有速度/位置辅助飞行而产生的倾斜误差。 + - 磁力计零偏会在可观测时被估计。 +2. 已弃用 +3. 已弃用 +4. 已弃用 +5. 无 (None): + - 永不使用磁力计数据。 + 当数据完全不可信时(例如:传感器附近有大电流、外部异常),这很有用。 + - 估计器将使用其他航向源:[GPS 航向](#yaw-measurements) 或外部视觉。 + - 当使用 GPS 测量而没有其他航向源时,航向只能在获得足够的水平加速度后才能初始化。 + 参见下文的 [从载具运动估计偏航](#yaw-from-gps-velocity)。 +6. 仅初始化 (Init only): + - 磁力计数据仅用于初始化航向估计。 + 当数据可以在解锁前使用但解锁后不能使用(例如:载具解锁后有大电流)时,这很有用。 + - 初始化后,航向使用其他观测值进行约束。 + - 与 `None` 模式不同,当与 GPS 测量结合使用时,此方法允许位置控制模式在起飞期间直接运行。 -The following selection tree can be used to select the right option: +可以使用以下选择树来选择正确的选项: -![EKF mag type selection tree](../../assets/config/ekf/ekf_mag_type_selection_tree.png) +![EKF 磁力计类型选择树](../../assets/config/ekf/ekf_mag_type_selection_tree.png) ### 高度 -A source of height data - GPS, barometric pressure, range finder, external vision or a combination of those at a minimum rate of 5Hz is required. +需要高度数据源 - GPS、气压计、测距仪、外部视觉或这些源的组合,最小速率为 5Hz。 -If none of the selected measurements are present, the EKF will not start. -当检测到这些测量值时,EKF 将初始化状态并完成倾角和偏航对准。 -当倾角和偏航对齐完成后,EKF 可以转换到其它操作模式,从而可以使用其它传感器数据: +如果不存在任何选定的测量值,EKF 将不会启动。 +当检测到这些测量值时,EKF 将初始化状态并完成倾斜和偏航对准。 +当倾斜和偏航对准完成后,EKF 可以转换到其他操作模式,从而能够使用额外的传感器数据: -Each height source can be enabled/disabled using its dedicated control parameter: +可以使用其专用控制参数启用/禁用每个高度源: - [GNSS/GPS](#gnss-gps): [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) -- [Barometer](#barometer): [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) -- [Range finder](#range-finder): [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) -- [External vision](#external-vision-system): Enabled when [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) is set to "Vision" +- [气压计](#barometer): [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) +- [测距仪](#range-finder): [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) +- [外部视觉](#external-vision-system): 当 [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) 设置为 "Vision" 时启用 -Over the long term the height estimate follows the "reference source" of height data. -This reference is defined by the [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) parameter. +从长远来看,高度估计遵循高度数据的“参考源”。 +此参考由 [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) 参数定义。 -#### Typical configurations +#### 典型配置 -| | [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) | [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) | [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) | [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) | -| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| Outdoor (default) | 7 (Lon/lat/alt/vel) | 1 (enabled) | 1 ([conditional](#conditional-range-aiding)) | 1 (GNSS) | -| Indoor (non-flat terrain) | 0 (disabled) | 1 (enabled) | 1 ([conditional](#conditional-range-aiding)) | 2 (range) | -| Indoor (flat terrain) | 0 (disabled) | 1 (enabled) | 2 ([always enabled](#range-height-fusion)) | 2 (range) | -| External vision | As required | As required | As required | 3 (vision) | +| | [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) | [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) | [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) | [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | +| 户外 (默认) | 7 (经/纬/高/速) | 1 (启用) | 1 ([条件性](#conditional-range-aiding)) | 1 (GNSS) | +| 室内 (非平坦地形) | 0 (禁用) | 1 (启用) | 1 ([条件性](#conditional-range-aiding)) | 2 (测距仪) | +| 室内 (平坦地形) | 0 (禁用) | 1 (启用) | 2 ([始终启用](#range-height-fusion)) | 2 (测距仪) | +| 外部视觉 | 按需 | 按需 | 按需 | 3 (视觉) | ### Barometer -Enable/disable using [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) as a source for [Height](#height) data. +使用 [EKF2_BARO_CTRL](../advanced_config/parameter_reference.md#EKF2_BARO_CTRL) 启用/禁用作为 [高度](#height) 数据的来源。 -Note that data from only one barometer is fused, even if multiple barometers are available. -The barometer with the highest [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) priority value is selected first, falling back to the next highest priority barometer if a sensor fault is detected. -If barometers have equal-highest priorities, the first detected is used. -A barometer can be completely disabled as a possible source by setting its `CAL_BAROx_PRIO` value to `0` (disabled). +注意,即使有多个气压计可用,也只融合来自一个气压计的数据。 +首先选择具有最高 [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) 优先级值的气压计,如果检测到传感器故障,则回退到下一个最高优先级的气压计。 +如果气压计具有相同的最高优先级,则使用第一个检测到的气压计。 +可以通过将其 `CAL_BAROx_PRIO` 值设置为 `0`(禁用)来完全禁用某个气压计作为可能的来源。 -See [Height](#height) more details about the configuration of height sources. +有关高度源配置的更多详细信息,请参阅 [高度](#height)。 -#### 静态气压位置误差校正 +#### 静压位置误差校正 -气压表示的海拔高度因机体风的相对速度和方向造成的空气动力扰动而发生误差。 -This is known in aeronautics as _static pressure position error_. -使用ECL/EKF2估计器库的EKF2模块提供了补偿这些误差的方法,只要风速状态估计是激活的。 +气压高度容易受到由载具风相对速度和方向产生的气动扰动引起的误差的影响。 +这在航空学中被称为 _静压位置误差 (static pressure position error)_。 +使用 ECL/EKF2 估计器库的 EKF2 模块提供了一种补偿这些误差的方法,前提是风速状态估计处于激活状态。 -For vehicles operating in a fixed-wing mode, wind speed state estimation requires either [Airspeed](#airspeed) and/or [Synthetic Sideslip](#synthetic-sideslip) fusion to be enabled. +对于以固定翼模式运行的飞行器,风速状态估计需要启用 [空速](#airspeed) 和/或 [合成侧滑](#synthetic-sideslip) 融合。 -For multi-rotors, fusion of [Drag Specific Forces](#mc_wind_estimation_using_drag) can be enabled and tuned to provide the required wind velocity state estimates. +对于多旋翼飞行器,可以启用并调整 [阻力比力](#mc_wind_estimation_using_drag) 的融合,以提供所需的风速状态估计。 -EKF2模块将误差建模为与机体固连的椭球体,在将其转换为高度估计之前,它指定了从大气气压中加/减的动态气压的分量。 +EKF2 模块将误差建模为一个机体固定的椭球体,该椭球体指定了在转换为高度估计之前,需要从气压中增加/减去的动压比例。 -以下方法可获得良好的调参参数: +可以通过以下方式获得良好的调参: -1. Fly once in [Position mode](../flight_modes_mc/position.md) repeatedly forwards/backwards/left/right/up/down between rest and maximum speed (best results are obtained when this testing is conducted in still conditions). +1. 在 [位置模式](../flight_modes_mc/position.md) 下反复向前/向后/向左/向右/向上/向下飞行,在静止和最大速度之间切换(在静风条件下进行此测试可获得最佳结果)。 -2. Extract the `.ulg` log file using, for example, [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) +2. 使用例如 [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) 提取 `.ulg` 日志文件。 - ::: info - The same log file can be used to tune the [multirotor wind estimator](#mc_wind_estimation_using_drag). + 同一日志文件可用于调整 [多旋翼风速估计器](#mc_wind_estimation_using_drag)。 ::: -3. Use the log with the [baro_static_pressure_compensation_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/baro_static_pressure_compensation) Python script to obtain the optimal set of parameters. +3. 使用 [baro_static_pressure_compensation_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/baro_static_pressure_compensation) Python 脚本处理日志,以获得最佳参数集。 -调整参数: +调参参数: - [EKF2_PCOEF_XP](../advanced_config/parameter_reference.md#EKF2_PCOEF_XP) - [EKF2_PCOEF_XN](../advanced_config/parameter_reference.md#EKF2_PCOEF_XN) @@ -256,329 +255,383 @@ EKF2模块将误差建模为与机体固连的椭球体,在将其转换为高 - [EKF2_PCOEF_YN](../advanced_config/parameter_reference.md#EKF2_PCOEF_YN) - [EKF2_PCOEF_Z](../advanced_config/parameter_reference.md#EKF2_PCOEF_Z) -#### Barometer bias compensation +#### 气压计零偏补偿 -A barometer at a constant altitude is subject to drift in its measurements due to changes in the ambient pressure environment or variations of the sensor temperature. -To compensate for this measurement error, EKF2 estimates the bias using GNSS height (if available) a "non drifting" reference. -No tuning is required. +恒定高度下的气压计容易因环境压力变化或传感器温度变化而产生测量漂移。 +为了补偿这种测量误差,EKF2 使用 GNSS 高度(如果可用)作为“无漂移”参考来估计零偏。 +不需要调参。 ### GNSS/GPS #### 位置和速度测量 -如果满足以下条件,GPS 测量将用于位置和速度: +如果满足以下条件,将使用 GPS 测量进行位置和速度估计: -- GPS use is enabled via setting of the [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) parameter. -- GPS 信号质量检查已通过。 - These checks are controlled by the [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) and `EKF2_REQ_*` parameters. +- 通过设置 [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) 参数启用 GPS 使用。 +- GPS 质量检查已通过。 + 这些检查由 [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) 和 `EKF2_REQ_*` 参数控制。 -For more details about the configuration of height sources, [click here](#height). +有关高度源配置的更多详细信息,请 [点击这里](#height)。 #### 偏航角测量 -Some GPS receivers such as the [Trimble MB-Two RTK GPS receiver](https://oemgnss.trimble.com/en/products/receiver-modules/mb-two) can be used to provide a heading measurement that replaces the use of magnetometer data. -在存在大型磁场异常的环境中工作时,或在高纬度地区,地球磁场具有很大的磁倾角时,这可能是一个重要的优势。 -Use of GPS yaw measurements is enabled by setting bit position 3 to 1 (adding 8) in the [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) parameter. +某些 GPS 接收机,例如 [Trimble MB-Two RTK GPS 接收机](https://oemgnss.trimble.com/en/products/receiver-modules/mb-two),可用于提供航向测量,以替代磁力计数据的使用。 +当在存在大型磁异常的环境中或在地球磁场倾角较大的纬度地区运行时,这可能是一个显著的优势。 +通过将 [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) 参数中的第 3 位设置为 1(加 8)来启用 GPS 偏航测量。 #### 从 GPS 速度数据获取偏航角 -EKF在内部运行一个附加的多假设滤波器,它使用多个3-状态---北/东向(N/E)的速度和偏航角---的扩展卡尔曼滤波器(EKF)。 -然后使用高斯加和滤波器(GSF)合并这些偏航角的估计值。 -单个3-状态的EKF使用了IMU和GPS水平速度数据(加上可选的空速数据),而不依赖于事先对偏航角或磁强计测量有任何知识。 -这里提供了一个对于主滤波器的偏航角备份,当起飞后导航丢失,表明磁力计的偏航估计值不好时,它被用于重置主 EKF 滤波器的24-状态的中的偏航数据。 -This will result in an `Emergency yaw reset - magnetometer use stopped` message information message at the GCS. +EKF 在内部运行一个额外的多假设滤波器,该滤波器使用多个 3 状态扩展卡尔曼滤波器 (EKF),其状态为北东 (NE) 速度和偏航角。 +然后使用高斯求和滤波器 (GSF) 组合这些单独的偏航角估计值。 +单独的 3 状态 EKF 使用 IMU 和 GPS 水平速度数据(加上可选的空速数据),不依赖于偏航角或磁力计测量的任何先验知识。 +这为自主滤波器的偏航提供了备份,并用于在起飞后导航丢失表明来自磁力计的偏航估计错误时重置主 24 状态 EKF 的偏航。 +这将导致 GCS 显示 `Emergency yaw reset - magnetometer use stopped`(紧急航向重置 - 磁力计停止使用)信息消息。 -Data from this estimator is logged when ekf2 replay logging is enabled and can be viewed in the `yaw_estimator_status` message. -The individual yaw estimates from the individual 3-state EKF yaw estimators are in the `yaw` fields. -The GSF combined yaw estimate is in the `yaw_composite` field. -The variance for the GSF yaw estimate is in the `yaw_variance` field. -所有角度的单位均为弧度。 -Weightings applied by the GSF to the individual 3-state EKF outputs are in the`weight` fields. +启用 ekf2 回放日志记录后,将记录来自此估计器的数据,并可在 `yaw_estimator_status` 消息中查看。 +来自各个 3 状态 EKF 偏航估计器的单独偏航估计值位于 `yaw` 字段中。 +GSF 组合偏航估计值位于 `yaw_composite` 字段中。 +GSF 偏航估计值的方差位于 `yaw_variance` 字段中。 +所有角度均以弧度为单位。 +GSF 应用于各个 3 状态 EKF 输出的权重位于 `weight` 字段中。 -这也使得 ECL 能够在没有任何磁力计、或没有双天线 GPS 接收器的情况下运行,并提供偏航数据,只要起飞后能够进行某种水平的移动,偏航数据就变得可观测。 -To use this feature, set [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE) to `none` (5) to disable magnetometer use. -一旦机体完成了足够的水平移动,使偏航角可观测, 24-状态的主EKF将使其偏航角与GSF的估计值对齐,并开始使用 GPS。 +这也可以实现在没有任何磁力计数据或双天线 GPS 接收机的情况下进行偏航操作,前提是起飞后可以进行一些水平运动以使偏航变得可观测。 +要使用此功能,请将 [EKF2_MAG_TYPE](../advanced_config/parameter_reference.md#EKF2_MAG_TYPE) 设置为 `none` (5) 以禁用磁力计使用。 +一旦载具进行了足够的水平运动使偏航可观测,主 24 状态 EKF 将把它的偏航对准 GSF 估计值并开始使用 GPS。 #### 双 GPS 接收器 -GPS接收器提供的数据可以用基于所报告数据的精确度的加权算法混合(如果两者都以相同的速度输出数据并使用相同的精确度,这样做效果最好)。 -如果来自接收器的数据丢失,该机制还提供了自动故障转移,(例如,它允许使用标准 GPS 作为更精确的 RTK 接收器的备份)。 -This is controlled by the [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) parameter. +可以使用一种算法混合来自 GPS 接收机的数据,该算法根据报告的精度对数据进行加权(如果两个接收机以相同的速率输出数据并使用相同的精度,效果最佳)。 +如果来自接收机的数据丢失,该机制还提供自动故障转移(例如,它允许使用标准 GPS 作为更精确的 RTK 接收机的备份)。 +这由 [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) 参数控制。 -The [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) parameter is set by default to disable blending and always use the first receiver, so it will have to be set to select which receiver accuracy metrics are used to decide how much each receiver output contributes to the blended solution. -Where different receiver models are used, it is important that the [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) parameter is set to a value that uses accuracy metrics that are supported by both receivers. -For example do not set bit position 0 to `true` unless the drivers for both receivers publish values in the `s_variance_m_s` field of the `vehicle_gps_position` message that are comparable. -由于精确度定义方法不同,例如 CEP 对比 1-sigma 等等,不同制造商的接收器可能很难做到这一点。 +[SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) 参数默认设置为禁用混合并始终使用第一个接收机,因此必须设置它以选择使用哪些接收机精度指标来决定每个接收机输出对混合解算的贡献程度。 +当使用不同的接收机型号时,重要的是将 [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) 参数设置为两个接收机都支持的精度指标值。 +例如,除非两个接收机的驱动程序都在 `vehicle_gps_position` 消息的 `s_variance_m_s` 字段中发布可比较的值,否则不要将第 0 位设置为 `true`。 +由于不同制造商定义精度的方式不同(例如 CEP 与 1-sigma 等),这对于来自不同制造商的接收机可能很困难。 -在设置过程中应检查以下条目: +设置期间应检查以下项目: -- 验证第二接收器的数据是否存在。 - This will be logged as `vehicle_gps_position_1` and can also be checked when connected via the _nsh console_ using the command `listener vehicle_gps_position -i 1`. - The [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter will need to be set correctly. -- Check the `s_variance_m_s`, `eph` and `epv` data from each receiver and decide which accuracy metrics can be used. - If both receivers output sensible `s_variance_m_s` and `eph` data, and GPS vertical position is not being used directly for navigation, then setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 3 is recommended. - Where only `eph` data is available and both receivers do not output `s_variance_m_s` data, set [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 2. - Bit position 2 would only be set if the GPS had been selected as the reference height source with the [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) parameter and both receivers output sensible `epv` data. -- The output from the blended receiver data is logged as `ekf_gps_position`, and can be checked whilst connect via the nsh terminal using the command `listener ekf_gps_position`. -- 如果接收器以不同的频率输出, 混合输出的频率将是较低的接收器的频率。 - 在可能的情况下,接收器应配置为同样的输出频率。 +- 验证第二个接收机的数据是否存在。 + 这将记录为 `vehicle_gps_position_1`,也可以在连接 _nsh console_ 时使用命令 `listener vehicle_gps_position -i 1` 进行检查。 + [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) 参数需要正确设置。 +- 检查来自每个接收机的 `s_variance_m_s`、`eph` 和 `epv` 数据,并决定可以使用哪些精度指标。 + 如果两个接收机都输出合理的 `s_variance_m_s` 和 `eph` 数据,并且 GPS 垂直位置未直接用于导航,则建议将 [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) 设置为 3。 + 如果只有 `eph` 数据可用,且两个接收机都不输出 `s_variance_m_s` 数据,则将 [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) 设置为 2。 + 只有当 GPS 已通过 [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) 参数被选为参考高度源,且两个接收机都输出合理的 `epv` 数据时,第 2 位才会被置位。 +- 混合接收机数据的输出记录为 `ekf_gps_position`,可以在连接 nsh 终端时使用命令 `listener ekf_gps_position` 进行检查。 +- 若各接收机输出速率不同,融合后的输出速率将与速率较慢的接收机保持一致。 + 在可能的情况下,接收机应配置为以相同的速率输出。 -#### 全球导航卫星系统性能要求 +#### GNSS 性能要求 -For the ECL to accept GNSS data for navigation, certain minimum requirements need to be satisfied over a period of time, defined by [EKF2_REQ_GPS_H](../advanced_config/parameter_reference.md#EKF2_REQ_GPS_H) (10 seconds by default). +为了让 ECL 接受 GNSS 数据进行导航,需要在一段时间内满足某些最低要求,该时间由 [EKF2_REQ_GPS_H](../advanced_config/parameter_reference.md#EKF2_REQ_GPS_H) 定义(默认为 10 秒)。 -Minima are defined in the [EKF2_REQ_\*](../advanced_config/parameter_reference.md#EKF2_REQ_EPH) parameters and each check can be enabled/disabled using the [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) parameter. +最小值在 [EKF2_REQ_\*](../advanced_config/parameter_reference.md#EKF2_REQ_EPH) 参数中定义,并且可以使用 [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) 参数启用/禁用每个检查。 -下表显示了从全球导航卫星系统数据中直接报告或计算的各种衡量标准,以及ECL使用的数据的最低要求值。 -In addition, the _Average Value_ column shows typical values that might reasonably be obtained from a standard GNSS module (e.g. u-blox M8 series) - i.e. values that are considered good/acceptable. +下表显示了直接报告或从 GNSS 数据计算出的不同指标,以及 ECL 使用数据所需的最小值。 +此外,_平均值 (Average Value)_ 列显示了可能从标准 GNSS 模块(例如 u-blox M8 系列)合理获得的典型值 - 即被认为良好/可接受的值。 -| 指标 | 最小需求 | 平均值 | 单位 | 备注 | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| eph | < 3 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_EPH)) | 0.8 | m | 水平位置误差的标准偏差 | -| epv | < 5 ([EKF2_REQ_EPV](../advanced_config/parameter_reference.md#EKF2_REQ_EPV)) | 1.5 | m | 垂直位置误差的标准偏差 | -| Number of satellites | ≥6 ([EKF2_REQ_NSATS](../advanced_config/parameter_reference.md#EKF2_REQ_NSATS)) | 14 | - | | -| sacc | < 0.5 ([EKF2_REQ_SACC](../advanced_config/parameter_reference.md#EKF2_REQ_SACC)) | 0.2 | m/s | 水平速度误差的标准偏差 | -| fix type | ≥ 3 | 4 | - | 0-1: 不修正, 2: 2D 修正, 3: 3D 修正, 4: RTCM 编码差分, 5: 实时动态定位, 浮动, 6: 实时动态定位, 固定, 8: 外推 | -| PDOP | < 2.5 ([EKF2_REQ_PDOP](../advanced_config/parameter_reference.md#EKF2_REQ_PDOP)) | 1.0 | - | 精度降低位置 | -| hpos drift rate | < 0.1 ([EKF2_REQ_HDRIFT](../advanced_config/parameter_reference.md#EKF2_REQ_HDRIFT)) | 0.01 | m/s | 根据所报告的全球导航卫星系统位置计算出的漂移率(在固定状态时)。 | -| vpos drift rate | < 0.2 ([EKF2_REQ_VDRIFT](../advanced_config/parameter_reference.md#EKF2_REQ_VDRIFT)) | 0.02 | m/s | 根据所报告的全球导航卫星系统高度计算出的漂移率(在固定时)。 | -| hspd | < 0.1 ([EKF2_REQ_HDRIFT](../advanced_config/parameter_reference.md#EKF2_REQ_HDRIFT)) | 0.01 | m/s | 所报告的全球导航卫星系统横向速度的筛选星等。 | -| vspd | < 0.2 ([EKF2_REQ_VDRIFT](../advanced_config/parameter_reference.md#EKF2_REQ_VDRIFT)) | 0.02 | m/s | 所报告的全球导航卫星系统垂直速度的滤波量级。 | +| 指标 (Metric) | 最低要求 | 平均值 (Average Value) | 单位 (Units) | 备注 | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| eph | < 3 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_EPH)) | 0.8 | 米 | 水平位置误差的标准偏差 | +| epv | < 5 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_EPV)) | 1.5 | 米 | 垂直位置误差的标准偏差 | +| 卫星数量 | ≥ 6 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_NSATS)) | 14 | - | | +| sacc | < 0.5 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_SACC)) | 0.2 | 米/秒 | 水平速度误差的标准偏差 | +| 定位类型 (fix type) | ≥ 3 | 4 | - | 0-1: 无定位, 2: 2D 定位, 3: 3D 定位, 4: RTCM 码差分, 5: 实时动态 (RTK) 浮点解, 6: 实时动态 (RTK) 固定解, 8: 外推值 | +| 位置精度衰減因子(PDOP) | < 2.5 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_PDOP)) | 1.0 | - | 位置精度衰减 | +| hpos 漂移率 | < 0.1 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_HDRIFT)) | 0.01 | 米/秒 | 静止时基于 GNSS 位置计算的漂移率 | +| vpos 漂移率 | < 0.2 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_VDRIFT)) | 0.02 | 米/秒 | 静止时基于 GNSS 高度计算的漂移率。 | +| hspd | < 0.1 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_HDRIFT)) | 0.01 | 米/秒 | 报告的 GNSS 水平速度的滤波幅值。 | +| 报告的 GNSS 垂直速度的滤波幅值。 | < 0.2 ([EKF2_REQ_EPH](../advanced_config/parameter_reference.md#EKF2_REQ_VDRIFT)) | 0.02 | 米/秒 | 所报告的全球导航卫星系统垂直速度的滤波量级。 | :::info -The `hpos_drift_rate`, `vpos_drift_rate` and `hspd` are calculated over a period of 10 seconds and published in the `ekf2_gps_drift` topic. -Note that `ekf2_gps_drift` is not logged! +`hpos_drift_rate`、`vpos_drift_rate` 和 `hspd` 是在 10 秒的时间段内计算的,并在 `ekf2_gps_drift` 主题中发布。 +注意 `ekf2_gps_drift` 不会被记录! ::: +#### GNSS 故障检测 + +PX4 的 GNSS 故障检测使用基于测量验证的选择性融合控制来防止恶意或错误的 GNSS 信号。 + +故障检测逻辑取决于 GPS 模式,并且对于水平位置和高度测量的操作也有所不同。 +该模式使用 [EKF2_GPS_MODE](../advanced_config/parameter_reference.md#EKF2_GPS_MODE) 参数设置: + +- **自动 (`0`)** (默认): 假设 GNSS 通常是可靠的,并且很可能会恢复。 + 如果此时没有其他位置源可用,EKF2 会在融合超时时重置。 +- **航位推算 (`1`)**: 假设 GNSS 可能会无限期丢失,因此当我们有其他位置数据估计时应避免重置。 + 如果没有其他位置或速度源可用,EKF2 可能会重置。 + 如果 GNSS 高度或水平位置数据漂移,系统将同时禁用这两个测量值的融合(即使其中一个仍能通过验证),并避免执行重置。 + +##### 检测逻辑 + +水平位置: + +- **自动模式**: 如果当前没有融合其他水平位置源(例如:辅助全局位置 - AGP),水平位置将重置为 GNSS 数据。 +- **航位推算模式**: 仅当当前没有融合其他水平位置或速度源(例如:AGP、空速、光流)时,水平位置才会重置为 GNSS 数据。 + +高度: + +- 由于高度参考传感器 ([EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)) 参数(在无 GNSS 场景中通常设置为 GNSS 或气压计),高度逻辑更加复杂。 +- 如果高度参考设置为气压计,则防止基于 GNSS 的高度重置(除非气压计融合完全失败且高度参考自动切换到 GNSS)。 +- 当高度参考设置为 GNSS 时: +- **自动模式**: 在 GNSS 高度测量值漂移时发生重置。 +- **航位推算模式**: 当验证开始失败时,系统会阻止 GNSS 高度重置并将 GNSS 数据标记为故障。 + +##### 启动期间的错误 GNSS 数据 + +系统无法在载具启动期间自动检测错误的 GNSS 数据,因为不存在基线比较。 + +如果启用了 GNSS 融合 ([EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL)),操作员将在地图上观察到不正确的位置,并应禁用 GNSS 融合,然后通过地面站手动设置正确的位置。 +全局位置得到修正,如果启用了 [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL),气压计偏移量会自动调整(通过零偏校正,而不是参数更改)。 + +##### 飞行中启用 GNSS 融合 + +存在错误 GNSS 数据时: + +- **自动模式**: 载具将重置到错误位置 - 具有潜在危险。 +- **航位推算模式**: 大的测量差异会导致 GNSS 被拒绝并激活故障检测。 + +存在有效 GNSS 数据时: + +- **自动模式**: 载具将重置到 GNSS 测量值。 +- **航位推算模式**: 如果估计位置/高度与测量值足够接近,则恢复融合;如果相距太远,数据将被标记为故障。 + +##### 备注 + +- **双重检测**: 水平和高度检查完全分开运行,但在触发时都会导致相同的结果 - 所有 GNSS 融合被禁用。 +- **恢复**: 只有将数据标记为无效的特定检查才能重新启用融合。 +- **替代来源**: 航位推算模式通过在允许重置之前要求没有替代导航源,提供了增强的保护。 +- **启动漏洞**: 初始错误 GNSS 数据无法自动检测;需要操作员干预和手动位置校正。 + ### 测距仪 -[Range finder](../sensor/rangefinders.md) distance to ground is used by a single state filter to estimate the vertical position of the terrain relative to the height datum. +[测距仪](../sensor/rangefinders.md) 对地距离由单状态滤波器使用,用于估计地形相对于高度基准的垂直位置。 -The fusion modes of operation are controlled by [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL): +融合操作模式由 [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) 控制: -1. [Conditional range aiding](#conditional-range-aiding) -2. [Range height fusion](#range-height-fusion) +1. [条件测距辅助](#conditional-range-aiding) +2. [测距高度融合](#range-height-fusion) -For more details about the configuration of height sources, [click here](#height). +有关高度源配置的更多详细信息,请 [点击这里](#height)。 -#### Conditional range aiding +#### 条件测距辅助 -Conditional range finder fusion (a.k.a. _Conditional range aid_) activates the range finder fusion for height estimation during low speed/low altitude operation (in addition to the other active height sources). -If the range finder is set as the reference height source (using [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)), the other active height sources such as baro and GNSS altitude will adjust their measurement to match the readings of the range finder over time. -When the conditions are not met to start range aiding, a secondary reference is automatically selected. +条件测距仪融合(又名 _条件测距辅助_)在低速/低空操作期间激活测距仪融合以进行高度估计(除了其他活动的高度源之外)。 +如果测距仪被设置为参考高度源(使用 [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF)),其他活动的高度源(如气压计和 GNSS 高度)将随着时间的推移调整其测量值以匹配测距仪的读数。 +当不满足启动测距辅助的条件时,会自动选择次要参考。 :::info -Switching between height references causes the absolute altitude estimate to drift over time. -This isn't an issue when flying in position mode but can be problematic if the drone is supposed to fly a mission at a specific GNSS altitude. -If the absolute altitude drift is unwanted, it is recommended to set the GNSS altitude as the height reference, even when using conditional range aid. +在高度参考之间切换会导致绝对高度估计随时间漂移。 +当在位置模式下飞行时,这不是问题,但如果无人机应该在特定的 GNSS 高度执行任务,则可能会有问题。 +如果不希望出现绝对高度漂移,建议将 GNSS 高度设置为高度参考,即使在使用条件测距辅助时也是如此。 ::: -It is primarily intended for _takeoff and landing_, in cases where the barometer setup is such that interference from rotor wash is excessive and can corrupt EKF state estimates. +它主要用于 _起飞和降落_,在这些情况下,气压计的设置可能会受到旋翼气流的过度干扰,从而破坏 EKF 状态估计。 -Range aid may also be used to improve altitude hold when the vehicle is stationary. +测距辅助也可用于改善载具静止时的高度保持。 :::tip -[Terrain Hold](../flying/terrain_following_holding.md#terrain_hold) is recommended over _Range Aid_ for terrain holding. -This is because terrain hold uses the normal ECL/EKF estimator for determining height, and this is generally more reliable than a distance sensor in most conditions. +对于地形保持,推荐使用 [地形保持](../flying/terrain_following_holding.md#terrain_hold) 而不是 _测距辅助_。 +这是因为地形保持使用正常的 ECL/EKF 估计器来确定高度,这在大多数情况下比距离传感器更可靠。 ::: -_Conditional range aid_ is enabled by setting [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) = "Enabled (conditional mode)" (1). +_条件测距辅助_ 通过设置 [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) = "Enabled (conditional mode)" (1) 来启用。 -It is further configured using the `EKF2_RNG_A_` parameters: +它使用 `EKF2_RNG_A_` 参数进一步配置: -- [EKF2_RNG_A_VMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_VMAX): Maximum horizontal speed, above which range aid is disabled. -- [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX): Maximum height, above which range aid is disabled. +- [EKF2_RNG_A_VMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_VMAX): 最大水平速度,高于此速度将禁用测距辅助。 +- [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX): 最大高度,高于此高度将禁用测距辅助。 -#### Range height fusion +#### 测距高度融合 -PX4 allows you to continuously fuse the range finder as a source of height (in any flight mode/vehicle type). -This may be useful for applications when the vehicle is _guaranteed_ to only fly over a near-flat surface (e.g. indoors). +PX4 允许您持续融合测距仪作为高度源(在任何飞行模式/载具类型中)。 +当载具 _保证_ 仅在接近平坦的表面上飞行(例如室内)时,这可能对应用程序有用。 -When using a distance sensor as a height source, fliers should be aware: +当使用距离传感器作为高度源时,飞行者应注意: -- Flying over obstacles can lead to the estimator rejecting rangefinder data (due to internal data consistency checks), which can result in poor altitude holding while the estimator is relying purely on accelerometer estimates. +- 飞越障碍物可能导致估计器拒绝测距仪数据(由于内部数据一致性检查),这可能导致高度保持效果不佳,而估计器仅依赖加速度计估计。 - ::: info - This scenario might occur when a vehicle ascends a slope at a near-constant height above ground, because the rangefinder altitude does not change while that estimated from the accelerometer does. - The EKF performs innovation consistency checks that take into account the error between measurement and current state as well as the estimated variance of the state and the variance of the measurement itself. - If the checks fail the rangefinder data will be rejected, and the altitude will be estimated from the accelerometer and the other selected height sources (GNSS, baro, vision), if enabled and available - After 5 seconds of inconsistent data if the distance sensor is the active source oh height data, the estimator resets the height state to match the current distance sensor data. - If one or more other sources of height are active, the range finder is declared faulty and the estimator continues to estimate its height using the other sensors. - The measurements might also become consistent again, for example, if the vehicle descends, or if the estimated height drifts to match the measured rangefinder height. + 这种情况可能会发生在载具以相对于地面几乎恒定的高度爬坡时,因为测距仪高度没有变化,而加速度计估计的高度却在变化。 + EKF 执行新息一致性检查,该检查考虑了测量值与当前状态之间的误差以及状态的估计方差和测量本身的方差。 + 如果检查失败,测距仪数据将被拒绝,高度将根据加速度计和其他选定的高度源(GNSS、气压计、视觉,如果启用且可用)进行估计。 + 如果距离传感器是活动的高度数据源,在数据不一致持续 5 秒后,估计器会重置高度状态以匹配当前的距离传感器数据。 + 如果一个或多个其他高度源处于活动状态,则测距仪被声明为故障,估计器继续使用其他传感器估计其高度。 + 测量值也可能再次变得一致,例如,如果载具下降,或者如果估计的高度漂移以匹配测量的测距仪高度。 ::: -- The local NED origin will move up and down with ground level. +- 局部 NED 原点将随地平面上下移动。 -- Rangefinder performance over uneven surfaces (e.g. trees) can be very poor, resulting in noisy and inconsistent data. - This again leads to poor altitude hold. +- 测距仪在不平坦表面(例如树木)上的性能可能非常差,导致数据嘈杂且不一致。 + 这同样会导致高度保持不佳。 -The feature is enabled by setting [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to "Enabled" (2). -To make the range finder the height reference when active, set: [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) to "Range sensor". +该功能通过将 [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) 设置为 "Enabled" (2) 来启用。 +要在活动时使测距仪成为高度参考,请设置:[EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) 为 "Range sensor"。 :::tip -To enable the range finder fusion only when the drone is stationary (in order to benefit from a better altitude estimate during takeoff and landing) but not fuse the range finder the rest of the time, use the [conditional mode](#conditional-range-aiding) (1) of [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL). +要仅在无人机静止时启用测距仪融合(以便在起飞和降落期间获得更好的高度估计),但在其余时间不融合测距仪,请使用 [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) 的 [条件模式](#conditional-range-aiding) (1)。 ::: -#### Range Finder Obstruction Detection +#### 测距仪遮挡检测 -The EKF can detect whether the rangefinder path-to-ground is obstructed (perhaps by a payload) using a kinematic consistency check between the vertical velocity estimate and the numerical derivative of the range finder data. -If the range finder is statistically inconsistent with EKF2, the sensor is rejected for the rest of the flight unless the statistical test passes again for at least 1 second at a vertical speed of 0.5m/s or more. +EKF 可以使用垂直速度估计值与测距仪数据数值导数之间的运动学一致性检查,来检测测距仪对地路径是否被遮挡(可能被负载遮挡)。 +如果测距仪在统计上与 EKF2 不一致,则在本次飞行的剩余时间内传感器将被拒绝,除非统计测试在 0.5m/s 或更高的垂直速度下再次通过至少 1 秒。 -The check is only enabled when the rangefinder is not used as the primary height source, and is only active while the vehicle is not moving horizontally (as it assumes a static ground height). +该检查仅在测距仪未用作主要高度源时启用,并且仅在载具未水平移动时处于活动状态(因为它假设地面高度是静态的)。 -For effective obstruction detection, the range finder noise parameter needs to be tightly tuned using flight data. -The kinematic consistency gate parameter can then be adjusted to obtain the desired fault detection sensitivity. +为了进行有效的遮挡检测,需要使用飞行数据对测距仪噪声参数进行严格调整。 +然后可以调整运动学一致性门限参数以获得所需的故障检测灵敏度。 -调整参数: +调参参数: - [EKF2_RNG_NOISE](../advanced_config/parameter_reference.md#EKF2_RNG_NOISE) - [EKF2_RNG_K_GATE](../advanced_config/parameter_reference.md#EKF2_RNG_K_GATE) ### 空速: -Equivalent Airspeed (EAS) data can be used to estimate wind velocity and reduce drift when GPS is lost by setting [EKF2_ARSP_THR](../advanced_config/parameter_reference.md#EKF2_ARSP_THR) to a positive value. -Airspeed data will be used when it exceeds the threshold set by a positive value for [EKF2_ARSP_THR](../advanced_config/parameter_reference.md#EKF2_ARSP_THR) and the vehicle type is not rotary wing. +通过将 [EKF2_ARSP_THR](../advanced_config/parameter_reference.md#EKF2_ARSP_THR) 设置为正值,可以使用等效空速 (EAS) 数据来估计风速并在 GPS 丢失时减少漂移。 +当空速超过 [EKF2_ARSP_THR](../advanced_config/parameter_reference.md#EKF2_ARSP_THR) 正值设置的阈值且载具类型不是旋翼机时,将使用空速数据。 ### 合成侧滑 -Fixed-wing platforms can take advantage of an assumed sideslip observation of zero to improve wind speed estimation and also enable wind speed estimation without an airspeed sensor. -This is enabled by setting the [EKF2_FUSE_BETA](../advanced_config/parameter_reference.md#EKF2_FUSE_BETA) parameter to 1. +固定翼平台可以利用假设的零侧滑观测来改善风速估计,并且还可以在没有空速传感器的情况下启用风速估计。 +这是通过将 [EKF2_FUSE_BETA](../advanced_config/parameter_reference.md#EKF2_FUSE_BETA) 参数设置为 1 来启用的。 -### Multicopter Wind Estimation using Drag Specific Forces {#mc_wind_estimation_using_drag} +### 使用阻力比力的多旋翼风速估计 {#mc_wind_estimation_using_drag} -多旋翼平台可以利用沿 X 和 Y 机体轴的空速和阻力之间的关系来估计风速的北/东分量。 -This can be enabled using [EKF2_DRAG_CTRL](../advanced_config/parameter_reference.md#EKF2_DRAG_CTRL). +多旋翼平台可以利用空速与沿 X 和 Y 机体轴的阻力之间的关系来估计风速的北/东分量。 +可以使用 [EKF2_DRAG_CTRL](../advanced_config/parameter_reference.md#EKF2_DRAG_CTRL) 启用此功能。 -The relationship between airspeed and specific force (IMU accelerometer measurements) along the X and Y body axes is controlled by the [EKF2_BCOEF_X](../advanced_config/parameter_reference.md#EKF2_BCOEF_X), [EKF2_BCOEF_Y](../advanced_config/parameter_reference.md#EKF2_BCOEF_Y) and [EKF2_MCOEF](../advanced_config/parameter_reference.md#EKF2_MCOEF) parameters which set the ballistic coefficients for flight in the X and Y directions, and the momentum drag produced by the propellers, respectively. -The amount of specific force observation noise is set by the [EKF2_DRAG_NOISE](../advanced_config/parameter_reference.md#EKF2_DRAG_NOISE) parameter. +空速与沿 X 和 Y 机体轴的比力(IMU 加速度计测量值)之间的关系由 [EKF2_BCOEF_X](../advanced_config/parameter_reference.md#EKF2_BCOEF_X)、[EKF2_BCOEF_Y](../advanced_config/parameter_reference.md#EKF2_BCOEF_Y) 和 [EKF2_MCOEF](../advanced_config/parameter_reference.md#EKF2_MCOEF) 参数控制,这些参数分别设置 X 和 Y 方向飞行的弹道系数以及螺旋桨产生的动量阻力。 +比力观测噪声的大小由 [EKF2_DRAG_NOISE](../advanced_config/parameter_reference.md#EKF2_DRAG_NOISE) 参数设置。 -以下方法可获得良好的调参参数: +可以通过以下方式获得良好的调参: -1. Fly once in [Position mode](../flight_modes_mc/position.md) repeatedly forwards/backwards/left/right/up/down between rest and maximum speed (best results are obtained when this testing is conducted in still conditions). -2. Extract the **.ulg** log file using, for example, [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) - ::: info - The same **.ulg** log file can also be used to tune the [static pressure position error coefficients](#correction-for-static-pressure-position-error). +1. 在 [位置模式](../flight_modes_mc/position.md) 下反复向前/向后/向左/向右/向上/向下飞行,在静止和最大速度之间切换(在静风条件下进行此测试可获得最佳结果)。 +2. 使用例如 [QGroundControl: Analyze > Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) 提取 **.ulg** 日志文件。 + ::: info + 同一 **.ulg** 日志文件也可用于调整 [静压位置误差系数](#correction-for-static-pressure-position-error)。 ::: -3. Use the log with the [mc_wind_estimator_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/mc_wind_estimator) Python script to obtain the optimal set of parameters. +3. 使用 [mc_wind_estimator_tuning.py](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/ekf2/EKF/python/tuning_tools/mc_wind_estimator) Python 脚本处理日志,以获得最佳参数集。 ### 光流 -[Optical flow](../sensor/optical_flow.md) data will be used if the following conditions are met: +如果满足以下条件,将使用 [光流](../sensor/optical_flow.md) 数据: - 有效的测距仪数据可用。 -- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL) is set. -- The quality metric returned by the flow sensor is greater than the minimum requirement set by the [EKF2_OF_QMIN](../advanced_config/parameter_reference.md#EKF2_OF_QMIN) parameter. +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL) 已设置。 +- 流量传感器返回的质量指标大于 [EKF2_OF_QMIN](../advanced_config/parameter_reference.md#EKF2_OF_QMIN) 参数设置的最低要求。 -For better performance, set the location of the optical flow sensor as described [here](../sensor/optical_flow.md#ekf2). +为了获得更好的性能,请按照 [此处](../sensor/optical_flow.md#ekf2) 所述设置光流传感器的位置。 -If a stable hover can be achieved at low altitude above ground (< 10m) but slow oscillations occur at higher altitude, consider adjusting the [optical flow scale factor](../sensor/optical_flow.md#scale-factor). +如果在低空(< 10m)可以实现稳定的悬停,但在较高高度出现缓慢振荡,请考虑调整 [光流比例因子](../sensor/optical_flow.md#scale-factor)。 ### 外部视觉系统 -Position, velocity or orientation measurements from an external vision system, e.g. Vicon, can be used. +可以使用来自外部视觉系统(例如 Vicon)的位置、速度或方向测量值。 -The measurements that are fused are configured by setting the appropriate bits of [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL) to `true`: +通过将 [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL) 的相应位设置为 `true` 来配置融合的测量值: -- `0`: Horizontal position data -- `1`: Vertical position data. - Height sources may additionally be configured using [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) (see section [Height](#height)). -- `2`: Velocity data -- `3`: Yaw data +- `0`: 水平位置数据 +- `1`: 垂直位置数据。 + 垂直位置数据。 + 高度源还可以使用 [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF) 进行配置(参见 [高度](#height) 部分)。 +- `2`:速度数据 +- `3`:偏航角数据 -Note that if yaw data is used (bit 3) the heading is with respect to the external vision frame; otherwise the heading is relative to North. +注意,如果使用偏航数据(第 3 位),则航向是相对于外部视觉坐标系的;否则航向是相对于北方的。 -EKF 要考虑视觉姿态估计的不确定性。 -This uncertainty information can be sent via the covariance fields in the MAVLink [ODOMETRY](https://mavlink.io/en/messages/common.html#ODOMETRY) message or it can be set through the parameters [EKF2_EVP_NOISE](../advanced_config/parameter_reference.md#EKF2_EVP_NOISE), [EKF2_EVV_NOISE](../advanced_config/parameter_reference.md#EKF2_EVV_NOISE) and [EKF2_EVA_NOISE](../advanced_config/parameter_reference.md#EKF2_EVA_NOISE). -You can choose the source of the uncertainty with [EKF2_EV_NOISE_MD](../advanced_config/parameter_reference.md#EKF2_EV_NOISE_MD). +EKF 会考虑视觉位姿估计中的不确定性。 +此不确定性信息可以通过 MAVLink [ODOMETRY](https://mavlink.io/en/messages/common.html#ODOMETRY) 消息中的协方差字段发送,也可以通过参数 [EKF2_EVP_NOISE](../advanced_config/parameter_reference.md#EKF2_EVP_NOISE)、[EKF2_EVV_NOISE](../advanced_config/parameter_reference.md#EKF2_EVV_NOISE) 和 [EKF2_EVA_NOISE](../advanced_config/parameter_reference.md#EKF2_EVA_NOISE) 进行设置。 +您可以使用 [EKF2_EV_NOISE_MD](../advanced_config/parameter_reference.md#EKF2_EV_NOISE_MD) 选择不确定性的来源。 -## 我如何启用 'ecl' 库中的 EKF ? +## 如何使用 'ecl' 库中的EKF? -EKF2 is enabled by default (for more information see [Switching State Estimators](../advanced/switching_state_estimators.md) and [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN)). +EKF2 默认启用(有关更多信息,请参阅 [切换状态估计器](../advanced/switching_state_estimators.md) 和 [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN))。 -## ecl EKF 和其它估计器相比的优点和缺点是什么? +## ecl EKF相较于其他估计器的优缺点是什么? -与所有估计器一样,大部分性能来自调参以匹配传感器特性。 -调参是准确性和鲁棒性之间的折衷,虽然我们试图提供满足大多数用户需求的调优,但是应用程序需要调整更改。 +像所有估计器一样,大部分性能来自于与传感器特性相匹配的调参。 +调参是精度和鲁棒性之间的折衷,虽然我们试图提供满足大多数用户需求的参数,但仍会有需要更改参数的应用。 -For this reason, no claims for accuracy relative to the legacy combination of `attitude_estimator_q` + `local_position_estimator` have been made and the best choice of estimator will depend on the application and tuning. +因此,相对于 `attitude_estimator_q` + `local_position_estimator` 的传统组合,我们不对精度做出声明,最佳的估计器选择将取决于应用和调参。 ### 缺点 -- ecl EKF 是一种复杂的算法,需要很好地理解扩展卡尔曼滤波器理论及其应用于导航中的问题才能成功调参。 - 因此,不知道怎么修改,用户就很难得到好结果。 -- ecl EKF 使用更多 RAM 和闪存空间。 +- ecl EKF 是一个复杂的算法,需要充分理解扩展卡尔曼滤波理论及其在导航问题中的应用才能成功调参。 + 因此,对于没有获得良好结果的用户来说,知道要更改什么比较困难。 +- ecl EKF 使用更多的 RAM 和闪存空间。 - ecl EKF 使用更多的日志空间。 -### 优势 +### 优点 -- ecl EKF 能够以数学上一致的方式融合来自具有不同时间延迟和数据速率的传感器的数据,一旦正确设置时间延迟参数,就可以提高动态操作期间的准确性。 -- ecl EKF 能够融合各种不同的传感器类型。 -- 当 ecl EKF 检测并报告传感器数据中统计上显着的不一致性,将帮助诊断传感器错误。 -- For fixed-wing operation, the ecl EKF estimates wind speed with or without an airspeed sensor and is able to use the estimated wind in combination with airspeed measurements and sideslip assumptions to extend the dead-reckoning time available if GPS is lost in flight. -- ecl EKF估计3轴加速度计偏差,这提高了尾座式无人机和其它机体在飞行阶段之间经历大的姿态变化时的精度。 +- ecl EKF 能够以数学上一致的方式融合来自具有不同时间延迟和数据速率的传感器的数据,一旦正确设置时间延迟参数,即可提高动态机动期间的精度。 +- ecl EKF 能够融合各种不同类型的传感器。 +- ecl EKF 检测并报告传感器数据中统计上的显著不一致,协助诊断传感器错误。 +- 对于固定翼操作,ecl EKF 在有或没有空速传感器的情况下均可估计风速,并且能够在飞行中 GPS 丢失时结合空速测量和侧滑假设来使用估计的风速,以延长可用的航位推算时间。 +- ecl EKF 估计三轴加速度计零偏,这提高了尾座式飞机和其他在飞行阶段之间经历大姿态变化的载具的精度。 - 联邦结构(组合姿态和位置/速度估计)意味着姿态估计受益于所有传感器测量。 如果调参正确,这应该提供改善态度估计的潜力。 ## 如何检查 EKF 性能? -EKF 输出,状态和状态数据发布到许多 uORB 主题,这些主题在飞行期间记录到 SD 卡上。 -The following guide assumes that data has been logged using the _.ulog file format_. -The **.ulog** format data can be parsed in python by using the [PX4 pyulog library](https://github.com/PX4/pyulog). +EKF 输出、状态和状态数据发布到许多 uORB 主题,这些主题在飞行期间记录到 SD 卡。 +以下指南假设已使用 _.ulog 文件格式_ 记录数据。 +可以使用 [PX4 pyulog 库](https://github.com/PX4/pyulog) 在 python 中解析 **.ulog** 格式数据。 -Most of the EKF data is found in the [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg) and [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) uORB messages that are logged to the .ulog file. +大多数 EKF 数据可以在记录到 .ulog 文件的 [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg) 和 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) uORB 消息中找到。 -A python script that automatically generates analysis plots and metadata can be found [here](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/process_logdata_ekf.py). -To use this script file, cd to the `Tools/ecl_ekf` directory and enter `python process_logdata_ekf.py `. -This saves performance metadata in a csv file named **.mdat.csv** and plots in a pdf file named `.pdf`. +可以在 [这里](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/process_logdata_ekf.py) 找到自动生成分析图和元数据的 python 脚本。 +要使用此脚本文件,请 cd 到 `Tools/ecl_ekf` 目录并输入 `python process_logdata_ekf.py `。 +这将性能元数据保存在名为 **.mdat.csv** 的 csv 文件中,并将图表保存在名为 `.pdf` 的 pdf 文件中。 -Multiple log files in a directory can be analysed using the [batch_process_logdata_ekf.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/batch_process_logdata_ekf.py) script. -When this has been done, the performance metadata files can be processed to provide a statistical assessment of the estimator performance across the population of logs using the [batch_process_metadata_ekf.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/batch_process_metadata_ekf.py) script. +可以使用 [batch_process_logdata_ekf.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/batch_process_logdata_ekf.py) 脚本分析目录中的多个日志文件。 +完成后,可以使用 [batch_process_metadata_ekf.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/ecl_ekf/batch_process_metadata_ekf.py) 脚本处理性能元数据文件,以对日志总体的估计器性能进行统计评估。 ### 输出数据 -- Attitude output data is found in the [VehicleAttitude](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitude.msg) message. -- Local position output data is found in the [VehicleLocalPosition](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLocalPosition.msg) message. -- Global \(WGS-84\) output data is found in the [VehicleGlobalPosition](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleGlobalPosition.msg) message. -- Wind velocity output data is found in the [Wind.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Wind.msg) message. +- 姿态输出数据位于 [VehicleAttitude](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitude.msg) 消息中。 +- 局部位置输出数据位于 [VehicleLocalPosition](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLocalPosition.msg) 消息中。 +- 全局 (WGS-84) 输出数据位于 [VehicleGlobalPosition](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleGlobalPosition.msg) 消息中。 +- 风速输出数据位于 [Wind.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/Wind.msg) 消息中。 ### 状态 -Refer to states\[24\] in [EstimatorStates](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg). -The index map for states\[24\] is as follows: +参考 [EstimatorStates](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg) 中的 states\[24\]。 +states\[24\] 的索引映射如下: -- \[0 ... 3\] Quaternions -- \[4 ... 6\] Velocity NED \(m/s\) -- \[7 ... 9\] Position NED \(m\) -- \[10 ... 12\] IMU delta angle bias XYZ \(rad\) -- \[13 ... 15\] IMU delta velocity bias XYZ \(m/s\) -- \[16 ... 18\] Earth magnetic field NED \(gauss\) -- \[19 ... 21\] Body magnetic field XYZ \(gauss\) -- \[22 ... 23\] Wind velocity NE \(m/s\) +- \[0 ... 3\] 四元数 +- \[4 ... 6\] 速度 NED \(m/s\) +- \[7 ... 9\] 位置 NED \(m\) +- \[10 ... 12\] IMU 角度增量零偏 XYZ \(rad\) +- \[13 ... 15\] IMU 速度增量零偏 XYZ \(m/s\) +- \[16 ... 18\] 地球磁场 NED \(gauss\) +- \[19 ... 21\] 机体磁场 XYZ \(gauss\) +- \[22 ... 23\] 风速 NE \(m/s\) ### 状态方差 -Refer to covariances\[24\] in [EstimatorStates](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg). -The index map for covariances\[24\] is as follows: +参考 [EstimatorStates](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStates.msg) 中的 covariances\[24\]。 +covariances\[24\] 的索引映射如下: -- \[0 ... 3\] Quaternions -- \[4 ... 6\] Velocity NED \(m/s\)^2 -- \[7 ... 9\] Position NED \(m^2\) -- \[10 ... 12\] IMU delta angle bias XYZ \(rad^2\) -- \[13 ... 15\] IMU delta velocity bias XYZ \(m/s\)^2 -- \[16 ... 18\] Earth magnetic field NED \(gauss^2\) -- \[19 ... 21\] Body magnetic field XYZ \(gauss^2\) -- \[22 ... 23\] Wind velocity NE \(m/s\)^2 +- \[0 ... 3\] 四元数 +- \[4 ... 6\] 速度 NED \(m/s\)^2 +- \[7 ... 9\] 位置 NED \(m^2\) +- \[10 ... 12\] IMU 角度增量零偏 XYZ \(rad^2\) +- \[13 ... 15\] IMU 速度增量零偏 XYZ \(m/s\)^2 +- \[16 ... 18\] 地球磁场 NED \(gauss^2\) +- \[19 ... 21\] 机体磁场 XYZ \(gauss^2\) +- \[22 ... 23\] 风速 NE \(m/s\)^2 -### Observation Innovations & Innovation Variances +### 观测新息与新息方差 -The observation `estimator_innovations`, `estimator_innovation_variances`, and `estimator_innovation_test_ratios` message fields are defined in [EstimatorInnovations.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg). -消息都有相同的字段名称/类型(但是单位不同)。 +观测 `estimator_innovations`、`estimator_innovation_variances` 与 `estimator_innovation_test_ratios` 消息字段定义在 [EstimatorInnovations.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg) 中。 +这些消息字段名称/类型相同(但单位不同)。 :::info -The messages have the same fields because they are generated from the same field definition. -The `# TOPICS` line (at the end of [the file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg)) lists the names of the set of messages to be created): +这些消息具有相同字段,是因为它们来自同一字段定义。 +`# TOPICS` 行(见 [文件末尾](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg))列出了要生成的消息名: ``` # TOPICS estimator_innovations estimator_innovation_variances estimator_innovation_test_ratios @@ -586,71 +639,70 @@ The `# TOPICS` line (at the end of [the file](https://github.com/PX4/PX4-Autopil ::: -一些观测值为: +部分观测包括: -- Magnetometer XYZ (gauss, gauss^2) : `mag_field[3]` -- Yaw angle (rad, rad^2) : `heading` -- True Airspeed (m/s, (m/s)^2) : `airspeed` -- Synthetic sideslip (rad, rad^2) : `beta` -- Optical flow XY (rad/sec, (rad/s)^2) : `flow` -- Height above ground (m, m^2) : `hagl` -- Drag specific force ((m/s)^2): `drag` +- 磁力计 XYZ(gauss, gauss^2):`mag_field[3]` +- 航向角(rad, rad^2):`heading` +- 真空速(m/s, (m/s)^2):`airspeed` +- 合成侧滑(rad, rad^2):`beta` +- 光流 XY(rad/sec, (rad/s)^2):`flow` +- 离地高度(m, m^2):`hagl` +- 阻力特定力((m/s)^2):`drag` - 速度和位置新息:每个传感器 此外,每个传感器都有其自己的字段,即横向和纵向位置和/或速度值(视情况而定)。 -这些基本上是自我描述的,现摘录如下: +这些字段基本自说明,下面给出原始定义: ``` -# GPS -float32[2] gps_hvel # horizontal GPS velocity innovation (m/sec) and innovation variance ((m/sec)**2) -float32 gps_vvel # vertical GPS velocity innovation (m/sec) and innovation variance ((m/sec)**2) -float32[2] gps_hpos # horizontal GPS position innovation (m) and innovation variance (m**2) -float32 gps_vpos # vertical GPS position innovation (m) and innovation variance (m**2) +float32[2] gps_hvel # 水平 GPS 速度新息 (m/sec) 与新息方差 ((m/sec)**2) +float32 gps_vvel # 垂直 GPS 速度新息 (m/sec) 与新息方差 ((m/sec)**2) +float32[2] gps_hpos # 水平 GPS 位置新息 (m) 与新息方差 (m**2) +float32 gps_vpos # 垂直 GPS 位置新息 (m) 与新息方差 (m**2) # External Vision -float32[2] ev_hvel # horizontal external vision velocity innovation (m/sec) and innovation variance ((m/sec)**2) -float32 ev_vvel # vertical external vision velocity innovation (m/sec) and innovation variance ((m/sec)**2) -float32[2] ev_hpos # horizontal external vision position innovation (m) and innovation variance (m**2) -float32 ev_vpos # vertical external vision position innovation (m) and innovation variance (m**2) +float32[2] ev_hvel # 水平外部视觉速度新息 (m/sec) 与新息方差 ((m/sec)**2) +float32 ev_vvel # 垂直外部视觉速度新息 (m/sec) 与新息方差 ((m/sec)**2) +float32[2] ev_hpos # 水平外部视觉位置新息 (m) 与新息方差 (m**2) +float32 ev_vpos # 垂直外部视觉位置新息 (m) 与新息方差 (m**2) # Fake Position and Velocity -float32[2] fake_hvel # fake horizontal velocity innovation (m/s) and innovation variance ((m/s)**2) -float32 fake_vvel # fake vertical velocity innovation (m/s) and innovation variance ((m/s)**2) -float32[2] fake_hpos # fake horizontal position innovation (m) and innovation variance (m**2) -float32 fake_vpos # fake vertical position innovation (m) and innovation variance (m**2) +float32[2] fake_hvel # 虚拟水平速度新息 (m/s) 与新息方差 ((m/s)**2) +float32 fake_vvel # 虚拟垂直速度新息 (m/s) 与新息方差 ((m/s)**2) +float32[2] fake_hpos # 虚拟水平位置新息 (m) 与新息方差 (m**2) +float32 fake_vpos # 虚拟垂直位置新息 (m) 与新息方差 (m**2) # Height sensors -float32 rng_vpos # range sensor height innovation (m) and innovation variance (m**2) -float32 baro_vpos # barometer height innovation (m) and innovation variance (m**2) +float32 rng_vpos # 测距高度新息 (m) 与新息方差 (m**2) +float32 baro_vpos # 气压计高度新息 (m) 与新息方差 (m**2) # Auxiliary velocity -float32[2] aux_hvel # horizontal auxiliary velocity innovation from landing target measurement (m/sec) and innovation variance ((m/sec)**2) -float32 aux_vvel # vertical auxiliary velocity innovation from landing target measurement (m/sec) and innovation variance ((m/sec)**2) +float32[2] aux_hvel # 来自着陆目标测量的水平辅助速度新息 (m/sec) 与新息方差 ((m/sec)**2) +float32 aux_vvel # 来自着陆目标测量的垂直辅助速度新息 (m/sec) 与新息方差 ((m/sec)**2) ``` ### 输出互补滤波器 -输出互补滤波器用于将状态从融合时间范围向前传播到当前时间。 -To check the magnitude of the angular, velocity and position tracking errors measured at the fusion time horizon, refer to `output_tracking_error[3]` in the `ekf2_innovations` message. +输出互补滤波器用于将状态从融合时间地平线推进到当前时间。 +要检查融合时间地平线处测得的角度、速度与位置跟踪误差大小,可参考 `ekf2_innovations` 消息中的 `output_tracking_error[3]`。 索引映射如下: - \[0\] 角度跟踪误差量级 (rad) - \[1\] 速度跟踪误差量级(m/s)。 - The velocity tracking time constant can be adjusted using the [EKF2_TAU_VEL](../advanced_config/parameter_reference.md#EKF2_TAU_VEL) parameter. + 速度跟踪时间常数可通过 [EKF2_TAU_VEL](../advanced_config/parameter_reference.md#EKF2_TAU_VEL) 调整。 减小此参数可减少稳态误差,但会增加 NED 速度输出上的观测噪声量。 - \[2\] 位置跟踪误差量级 \(m\)。 - The position tracking time constant can be adjusted using the [EKF2_TAU_POS](../advanced_config/parameter_reference.md#EKF2_TAU_POS) parameter. + 位置跟踪时间常数可通过 [EKF2_TAU_POS](../advanced_config/parameter_reference.md#EKF2_TAU_POS) 调整。 减小此参数可减少稳态误差,但会增加 NED 位置输出上的观测噪声量。 ### EKF 错误 EKF 包含针对严重条件状态和协方差更新的内部错误检查。 -Refer to the `filter_fault_flags` in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg). +请参考 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 中的 `filter_fault_flags`。 ### 观测错误 -有两种类型观测错误: +观测故障分为两类: - 数据丢失。 一个例子是测距仪无法提供返回数据。 @@ -659,26 +711,26 @@ Refer to the `filter_fault_flags` in [EstimatorStatus](https://github.com/PX4/PX 这两者都可能导致观测数据被拒绝,如果时间足够长,使得 EKF 尝试重置状态以使用传感器观测数据。 所有观测结果均对新息进行了统计置信度检查。 -The number of standard deviations for the check are controlled by the `EKF2_*_GATE` parameter for each observation type. +各观测类型的检查标准差数由对应的 `EKF2_*_GATE` 参数控制。 -Test levels are available in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) as follows: +测试指标可在 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 中查看: -- `mag_test_ratio`: ratio of the largest magnetometer innovation component to the innovation test limit -- `vel_test_ratio`: ratio of the largest velocity innovation component to the innovation test limit -- `pos_test_ratio`: ratio of the largest horizontal position innovation component to the innovation test limit -- `hgt_test_ratio`: ratio of the vertical position innovation to the innovation test limit -- `tas_test_ratio`: ratio of the true airspeed innovation to the innovation test limit -- `hagl_test_ratio`: ratio of the height above ground innovation to the innovation test limit +- `mag_test_ratio`:磁力计新息最大分量与测试限值的比值 +- `vel_test_ratio`:速度新息最大分量与测试限值的比值 +- `pos_test_ratio`:水平位置新息最大分量与测试限值的比值 +- `hgt_test_ratio`:垂直位置新息与测试限值的比值 +- `tas_test_ratio`:真空速新息与测试限值的比值 +- `hagl_test_ratio`:离地高度新息与测试限值的比值 -For a binary pass/fail summary for each sensor, refer to innovation_check_flags in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg). +若需查看每个传感器的二值通过/失败汇总,请参考 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 中的 `innovation_check_flags`。 ### GPS 数据质量检查 -在开始 GPS 辅助之前,EKF 应用了许多 GPS 数据质量检查。 -These checks are controlled by the [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) and `EKF2_REQ_*` parameters. -The pass/fail status for these checks is logged in the [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).gps_check_fail_flags message. +EKF 在开始 GPS 辅助前会执行一系列 GPS 质量检查。 +这些检查由 [EKF2_GPS_CHECK](../advanced_config/parameter_reference.md#EKF2_GPS_CHECK) 和 `EKF2_REQ_*` 参数控制。 +这些检查的通过/失败状态记录在 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 的 `gps_check_fail_flags` 字段中。 当所有所需的 GPS 检查通过后,此整数将为零。 -If the EKF is not commencing GPS alignment, check the value of the integer against the bitmask definition `gps_check_fail_flags` in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg). +如果 EKF 未开始 GPS 对齐,请将该整数与 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 中 `gps_check_fail_flags` 的位掩码定义进行对比。 ### EKF 数值误差 @@ -689,44 +741,44 @@ EKF 对其所有计算使用单精度浮点运算,并使用一阶近似来推 - 如果新息方差小于观测方差(这需要一个不可能的负值状态方差)或协方差更新将为任何一个状态产生负值方差,那么: - 跳过状态和协方差更新 - - 协方差矩阵中的相应行和列被重置 - - The failure is recorded in the [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) `filter_fault_flags` message + - 重置协方差矩阵对应行与列 + - 在 [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg) 的 `filter_fault_flags` 中记录该故障 - 状态方差(协方差矩阵中的对角线)被限制为非负。 - 状态方差应用数值上限。 - 协方差矩阵强制对称。 -After re-tuning the filter, particularly re-tuning that involve reducing the noise variables, the value of `estimator_status.gps_check_fail_flags` should be checked to ensure that it remains zero. +重新调参后,尤其是降低噪声变量的调参,应检查 `estimator_status.gps_check_fail_flags` 是否保持为零。 -## 如果高度估计值发散了怎么办? +## 如何应对高度估计的发散? 在飞行期间 EKF 高度偏离 GPS 和高度计测量的最常见原因是由振动引起的 IMU 测量的削波和/或混叠。 -如果发生这种情况,则数据中应显示以下迹象 +出现该问题时,通常会在数据中看到以下迹象: -- [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg).vel_pos_innov\[2\] and [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg).vel_pos_innov\[5\] will both have the same sign. -- [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).hgt_test_ratio will be greater than 1.0 +- [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg).vel_pos_innov\[2\] 与 [EstimatorInnovations](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorInnovations.msg).vel_pos_innov\[5\] 同号。 +- [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).hgt_test_ratio 大于 1.0 -建议第一步是确保使用有效的隔离安装系统将无人机与机身隔离。 +建议的第一步是使用有效的隔振安装方式将飞控与机架隔离。 隔离安装座具有 6 个自由度,因此具有 6 个谐振频率。 作为一般规则,隔离支架上的自动驾驶仪的 6 个共振频率应高于 25Hz,以避免与无人机动力学相互作用并低于电动机的频率。 如果谐振频率与电动机或螺旋桨叶片通过频率一致,则隔离安装件会使振动更严重。 -通过进行以下参数更改,可以使 EKF 能更加抵御振动引起的高度发散: +可通过以下参数调整提高 EKF 对振动引起的高度发散的鲁棒性: -- 将主要的高度传感器的新息门槛的值加倍。 - If using barometric height this is [EKF2_BARO_GATE](../advanced_config/parameter_reference.md#EKF2_BARO_GATE). -- Increase the value of [EKF2_ACC_NOISE](../advanced_config/parameter_reference.md#EKF2_ACC_NOISE) to 0.5 initially. - 如果仍然出现发散,则进一步增加 0.1,但不要超过 1.0。 +- 将主高度传感器的创新门限加倍。 + 若使用气压高度,可调 [EKF2_BARO_GATE](../advanced_config/parameter_reference.md#EKF2_BARO_GATE)。 +- 将 [EKF2_ACC_NOISE](../advanced_config/parameter_reference.md#EKF2_ACC_NOISE) 增大到 0.5 作为初值。 + 若仍发散,则每次增加 0.1,但不应超过 1.0。 注意 这些变化的影响将使 EKF 对 GPS 垂直速度和气压的误差更敏感。 -## 如果位置估计发散了应该怎么办? +## 如何应对位置估计的发散? 位置发散的最常见原因是: - 高振动级别。 - 通过改进无人机的机械隔离来解决。 - - Increasing the value of [EKF2_ACC_NOISE](../advanced_config/parameter_reference.md#EKF2_ACC_NOISE) and [EKF2_GYR_NOISE](../advanced_config/parameter_reference.md#EKF2_GYR_NOISE) can help, but does make the EKF more vulnerable to GPS glitches. + - 增大 [EKF2_ACC_NOISE](../advanced_config/parameter_reference.md#EKF2_ACC_NOISE) 和 [EKF2_GYR_NOISE](../advanced_config/parameter_reference.md#EKF2_GYR_NOISE) 也有帮助,但会让 EKF 更容易受 GPS 突变影响。 - 过大的陀螺仪偏差偏移。 - 通过重新校准陀螺仪来修复。 检查过度温度灵敏度(> 3 deg/sec 偏差在从冷机开始热启动时发生变化,如果受隔热影响以减缓温度变化的速度,则替换传感器。 @@ -741,45 +793,45 @@ After re-tuning the filter, particularly re-tuning that involve reducing the noi 确定其中哪一个是主要原因需要对 EKF 日志数据进行系统分析: -- Plot the velocity innovation test ratio - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vel_test_ratio -- Plot the horizontal position innovation test ratio - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).pos_test_ratio -- Plot the height innovation test ratio - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).hgt_test_ratio -- Plot the magnetometer innovation test ratio - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).mag_test_ratio -- Plot the GPS receiver reported speed accuracy - [SensorGps.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGps.msg).s_variance_m_s -- Plot the IMU delta angle state estimates - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).states\[10\], states\[11\] and states\[12\] +- 绘制速度创新测试比值 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vel_test_ratio +- 绘制水平位置创新测试比值 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).pos_test_ratio +- 绘制高度创新测试比值 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).hgt_test_ratio +- 绘制磁力计创新测试比值 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).mag_test_ratio +- 绘制 GPS 接收机报告的速度精度 - [SensorGps.msg](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGps.msg).s_variance_m_s +- 绘制 IMU 增量角状态估计 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).states\[10\]、states\[11\] 和 states\[12\] - 绘制 EKF 内部高频振动指标: - - Delta angle coning vibration - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[0\] - - High frequency delta angle vibration - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[1\] - - High frequency delta velocity vibration - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[2\] + - 增量角锥形振动 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[0\] + - 高频增量角振动 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[1\] + - 高频增量速度振动 - [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vibe\[2\] -在正常操作期间,所有测试比率应保持在 0.5 以下,并且只有偶然的峰值高于此值,如下面成功飞行中的示例所示: +正常情况下,所有测试比值应保持在 0.5 以下,仅偶尔出现短暂尖峰,如下成功飞行示例所示: ![Position, Velocity, Height and Magnetometer Test Ratios](../../assets/ecl/test_ratios_-_successful.png) 下图显示了具有良好隔离的多旋翼飞行器的 EKF 振动指标。 可以看到着陆冲击和起飞和着陆期间增加的振动。 -如果收集的数据不足,使用这些指标无法提供有关最大阈值的具体建议。 +目前尚无足够数据给出最大阈值的具体建议。 ![Vibration metrics - successful](../../assets/ecl/vibration_metrics_-_successful.png) 上述振动指标的数值有限值,因为在接近 IMU 采样频率的频率下存在的振动(大多数电路板为 1kHz)将导致在高频振动指标中未显示的数据中出现偏移。 检测混叠误差的唯一方法是它们对惯性导航精度和新息水平的提高。 -除了生成 > 1.0 的大的位置和速度测试比率外,不同的误差机制还以不同的方式影响其它测试比率: +除了产生较大的位置与速度测试比值( > 1.0)外,不同误差机制对其他测试比值的影响也不同: ### 确定过度振动 -高振动级别通常会影响垂直位置和速度新息以及水平分量。 +高振动通常会影响垂直位置与速度新息以及水平分量。 磁力计测试级别仅受到很小程度的影响。 \(在此插入示例绘图显示不好振动\) ### 确定过度的陀螺偏差 -大的陀螺偏差偏移通常的特征是在飞行期间增量角度偏差值的变化大于 5E-4(相当于 ~3 度/秒),并且如果偏航轴受到影响,也会导致磁强计测试比大幅增加。 +陀螺零偏过大通常表现为飞行中增量角偏置变化超过 5E-4(约 3 deg/sec),若影响航向轴,还会导致磁力计测试比值显著上升。 除极端情况外,高度通常不受影响。 如果滤波器在飞行前给定时间稳定,则可以容忍接通最高 5 度/秒的偏差值。 -如果位置发散,飞手进行的飞行前检查应防止解锁。 +若位置发散,指挥器(commander)的预飞检查应阻止解锁。 \(在此插入示例图表显示不好的陀螺偏差\) @@ -795,14 +847,14 @@ After re-tuning the filter, particularly re-tuning that involve reducing the noi GPS 数据精度差通常伴随着接收器报告的速度误差的增加以及新息的增加。 由多路径,遮蔽和干扰引起的瞬态误差是更常见的原因。 -下面是一个暂时失去 GPS 数据精度的例子,其中多旋翼飞行器开始从其游荡位置漂移并且必须使用摇杆进行校正。 -The rise in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vel_test_ratio to greater than 1 indicates the GPs velocity was inconsistent with other measurements and has been rejected. +以下为 GPS 精度暂时下降的示例:多旋翼开始偏离悬停点,需要使用摇杆修正。 +[EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg/EstimatorStatus.msg).vel_test_ratio 上升到 1 以上,说明 GPS 速度与其他测量不一致并已被拒绝。 ![GPS glitch - test ratios](../../assets/ecl/gps_glitch_-_test_ratios.png) -这伴随着 GPS 接收器报告的速度精度的上升,这表明它可能是 GPS 误差。 +同时 GPS 接收机报告的速度精度也上升,表明可能是 GPS 错误。 -![GPS Glitch - reported receiver accuracy](../../assets/ecl/gps_glitch_-_reported_receiver_accuracy.png) +![GPS Glitch - velocity innovations](../../assets/ecl/gps_glitch_-_velocity_innovations.png) 如果我们还看一下 GPS 水平速度新息和新息差异,我们可以看到北向速度新息伴随着这次 GPS “故障”事件的大幅增长。 @@ -810,36 +862,37 @@ The rise in [EstimatorStatus](https://github.com/PX4/PX4-Autopilot/blob/main/msg ### 确定 GPS 数据的丢失 -GPS 数据的丢失将通过速度和位置新息测试比率 'flat-lining' 来显示。 -If this occurs, check the other GPS status data in `vehicle_gps_position` for further information. +GPS 数据丢失会表现为速度与位置创新测试比值“贴平(flat-lining)”。 +出现该情况时,请检查 `vehicle_gps_position` 中的其他 GPS 状态数据。 -The following plot shows the NED GPS velocity innovations `ekf2_innovations_0.vel_pos_innov[0 ... 2]`, the GPS NE position innovations `ekf2_innovations_0.vel_pos_innov[3 ... 4]` and the Baro vertical position innovation `ekf2_innovations_0.vel_pos_innov[5]` generated from a simulated VTOL flight using SITL Gazebo. +下图显示了使用 SITL Gazebo 模拟 VTOL 飞行生成的 NED GPS 速度新息 `ekf2_innovations_0.vel_pos_innov[0 ... 2]`、GPS NE 位置新息 `ekf2_innovations_0.vel_pos_innov[3 ... 4]` 以及气压垂直位置新息 `ekf2_innovations_0.vel_pos_innov[5]`。 模拟的 GPS 在 73 秒时失锁。 -注意 GPS 丢失后,NED 速度新息和 NE 位置新息 'flat-line' 。 -注意在没有 GPS 数据的 10 秒后,EKF 使用最后的已知位置恢复到静态位置模式,并且 NE 位置新息开始再次改变。 +注意 GPS 丢失后 NED 速度新息与 NE 位置新息“贴平(flat-line)”。 +注意 GPS 丢失 10 秒后,EKF 会回退到使用最后已知位置的静态位置模式,NE 位置新息开始再次变化。 ![GPS Data Loss - in SITL](../../assets/ecl/gps_data_loss_-_velocity_innovations.png) ### 气压计地面效应补偿 -如果机体在降落期间在靠近地面时往往爬升回到空中, 最可能的原因是气压计地面效应。 +如果飞行器在降落接近地面时倾向于再次上升,最可能的原因是气压计地面效应。 这种情况是在推进器向地面推进并在无人机下空形成高压区时造成的。 其结果是降低了对压力高度的解读,从而导致了不必要的爬升。 下图显示了存在地面效应的典型情况。 -注意气压计信号如何在飞行开始和结束时消失。 +注意气压信号在飞行开始与结束时的下探。 ![Barometer ground effect](../../assets/ecl/gnd_effect.png) -You can enable _ground effect compensation_ to fix this problem: +可启用 _地面效应补偿_ 修复该问题: -- 从绘图中估算出气压计在起飞或着陆期间的跌落程度。 在上面的绘图中,人们可以看到降落过程中大约6米的气压计下沉。 -- Then set the parameter [EKF2_GND_EFF_DZ](../advanced_config/parameter_reference.md#EKF2_GND_EFF_DZ) to that value and add a 10 percent margin. 因此,在这种情况下,6.6米的数值将是一个良好的起点。 +- 从绘图中估算出气压计在起飞或着陆期间的跌落程度。 上图中可读出降落时约 6 米的气压下探。 +- 将 [EKF2_GND_EFF_DZ](../advanced_config/parameter_reference.md#EKF2_GND_EFF_DZ) 设为该值并加 10% 裕量。 因此,在这种情况下,6.6 米是合适的起始值。 -If a terrain estimate is available (e.g. the vehicle is equipped with a range finder) then you can additionally specify [EKF2_GND_MAX_HGT](../advanced_config/parameter_reference.md#EKF2_GND_MAX_HGT), the above ground-level altitude below which ground effect compensation should be activated. -如果没有可用的地形估计,这个参数将不会产生任何效果,系统将使用继承法来确定是否应激活地面效果补偿。 +如果有地形估计(例如配备测距仪),还可设置 [EKF2_GND_MAX_HGT](../advanced_config/parameter_reference.md#EKF2_GND_MAX_HGT) 来指定启用地面效应补偿的离地高度上限。 +若没有地形估计,该参数无效,系统会使用启发式方法判断是否启用地面效应补偿。 +若没有地形估计,该参数无效,系统会使用启发式方法判断是否启用地面效应补偿。 ## 更多信息 -- [PX4 State Estimation Overview](https://youtu.be/HkYRJJoyBwQ), _PX4 Developer Summit 2019_, Dr. Paul Riseborough): Overview of the estimator, and major changes from 2018/19, and the expected improvements through 2019/20. +- [PX4 State Estimation Overview](https://youtu.be/HkYRJJoyBwQ),_PX4 Developer Summit 2019_,Dr. Paul Riseborough:估计器概览、2018/19 的主要变化,以及 2019/20 期间的预期改进。 diff --git a/docs/zh/advanced_features/precland.md b/docs/zh/advanced_features/precland.md index 821d15a25c..cce0c92e20 100644 --- a/docs/zh/advanced_features/precland.md +++ b/docs/zh/advanced_features/precland.md @@ -38,14 +38,14 @@ If it is not visible the vehicle immediately performs a _normal_ landing at the A precision landing has three phases: 1. **Horizontal approach:** The vehicle approaches the target horizontally while keeping its current altitude. - Once the position of the target relative to the vehicle is below a threshold ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), the next phase is entered. - If the target is lost during this phase (not visible for longer than [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). + Once the position of the target relative to the vehicle is below a threshold ([PLD_HACC_RAD](../advanced_config/parameter_reference.md#PLD_HACC_RAD)), the next phase is entered. + If the target is lost during this phase (not visible for longer than [PLD_BTOUT](../advanced_config/parameter_reference.md#PLD_BTOUT)), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). 2. **Descent over target:** The vehicle descends, while remaining centered over the target. - If the target is lost during this phase (not visible for longer than `PLD_BTOUT`), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). + If the target is lost during this phase (not visible for longer than `PLD_BTOUT`), a search procedure is initiated (during a required precision landing) or the vehicle does a normal landing (during an opportunistic precision landing). 3. **Final approach:** When the vehicle is close to the ground (closer than [PLD_FAPPR_ALT](../advanced_config/parameter_reference.md#PLD_FAPPR_ALT)), it descends while remaining centered over the target. - If the target is lost during this phase, the descent is continued independent of the kind of precision landing. + If the target is lost during this phase, the descent is continued independent of the kind of precision landing. Search procedures are initiated in the first and second steps, and will run at most [PLD_MAX_SRCH](../advanced_config/parameter_reference.md#PLD_MAX_SRCH) times. Landing Phases Flow Diagram diff --git a/docs/zh/advanced_features/satcom_roadblock.md b/docs/zh/advanced_features/satcom_roadblock.md index fcb45ba7cf..47afa7adcf 100644 --- a/docs/zh/advanced_features/satcom_roadblock.md +++ b/docs/zh/advanced_features/satcom_roadblock.md @@ -54,19 +54,19 @@ If an external antenna is used always make sure that the antenna is connected to The default baud rate of the module is 19200. However, the PX4 _iridiumsbd_ driver requires a baud rate of 115200 so it needs to be changed using the [AT commands](https://www.groundcontrol.com/wp-content/uploads/2022/02/IRDM_ISU_ATCommandReferenceMAN0009_Rev2.0_ATCOMM_Oct2012.pdf). 1. Connect to the module with using a 19200/8-N-1 setting and check if the communication is working using the command: `AT`. - The response should be: `OK`. + The response should be: `OK`. 2. Change the baud rate: - ``` - AT+IPR=9 - ``` + ``` + AT+IPR=9 + ``` 3. Reconnect to the model now with a 115200/8-N-1 setting and save the configuration using: - ``` - AT&W0 - ``` + ``` + AT&W0 + ``` The module is now ready to be used with PX4. @@ -101,55 +101,55 @@ Set up a delivery group for the message relay server and add the module to that The relay server should be run on either Ubuntu 16.04 or 14.04 OS. 1. The server working as a message relay should have a static IP address and two publicly accessible, open, TCP ports: - - `5672` for the _RabbitMQ_ message broker (can be changed in the _rabbitmq_ settings) - - `45679` for the HTTP POST interface (can be changed in the **relay.cfg** file) + - `5672` for the _RabbitMQ_ message broker (can be changed in the _rabbitmq_ settings) + - `45679` for the HTTP POST interface (can be changed in the **relay.cfg** file) 2. Install the required python modules: - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 3. Install the `rabbitmq` message broker: - ```sh - sudo apt install rabbitmq-server - ``` + ```sh + sudo apt install rabbitmq-server + ``` 4. Configure the broker's credentials (change PWD to your preferred password): - ```sh - sudo rabbitmqctl add_user iridiumsbd PWD - sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" - ``` + ```sh + sudo rabbitmqctl add_user iridiumsbd PWD + sudo rabbitmqctl set_permissions iridiumsbd ".*" ".*" ".*" + ``` 5. Clone the [SatComInfrastructure](https://github.com/acfloria/SatComInfrastructure) repository: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 6. Go to the location of the _SatComInfrastructure_ repo and configure the broker's queues: - ```sh - ./setup_rabbit.py localhost iridiumsbd PWD - ``` + ```sh + ./setup_rabbit.py localhost iridiumsbd PWD + ``` 7. Verify the setup: - ```sh - sudo rabbitmqctl list_queues - ``` + ```sh + sudo rabbitmqctl list_queues + ``` - This should give you a list of 4 queues: `MO`, `MO_LOG`, `MT`, `MT_LOG` + This should give you a list of 4 queues: `MO`, `MO_LOG`, `MT`, `MT_LOG` 8. Edit the `relay.cfg` configuration file to reflect your settings. 9. Start the relay script in the detached mode: - ```sh - screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py - ``` + ```sh + screen -dm bash -c 'cd SatcomInfrastructure/; ./relay.py + ``` Other instructions include: @@ -177,15 +177,15 @@ To setup the ground station: 1. Install the required python modules: - ```sh - sudo pip install pika tornado future - ``` + ```sh + sudo pip install pika tornado future + ``` 2. Clone the SatComInfrastructure repository: - ```sh - git clone https://github.com/acfloria/SatComInfrastructure.git - ``` + ```sh + git clone https://github.com/acfloria/SatComInfrastructure.git + ``` 3. Edit the **udp2rabbit.cfg** configuration file to reflect your settings. @@ -193,20 +193,20 @@ To setup the ground station: 5. Add a UDP connection in QGC with the parameters: - - Listening port: 10000 - - Target hosts: 127.0.0.1:10001 - - High Latency: checked + - Listening port: 10000 + - Target hosts: 127.0.0.1:10001 + - High Latency: checked - ![High Latency Link Settings](../../assets/satcom/linksettings.png) + ![High Latency Link Settings](../../assets/satcom/linksettings.png) ### 验证 1. Open a terminal on the ground station computer and change to the location of the _SatComInfrastructure_ repository. - Then start the **udp2rabbit.py** script: + Then start the **udp2rabbit.py** script: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 2. Send a test message from [RockBlock Account](https://rockblock.rock7.com/Operations) to the created delivery group in the `Test Delivery Groups` tab. @@ -217,36 +217,36 @@ If in the terminal where the `udp2rabbit.py` script is running within a couple o ## Running the System 1. Start _QGroundControl_. - Manually connect the high latency link first, then the regular telemetry link: + Manually connect the high latency link first, then the regular telemetry link: - ![Connect the High Latency link](../../assets/satcom/linkconnect.png) + ![Connect the High Latency link](../../assets/satcom/linkconnect.png) 2. Open a terminal on the ground station computer and change to the location of the _SatComInfrastructure_ repository. - Then start the **udp2rabbit.py** script: + Then start the **udp2rabbit.py** script: - ```sh - ./udp2rabbit.py - ``` + ```sh + ./udp2rabbit.py + ``` 3. Power up the vehicle. 4. Wait until the first `HIGH_LATENCY2` message is received on QGC. - This can be checked either using the _MAVLink Inspector_ widget or on the toolbar with the _LinkIndicator_. - If more than one link is connected to the active vehicle the _LinkIndicator_ shows all of them by clicking on the name of the shown link: + This can be checked either using the _MAVLink Inspector_ widget or on the toolbar with the _LinkIndicator_. + If more than one link is connected to the active vehicle the _LinkIndicator_ shows all of them by clicking on the name of the shown link: - ![Link Toolbar](../../assets/satcom/linkindicator.jpg) + ![Link Toolbar](../../assets/satcom/linkindicator.jpg) - The link indicator always shows the name of the priority link. + The link indicator always shows the name of the priority link. 5. The satellite communication system is now ready to use. - The priority link, which is the link over which commands are send, is determined the following ways: - - If no link is commanded by the user a regular radio telemetry link is preferred over the high latency link. - - The autopilot and QGC will fall back from the regular radio telemetry to the high latency link if the vehicle is armed and the radio telemetry link is lost (no MAVLink messages received for a certain time). - As soon as the radio telemetry link is regained QGC and the autopilot will switch back to it. - - The user can select a priority link over the `LinkIndicator` on the toolbar. - This link is kept as the priority link as long as this link is active or the user selects another priority link: + The priority link, which is the link over which commands are send, is determined the following ways: + - If no link is commanded by the user a regular radio telemetry link is preferred over the high latency link. + - The autopilot and QGC will fall back from the regular radio telemetry to the high latency link if the vehicle is armed and the radio telemetry link is lost (no MAVLink messages received for a certain time). + As soon as the radio telemetry link is regained QGC and the autopilot will switch back to it. + - The user can select a priority link over the `LinkIndicator` on the toolbar. + This link is kept as the priority link as long as this link is active or the user selects another priority link: - ![Prioritylink Selection](../../assets/satcom/linkselection.png) + ![Prioritylink Selection](../../assets/satcom/linkselection.png) ## 故障处理 diff --git a/docs/zh/airframes/airframe_reference.md b/docs/zh/airframes/airframe_reference.md index cc3884a39e..940ae6a4be 100644 --- a/docs/zh/airframes/airframe_reference.md +++ b/docs/zh/airframes/airframe_reference.md @@ -615,6 +615,10 @@ div.frame_variant td, div.frame_variant th { Axial SCX10 2 Trail Honcho Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 51001

+ + NXP B3RB Rover Ackermann + Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 51002

+ Generic Rover Mecanum Maintainer: John Doe <john@example.com>

SYS_AUTOSTART = 52000

@@ -628,7 +632,16 @@ div.frame_variant td, div.frame_variant th { ### Free-Flyer
- + + + + + + + + + +
常规输出接法
  • Motor1: back left thruster, +x thrust
  • Motor2: front left thruster, -x thrust
  • Motor3: back right thruster, +x thrust
  • Motor4: front right thruster, -x thrust
  • Motor5: front left thruster, +y thrust
  • Motor6: front right thruster, -y thrust
  • Motor7: back left thruster, +y thrust
  • Motor8: back right thruster, -y thrust
@@ -638,7 +651,7 @@ div.frame_variant td, div.frame_variant th { - KTH-ATMOS + KTH-ATMOS Maintainer: DISCOWER

SYS_AUTOSTART = 70000

diff --git a/docs/zh/assembly/_assembly.md b/docs/zh/assembly/_assembly.md index 49f25eedd1..fed4f8f7ed 100644 --- a/docs/zh/assembly/_assembly.md +++ b/docs/zh/assembly/_assembly.md @@ -72,7 +72,7 @@ The FCs have much the same ports with similar names, and core peripherals are co | Full GPS plus Safety Switch | GPS1 | GPS&SAFETY | Primary GNSS module (GPS, compass, safety switch, buzzer, LED) | | Basic GPS | GPS2 | GPS2 | Secondary GNSS module (GNSS/compass) | | CAN | CAN1/CAN2 | CAN1/CAN2 | DroneCAN devices, such as GNSS modules, motors, etc | -| Telemetry | TELEM (1,2,3) | TELEM (1,2,3) | Telemetry radios, companion computers, MAVLink cameras, etc. | +| 数传 | TELEM (1,2,3) | TELEM (1,2,3) | Telemetry radios, companion computers, MAVLink cameras, etc. | | Analog Power | POWER (1,2) | POWER (1,2) | SMbus (I2C) power modules | | I2C | I2C | None | Other I2C peripherals | | SPI | SPI | SPI6 | SPI devices (note: 11 pin, not 6 as in standard) | @@ -285,13 +285,13 @@ A particular vehicle might have more/fewer motors and actuators, but the wiring The following sections explain each part in more detail. :::tip -If you're using [DroneCAN ESC](../peripherals/esc_motors.md#dronecan) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. +If you're using [DroneCAN ESC](../dronecan/escs.md) the control signals will be connected to the CAN BUS instead of the PWM outputs as shown. ::: ### Flight Controller Power Pixhawk FCs require a regulated power supply that can supply at around 5V/3A continuous (check your specific FC)! -This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC transmitter, and low power telemetry radio, but not for motors, actuators, and other peripherals. +This is sufficient to power the controller itself and a few low-power peripherals, such as a GNSS module, RC receiver, and low power telemetry radio, but not for motors, actuators, and other peripherals. [Power modules](../power_module/index.md) are commonly used to "split off" this regulated power supply for the FC and also to provide measurements of the battery voltage and total current to the whole system — which PX4 can use to estimate power levels. The power module is connected to the FC power port, which is normally labeled `POWER` (or `POWER 1` or `POWER 2` for FCs that have redundant power supply). @@ -421,12 +421,11 @@ They recommend sensors, power systems, and other components from the same manufa - [Pixracer Wiring Quickstart](../assembly/quick_start_pixracer.md) - [mRo (3DR) Pixhawk Wiring Quickstart](../assembly/quick_start_pixhawk.md) -## See Also +## 另见 - [Drone Components & Parts](../getting_started/px4_basic_concepts.md#drone-components-parts) (Basic Concepts) - [Payloads](../getting_started/px4_basic_concepts.md#payloads) (Basic Concepts) - [Hardware Selection & Setup](../hardware/drone_parts.md) — information about connecting and configuring specific flight controllers, sensors and other peripherals (e.g. airspeed sensor for planes). - - [Mounting the Flight Controller](../assembly/mount_and_orient_controller.md) - [Vibration Isolation](../assembly/vibration_isolation.md) - [Mounting a Compass](../assembly/mount_gps_compass.md) diff --git a/docs/zh/camera/camera_architecture.md b/docs/zh/camera/camera_architecture.md index fd81c41352..89b9ea5a54 100644 --- a/docs/zh/camera/camera_architecture.md +++ b/docs/zh/camera/camera_architecture.md @@ -107,7 +107,7 @@ The logged topic will depend on whether or not the camera capture pin is enabled Note that camera capture events are not logged when using the [MAVLink cameras that support Camera Protocol v2](../camera/mavlink_v2_camera.md), because the corresponding trigger events are not generated within PX4. -## See Also +## 另见 - Camera trigger driver: [source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/camera_trigger) - Camera capture driver: [source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/camera_capture) diff --git a/docs/zh/camera/fc_connected_camera.md b/docs/zh/camera/fc_connected_camera.md index 8645b80e94..fdae04a272 100644 --- a/docs/zh/camera/fc_connected_camera.md +++ b/docs/zh/camera/fc_connected_camera.md @@ -97,13 +97,13 @@ For more information see [Finding/Updating Parameters > Parameters Not In Firmwa Four different modes are supported, controlled by the [TRIG_MODE](../advanced_config/parameter_reference.md#TRIG_MODE) parameter: -| Mode | 描述 | -| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0 | Camera triggering is disabled. | -| 1 | Works like a basic intervalometer that can be enabled and disabled by using the MAVLink command `MAV_CMD_DO_TRIGGER_CONTROL`. See [command interface](#mavlink-command-interface) for more details. | -| 2 | Switches the intervalometer constantly on. | -| 3 | Triggers based on distance. A shot is taken every time the set horizontal distance is exceeded. The minimum time interval between two shots is however limited by the set triggering interval. | -| 4 | Triggers automatically when flying a survey in Mission mode. | +| 模式 | 描述 | +| -- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0 | Camera triggering is disabled. | +| 1 | Works like a basic intervalometer that can be enabled and disabled by using the MAVLink command `MAV_CMD_DO_TRIGGER_CONTROL`. See [command interface](#mavlink-command-interface) for more details. | +| 2 | Switches the intervalometer constantly on. | +| 3 | Triggers based on distance. A shot is taken every time the set horizontal distance is exceeded. The minimum time interval between two shots is however limited by the set triggering interval. | +| 4 | Triggers automatically when flying a survey in Mission mode. | :::info If it is your first time enabling the camera trigger app, remember to reboot after changing the `TRIG_MODE` parameter. @@ -188,16 +188,16 @@ The following sections are out of date and need retesting. 1. On the PX4 console: - ```shell - camera_trigger test - ``` + ```shell + camera_trigger test + ``` 2. From _QGroundControl_: - Click on **Trigger Camera** in the main instrument panel. - These shots are not logged or counted for geotagging. + Click on **Trigger Camera** in the main instrument panel. + These shots are not logged or counted for geotagging. - ![QGC Test Camera](../../assets/camera/qgc_test_camera.png) + ![QGC Test Camera](../../assets/camera/qgc_test_camera.png) ## Sony QX-1 example (Photogrammetry) @@ -310,7 +310,7 @@ Wire up your cameras to your AUX port by connecting the ground and signal pins t You will have to modify your driver to follow the sequence diagram above. Public reference implementations for [IDS Imaging UEye](https://github.com/ProjectArtemis/ueye_cam) cameras and for [IEEE1394 compliant](https://github.com/andre-nguyen/camera1394) cameras are available. -## See Also +## 另见 - Camera trigger driver: [source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/camera_trigger) - Camera capture driver: [source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/camera_capture) diff --git a/docs/zh/camera/index.md b/docs/zh/camera/index.md index 015d7fc9a5..6367fb82c0 100644 --- a/docs/zh/camera/index.md +++ b/docs/zh/camera/index.md @@ -14,7 +14,7 @@ PX4 integrates with three types of cameras: 推荐[MAVLink 摄像头](../camera/mavlink_v2_camera.md),因为它们使用简单一致的命令/消息集提供了最广泛的相机功能访问。 如果相机不支持该协议,则可以在一台机载计算机上运行[摄像机管理器](../camera/mavlink_v2_camera.md#camera-managers)以在 MAVLink 和相机的本机协议之间进行接口交互。 -## See Also +## 另见 - [云台(相机支架)](../advanced/gimbal_control.md) - [相机集成/架构](../camera/camera_architecture.md) ( PX4 开发者) diff --git a/docs/zh/camera/mavlink_v1_camera.md b/docs/zh/camera/mavlink_v1_camera.md index f7a20dcc0a..2c1289fa32 100644 --- a/docs/zh/camera/mavlink_v1_camera.md +++ b/docs/zh/camera/mavlink_v1_camera.md @@ -86,7 +86,7 @@ PX4 重新使用与自驾仪相同的系统 ID 和组件 ID [MAV_COMP_ID_ALL](ht 1. 修改一个未使用的 `MAV_n_CONFIG` 参数,例如[MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG),使其分配给相机连接的端口。 2. 将对应的 [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) 设置为 `2` (板载)。 - 这确保正确的 MAVLink 消息集被发出和转发。 + 这确保正确的 MAVLink 消息集被发出和转发。 3. 您可能需要设置一些其他参数,取决于您的连接 - 例如波特率。 然后按照其用户指南中的建议连接和配置相机。 diff --git a/docs/zh/camera/mavlink_v2_camera.md b/docs/zh/camera/mavlink_v2_camera.md index 5935a2d75c..abf7eb0490 100644 --- a/docs/zh/camera/mavlink_v2_camera.md +++ b/docs/zh/camera/mavlink_v2_camera.md @@ -112,7 +112,7 @@ The linked document explains how, but in summary: 1. Modify an unused `MAV_n_CONFIG` parameter, such as [MAV_2_CONFIG](../advanced_config/parameter_reference.md#MAV_2_CONFIG), so that it is assigned to port to which you connected the camera/companion computer. 2. 将对应的 [MAV_2_MODE](../advanced_config/parameter_reference.md#MAV_2_MODE) 设置为 `2` (板载)。 - This ensures that the right set of MAVLink messages are emitted for a companion computer (or camera). + This ensures that the right set of MAVLink messages are emitted for a companion computer (or camera). 3. Set [MAV_2_FORWARD](../advanced_config/parameter_reference.md#MAV_2_FORWARD) to enable forwarding of communications from the port to other ports, such as the one that is connected to the ground station. 4. You may need to set some of the other parameters, depending on your connection type and any particular requirements of the camera on the expected baud rate, and so on. diff --git a/docs/zh/can/index.md b/docs/zh/can/index.md index 1e3264327d..452f0aba97 100644 --- a/docs/zh/can/index.md +++ b/docs/zh/can/index.md @@ -1,9 +1,19 @@ -# CAN +# CAN (DroneCAN & Cyphal) -[控制器局域网(CAN)](https://en.wikipedia.org/wiki/CAN_bus)是一种可靠的有线网络,它能让诸如飞行控制器、电调、传感器及其他外设等无人机组件相互通信。 -它被设计为分布式架构,使用差分信号,即使在较长的电缆 (大型车辆上) 上也非常强大,避免单点故障。 +[Controller Area Network (CAN)](https://en.wikipedia.org/wiki/CAN_bus) is a robust wired network that allows drone components such as flight controller, ESCs, sensors, and other peripherals, to communicate with each other. + +It is particularly recommended on larger vehicles. + +## 综述 + +CAN it is designed to be democratic and uses differential signaling. +For this reason it is very robust even over longer cable lengths (on large vehicles), and avoids a single point of failure. CAN 还允许来自外设的状态反馈,并通过总线方便的进行固件升级。 +PX4 has the ability to track and log detailed information from CAN devices, including firmware versions, hardware versions, and serial numbers. +This enables unique identification and lifecycle tracking of hardware connected to the flight controller. +See [Asset Tracking](../debug/asset_tracking.md) for more information. + PX4 支持与 CAN 设备通信的两个软件协议: - [DroneCAN](../dronecan/index.md): PX4 推荐大多数常见的设置。 @@ -18,29 +28,36 @@ DroneCAN 和 Cyphal 都是早先一个叫做UAVCAN的项目。 这两项协议之间的差异在[Cyphal vs. DroneCAN](https://forum.opencyphal.org/t/cyphal-vs-dronecan/1814)中作了概述。 ::: -:::warning PX4不支持KDECAN等无人驾驶飞机的其他CAN软件协议(撰写时)。 -::: ## 布线 CAN 网络的接线对于 DroneCAN 和 Cyphal/CAN 是一样 (实际上对所有的 CAN 网络都一样)。 -设备以任意顺序连接成链。 +Devices within a network are connected in a _daisy-chain_ in any order (this differs from UARTs peripherals, where you attach just one component per port). + +:::warning +Don't connect each CAN peripheral to a separate CAN port! +Unlike UARTs, CAN peripherals are designed to be daisy chained, with additional ports such as `CAN2` used for [redundancy](redundancy). +::: + 在链的任一端,应该在两个数据线之间连接一个 120Ω 的终端电阻。 飞控和一些 GNSS 模块为了方便使用内置了终端电阻, 因此应该放在链的终端。 否则,你可以使用终端电阻,比如 [Zubax Robotics 的这款](https://shop.zubax.com/products/uavcan-micro-termination-plug?variant=6007985111069)。如果你有JST - GH压接工具,也可以自己焊接一个。 下图显示了一个 CAN 总线连接飞控到 4 个 CAN 电调和一个 GNSS 的示例。 +It includes a redundant bus connected to `CAN 2`. ![CAN 布线](../../assets/can/uavcan_wiring.svg) 图中未显示任何电源接线。 参考制造商的说明,确认组件是否需要单独供电,还是可以通过 CAN 总线供电。 +:::info For more information, see [Cyphal/CAN device interconnection](https://wiki.zubax.com/public/cyphal/CyphalCAN-device-interconnection?pageId=2195476) (kb.zubax.com). 虽然本文是以 Cyphal 协议为基础编写的,但同样适用于 DroneCAN 硬件和任何其他 CAN 设置。 如需了解更复杂的场景,请参考 [论CAN总线拓扑结构与终端匹配](https://forum.opencyphal.org/t/on-can-bus-topology-and-termination/1685)。 +::: ### 连接器 @@ -54,7 +71,30 @@ Pixhawk标准兼容的 CAN 设备使用 4 引脚的 JST-GH 连接器为 CAN。 DroneCAN 和 Cyphal/CAN支持使用第二个(冗余) CAN 接口。 这是完全可选的,但会增加连接的强度。 -所有Pixhawk飞行控制器都带有两个CAN接口; 如果您的外围设备也支持 2 CAN 接口,建议您同时进行电线连接以提高安全。 + +Pixhawk flight controllers come with 2 CAN interfaces; if your peripherals support 2 CAN interfaces as well, it is recommended to wire both up for increased safety. + +### Flight Controllers with Multiple CAN Ports + +[Flight Controllers](../flight_controller/index.md) may have up to three independent CAN ports, such as `CAN1`, `CAN2`, `CAN3` (neither DroneCAN or Cyphal support more than three). +Note that you can't have both DroneCAN and Cyphal running on PX4 at the same time. + +:::tip +You only _need_ one CAN port to support an arbitrary number of CAN devices using a particular CAN protocol. +Don't connect each CAN peripheral to a separate CAN port! +::: + +Generally you'll daisy all CAN peripherals off a single port, and if there is more than one CAN port, use the second one for [redundancy](redundancy). +If three are three ports, you might use the remaining network for devices that support another CAN protocol. + +The documentation for your flight controller should indicate which ports are supported/enabled. +At runtime you can check what DroneCAN ports are enabled and their status using the following command on the [MAVLink Shell](../debug/mavlink_shell.md) (or some other console): + +```sh +uavcan status +``` + +Note that you can also check the number of supported CAN interfaces for a board by searching for `CONFIG_BOARD_UAVCAN_INTERFACES` in its [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#) configuration file. ## 固件 diff --git a/docs/zh/companion_computer/ark_jetson_pab_carrier.md b/docs/zh/companion_computer/ark_jetson_pab_carrier.md index c34e2a96e4..bbfa91cc1e 100644 --- a/docs/zh/companion_computer/ark_jetson_pab_carrier.md +++ b/docs/zh/companion_computer/ark_jetson_pab_carrier.md @@ -89,6 +89,6 @@ To flash the kernel, connect the Jetson to your Host PC via Micro USB, and boot ![Jetson Carrier Flashing Guide](../../assets/companion_computer/ark_jetson_pab_carrier/ark_jetson_flashing_guide.png) -## See Also +## 另见 - [ARK Jetson PAB Documentation](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-jetson-pab-carrier) (ARK Docs) diff --git a/docs/zh/companion_computer/holybro_pixhawk_jetson_baseboard.md b/docs/zh/companion_computer/holybro_pixhawk_jetson_baseboard.md index 5a49dd739d..e49a32a97a 100644 --- a/docs/zh/companion_computer/holybro_pixhawk_jetson_baseboard.md +++ b/docs/zh/companion_computer/holybro_pixhawk_jetson_baseboard.md @@ -892,95 +892,95 @@ These instructions approximately mirror the [PX4 Ethernet setup](../advanced_con Next we modify the Jetson IP address to be on the same network as the Pixhawk: 1. Make sure `netplan` is installed. - You can check by running the following command: + You can check by running the following command: - ```sh - netplan -h - ``` + ```sh + netplan -h + ``` - If not, install it using the commands: + If not, install it using the commands: - ```sh - sudo apt update - sudo apt install netplan.io - ``` + ```sh + sudo apt update + sudo apt install netplan.io + ``` 2. Check `system_networkd` is running: - ```sh - sudo systemctl status systemd-networkd - ``` + ```sh + sudo systemctl status systemd-networkd + ``` - You should see output like below if it is active: + You should see output like below if it is active: - ```sh - ● systemd-networkd.service - Network Configuration - Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) - Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago - TriggeredBy: ● systemd-networkd.socket - Docs: man:systemd-networkd.service(8) - Main PID: 2452 (systemd-network) - Status: "Processing requests..." - Tasks: 1 (limit: 18457) - Memory: 2.7M - CPU: 157ms - CGroup: /system.slice/systemd-networkd.service - └─2452 /lib/systemd/systemd-networkd + ```sh + ● systemd-networkd.service - Network Configuration + Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) + Active: active (running) since Wed 2024-09-11 23:32:44 EDT; 23min ago + TriggeredBy: ● systemd-networkd.socket + Docs: man:systemd-networkd.service(8) + Main PID: 2452 (systemd-network) + Status: "Processing requests..." + Tasks: 1 (limit: 18457) + Memory: 2.7M + CPU: 157ms + CGroup: /system.slice/systemd-networkd.service + └─2452 /lib/systemd/systemd-networkd - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed - Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. - Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> - Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost - ``` + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: lo: Gained carrier + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: eth0: Gained IPv6LL + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: Enumeration completed + Sep 11 23:32:44 ubuntu systemd[1]: Started Network Configuration. + Sep 11 23:32:44 ubuntu systemd-networkd[2452]: wlan0: Connected WiFi access point: Verizon_7YLWWD (78:67:0e:ea:a6:0> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: Re-configuring with /run/systemd/network/10-netplan-eth0.netwo> + Sep 11 23:34:16 ubuntu systemd-networkd[2452]: eth0: DHCPv6 lease lost + ``` - If `system_networkd` is not running, it can be enabled using: + If `system_networkd` is not running, it can be enabled using: - ```sh - sudo systemctl start systemd-networkd - sudo systemctl enable systemd-networkd - ``` + ```sh + sudo systemctl start systemd-networkd + sudo systemctl enable systemd-networkd + ``` 3. Open the Netplan configuration file (so we can set up a static IP for the Jetson). - The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). - Below we use `nano` to open the file, but you can use your preferred text editor: + The Netplan configuration file is usually located in the `/etc/netplan/` directory and named something like `01-netcfg.yaml` (the name can vary). + Below we use `nano` to open the file, but you can use your preferred text editor: - ```sh - sudo nano /etc/netplan/01-netcfg.yaml - ``` + ```sh + sudo nano /etc/netplan/01-netcfg.yaml + ``` 4. Modify the yaml configuration, by overwriting the contents with the following information and then saving: - ```sh - network: - version: 2 - renderer: networkd - ethernets: - eth0: - dhcp4: no - addresses: - - 10.41.10.1/24 - routes: - - to: 0.0.0.0/0 - via: 10.41.10.254 - nameservers: - addresses: - - 10.41.10.254 - ``` + ```sh + network: + version: 2 + renderer: networkd + ethernets: + eth0: + dhcp4: no + addresses: + - 10.41.10.1/24 + routes: + - to: 0.0.0.0/0 + via: 10.41.10.254 + nameservers: + addresses: + - 10.41.10.254 + ``` - This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . + This gives the Jetson a static IP address on the Ethernet interface of `10.41.10.1` . 5. Apply the changes using the following command: - ```sh - sudo netplan apply - ``` + ```sh + sudo netplan apply + ``` The Pixhawk Ethernet address is set to `10.41.10.2` by default, which is on the same subnet. We can test our changes above by pinging the Pixhawk from within the Jetson terminal: @@ -1329,7 +1329,7 @@ You should see high frequency sensor messages as the output: [sensor_combined_listener-1] accelerometer_integral_dt: 4999 ``` -## See Also +## 另见 - [Jetson carrier board Holybro Docs](https://docs.holybro.com/autopilot/pixhawk-baseboards/pixhawk-jetson-baseboard) - [PX4 Middleware docs](../middleware/uxrce_dds.md#starting-the-client) diff --git a/docs/zh/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md b/docs/zh/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md index 5c331fd9bb..91bceef69c 100644 --- a/docs/zh/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md +++ b/docs/zh/companion_computer/holybro_pixhawk_rpi_cm4_baseboard.md @@ -69,15 +69,15 @@ To install the RPi CM4 companion computer: 1. Disconnect the `FAN` wiring. - ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) + ![HB_Pixhawk_CM4_Fan](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fan.jpg) 2. Remove these 4 screws on the back side of the baseboard. - ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) + ![Bottom of the board showing screws in corners holding the cover](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_bottom.jpg) 3. Remove the baseboard case, install the CM4, and use the 4 screws to attach it (as shown): - ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) + ![HB_Pixhawk_CM4_Screws](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_screws.jpg) 4. Reattach the cover. @@ -115,29 +115,29 @@ To flash a RPi image onto EMMC. 1. Switch Dip-Switch to `RPI`. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_dip_switch.png) 2. Connect computer to USB-C _CM4 Slave_ port used to power & flash the RPi. - ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) + ![](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/cm4_usbc_slave_port.png) 3. Get `usbboot`, build it and run it. - ```sh - sudo apt install libusb-1.0-0-dev - git clone --depth=1 https://github.com/raspberrypi/usbboot - cd usbboot - make - sudo ./rpiboot - ``` + ```sh + sudo apt install libusb-1.0-0-dev + git clone --depth=1 https://github.com/raspberrypi/usbboot + cd usbboot + make + sudo ./rpiboot + ``` 4. You can now install your preferred Linux distro using The `rpi-imager`. - Make sure you add WiFi and SSH settings (hidden behind the gear/advanced symbol). + Make sure you add WiFi and SSH settings (hidden behind the gear/advanced symbol). - ```sh - sudo apt install rpi-imager - rpi-imager - ``` + ```sh + sudo apt install rpi-imager + rpi-imager + ``` 5. Once done, unplugging USB-C CM4 Slave (this will unmount the volumes, and power off the CM4). @@ -146,8 +146,8 @@ To flash a RPi image onto EMMC. 7. Power on CM4 by providing power to USB-C CM4 Slave port. 8. To check if it's booting/working you can either: - - Check there is HDMI output - - Connect via SSH (if set up in rpi-imager, and WiFi is available). + - Check there is HDMI output + - Connect via SSH (if set up in rpi-imager, and WiFi is available). ## Configure PX4 to CM4 MAVLink Serial Connection @@ -167,13 +167,13 @@ To enable this MAVLink instance on the FC: 1. Connect a computer running QGroundControl via USB Type C port on the baseboard labeled `FC` - ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) + ![Image of baseboard showing FC USB-C connector](../../assets/companion_computer/holybro_pixhawk_rpi_cm4_baseboard/baseboard_fc_usb_c.jpg) 2. [Set the parameters](../advanced_config/parameters.md): - - `MAV_1_CONFIG` = `102` - - `MAV_1_MODE = 2` - - `SER_TEL2_BAUD` = `921600` + - `MAV_1_CONFIG` = `102` + - `MAV_1_MODE = 2` + - `SER_TEL2_BAUD` = `921600` 3. Reboot the FC. @@ -185,13 +185,13 @@ On the RPi side: 2. 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` - - `serial port hardware enabled` → `Yes` + - Go to `3 Interface Options`, then `I6 Serial Port`. + Then choose: + - `login shell accessible over serial → No` + - `serial port hardware enabled` → `Yes` 3. Finish, and reboot. - This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. + This will add `enable_uart=1` to `/boot/config.txt`, and remove `console=serial0,115200` from `/boot/cmdline.txt`. 4. Now MAVLink traffic should be available on `/dev/serial0` at a baudrate of 921600. @@ -201,9 +201,9 @@ On the RPi side: 2. Install MAVSDK Python: - ```sh - python3 -m pip install mavsdk - ``` + ```sh + python3 -m pip install mavsdk + ``` 3. Copy an example from the [MAVSDK-Python examples](https://github.com/mavlink/MAVSDK-Python/tree/main/examples). @@ -418,7 +418,7 @@ And such output is expected if everything is set up correctly: [1731210066.597046] info | ProxyClient.cpp | create_datareader | datareader created | client_key: 0x00000001, datareader_id: 0x804(6), subscriber_id: 0x804(4) ``` -## See Also +## 另见 - [Get The Pixhawk Raspberry Pi CM4 Baseboard By Holybro Talking With PX4](https://px4.io/get-the-pixhawk-raspberry-pi-cm4-baseboard-by-holybro-talking-with-px4/) (px4.io blog): - 展示如何通过有线以太网连接 Pixhawk 6X + Raspberry Pi 到 CM4 主板。 diff --git a/docs/zh/companion_computer/pixhawk_rpi.md b/docs/zh/companion_computer/pixhawk_rpi.md index 26948bd350..73406d2a8d 100644 --- a/docs/zh/companion_computer/pixhawk_rpi.md +++ b/docs/zh/companion_computer/pixhawk_rpi.md @@ -132,50 +132,50 @@ Enter the following commands (in sequence) a terminal to configure Ubuntu for RP 1. Install `raspi-config`: - ```sh - sudo apt update - sudo apt upgrade - sudo apt-get install raspi-config - ``` + ```sh + sudo apt update + sudo apt upgrade + sudo apt-get install raspi-config + ``` 2. Open `raspi-config`: - ```sh - sudo raspi-config - ``` + ```sh + sudo raspi-config + ``` 3. 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. + - Select **No** to disable serial login shell. + - Select **Yes** to enable the serial interface. + - Click **Finish** and restart the RPi. 4. Open the firmware boot configuration file in the `nano` editor on RPi: - ```sh - sudo nano /boot/firmware/config.txt - ``` + ```sh + sudo nano /boot/firmware/config.txt + ``` 5. Append the following text to the end of the file (after the last line): - ```sh - enable_uart=1 - dtoverlay=disable-bt - ``` + ```sh + enable_uart=1 + dtoverlay=disable-bt + ``` 6. 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**. + - In `nano` you can save the file using the following sequence of keyboard shortcuts: **ctrl+x**, **ctrl+y**, **Enter**. 7. Check that the serial port is available. - In this case we use the following terminal commands to list the serial devices: + In this case we use the following terminal commands to list the serial devices: - ```sh - cd / - ls /dev/ttyAMA0 - ``` + ```sh + cd / + ls /dev/ttyAMA0 + ``` - The result of the command should include the RX/TX connection `/dev/ttyAMA0` (note that this serial port is also available as `/dev/serial0`). + The result of the command should include the RX/TX connection `/dev/ttyAMA0` (note that this serial port is also available as `/dev/serial0`). The RPi is now setup to work with RPi and communicate using the `/dev/ttyAMA0` serial port. Note that we'll install more software in the following sections to work with MAVLink and ROS 2. @@ -199,39 +199,39 @@ First check the Pixhawk `TELEM 2` configuration: 2. Open QGroundControl (the vehicle should connect). 3. [Check/change the following parameters](../advanced_config/parameters.md) in QGroundControl: - ```ini - MAV_1_CONFIG = TELEM2 - UXRCE_DDS_CFG = 0 (Disabled) - SER_TEL2_BAUD = 57600 - ``` + ```ini + MAV_1_CONFIG = TELEM2 + UXRCE_DDS_CFG = 0 (Disabled) + SER_TEL2_BAUD = 57600 + ``` - Note that the parameters may already be set appropriately. - For information about how serial ports and MAVLink configuration work see [Serial Port Configuration](../peripherals/serial_configuration.md) and [MAVLink Peripherals](../peripherals/mavlink_peripherals.md). + Note that the parameters may already be set appropriately. + For information about how serial ports and MAVLink configuration work see [Serial Port Configuration](../peripherals/serial_configuration.md) and [MAVLink Peripherals](../peripherals/mavlink_peripherals.md). Then install setup MAVProxy on the RPi using the following terminal commands: 1. Install MAVProxy: - ```sh - sudo apt install python3-pip - sudo pip3 install mavproxy - sudo apt remove modemmanager - ``` + ```sh + sudo apt install python3-pip + sudo pip3 install mavproxy + sudo apt remove modemmanager + ``` 2. Run MAVProxy, setting the port to connect to `/dev/ttyAMA0` and the baud rate to match the PX4: - ```sh - sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 - ``` + ```sh + sudo mavproxy.py --master=/dev/serial0 --baudrate 57600 + ``` - ::: info - Note that above we used `/dev/serial0`, but we could equally well have used `/dev/ttyAMA0`. - If we were connecting via USB then we would instead set the port as `/dev/ttyACM0`: + ::: info + Note that above we used `/dev/serial0`, but we could equally well have used `/dev/ttyAMA0`. + If we were connecting via USB then we would instead set the port as `/dev/ttyACM0`: - ```sh - sudo chmod a+rw /dev/ttyACM0 - sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 - ``` + ```sh + sudo chmod a+rw /dev/ttyACM0 + sudo mavproxy.py --master=/dev/ttyACM0 --baudrate 57600 + ``` ::: @@ -259,27 +259,27 @@ The configuration steps are: 2. [Check/change the following parameters](../advanced_config/parameters.md) in QGroundControl: - ```ini - MAV_1_CONFIG = 0 (Disabled) - UXRCE_DDS_CFG = 102 (TELEM2) - SER_TEL2_BAUD = 921600 - ``` + ```ini + MAV_1_CONFIG = 0 (Disabled) + UXRCE_DDS_CFG = 102 (TELEM2) + SER_TEL2_BAUD = 921600 + ``` - [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) and [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) disable MAVLink on TELEM2 and enable the uXRCE-DDS client on TELEM2, respectively. - The `SER_TEL2_BAUD` rate sets the comms link data rate.\ - You could similarly configure a connection to `TELEM1` using either `MAV_1_CONFIG` or `MAV_0_CONFIG`. + [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) and [UXRCE_DDS_CFG=102](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG) disable MAVLink on TELEM2 and enable the uXRCE-DDS client on TELEM2, respectively. + The `SER_TEL2_BAUD` rate sets the comms link data rate. + You could similarly configure a connection to `TELEM1` using either `MAV_1_CONFIG` or `MAV_0_CONFIG`. - ::: info - You will need to reboot the flight controller to apply any changes to these parameters. + ::: info + You will need to reboot the flight controller to apply any changes to these parameters. ::: 3. Check that the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module is now running. - YOu can do this by running the following command in the QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): + YOu can do this by running the following command in the QGroundControl [MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - ```sh - uxrce_dds_client status - ``` + ```sh + uxrce_dds_client status + ``` :::info If the client module is not running you can start it manually in the MAVLink console: @@ -300,32 +300,32 @@ The steps to setup ROS 2 and the Micro XRCE-DDS Agent on the RPi are: 2. Install the git using the RPi terminal: - ```sh - sudo apt install git - ``` + ```sh + sudo apt install git + ``` 3. Install the uXRCE_DDS agent: - ```sh - git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` - See [uXRCE-DDS > Micro XRCE-DDS Agent Installation](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) for alternative ways of installing the agent. + See [uXRCE-DDS > Micro XRCE-DDS Agent Installation](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation) for alternative ways of installing the agent. 4. Start the agent in the RPi terminal: - ```sh - sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 - ``` + ```sh + sudo MicroXRCEAgent serial --dev /dev/serial0 -b 921600 + ``` - Note how we use the serial port set up earlier and the same baud rate as for PX4. + Note how we use the serial port set up earlier and the same baud rate as for PX4. Now that both the agent and client are running, you should see activity on both the MAVLink console and the RPi terminal. You can view the available topics using the following command on the RPi: diff --git a/docs/zh/companion_computer/video_streaming_wfb_ng_wifi.md b/docs/zh/companion_computer/video_streaming_wfb_ng_wifi.md index 80227c2b6d..86982c4b20 100644 --- a/docs/zh/companion_computer/video_streaming_wfb_ng_wifi.md +++ b/docs/zh/companion_computer/video_streaming_wfb_ng_wifi.md @@ -80,18 +80,18 @@ If you use a special "very" high power cards from Taobao/Aliexpress then you MUS 5. Setup camera pipeline. Open `/etc/systemd/system/fpv-camera.service` and uncomment pipeline according to your camera (PI camera or Logitech camera) 6. Open `/etc/wifibroadcast.cfg` and configure WiFi channel according to your antenna setup (or use default #165 for 5.8GHz) 7. Configure PX4 to output telemetry stream at speed 1500 Kbps (other UART speeds doesn't match well to RPi frequency dividers). - Connect Pixhawk UART to Raspberry Pi UART. - In `/etc/wifibroadcast.cfg` uncomment `peer = 'serial:ttyS0:1500000'` in `[drone_mavlink]` section. + Connect Pixhawk UART to Raspberry Pi UART. + In `/etc/wifibroadcast.cfg` uncomment `peer = 'serial:ttyS0:1500000'` in `[drone_mavlink]` section. ### Using a Linux Laptop as GCS (Harder than using a RPi) 1. On **ground** Linux development computer: - ```sh - sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted - git clone -b stable https://github.com/svpcom/wfb-ng.git - cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb - ``` + ```sh + sudo apt install libpcap-dev libsodium-dev python3-all python3-twisted + git clone -b stable https://github.com/svpcom/wfb-ng.git + cd wfb-ng && make deb && sudo apt install ./deb_dist/wfb-ng*.deb + ``` 2. Follow the [Setup HOWTO](https://github.com/svpcom/wfb-ng/wiki/Setup-HOWTO) to complete installation diff --git a/docs/zh/complete_vehicles_fw/index.md b/docs/zh/complete_vehicles_fw/index.md index 636dfd5ef6..23a08e6ada 100644 --- a/docs/zh/complete_vehicles_fw/index.md +++ b/docs/zh/complete_vehicles_fw/index.md @@ -35,7 +35,7 @@ This section lists vehicles that are sold fully assembled and ready to fly (RTF) This section lists vehicles where you can update the software to run PX4. --> -## See Also +## 另见 - [DIY Builds](../frames_plane/diy_builds.md) - [Complete Vehicles (VTOL)](../complete_vehicles_vtol/index.md) diff --git a/docs/zh/complete_vehicles_mc/amov_F410_drone.md b/docs/zh/complete_vehicles_mc/amov_F410_drone.md index 1a64d3a506..2f25e16aa9 100644 --- a/docs/zh/complete_vehicles_mc/amov_F410_drone.md +++ b/docs/zh/complete_vehicles_mc/amov_F410_drone.md @@ -22,7 +22,7 @@ It is pre-installed with PX4 v1.15.4 at time of writing (a more recent version m - Compatibility with many different components, providing platform for loading other user sensors, preparing for functional model development. - Abundant power supply making it perfect for installing additional sensors and onboard computers (including 5 external output voltages, 3 channels of 5V, 2 channels of 12V). - Pc-SDK support. - This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! + This is a PC-based Python SDK Library based on MAVSDK that significantly simplifies UAV development compared to other approaches, such as using ROS or using C++. All you need is a basic understanding of Python programming and some simple coordinate system principles! - The [documentation](https://docs.amovlab.com/f450-v6c-wiki/#/en/) shows many of the options. 7. Quasi-smart battery. The battery has a hard housing design that makes easy to install and remove. It provides accurate power estimates, but does not have some more advanced "smart battery" features. @@ -53,7 +53,7 @@ It is pre-installed with PX4 v1.15.4 at time of writing (a more recent version m | 处理器 | FMU: STM32H743; IO Processor: STM32F103 | | Accelerometer | BMI055/ICM-42688-P | | Gyroscope | BMI055/ICM-42688-P | -| 磁罗盘 | IST8310 | +| 磁力计 | IST8310 | | Barometer | MS5611 | | 重量 | 59.3g | | 尺寸 | Length 84.8mm × Width 44mm × Height 12.4mm | diff --git a/docs/zh/complete_vehicles_mc/crazyflie2.md b/docs/zh/complete_vehicles_mc/crazyflie2.md index 57e7af9c1d..67534784c5 100644 --- a/docs/zh/complete_vehicles_mc/crazyflie2.md +++ b/docs/zh/complete_vehicles_mc/crazyflie2.md @@ -51,54 +51,54 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the source code of the PX4 Bootloader: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git + ``` 2. Navigate into the top directory of the source code and compile it using: - ```sh - make crazyflie_bl - ``` + ```sh + make crazyflie_bl + ``` 3. Put the Crazyflie 2.0 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Hold down the reset button (see figure below...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Hold down the reset button (see figure below...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 4. Install _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.0 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie_bl/crazyflie_bl.bin + ``` - When powering on the Crazyflie 2.0 the yellow LED should blink. + When powering on the Crazyflie 2.0 the yellow LED should blink. 6. Download the source code of the PX4 autopilot: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Navigate into the top directory of the source code and compile it using: - ```sh - make bitcraze_crazyflie_default upload - ``` + ```sh + make bitcraze_crazyflie_default upload + ``` 8. When prompted to plug in device, plug in Crazyflie 2.0. - The yellow LED should start blinking indicating bootloader mode. - Then the red LED should turn on indicating that the flashing process has started. + The yellow LED should start blinking indicating bootloader mode. + Then the red LED should turn on indicating that the flashing process has started. 9. Wait for completion. diff --git a/docs/zh/complete_vehicles_mc/crazyflie21.md b/docs/zh/complete_vehicles_mc/crazyflie21.md index 3002164a54..370c0b61d1 100644 --- a/docs/zh/complete_vehicles_mc/crazyflie21.md +++ b/docs/zh/complete_vehicles_mc/crazyflie21.md @@ -64,56 +64,56 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the source code of the PX4 Bootloader: - ```sh - git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules - ``` + ```sh + git clone https://github.com/PX4/PX4-Bootloader.git --recurse-submodules + ``` 2. Navigate into the top directory of the source code and compile it using: - ```sh - make crazyflie21_bl - ``` + ```sh + make crazyflie21_bl + ``` 3. Put the Crazyflie 2.1 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Ensure battery is disconnected. - - Hold down the reset button (see figure below...). - ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Ensure battery is disconnected. + - Hold down the reset button (see figure below...). + ![Crazyflie2 Reset Button](../../assets/flight_controller/crazyflie/crazyflie_reset_button.jpg) + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 4. Install _dfu-util_: - ```sh - sudo apt-get update - sudo apt-get install dfu-util - ``` + ```sh + sudo apt-get update + sudo apt-get install dfu-util + ``` 5. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.1 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D ./build/crazyflie21_bl/crazyflie21_bl.bin + ``` - When powering on the Crazyflie 2.1 the yellow LED should blink. + When powering on the Crazyflie 2.1 the yellow LED should blink. 6. Download the source code of the PX4 autopilot: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + ``` 7. Navigate into the top directory of the source code and compile it using: - ```sh - cd PX4-Autopilot/ - make bitcraze_crazyflie21_default upload - ``` + ```sh + cd PX4-Autopilot/ + make bitcraze_crazyflie21_default upload + ``` 8. When prompted to plug in device, plug in Crazyflie 2.1. - The yellow LED should start blinking indicating bootloader mode. - Then the red LED should turn on indicating that the flashing process has started. + The yellow LED should start blinking indicating bootloader mode. + Then the red LED should turn on indicating that the flashing process has started. 9. Wait for completion. @@ -124,20 +124,20 @@ After setting up the PX4 development environment, follow these steps to install 1. Download the latest [Crazyflie 2.1 bootloader](https://github.com/bitcraze/crazyflie2-stm-bootloader/releases) 2. Put the Crazyflie 2.1 into DFU mode by following these steps: - - Ensure it is initially unpowered. - - Ensure battery is disconnected. - - Hold down the reset button. - - Plug into computer's USB port. - - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. - - Release button. + - Ensure it is initially unpowered. + - Ensure battery is disconnected. + - Hold down the reset button. + - Plug into computer's USB port. + - After a second, the blue LED should start blinking and after 5 seconds should start blinking faster. + - Release button. 3. Flash bootloader using _dfu-util_ and unplug Crazyflie 2.1 when done: - ```sh - sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin - ``` + ```sh + sudo dfu-util -d 0483:df11 -a 0 -s 0x08000000 -D cf2loader-1.0.bin + ``` - When powering on the Crazyflie 2.1 the yellow LED should blink. + When powering on the Crazyflie 2.1 the yellow LED should blink. 4. Install the latest Bitcraze Crazyflie 2.1 Firmware using [this](https://www.bitcraze.io/documentation/tutorials/getting-started-with-crazyflie-2-x/#update-fw) tutorial. diff --git a/docs/zh/complete_vehicles_mc/index.md b/docs/zh/complete_vehicles_mc/index.md index b8a8f1d948..9080d8601f 100644 --- a/docs/zh/complete_vehicles_mc/index.md +++ b/docs/zh/complete_vehicles_mc/index.md @@ -40,7 +40,7 @@ These may or may not be updatable to run "vanilla" PX4. - [Yuneec H520](https://px4.io/project/yuneec-h520-hexacopter/) - [AeroSense Aerobo (AS-MC02-P)](https://px4.io/project/aerosense-aerobo/) -## See Also +## 另见 - [Kits (MC)](../frames_multicopter/kits.md) - [DIY Builds](../frames_multicopter/diy_builds.md) diff --git a/docs/zh/complete_vehicles_mc/modalai_starling.md b/docs/zh/complete_vehicles_mc/modalai_starling.md index 3791ce71f9..9ceebd8329 100644 --- a/docs/zh/complete_vehicles_mc/modalai_starling.md +++ b/docs/zh/complete_vehicles_mc/modalai_starling.md @@ -1,127 +1,39 @@ -# ModalAI Starling (PX4 Autonomy Developer Kit) +# ModalAI Starling 2 -The [Starlings](https://www.modalai.com/pages/starlings) are SLAM development drones supercharged by [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -Powered by Blue UAS Framework autopilot, VOXL 2, the Starling weighs only 275g and boasts an impressive 30 minutes of autonomous indoor flight time. +The [Starlings](https://www.modalai.com/pages/starlings) are NDAA-compliant SLAM development drones based on the [VOXL 2](../flight_controller/modalai_voxl_2.md) and PX4 with SWAP-optimized sensors and payloads optimized for indoor and outdoor autonomous navigation. -![Overview](../../assets/hardware/complete_vehicles/modalai_starling/starling_front_hero.jpg) +## 综述 -The ModalAI PX4 Autonomy Developer Kit is a Starling-based development drone. -It houses a [VOXL 2](../flight_controller/modalai_voxl_2.md), which is a powerful companion computer and PX4 flight controller in one small package, image sensors, GPS, and connectivity modem, and is ready-to-fly out-of-the-box. -The Starling features ModalAI's [open SDK](https://docs.modalai.com/voxl-developer-bootcamp/) that has pre-configured autonomy models for computer vision assisted flight. -This development drone is meant to help you get to market faster and accelerate your application development and prototyping. +Starling drones house _VOXL 2_, which is a powerful companion computer, a PX4 flight controller, image sensors, GPS, and connectivity modem, in one small package. +The Starlings feature ModalAI's open source [VOXL SDK](https://gitlab.com/voxl-public/voxl-sdk) that has pre-configured autonomy models for computer vision assisted flight. -This guide explains the minimal additional setup required to get the UAV ready to fly. -It also covers a hardware overview, first flight, setting up WiFi, and more. - -:::info -For complete and regularly updated documentation, please visit . -::: +These development drones are ready-to-fly out-of-the-box. +They are designed to help you get to market faster and accelerate your application development and prototyping. :::info If you are new to VOXL, be sure to familiarize yourself with the core features of VOXL hardware and software by reviewing the [VOXL Bootcamp](https://docs.modalai.com/voxl-developer-bootcamp/). ::: +:::info +For complete and regularly updated documentation, please visit and . +::: + +## Starling 2 + +The [Starling 2](https://www.modalai.com/products/starling-2) is an NDAA-compliant development drone supercharged by the VOXL SDK and equipped with a new image sensor suite for precise, indoor visual navigation and SLAM. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 weighs 280g and boasts an impressive 40 minutes of autonomous flight time. + +![Image of the front of Starling 2](../../assets/hardware/complete_vehicles/modalai_starling/d0014_front_1920x800.png) + +## Starling 2 Max + +The [Starling 2 Max](https://www.modalai.com/products/starling-2-max) is VOXL 2-powered, NDAA-compliant development drone supercharged by VOXL SDK specifically designed for computer vision-based, long-range dead reckoning with a 500g payload capacity. Powered by the Blue UAS Framework autopilot, VOXL 2, the Starling 2 Max weighs 500g and boasts an impressive 55 minutes of autonomous flight time. + +![Image of front of a Starling 2 Max](../../assets/hardware/complete_vehicles/modalai_starling/d0012_front_1920x800.png) + ## 购买渠道 -[ModalAI PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit?variant=46969885950256) +[ModalAI Starling 2](https://www.modalai.com/products/starling-2) -## Hardware Overview - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/mrb_d0005_4_v2_c6_m22__callouts_a.jpg) - -| Callout | 描述 | MPN | -| ------- | -------------------------------------------------------- | ---------------- | -| A | VOXL 2 | MDK-M0054-1 | -| B | VOXL 4-in-1 ESC | MDK-M0117-1 | -| C | Barometer Shield Cap | M10000533 | -| D | ToF Image Sensor (PMD) | MDK-M0040 | -| E | Tracking Image Sensor (OV7251) | M0014 | -| F | Hires Image Sensor (IMX214) | M0025-2 | -| G | AC600 WiFi Dongle | AWUS036EACS | -| H | GNSS GPS Module & Compass | M10-5883 | -| I | 915MHz ELRS Receiver | BetaFPV Nano RX | -| J | USB C Connector on VOXL 2 (not shown) | | -| K | VOXL Power Module | MCCA-M0041-5-B-T | -| L | 4726FM Propellor | M10000302 | -| M | Motor 1504 | | -| N | XT30 Power Connector | | - -## Datasheet - -### 产品规格 - -| Component | 技术规范 | -| --------------- | ----------------------------------------------------------------- | -| 飞控 | VOXL2 | -| Take-off Weight | 275g (172g without battery) | -| Diagonal Size | 211mm | -| Flight Time | > 30 minutes | -| 电机 | 1504 | -| Propellers | 120mm | -| 框架 | 3mm Carbon Fiber | -| ESC | ModalAI VOXL 4-in-1 ESC V2 | -| GPS | UBlox M10 | -| RC Receiver | 915mhz ELRS | -| Power Module | ModalAI Power Module v3 - 5V/6A | -| Battery | Sony VTC6 3000mah 2S, or any 2S 18650 battery with XT30 connector | -| 高度 | 83mm | -| Width | 187mm (Props folded) | -| Length | 142mm (Props folded) | - -### Hardware Wiring Diagram - -![Hardware Overview](../../assets/hardware/complete_vehicles/modalai_starling/d0005_compute_wiring_d.jpg) - -## Tutorials - -### ELRS Set Up - -Binding your ELRS (ExpressLRS) receiver to a transmitter is a crucial step in preparing your VOXL 2 based PX4 Autonomy Developer Kit by ModalAI for flight. -This process ensures a secure and responsive connection between your drone and its control system. - -Follow this guide to bind your ELRS receiver to your transmitter. - -#### Setting up the Receiver - -1. **Power On the Receiver**: Once your drone is powered on, you'll notice the ELRS receiver's blue LED flashing. - This is an indication that the receiver is on but has not yet established a connection with a transmitter. - - ![Starling Receiver](../../assets/hardware/complete_vehicles/modalai_starling/starling-photo.png) - -2. **Enter Binding Mode**: To initiate binding, open a terminal and execute the `adb shell` and `voxl-elrs -bind` commands. - You'll observe the receiver's LED switch to a flashing in a heartbeat pattern, signaling that it is now in binding mode. - - ![Boot Screenshot](../../assets/hardware/complete_vehicles/modalai_starling/screenshot-boot.png) - -#### Setting up the Transmitter - -1. **Access the Menu**: On your Commando 8 radio transmitter included in the kit, press the left mode button to open the menu system. - - ![Press Menu on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-1.png) - -2. **Navigate to ExpressLRS**: Use the right button to select the first menu entry, which should be "ExpressLRS." - -3. **Find the Bind Option**: With the "ExpressLRS" option selected, scroll down to the bottom of the menu to locate the "Bind" section. This can be done by pressing the right button downwards until you reach the "Bind" option. - - ![Press Binding on RC](../../assets/hardware/complete_vehicles/modalai_starling/radio-2.png) - -4. **Initiate Binding**: Select "Bind" to put the transmitter into binding mode. You will know the process has been successful when the transmitter emits a beep, indicating a successful bind. - -#### Completing the Binding Process - -Once the transmitter is set to bind mode, the ELRS receiver on the drone will change its LED from flashing to a steady light, signifying a successful connection between the receiver and the transmitter. - -- **Power Cycle**: After the binding process is complete, it's essential to power cycle the VOXL 2 before attempting to fly. - This means turning off the VOXL 2 and then turning it back on. - This step ensures that all settings are properly applied and that the system recognizes the newly established connection. - -You should now have a successfully bound ELRS receiver to your transmitter, ready for use with the PX4 Autonomy Kit by ModalAI. -A secure connection is vital for the reliable operation of your drone, so always confirm the binding status before flight. - -### 视频 - -- [VOXL 2 Starling Hardware Overview](https://youtu.be/M9OiMpbEYOg) -- [VOXL 2 Starling First Flight Tutorial](https://youtu.be/Cpbbye3Z6co) -- [VOXL 2 Starling ELRS Set Up](https://youtu.be/7OwGS-kcFVg) +[ModalAI Starling 2 Max](https://www.modalai.com/products/starling-2-max) diff --git a/docs/zh/complete_vehicles_mc/px4_vision_kit.md b/docs/zh/complete_vehicles_mc/px4_vision_kit.md index 4a1fb66457..422ed34af2 100644 --- a/docs/zh/complete_vehicles_mc/px4_vision_kit.md +++ b/docs/zh/complete_vehicles_mc/px4_vision_kit.md @@ -42,17 +42,17 @@ This kit is still highly recommended for developing and testing vision solutions ## Warnings and Notifications 1. The kit is intended for computer vision projects that use a forward-facing camera (it does not have downward or rear-facing depth cameras). - Consequently it can't be used (without modification) for testing features that require a downward-facing camera. + Consequently it can't be used (without modification) for testing features that require a downward-facing camera. 2. Obstacle avoidance in missions can only be tested when GPS is available (missions use GPS coordinates). - Collision prevention can be tested in position mode provided there is a good position lock from either GPS or optical flow. + Collision prevention can be tested in position mode provided there is a good position lock from either GPS or optical flow. 3. The port labeled `USB1` may jam the GPS if used with a _USB3_ peripheral (disable GPS-dependent functionality including missions). - This is why the boot image is supplied on a _USB2.0_ memory stick. + This is why the boot image is supplied on a _USB2.0_ memory stick. 4. PX4 Vision v1 with ECN 010 or above (carrier board RC05 and up), the _UP Core_ can be powered by either the DC plug or with battery. - ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) + ![RC Number](../../assets/hardware/px4_vision_devkit/rc.png) ![ECN Number](../../assets/hardware/px4_vision_devkit/serial_number_update.jpg) 5. All PX4 Vision v1.5 _UP Core_ can be powered by either the DC plug or with battery. @@ -132,37 +132,37 @@ In addition, users will need ground station hardware/software: ## First-time Setup 1. Attach a [compatible RC receiver](../getting_started/rc_transmitter_receiver.md#connecting-receivers) to the vehicle (not supplied with kit): - - Remove/unscrew the top plate (where the battery goes) using an H2.0 hex key tool. - - [Connect the receiver to the flight controller](../assembly/quick_start_pixhawk4.md#radio-control). - - Re-attach the top plate. - - Mount the RC receiver on the _UP Core_ carrier board plate at the back of the vehicle (use zipties or double-sided tape). - - Ensure the antennas are clear of any obstructions and electrically isolated from the frame (e.g. secure them under the carrier board or to the vehicle arms or legs). + - Remove/unscrew the top plate (where the battery goes) using an H2.0 hex key tool. + - [Connect the receiver to the flight controller](../assembly/quick_start_pixhawk4.md#radio-control). + - Re-attach the top plate. + - Mount the RC receiver on the _UP Core_ carrier board plate at the back of the vehicle (use zipties or double-sided tape). + - Ensure the antennas are clear of any obstructions and electrically isolated from the frame (e.g. secure them under the carrier board or to the vehicle arms or legs). 2. [Bind](../getting_started/rc_transmitter_receiver.md#binding) the RC ground and air units (if not already done). - The binding procedure depends on the specific radio system used (read the receiver manual). + The binding procedure depends on the specific radio system used (read the receiver manual). 3. Raise the GPS mast to the vertical position and screw the cover onto the holder on the base plate. (Not required for v1.5) - ![Raise GPS mast](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) + ![Raise GPS mast](../../assets/hardware/px4_vision_devkit/raise_gps_mast.jpg) 4. Insert the pre-imaged USB2.0 stick from the kit into the _UP Core_ port labeled `USB1` (highlighted below). - ![UP Core: USB1 Port ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) + ![UP Core: USB1 Port ](../../assets/hardware/px4_vision_devkit/upcore_port_usb1.png) 5. Power the vehicle with a fully charged battery. - ::: info - Ensure propellers are removed before connecting the battery. + ::: info + Ensure propellers are removed before connecting the battery. ::: 6. Connect the ground station to the vehicle WiFi network (after a few seconds) using the following default credentials: - - **SSID:** pixhawk4 - - **Password:** pixhawk4 + - **SSID:** pixhawk4 + - **Password:** pixhawk4 - :::tip - WiFi network SSID, password, and other credentials may be changed after connecting (if desired), by using a web browser to open the URL: `http://192.168.4.1`. - The baud rate must not be changed from 921600. + :::tip + WiFi network SSID, password, and other credentials may be changed after connecting (if desired), by using a web browser to open the URL: `http://192.168.4.1`. + The baud rate must not be changed from 921600. ::: @@ -170,39 +170,39 @@ In addition, users will need ground station hardware/software: 8. [Configure/calibrate](../config/index.md) the vehicle: - ::: info - The vehicle should arrive pre-calibrated (e.g. with firmware, airframe, battery, and sensors all setup). - You will however need to calibrate the radio system (that you just connected) and it is often worth re-doing the compass calibration. + ::: info + The vehicle should arrive pre-calibrated (e.g. with firmware, airframe, battery, and sensors all setup). + You will however need to calibrate the radio system (that you just connected) and it is often worth re-doing the compass calibration. ::: - - [Calibrate the Radio System](../config/radio.md) - - [Calibrate the Compass](../config/compass.md) + - [Calibrate the Radio System](../config/radio.md) + - [Calibrate the Compass](../config/compass.md) 9. (Optional) Configure a [Flight Mode selector switch](../config/flight_mode.md) on the remote controller. - ::: info - Modes can also be changed using _QGroundControl_ + ::: info + Modes can also be changed using _QGroundControl_ ::: - We recommend RC controller switches are define for: + We recommend RC controller switches are define for: - - [Position Mode](../flight_modes_mc/position.md) - a safe manual flight mode that can be used to test collision prevention. - - [Mission Mode](../flight_modes_mc/mission.md) - run missions and test obstacle avoidance. - - [Return Mode](../flight_modes_mc/return.md) - return vehicle safely to its launch point and land. + - [Position Mode](../flight_modes_mc/position.md) - a safe manual flight mode that can be used to test collision prevention. + - [Mission Mode](../flight_modes_mc/mission.md) - run missions and test obstacle avoidance. + - [Return Mode](../flight_modes_mc/return.md) - return vehicle safely to its launch point and land. 10. Attach the propellers with the rotations as shown: - ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) + ![Motor Order Diagram](../../assets/hardware/px4_vision_devkit/motor_order_diagram.png) - - The propellers directions can be determined from the labels: _6045_ (normal, counter-clockwise) and _6045_**R** (reversed, clockwise). + - The propellers directions can be determined from the labels: _6045_ (normal, counter-clockwise) and _6045_**R** (reversed, clockwise). - ![Propeller identification](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) + ![Propeller identification](../../assets/hardware/px4_vision_devkit/propeller_directions.jpg) - - Screw down firmly using the provided propellor nuts: + - Screw down firmly using the provided propellor nuts: - ![Propeller nuts](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) + ![Propeller nuts](../../assets/hardware/px4_vision_devkit/propeller_nuts.png) ## Fly the Drone with Avoidance @@ -212,30 +212,30 @@ When the vehicle setup described above is complete: 2. Wait until the boot sequence completes and the avoidance system has started (the vehicle will reject arming commands during boot). - :::tip - The boot/startup process takes around 1 minute from the supplied USB stick (or 30 seconds from [internal memory](#install_image_mission_computer)). + :::tip + The boot/startup process takes around 1 minute from the supplied USB stick (or 30 seconds from [internal memory](#install_image_mission_computer)). ::: 3. Check that the avoidance system has started properly: - - The _QGroundControl_ notification log displays the message: **Avoidance system connected**. + - The _QGroundControl_ notification log displays the message: **Avoidance system connected**. - ![QGC Log showing avoidance system has started](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) + ![QGC Log showing avoidance system has started](../../assets/hardware/px4_vision_devkit/qgc_console_vision_system_started.jpg) - - A red laser is visible on the front of the _Structure Core_ camera. + - A red laser is visible on the front of the _Structure Core_ camera. 4. Wait for the GPS LED to turn green. - This means that the vehicle has a GPS fix and is ready to fly! + This means that the vehicle has a GPS fix and is ready to fly! 5. Connect the ground station to the vehicle WiFi network. 6. Find a safe outdoor location for flying, ideally with a tree or some other convenient obstacle for testing PX4 Vision. 7. To test [collision prevention](../computer_vision/collision_prevention.md), enable [Position Mode](../flight_modes_mc/position.md) and fly manually towards an obstacle. - The vehicle should slow down and then stop within 6m of the obstacle (the distance can be [changed](../advanced_config/parameters.md) using the [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST) parameter). + The vehicle should slow down and then stop within 6m of the obstacle (the distance can be [changed](../advanced_config/parameters.md) using the [CP_DIST](../advanced_config/parameter_reference.md#CP_DIST) parameter). 8. To test obstacle avoidance, create a mission where the path is blocked by an obstacle. - Then switch to [Mission Mode](../flight_modes_mc/mission.md) to run the mission, and observe the vehicle moving around the obstacle and then returning to the planned course. + Then switch to [Mission Mode](../flight_modes_mc/mission.md) to run the mission, and observe the vehicle moving around the obstacle and then returning to the planned course. ## Development using the Kit @@ -280,22 +280,22 @@ To flash the USB image to the _UP Core_: 2. [Login to the companion computer](#login_mission_computer) (as described above). 3. Open a terminal and run the following command to copy the image onto internal memory (eMMC). - The terminal will prompt for a number of responses during the flashing process. + The terminal will prompt for a number of responses during the flashing process. - ```sh - cd ~/catkin_ws/src/px4vision_ros/tools - sudo ./flash_emmc.sh - ``` + ```sh + cd ~/catkin_ws/src/px4vision_ros/tools + sudo ./flash_emmc.sh + ``` - ::: info - All information saved in the _UP Core_ computer will be removed when executing this script. + ::: info + All information saved in the _UP Core_ computer will be removed when executing this script. ::: 4. Pull out the USB stick. 5. Restart the vehicle. - The _UP Core_ computer will now boot from internal memory (eMMC). + The _UP Core_ computer will now boot from internal memory (eMMC). ### Boot the Companion Computer @@ -319,23 +319,23 @@ To login to the companion computer: 1. Connect a keyboard and mouse to the _UP Core_ via port `USB2`: - ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) + ![UP Core: USB2](../../assets/hardware/px4_vision_devkit/upcore_port_usb2.png) - - Use the USB-JST cable from the kit to get a USB A connector + - Use the USB-JST cable from the kit to get a USB A connector - ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) + ![USB to JST cable](../../assets/hardware/px4_vision_devkit/usb_jst_cable.jpg) - - A USB hub can be attached to the cable if the keyboard and mouse have separate connectors. + - A USB hub can be attached to the cable if the keyboard and mouse have separate connectors. 2. Connect a monitor to the _UP Core_ HDMI port. - ![UP Core: HDMI port](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) + ![UP Core: HDMI port](../../assets/hardware/px4_vision_devkit/upcore_port_hdmi.png) - The Ubuntu login screen should then appear on the monitor. + The Ubuntu login screen should then appear on the monitor. 3. Login to the _UP Core_ using the credentials: - - **Username:** px4vision - - **Password:** px4vision + - **Username:** px4vision + - **Password:** px4vision ### Developing/Extending PX4 Avoidance @@ -350,39 +350,39 @@ To integrate a different planner, this needs to be disabled. 1. Disable the avoidance process using the following command: - ```sh - systemctl stop avoidance.service - ``` + ```sh + systemctl stop avoidance.service + ``` - You can simply reboot the machine to restart the service. + You can simply reboot the machine to restart the service. - Other useful commands are: + Other useful commands are: - ```sh - # restart service - systemctl start avoidance.service + ```sh + # restart service + systemctl start avoidance.service - # disable service (stop service and do not restart after boot) - systemctl disable avoidance.service + # disable service (stop service and do not restart after boot) + systemctl disable avoidance.service - # enable service (start service and enable restart after boot) - systemctl enable avoidance.service - ``` + # enable service (start service and enable restart after boot) + systemctl enable avoidance.service + ``` 2. The source code of the obstacle avoidance package can be found in https://github.com/PX4/PX4-Avoidance which is located in `~/catkin_ws/src/avoidance`. 3. Make changes to the code! To get the latest code of avoidance pull the code from the avoidance repo: - ```sh - git pull origin - git checkout origin/master - ``` + ```sh + git pull origin + git checkout origin/master + ``` 4. Build the package - ```sh - catkin build local_planner - ``` + ```sh + catkin build local_planner + ``` The ROS workspace is placed in `~/catkin_ws`. For reference on developing in ROS and using the catkin workspace, see the [ROS catkin tutorials](https://wiki.ros.org/catkin/Tutorials). diff --git a/docs/zh/complete_vehicles_rover/aion_r1.md b/docs/zh/complete_vehicles_rover/aion_r1.md index 0e4f89b899..e6bc0298cb 100644 --- a/docs/zh/complete_vehicles_rover/aion_r1.md +++ b/docs/zh/complete_vehicles_rover/aion_r1.md @@ -54,15 +54,15 @@ Use _QGroundControl_ for rover configuration: First configure the serial connection: 1. Navigate to the [Parameters](../advanced_config/parameters.md) section in QGroundControl. - - Set the [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) parameter to the serial port to which the RoboClaw is connected (such as `GPS2`). - - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) specifies the number of encoder counts required for one wheel revolution. - This value should be left at `1200` for the tested `RoboClaw 2x15A Motor Controller`. - Adjust the value based on your specific encoder and wheel setup. - - RoboClaw motor controllers must be assigned a unique address on the bus. - The default address is 128 and you should not need to change this (if you do, update the PX4 parameter [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) to match). + - Set the [RBCLW_SER_CFG](../advanced_config/parameter_reference.md#RBCLW_SER_CFG) parameter to the serial port to which the RoboClaw is connected (such as `GPS2`). + - [RBCLW_COUNTS_REV](../advanced_config/parameter_reference.md#RBCLW_COUNTS_REV) specifies the number of encoder counts required for one wheel revolution. + This value should be left at `1200` for the tested `RoboClaw 2x15A Motor Controller`. + Adjust the value based on your specific encoder and wheel setup. + - RoboClaw motor controllers must be assigned a unique address on the bus. + The default address is 128 and you should not need to change this (if you do, update the PX4 parameter [RBCLW_ADDRESS](../advanced_config/parameter_reference.md#RBCLW_ADDRESS) to match). - ::: info - PX4 does not support multiple RoboClaw motor controllers in the same vehicle — each controller needs a unique address on the bus, and there is only one parameter for setting the address in PX4 (`RBCLW_ADDRESS`). + ::: info + PX4 does not support multiple RoboClaw motor controllers in the same vehicle — each controller needs a unique address on the bus, and there is only one parameter for setting the address in PX4 (`RBCLW_ADDRESS`). ::: @@ -71,12 +71,12 @@ Then configure the actuator configuration: 1. Navigate to [Actuators Configuration & Testing](../config/actuators.md) in QGroundControl. 2. Select the RoboClaw driver from the list of _Actuator Outputs_. - For the channel assignments, disarm, minimum, and maximum values, please refer to the image below. + For the channel assignments, disarm, minimum, and maximum values, please refer to the image below. - ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) + ![RoboClaw QGC](../../assets/airframes/rover/aion_r1/roboclaw_actuator_config_qgc.png) - For systems with more than two motors, it is possible to assign the same function to several motors. - The reason for the unusual values, can be found in the [RoboClaw User Manual](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) under `Compatibility Commands` for `Packet Serial`: + For systems with more than two motors, it is possible to assign the same function to several motors. + The reason for the unusual values, can be found in the [RoboClaw User Manual](https://downloads.basicmicro.com/docs/roboclaw_user_manual.pdf) under `Compatibility Commands` for `Packet Serial`: ```plain Drive motor forward. Valid data range is 0 - 127. A value of 127 = full speed forward, 64 = diff --git a/docs/zh/complete_vehicles_vtol/index.md b/docs/zh/complete_vehicles_vtol/index.md index 9f32760d55..d3dc22f104 100644 --- a/docs/zh/complete_vehicles_vtol/index.md +++ b/docs/zh/complete_vehicles_vtol/index.md @@ -30,7 +30,7 @@ These may or may not be updatable to run "vanilla" PX4. - [WingtraOne Tailsitter VTOL](https://px4.io/project/wingtraone-tailsitter-vtol/) - [Flightwave Edge](https://px4.io/project/flywave-edge/) -## See Also +## 另见 - [Complete Vehicles (Fixed-Wing)](../complete_vehicles_fw/index.md) - [Complete Vehicles (MC)](../complete_vehicles_mc/index.md) diff --git a/docs/zh/computer_vision/collision_prevention.md b/docs/zh/computer_vision/collision_prevention.md index f2eb057d4c..53c5572090 100644 --- a/docs/zh/computer_vision/collision_prevention.md +++ b/docs/zh/computer_vision/collision_prevention.md @@ -203,85 +203,85 @@ The Lua script works by extracting the `obstacle_distance_fused` data at each ti 2. Configure PX4 to publish obstacle distance data (so that it is available to PlotJuggler): - Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: + Add the [`obstacle_distance_fused`](../msg_docs/ObstacleDistance.md) UORB topic to your [`dds_topics.yaml`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) so that it is published by PX4: - ```sh - - topic: /fmu/out/obstacle_distance_fused - type: px4_msgs::msg::ObstacleDistance - ``` + ```sh + - topic: /fmu/out/obstacle_distance_fused + type: px4_msgs::msg::ObstacleDistance + ``` - For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. + For more information see [DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml) in [uXRCE-DDS](../middleware/uxrce_dds.md) (PX4-ROS 2/DDS Bridge)\_. 3. Open PlotJuggler and navigate to the **Tools > Reactive Script Editor** section. - In the **Script Editor** tab, add following scripts in the appropriate sections: + In the **Script Editor** tab, add following scripts in the appropriate sections: - - **Global code, executed once:** + - **Global code, executed once:** - ```lua - obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") - obs_dist_min = Timeseries.new("obstacle_distance_minimum") - ``` + ```lua + obs_dist_fused_xy = ScatterXY.new("obstacle_distance_fused_xy") + obs_dist_min = Timeseries.new("obstacle_distance_minimum") + ``` - - **function(tracker_time)** + - **function(tracker_time)** - ```lua - obs_dist_fused_xy:clear() + ```lua + obs_dist_fused_xy:clear() - i = 0 - angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") - increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") - min_dist = 65535 + i = 0 + angle_offset = TimeseriesView.find("/fmu/out/obstacle_distance_fused/angle_offset") + increment = TimeseriesView.find("/fmu/out/obstacle_distance_fused/increment") + min_dist = 65535 - -- Cache increment and angle_offset values at tracker_time to avoid repeated calls - local angle_offset_value = angle_offset:atTime(tracker_time) - local increment_value = increment:atTime(tracker_time) + -- Cache increment and angle_offset values at tracker_time to avoid repeated calls + local angle_offset_value = angle_offset:atTime(tracker_time) + local increment_value = increment:atTime(tracker_time) - if increment_value == nil or increment_value <= 0 then - print("Invalid increment value: " .. tostring(increment_value)) - return - end + if increment_value == nil or increment_value <= 0 then + print("Invalid increment value: " .. tostring(increment_value)) + return + end - local max_steps = math.floor(360 / increment_value) + local max_steps = math.floor(360 / increment_value) - while i < max_steps do - local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) - local distance = TimeseriesView.find(str) - if distance == nil then - print("No distance data for: " .. str) - break - end + while i < max_steps do + local str = string.format("/fmu/out/obstacle_distance_fused/distances[%d]", i) + local distance = TimeseriesView.find(str) + if distance == nil then + print("No distance data for: " .. str) + break + end - local dist = distance:atTime(tracker_time) - if dist ~= nil and dist < 65535 then - -- Calculate angle and Cartesian coordinates - local angle = angle_offset_value + i * increment_value - local y = dist * math.cos(math.rad(angle)) - local x = dist * math.sin(math.rad(angle)) + local dist = distance:atTime(tracker_time) + if dist ~= nil and dist < 65535 then + -- Calculate angle and Cartesian coordinates + local angle = angle_offset_value + i * increment_value + local y = dist * math.cos(math.rad(angle)) + local x = dist * math.sin(math.rad(angle)) - obs_dist_fused_xy:push_back(x, y) + obs_dist_fused_xy:push_back(x, y) - -- Update minimum distance - if dist < min_dist then - min_dist = dist - end - end + -- Update minimum distance + if dist < min_dist then + min_dist = dist + end + end - i = i + 1 - end + i = i + 1 + end - -- Push minimum distance once after the loop - if min_dist < 65535 then - obs_dist_min:push_back(tracker_time, min_dist) - else - print("No valid minimum distance found") - end - ``` + -- Push minimum distance once after the loop + if min_dist < 65535 then + obs_dist_min:push_back(tracker_time, min_dist) + else + print("No valid minimum distance found") + end + ``` 4. Enter a name for the script on the top right, and press **Save**. - Once saved, the script should appear in the _Active Scripts_ section. + Once saved, the script should appear in the _Active Scripts_ section. 5. Start streaming the data using the approach described in [Plotting uORB Topic Data in Real Time using PlotJuggler](../debug/plotting_realtime_uorb_data.md). - You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. + You should see the `obstacle_distance_fused_xy` and `obstacle_distance_minimum` timeseries on the left. Note that you have to press **Save** again to re-enable the scripts after loading a new log file or otherwise clearing data. diff --git a/docs/zh/computer_vision/visual_inertial_odometry.md b/docs/zh/computer_vision/visual_inertial_odometry.md index 3e6c5f0237..0c91c383be 100644 --- a/docs/zh/computer_vision/visual_inertial_odometry.md +++ b/docs/zh/computer_vision/visual_inertial_odometry.md @@ -125,15 +125,15 @@ Perform the following checks to verify that VIO is working properly _before_ you 可以通过更改参数来进一步调整该值,以找到在动态变化中最低的EKF更新值。 1. Put the vehicle on the ground and start streaming `ODOMETRY` feedback (as above). - 油门杆推到最低并解锁。 + 油门杆推到最低并解锁。 - 此时,设置为位置控制模式。 - 如果切换成功,飞控会闪绿灯。 - 绿灯代表:你的外部位置信息已经注入到飞控中,并且位置控制模式已经切换成功。 + 此时,设置为位置控制模式。 + 如果切换成功,飞控会闪绿灯。 + 绿灯代表:你的外部位置信息已经注入到飞控中,并且位置控制模式已经切换成功。 2. 油门杆放到中间位置(死区),以便无人机保持飞行高度。 - 提高操控杆会增加参考高度,降低操控杆会降低参考高度。 - Similarly, the other stick will change the position over the ground. + 提高操控杆会增加参考高度,降低操控杆会降低参考高度。 + Similarly, the other stick will change the position over the ground. 3. Increase the value of the throttle stick and the vehicle will take off. Move it back to the middle immediately afterwards. diff --git a/docs/zh/concept/flight_modes.md b/docs/zh/concept/flight_modes.md index 02213e41b4..66a4e79841 100644 --- a/docs/zh/concept/flight_modes.md +++ b/docs/zh/concept/flight_modes.md @@ -95,9 +95,9 @@ mode_req_other # other requirements, not covered above (for external If the condition of restriction is not met: -- arming is not allowed, while the mode is selected -- when already armed, the mode cannot be selected -- when armed and the mode is selected, the relevant failsafe is triggered (e.g. RC loss for the manual control requirement). +- 在选定模式时不允许进行解锁操作 +- 当已处于武装状态时,该模式无法被选择。 +- 当载具已解锁且该模式被选中时,相关的故障保护机制会被触发(例如,针对手动控制需求的遥控器信号丢失故障保护)。 Check [Safety (Failsafe) Configuration](../config/safety.md) for how to configure failsafe behaviour. This is the corresponding flow diagram for the manual control flag (`mode_req_manual_control`): diff --git a/docs/zh/concept/flight_tasks.md b/docs/zh/concept/flight_tasks.md index 7e25faa449..a2aeecea79 100644 --- a/docs/zh/concept/flight_tasks.md +++ b/docs/zh/concept/flight_tasks.md @@ -38,24 +38,24 @@ The instructions below might be used to create a task named _MyTask_: - Update the copyright to the current year - ```cmake - ############################################################################ - # - # Copyright (c) 2021 PX4 Development Team. All rights reserved. - # - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2021 PX4 Development Team. All rights reserved. + # + ``` - Modify the code to reflect the new task - e.g. replace `FlightTaskOrbit` with `FlightTaskMyTask`. - The code will look something like this: + The code will look something like this: - ```cmake - px4_add_library(FlightTaskMyTask - FlightTaskMyTask.cpp - ) + ```cmake + px4_add_library(FlightTaskMyTask + FlightTaskMyTask.cpp + ) - target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) - target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - ``` + target_link_libraries(FlightTaskMyTask PUBLIC FlightTask) + target_include_directories(FlightTaskMyTask PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + ``` 4. Update the header file (in this case **FlightTaskMyTask.hpp**): Most tasks reimplement the virtual methods `activate()` and `update()`, and in this example we also have a private variable. @@ -141,35 +141,35 @@ The instructions below might be used to create a task named _MyTask_: - 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 - ... - * @value 0 Direct velocity - * @value 3 Smoothed velocity - * @value 4 Acceleration based - * @value 5 My task - * @group Multicopter Position Control - */ - PARAM_DEFINE_INT32(MPC_POS_MODE, 5); - ``` + ```c + ... + * @value 0 Direct velocity + * @value 3 Smoothed velocity + * @value 4 Acceleration based + * @value 5 My task + * @group Multicopter Position Control + */ + PARAM_DEFINE_INT32(MPC_POS_MODE, 5); + ``` - Add a case for your new option in the switch for the parameter [FlightModeManager.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/flight_mode_manager/FlightModeManager.cpp#L266-L285) to enable the task when `_param_mpc_pos_mode` has the right value. - ```cpp - ... - // manual position control - ... - switch (_param_mpc_pos_mode.get()) { - ... - case 3: - error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); - break; - case 5: // Add case for new task: MyTask - error = switchTask(FlightTaskIndex::MyTask); - break; - case 4: - .... - ... - ``` + ```cpp + ... + // manual position control + ... + switch (_param_mpc_pos_mode.get()) { + ... + case 3: + error = switchTask(FlightTaskIndex::ManualPositionSmoothVel); + break; + case 5: // Add case for new task: MyTask + error = switchTask(FlightTaskIndex::MyTask); + break; + case 4: + .... + ... + ``` ## Test New Flight Task diff --git a/docs/zh/concept/system_startup.md b/docs/zh/concept/system_startup.md index 381ecdeeb9..28456ce738 100644 --- a/docs/zh/concept/system_startup.md +++ b/docs/zh/concept/system_startup.md @@ -1,7 +1,7 @@ # 系统启动 PX4 系统的启动由 shell 脚本文件控制。 -On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/MacOS). +On NuttX they reside in the [ROMFS/px4fmu_common/init.d](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d) folder - some of these are also used on Posix (Linux/macOS). The scripts that are only used on Posix are located in [ROMFS/px4fmu_common/init.d-posix](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d-posix). All files starting with a number and underscore (e.g. `10000_airplane`) are predefined airframe configurations. @@ -13,9 +13,9 @@ The first executed file is the [init.d/rcS](https://github.com/PX4/PX4-Autopilot 根据 PX4 运行的操作系统将本文后续内容分成了如下各小节。 -## Posix (Linux/MacOS) +## POSIX (Linux/macOS) -在 Posix 操作系统上,系统的 shell 将会作为脚本文件的解释器(例如, 在 Ubuntu 中 /bin/sh 与 Dash 建立了符号链接)。 +On POSIX, the system shell is used as script interpreter (e.g. /bin/sh, being symlinked to dash on Ubuntu). 为了使 PX4 可以在 Posix 中正常运行,需要做到以下几点: - PX4 的各个模块需要看起来像系统的单个可执行文件。 @@ -59,7 +59,7 @@ cd /build/px4_sitl_default/bin ### Dynamic Modules 通常,所有模块都被编入一个 PX4 可执行程序。 -However, on Posix, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. +However, on POSIX, there's the option of compiling a module into a separate file, which can be loaded into PX4 using the `dyn` command. ```sh dyn ./test.px4mod @@ -95,6 +95,8 @@ The whole boot can be replaced by creating a file `/etc/rc.txt` on the microSD c The best way to customize the system startup is to introduce a [new frame configuration](../dev_airframes/adding_a_new_frame.md). 机架配置文件可以在固件中,也可以在SD卡上。 +#### Dynamic Customization + If you only need to "tweak" the existing configuration, such as starting one more application or setting the value of a few parameters, you can specify these by creating two files in the `/etc/` directory of the SD Card: - [/etc/config.txt](#customizing-the-configuration-config-txt): modify parameter values @@ -111,7 +113,7 @@ The system boot files are UNIX FILES which require UNIX LINE ENDINGS. These files are referenced in PX4 code as `/fs/microsd/etc/config.txt` and `/fs/microsd/etc/extras.txt`, where the root folder of the microsd card is identified by the path `/fs/microsd`. ::: -#### 自定义配置(config.txt) +##### 自定义配置(config.txt) The `config.txt` file can be used to modify parameters. It is loaded after the main system has been configured and _before_ it is booted. @@ -123,7 +125,7 @@ param set-default PWM_MAIN_DIS3 1000 param set-default PWM_MAIN_MIN3 1120 ``` -#### 启动附加应用程序 (extras.txt) +##### 启动附加应用程序 (extras.txt) The `extras.txt` can be used to start additional applications after the main system boot. 通常,额外启动的将是有效载荷控制器或类似的可选自定义组件。 @@ -150,3 +152,37 @@ Calling an unknown command in system boot files may result in boot failure. mandatory_app start # Will abort boot if mandatory_app is unknown or fails ``` + +#### Additional Init-File Customization + +In rare cases where the desired setup cannot be achieved through frame configuration or dynamic customization, you can add a script that will be compiled into the binary for a particular `make` target build variant. + +:::warning +In almost all cases, you should use a frame configuration. +This method should only be used for edge-cases such as customizing `cannode` based boards. +::: + +步骤如下: + +- Add a new init script in `boards///init` that will run during board startup. + 例如: + + ```sh + # File: boards///init/rc.additional + param set-default + ``` + +- Add a new board variant in `boards///.px4board` that includes the additional script. + 例如: + + ```sh + # File: boards///var.px4board + CONFIG_BOARD_ADDITIONAL_INIT="rc.additional" + ``` + +- Compile the firmware with your new variant by appending the variant name to the compile target. + 例如: + + ```sh + make _var + ``` diff --git a/docs/zh/config/_autotune.md b/docs/zh/config/_autotune.md index 6495d5ae91..c9e2b5bfee 100644 --- a/docs/zh/config/_autotune.md +++ b/docs/zh/config/_autotune.md @@ -43,13 +43,13 @@ To make sure the vehicle is stable enough for auto-tuning: 2. Take off and
hover at 1m above ground in [Altitude mode](../flight_modes_mc/altitude.md) or [Stabilized mode](../flight_modes_mc/manual_stabilized.md)
fly at cruise speed in [Position mode](../flight_modes_fw/position.md) or [Altitude mode](../flight_modes_fw/altitude.md)
. 3. Use the RC transmitter roll stick to perform the following maneuver, tilting the vehicle just a few degrees: _roll left > roll right > center_ (The whole maneuver should take about 3 seconds). - The vehicle should stabilise itself within 2 oscillations. + The vehicle should stabilise itself within 2 oscillations. 4. Repeat the maneuver, tilting with larger amplitudes at each attempt. - If the vehicle can stabilise itself within 2 oscillations at ~20 degrees move to the next step. + If the vehicle can stabilise itself within 2 oscillations at ~20 degrees move to the next step. 5. Repeat the same maneuvers but on the pitch axis. - As above, start with small angles and confirm that the vehicle can stabilise itself within 2 oscillations before increasing the tilt. + As above, start with small angles and confirm that the vehicle can stabilise itself within 2 oscillations before increasing the tilt. If the drone can stabilize itself within 2 oscillations it is ready for the [auto-tuning procedure](#auto-tuning-procedure). @@ -72,41 +72,55 @@ The test steps are: 1. Perform the [pre-tuning test](#pre-tuning-test). 2. Takeoff using RC control
in [Altitude mode](../flight_modes_mc/altitude.md). - Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
- Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). - This will guide the plane to fly in circle at constant altitude and speed.
+ Hover the vehicle at a safe distance and at a few meters above ground (between 4 and 20m).
+ Once flying at cruise speed, activate [Hold mode](../flight_modes_fw/hold.md). + This will guide the plane to fly in circle at constant altitude and speed.
3. Enable autotune. -
-

TIP

+
+

TIP

- If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. + If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position. -
+
- 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: + 1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**: - ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) + ![Tuning Setup > Autotune Enabled](../../assets/qgc/setup/autotune/autotune.png) - 2. Select either the _Rate Controller_ or _Attitude Controller_ tabs. + 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). + 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. - -4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. - The progress is shown in the progress bar, next to the _Autotune_ button. + 4. Read the warning popup and click on **OK** to start tuning.
+4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. + The progress is shown in the progress bar, next to the _Autotune_ button. + +
+ +4. The drone will first start to perform quick roll motions followed by pitch and yaw motions. When [`FW_AT_SYSID_TYPE`](../advanced_config/parameter_reference.md#FW_AT_SYSID_TYPE) is set to linear/logarithmic sine sweep (recommended), the max rates reached during the maneuvers are 75% of the maximum configured roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. The progress is shown in the progress bar, next to the _Autotune_ button. + +
+
+ 5. Manually land and disarm to apply the new tuning parameters. - Takeoff carefully and manually test that the vehicle is stable. + Takeoff carefully and manually test that the vehicle is stable.
5. The tuning will be immediately/automatically be applied and tested in flight (by default). - PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + PX4 will then run a 4 second test and revert the new tuning if a problem is detected. + +The figure below shows how steps 4 and 5 might look in flight on the pitch axis. +The pitch rate gradually increases up until it reaches the target. +This amplitude is then held while the signal frequency is increased. +You can then see how the tuned system is able to follow the setpoint in the test signal. + +
@@ -174,9 +188,20 @@ Fast oscillations (more than 1 oscillation per second): this is because the gain ### The auto-tuning sequence fails +
+ If the drone was not moving enough during auto-tuning, the system identification algorithm might have issues to find the correct coefficients. -Increase the
[MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP)
[FW_AT_SYSID_AMP](../advanced_config/parameter_reference.md#FW_AT_SYSID_AMP)
parameter by steps of 1 and trigger the auto-tune again. +Increase the [MC_AT_SYSID_AMP](../advanced_config/parameter_reference.md#MC_AT_SYSID_AMP) parameter by steps of 1 and trigger the auto-tune again. + +
+
+ +By default, the autotune maneuvers ensure that a sufficient angular rate is reached for system identification, corresponding to 75% of the configured maximum roll (`FW_R_RMAX`), pitch (`FW_P_RMAX_NEG`, `FW_P_RMAX_POS`) and yaw (`FW_Y_RMAX`) rates. + +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. + +
### The drone oscillates after auto-tuning diff --git a/docs/zh/config/actuators.md b/docs/zh/config/actuators.md index 298f878b1b..716d974043 100644 --- a/docs/zh/config/actuators.md +++ b/docs/zh/config/actuators.md @@ -161,6 +161,7 @@ The fields are: [Generally you should use the default actuator value](#actuator-roll-pitch-and-yaw-scaling). - `Trim`: An offset added to the actuator so that it is centered without input. This might be determined by trial and error. + Prefer using the improved `PWM_CENT` instead: [PWM control surfaces](actuators.md#pwm-control-surfaces-that-move-both-directions-about-a-neutral-point). - (Advanced) `Slew Rate`: Limits the minimum time in which the motor/servo signal is allowed to pass through its full output range, in seconds. - The setting limits the rate of change of an actuator (if not specified then no rate limit is applied). It is intended for actuators that may be damaged or cause flight disturbance if they move too fast — such as the tilting actuators on a tiltrotor VTOL vehicle, or fast moving flaps, respectively. @@ -448,9 +449,9 @@ Instructions: 4. One motor will start spinning (click **Spin Motor Again** if it stops spinning too quickly to note.) - Select the corresponding motor in the geometry section. + Select the corresponding motor in the geometry section. - ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) + ![Screenshot showing how to identify/assign motors](../../assets/config/actuators/identify_motors_in_progress.png) 5. After assigning all motors, the tool will set the correct motor mapping for the outputs and then exit. @@ -467,15 +468,15 @@ To assign an actuator: 1. First assign functions to the outputs that you think are _likely_ to be correct in the _Actuator Outputs_ section. 2. Toggle the **Enable sliders** switch in _Actuator Testing_ section. 3. Move the slider for the actuator you want to test: - - Motors should be moved to the minimum thrust position. - - Servos should be moved near the middle position. + - Motors should be moved to the minimum thrust position. + - Servos should be moved near the middle position. 4. Check which actuator moves on the vehicle. - This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). - - If the correct actuator moves, then proceed to the next step. - - If a wrong actuator moves, swap the output assignment over. - - If nothing moves then increase the slider mid-way though the range, then higher if needed. - If nothing moves after that the output might not be connected, the motor might not be powered, or the output might be misconfigured. - You will need to troubleshoot (perhaps try other actuator outputs to see if "anything" moves). + This should match the actuator positions for your geometry (the [airframe reference](../airframes/airframe_reference.md) shows motor positions for a number of standard airframes). + - If the correct actuator moves, then proceed to the next step. + - If a wrong actuator moves, swap the output assignment over. + - If nothing moves then increase the slider mid-way though the range, then higher if needed. + If nothing moves after that the output might not be connected, the motor might not be powered, or the output might be misconfigured. + You will need to troubleshoot (perhaps try other actuator outputs to see if "anything" moves). 5. Return the slider to the "disarmed" position (bottom of slider for motors, centre of slider for servos). 6. Repeat for all actuators @@ -501,32 +502,32 @@ The motor configuration sets output values such that motors: For each motor: 1. Pull the motor slider down so that it snaps to the bottom. - In this position the motor is set to the outputs `disarmed` value. - - Verify that the motor doesn't spin in this position. - - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. + In this position the motor is set to the outputs `disarmed` value. + - Verify that the motor doesn't spin in this position. + - If the motor spins, reduce the corresponding PWM `disarmed` value in the [Actuator Outputs](#actuator-outputs) section to below the level at which it still spins. 2. Slowly move the slider up until it snaps to the _minimum_ position. - In this position the motor is set to the outputs `minimum` value. - - Verify that the motor is spinning very slowly in this position. - - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. + In this position the motor is set to the outputs `minimum` value. + - Verify that the motor is spinning very slowly in this position. + - If the motor is not spinning, or spinning too fast you will need to adjust the corresponding PWM `minimum` value in the [Actuator Outputs](#actuator-outputs) such that the motors barely spin. - ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) - ::: info - For DShot output, this is not required. + ![PWM Minimum Output](../../assets/config/actuators/pwm_minimum_output.png) + ::: info + For DShot output, this is not required. ::: 3. Increase the slider value to a level where you can verify that the motor is spinning in the correct direction and that it would give a positive thrust in the expected direction. - - The expected thrust direction can vary by vehicle type. - For example in multicopters the thrust should always point upwards, while in a fixed-wing vehicle the thrust will push the vehicle forwards. - - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). - Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. - - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). + - The expected thrust direction can vary by vehicle type. + For example in multicopters the thrust should always point upwards, while in a fixed-wing vehicle the thrust will push the vehicle forwards. + - For VTOL, thrust should point upwards when the Tilt Servo is at 0 degrees as defined the [Tilt Servo Convention](#tilt-servo-coordinate-system). + Testing of the [Tilt Servo](#tilt-servo-setup) is covered below as well. + - If thrust is in the wrong direction, you may need to [reverse the motors](#reversing-motors). 4. Increase the slider value to the maximum value, so the motor is spinning quickly. - Reduce the value of the PWM output's `maximum` value just below the default. - Listen to the tone of the motors as you increase the value in small (25us) increments. - The "optimal" maximum value is the value at which you last hear a change in the tone. + Reduce the value of the PWM output's `maximum` value just below the default. + Listen to the tone of the motors as you increase the value in small (25us) increments. + The "optimal" maximum value is the value at which you last hear a change in the tone. ### Control Surface Setup @@ -542,40 +543,76 @@ If you're using PWM servos, PWM50 is far more common. If a high rate servo is _really_ needed, DShot offers better value. ::: -#### Control surfaces that move both directions about a neutral point +##### PWM: Control surfaces that move both directions about a neutral point + +To facilitate setting the neutral point of the servos, a bilinear curve function can be defined using the following parameters `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` for each servo. This allows for unequal deflections in the positive and negative direction: + +![Asymmetric Servo Deflections](../../assets/config/actuators/servo_pwm_center.png) + +To set this up: + +1. Set all surface `Trim` to `0.00` for all surfaces: + + ![PWM Trimming](../../assets/config/actuators/control_surface_trim.png) + +2. Set the `PWM_MAIN_CENTx` / `PWM_AUX_CENTx` value so that the surface will stay at the neutral (aligned with airfoil) position. + This is usually around `1500` for PWM servos (near the center of the servo range). + + ![Control Surface Trimming](../../assets/config/actuators/pwm_center_output.png) + +3. Gradually increase the `Maximum` for each servo until the desired deflection is reached. Check the deflection with a remote manual mode while [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) is set to `Always` or use the sliders. + +4. Gradually decrease the `Minimum` for each servo, until the desired deflection is reached. + +5. Set `Disarmed` value to the desired value. It is usually desirable to have it the same as the `Center` value. + +:::info +If you want to retain the linear behaviour of the servo after setting the `Center`, make sure to adjust the `Minimum` or `Maximum`, such that both intervals (`min` to `cent` & `cent` to `max`) are equally large. + +![Linear PWM Adjustment](../../assets/config/actuators/servo_pwm_linear.png) +::: + +#### Non-PWM: Control surfaces that move both directions about a neutral point Control surfaces that move either direction around a neutral point include: ailerons, elevons, V-tails, A-tails, and rudders. To set these up: -1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. - This is usually around `1500` for PWM servos (near the centre of the servo range). +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. - ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) +1. Set the `Disarmed` value so that the surfaces will stay at neutral position when disarmed. + This is usually around `1500` for PWM servos (near the centre of the servo range). + + ![Control Surface Disarmed 1500 Setting](../../assets/config/actuators/control_surface_aileron_setup.png) 2. Move the slider for the surface upwards (positive command) and verify that it moves in the direction defined in the [Control Surface Convention](#control-surface-deflection-convention). - - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. - - Rudders and other "purely vertical" surfaces should move right. + - Ailerons, elevons, V-Tails, A-Tails, and other horizontal surfaces should move up. + - Rudders and other "purely vertical" surfaces should move right. - ::: tip - It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). + ::: tip + It is important that the slider movement matches the control surface convention, in order to normalize control for different servo mountings (moving the slider up may actually decrease the output value sent to the servo). ::: - If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. + If the control surface moves in the opposite direction, click on the `Rev Range` checkbox to reverse the range. 3. Move the slider again to the middle and check if the Control Surfaces are aligned in the neutral position of the wing. - - If it is not aligned, you can set the **Trim** value for the control surface. - ::: info - This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". - ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) + - If it is not aligned, you can set the **Trim** value for the control surface. + + ::: info + This is done in the `Trim` setting of the Geometry panel, usually by "trial and error". + ![Control Surface Trimming](../../assets/config/actuators/control_surface_trim.png) ::: - - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. - Confirm that surface is in the neutral position. + - After setting the trim for a control surface, move its slider away from the centre, release, and then back into disarmed (middle) position. + Confirm that surface is in the neutral position. + +:::tip +If any servo has a `PWM_MAIN_CENTx` or `PWM_AUX_CENTx` not set to default (-1), the system will automatically remove `Trim` from all surfaces. This is done to prevent mixing of old and new trimming tools. +::: :::info Another way to test without using the sliders would be to set the [`COM_PREARM_MODE`](../advanced_config/parameter_reference.md#COM_PREARM_MODE) parameter to `Always`: @@ -595,15 +632,17 @@ For a flap, that is when the flap is fully retracted and flush with the wing. One approach for setting these up is: +0. Set all `PWM_MAIN_CENTx` and `PWM_AUX_CENTx` to default (-1), or trimming will not be possible. 1. Set values `Disarmed` to `1500`, `Min` to `1200`, `Max` to `1700` so that the values are around the centre of the servo range. 2. Move the corresponding slider up and check the control moves and that it is extending (moving away from the disarmed position). - If not, click on the `Rev Range` checkbox to reverse the range. + If not, click on the `Rev Range` checkbox to reverse the range. 3. Enable slider in the disarmed position, them change the value of the `Disarmed` signal until the control is retracted/flush with wing. - This may require that the `Disarmed` value is increased or decreased: - - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. - - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. + This may require that the `Disarmed` value is increased or decreased: + - If the value was decreased towards `Min`, then set `Min` to match `Disarmed`. + - If the value was increased towards `Max`, then set `Max` to match `Disarmed`. 4. The value that you did _not_ set to match `Disarmed` controls the maximum amount that the control surface can extend. - Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. + Set the slider to the top of the control, then change the value (`Max` or `Min`) so that the control surface is fully extended when the slider is at top. +5. (Only PWM servos) Set the `Center` value to the middle between `Min` and `Max`. :::info Special note for flaps In some vehicle builds, flaps may be configured such that both flaps are controlled from a single output. @@ -627,7 +666,7 @@ For each of the tilt servos: 2. Position the slider for the servo in the lowest position, and verify that a positive value increase will point towards the `Angle at Min Tilt` (defined in the Geometry section). - ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) + ![Tilt Servo Geometry Setup](../../assets/config/actuators/tilt_servo_geometry_config.png) 3. Position the slider for the servo in the highest position, and verify that positive motor thrust will point towards the `Angle at Max Tilt` (as defined in the Geometry section). @@ -642,6 +681,11 @@ For each of the tilt servos: - Standard VTOL : Motors defined as multicopter motors will be turned off - Tiltrotors : Motors that have no associated tilt servo will turn off - Tailsitters do not turn off any motors in fixed-wing flight +- The following formula can be used to migrate from surface trim to PWM trim: + + ```plain + PWM_MAIN_CENTx = ((PWM_MAX - PWM_MIN) / 2) * CA_SV_CSx_TRIM + PWM_MIN + ((PWM_MAX - PWM_MIN) / 2) + ``` ### Reversing Motors diff --git a/docs/zh/config/airspeed.md b/docs/zh/config/airspeed.md index 90e3006948..bde7aa8f9c 100644 --- a/docs/zh/config/airspeed.md +++ b/docs/zh/config/airspeed.md @@ -27,18 +27,18 @@ To calibrate the airspeed sensor: 4. Click the **Airspeed** sensor button. - ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) + ![Airspeed calibration](../../assets/qgc/setup/sensor/sensor_airspeed.jpg) 5. Shield the sensor from the wind (i.e. cup it with your hand). - Take care not to block any of its holes. + Take care not to block any of its holes. 6. Click **OK** to start the calibration. 7. Once asked for, blow into the tip of the pitot tube to signal the end of calibration. - :::tip - Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. - If they are swapped then the sensor will read a large negative differential pressure when you blow into the tube, and the calibration will abort with an error. + :::tip + Blowing into the tube is also a basic check that the dynamic and static ports are installed correctly. + If they are swapped then the sensor will read a large negative differential pressure when you blow into the tube, and the calibration will abort with an error. ::: diff --git a/docs/zh/config/compass.md b/docs/zh/config/compass.md index adfeb33028..e121662f01 100644 --- a/docs/zh/config/compass.md +++ b/docs/zh/config/compass.md @@ -10,7 +10,7 @@ If you have [mounted the compass](../assembly/mount_gps_compass.md#compass-orien ## 综述 -You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to recalibrate it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. +You will need to calibrate your compass(es) when you first setup your vehicle, and you may need to [recalibrate](#recalibration) it if the vehicles is ever exposed to a very strong magnetic field, or if it is used in an area with abnormal magnetic characteristics. :::tip Indications of a poor compass calibration include multicopter circling during hover, toilet bowling (circling at increasing radius/spiraling-out, usually constant altitude, leading to fly-way), or veering off-path when attempting to fly straight. @@ -20,13 +20,16 @@ _QGroundControl_ should also notify the error `mag sensors inconsistent`. The process calibrates all compasses and autodetects the orientation of any external compasses. If any external magnetometers are available, it then disables the internal magnetometers (these are primarily needed for automatic rotation detection of external magnetometers). +### Types of Calibration + Several types of compass calibration are available: 1. [Complete](#complete-calibration): This calibration is required after installing the autopilot on an airframe for the first time or when the configuration of the vehicle has changed significantly. - It compensates for hard and soft iron effects by estimating an offset and a scale factor for each axis. + It compensates for hard and soft iron effects by estimating an offset and a scale factor for each axis. 2. [Partial](#partial-quick-calibration): This calibration can be performed as a routine when preparing the vehicle for a flight, after changing the payload, or simply when the compass rose seems inaccurate. - This type of calibration only estimates the offsets to compensate for a hard iron effect. -3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. This type of calibration only estimates the offsets to compensate for a hard iron effect. + This type of calibration only estimates the offsets to compensate for a hard iron effect. +3. [Large vehicle](#large-vehicle-calibration): This calibration can be performed when the vehicle is too large or heavy to perform a complete calibration. + This type of calibration only estimates the offsets to compensate for a hard iron effect. ## 执行校准 @@ -35,13 +38,13 @@ Several types of compass calibration are available: Before starting the calibration: 1. Choose a location away from large metal objects or magnetic fields. - :::tip - Metal is not always obvious! Avoid calibrating on top of an office table (often contain metal bars) or next to a vehicle. - Calibration can even be affected if you're standing on a slab of concrete with uneven distribution of re-bar. + :::tip + Metal is not always obvious! Avoid calibrating on top of an office table (often contain metal bars) or next to a vehicle. + Calibration can even be affected if you're standing on a slab of concrete with uneven distribution of re-bar. ::: 2. Connect via telemetry radio rather than USB if at all possible. - USB can potentially cause significant magnetic interference. + USB can potentially cause significant magnetic interference. 3. If using an external compass (or a combined GPS/compass module), make sure it is [mounted](../assembly/mount_gps_compass.md) as far as possible from other electronics in order to reduce magnetic interference, and in a _supported orientation_. ### Complete Calibration @@ -54,29 +57,33 @@ The calibration steps are: 3. Click the **Compass** sensor button. - ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) + ![Select Compass calibration PX4](../../assets/qgc/setup/sensor/sensor_compass_select_px4.png) - ::: info - You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). If not, you can also set it here. + ::: info + You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). + If not, you can also set it here. ::: 4. Click **OK** to start the calibration. -5. 把你的飞机放置在下面显示的某一个方向,并保持静止。 随后提示(方向图像变为黄色)在指定方向旋转飞行器。 该位置标定完成后,屏幕上的相应图示将变成绿色。 +5. 把你的飞机放置在下面显示的某一个方向,并保持静止。 + 随后提示(方向图像变为黄色)在指定方向旋转飞行器。 + 该位置标定完成后,屏幕上的相应图示将变成绿色。 - ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) + ![Compass calibration steps on PX4](../../assets/qgc/setup/sensor/sensor_compass_calibrate_px4.png) 6. 在机体的所有方向上重复校准步骤。 -Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). You can then proceed to the next sensor. +Once you've calibrated the vehicle in all the positions _QGroundControl_ will display _Calibration complete_ (all orientation images will be displayed in green and the progress bar will fill completely). +You can then proceed to the next sensor. ### Partial "Quick" Calibration This calibration is similar to the well-known figure-8 compass calibration done on a smartphone: 1. Hold the vehicle in front of you and randomly perform partial rotations on all its axes. - 2-3 oscillations of ~30 degrees in every direction is usually sufficient. + 2-3 oscillations of ~30 degrees in every direction is usually sufficient. 2. Wait for the heading estimate to stabilize and verify that the compass rose is pointing to the correct direction (this can take a couple of seconds). 备注: @@ -92,14 +99,15 @@ This calibration is similar to the well-known figure-8 compass calibration done This calibration process leverages external knowledge of vehicle's orientation and location, and a World Magnetic Model (WMM) to calibrate the hard iron biases. -1. Ensure GNSS Fix. This is required to find the expected Earth magnetic field in WMM tables. +1. Ensure GNSS Fix. + This is required to find the expected Earth magnetic field in WMM tables. 2. Align the vehicle to face True North. - Be as accurate as possible for best results. + Be as accurate as possible for best results. 3. Open the [QGroundControl MAVLink Console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) and send the following command: - ```sh - commander calibrate mag quick - ``` + ```sh + commander calibrate mag quick + ``` 备注: @@ -112,6 +120,30 @@ This calibration process leverages external knowledge of vehicle's orientation a After the calibration is complete, check that the heading indicator and the heading of the arrow on the map are stable and match the orientation of the vehicle when turning it e.g. to the cardinal directions. +## Recalibration + +Recalibration is recommended whenever the magnetic environment of the vehicle has changed or when heading behavior appears unreliable. + +You can use either complete calibration or mag quick calibration depending on the size of the vehicle and your ability to rotate it through the required orientations. +Complete calibration provides the most accurate soft-iron compensation. + +Recalibrate the compass when: + +- _The compass module or its mounting orientation has changed._ + This includes replacing the GPS or mag unit, rotating the mast, or altering how the module is fixed to the airframe. +- _The vehicle has been exposed to a strong magnetic disturbance._ + Examples include transport or storage near large steel structures, welding operations near the airframe, or operation close to high-current equipment. +- _Structural, wiring, or payload changes may have altered the magnetic field around the sensors._ + New payloads, rerouted wires, additional batteries, or metal fasteners can introduce soft-iron effects that affect heading accuracy. +- _The vehicle is operated in a region with significantly different magnetic characteristics._ + Large changes in latitude, longitude, or magnetic inclination can require re-estimation of offsets. +- _QGroundControl reports magnetometer inconsistencies_. + For example, if you see the error `mag sensors inconsistent`. +- _Heading behavior does not match the vehicle’s observed orientation._ + Symptoms include drifting yaw, sudden heading jumps when attempting to fly straight, and toilet bowling +- _QGroundControl_ sends the error `mag sensors inconsistent`. + This indicates that multiple magnetometers are reporting different headings. + ## Additional Calibration/Configuration The process above will autodetect, [set default rotations](../advanced_config/parameter_reference.md#SENS_MAG_AUTOROT), calibrate, and prioritise, all available magnetometers. diff --git a/docs/zh/config/firmware.md b/docs/zh/config/firmware.md index 55dc6039ec..0244ee351a 100644 --- a/docs/zh/config/firmware.md +++ b/docs/zh/config/firmware.md @@ -61,10 +61,10 @@ To install a different version of PX4: 2. Check **Advanced settings** and select the version from the dropdown list: - **Standard Version (stable):** The default version (i.e. no need to use advanced settings to install this!) - **Beta Testing (beta):** A beta/candidate release. - 只有当新版本准备完毕时才可用。 + 只有当新版本准备完毕时才可用。 - **Developer Build (master):** The latest build of PX4/PX4-Autopilot _main_ branch. - **Custom Firmware file...:** A custom firmware file (e.g. [that you have built locally](../dev_setup/building_px4.md)). - 如果选择 Custom firmware file ,您需要在下一步中从文件系统中选择自定义固件。 + 如果选择 Custom firmware file ,您需要在下一步中从文件系统中选择自定义固件。 Firmware update then continues as before. diff --git a/docs/zh/config/flight_mode.md b/docs/zh/config/flight_mode.md index a418f4c3b1..557577e9ad 100644 --- a/docs/zh/config/flight_mode.md +++ b/docs/zh/config/flight_mode.md @@ -40,24 +40,24 @@ To configure single-channel flight mode selection: 3. Select **"Q" icon > Vehicle Setup > Flight Modes** (sidebar) to open _Flight Modes Setup_. - ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) + ![Flight modes single-channel](../../assets/qgc/setup/flight_modes/flight_modes_single_channel.jpg) 4. 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 **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. + - Select the flight mode that you want triggered for each switch position. 5. 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 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). 6. 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. diff --git a/docs/zh/config/index.md b/docs/zh/config/index.md index 1f02d044e1..cfc1fb3515 100644 --- a/docs/zh/config/index.md +++ b/docs/zh/config/index.md @@ -72,7 +72,7 @@ The video below shows most of the calibration process (it uses an older version If you need help with the configuration you can ask for help on the [QGroundControl Support forum](https://discuss.px4.io/c/qgroundcontrol/qgroundcontrol-usage/18). -## See Also +## 另见 - [QGroundControl > Setup](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/setup_view.html) - [飞控外设](../peripherals/index.md) - 设置特定传感器、可选传感器、执行器等。 diff --git a/docs/zh/config/safety.md b/docs/zh/config/safety.md index a928faa4ea..433eb1d99f 100644 --- a/docs/zh/config/safety.md +++ b/docs/zh/config/safety.md @@ -106,7 +106,7 @@ The settings and underlying parameters are shown below. | 设置 | 参数 | 描述 | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None, `1`: Warning, `3`: Return mode (default). | +| Low flight time for safe return action | [COM_FLTT_LOW_ACT](../advanced_config/parameter_reference.md#COM_FLTT_LOW_ACT) | Action when return mode can only just reach safety with remaining battery. `0`: None (default), `1`: Warning, `3`: Return mode. | | Maximum flight time failsafe level | [COM_FLT_TIME_MAX](../advanced_config/parameter_reference.md#COM_FLT_TIME_MAX) | Maximum allowed flight time before Return mode will be engaged, in seconds. `-1`: Disabled (default). | ## Manual Control Loss Failsafe @@ -121,36 +121,32 @@ PX4 and the receiver may also need to be configured in order to _detect RC loss_ ![Safety - RC Loss (QGC)](../../assets/qgc/setup/safety/safety_rc_loss.png) -The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [RC Loss timeout](#COM_RC_LOSS_T). -Users that want to disable the RC loss failsafe in specific automatic modes (mission, hold, offboard) can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). +The QGCroundControl Safety UI allows you to set the [failsafe action](#failsafe-actions) and [manual control loss timeout](#COM_RC_LOSS_T). +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_RCL_EXCEPT](#COM_RCL_EXCEPT). Additional (and underlying) parameter settings are shown below. | 参数 | 设置 | 描述 | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [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 old manual control setpoint until the timeout triggers. | +| [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. | | [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. | | [NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | 故障保护动作 | Disabled, Loiter, Return, Land, Disarm, Terminate. | -| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set the modes in which manual control loss is ignored: Mission, Hold, Offboard. | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set modes in which manual control loss is ignored. | ## 数据链路丢失故障保护 -The Data Link Loss failsafe is triggered if a telemetry link (connection to ground station) is lost. +The Data Link Loss failsafe is triggered if the connection to the last MAVLink ground station like QGroundControl is lost. +Users that want to disable this failsafe in specific modes can do so using the parameter [COM_DLL_EXCEPT](#COM_DLL_EXCEPT). ![Safety - Data Link Loss (QGC)](../../assets/qgc/setup/safety/safety_data_link_loss.png) The settings and underlying parameters are shown below. -| 设置 | 参数 | 描述 | -| -------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| 数据链路丢失超时 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 数据连接断开后到故障保护触发之前的时间。 | -| 故障保护动作 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | - -The following settings also apply, but are not displayed in the QGC UI. - -| 设置 | 参数 | 描述 | -| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes where DL loss will not trigger a failsafe. | +| 设置 | 参数 | 描述 | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| 数据链路丢失超时 | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | 数据连接断开后到故障保护触发之前的时间。 | +| 故障保护动作 | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. | +| 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. | ## 地理围栏故障保护 @@ -206,23 +202,13 @@ The relevant parameters shown below. ### Position Loss Failsafe Action -The failure action is controlled by [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL), based on whether RC control is assumed to be available (and altitude information): - -- `0`: Remote control available. - Switch to _Altitude mode_ if a height estimate is available, otherwise _Stabilized mode_. -- `1`: Remote control _not_ available. - Switch to _Descend mode_ if a height estimate is available, otherwise enter flight termination. - _Descend mode_ is a landing mode that does not require a position estimate. +Multicopters will switch to [Altitude mode](../flight_modes_mc/altitude.md) if a height estimate is available, otherwise [Stabilized mode](../flight_modes_mc/manual_stabilized.md). Fixed-wing planes, and VTOLs not configured to land in hover ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)), have a parameter ([FW_GPSF_LT](../advanced_config/parameter_reference.md#FW_GPSF_LT)) that defines how long they will loiter (circle with a constant roll angle ([FW_GPSF_R](../advanced_config/parameter_reference.md#FW_GPSF_R)) at the current altitude) after losing position before attempting to land. If VTOLs have are configured to switch to hover for landing ([NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT)) then they will first transition and then descend. The relevant parameters for all vehicles shown below. -| 参数 | 描述 | -| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [COM_POSCTL_NAVL](../advanced_config/parameter_reference.md#COM_POSCTL_NAVL) | Position control navigation loss response during mission. Values: `0` - assume use of RC, `1` - Assume no RC. | - Parameters that only affect Fixed-wing vehicles: | 参数 | 描述 | @@ -286,18 +272,18 @@ The relevant parameters are listed in the table below. ## 故障检测器 -The failure detector allows a vehicle to take protective action(s) if it unexpectedly flips, or if it is notified by an external failure detection system. +The failure detector allows a vehicle to take protective actions if it unexpectedly flips, detects a motor failure, or if it is notified by an external failure detection system. During **flight**, the failure detector can be used to trigger [flight termination](../advanced_config/flight_termination.md) if failure conditions are met, which may then launch a [parachute](../peripherals/parachute.md) or perform some other action. :::info -Failure detection during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). +Acting on a detected failure during flight is deactivated by default (enable by setting the parameter: [CBRK_FLIGHTTERM=0](#CBRK_FLIGHTTERM)). ::: During **takeoff** the failure detector [attitude trigger](#attitude-trigger) invokes the [disarm action](#act_disarm) if the vehicle flips (disarm kills the motors but, unlike flight termination, will not launch a parachute or perform other failure actions). Note that this check is _always enabled on takeoff_, irrespective of the `CBRK_FLIGHTTERM` parameter. -The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/altitude.md), [Acro mode (FW)](../flight_modes_fw/altitude.md), and [Manual (FW)](../flight_modes_fw/manual.md)). +The failure detector is active in all vehicle types and modes, except for those where the vehicle is _expected_ to do flips (i.e. [Acro mode (MC)](../flight_modes_mc/acro.md), [Acro mode (FW)](../flight_modes_fw/acro.md), and [Manual (FW)](../flight_modes_fw/manual.md)). ### 姿态触发器 @@ -313,6 +299,26 @@ The relevant parameters are shown below: | [FD_FAIL_P_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_P_TTRI) | Time to exceed [FD_FAIL_P](#FD_FAIL_P) for failure detection (default 0.3s). | | [FD_FAIL_R_TTRI](../advanced_config/parameter_reference.md#FD_FAIL_R_TTRI) | Time to exceed [FD_FAIL_R](#FD_FAIL_R) for failure detection (default 0.3s). | +### Motor Failure Trigger + +The failure detector can be configured to detect a motor failure while armed (and trigger an associated action) in the following conditions: + +- A 300 ms timeout occurs in telemetry from an ESC that was previously available. +- The input current in the telemetry of an ESC which was previously positive gets too low for more than [`FD_ACT_MOT_TOUT`](FD_ACT_MOT_TOUT) ms. + The "too low" condition is defined by: + + ```text + {esc current} < {parameter FD_ACT_MOT_C2T} * {motor command between 0 and 1} + ``` + +| 参数 | 描述 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [FD_ACT_EN](../advanced_config/parameter_reference.md#FD_ACT_EN) | Enable/disable the motor failure trigger completely. | +| [FD_ACT_MOT_THR](../advanced_config/parameter_reference.md#FD_ACT_MOT_THR) | Minimum normalized [0,1] motor command below which motor under current is ignored. | +| [FD_ACT_MOT_C2T](../advanced_config/parameter_reference.md#FD_ACT_MOT_C2T) | Scale between normalized [0,1] motor command and expected minimally reported currrent when the rotor is healthy. | +| [FD_ACT_MOT_TOUT](../advanced_config/parameter_reference.md#FD_ACT_MOT_TOUT) | Time in miliseconds for which the under current detection condition needs to stay true. | +| [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) | Configure to not only warn about a motor failure but remove the first motor that detects a failure from the allocation effectiveness which turns off the motor and tries to operate the vehicle without it until disarming the next time. | + ### 外部自动触发系统(ATS) The [failure detector](#failure-detector), if [enabled](#CBRK_FLIGHTTERM), can also be triggered by an external ATS system. diff --git a/docs/zh/config/safety_simulation.md b/docs/zh/config/safety_simulation.md index be2f6cb89a..bee01fc8d3 100644 --- a/docs/zh/config/safety_simulation.md +++ b/docs/zh/config/safety_simulation.md @@ -14,7 +14,7 @@ To use it: 2. Set the vehicle type 3. Set the other values in the **State** or any of the flags under **Conditions** - The **Intended Mode** corresponds to the commanded mode via RC or GCS (or external script). - The failsafe state machine can override this in case of a failsafe. + The failsafe state machine can override this in case of a failsafe. 4. Check the action under **Output** 5. Check what happens when changing mode or **Move the RC sticks** 6. Play with different settings and conditions! diff --git a/docs/zh/config_fw/airspeed_scale_handling.md b/docs/zh/config_fw/airspeed_scale_handling.md new file mode 100644 index 0000000000..02f745fc72 --- /dev/null +++ b/docs/zh/config_fw/airspeed_scale_handling.md @@ -0,0 +1,112 @@ +# Airspeed Scale Handling + +:::info +This section complements the existing [Airspeed Validation](../advanced_config/airspeed_validation.md) documentation. +::: + +The airspeed scale is used by PX4 to convert the measured airspeed (indicated airspeed) to the calibrated airspeed. +This scale can be set by [ASPD_SCALE_n](../advanced_config/parameter_reference.md#ASPD_SCALE_1) (where `n` is the sensor number), and logged in [AirspeedWind.msg](../msg_docs/AirspeedWind.md). + +Note that the airspeed scale is different from the airspeed sensor offset calibration done on the ground at 0 m/s. The airspeed scale accounts for errors in the airspeed measurement during flight, such as those caused by sensor placement or installation effects. + +This topic describes how to set an initial airspeed scale for a new fixed-wing vehicle during its first flight. Correct scale calibration ensures reliable airspeed data, accurate TAS calculation, robust PX4 airspeed validation, and consistent controller performance. + +## Airspeed in PX4 + +PX4 handles multiple types of airspeed: + +- **IAS (Indicated Airspeed):** The raw measurement from the airspeed sensor, directly influenced by sensor characteristics and installation effects (e.g., pitot-static errors). +- **CAS (Calibrated Airspeed):** IAS corrected for sensor-specific and installation-related errors. +- **EAS (Equivalent Airspeed):** _Not explicitly handled by PX4_ - Calibrated airspeed corrected for compressibility effects. + While PX4 does not currently model EAS separately, this correction is negligible at low speeds and altitudes, so EAS is treated as equivalent to CAS for simplicity. +- **TAS (True Airspeed):** CAS adjusted for atmospheric effects such as air pressure and temperature (i.e., altitude and atmospheric conditions). + +The standard conversion chain used in PX4 is: `IAS → CAS (= EAS) → TAS`. + +## CAS Scale Estimation + +PX4 estimates the IAS to CAS scale (referred to as the CAS scale) during flight using GNSS ground speed and wind estimation. +To compute the final TAS, standard environment conversions are applied (CAS → TAS). + +:::warning +Important +A GNSS is required for scale estimation. +::: + +PX4 uses a two-stage approach to robustly estimate the scale: + +1. **Continuous EKF Estimation**: A wind estimator constantly compares your measured airspeed against what it expects based on ground velocity (from GNSS) and estimated wind. + If there's a consistent bias, it adjusts the scale estimate. + The estimated scale is logged in the `AirspeedWind.msg` as the `tas_scale_raw`. +2. **Validation**: To ensure robustness, PX4 collects airspeed and ground speed data across 12 different heading segments (every 30°). + This averages out wind estimation errors. + The validated scale is only updated when the new estimate demonstrably reduces the error between predicted and actual ground speeds across all headings. + The validated scale is logged in the `AirspeedWind.msg` as the `tas_scale_validated`. + +### Understanding the Scale: Physical Intuition + +The CAS scale is essentially a correction factor that accounts for systematic errors in your airspeed sensor installation. + +- A scale of 1.0 means your sensor reads perfectly (no correction needed) +- A scale > 1.0 (e.g., 1.1) means your sensor _under-reads_ by 10%, so measured airspeed (IAS) must be multiplied by 1.1 +- A scale < 1.0 (e.g., 0.9) means your sensor _over-reads_ by ~11%, so measured airspeed (IAS) must be multiplied by 0.9 + +### What Affects the Airspeed Scale + +The primary factor influencing the airspeed scale is **sensor placement**. + +Biased readings can be reflected in the scale estimate for pitot tubes installed: + +- In regions experiencing disturbed flow (commonly near blunt aircraft noses) +- Near propellers +- Under aerodynamic surfaces +- At an angle with respect to the airflow + +### Symptoms of Incorrect Scale + +Symptoms of an incorrectly scaled airspeed measurement include: + +- Stalling or overspeeding +- Persistent under- or overestimation of the TAS relative to wind-corrected groundspeed +- False positives or missed detections in [airspeed innovation checks](../advanced_config/airspeed_validation.md#innovation-check) +- Degraded tracking of the rate controllers + +## Recommended First Flight Process + +During the first flight of a new fixed-wing vehicle, allocate time for the CAS scale to converge to a reasonable initial estimate. +Follow these steps: + +1. **Set an Initial Scale** + + Set the CAS scale (`ASPD_SCALE_n`) to 1.0 (the default value). + When the scale is at exactly 1.0, PX4 automatically accelerates the learning process during the first 5 minutes of flight, allowing faster convergence to the correct scale value. + +2. **Perform a Flight** + + After takeoff, place the vehicle in loiter for about 15 minutes to allow the scale estimation to converge. + + ::: tip + Flying in circles (loiter/hold mode) is important as the scale-validation algorithm requires the aircraft to pass through multiple heading segments (12 segments covering all compass directions). + If these heading segments aren’t completed, PX4 cannot validate the estimated scale. + +::: + +3. **Check Scale Convergence** + + After the flight, review the estimated scale in logs. + Verify that: + + - `tas_scale_validated` in `AirspeedWind.msg` converged during flight. + - `true_airspeed_m_s` (TAS) in [AirspeedValidated.msg](../msg_docs/AirspeedValidated.md) is consistent with groundspeed corrected for wind. + +4. **Update the Airframe Configuration** + + If using an [airframe configuration file](../dev_airframes/adding_a_new_frame.md): update `ASPD_SCALE_n`with the estimated CAS scale for future flights. + For similar vehicles with similarly mounted sensors, this value is typically a reliable starting point. + +:::info +If you are not able to perform the steps outlined above ... + +For a quick manual CAS scale estimate, compare groundspeed minus windspeed (from the [VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) and [Wind](../msg_docs/Wind.md) messages, respectively) to indicated airspeed values (in the [Airspeed](../msg_docs/Airspeed.md) message). +The ratio of indicated airspeed to groundspeed minus windspeed can provide a reasonable starting estimate for `ASPD_SCALE_n`. +::: diff --git a/docs/zh/config_fw/index.md b/docs/zh/config_fw/index.md index 60fe4c9b6c..2a0834860a 100644 --- a/docs/zh/config_fw/index.md +++ b/docs/zh/config_fw/index.md @@ -3,7 +3,7 @@ Fixed-wing configuration and calibration follows the same high level steps as other frames: selection of firmware, configuration of the frame including actuator/motor geometry and output mappings, sensor configuration and calibration, configuration of safety and other features, and finally tuning. :::info -This topic is the recommended entry point when performing first-time configuration and calibration of a new multicopter frame. +This topic is the recommended entry point when performing first-time configuration and calibration of a new fixed-wing frame. ::: The main steps are: @@ -20,3 +20,5 @@ The main steps are: - [Fixed-wing Altitude/Position Controller Tuning Guide](../config_fw/position_tuning_guide_fixedwing.md) - [Fixed-wing Trimming Guide](../config_fw/trimming_guide_fixedwing.md) + +- [Fixed-Wing Airspeed Scale Handling](../config_fw/airspeed_scale_handling.md) diff --git a/docs/zh/config_fw/pid_tuning_guide_fixedwing.md b/docs/zh/config_fw/pid_tuning_guide_fixedwing.md index b9884d8a7c..8f8181c6f8 100644 --- a/docs/zh/config_fw/pid_tuning_guide_fixedwing.md +++ b/docs/zh/config_fw/pid_tuning_guide_fixedwing.md @@ -17,6 +17,8 @@ - 过高地增益(和快速的舵面响应)可能会超过你的机体结构允许最大过载――增加增益时需谨慎。 - 滚转和俯仰参数调整都遵循相同的顺序。 The only difference is that pitch is more sensitive to trim offsets, so [trimming](../config_fw/trimming_guide_fixedwing.md) has to be done carefully and integrator gains need more attention to compensate this. +- Disable automatic [gain compression](../features_fw/gain_compression.md) ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)) to avoid over-tuning. + Remember to re-enable it when tuning is done. ## 建立机型基准线 diff --git a/docs/zh/config_fw/position_tuning_guide_fixedwing.md b/docs/zh/config_fw/position_tuning_guide_fixedwing.md index 0b0dd06044..556cbfe6fb 100644 --- a/docs/zh/config_fw/position_tuning_guide_fixedwing.md +++ b/docs/zh/config_fw/position_tuning_guide_fixedwing.md @@ -9,7 +9,7 @@ An incorrectly set gain during tuning can make altitude or heading control unsta ::: :::tip -All parameters are documented in the [Parameter Reference](../advanced_config/parameter_reference.md#fw-tecs). +All parameters are documented in the Parameter Reference [FW Performance](../advanced_config/parameter_reference.md#fw-performance) and [FW NPFG Control](../advanced_config/parameter_reference.md#fw-npfg-control) sections. 本指南将介绍所有重要参数。 ::: @@ -77,7 +77,7 @@ Furthermore, these two values define the height rate limits commanded by the use ### 固定翼轨迹控制调整(位置) -All path control parameters are described [here](../advanced_config/parameter_reference.md#fw-path-control). +All path control parameters are described in [FW NPFG Control (Parameter Reference)](../advanced_config/parameter_reference.md#fw-npfg-control). - [NPFG_PERIOD](../advanced_config/parameter_reference.md#NPFG_PERIOD) - This is the previously called L1 distance and defines the tracking point ahead of the aircraft it's following. 大多数飞机适用于10-20米的数值范围。 diff --git a/docs/zh/config_fw/trimming_guide_fixedwing.md b/docs/zh/config_fw/trimming_guide_fixedwing.md index 833f5f1cb0..e8e7f0c00b 100644 --- a/docs/zh/config_fw/trimming_guide_fixedwing.md +++ b/docs/zh/config_fw/trimming_guide_fixedwing.md @@ -29,10 +29,10 @@ The [Advanced Trimming](#advanced-trimming) section introduces parameters that c 1. Trim the servos by physically adjusting the linkages lengths if possible and fine tune by trimming the PWM channels (use `PWM_MAIN/AUX_TRIMx`) on the bench to properly set the control surfaces to their theoretical position. 2. Fly in stabilized mode at cruise speed and set the pitch setpoint offset (`FW_PSP_OFF`) to desired angle of attack. - 巡航速度飞行下的需用攻角为飞机在平飞状态下保持固定高度时的实际飞行迎角。 - If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). + 巡航速度飞行下的需用攻角为飞机在平飞状态下保持固定高度时的实际飞行迎角。 + If you are using an airspeed sensor, also set the correct cruise airspeed (`FW_AIRSPD_TRIM`). 3. Look at the actuator controls in the log file (upload it to [Flight Review](https://logs.px4.io) and check the _Actuator Controls_ plot for example) and set the pitch trim (`TRIM_PITCH`). - 将该值设置为平飞时俯仰角度的平均值。 + 将该值设置为平飞时俯仰角度的平均值。 步骤3可以在步骤2之前执行,如果你不想查看日志, 或者如果您在手动模式下感觉舒适。 You can then trim your remote (with the trim switches) and report the values to `TRIM_PITCH` (and remove the trims from your transmitter) or update `TRIM_PITCH` directly during flight via telemetry and QGC. diff --git a/docs/zh/config_heli/index.md b/docs/zh/config_heli/index.md index 1d594e1885..f2c5ac697e 100644 --- a/docs/zh/config_heli/index.md +++ b/docs/zh/config_heli/index.md @@ -53,15 +53,15 @@ To setup and configure a helicopter: 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: + 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: - | # | Angle | - | ------- | ----- | - | Servo 1 | 60° | - | Servo 2 | 180° | - | Servo 3 | 300° | + | # | Angle | + | ------- | ----- | + | Servo 1 | 60° | + | Servo 2 | 180° | + | Servo 3 | 300° | - warning and requirement + warning and requirement - `Arm Length (relative to each other)`: Radius from the swash plate center (top view). A shorter arm means the same servo motion moves the plate more. This allows the autopilot to compensate. @@ -72,7 +72,7 @@ To setup and configure a helicopter: - `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. - A larger value may improve user experience. + A larger value may improve user experience. 3. Remove the rotor blades and propellers diff --git a/docs/zh/config_mc/filter_tuning.md b/docs/zh/config_mc/filter_tuning.md index d7fe6deca3..0b9796bb23 100644 --- a/docs/zh/config_mc/filter_tuning.md +++ b/docs/zh/config_mc/filter_tuning.md @@ -70,7 +70,7 @@ Airframes with more than two frequency noise spikes typically clean the first tw Dynamic notch filters use ESC RPM feedback and/or the onboard FFT analysis. The ESC RPM feedback is used to track the rotor blade pass frequency and its harmonics, while the FFT analysis can be used to track a frequency of another vibration source, such as a fuel engine. -ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/esc_motors.md#dshot) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). +ESC RPM feedback requires ESCs capable of providing RPM feedback such as [DShot](../peripherals/dshot.md) with telemetry connected, a bidirectional DShot set up ([work in progress](https://github.com/PX4/PX4-Autopilot/pull/23863)), or [UAVCAN/DroneCAN ESCs](../dronecan/escs.md). Before enabling, make sure that the ESC RPM is correct. You might have to adjust the [pole count of the motors](../advanced_config/parameter_reference.md#MOT_POLE_COUNT). @@ -166,11 +166,11 @@ The low pass filters and the notch filter can be tuned independently (i.e. you d ## Additional Tips 1. Acceptable latency depends on vehicle size and expectations. - FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). - For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. + FPV racers typically tune for the absolute minimal latency (as a ballpark `IMU_GYRO_CUTOFF` around 120, `IMU_DGYRO_CUTOFF` of 50 to 80). + For bigger vehicles latency is less critical and `IMU_GYRO_CUTOFF` of around 80 might be acceptable. 2. You can start tuning at higher `IMU_GYRO_CUTOFF` values (e.g. 100Hz), which might be desirable because the default tuning of `IMU_GYRO_CUTOFF` is set very low (30Hz). - The only caveat is that you must be aware of the risks: - - Don't fly for more than 20-30 seconds - - Check that the motors are not getting to hot - - Listen for odd sounds and symptoms of excessive noise, as discussed above. + The only caveat is that you must be aware of the risks: + - Don't fly for more than 20-30 seconds + - Check that the motors are not getting to hot + - Listen for odd sounds and symptoms of excessive noise, as discussed above. diff --git a/docs/zh/config_mc/index.md b/docs/zh/config_mc/index.md index e74e71cec9..3cb84d34cf 100644 --- a/docs/zh/config_mc/index.md +++ b/docs/zh/config_mc/index.md @@ -161,7 +161,7 @@ My assumption is that the mixing system can cope with whatever geometry you thro Yes but it must be physically feasible. E.g. if you make a quadrotor where all motors turn the same way it will "deal" with it but that cannot work without very specific controllers. Same for a monocopter or a tricopter without swiveling one motor. --> -## See Also +## 另见 - [QGroundControl > Setup](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/setup_view.html) - [飞控外设](../peripherals/index.md) - 设置特定传感器、可选传感器、执行器等。 diff --git a/docs/zh/config_mc/pid_tuning_guide_multicopter_basic.md b/docs/zh/config_mc/pid_tuning_guide_multicopter_basic.md index 6f31c50c9e..2a7602bae5 100644 --- a/docs/zh/config_mc/pid_tuning_guide_multicopter_basic.md +++ b/docs/zh/config_mc/pid_tuning_guide_multicopter_basic.md @@ -72,7 +72,7 @@ The tuning procedure is: 1. Arm the vehicle, takeoff, and hover (typically in [Position mode](../flight_modes_mc/position.md)). 2. Open _QGroundControl_ **Vehicle Setup > PID Tuning** - ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) + ![QGC Rate Controller Tuning UI](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_rate_controller.png) 3. Select the **Rate Controller** tab. @@ -80,60 +80,60 @@ The tuning procedure is: 5. Set the _Thrust curve_ value to: 0.3 (PWM, power-based controllers) or 1 (RPM-based ESCs) - ::: info - For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. - As a result, the optimal tuning at hover thrust may not be ideal when the vehicle is operating at higher thrust. + ::: info + For PWM, power-based and (some) UAVCAN speed controllers, the control signal to thrust relationship may not be linear. + 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: + 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). + - 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). - For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). + For more information see the [detailed PID tuning guide](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve). ::: 6. Set the _Select Tuning_ radio button to: **Roll**. 7. (Optionally) Select the **Automatic Flight Mode Switching** checkbox. - This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button + This will _automatically_ switch from [Position mode](../flight_modes_mc/position.md) to [Stabilised mode](../flight_modes_mc/manual_stabilized.md) when you press the **Start** button 8. For rate controller tuning switch to _Acro mode_, _Stabilized mode_ or _Altitude mode_ (unless automatic switching is enabled). 9. Select the **Start** button in order to start tracking the setpoint and response curves. 10. Rapidly move the _roll stick_ full range and observe the step response on the plots. - :::tip - Stop tracking to enable easier inspection of the plots. - This happens automatically when you zoom/pan. - Use the **Start** button to restart the plots, and **Clear** to reset them. + :::tip + Stop tracking to enable easier inspection of the plots. + This happens automatically when you zoom/pan. + Use the **Start** button to restart the plots, and **Clear** to reset them. ::: 11. Modify the three PID values using the sliders (for roll rate-tuning these affect `MC_ROLLRATE_K`, `MC_ROLLRATE_I`, `MC_ROLLRATE_D`) and observe the step response again. - The values are saved to the vehicle as soon as the sliders are moved. - ::: info - The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). + The values are saved to the vehicle as soon as the sliders are moved. + ::: info + The goal is for the _Response_ curve to match the _Setpoint_ curve as closely as possible (i.e. a fast response without overshoots). ::: - The PID values can be adjusted as follows: - - P (proportional) or K gain: - - increase this for more responsiveness - - reduce if the response is overshooting and/or oscillating (up to a certain point increasing the D gain also helps). - - D (derivative) gain: - - this can be increased to dampen overshoots and oscillations - - increase this only as much as needed, as it amplifies noise (and can lead to hot motors) - - I (integral) gain: - - used to reduce steady-state error - - if too low, the response might never reach the setpoint (e.g. in wind) - - if too high, slow oscillations can occur + The PID values can be adjusted as follows: + - P (proportional) or K gain: + - increase this for more responsiveness + - reduce if the response is overshooting and/or oscillating (up to a certain point increasing the D gain also helps). + - D (derivative) gain: + - this can be increased to dampen overshoots and oscillations + - increase this only as much as needed, as it amplifies noise (and can lead to hot motors) + - I (integral) gain: + - used to reduce steady-state error + - if too low, the response might never reach the setpoint (e.g. in wind) + - if too high, slow oscillations can occur 12. Repeat the tuning process above for the pitch and yaw: - - Use _Select Tuning_ radio button to select the axis to tune - - Move the appropriate sticks (i.e. pitch stick for pitch, yaw stick for yaw). - - For pitch tuning, start with the same values as for roll. - :::tip - Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. + - Use _Select Tuning_ radio button to select the axis to tune + - Move the appropriate sticks (i.e. pitch stick for pitch, yaw stick for yaw). + - For pitch tuning, start with the same values as for roll. + :::tip + Use the **Save to Clipboard** and **Reset from Clipboard** buttons to copy the roll settings for initial pitch settings. ::: @@ -141,10 +141,10 @@ The tuning procedure is: 14. 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) + - 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) - ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) + ![QGC PID tuning: Simple control selector](../../assets/mc_pid_tuning/qgc_mc_pid_tuning_simple_control.png) All done! Remember to re-enable airmode before leaving the setup. diff --git a/docs/zh/config_rover/basic_setup.md b/docs/zh/config_rover/basic_setup.md index 17aa6490bb..02a05b138a 100644 --- a/docs/zh/config_rover/basic_setup.md +++ b/docs/zh/config_rover/basic_setup.md @@ -27,10 +27,18 @@ That is the minimum setup to use the rover in [Manual mode](../flight_modes_rover/manual.md#manual-mode). +:::info +The rest of the tuning on this page is not mandatory for [Manual mode](../flight_modes_rover/manual.md#manual-mode), but it will have an effect on the behaviour of the rover. +::: + +:::warning +Do not skip the rest of this setup if you intend to use more sophisticated modes! +All parameters will be mandatory for all subsequent modes, except those tagged as `(Optional)`. +::: + ## Geometric Parameters -Manual mode is also affected by (optional) acceleration/deceleration limits set using the geometric described below. -These limits are mandatory for all other modes. +First, we set up the geometric parameters of the rover: ![Geometric parameters](../../assets/config/rover/geometric_parameters.png) @@ -42,7 +50,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and 2. [RA_MAX_STR_ANG](#RA_MAX_STR_ANG) [deg]: Measure the maximum steering angle. 3. (Optional) [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) [deg/s]: Maximum steering rate you want to allow for your rover. - :::tip + ::: tip This value depends on your rover and use case. For bigger rovers there might be a mechanical limit that is easy to identify by steering the rover at a standstill and increasing [RA_STR_RATE_LIM](#RA_STR_RATE_LIM) until you observe the steering rate to no longer be limited by the parameter. @@ -51,7 +59,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: - :::warning + ::: warning A low maximum steering rate makes the rover worse at tracking steering setpoints, which can lead to a poor performance in the subsequent modes. ::: @@ -85,7 +93,7 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and One approach to determine an appropriate value is: 1. From a standstill, give the rover full throttle until it reaches the maximum speed. - 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md). + 2. Disarm the rover and plot the `measured_speed_body_x` from [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md). 3. Divide the maximum speed by the time it took to reach it and set this as the value for [RO_ACCEL_LIM](#RO_ACCEL_LIM). Some RC rovers have enough torque to lift up if the maximum acceleration is not limited. @@ -109,6 +117,39 @@ Navigate to [Parameters](../advanced_config/parameters.md) in QGroundControl and ::: +## (Optional) Stick Input Mapping + +Input shaping can be used to adjust the default linear mapping from stick inputs $\in [-1, 1]$ to normalized setpoints $\in [-1, 1]$. Applying this specifically to the steering input, can provide a smoother driving experience, by enabling the user to make small adjustments when the stick is close to the center, but still send large inputs when moving them to the edges. +We provide this input shaping through the super exponential function: + +$$ +\delta = \frac{(f \cdot x^3 + x(1-f)) \cdot (1-g)}{1-g \cdot |x|} +$$ + +with: + +- $\delta \in [-1, 1]=$ Normalized steering setpoint. +- $x \in [-1, 1]=$ Normalized stick input. +- $f=$ [RO_YAW_EXPO](#RO_YAW_EXPO): `0` Purely linear input curve, `1` Purely cubic input curve. +- $g=$ [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO): `0` Pure Expo function, `0.7` reasonable shape enhancement for intuitive stick feel, `0.95` very strong bent input curve only near maxima have effect. + +In [Manual mode](../flight_modes_rover/manual.md#manual-mode) we can additionally scale $\delta$ with an additional parameter $r$: + +- Differential Rover: $r=$ [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN), [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)]. +- Mecanum Rover: $r=$ [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), which enables adjusting the slope of the input mapping. This leads to a normalized steering input $\hat{\delta} = \delta \cdot r \in$ [-[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN), [RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN)]. + +This scaling is useful to limit the normalized steering setpoint, if it is too aggresive for your rover in manual mode. + +You can experiment with the relationships graphically using the [PX4 SuperExpo Rover calculator](https://www.desmos.com/calculator/gwm8lrlanx). + +:::info +In [Acro](../flight_modes_rover/manual.md#acro-mode), [Stabilized](../flight_modes_rover/manual.md#stabilized-mode) and [Position](../flight_modes_rover/manual.md#position-mode) Mode, $\delta$ is instead scaled by $r=$ [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) for all rovers. This leads to a yaw rate setpoint $\dot{\psi} = \delta \cdot r \in$ [-[RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED), [RO_YAW_RATE_LIM](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED)]. This parameter is setup during [rate tuning](rate_tuning.md). +::: + +:::info +The input shaping through [RO_YAW_EXPO](#RO_YAW_EXPO) and [RO_YAW_SUPEXPO](#RO_YAW_SUPEXPO) applies for all manual modes, while [RD_YAW_STK_GAIN](#RD_YAW_STK_GAIN)/[RM_YAW_STK_GAIN](#RM_YAW_STK_GAIN) only affects full manual mode. +::: + You can now continue the configuration process with [rate tuning](rate_tuning.md). ## Parameter Overview @@ -118,6 +159,8 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md | [RO_MAX_THR_SPEED](../advanced_config/parameter_reference.md#RO_MAX_THR_SPEED) | Speed the rover drives at maximum throttle | $m/s$ | | [RO_ACCEL_LIM](../advanced_config/parameter_reference.md#RO_ACCEL_LIM) | (Optional) Maximum allowed acceleration | $m/s^2$ | | [RO_DECEL_LIM](../advanced_config/parameter_reference.md#RO_DECEL_LIM) | (Optional) Maximum allowed deceleration | $m/s^2$ | +| [RO_YAW_EXPO](../advanced_config/parameter_reference.md#RO_YAW_EXPO) | (Optional) Yaw rate expo factor | $-$ | +| [RO_YAW_SUPEXPO](../advanced_config/parameter_reference.md#RO_YAW_SUPEXPO) | (Optional) Yaw rate super expo factor | $-$ | ### Ackermann Specific @@ -129,12 +172,14 @@ You can now continue the configuration process with [rate tuning](rate_tuning.md ### Differential Specific -| 参数 | 描述 | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | m | +| 参数 | 描述 | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RD_WHEEL_TRACK](../advanced_config/parameter_reference.md#RD_WHEEL_TRACK) | Wheel track | $m$ | +| [RD_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RD_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | ### Mecanum Specific -| 参数 | 描述 | Unit | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | m | +| 参数 | 描述 | Unit | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---- | +| [RM_WHEEL_TRACK](../advanced_config/parameter_reference.md#RM_WHEEL_TRACK) | Wheel track | $m$ | +| [RM_YAW_STK_GAIN](../advanced_config/parameter_reference.md#RM_YAW_STK_GAIN) | (Optional) Yaw stick gain for Manual mode | $-$ | diff --git a/docs/zh/config_rover/index.md b/docs/zh/config_rover/index.md index 3dadee2f53..212839bc12 100644 --- a/docs/zh/config_rover/index.md +++ b/docs/zh/config_rover/index.md @@ -25,18 +25,18 @@ Rovers use a custom build that must be flashed onto your flight controller inste 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: - ```sh - make px4_fmu-v6x_rover - ``` + ```sh + make px4_fmu-v6x_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)): - ```sh - CONFIG_MODULES_ROVER_ACKERMANN=y - CONFIG_MODULES_ROVER_DIFFERENTIAL=y - CONFIG_MODULES_ROVER_MECANUM=y - ``` + ```sh + CONFIG_MODULES_ROVER_ACKERMANN=y + CONFIG_MODULES_ROVER_DIFFERENTIAL=y + CONFIG_MODULES_ROVER_MECANUM=y + ``` 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). diff --git a/docs/zh/config_rover/position_tuning.md b/docs/zh/config_rover/position_tuning.md index 61aeb14791..6d02346cd5 100644 --- a/docs/zh/config_rover/position_tuning.md +++ b/docs/zh/config_rover/position_tuning.md @@ -43,7 +43,7 @@ To tune the position controller configure the [parameters](../advanced_config/pa ::: -3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. +3. Plot the `adjusted_speed_body_x_setpoint` and `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. If the tracking of these setpoints is not satisfactory adjust the values for [RO_SPEED_P](../advanced_config/parameter_reference.md#RO_SPEED_P) and [RO_SPEED_I](../advanced_config/parameter_reference.md#RO_SPEED_I). ## Path Following @@ -133,11 +133,11 @@ $$ | Symbol | 描述 | Unit | | ----------------------------------- | ---------------------------------- | ---- | -| $\vec{a}$ | Vector from current to previous WP | m | -| $\vec{b}$ | Vector from current to next WP | m | -| $r_{min}$ | Minimum turn radius | m | -| $\delta_{max}$ | Maximum steer angle | m | -| $r_{acc}$ | Acceptance radius | m | +| $\vec{a}$ | Vector from current to previous WP | 米 | +| $\vec{b}$ | Vector from current to next WP | 米 | +| $r_{min}$ | Minimum turn radius | 米 | +| $\delta_{max}$ | Maximum steer angle | 米 | +| $r_{acc}$ | Acceptance radius | 米 | ## Differential Rover Only @@ -187,14 +187,14 @@ The position controller uses the following structure: | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---- | | [RO_SPEED_RED](../advanced_config/parameter_reference.md#RO_SPEED_RED) | (Optional) Tuning parameter for the speed reduction based on the course error | - | | [PP_LOOKAHD_GAIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_GAIN) | Pure pursuit: Main tuning parameter | - | -| [PP_LOOKAHD_MAX](../advanced_config/parameter_reference.md#PP_LOOKAHD_MAX) | Pure pursuit: Maximum value for the look ahead radius | m | -| [PP_LOOKAHD_MIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_MIN) | Pure pursuit: Minimum value for the look ahead radius | m | +| [PP_LOOKAHD_MAX](../advanced_config/parameter_reference.md#PP_LOOKAHD_MAX) | Pure pursuit: Maximum value for the look ahead radius | 米 | +| [PP_LOOKAHD_MIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_MIN) | Pure pursuit: Minimum value for the look ahead radius | 米 | ## Ackermann Specific | 参数 | 描述 | Unit | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ---- | -| [RA_ACC_RAD_MAX](../advanced_config/parameter_reference.md#RA_ACC_RAD_MAX) | (Optional) Maximum radius the acceptance radius can be scaled to | m | +| [RA_ACC_RAD_MAX](../advanced_config/parameter_reference.md#RA_ACC_RAD_MAX) | (Optional) Maximum radius the acceptance radius can be scaled to | 米 | | [RA_ACC_RAD_GAIN](../advanced_config/parameter_reference.md#RA_ACC_RAD_GAIN) | (Optional) Tuning parameter for the acceptance radius scaling | - | ## Differential Specific diff --git a/docs/zh/config_rover/velocity_tuning.md b/docs/zh/config_rover/velocity_tuning.md index cc265361d5..5796839ca3 100644 --- a/docs/zh/config_rover/velocity_tuning.md +++ b/docs/zh/config_rover/velocity_tuning.md @@ -28,7 +28,7 @@ To tune the velocity controller configure the following [parameters](../advanced 1. Set [RO_SPEED_P](#RO_SPEED_P) and [RO_SPEED_I](#RO_SPEED_I) to zero. This way the speed is only controlled by the feed-forward term, which makes it easier to tune. 2. Put the rover in [Position mode](../flight_modes_rover/manual.md#position-mode) and then move the left stick of your controller up and/or down and hold it at a few different levels for a couple of seconds each. - 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) message over each other. + 3. Disarm the rover and from the flight log plot the `adjusted_speed_body_x_setpoint` and the `measured_speed_body_x` from the [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) message over each other. 4. If the actual speed of the rover is higher than the speed setpoint, increase [RO_MAX_THR_SPEED](#RO_MAX_THR_SPEED). If it is the other way around decrease the parameter and repeat until you are satisfied with the setpoint tracking. @@ -94,7 +94,7 @@ These steps are only necessary if you are tuning/want to unlock the manual [Posi The rover is now ready to drive in [Position mode](../flight_modes_rover/manual.md#position-mode) and the configuration can be continued with [position tuning](position_tuning.md). -## Attitude Controller Structure (Info Only) +## Velocity Controller Structure (Info Only) This section provides additional information for developers and people with experience in control system design. @@ -129,5 +129,5 @@ Both these setpoint are then sent to their own closed loop speed controllers. | 参数 | 描述 | Unit | | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ---- | | [PP_LOOKAHD_GAIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_GAIN) | Pure pursuit: Main tuning parameter | - | -| [PP_LOOKAHD_MAX](../advanced_config/parameter_reference.md#PP_LOOKAHD_MAX) | Pure pursuit: Maximum value for the look ahead radius | m | -| [PP_LOOKAHD_MIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_MIN) | Pure pursuit: Minimum value for the look ahead radius | m | +| [PP_LOOKAHD_MAX](../advanced_config/parameter_reference.md#PP_LOOKAHD_MAX) | Pure pursuit: Maximum value for the look ahead radius | 米 | +| [PP_LOOKAHD_MIN](../advanced_config/parameter_reference.md#PP_LOOKAHD_MIN) | Pure pursuit: Minimum value for the look ahead radius | 米 | diff --git a/docs/zh/config_vtol/index.md b/docs/zh/config_vtol/index.md index fe5ff34801..24096ad139 100644 --- a/docs/zh/config_vtol/index.md +++ b/docs/zh/config_vtol/index.md @@ -9,3 +9,4 @@ Then perform VTOL-specific configuration and tuning: - [Back-transition Tuning](../config_vtol/vtol_back_transition_tuning.md) - [VTOL w/o Airspeed Sensor](../config_vtol/vtol_without_airspeed_sensor.md) - [VTOL Weather Vane](../config_vtol/vtol_weathervane.md) +- [Ice Shedding](../config_vtol/vtol_ice_shedding.md) diff --git a/docs/zh/config_vtol/vtol_ice_shedding.md b/docs/zh/config_vtol/vtol_ice_shedding.md new file mode 100644 index 0000000000..6884211c7b --- /dev/null +++ b/docs/zh/config_vtol/vtol_ice_shedding.md @@ -0,0 +1,22 @@ +# VTOL Ice Shedding feature + +## 综述 + +Ice shedding is a feature that periodically spins unused motors in fixed-wing +flight, to break off any ice that is starting to build up in the motors while it +is still feasible to do so. + +It is configured by the paramter `CA_ICE_PERIOD`. When it is 0, the feature is +disabled, when it is above 0, it sets the duration of the ice shedding cycle in +seconds. In each cycle, the rotors are spun for two seconds at a motor output of +0.01. + +:::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 + +::: diff --git a/docs/zh/config_vtol/vtol_quad_configuration.md b/docs/zh/config_vtol/vtol_quad_configuration.md index aa580ddc12..ecb9ce0df1 100644 --- a/docs/zh/config_vtol/vtol_quad_configuration.md +++ b/docs/zh/config_vtol/vtol_quad_configuration.md @@ -11,7 +11,7 @@ For airframe specific documentation and build instructions see [VTOL Framebuilds 2. Flash the firmware for your current release or master (PX4 `main` branch build). 3. In the [Frame setup](../config/airframe.md) section select the appropriate VTOL airframe. - If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. + If your airframe is not listed select the [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) frame. ### 飞行模式/模式转换 diff --git a/docs/zh/contribute/code.md b/docs/zh/contribute/code.md index 386458a6f0..793a629099 100644 --- a/docs/zh/contribute/code.md +++ b/docs/zh/contribute/code.md @@ -34,7 +34,7 @@ If you update an existing file you are not required to make the whole file compl ### Line Length -- Maximum line length is 120 characters. +- Maximum line length is 140 characters. ### File Extensions diff --git a/docs/zh/contribute/docs.md b/docs/zh/contribute/docs.md index bbaa75151e..91805dff44 100644 --- a/docs/zh/contribute/docs.md +++ b/docs/zh/contribute/docs.md @@ -63,33 +63,33 @@ The instructions below explain how to get git and use it on your local computer. 4. Clone (copy) your forked repository to your local computer: - ```sh - cd ~/wherever/ - git clone https://github.com//PX4-Autopilot.git - ``` + ```sh + cd ~/wherever/ + git clone https://github.com//PX4-Autopilot.git + ``` - For example, to clone PX4 source fork for a user with Github account "john_citizen": + For example, to clone PX4 source fork for a user with Github account "john_citizen": - ```sh - git clone https://github.com/john_citizen/PX4-Autopilot.git - ``` + ```sh + git clone https://github.com/john_citizen/PX4-Autopilot.git + ``` 5. Navigate to your local repository: - ```sh - cd ~/wherever/PX4-Autopilot - ``` + ```sh + cd ~/wherever/PX4-Autopilot + ``` 6. Add a _remote_ called "upstream" to point to the "official" PX4 version of the library: - ```sh - git remote add upstream https://github.com/PX4/PX4-Autopilot.git - ``` + ```sh + git remote add upstream https://github.com/PX4/PX4-Autopilot.git + ``` - :::tip - A "remote" is a handle to a particular repository. - The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. - Above you create a new remote _upstream_ that points to the PX4 project version of the documents. + :::tip + A "remote" is a handle to a particular repository. + The remote named _origin_ is created by default when you clone the repository, and points to _your fork_ of the guide. + Above you create a new remote _upstream_ that points to the PX4 project version of the documents. ::: @@ -99,111 +99,111 @@ Within the repository you created above: 1. Bring your copy of the repository `main` branch up to date: - ```sh - git checkout main - git fetch upstream main - git pull upstream main - ``` + ```sh + git checkout main + git fetch upstream main + git pull upstream main + ``` 2. Create a new branch for your changes: - ```sh - git checkout -b - ``` + ```sh + git checkout -b + ``` - This creates a local branch on your computer named `your_feature_branch_name`. + This creates a local branch on your computer named `your_feature_branch_name`. 3. Make changes to the documentation as needed (general guidance on this in following sections) 4. Once you are satisfied with your changes, you can add them to your local branch using a "commit": - ```sh - git add - git commit -m "" - ``` + ```sh + git add + git commit -m "" + ``` - For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. + For a good commit message, please refer to the [Source Code Management](../contribute/code.md#commits-and-commit-messages) section. 5. Push your local branch (including commits added to it) to your forked repository on Github. - ```sh - git push origin your_feature_branch_name - ``` + ```sh + git push origin your_feature_branch_name + ``` 6. Go to your forked repository on Github in a web browser, e.g.: `https://github.com//PX4-Autopilot.git`. - There you should see the message that a new branch has been pushed to your forked repository. + There you should see the message that a new branch has been pushed to your forked repository. 7. Create a pull request (PR): - - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". - Press it. - - A pull request template will be created. - It will list your commits and you can (must) add a meaningful title (in case of a one commit PR, it's usually the commit message) and message (explain what you did for what reason. - Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). - - Add the "Documentation" label. + - On the right hand side of the "new branch message" (see one step before), you should see a green button saying "Compare & Create Pull Request". + Press it. + - A pull request template will be created. + It will list your commits and you can (must) add a meaningful title (in case of a one commit PR, it's usually the commit message) and message (explain what you did for what reason. + Check [other pull requests](https://github.com/PX4/PX4-Autopilot/pulls) for comparison). + - Add the "Documentation" label. 8. You're done! - Maintainers for the PX4 User Guide will now have a look at your contribution and decide if they want to integrate it. - Check if they have questions on your changes every once in a while. + Maintainers for the PX4 User Guide will now have a look at your contribution and decide if they want to integrate it. + Check if they have questions on your changes every once in a while. ### Gitbook Documentation Toolchain 概述: 1. Install the [Vitepress prerequisites](https://vitepress.dev/guide/getting-started#prerequisites): - - [Nodejs 18+](https://nodejs.org/en) - - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) + - [Nodejs 18+](https://nodejs.org/en) + - [Yarn classic](https://classic.yarnpkg.com/en/docs/install) 2. Navigate to your local repository and the `/docs` subdirectory: - ```sh - cd ~/wherever/PX4-Autopilot/docs - ``` + ```sh + cd ~/wherever/PX4-Autopilot/docs + ``` 3. Install dependencies (including Vitepress): - ```sh - yarn install - ``` + ```sh + yarn install + ``` 4. Preview and serve the library: - ```sh - yarn start - ``` + ```sh + yarn start + ``` - - Once the development/preview server has built the library (less than a minute for the first time) it will show you the URL you can preview the site on. - This will be something like: `http://localhost:5173/px4_user_guide/`. - - Stop serving using **CTRL+C** in the terminal prompt. + - Once the development/preview server has built the library (less than a minute for the first time) it will show you the URL you can preview the site on. + This will be something like: `http://localhost:5173/px4_user_guide/`. + - Stop serving using **CTRL+C** in the terminal prompt. 5. Open previewed pages in your local editor: - First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. - For example, you can enable VSCode as your default editor by entering: + First specify a local text editor file using the `EDITOR` environment variable, before calling `yarn start` to preview the library. + For example, you can enable VSCode as your default editor by entering: - - Windows: + - Windows: - ```sh - set EDITOR=code - ``` + ```sh + set EDITOR=code + ``` - - Linux: + - Linux: - ```sh - export EDITOR=code - ``` + ```sh + export EDITOR=code + ``` - The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). + The **Open in your editor** link at the bottom of each page will then open the current page in the editor (this replaces the _Open in GitHub_ link). 6. You can build the library as it would be done for deployment: - ```sh - # Ubuntu - yarn docs:build + ```sh + # Ubuntu + yarn docs:build - # Windows - yarn docs:buildwin - ``` + # Windows + yarn docs:buildwin + ``` :::tip Use `yarn start` to preview changes _as you make them_ (documents are updated and served very quickly). @@ -256,38 +256,38 @@ When you add a new page you must also add it to `en/SUMMARY.md`! ## 翻译 1. 图片 - - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. - Do not further nest folders. - - Put new image files in an appropriate nested sub-folder of `/assets/`. - Deeper nesting is allowed/encouraged. - - Use descriptive names for folders and files. - In particular, image filenames should describe what they contain (don't name as "image1.png") - - Use lower case filenames and separate words using underscores (`_`). + - Put new markdown files in an appropriate sub-folder of `/en/`, such as `/en/contribute/`. + Do not further nest folders. + - Put new image files in an appropriate nested sub-folder of `/assets/`. + Deeper nesting is allowed/encouraged. + - Use descriptive names for folders and files. + In particular, image filenames should describe what they contain (don't name as "image1.png") + - Use lower case filenames and separate words using underscores (`_`). 2. 内容: - - 将新文件放入相应的子文件夹 - - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). - - SVG files are preferred for diagrams. - PNG files are preferred over JPG for screenshots. + - 将新文件放入相应的子文件夹 + - New images should be created in a sub-folder of `/assets/` (so they can be shared between translations). + - SVG files are preferred for diagrams. + PNG files are preferred over JPG for screenshots. 3. Content: - - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). - - **Bold** for button presses and menu definitions. - - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. - - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. - - Headings and page titles should use "First Letter Capitalisation". - - The page title should be a first level heading (`#`). - All other headings should be h2 (`##`) or lower. - - Don't add any style to headings. - - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. - - Break lines on sentences by preference. - Don't break lines based on some arbitrary line length. - - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). + - Use "style" (**bold**, _emphasis_, etc.) consistently and sparingly (as little as possible). + - **Bold** for button presses and menu definitions. + - _Emphasis_ for tool names such as _QGroundControl_ or _prettier_. + - `code` for file paths, and code, parameter names that aren't linked, using tools in a command line, such as `prettier`. + - Headings and page titles should use "First Letter Capitalisation". + - The page title should be a first level heading (`#`). + All other headings should be h2 (`##`) or lower. + - Don't add any style to headings. + - Don't translate the text indicating the name of an `info`, `tip` or `warning` declaration (e.g. `::: tip`) as this precise text is required to render the aside properly. + - Break lines on sentences by preference. + Don't break lines based on some arbitrary line length. + - Format using _prettier_ (_VSCode_ is a has extensions can be used for this). 4. Videos: - - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). - - Use instructional videos sparingly as they date badly, and are hard to maintain. - - Cool videos of airframes in flight are always welcome. + - Youtube videos can be added using the format `` (supported via the [https://www.npmjs.com/package/lite-youtube-embed](https://www.npmjs.com/package/lite-youtube-embed) custom element, which has other parameters you can pass). + - Use instructional videos sparingly as they date badly, and are hard to maintain. + - Cool videos of airframes in flight are always welcome. ## 许可证 diff --git a/docs/zh/contribute/git_examples.md b/docs/zh/contribute/git_examples.md index 5fd7c15f6e..328d3e11c1 100644 --- a/docs/zh/contribute/git_examples.md +++ b/docs/zh/contribute/git_examples.md @@ -109,23 +109,23 @@ To switch between branches: 1. Clean up the current branch, de-initializing submodule and removing all build artifacts: - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` 2. Switch to a new branch or tag (here we first fetch the fictional branch "PR_test_branch" from the `upstream` remote): - ```sh - git fetch upstream PR_test_branch - git checkout PR_test_branch - ``` + ```sh + git fetch upstream PR_test_branch + git checkout PR_test_branch + ``` 3. Get the submodules for the new branch: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` @@ -138,35 +138,35 @@ To get the source code for a _specific older release_ (tag): 1. Clone the PX4-Autopilot repo and navigate into _PX4-Autopilot_ directory: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + ``` - :::note + :::note - You can reuse an existing repo rather than cloning a new one. - In this case clean the build environment (see [changing source trees](#changing-source-trees)): + You can reuse an existing repo rather than cloning a new one. + In this case clean the build environment (see [changing source trees](#changing-source-trees)): - ```sh - make clean - make distclean - ``` + ```sh + make clean + make distclean + ``` ::: 2. Checkout code for particular tag (e.g. for tag v1.13.0-beta2) - ```sh - git checkout v1.13.0-beta2 - ``` + ```sh + git checkout v1.13.0-beta2 + ``` 3. Update submodules: - ```sh - make submodulesclean - ``` + ```sh + make submodulesclean + ``` ## Get a Release Branch diff --git a/docs/zh/data_links/index.md b/docs/zh/data_links/index.md index 8e2ee7e2df..03154f03ce 100644 --- a/docs/zh/data_links/index.md +++ b/docs/zh/data_links/index.md @@ -12,6 +12,6 @@ PX4 使用 [MAVLink](https://mavlink.io/en/) 协议在无线电频道上传送 - [TBS Crossfire (CRSF) Telemetry](../telemetry/crsf_telemetry.md) — TBS Crossfire 接收机上的遥测 - [Satellite Comms (Iridium/RockBlock)](../advanced_features/satcom_roadblock.md) — 高延迟卫星通信 -## See Also +## 另见 - [安全配置 > 数据连接丢失的失效保护](../config/safety.md#data-link-loss-failsafe) diff --git a/docs/zh/debug/asset_tracking.md b/docs/zh/debug/asset_tracking.md new file mode 100644 index 0000000000..c4bcdda67a --- /dev/null +++ b/docs/zh/debug/asset_tracking.md @@ -0,0 +1,68 @@ +# Asset Tracking + + + +PX4 can track and log detailed information about external hardware devices connected to the flight controller. +This enables unique identification of vehicle parts throughout their operational lifetime using device IDs, serial numbers, and version information. + +:::info +Asset tracking is currently implemented for [DroneCAN](../dronecan/index.md) devices only. +::: + +## 综述 + +Asset tracking allows you to determine exactly which hardware is installed on a vehicle, providing serial number, version, and other information. +This makes it easier to track and maintain specific vehicle parts across multiple vehicles, to quickly see what versions you're running when debugging, and log component information for regulatory audits. + +Asset tracking automatically collects and logs the following metadata from external devices: + +- **Device identification**: Vendor name, model name, device type +- **Version information**: Firmware version, hardware version +- **Unique identifiers**: Serial number, device ID +- **Device capabilities**: ESC, GPS, magnetometer, barometer, etc. + +This information is published via the [`device_information`](../msg_docs/DeviceInformation.md) uORB topic and logged to flight logs. +This enables fleet management, maintenance tracking, and troubleshooting. + +## Viewing Device Information + +### Real-Time Monitoring + +You can view device information in real-time using the [MAVLink Shell](../debug/mavlink_shell.md) or console: + +```sh +listener device_information +``` + +Example output for a CAN GPS module: + +```plain +TOPIC: device_information + device_information + timestamp: 16258961403 (0.216525 seconds ago) + device_id: 8944643 (Type: 0x88, UAVCAN:0 (0x7C)) + device_type: 5 + vendor_name: "cubepilot" + model_name: "here4" + firmware_version: "1.14.3006590" + hardware_version: "4.19" + serial_number: "1c00410018513331" +``` + +Device information is published in a round-robin fashion for each detected device, at a rate of approximately 1 Hz. + +### Multi-Capability Devices + +Devices with multiple sensors (e.g., a CAN GPS/magnetometer combo module like the HERE4) register separate device information entries for each capability. +Each entry shares the same serial number and base metadata but has a different `device_id` corresponding to the specific sensor capability. + +## 飞行日志分析 + +Device information is automatically logged to flight logs. +You can extract it using [pyulog](../log/flight_log_analysis.md#pyulog), though note that fields like vendor name, model name, and serial number are stored as `char` arrays and require additional parsing. + +## 另见 + +- [CAN (DroneCAN & Cyphal)](../can/index.md) — CAN bus configuration and setup +- [DroneCAN](../dronecan/index.md) — DroneCAN-specific documentation +- [Flight Log Analysis](../log/flight_log_analysis.md) — Flight log analysis diff --git a/docs/zh/debug/eclipse_jlink.md b/docs/zh/debug/eclipse_jlink.md index bf292df0e3..e23e23833d 100644 --- a/docs/zh/debug/eclipse_jlink.md +++ b/docs/zh/debug/eclipse_jlink.md @@ -53,17 +53,17 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal 7. Update packs: - Click the small icon on the top right called _Open Perspective_ and open the _Packs_ perspective. - ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) + ![Eclipse: Workspace](../../assets/debug/eclipse_workspace_perspective.png) - Click the **update all** button. - :::tip - This takes a VERY LONG TIME (10 minutes). - Ignore all the errors about missing packages that pop up. + :::tip + This takes a VERY LONG TIME (10 minutes). + Ignore all the errors about missing packages that pop up. ::: - ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) + ![Eclipse: Workspace Packs Perspective](../../assets/debug/eclipse_packs_perspective.jpg) - The STM32Fxx devices are found in the Keil folder, install by right-clicking and then selecting **install** on the according device for F4 and F7. @@ -79,24 +79,24 @@ For more information, see: [https://gnu-mcu-eclipse.github.io/debug/jlink/instal ![Eclipse: Debug config](../../assets/debug/eclipse_settings_debug_config.png) 10. Then select _GDB SEGGER J-Link Debugging_ and then the **New config** button on the top left. - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger.png) 11. Setup build config: - - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. - - Choose _Disable Auto build_ + - Give it a name and set the _C/C++ Application_ to the corresponding **.elf** file. + - Choose _Disable Auto build_ ::: info Remember that you must build the target from the command line before starting a debug session. ::: - ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) + ![Eclipse: GDB Segger Debug config](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config.png) 12. The _Debugger_ and _Startup_ tabs shouldn’t need any modifications (just verify your settings with the screenshots below) - ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) - ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) + ![Eclipse: GDB Segger Debug config: debugger tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_debugger_tab.png) + ![Eclipse: GDB Segger Debug config: startup tab](../../assets/debug/eclipse_settings_debug_config_gdb_segger_build_config_startup_tab.png) ## SEGGER Task-aware debugging @@ -109,16 +109,16 @@ To enable this feature for use in Eclipse: - Open a terminal in the root of your PX4-Autopilot source code - In the terminal, open `menuconfig` using the appropriate make target for the build. - This will be something like: + This will be something like: - ```sh - make px4_fmu-v5_default boardguiconfig - ``` + ```sh + make px4_fmu-v5_default boardguiconfig + ``` - (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). + (See [PX4 Menuconfig Setup](../hardware/porting_guide_config.md#px4-menuconfig-setup) for more information) on using the config tools). - Ensure that the _Enable TCBinfo struct for debug_ is selected as shown: - ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) + ![NuttX: Menuconfig: CONFIG_DEBUG_TCBINFO](../../assets/debug/nuttx_tcb_task_aware.png) 2. Compile the **jlink-nuttx.so** library in the terminal by running the following command in the terminal: `make jlink-nuttx` diff --git a/docs/zh/debug/failure_injection.md b/docs/zh/debug/failure_injection.md index 62db0208cc..f6889c2bb6 100644 --- a/docs/zh/debug/failure_injection.md +++ b/docs/zh/debug/failure_injection.md @@ -9,7 +9,7 @@ Failure injection is disabled by default, and can be enabled using the [SYS_FAIL Failure injection still in development. At time of writing (PX4 v1.14): -- It can only be used in simulation (support for both failure injection in real flight is planned). +- Support may vary by failure type and between simulatiors and real vehicle. - It requires support in the simulator. It is supported in Gazebo Classic - Many failure types are not broadly implemented. @@ -19,7 +19,7 @@ At time of writing (PX4 v1.14): ## Failure System Command -Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 console/shell, specifying both the target and type of the failure. +Failures can be injected using the [failure system command](../modules/modules_command.md#failure) from any PX4 [console/shell](../debug/consoles.md) (such as the [QGC MAVLink Console](../debug/mavlink_shell.md#qgroundcontrol-mavlink-console) or SITL _pxh shell_), specifying both the target and type of the failure. ### Syntax @@ -33,52 +33,68 @@ where: - _component_: - 传感器: - - `gyro`: Gyro. - - `accel`: Accelerometer. + - `gyro`: Gyroscope + - `accel`: Accelerometer - `mag`: Magnetometer - `baro`: Barometer - - `gps`: GPS + - `gps`: Global navigation satellite system - `optical_flow`: Optical flow. - - `vio`: Visual inertial odometry. + - `vio`: Visual inertial odometry - `distance_sensor`: Distance sensor (rangefinder). - - `airspeed`: Airspeed sensor. + - `airspeed`: Airspeed sensor - Systems: - - `battery`: Battery. - - `motor`: Motor. - - `servo`: Servo. - - `avoidance`: Avoidance. - - `rc_signal`: RC Signal. - - `mavlink_signal`: MAVLink signal (data telemetry). + - `battery`: Battery + - `motor`: Motor + - `servo`: Servo + - `avoidance`: Avoidance + - `rc_signal`: RC Signal + - `mavlink_signal`: MAVLink data telemetry connection - _failure_type_: - - `ok`: Publish as normal (Disable failure injection). - - `off`: Stop publishing. - - `stuck`: Report same value every time (_could_ indicate a malfunctioning sensor). - - `garbage`: Publish random noise. This looks like reading uninitialized memory. - - `wrong`: Publish invalid values (that still look reasonable/aren't "garbage"). - - `slow`: Publish at a reduced rate. - - `delayed`: Publish valid data with a significant delay. - - `intermittent`: Publish intermittently. + - `ok`: Publish as normal (Disable failure injection) + - `off`: Stop publishing + - `stuck`: Constantly report the same value which _can_ happen on a malfunctioning sensor + - `garbage`: Publish random noise. This looks like reading uninitialized memory + - `wrong`: Publish invalid values that still look reasonable/aren't "garbage" + - `slow`: Publish at a reduced rate + - `delayed`: Publish valid data with a significant delay + - `intermittent`: Publish intermittently - _instance number_ (optional): Instance number of affected sensor. 0 (default) indicates all sensors of specified type. -### Example - -To simulate losing RC signal without having to turn off your RC controller: - -1. Enable the parameter [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN). -2. Enter the following commands on the MAVLink console or SITL _pxh shell_: - - ```sh - # Fail RC (turn publishing off) - failure rc_signal off - - # Restart RC publishing - failure rc_signal ok - ``` - ## MAVSDK Failure Plugin The [MAVSDK failure plugin](https://mavsdk.mavlink.io/main/en/cpp/api_reference/classmavsdk_1_1_failure.html) can be used to programmatically inject failures. It is used in [PX4 Integration Testing](../test_and_ci/integration_testing_mavsdk.md) to simulate failure cases (for example, see [PX4-Autopilot/test/mavsdk_tests/autopilot_tester.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/test/mavsdk_tests/autopilot_tester.cpp)). The plugin API is a direct mapping of the failure command shown above, with a few additional error signals related to the connection. + +## Example: RC signal + +To simulate losing RC signal without having to turn off your RC controller: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Fail RC (turn publishing off) + failure rc_signal off + + # Restart RC publishing + failure rc_signal ok + ``` + +## Example: Motor + +To stop a motor mid-flight without the system anticipating it or excluding it from allocation effectiveness: + +1. Enable the [SYS_FAILURE_EN](../advanced_config/parameter_reference.md#SYS_FAILURE_EN) parameter. +2. Enable [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) parameter to allow turning off motors. +3. Enter the following commands on the MAVLink console or SITL _pxh shell_: + + ```sh + # Turn off first motor + failure motor off -i 1 + + # Turn it back on + failure motor ok -i 1 + ``` diff --git a/docs/zh/dev_airframes/adding_a_new_frame.md b/docs/zh/dev_airframes/adding_a_new_frame.md index 6681de2605..6bc2662d6d 100644 --- a/docs/zh/dev_airframes/adding_a_new_frame.md +++ b/docs/zh/dev_airframes/adding_a_new_frame.md @@ -37,8 +37,8 @@ Alternatively you can just append the modified parameters to the startup configu To add a frame configuration to firmware: 1. Create a new config file in the [init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) folder. - - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). - - Update the file with configuration parameters and apps (see section above). + - Give it a short descriptive filename and prepend the filename with an unused autostart ID (for example, `1033092_superfast_vtol`). + - Update the file with configuration parameters and apps (see section above). 2. Add the name of the new frame config file to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt) in the relevant section for the type of vehicle. 3. [Build and upload](../dev_setup/building_px4.md) the software. @@ -292,37 +292,37 @@ If the airframe is for a **new group** you additionally need to: 2. Add a mapping between the new group name and image filename in the [srcparser.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/px4airframes/srcparser.py) method `GetImageName()` (follow the pattern below): - ```python - def GetImageName(self): - """ - Get parameter group image base name (w/o extension) - """ - if (self.name == "Standard Plane"): - return "Plane" - elif (self.name == "Flying Wing"): - return "FlyingWing" - ... - ... - return "AirframeUnknown" - ``` + ```python + def GetImageName(self): + """ + Get parameter group image base name (w/o extension) + """ + if (self.name == "Standard Plane"): + return "Plane" + elif (self.name == "Flying Wing"): + return "FlyingWing" + ... + ... + return "AirframeUnknown" + ``` 3. 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: + - 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: - ```xml - - ... - src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg - src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg - src/AutoPilotPlugins/Common/Images/Boat.svg - src/AutoPilotPlugins/Common/Images/FlyingWing.svg - ... - ``` + ```xml + + ... + src/AutoPilotPlugins/Common/Images/AirframeSimulation.svg + src/AutoPilotPlugins/Common/Images/AirframeUnknown.svg + src/AutoPilotPlugins/Common/Images/Boat.svg + src/AutoPilotPlugins/Common/Images/FlyingWing.svg + ... + ``` - ::: info - The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). + ::: info + The remaining airframe metadata should be automatically included in the firmware (once **srcparser.py** is updated). ::: diff --git a/docs/zh/dev_log/log_encryption.md b/docs/zh/dev_log/log_encryption.md index be7cba82e7..bc4380f471 100644 --- a/docs/zh/dev_log/log_encryption.md +++ b/docs/zh/dev_log/log_encryption.md @@ -30,7 +30,7 @@ If another algorithm is supported in future, the process is _likely_ to remain t The encryption process for each new ULog is: 1. A XChaCha20 symmetric key is generated and encrypted using an RSA2048 public key. - This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). + This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted"). 2. When a log is captured, the ULog data is encrypted with the unwrapped symmetric key and the resulting data is appended into the end of the `.ulge` file immediately after the wrapped key data. After the flight, the `.ulge` file containing both the wrapped symmetric key and the encrypted log data can be found on the SD card. @@ -356,26 +356,26 @@ This section explains how you might manually run the same steps as the script (s 2. Use OpenSSL to generate a RSA2048 private and public key: - ```sh - openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 - ``` + ```sh + openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 + ``` 3. Create a public key from this private key: - ```sh - # Convert private_key.pem to a DER file - openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der - # From the DER file, generate a public key in hex format, separated by commas - xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub - ``` + ```sh + # Convert private_key.pem to a DER file + openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der + # From the DER file, generate a public key in hex format, separated by commas + xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub + ``` 4. Copy the keys into the appropriate locations expected by the rest of the toolchain (as shown in previous section). 5. To use this key, modify your `.px4board` file to point `CONFIG_PUBLIC_KEY1` to the file location of `public_key.pub`. - ```sh - CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" - ``` + ```sh + CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub" + ``` ## Flight Review & Encrypted logs @@ -397,10 +397,10 @@ This can use logs that you have downloaded and decrypted yourself, or you can in 3. Add this key location into the server config file: `flight_review/app/config_default.ini`. - The line to add should look something like this (for the file above): + The line to add should look something like this (for the file above): - ```sh - ulge_private_key = ../private_key/private_key.pem - ``` + ```sh + ulge_private_key = ../private_key/private_key.pem + ``` 4. Follow the Flight Review Instructions to start your server. diff --git a/docs/zh/dev_log/logging.md b/docs/zh/dev_log/logging.md index 44af24829b..36bb608f46 100644 --- a/docs/zh/dev_log/logging.md +++ b/docs/zh/dev_log/logging.md @@ -33,16 +33,17 @@ 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. -| 参数 | 描述 | -| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [SDLOG_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | 日志模式 Defines when logging starts and stops.
- `-1`: Logging disabled.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `4`: Log from first armed until shutdown. | -| [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".
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_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | 日志模式 Defines when logging starts and stops.
- `0`: Log when armed until disarm (default).
- `1`: Log from boot until disarm.
- `2`: Log from boot until shutdown.
- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).
- `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.
- bit `0`: SD card logging.
- 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".
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: - Raw sensor data for comparison: [SDLOG_MODE=1](../advanced_config/parameter_reference.md#SDLOG_MODE) and [SDLOG_PROFILE=64](../advanced_config/parameter_reference.md#SDLOG_PROFILE). -- Disabling logging altogether: [SDLOG_MODE=`-1`](../advanced_config/parameter_reference.md#SDLOG_MODE) +- Disabling logging altogether: [SDLOG_BACKEND=`0`](../advanced_config/parameter_reference.md#SDLOG_BACKEND) ### Logger module @@ -160,7 +161,7 @@ There are different clients that support ulog streaming: - If log streaming does not start, make sure the `logger` is running (see above), and inspect the console output while starting. - If it still does not work, make sure that Mavlink 2 is used. Enforce it by setting MAV_PROTO_VER to 2. - Enforce it by setting `MAV_PROTO_VER` to 2. + `MAV_PROTO_VER` needs to be set to 2. - Log streaming uses a maximum of 70% of the configured MAVLink rate (`-r` parameter). 如果需要更大的速率,数据会丢失。 The currently used percentage can be inspected with `mavlink status` (1.8% is used in this example): @@ -185,6 +186,6 @@ There are different clients that support ulog streaming: Also make sure `txerr` stays at 0. Also make sure txerr stays at 0. If this goes up, either the NuttX sending buffer is too small, the physical link is saturated or the hardware is too slow to handle the data. -## See Also +## 另见 - [Encrypted logging](../dev_log/log_encryption.md) diff --git a/docs/zh/dev_log/ulog_file_format.md b/docs/zh/dev_log/ulog_file_format.md index 8467903fa6..87abd891fd 100644 --- a/docs/zh/dev_log/ulog_file_format.md +++ b/docs/zh/dev_log/ulog_file_format.md @@ -218,7 +218,7 @@ A key defined in the Information message must be unique. Meaning there must not | `char[value_len] ver_sw_branch` | git branch | "master" | | `uint32_t ver_sw_release` | 软件版本 (见下文) | 0x010401ff | | `char[value_len] sys_os_name` | 操作系统名称 | "Linux" | -| `char[value_len] sys_os_ve`r | 操作系统版本 (git 标签) | "9f82919" | +| `char[value_len] sys_os_ver` | 操作系统版本 (git 标签) | "9f82919" | | `uint32_t ver_os_release` | 操作系统版本 (见下文) | 0x010401ff | | `char[value_len] sys_toolchain` | 工具链名称 | "GNU GCC" | | `char[value_len] sys_toolchain_ver` | 工具链版本 | "6.2.1" | @@ -491,6 +491,7 @@ Since the Definitions and Data Sections use the same message header format, they - [replay module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/replay) - [hardfault_log module](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hardfault_log): append hardfault crash data. - [pyulog](https://github.com/PX4/pyulog): python, ULog reader and writer library with CLI scripts. + The project also has tools to convert ULog to rosbag and other formats. - [ulog_cpp](https://github.com/PX4/ulog_cpp): C++, ULog reader and writer library. - [FlightPlot](https://github.com/PX4/FlightPlot): Java, log plotter. - [MAVLink](https://github.com/mavlink/mavlink): Messages for ULog streaming via MAVLink (note that appending data is not supported, at least not for cut off messages). @@ -501,6 +502,7 @@ Since the Definitions and Data Sections use the same message header format, they - [ulogreader](https://github.com/maxsun/ulogreader): Javascript, ULog reader and parser outputs log in JSON object format. - [Foxglove](https://foxglove.dev): an integrated visualization and diagnosis tool for robotics data that supports ULog files. - [TypeScript ULog parser](https://github.com/foxglove/ulog): TypeScript, ULog reader that outputs JS objects. +- [yule_log](https://crates.io/crates/yule_log): A streaming ULog parser written in Rust. ## 文件格式版本历史 diff --git a/docs/zh/dev_setup/building_px4.md b/docs/zh/dev_setup/building_px4.md index 4f56b68641..ba27d4940a 100644 --- a/docs/zh/dev_setup/building_px4.md +++ b/docs/zh/dev_setup/building_px4.md @@ -2,12 +2,12 @@ 无论对于模拟器还是硬件目标设备,PX4固件可以在控制台或者IDE中从源码构建 -You need to build PX4 in order to use [simulators](../simulation/index.md), or if you want to modify PX4 and create a custom build. +若要使用[模拟器](../simulation/index.md),或需要修改PX4并创建自定义构建,则必须自行构建PX4。 如果您只想在实际硬件上试试 PX4,那么可以使用 QGroundControl[烧录预构建的二进制文件](../config/firmware.md)(无需跟着下面的指导)。 :::info 在跟着这些指导之前,你必须先为主机操作系统和目标硬件安装 [开发者工具链](../dev_setup/dev_env.md)。 -如果您在跟着这些步骤操作后有任何问题,请参阅下面的 [Troubleshooting](#troubleshooting)。 +如果您在跟着这些步骤操作后有任何问题,请参阅下面的 [故障排除](#troubleshooting)。 ::: ## 下载 PX4 源代码 @@ -20,12 +20,12 @@ PX4 源代码存储在 Github 上的 [PX4/PX4-Autopilot](https://github.com/PX4/ git clone https://github.com/PX4/PX4-Autopilot.git --recursive ``` -Note that you may already have done this when installing the [Developer Toolchain](../dev_setup/dev_env.md) +注意,您可能在[安装开发工具链](../dev_setup/dev_env.md)时已经完成了这项操作 :::info -This is all you need to do in order to get the latest code. -If needed you can also [get the source code specific to a particular release](../contribute/git_examples.md#get-a-specific-release). -[GIT Examples](../contribute/git_examples.md) provides a lot more information working with releases and contributing to PX4. +你只需要执行它就能够得到最新的代码。 +如果需要,您也可以[获取特定版本的源代码](../contribute/git_examples.md#get-a-specific-release)。 +[[GIT 示例](../contribute/git_examples.md) 提供了更多的信息,用于发布版本并对 PX4 作出贡献。 ::: ## 初次构建(使用模拟器) @@ -33,15 +33,15 @@ If needed you can also [get the source code specific to a particular release](.. 首先我们要用控制台环境来构建一个模拟器目标 这使我们能够在转移到真正的硬件和 IDE 之前验证系统设置。 -Navigate into the **PX4-Autopilot** directory and start [Gazebo SITL](../sim_gazebo_gz/index.md) using the following command: +导航到 **PX4-Autopilot** 目录并使用以下命令启动 [Gazebo SITL](../sim_gazebo_gz/index.md): ```sh make px4_sitl gz_x500 ``` :::details -If you installed Gazebo Classic -Start [Gazebo Classic SITL](../sim_gazebo_classic/index.md) using the following command: +如果您安装的是 Gazebo Classic +使用以下命令启动 [Gazebo SITL](../sim_gazebo_classic/index.md): ```sh make px4_sitl gazebo-classic @@ -51,11 +51,11 @@ make px4_sitl gazebo-classic 这将显示 PX4 控制台: -![PX4 Console](../../assets/toolchain/console_gazebo.png) +![PX4 控制台](../../assets/toolchain/console_gazebo.png) :::info -You may need to start _QGroundControl_ before proceeding, as the default PX4 configuration requires a ground control connection before takeoff. -This can be [downloaded from here](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html). +您可能需要在继续之前启动 _QGroundControl_ ,因为默认的 PX4 配置需要在起飞前进行地面控制连接。 +可以[从这里下载](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html)。 ::: 可以通过键入以下命令(如上方控制台中所示)来控制飞行器。 @@ -64,11 +64,11 @@ This can be [downloaded from here](https://docs.qgroundcontrol.com/master/en/qgc pxh> commander takeoff ``` -The vehicle will take off and you'll see this in the Gazebo simulator UI: +该载具将起飞,您将在 Gazebo simulator UI 中看到: -![Gazebo UI with vehicle taking off](../../assets/toolchain/gazebo_takeoff.png) +![Gazebo UI 载具起飞](../../assets/toolchain/gazebo_takeoff.png) -The drone can be landed by typing `commander land` and the whole simulation can be stopped by doing **CTRL+C** (or by entering `shutdown`). +无人机可以通过输入 `Commander land` 来着陆,整个模拟可以通过 **CTRL+C** (或输入 `shutdown` )来停止。 与地面站一起飞模拟器更接近飞机的实际运行。 在飞机飞行时(Takeoff飞行模式),单击地图上的某个位置并启用滑块。 @@ -80,9 +80,9 @@ The drone can be landed by typing `commander land` and the whole simulation can ### 为NuttX构建 -To build for NuttX- or Pixhawk- based boards, navigate into the **PX4-Autopilot** directory and then call `make` with the build target for your board. +若要构建基于NuttX-或 Pixhawk的飞控板,请导航到 **PX4-Autopilot** 目录,然后调用 `make` ,并为您的板调用构建目标。 -For example, to build for [Pixhawk 4](../flight_controller/pixhawk4.md) hardware you could use the following command: +例如,要为 [Pixhawk 4](../flight_controller/pixhawk4.md) 硬件构建,可使用以下命令: ```sh cd PX4-Autopilot @@ -96,15 +96,15 @@ make px4_fmu-v5_default [954/954] Creating /home/youruser/src/PX4-Autopilot/build/px4_fmu-v4_default/px4_fmu-v4_default.px4 ``` -The first part of the build target `px4_fmu-v4` indicates the target flight controller hardware for the firmware. -The suffix, in this case `_default`, indicates a firmware _configuration_, such as supporting or omitting particular features. +构建目标 `px4_fmu-v4` 的第一部分表示目标飞行控制器固件的硬件。 +后缀(此处为`_default`)表示固件的_配置_,例如支持或省略特定功能。 :::info -The `_default` suffix is optional. -For example, `make px4_fmu-v5` and `px4_fmu-v5_default` result in the same firmware. +`_default` 后缀是可选的。 +例如,`make px4_fmu-v5` 和 `px4_fmu-v5_default` 都会生成相同的固件。 ::: -The following list shows the build commands for the [Pixhawk standard](../flight_controller/autopilot_pixhawk_standard.md) boards: +以下列表显示了[Pixhawk标准](../flight_controller/autopilot_pixhawk_standard.md)飞行控制板的构建命令: - [Holybro Pixhawk 6X-RT (FMUv6X)](../flight_controller/pixhawk6x-rt.md): `make px4_fmu-v6xrt_default` @@ -134,7 +134,7 @@ The following list shows the build commands for the [Pixhawk standard](../flight - [Pixhawk 2 (Cube Black) (FMUv3)](../flight_controller/pixhawk-2.md): `make px4_fmu-v3_default` -- [mRo Pixhawk (FMUv3)](../flight_controller/mro_pixhawk.md): `make px4_fmu-v3_default` (supports 2MB Flash) +- [mRo Pixhawk (FMUv3)](../flight_controller/mro_pixhawk.md): `make px4_fmu-v3_default` (支持 2MB Flash) - [Holybro pix32 (FMUv2)](../flight_controller/holybro_pix32.md): `make px4_fmu-v2_default` @@ -145,17 +145,17 @@ The following list shows the build commands for the [Pixhawk standard](../flight - [Pixhawk 1 (FMUv2)](../flight_controller/pixhawk.md): `make px4_fmu-v2_default` :::warning - You **must** use a supported version of GCC to build this board (e.g. the same as used by [CI/docker](../test_and_ci/docker.md)) or remove modules from the build. Building with an unsupported GCC may fail, as PX4 is close to the board's 1MB flash limit. + 您**必须**使用受支持的GCC版本来构建此开发板(例如与[CI/docker](../test_and_ci/docker.md)中使用的相同版本),否则需从构建中移除相关模块。 使用不受支持的GCC进行构建可能会失败,因为PX4接近板载1MB闪存的容量限制。 ::: -- Pixhawk 1 with 2 MB flash: `make px4_fmu-v3_default` +- 具有 2 MB flash 的 Pixhawk 1: `make px4_fmu-v3_default` -Build commands for non-Pixhawk NuttX fight controllers (and for all other-boards) are provided in the documentation for the individual [flight controller boards](../flight_controller/index.md). +非 Pixhawk NuttX 飞控的构建命令(以及所有其他主板的命令)均在各款[飞控主板](../flight_controller/index.md)的文档中提供。 ### 将固件烧录到飞控板 -Append `upload` to the make commands to upload the compiled binary to the autopilot hardware via USB. +在 make 命令后添加 `upload`,通过USB将编译后的二进制文件上传至 autopilot 硬件。 例如 ```sh @@ -174,13 +174,13 @@ Rebooting. ``` :::tip -This is not supported when developing on WSL2. -See [ Windows Development Environment (WSL2-Based) > Flash a Control Board](../dev_setup/dev_env_windows_wsl.md#flash-a-flight-control-board). +在 WSL2 上开发时不支持此操作。 +参见[ Windows 开发环境 (WSL2-基于) > 烧录主板](../dev_setup/dev_env_windows_wsl.md#flash-a-flight-control-board)。 ::: ## 其他飞控板 -Build commands for other boards are given the [board-specific flight controller pages](../flight_controller/index.md) (usually under a heading _Building Firmware_). +其他主板的构建命令详见[各主板专属飞行控制器页面](../flight_controller/index.md)(通常位于_构建固件_标题下)。 您还可以使用以下命令列出所有配置目标: @@ -190,15 +190,15 @@ make list_config_targets ## 用图形界面 IDE 编译 -[VSCode](../dev_setup/vscode.md) is the officially supported (and recommended) IDE for PX4 development. -It is easy to set up and can be used to compile PX4 for both simulation and hardware environments. +[VSCode](../dev_setup/vscode.md是官方支持 (且推荐) 的 用于 PX4 开发的 IDE。 +它很容易设置,可以用于编译模拟和硬件环境的 PX4。 ## 故障处理 ### 常规构建错误 许多构建问题是由不匹配的子模块或未完全清理的构建环境引起的。 -Updating the submodules and doing a `distclean` can fix these kinds of errors: +更新子模块并进行 `distclean` 可以修复这些类型的错误: ```sh git submodule update --recursive @@ -207,11 +207,11 @@ make distclean ### 闪存溢出了 XXX 字节 -The `region 'flash' overflowed by XXXX bytes` error indicates that the firmware is too large for the target hardware platform. -This is common for `make px4_fmu-v2_default` builds, where the flash size is limited to 1MB. +`region 'flash' overflowed by XXXX bytes` 错误表明固件对目标硬件平台太大了。 +这对于`make px4_fmu-v2_default` 构建是常见的,它的 flash 大小被限制在 1MB。 -If you're building the _vanilla_ master branch, the most likely cause is using an unsupported version of GCC. -In this case, install the version specified in the [Developer Toolchain](../dev_setup/dev_env.md) instructions. +如果您正在构建_vanilla_master 分支,最可能的原因是使用不支持的 GCC版本。 +在这种情况下,安装[开发者工具链](../dev_setup/dev_env.md)说明中指定的版本。 如果在构建自己的分支,您可能已将固件大小增加到超过1MB的限制。 在这种情况下,您需要从构建中删除您不需要的任何驱动程序/模块。 @@ -221,16 +221,16 @@ In this case, install the version specified in the [Developer Toolchain](../dev_ MacOS 默认允许在所有正在运行的进程中最多打开256个文件。 PX4构建系统打开大量文件,因此您可能会超出此数量。 -The build toolchain will then report `Too many open files` for many files, as shown below: +构建工具链为很多文件报 `Too many open files`,如下所示: ```sh /usr/local/Cellar/gcc-arm-none-eabi/20171218/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: cannot find NuttX/nuttx/fs/libfs.a: Too many open files ``` 解决方案是增加允许打开文件的最大数量(例如增加到300)。 -You can do this in the macOS _Terminal_ for each session: +您可以在每个会话的 macOS _终端_ 中这样做: -- Run this script [Tools/mac_set_ulimit.sh](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/mac_set_ulimit.sh), or +- 运行此脚本 [Tools/mac_set_ulimit.sh](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/mac_set_ulimit.sh),或 - 运行这个命令: ```sh @@ -239,7 +239,7 @@ You can do this in the macOS _Terminal_ for each session: ### macOS Catalina:运行cmake时出现问题 -As of macOS Catalina 10.15.1 there may be problems when trying to build the simulator with _cmake_. +对于 macOS Catalina 10.15.1 ,在尝试使用 _cmake _ 构建模拟器时可能会遇到问题。 如果您在这个平台上遇到构建问题,请尝试在终端中运行以下命令: ```sh @@ -249,7 +249,7 @@ sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/* /us ### Ubuntu 18.04:涉及arm_none_eabi_gcc的编译错误 -Build issues related to `arm_none_eabi_gcc`may be due to a broken g++ toolchain installation. +与 arm_none_eabi_gcc 相关的构建问题可能是由于损坏的g++工具链安装引起的。 您可以通过检查缺少的依赖项来验证这一点: ```sh @@ -266,15 +266,15 @@ arm-none-eabi-gdb --version arm-none-eabi-gdb: command not found ``` -This can be resolved by removing and [reinstalling the compiler](https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa). +这个问题可以通过删除和[重新安装编译器](https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa)来解决。 ### Ubuntu 18.04:Visual Studio Code 无法监视此大型工作区中的文件更改 -See [Visual Studio Code IDE (VSCode) > Troubleshooting](../dev_setup/vscode.md#troubleshooting). +请参阅[Visual Studio 代码 IDE (VSCode) > 疑难解答](../dev_setup/vscode.md#troubleshooting)。 ### 导入Python软件包失败 -"Failed to import" errors when running the `make px4_sitl jmavsim` command indicates that some Python packages are not installed (where expected). +在运行 `make px4_sitl jmavsim` 命令时,“导入失败”错误表示某些Python 软件包未安装(如预期般安装)。 ```sh Failed to import jinja2: No module named 'jinja2' @@ -292,25 +292,25 @@ pip3 install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg ## PX4 创建生成目标 -The previous sections showed how you can call _make_ to build a number of different targets, start simulators, use IDEs etc. +前面的章节显示了您如何调用 _make_ 来构建一些不同的目标,启动模拟器,使用 IDE 等。 This section shows how _make_ options are constructed and how to find the available choices. -The full syntax to call _make_ with a particular configuration and initialization file is: +使用特定配置和初始化文件调用 _make_ 的完整语法是: ```sh make [VENDOR_][MODEL][_VARIANT] [VIEWER_MODEL_DEBUGGER_WORLD] ``` -**VENDOR_MODEL_VARIANT**: (also known as `CONFIGURATION_TARGET`) +**VENDOR_MODEL_VARIANT**: (也称为`CONFIGURATION_TARGET`) -- **VENDOR:** The manufacturer of the board: `px4`, `aerotenna`, `airmind`, `atlflight`, `auav`, `beaglebone`, `intel`, `nxp`, etc. - The vendor name for Pixhawk series boards is `px4`. -- **MODEL:** The _board model_ "model": `sitl`, `fmu-v2`, `fmu-v3`, `fmu-v4`, `fmu-v5`, `navio2`, etc. -- **VARIANT:** Indicates particular configurations: e.g. `bootloader`, `cyphal`, which contain components that are not present in the `default` configuration. - Most commonly this is `default`, and may be omitted. +- \*\*VENDOR:\*\*主板制造商:`px4`、`aerotenna`、`airmind`、`atlflight`、`auav`、`beaglebone`、`intel`、`nxp` 等。 + Pixhawk 系列主板的供应商名称为 `px4`。 +- \*\*MODEL:\*\*飞控板型号 “model”:`sitl`、`fmu-v2`、`fmu-v3`、`fmu-v4`、`fmu-v5`、`navio2` 等。 +- **VARIANT:** 指示特定的配置:例如`bootloader`, `cyphal`, 其中包含不存在于“默认”配置中的组件。 + 最常见的情况是 `default`, 并且可能被省略。 :::tip -You can get a list of _all_ available `CONFIGURATION_TARGET` options using the command below: +您可以使用下面的命令获取一个可用的`CONFIGURATION_TARGET`选项列表: ```sh make list_config_targets @@ -318,29 +318,29 @@ make list_config_targets ::: -**VIEWER_MODEL_DEBUGGER_WORLD:** +**VIEWER_MODEL_DEBUGER_WORLD:** -- **VIEWER:** This is the simulator ("viewer") to launch and connect: `gz`, `gazebo`, `jmavsim`, `none` +- **VIEWER:** 这是启动和连接的模拟器 ("查看器") : `gz`, `gzebo`, `jmavsim`, `none` :::tip - `none` can be used if you want to launch PX4 and wait for a simulator (jmavsim, Gazebo, Gazebo Classic, or some other simulator). - For example, `make px4_sitl none_iris` launches PX4 without a simulator (but with the iris airframe). + `none` 可以用于启动PX4并等待模拟器(jmavsim, Gazebo, Gazebo Classic, 或其他模拟器)。 + 例如,`make px4_sitl none_iris` 在没有模拟器的情况下启动 PX4 (但使用 iris 机架)。 ::: -- **MODEL:** The _vehicle_ model to use (e.g. `iris` (_default_), `rover`, `tailsitter`, etc), which will be loaded by the simulator. - The environment variable `PX4_SIM_MODEL` will be set to the selected model, which is then used in the [startup script](../simulation/index.md#startup-scripts) to select appropriate parameters. +- MODEL:要使用的 载具 模型(例如 iris (default)、rover、tailsitter 等),该模型将由模拟器加载。 + 环境变量 `PX4_SIM_MODEL` 将被设置为选中的模型,然后在[启动脚本](../simulation/index.md#startup-scripts)中使用以选择适当的参数。 -- **DEBUGGER:** Debugger to use: `none` (_default_), `ide`, `gdb`, `lldb`, `ddd`, `valgrind`, `callgrind`. - For more information see [Simulation Debugging](../debug/simulation_debugging.md). +- **DEBUGER:** 调试器使用: `none` (_default_), `ide`, `gdb`, `lldb`, `ddd`, `valgrind`, `callgrind`. + 更多信息请参阅[模拟调试](../debug/simulation_debugging.md)。 -- **WORLD:** (Gazebo Classic only). - Set the world ([PX4-Autopilot/Tools/simulation/gazebo-classic/sitl_gazebo-classic/worlds](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/main/worlds)) that is loaded. - Default is [empty.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/empty.world). - For more information see [Gazebo Classic > Loading a Specific World](../sim_gazebo_classic/index.md#loading-a-specific-world). +- **WORLD**: (仅限Gazebo Classic). + 设置加载的世界([PX4-Autopilot/Tools/simulation/gazebo-classic/sitl_gazebo-classic/worlds](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/main/worlds))。 + 默认为 [empty.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/empty.world)。 + 欲了解更多信息,请参阅[Gazebo Classic > 加载特定世界](../sim_gazebo_classic/index.md#loading-a-specific-world)。 :::tip -You can get a list of _all_ available `VIEWER_MODEL_DEBUGGER_WORLD` options using the command below: +您可以使用下面的命令获取_所有_可用的选项: `VIEWER_MODEBUGER_WORLD` ```sh make px4_sitl list_vmd_make_targets @@ -350,33 +350,33 @@ make px4_sitl list_vmd_make_targets ::: info -- Most of the values in the `CONFIGURATION_TARGET` and `VIEWER_MODEL_DEBUGGER` have defaults, and are hence optional. - For example, `gazebo-classic` is equivalent to `gazebo-classic_iris` or `gazebo-classic_iris_none`. +- `CONFIGURATION_TARGET`和`VIEWER_MODEBUGER`中的大多数值都有默认值,因此是可选的。 + 例如,`gazebo-classic`等于`gazebo-classic_iris`或`gazebo-classic_iris_none`。 - 如果要在其他两个设置之间指定默认值,可以使用三个下划线。 - For example, `gazebo-classic___gdb` is equivalent to `gazebo-classic_iris_gdb`. -- You can use a `none` value for `VIEWER_MODEL_DEBUGGER` to start PX4 and wait for a simulator. - For example start PX4 using `make px4_sitl_default none` and jMAVSim using `./Tools/simulation/jmavsim/jmavsim_run.sh -l`. + 例如,`gazebo-classic___gdb`相当于`gazebo-classic_iris_gdb`。 +- 你可以使用 "none" 值为 "VIEWER_MODEBUGER" 来启动 PX4 并等待模拟器。 + 例如,使用 `make px4_sitl_default none` 和 jMAVSim 使用 `./Tools/simulation/jmavsim/jmavsim_run.sh -l` 启动 PX4。 ::: -The `VENDOR_MODEL_VARIANT` options map to particular _px4board_ configuration files in the PX4 source tree under the [/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards) directory. -Specifically `VENDOR_MODEL_VARIANT` maps to a configuration file **boards/VENDOR/MODEL/VARIANT.px4board** -(e.g. `px4_fmu-v5_default` corresponds to [boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board)). +`VENDOR_MODEL_VARIANT`选项映射为 [/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards) 目录下的 PX4 源树中的特殊_px4board_ 配置文件。 +具体而言,`VENDOR_MODEL_VARIANT` 映射到配置文件 **boards/VENDOR/MODEL/VARIANT.px4board** +(例如 `px4_fmu-v5_default` 对应 [boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board))。 其他 make 目标在相关章节中讨论: -- `bloaty_compare_master`: [Binary Size Profiling](../debug/binary_size_profiling.md) +- `bloaty_compare_master`:[二进制大小分析](../debug/binary_size_profiling.md) - ... -## Firmware Version & Git Tags +## 固件版本和 Git 标签 -The _PX4 Firmware Version_ and _Custom Firmware Version_ are published using the MAVLink [AUTOPILOT_VERSION](https://mavlink.io/en/messages/common.html#AUTOPILOT_VERSION) message, and displayed in the _QGroundControl_ **Setup > Summary** airframe panel: +_PX4固件版本_和_自定义固件版本_通过 MAVLink [AUTOPILOT_VERSION](https://mavlink.io/en/messages/common.html#AUTOPILOT_VERSION)消息发布,并在_QGroundControl_的**设置 > 摘要**机身面板中显示: -![Firmware info](../../assets/gcs/qgc_setup_summary_airframe_firmware.jpg) +![固件信息](../../assets/gcs/qgc_setup_summary_airframe_firmware.jpg) -These are extracted at build time from the active _git tag_ for your repo tree. -The git tag should be formatted as `-` (e.g. the tag in the image above was set to `v1.8.1-2.22.1`). +这些是在构建时从您仓库树的活动_gi tag_中提取的。 +git 标签应该格式化为 `-` (例如上面图像中的标签被设置为 `v1.8.1-2.22.1`)。 :::warning -If you use a different git tag format, versions information may not be displayed properly. +如果您使用不同的 git 标签格式,可能无法正确显示版本信息。 ::: diff --git a/docs/zh/dev_setup/config_initial.md b/docs/zh/dev_setup/config_initial.md index 32a4b51e77..dd6cdf1e6a 100644 --- a/docs/zh/dev_setup/config_initial.md +++ b/docs/zh/dev_setup/config_initial.md @@ -1,4 +1,4 @@ -# Initial Setup & Configuration +# 初始配置 我们建议开发者们获取下文描述的基本配置的硬件设备(或者相似的设备)并使用"默认" 机架 构型。 diff --git a/docs/zh/dev_setup/dev_env.md b/docs/zh/dev_setup/dev_env.md index fadf7c8dca..b53b801540 100644 --- a/docs/zh/dev_setup/dev_env.md +++ b/docs/zh/dev_setup/dev_env.md @@ -2,15 +2,15 @@ The _supported platforms_ for PX4 development are: -- [Ubuntu Linux (22.04/20.04/18.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended +- [Ubuntu Linux (24.04/22.04)](../dev_setup/dev_env_linux_ubuntu.md) — Recommended - [Windows (10/11)](../dev_setup/dev_env_windows_wsl.md) — via WSL2 -- [Mac OS](../dev_setup/dev_env_mac.md) +- [macOS](../dev_setup/dev_env_mac.md) ## 支持的编译目标 下表显示了您可以在每个操作系统上构建何种 PX平台的固件编译。 -| 平台 | Linux (Ubuntu) | Mac | Windows | +| 平台 | 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) | ✓ | | | diff --git a/docs/zh/dev_setup/dev_env_linux_ubuntu.md b/docs/zh/dev_setup/dev_env_linux_ubuntu.md index 3c01f2f634..85e5d3670e 100644 --- a/docs/zh/dev_setup/dev_env_linux_ubuntu.md +++ b/docs/zh/dev_setup/dev_env_linux_ubuntu.md @@ -33,24 +33,24 @@ To install the toolchain: 1. [Download PX4 Source Code](../dev_setup/building_px4.md): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 2. Run the **ubuntu.sh** with no arguments (in a bash shell) to install everything: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - - 在安装过程中确认并通过所有的提示。 - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - 在安装过程中确认并通过所有的提示。 + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. 3. If you need Gazebo Classic (Ubuntu 22.04 only) then you can manually remove Gazebo and install it by following the instructions in [Gazebo Classic > Installation](../sim_gazebo_classic/index.md#installation). diff --git a/docs/zh/dev_setup/dev_env_mac.md b/docs/zh/dev_setup/dev_env_mac.md index f379cceb75..4c52a89da8 100644 --- a/docs/zh/dev_setup/dev_env_mac.md +++ b/docs/zh/dev_setup/dev_env_mac.md @@ -1,4 +1,4 @@ -# Mac 上的开发环境 +# macOS Development Environment MacOS 是受支持的 PX4 开发平台。 根据本文的指示构建的开发环境可以用编译: @@ -22,8 +22,8 @@ The "base" macOS setup installs the tools needed for building firmware, and incl ### Environment Setup :::details -Apple Silicon Macbook users! -If you have an Apple M1, M2 etc. Macbook, make sure to run the terminal as x86 by setting up an x86 terminal: +Apple Silicon MacBook users! +If you have an Apple M1, M2 etc. MacBook, make sure to run the terminal as x86 by setting up an x86 terminal: 1. Locate the Terminal application within the Utilities folder (**Finder > Go menu > Utilities**) 2. Select _Terminal.app_ and right-click on it, then choose **Duplicate**. @@ -38,21 +38,21 @@ First set up the environment 1. Enable more open files by appending the following line to the `~/.zshenv` file (creating it if necessary): - ```sh - echo ulimit -S -n 2048 >> ~/.zshenv - ``` + ```sh + echo ulimit -S -n 2048 >> ~/.zshenv + ``` - ::: info - If you don't do this, the build toolchain may report the error: `"LD: too many open files"` + ::: info + If you don't do this, the build toolchain may report the error: `"LD: too many open files"` ::: 2. Enforce Python 3 by appending the following lines to `~/.zshenv` - ```sh - # Point pip3 to MacOS system python 3 pip - alias pip3=/usr/bin/pip3 - ``` + ```sh + # Point pip3 to macOS system python 3 pip + alias pip3=/usr/bin/pip3 + ``` ### Common Tools @@ -62,19 +62,19 @@ To setup the environment to be able to build for Pixhawk/NuttX hardware (and ins 2. Run these commands in your shell to install the common tools: - ```sh - brew tap PX4/px4 - brew install px4-dev - ``` + ```sh + brew tap PX4/px4 + brew install px4-dev + ``` 3. Install the required Python packages: - ```sh - # install required packages using pip3 - python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - # if this fails with a permissions error, your Python install is in a system path - use this command instead: - sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema - ``` + ```sh + # install required packages using pip3 + python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + # if this fails with a permissions error, your Python install is in a system path - use this command instead: + sudo -H python3 -m pip install --user pyserial empty toml numpy pandas jinja2 pyyaml pyros-genmsg packaging kconfiglib future jsonschema + ``` ## Gazebo Classic 模拟 @@ -82,35 +82,35 @@ To setup the environment for [Gazebo Classic](../sim_gazebo_classic/index.md) si 1. Run the following commands in your shell: - ```sh - brew unlink tbb - sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb - brew install tbb@2020 - brew link tbb@2020 - ``` + ```sh + brew unlink tbb + sed -i.bak '/disable! date:/s/^/ /; /disable! date:/s/./#/3' $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/tbb@2020.rb + brew install tbb@2020 + brew link tbb@2020 + ``` - ::: info - September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). - They can be removed once it is fixed (along with this note). + ::: info + September 2021: The commands above are a workaround to this bug: [PX4-Autopilot#17644](https://github.com/PX4/PX4-Autopilot/issues/17644). + They can be removed once it is fixed (along with this note). ::: 2. To install SITL simulation with Gazebo Classic: - ```sh - brew install --cask temurin - brew install --cask xquartz - brew install px4-sim-gazebo - ``` + ```sh + brew install --cask temurin + brew install --cask xquartz + brew install px4-sim-gazebo + ``` 3. Run the macOS setup script: `PX4-Autopilot/Tools/setup/macos.sh` - The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: + The easiest way to do this is to clone the PX4 source, and then run the script from the directory, as shown: - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - cd PX4-Autopilot/Tools/setup - sh macos.sh - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + cd PX4-Autopilot/Tools/setup + sh macos.sh + ``` ## Gazebo dependencies diff --git a/docs/zh/dev_setup/dev_env_windows_cygwin_packager_setup.md b/docs/zh/dev_setup/dev_env_windows_cygwin_packager_setup.md index fef641a137..1e69010fb9 100644 --- a/docs/zh/dev_setup/dev_env_windows_cygwin_packager_setup.md +++ b/docs/zh/dev_setup/dev_env_windows_cygwin_packager_setup.md @@ -135,31 +135,31 @@ The toolchain gets maintained and hence these instructions might not cover every 10. Download [**Apache Ant**](https://ant.apache.org/bindownload.cgi) as zip archive of the binaries for Windows and unpack the content to the folder `C:\PX4\toolchain\apache-ant`. - :::tip - Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. + :::tip + Make sure you don't have an additional folder layer from the folder which is inside the downloaded archive. ::: - ::: info - This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). + ::: info + This is what the toolchain does in: [apache-ant/install-apache-ant.bat](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/apache-ant/install-apache-ant.bat). ::: 11. Download, build and add _genromfs_ to the path: - - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with + - Clone the source code to the folder **C:\PX4\toolchain\genromfs\genromfs-src** with ```sh cd /c/toolchain/genromfs git clone https://github.com/chexum/genromfs.git genromfs-src ``` - - Compile it with: + - Compile it with: ```sh cd genromfs-src make all ``` - - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** + - Copy the resulting binary **genromfs.exe** one folder level out to: **C:\PX4\toolchain\genromfs** 12. Make sure all the binary folders of all the installed components are correctly listed in the `PATH` variable configured by [**setup-environment.bat**](https://github.com/PX4/PX4-windows-toolchain/blob/master/toolchain/scripts/setup-environment.bat). diff --git a/docs/zh/dev_setup/dev_env_windows_vm.md b/docs/zh/dev_setup/dev_env_windows_vm.md index c9190d5ea5..8bfc9a4148 100644 --- a/docs/zh/dev_setup/dev_env_windows_vm.md +++ b/docs/zh/dev_setup/dev_env_windows_vm.md @@ -57,12 +57,12 @@ VMWare performance is acceptable for basic usage (building Firmware) but not for Remember all settings are only for within your host operating system usage and hence you can disable any screen saver and local workstation security features which do not increase risk of a network attack. 10. Once the new VM is booted up make sure you install _VMWare tools drivers and tools extension_ inside your guest system. - This will enhance performance and usability of your VM usage: - - Significantly enhanced graphics performance - - Proper support for hardware device usage like USB port allocation (important for target upload), proper mouse wheel scrolling, sound support - - Guest display resolution adaption to the window size - - Clipboard sharing to host system - - File sharing to host system + This will enhance performance and usability of your VM usage: + - Significantly enhanced graphics performance + - Proper support for hardware device usage like USB port allocation (important for target upload), proper mouse wheel scrolling, sound support + - Guest display resolution adaption to the window size + - Clipboard sharing to host system + - File sharing to host system 11. Continue with [PX4 environment setup for Linux](../dev_setup/dev_env_linux.md) @@ -96,11 +96,11 @@ To allow this, you need to configure USB passthrough settings: 4. Add USB filters for the bootloader in VM: **VirtualBox > Settings > USB > Add new USB filter**. - Open the menu and plug in the USB cable connected to your autopilot. - Select the `...Bootloader` device when it appears in the UI. + Select the `...Bootloader` device when it appears in the UI. - ::: info - The bootloader device only appears for a few seconds after connecting USB. - If it disappears before you can select it, disconnect and then reconnect USB. + ::: info + The bootloader device only appears for a few seconds after connecting USB. + If it disappears before you can select it, disconnect and then reconnect USB. ::: diff --git a/docs/zh/dev_setup/dev_env_windows_wsl.md b/docs/zh/dev_setup/dev_env_windows_wsl.md index 6c1083f1e2..769ce4fc46 100644 --- a/docs/zh/dev_setup/dev_env_windows_wsl.md +++ b/docs/zh/dev_setup/dev_env_windows_wsl.md @@ -33,7 +33,7 @@ _QGroundControl for Windows_ is additionally required if you need to: Note that you can also use it to monitor a simulation, but you must manually [connect to the simulation running in WSL](#qgroundcontrol-on-windows). :::info -Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. +Connecting to an USB device from within WSL is not natively supported, however it can still be achieved by using the [USBIPD-WIN](https://learn.microsoft.com/en-us/windows/wsl/connect-usb) project. With this you can automatically upload firmware from the command line in WSL using the [`upload`](../dev_setup/building_px4.md#uploading-firmware-flashing-the-board) function. ::: :::info @@ -48,38 +48,38 @@ The benefit of WSL2 is that its virtual machine is deeply integrated into Window To install WSL2 with Ubuntu on a new installation of Windows 10 or 11: 1. Make sure your computer your computer's virtualization feature is enabled in the BIOS. - It's usually referred as "Virtualization Technology", "Intel VT-x" or "AMD-V" respectively + It's usually referred as "Virtualization Technology", "Intel VT-x" or "AMD-V" respectively 2. Open _cmd.exe_ as administrator. - This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. + This can be done by pressing the start key, typing `cmd`, right-clicking on the _Command prompt_ entry and selecting **Run as administrator**. 3. Execute the following commands to install WSL2 and a particular Ubuntu version: - - Default version (Ubuntu 22.04): + - Default version (Ubuntu 22.04): - ```sh - wsl --install - ``` + ```sh + wsl --install + ``` - - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) + - Ubuntu 20.04 ([Gazebo-Classic Simulation](../sim_gazebo_classic/index.md)) - ```sh - wsl --install -d Ubuntu-20.04 - ``` + ```sh + wsl --install -d Ubuntu-20.04 + ``` - - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) + - Ubuntu 22.04 ([Gazebo Simulation](../sim_gazebo_gz/index.md)) - ```sh - wsl --install -d Ubuntu-22.04 - ``` + ```sh + wsl --install -d Ubuntu-22.04 + ``` - ::: info - You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: + ::: info + You can also install[Ubuntu 20.04](https://www.microsoft.com/store/productId/9MTTCL66CPXJ) and [Ubuntu 22.04](https://www.microsoft.com/store/productId/9PN20MSR04DW) from the store, which allows you to delete the application using the normal Windows Add/Remove settings: ::: 4. WSL will prompt you for a user name and password for the Ubuntu installation. - Record these credentials as you will need them later on! + Record these credentials as you will need them later on! The command prompt is now a terminal within the newly installed Ubuntu environment. @@ -94,26 +94,26 @@ If you're using [Windows Terminal](https://learn.microsoft.com/en-us/windows/ter To open a WSL shell using a command prompt: 1. Open a command prompt: - - Press the Windows **Start** key. - - Type `cmd` and press **Enter** to open the prompt. + - Press the Windows **Start** key. + - Type `cmd` and press **Enter** to open the prompt. 2. To start WSL and access the WSL shell, execute the command: - ```sh - wsl -d - ``` + ```sh + wsl -d + ``` - 例如: + 例如: - ```sh - wsl -d Ubuntu - ``` + ```sh + wsl -d Ubuntu + ``` - ```sh - wsl -d Ubuntu-20.04 - ``` + ```sh + wsl -d Ubuntu-20.04 + ``` - If you only have one version of Ubuntu, you can just use `wsl`. + If you only have one version of Ubuntu, you can just use `wsl`. Enter the following commands to first close the WSL shell, and then shut down WSL: @@ -135,57 +135,57 @@ To install the development toolchain: 2. Execute the command `cd ~` to switch to the home folder of WSL for the next steps. - :::warning - This is important! - If you work from a location outside of the WSL file system you'll run into issues such as very slow execution and access right/permission errors. + :::warning + This is important! + If you work from a location outside of the WSL file system you'll run into issues such as very slow execution and access right/permission errors. ::: 3. Download the PX4 source code using `git` (which is already installed in WSL2): - ```sh - git clone https://github.com/PX4/PX4-Autopilot.git --recursive - ``` + ```sh + git clone https://github.com/PX4/PX4-Autopilot.git --recursive + ``` - ::: info - The environment setup scripts in the source usually work for recent PX4 releases. - If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). + ::: info + The environment setup scripts in the source usually work for recent PX4 releases. + If working with an older version of PX4 you may need to [get the source code specific to your release](../contribute/git_examples.md#get-a-specific-release). ::: 4. Run the **ubuntu.sh** installer script and acknowledge any prompts as the script progresses: - ```sh - bash ./PX4-Autopilot/Tools/setup/ubuntu.sh - ``` + ```sh + bash ./PX4-Autopilot/Tools/setup/ubuntu.sh + ``` - ::: info - This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: + ::: info + This installs tools to build PX4 for Pixhawk and either Gazebo or Gazebo Classic targets: - - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. - - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). + - You can use the `--no-nuttx` and `--no-sim-tools` options to omit the NuttX and/or simulation tools. + - Other Linux build targets are untested (you can try these by entering the appropriate commands in [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) into the WSL shell). ::: 5. Restart the "WSL computer" after the script completes (exit the shell, shutdown WSL, and restart WSL): - ```sh - exit - wsl --shutdown - wsl - ``` + ```sh + exit + wsl --shutdown + wsl + ``` 6. Switch to the PX4 repository in the WSL home folder: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 7. Build the PX4 SITL target and test your environment: - ```sh - make px4_sitl - ``` + ```sh + make px4_sitl + ``` For more build options see [Building PX4 Software](../dev_setup/building_px4.md). @@ -205,26 +205,26 @@ To set up the integration: 5. In the WSL shell, switch to the PX4 folder: - ```sh - cd ~/PX4-Autopilot - ``` + ```sh + cd ~/PX4-Autopilot + ``` 6. In the WSL shell, start VS Code: - ```sh - code . - ``` + ```sh + code . + ``` - This will open the IDE fully integrated with the WSL shell. + This will open the IDE fully integrated with the WSL shell. - Make sure you always open the PX4 repository in the Remote WSL mode. + Make sure you always open the PX4 repository in the Remote WSL mode. 7. Next time you want to develop WSL2 you can very easily open it again in Remote WSL mode by selecting **Open Recent** (as shown below). - This will start WSL for you. + This will start WSL for you. - ![](../../assets/toolchain/vscode/vscode_wsl.png) + ![](../../assets/toolchain/vscode/vscode_wsl.png) - Note however that the IP address of the WSL virtual machine will have changed, so you won't be able to monitor simulation from QGC for Windows (you can still monitor using QGC for Linux) + Note however that the IP address of the WSL virtual machine will have changed, so you won't be able to monitor simulation from QGC for Windows (you can still monitor using QGC for Linux) ## QGroundControl @@ -240,21 +240,21 @@ You can do this from within the WSL shell. 1. In a web browser, navigate to the QGC [Ubuntu download section](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html#ubuntu) 2. Right-click on the **QGroundControl.AppImage** link, and select "Copy link address". - This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ + This will be something like _https://d176td9ibe4jno.cloudfront.net/builds/master/QGroundControl.AppImage_ 3. [Open a WSL shell](#opening-a-wsl-shell) and enter the following commands to download the appimage and make it executable (replace the AppImage URL where indicated): - ```sh - cd ~ - wget - chmod +x QGroundControl.AppImage - ``` + ```sh + cd ~ + wget + chmod +x QGroundControl.AppImage + ``` 4. Run QGroundControl: - ```sh - ./QGroundControl.AppImage - ``` + ```sh + ./QGroundControl.AppImage + ``` QGroundControl will launch and automatically connect to a running simulation and allow you to monitor and control your vehicle(s). @@ -270,15 +270,15 @@ These steps describe how you can connect to the simulation running in the WSL: 2. Check the IP address of the WSL virtual machine by running the command `ip addr | grep eth0`: - ```sh - $ ip addr | grep eth0 + ```sh + $ ip addr | grep eth0 - 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 - inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 - ``` + 6: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + inet 172.18.46.131/20 brd 172.18.47.255 scope global eth0 + ``` - Copy the first part of the `eth0` interface `inet` address to the clipboard. - In this case: `172.18.46.131`. + Copy the first part of the `eth0` interface `inet` address to the clipboard. + In this case: `172.18.46.131`. 3. In QGC go to **Q > Application Settings > Comm Links** @@ -304,14 +304,14 @@ Do the following steps to flash your custom binary built in WSL: 1. If you haven't already built the binary in WSL e.g. with a [WSL shell](dev_env_windows_wsl.md#opening-a-wsl-shell) and by running: - ```sh - cd ~/PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + cd ~/PX4-Autopilot + make px4_fmu-v5 + ``` - ::: tip - Use the correct `make` target for your board. - `px4_fmu-v5` can be used for a Pixhawk 4 board. + ::: tip + Use the correct `make` target for your board. + `px4_fmu-v5` can be used for a Pixhawk 4 board. ::: @@ -325,12 +325,12 @@ Do the following steps to flash your custom binary built in WSL: 6. Continue and select the firmware binary you just built in WSL. - In the open dialog look for the "Linux" location with the penguin icon in the left pane. - It's usually all the way at the bottom. - Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` + In the open dialog look for the "Linux" location with the penguin icon in the left pane. + It's usually all the way at the bottom. + Choose the file in the path: `Ubuntu\home\{your WSL user name}\PX4-Autopilot\build\{your build target}\{your build target}.px4` - ::: info - You can add the folder to the favourites to access it quickly next time. + ::: info + You can add the folder to the favourites to access it quickly next time. ::: @@ -349,3 +349,9 @@ sudo add-apt-repository ppa:kisak/kisak-mesa sudo apt update sudo apt upgrade ``` + +### QGroundControl not connecting to PX4 SITL + +- The connection between PX4 SITL on WSL2 and QGroundControl on Windows requires [broadcasting](../simulation/index.md#enable-udp-broadcasting) or [streaming to a specific address](../simulation/index.md#enable-streaming-to-specific-address) to be enabled. + Streaming to a specific address should be enabled by default, but is something to check if a connection can't be established. +- Network traffic might be blocked by firewall or antivirus on you system. diff --git a/docs/zh/dev_setup/vscode.md b/docs/zh/dev_setup/vscode.md index 634709f834..27d65694fb 100644 --- a/docs/zh/dev_setup/vscode.md +++ b/docs/zh/dev_setup/vscode.md @@ -19,7 +19,7 @@ With _VScode_, configuration is stored in the PX4/PX4-Autopilot tree ([PX4-Autop You must already have installed the command line [PX4 developer environment](../dev_setup/dev_env.md) for your platform and downloaded the _Firmware_ source code repo. -## Installation & Setup +## 安装与设置 1. [Download and install VSCode](https://code.visualstudio.com/) (you will be offered the correct version for your OS). @@ -27,10 +27,10 @@ You must already have installed the command line [PX4 developer environment](../ - Select _Open folder ..._ option on the welcome page (or using the menu: **File > Open Folder**): - ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) + ![Open Folder](../../assets/toolchain/vscode/welcome_open_folder.jpg) - A file selection dialog will appear. - Select the **PX4-Autopilot** directory and then press **OK**. + Select the **PX4-Autopilot** directory and then press **OK**. The project files and configuration will then load into _VSCode_. @@ -49,9 +49,9 @@ You must already have installed the command line [PX4 developer environment](../ ::: - 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)). + - 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: - - This is up to you! It provides a deep integration between Github and the IDE, which may simplify your workflow. + - This is up to you! It provides a deep integration between Github and the IDE, which may simplify your workflow. - Other prompts are optional, and may be installed if they seem useful. @@ -63,21 +63,21 @@ 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). - ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) + ![Select Cmake build target](../../assets/toolchain/vscode/cmake_build_config.jpg) - ::: info - The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). + ::: info + The cmake target you select affects the targets offered for when [building/debugging](#debugging) (i.e. for hardware debugging you must select a hardware target like `px4_fmu-v6`). ::: - Click the target on the config bar to display other options, and select the one you want (this will replace any selected target). - _Cmake_ will then configure your project (see notification in bottom right). - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project.jpg) - Wait until configuration completes. - When this is done the notification will disappear and you'll be shown the build location: - ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). + When this is done the notification will disappear and you'll be shown the build location: + ![Cmake config project](../../assets/toolchain/vscode/cmake_configuring_project_done.jpg). 2. You can then kick off a build from the config bar (select either **Build** or **Debug**). ![Run debug or build](../../assets/toolchain/vscode/run_debug_build.jpg) diff --git a/docs/zh/development/development.md b/docs/zh/development/development.md index bbc8c949f3..e524cef519 100644 --- a/docs/zh/development/development.md +++ b/docs/zh/development/development.md @@ -24,5 +24,5 @@ - [支持](../contribute/support.md):使用 [讨论板](https://discuss.px4.io//) 和其他支持渠道获得帮助。 - [每周开发者电话会议](../contribute/dev_call.md):这是一个很好的机会来会见 PX4 开发团队,讨论平台技术细节(包括pull requests, 主要问题,一般性问答)。 -- [Licences](../contribute/licenses.md): What you can do with the code (free to use and modify under terms of the permissive [BSD 3-clause license](https://opensource.org/license/BSD-3-Clause)!) +- [Licences](../contribute/licenses.md): 您对代码的操作权限(可在宽松的 [BSD 3-clause license](https://opensource.org/license/BSD-3-Clause)条款下自由使用和修改!) - [贡献](../contribute/index.md): 如何使用我们的 [源代码](../contribute/code.md)。 diff --git a/docs/zh/dronecan/ark_cannode.md b/docs/zh/dronecan/ark_cannode.md index 57cf74e5d4..d7b0724f8e 100644 --- a/docs/zh/dronecan/ark_cannode.md +++ b/docs/zh/dronecan/ark_cannode.md @@ -83,9 +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: -| 参数 | 描述 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED含义 @@ -98,6 +99,6 @@ If you see a solid red LED there is an error and you should check the following: - Make sure the ARK CANnode has `ark_cannode_canbootloader` installed prior to flashing `ark_cannode_default`. - Remove binaries from the root and ufw directories of the SD card and try to build and flash again. -## See Also +## 另见 - [ARK CANnode Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-cannode) (ARK Docs) diff --git a/docs/zh/dronecan/ark_dist.md b/docs/zh/dronecan/ark_dist.md new file mode 100644 index 0000000000..4802469018 --- /dev/null +++ b/docs/zh/dronecan/ark_dist.md @@ -0,0 +1,98 @@ +# ARK DIST SR + +ARK DIST SR is a low range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). +It has an approximate range of between 8cm to 30m. + +![ARK DIST SR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-sr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- 传感器 + - [Broadcom AFBR-S50LV85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lv85d) + - Typical distance range up to 30m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 84mA Average + - 86mA Max + +## 硬件安装 + +### 布线 + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST SR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 配置 + +### DroneCAN + +#### Enable DroneCAN + +步骤如下: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `30`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `30`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## 另见 + +- [ARK DIST SR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/zh/dronecan/ark_dist_mr.md b/docs/zh/dronecan/ark_dist_mr.md new file mode 100644 index 0000000000..8408b486c0 --- /dev/null +++ b/docs/zh/dronecan/ark_dist_mr.md @@ -0,0 +1,97 @@ +# ARK DIST MR + +ARK DIST MR is a mid range, open source [DroneCAN](index.md) [distance sensor](../sensor/rangefinders.md). + +![ARK DIST MR](../../assets/hardware/sensors/optical_flow/ark_dist.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dist-mr/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DIST) +- 传感器 + - [Broadcom AFBR-S50LX85D Time-of-Flight Distance Sensor](https://www.broadcom.com/products/optical-sensors/time-of-flight-3d-sensors/afbr-s50lx85d) + - Typical distance range up to 50m + - Integrated 850 nm laser light source + - Field-of-View (FoV) of 12.4° x 6.2° with 32 pixels + - Operation of up to 200k Lux ambient light + - Reference Pixel for system health monitoring + - Works well on all surface conditions + - Transmitter beam of 2° x 2° to illuminate between 1 and 3 pixels +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- Pixhawk Standard UART Connector (6 Pin JST SH) +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- Small Form Factor + - 2.0cm x 2.8cm x 1.4cm + - 4g +- LED Indicators +- USA Built +- NDAA Compliant +- Power Requirements + - 5v + - 78mA Average + - 84mA Max + +## 硬件安装 + +### 布线 + +The ARK DIST is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +The ARK DIST can also be connected with UART and communicates over MAVLink sending the [DISTANCE_SENSOR](https://mavlink.io/en/messages/common.html#DISTANCE_SENSOR) message. + +## Firmware Setup + +ARK DIST MR runs the [PX4 DroneCAN Firmware](px4_cannode_fw.md). +As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +## PX4 配置 + +### DroneCAN + +#### Enable DroneCAN + +步骤如下: + +- 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)). +- Connect ARK DIST SR CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +Distance sensor data should arrive at 40Hz. + +DroneCAN configuration in PX4 is explained in more detail in [DroneCAN > Enabling DroneCAN](../dronecan/index.md#enabling-dronecan). + +#### CAN Configuration + +First set the parameters to [Enable DroneCAN](#enable-dronecan) (as shown above). + +Set the following parameters in _QGroundControl_: + +- Enable [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to 2 for dynamic node allocation. +- Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. +- Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. +- Set [UAVCAN_RNG_MAX](../advanced_config/parameter_reference.md#UAVCAN_RNG_MAX) to `50`. + +See also [Distance Sensor/Range Finder in _DroneCAN > Subscriptions and Publications_](../dronecan/#distance-sensor-range-finder). + +### UART/MAVLink Configuration + +If connecting via a UART set the following parameters in _QGroundControl_: + +- Set [MAV_X_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) to the port the sensor is connected to. +- Set [MAV_X_FORWARD](../advanced_config/parameter_reference.md#MAV_0_FORWARD) to `0` (off). +- Set [MAV_X_MODE](../advanced_config/parameter_reference.md#MAV_0_MODE) to `7` or `13` to (Minimal or Low Bandwidth) to reduce memory usage. +- Set `SER_XXX_BAUD` to `115200`, where `XXX` is specific to the port you are using (such as [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD)). +- Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `50`. +- Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. + +## 另见 + +- [ARK DIST MR](https://docs.arkelectron.com/sensor/ark-dist) (ARK Docs) diff --git a/docs/zh/dronecan/ark_flow.md b/docs/zh/dronecan/ark_flow.md index 84a6d8def2..fa64ec94ae 100644 --- a/docs/zh/dronecan/ark_flow.md +++ b/docs/zh/dronecan/ark_flow.md @@ -94,6 +94,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -109,9 +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: -| 参数 | 描述 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED含义 @@ -132,6 +134,6 @@ If you see a solid red LED there is an error and you should check the following: _PX4 holding position using the ARK Flow sensor for velocity estimation (in [Position Mode](../flight_modes_mc/position.md))._ -## See Also +## 另见 - [ARK Flow](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-flow) (ARK Docs) diff --git a/docs/zh/dronecan/ark_flow_mr.md b/docs/zh/dronecan/ark_flow_mr.md index a7fa7ebb6f..f3fb47940d 100644 --- a/docs/zh/dronecan/ark_flow_mr.md +++ b/docs/zh/dronecan/ark_flow_mr.md @@ -91,6 +91,7 @@ Set the following parameters in _QGroundControl_: - To optionally disable GPS aiding, set [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to `0`. - Enable [UAVCAN_SUB_FLOW](../advanced_config/parameter_reference.md#UAVCAN_SUB_FLOW). - Enable [UAVCAN_SUB_RNG](../advanced_config/parameter_reference.md#UAVCAN_SUB_RNG). +- Set [EKF2_RNG_CTRL](../advanced_config/parameter_reference.md#EKF2_RNG_CTRL) to `1`. - Set [EKF2_RNG_A_HMAX](../advanced_config/parameter_reference.md#EKF2_RNG_A_HMAX) to `10`. - Set [EKF2_RNG_QLTY_T](../advanced_config/parameter_reference.md#EKF2_RNG_QLTY_T) to `0.2`. - Set [UAVCAN_RNG_MIN](../advanced_config/parameter_reference.md#UAVCAN_RNG_MIN) to `0.08`. @@ -104,9 +105,10 @@ 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: -| 参数 | 描述 | -| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. | ## LED含义 @@ -127,6 +129,6 @@ If you see a solid red LED there is an error and you should check the following: _PX4 holding position using the ARK Flow MR sensor for velocity estimation (in [Position Mode](../flight_modes_mc/position.md))._ -## See Also +## 另见 - [ARK Flow MR](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-flow-mr) (ARK Docs) diff --git a/docs/zh/dronecan/ark_g5_rtk_gps.md b/docs/zh/dronecan/ark_g5_rtk_gps.md new file mode 100644 index 0000000000..67c3145a0f --- /dev/null +++ b/docs/zh/dronecan/ark_g5_rtk_gps.md @@ -0,0 +1,112 @@ +# ARK G5 RTK GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band [RTK GPS](../gps_compass/rtk_gps.md). + +The module incorporates the [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 传感器 + - [Septentrio mosaic-G5 P3 Ultra-compact high-precision GPS/GNSS receiver module](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 蜂鸣器 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 尺寸 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 硬件安装 + +### 布线 + +The ARK G5 RTK GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 Configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK GPS from the vehicle's centre of gravity. + +## LED含义 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## 另见 + +- [ARK G5 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_g5_rtk_heading_gps.md b/docs/zh/dronecan/ark_g5_rtk_heading_gps.md new file mode 100644 index 0000000000..c8ffb4367e --- /dev/null +++ b/docs/zh/dronecan/ark_g5_rtk_heading_gps.md @@ -0,0 +1,150 @@ +# ARK G5 RTK HEADING GPS + +:::info +This GPS module is made in the USA and NDAA compliant. +::: + +[ARK G5 RTK HEADING GPS](https://arkelectron.com/product/ark-g5-rtk-gps/) is a [DroneCAN](index.md) quad-band dual antenna [RTK GPS](../gps_compass/rtk_gps.md) that additionally provides vehicle yaw information from GPS. + +The module incorporates the [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H), magnetometer, barometer, IMU, and buzzer module. + +![ARK G5 RTK HEADING GPS](../../assets/hardware/gps/ark/ark_g5_rtk_gps.png) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-g5-rtk-heading-gps/) (US) + +## Hardware Specifications + +- [DroneCAN](index.md) RTK GNSS, Magnetometer, Barometer, IMU, and Buzzer Module +- [Dronecan Firmware Updating](../dronecan/index.md#firmware-update) +- 传感器 + - [Septentrio mosaic-G5 P3H Ultra-compact high-precision GPS/GNSS receiver module with heading capability](https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H) + - All-band all constellation GNSS receiver + - All-in-view satellite tracking: multi-constellation, quad-band GNSS module receiver + - Full raw data with positioning measurements and Galileo HAS positioning service compatibility + - Best-in-class RTK cm-level positioning accuracy + - Advanced GNSS+ algorithms + - 20Hz update rate + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) + - [Bosch BMP390 Barometer](https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/) + - [Invensense ICM-42688-P 6-Axis IMU](https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/) +- STM32F412VGH6 MCU +- Safety Button +- 蜂鸣器 +- Two CAN Connectors (Pixhawk Connector Standard 4-pin JST GH) +- G5 "UART 2" Connector + - 4-pin JST GH + - TX, RX, PPS, GND +- G5 USB C +- Debug Connector (Pixhawk Connector Standard 6-pin JST SH) +- LED Indicators + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- NDAA Compliant +- Power Requirements + - 5V + - 270mA +- 尺寸 + - Without Antenna + - 48.0mm x 40.0mm x 15.4mm + - 13.0g + - With Antenna + - 48.0mm x 40.0mm x 51.0mm + - 43.5g +- Includes + - CAN Cable (Pixhawk Connector Standard 4-pin) + - Full-Frequency Helical GPS Antenna + +## 硬件安装 + +### 布线 + +The ARK G5 RTK HEADING GPS is connected to the CAN bus using a [Pixhawk connector standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-009%20Pixhawk%20Connector%20Standard.pdf) 4-pin JST GH cable. +For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +The Septentrio G5 module firmware can be updated using the Septentrio [RxTools](https://www.septentrio.com/en/products/gps-gnss-receiver-software/rxtools) application. + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK G5 RTK HEADING GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK G5 RTK HEADING GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. + +There is also CAN built-in bus termination via [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK G5 RTK HEADING GPS from the vehicle's centre of gravity. + +### Parameter references + +This GPS is using ARK's private driver, the prameters below only exist on the firmware we ship the GPS with. You can set these params either in QGC or using the DroneCAN GUI Tool. + +#### SEP_OFFS_YAW (float) + +Heading offset angle for dual antenna GPS setups that support heading estimation. +Set this to 0 if the antennas are parallel to the forward-facing direction of the vehicle and the Rover/ANT2 antenna is in front. +The offset angle increases clockwise. +Set this to 90 if the ANT2 antenna is placed on the right side of the vehicle and the Moving Base/MAIN antenna is on the left side. + +- Default: 0 +- Min: -360 +- Max: 360 +- Unit: degree + +#### SEP_OFFS_PITCH (float) + +Vertical offsets can be compensated for by adjusting the Pitch offset. +Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. + +- Default: 0 +- Min: -90 +- Max: 90 +- Unit: degree + +#### SEP_OUT_RATE (enum) + +Configures the output rate for GNSS data messages. + +- -1: OnChange (Default) +- 50: 50 ms +- 100: 100 ms +- 200: 200 ms +- 500: 500 ms + +## LED含义 + +The GPS status lights are located to the right of the connectors: + +- Blinking green is GPS fix +- Blinking blue is received corrections and RTK Float +- Solid blue is RTK Fixed + +## 另见 + +- [ARK G5 RTK HEADING GPS Documentation](https://docs.arkelectron.com/gps/ark-g5-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_gps.md b/docs/zh/dronecan/ark_gps.md index 962760f754..f7284e0bae 100644 --- a/docs/zh/dronecan/ark_gps.md +++ b/docs/zh/dronecan/ark_gps.md @@ -91,9 +91,17 @@ If the sensor is not centred within the vehicle you will also need to define sen - Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` if this is that last node on the CAN bus. - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK GPS from the vehicles centre of gravity. +### ARK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK GPS itself: + +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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含义 You will see green, blue and red LEDs on the ARK GPS when it is being flashed, and a blinking green LED if it is running properly. @@ -104,6 +112,6 @@ If you see a red LED there is an error and you should check the following: - Make sure the ARK GPS has `ark_can-gps_canbootloader` installed prior to flashing `ark_can-gps_default`. - Remove binaries from the root and ufw directories of the SD card and try to build and flash again. -## See Also +## 另见 - [ARK GPS](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_mosaic__rtk_gps.md b/docs/zh/dronecan/ark_mosaic__rtk_gps.md index 24193f8de8..fb3851bd85 100644 --- a/docs/zh/dronecan/ark_mosaic__rtk_gps.md +++ b/docs/zh/dronecan/ark_mosaic__rtk_gps.md @@ -44,6 +44,6 @@ Order this module from: - USA Built - Supports DroneCAN Firmware Updating -## See Also +## 另见 - [ARK MOSAIC-X5 RTK GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-mosaic-x5-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_rtk_gps.md b/docs/zh/dronecan/ark_rtk_gps.md index fdecdc4b08..595daaf686 100644 --- a/docs/zh/dronecan/ark_rtk_gps.md +++ b/docs/zh/dronecan/ark_rtk_gps.md @@ -20,6 +20,7 @@ Order this module from: - Multi-band RTK with fast convergence times and reliable performance - High update rate for highly dynamic applications - Centimetre accuracy in a small and energy efficient module + - Moving Base for Heading - Bosch BMM150 Magnetometer - Bosch BMP388 Barometer - Invensense ICM-42688-P 6-Axis IMU @@ -27,7 +28,7 @@ Order this module from: - Safety Button - 蜂鸣器 - Two Pixhawk Standard CAN Connectors (4 Pin JST GH) -- F9P “UART 2” Connector +- F9P `UART 2` Connector - 3 Pin JST GH - TX, RX, GND - Pixhawk Standard Debug Connector (6 Pin JST SH) @@ -85,7 +86,34 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if - Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). - Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). - The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS from the vehicles centre of gravity. -- Set [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) to `1` on the GPS if this it that last node on the CAN bus. + +### ARK RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS itself: + +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. ### Setting Up Moving Baseline & GPS Heading @@ -128,10 +156,11 @@ Setup via UART: - On the _Moving Base_, set the following: - [GPS_UBX_MODE](../advanced_config/parameter_reference.md#GPS_UBX_MODE) to `2`. +For more information see [Rover and Moving Base](../dronecan/index.md#rover-and-moving-base) in the DroneCAN guide. + ## LED含义 - The GPS status lights are located to the right of the connectors - - Blinking green is GPS fix - Blinking blue is received corrections and RTK Float - Solid blue is RTK Fixed @@ -172,6 +201,6 @@ ARK RTK GPS comes with the Ublox F9P module up to date with version 1.13 or newe - "Firmware Update SUCCESS" should be displayed if it updated successfully ![Firmware Update](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_f9p_firmware_update.png) -## See Also +## 另见 - [ARK RTK GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_rtk_gps_l1_l2.md b/docs/zh/dronecan/ark_rtk_gps_l1_l2.md new file mode 100644 index 0000000000..4260b6e3e0 --- /dev/null +++ b/docs/zh/dronecan/ark_rtk_gps_l1_l2.md @@ -0,0 +1,163 @@ +# ARK RTK GPS L1 L5 + +[ARK RTK GPS L1 L5](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox F9P](https://www.u-blox.com/en/product/zed-f9p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK RTK GPS L1 L5](../../assets/hardware/gps/ark/ark_rtk_gps_l1_l5.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-rtk-gps-l1-l5/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- 传感器 + - Ublox F9P GPS + - Multi-band GNSS receiver delivers centimetre level accuracy in seconds + - Concurrent reception of GPS, GLONASS, Galileo and BeiDou + - Multi-band RTK with fast convergence times and reliable performance + - High update rate for highly dynamic applications + - Centimetre accuracy in a small and energy efficient module + - Does not Support Moving Base for Heading + - Bosch BMM150 Magnetometer + - Bosch BMP388 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412CEU6 MCU +- Safety Button +- 蜂鸣器 +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- F9P `UART 2` Connector + - 3 Pin JST GH + - TX, RX, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 170mA Average + - 180mA Max + +## 硬件安装 + +### 布线 + +The ARK RTK GPS L1 L5 is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK RTK GPS L1 L5 runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK RTK GPS L1 L5 boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK RTK GPS L1 L5, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK RTK GPS L1 L5 CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK RTK GPS L1 L5 from the vehicles centre of gravity. + +### ARK RTK GPS L1 L5 Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS L1 L5 itself: + +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED含义 + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK RTK GPS L1 L5 has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +### Updating Ublox F9P Module + +ARK RTK GPS L1 L5 comes with the Ublox F9P module up to date with version 1.13 or newer. However, you can check the version and update the firmware if desired. + +步骤如下: + +1. [Download u-center from u-blox.com](https://www.u-blox.com/en/product/u-center) and install on your PC (Windows only) +2. Open the [u-blox ZED-F9P website](https://www.u-blox.com/en/product/zed-f9p-module#tab-documentation-resources) +3. Scroll down and click on the "Show Legacy Documents" box +4. Scroll down again to Firmware Update and download your desired firmware (at least version 1.13 is needed) +5. While holding down the safety switch on the ARK RTK GPS L1 L5, connect it to power via one of its CAN ports and hold until all 3 LEDs blink rapidly +6. Connect the ARK RTK GPS L1 L5 to your PC via its debug port with a cable such as the Black Magic Probe or an FTDI +7. Open u-center, select the COM port for the ARK RTK GPS L1 L5 and connect + ![U-Center Connect](../../assets/hardware/gps/ark/ark_rtk_gps_ucenter_connect.png) +8. Check the current firmware version by selecting View, Messages View, UBX, MON, VER + ![Check Version](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_version.png) +9. To update the firmware: + 1. Select Tools, Firmware Update + 2. The Firmware image field should be the .bin file downloaded from the u-blox ZED-F9P website + 3. Check the "Use this baudrate for update" checkbox and select 115200 from the drop-down + 4. Ensure the other checkboxes are as shown below + 5. Push the green GO button on the bottom left + 6. "Firmware Update SUCCESS" should be displayed if it updated successfully + ![Firmware Update](../../assets/hardware/gps/ark/ark_rtk_gps_ublox_f9p_firmware_update.png) + +## 另见 + +- [ARK RTK GPS L1 L5 Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_teseo_gps.md b/docs/zh/dronecan/ark_teseo_gps.md index d5a3285f01..04313dc583 100644 --- a/docs/zh/dronecan/ark_teseo_gps.md +++ b/docs/zh/dronecan/ark_teseo_gps.md @@ -69,6 +69,6 @@ Order this module from: | 5 | FMU_SWCLK | 3.3V | | 6 | GND | GND | -## See Also +## 另见 - [ARK TESEO GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/sensors/ark-teseo-gps) (ARK Docs) diff --git a/docs/zh/dronecan/ark_x20_rtk_gps.md b/docs/zh/dronecan/ark_x20_rtk_gps.md new file mode 100644 index 0000000000..1feb0bfb33 --- /dev/null +++ b/docs/zh/dronecan/ark_x20_rtk_gps.md @@ -0,0 +1,141 @@ +# ARK X20 RTK GPS + +[ARK X20 RTK GPS](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) is an open source [DroneCAN](index.md) [RTK GPS](../gps_compass/rtk_gps.md), [u-blox ZED-X20P all-band high precision GNSS module](https://www.u-blox.com/en/product/zed-x20p-module), magnetometer, barometer, IMU, buzzer, and safety switch module. + +![ARK X20 RTK GPS](../../assets/hardware/gps/ark/ark_x20_rtk_gps.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-x20-rtk-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_RTK_GPS) +- 传感器 + - Ublox ZED-X20P + - All-band all constellation GNSS receiver + - Best position accuracy and availability in different environments + - RTK, PPP-RTK and PPP algorithms expanding the limits of performance + - Highest quality GNSS raw data + - u-blox end-to-end hardened security + - 25Hz update rate + - ST IIS2MDC Magnetometer + - Bosch BMP390 Barometer + - Invensense ICM-42688-P 6-Axis IMU +- STM32F412VGH6 MCU +- Safety Button +- 蜂鸣器 +- Two Pixhawk Standard CAN Connectors (4 Pin JST GH) +- X20 “UART 2” Connector + - 4 Pin JST GH + - TX, RX, PPS, GND +- I2C Expansion Connector + - 4 Pin JST-GH + - 5.0V, SCL, SDA, GND +- Pixhawk Standard Debug Connector (6 Pin JST SH) +- LED Indicators + - Safety LED + - GPS Fix + - RTK Status + - RGB system status +- USA Built +- Power Requirements + - 5V + - 144mA Average + - 157mA Max + +## 硬件安装 + +### 布线 + +The ARK X20 RTK GPS is connected to the CAN bus using a Pixhawk standard 4 pin JST GH cable. For more information, refer to the [CAN Wiring](../can/index.md#wiring) instructions. + +### Mounting + +The recommended mounting orientation is with the connectors on the board pointing towards the **back of vehicle**. + +The sensor can be mounted anywhere on the frame, but you will need to specify its position, relative to vehicle centre of gravity, during [PX4 configuration](#px4-configuration). + +## Firmware Setup + +ARK X20 RTK GPS runs the [PX4 cannode firmware](px4_cannode_fw.md). As such, it supports firmware update over the CAN bus and [dynamic node allocation](index.md#node-id-allocation). + +ARK X20 RTK GPS boards ship with recent firmware pre-installed, but if you want to build and flash the latest firmware yourself, refer to the [cannode firmware build instructions](px4_cannode_fw.md#building-the-firmware). + +Firmware target: `ark_can-rtk-gps_default` +Bootloader target: `ark_can-rtk-gps_canbootloader` + +## Flight Controller Setup + +### Enabling DroneCAN + +In order to use the ARK X20 RTK GPS, connect it to the Pixhawk CAN bus and enable the DroneCAN driver by setting 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)). + +步骤如下: + +- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` or `3` and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)). +- Connect ARK X20 RTK GPS CAN to the Pixhawk CAN. + +Once enabled, the module will be detected on boot. +GPS data should arrive at 10Hz. + +### PX4 配置 + +You need to set necessary [DroneCAN](index.md) parameters and define offsets if the sensor is not centred within the vehicle: + +- Enable GPS yaw fusion by setting bit 3 of [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) to true. +- Enable GPS blending to ensure the heading is always published by setting [SENS_GPS_MASK](../advanced_config/parameter_reference.md#SENS_GPS_MASK) to 7 (all three bits checked). +- Enable [UAVCAN_SUB_GPS](../advanced_config/parameter_reference.md#UAVCAN_SUB_GPS), [UAVCAN_SUB_MAG](../advanced_config/parameter_reference.md#UAVCAN_SUB_MAG), and [UAVCAN_SUB_BARO](../advanced_config/parameter_reference.md#UAVCAN_SUB_BARO). +- The parameters [EKF2_GPS_POS_X](../advanced_config/parameter_reference.md#EKF2_GPS_POS_X), [EKF2_GPS_POS_Y](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Y) and [EKF2_GPS_POS_Z](../advanced_config/parameter_reference.md#EKF2_GPS_POS_Z) can be set to account for the offset of the ARK X20 RTK GPS from the vehicles centre of gravity. + +### ARK X20 RTK GPS Configuration + +You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK X20 RTK GPS itself: + +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [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. | +| [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 + +Position of the rover is established using RTCM messages from the RTK base module (the base module is connected to QGC, which sends the RTCM information to PX4 via MAVLink). + +PX4 DroneCAN parameters: + +- [UAVCAN_PUB_RTCM](../advanced_config/parameter_reference.md#UAVCAN_PUB_RTCM): + - Makes PX4 publish RTCM messages ([RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream)) to the bus (which it gets from the RTK base module via QGC). + +Rover module parameters (also [set using QGC](../dronecan/index.md#qgc-cannode-parameter-configuration)): + +- [CANNODE_SUB_RTCM](../advanced_config/parameter_reference.md#CANNODE_SUB_RTCM) tells the rover that it should subscribe to [RTCMStream](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#rtcmstream) RTCM messages on the bus (from the moving base). + +:::info +Use [UAVCAN_PUB_MBD](../advanced_config/parameter_reference.md#UAVCAN_PUB_MBD) and [CANNODE_SUB_MBD](../advanced_config/parameter_reference.md#CANNODE_SUB_MBD) instead if you want to implement moving base (see below) at the same time. +::: + +For more information see [Rover and Fixed Base](../dronecan/index.md#rover-and-fixed-base) in the DroneCAN guide. + +## LED含义 + +- The GPS status lights are located to the right of the connectors + - Blinking green is GPS fix + - Blinking blue is received corrections and RTK Float + - Solid blue is RTK Fixed + +- The CAN status lights are located top the left of the connectors + - Slow blinking green is waiting for CAN connection + - Fast blinking green is normal operation + - Slow blinking green and blue is CAN enumeration + - Fast blinking blue and red is firmware update in progress + - Blinking red is error + - If you see a red LED there is an error and you should check the following + - Make sure the flight controller has an SD card installed + - Make sure the ARK X20 RTK GPS has `ark_can-rtk-gps_canbootloader` installed prior to flashing `ark_can-rtk-gps_default` + - Remove binaries from the root and ufw directories of the SD card and try to build and flash again + +## 另见 + +- [ARK X20 RTK GPS Documentation](https://docs.arkelectron.com/gps/ark-x20-rtk-gps) (ARK Docs) diff --git a/docs/zh/dronecan/escs.md b/docs/zh/dronecan/escs.md index 9742e3739e..5d40bc879c 100644 --- a/docs/zh/dronecan/escs.md +++ b/docs/zh/dronecan/escs.md @@ -1,7 +1,14 @@ # DroneCAN ESCs PX4 supports DroneCAN compliant ESCs. -For more information, see the following articles for specific hardware/firmware: + +## Supported ESC + +:::info +[Supported ESCs](../peripherals/esc_motors#supported-esc) in _ESCs & Motors_ may include additional devices that are not listed below. +::: + +The following articles have specific hardware/firmware information: - [PX4 Sapog ESC Firmware](sapog.md) - [Holybro Kotleta 20](holybro_kotleta.md) @@ -9,3 +16,18 @@ For more information, see the following articles for specific hardware/firmware: - [Vertiq](../peripherals/vertiq.md) (larger modules) - [VESC Project](../peripherals/vesc.md) - [RaccoonLab Cyphal and DroneCAN PWM nodes](raccoonlab_nodes.md) + +## 硬件配置 + +General DroneCAN hardware configuration is covered in [DroneCAN > Hardware Setup](../dronecan/index.md#hardware-setup). + +DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + +## PX4 配置 + +DroneCAN peripherals are configured by following the procedure outlined in [DroneCAN](../dronecan/index.md). + +In addition to the general setup, such as setting `UAVCAN_ENABLE` to `3`: + +- Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +- Configure the [motor order and servo outputs](../config/actuators.md). diff --git a/docs/zh/dronecan/holybro_h_rtk_zed_f9p_gps.md b/docs/zh/dronecan/holybro_h_rtk_zed_f9p_gps.md index 12c43945c6..9418fab0b8 100644 --- a/docs/zh/dronecan/holybro_h_rtk_zed_f9p_gps.md +++ b/docs/zh/dronecan/holybro_h_rtk_zed_f9p_gps.md @@ -64,10 +64,10 @@ To update the "AP Periph" firmware to the latest version: 1. [Download the latest binary](https://firmware.ardupilot.org/AP_Periph/latest/HolybroG4_GPS/). 2. Update the firmware using either of the following approaches: - - Using ArduPilot: - 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. - 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. - - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). + - Using ArduPilot: + 1. Install _Ardupilot_ firmware on your flight controller and the Mission Planner GCS on your computer. + 2. Update the binary by following the instructions in the [DroneCAN FW Upgrade](https://docs.holybro.com/gps-and-rtk-system/zed-f9p-h-rtk-series/dronecan-fw-upgrade) guide. + - Use a serial-to-can converter (such as the [Zubax Babel](https://github.com/Zubax/canface_cf1?tab=readme-ov-file)) and the [DroneCAN GUI Tool](https://dronecan.github.io/Implementations/Libuavcan/Tutorials/11._Firmware_update/). Remember to change the firmware on the flight controller back to PX4 afterwards. @@ -98,14 +98,14 @@ In order to use dual ZED-F9P GPS heading in PX4, follow these steps: 1. Open the QGroundControl parameters page. 2. On the left side next to the parameters list, double-click on the _System_ section (this hides the section). 3. Components should be visible on the left panel. - Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). + Click on the first `_Component_` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_). 4. 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 - - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. - This is the local offset (FRD) with respect to the autopilot. + - `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 + - `GPS_POS_X`, `GPS_POS_Y`, `GPS_POS_Z`: This is the antenna placement, which for the F9P is internal to the module. + This is the local offset (FRD) with respect to the autopilot. ![QGC Setup](../../assets/hardware/gps/holybro_h_rtk_zed_f9p_rover/holybro_f9p_gps_qgc_setup.png) diff --git a/docs/zh/dronecan/index.md b/docs/zh/dronecan/index.md index 7e056d7be2..24cccd66d5 100644 --- a/docs/zh/dronecan/index.md +++ b/docs/zh/dronecan/index.md @@ -27,6 +27,8 @@ Connecting peripherals over DroneCAN has many benefits: - Wiring is less complicated as you can have a single bus for connecting all your ESCs and other DroneCAN peripherals. - Setup is easier as you configure ESC numbering by manually spinning each motor. - It allows users to configure and update the firmware of all CAN-connected devices centrally through PX4. +- PX4 automatically tracks device information (vendor, model, versions, serial numbers) for maintenance and fleet management. + See [Asset Tracking](../debug/asset_tracking.md). ## 支持的硬件 @@ -67,6 +69,8 @@ Supported hardware includes (this is not an exhaustive list): - [RaccoonLab RM3100 Magnetometer](https://docs.raccoonlab.co/guide/gps_mag_baro/mag_rm3100.html) - Distance sensors + - [ARK Dist](ark_dist.md) + - [Ark Dist MR](ark_dist_mr.md) - [ARK Flow](ark_flow.md) - [Ark Flow MR](ark_flow_mr.md) - [Avionics Anonymous Laser Altimeter UAVCAN Interface](../dronecan/avanon_laser_interface.md) @@ -102,6 +106,10 @@ If the DNA is still running and certain devices need to be manually configured, :::info The PX4 node ID can be configured using the [UAVCAN_NODE_ID](../advanced_config/parameter_reference.md#UAVCAN_NODE_ID) parameter. The parameter is set to 1 by default. + +Devices running the [PX4 DroneCAN firmware](px4_cannode_fw.md) (such as [ARK CANnode](ark_cannode.md)) can use the +[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter to set a static node ID. +Set it to 0 (default) for dynamic allocation, or to a value between 1-127 to use a specific static node ID. ::: :::warning @@ -276,6 +284,9 @@ PX4 DroneCAN parameters: [DroneCAN ESCs and servos](../dronecan/escs.md) require the [motor order and servo outputs](../config/actuators.md) to be configured. +Select the specific CAN interface(s) used for ESC data output using the [UAVCAN_ESC_IFACE](../advanced_config/parameter_reference.md#UAVCAN_ESC_IFACE) parameter (all that all interfaces are selected by default). +Note that DroneCAN ESCs should be on their own dedicated CAN interface(s) because ESC messages can saturate the bus and starve other nodes of bandwidth. + ## QGC CANNODE Parameter Configuration QGroundControl can inspect and modify parameters belonging to CAN devices attached to the flight controller, provided the device are connected to the flight controller before QGC is started. @@ -285,6 +296,11 @@ For example, the screenshot below shows the parameters for a CAN GPS with node i ![QGC Parameter showing selected DroneCAN node](../../assets/can/dronecan/qgc_can_parameters.png) +Common CANNODE parameters that you can configure include: + +- [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID): Set a static node ID (1-127) or use 0 for dynamic allocation. See [PX4 DroneCAN Firmware > Static Node ID](px4_cannode_fw.md#static-node-id) for more information. +- [CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM): Enable CAN bus termination on the last node in the bus. + ## Device Specific Setup Most DroneCAN nodes require no further setup, unless specifically noted in their device-specific documentation. @@ -313,7 +329,10 @@ If successful, the firmware binary will be removed from the root directory and t **Q**: The motors aren't spinning when armed. -**A**: Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +**A**: + +- Make sure `UAVCAN_ENABLE` is set to `3` to enable DroneCAN ESC output. +- Make sure `UAVCAN_ESC_IFACE` is set to enable the CAN interface(s) used for ESCs. --- diff --git a/docs/zh/dronecan/pomegranate_systems_pm.md b/docs/zh/dronecan/pomegranate_systems_pm.md index d63d011d6c..3550f395b3 100644 --- a/docs/zh/dronecan/pomegranate_systems_pm.md +++ b/docs/zh/dronecan/pomegranate_systems_pm.md @@ -45,11 +45,11 @@ Source code and build instructions can be found on [the bitbucket](https://bitbu 1. Enable DroneCAN by setting the [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) parameter to `2` (Sensors Automatic Config) or `3`. 2. Enable DroneCAN battery monitoring by setting [UAVCAN_SUB_BAT](../advanced_config/parameter_reference.md#UAVCAN_SUB_BAT) to `1` or `2` ( depending on your battery). 3. Set the following module parameters using the [MAVLink console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html): - - Battery capacity in mAh: `battery_capacity_mAh` - - Battery voltage when _full_: `battery_full_V`, - - Battery voltage when _empty_: `battery_empty_V` - - Turn on current integration: `enable_current_track` - - (optional) Turn Off CANbus termination resistor :`enable_can_term` + - Battery capacity in mAh: `battery_capacity_mAh` + - Battery voltage when _full_: `battery_full_V`, + - Battery voltage when _empty_: `battery_empty_V` + - Turn on current integration: `enable_current_track` + - (optional) Turn Off CANbus termination resistor :`enable_can_term` **Example:** A Power Module with UAVCAN node id `125` connected to a `3S` LiPo with capacity of `5000mAh` can be configured with the following commands: diff --git a/docs/zh/dronecan/px4_cannode_fw.md b/docs/zh/dronecan/px4_cannode_fw.md index d96ad3e14c..23ce08461b 100644 --- a/docs/zh/dronecan/px4_cannode_fw.md +++ b/docs/zh/dronecan/px4_cannode_fw.md @@ -20,6 +20,26 @@ make ark_can-flow_default This will create an output in **build/ark_can-flow_default** named **XX-X.X.XXXXXXXX.uavcan.bin**. Follow the instructions at [DroneCAN firmware update](index.md#firmware-update) to flash the firmware. +## 配置 + +### Static Node ID + +By default, DroneCAN devices use [Dynamic Node Allocation (DNA)](index.md#node-id-allocation) to automatically obtain a unique node ID from the flight controller. +However, you can configure a static node ID using the [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) parameter. + +To configure a static node ID: + +1. Set [CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) to a value between 1-127 using [QGroundControl](index.md#qgc-cannode-parameter-configuration) +2. Reboot the device + +To return to dynamic allocation, set `CANNODE_NODE_ID` back to 0. +Note that when switching back to dynamic allocation, the flight controller will typically continue to allocate the same node ID that was previously used (this is normal DNA behavior). + +:::warning +When using static node IDs, you must ensure that each device on the CAN bus has a unique node ID. +Configuring two devices with the same ID will cause communication conflicts. +::: + ## 开发人员信息 This section has information that is relevant to developers who want to add support for new DroneCAN hardware to the PX4 Autopilot. diff --git a/docs/zh/dronecan/raccoonlab_power.md b/docs/zh/dronecan/raccoonlab_power.md index 6fb21706eb..e40ded7c3d 100644 --- a/docs/zh/dronecan/raccoonlab_power.md +++ b/docs/zh/dronecan/raccoonlab_power.md @@ -7,9 +7,9 @@ CAN power connectors are designed for light unmanned aerial (UAV) and other vehi There are two types of devices: 1. `CAN-MUX` devices provide power from XT30 connector to CAN. - There are 2 variation of this type of the device with different number of connectors. + There are 2 variation of this type of the device with different number of connectors. 2. `Power connector node` is designed to pass current (up to 60A) to power load and CAN, measure voltage and current on load. - It behaves as Cyphal/DroneCAN node. + It behaves as Cyphal/DroneCAN node. Please refer to the RaccoonLab docs [CAN Power Connectors](https://docs.raccoonlab.co/guide/pmu/power/) page. diff --git a/docs/zh/esc/ark_4in1_esc.md b/docs/zh/esc/ark_4in1_esc.md new file mode 100644 index 0000000000..561e71e969 --- /dev/null +++ b/docs/zh/esc/ark_4in1_esc.md @@ -0,0 +1,65 @@ +# ARK 4IN1 ESC (with/without Connectors) + +4 in 1 Electronic Speed Controller (ESC) that is made in the USA, NDAA compliant, and DIU Blue Framework listed. + +The ESC comes in variants without connectors that you can solder in place, and a variant that has built-in motor and battery connectors (no soldering required). + +![ARK 4IN1 ESC without connectors ](../../assets/hardware/esc/ark/ark_4_in_1_esc.jpg)![ARK 4IN1 ESC with connectors](../../assets/hardware/esc/ark/ark_4_in_1_esc_with_connectors.jpg) + +## 购买渠道 + +Order this module from: + +- [4IN1 ESC (with connectors)](https://arkelectron.com/product/ark-4in1-esc/) (ARK Electronics - US) +- [ARK Electronics (without connectors)](https://arkelectron.com/product/ark-4in1-esc-cons/) (ARK Electronics US) + +## Hardware Specifications + +- Battery Voltage: 3-8s + - 6V Minimum + - 65V Absolute Maximum + +- Current Rating: 50A Continuous, 75A Burst Per Motor + +- [STM32F0](https://www.st.com/en/microcontrollers-microprocessors/stm32f0-series.html) + +- [AM32 Firmware](https://github.com/am32-firmware/AM32/pull/27) + +- Onboard Current Sensor, Serial Telemetry + - 100V/A + +- Input Protocols + - DShot (300, 600) + - Bi-directional DShot + - KISS Serial Telemetry + - PWM + +- 8 Pin JST-SH Input/Output + +- 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 + +- Dimensions (without connectors) + - Size: 43.00mm x 40.50mm x 7.60mm + - Mounting Pattern: 30.5mm + - Weight: 14.5g + +Other + +- Made in the USA +- Open source AM32 firmware +- [DIU Blue Framework Listed](https://www.diu.mil/blue-uas/framework) + +## 另见 + +- [ARK 4IN1 ESC CONS](https://docs.arkelectron.com/electronic-speed-controller/ark-4in1-esc) (ARK Docs) diff --git a/docs/zh/esc/esc_protocols.md b/docs/zh/esc/esc_protocols.md new file mode 100644 index 0000000000..930d436de6 --- /dev/null +++ b/docs/zh/esc/esc_protocols.md @@ -0,0 +1,66 @@ +# ESC Protocols + +This topic lists the main [Electronic Speed Controller (ESC)](../peripherals/esc_motors.md) protocols supported by PX4. + +## DShot + +[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduced latency, in particular racing multicopters, VTOL vehicles, and so on. + +It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). +In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can reverse motor spin directions. + +PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). +Selecting a higher rate DShot ESC in the UI results in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. + +## DroneCAN + +[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. +The PX4 implementation is currently limited to update rates of 200 Hz. + +DroneCAN shares many similar benefits to [DShot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. + +[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). + +## PWM + +[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). + +PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired speed. +The pulse width typically ranges between 1000 μs for zero power and 2000 μs for full power. +The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50 Hz and 490 Hz (the theoretical maximum being 500 Hz for a very small "off" cycle). +A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. +For PWM servos 50 Hz is usually sufficient, and many don't support higher rates. + +![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) + +In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the pulse widths representing low and high values can vary significantly. +Unlike [DShot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) +- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) + +## OneShot 125 + +[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. +They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). +There are a number of variants of the OneShot protocol, which support different rates. +PX4 only supports OneShot 125. + +OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125 μs to 250 μs for zero to full power). +This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. +For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. +The actual supported rate depends on the ESC used. + +Setup: + +- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) +- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) +- [ESC Calibration](../advanced_config/esc_calibration.md) diff --git a/docs/zh/features_fw/gain_compression.md b/docs/zh/features_fw/gain_compression.md new file mode 100644 index 0000000000..eaee06ce5e --- /dev/null +++ b/docs/zh/features_fw/gain_compression.md @@ -0,0 +1,24 @@ +# Gain compression + + + +Automatic gain compression reduces the gains of the angular-rate PID whenever oscillations are detected. +It monitors the angular-rate controller output through a band-pass filter to identify these oscillations. + +This approach is a safe adaptive mechanism for stable aircraft: the PID gains remain unchanged when no oscillations are present, they are never increased beyond their nominal values, and they are bounded by a minimum limit. + +Gain compression can help prevent actuator damage and even loss of the vehicle in cases such as airspeed-sensor failure (loss of airspeed scaling) or in-flight changes in dynamics (e.g.: CG shifts, inertia changes), or other failures that could cause the angular-rate loop to become oscillatory. + +![Gain compression diagram](../../assets/config/fw/gain_compression_diagram.png) + +## 用法 + +Gain compression is enabled by default ([FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN)). + +It should be disabled during fixed wing [manual tuning](../config_fw/pid_tuning_guide_fixedwing.md) to avoid over-tuning. +It does not need to be disabled when autotuning. + +## 参数 + +- [FW_GC_EN](../advanced_config/parameter_reference.md#FW_GC_EN) +- [FW_GC_GAIN_MIN](../advanced_config/parameter_reference.md#FW_GC_GAIN_MIN) diff --git a/docs/zh/features_fw/index.md b/docs/zh/features_fw/index.md new file mode 100644 index 0000000000..7eab8e9c6c --- /dev/null +++ b/docs/zh/features_fw/index.md @@ -0,0 +1,5 @@ +# Fixedwing-Specific Features + +This section lists features that are specific to (or customised for) fixed-wings: + +- [Gain Compression](../features_fw/gain_compression.md) diff --git a/docs/zh/flight_controller/accton-godwit_ga1.md b/docs/zh/flight_controller/accton-godwit_ga1.md new file mode 100644 index 0000000000..20e78c102b --- /dev/null +++ b/docs/zh/flight_controller/accton-godwit_ga1.md @@ -0,0 +1,153 @@ +# Accton Godwit G-A1 + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://cubepilot.org/#/home) for hardware support or compliance issues. +::: + +The G-A1 is a state-of-the-art flight controller developed derived from the [Pixhawk Autopilot v6X Standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-012%20Pixhawk%20Autopilot%20v6X%20Standard.pdf). + +It includes an STM32H753 double-precision floating-point FMU processor and an STM32F103 IO coprocessor, multiple IMUs with 6-axis inertial sensors, two pressure/temperature sensors, and a geomagnetic sensor. +It also has independent buses and power supplies, and is designed for safety and rich expansion capabilities. + +With an integrated 10/100M Ethernet Physical Layer (PHY), the G-A1 can also communicate with a mission computer (airborne computer), high-end surveying and mapping cameras, and other UxV-mounted equipment for high-speed communications, meeting the needs of advanced UxV systems. + +:::tip +Visit [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) for more information. +::: + +![AccGodwitGA1](../../assets/flight_controller/accton-godwit/ga1/outlook.png "Accton Godwit G-A1") + +![AccGodwitGA1 Top View](../../assets/flight_controller/accton-godwit/ga1/orientation.png "Accton Godwit G-A1 Top View") + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## 产品规格 + +### 处理器 + +- STM32H753IIK (Arm® Cortex®-M7 480MHz) +- STM32F103 (Arm® Cortex®-M3, 72MHz) + +### 传感器 + +- Bosch BMI088 (vibration isolated) +- TDK InvenSense ICM-42688-P x 2 (one vibration isolated) +- TDK Barometric Pressure and Temperature Sensor CP-20100 x 2 (one vibration isolated) +- PNI RM3100 Geomagnetic Sensor (vibration isolated) + +### 电源 + +- 4.6V to 5.7V + +### External ports + +- 2 CAN Buses (CAN1 and CAN2) +- 3 TELEM Ports (TELEM1, TELEM2 and TELEM3) +- 2 GPS Ports (GPS1 with safety switch, LED, buzzer, and GPS2) +- 1 PPM IN +- 1 SBUS OUT +- 2 USB Ports (1 TYPE-C and 1 JST GH1.25) +- 1 10/100Base-T Ethernet Port +- 1 DSM/SBUS RC +- 1 UART 4 +- 1 AD&IO Port +- 2 Debug Ports (1 IO Debug and 1 FMU Debug) +- 1 SPI6 Bus +- 4 Power Inputs (Power 1, Power 2, Power C1 and Power C2) +- 16 PWM Servo Outputs (A1-A8 from FMU and M1-M8 from IO) +- Micro SD Socket (supports SD 4.1 & SDIO 4.0 in two databus modes: 1 bit (default) and 4 bits) + +### Size and Dimensions + +- 92.2 (L) x 51.2 (W) x 28.3 (H) mm +- 77.6g (carrier board with IMU) + +## 购买渠道 + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) + +## 针脚定义 + +![G-A1 Pin definition](../../assets/flight_controller/accton-godwit/ga1/pin_definition.png "G-A1 Pin definition") + +## UART Mapping + +| Serial# | Protocol | Port | 备注 | +| ------- | --------- | ------ | ---------- | +| SERIAL1 | Telem1 | UART7 | /dev/ttyS6 | +| SERIAL2 | Telem2 | UART5 | /dev/ttyS4 | +| SERIAL3 | GPS1 | USART1 | /dev/ttyS0 | +| SERIAL4 | GPS2 | UART8 | /dev/ttyS7 | +| SERIAL5 | Telem3 | USART2 | /dev/ttyS1 | +| SERIAL6 | UART4 | UART4 | /dev/ttyS3 | +| SERIAL7 | FMU Debug | USART3 | | +| SERIAL8 | OTG2 | USB | | + +## Wiring Diagram + +![G-A1 Wiring](../../assets/flight_controller/accton-godwit/ga1/wiring.png "G-A1 Wiring") + +## PWM Output + +PWM M1-M8 (IO Main PWM), A1-A8(FMU PWM). +All these 16 support normal PWM output formats. +FMU PWM A1-A6 can support DShot and B-Directional DShot. +A1-A8(FMU PWM) are grouped as: + +- Group 1: A1, A2, A3, A4 +- Group 2: A5, A6 +- Group 3: A7, A8 + +The motor and servo system should be connected to these ports according to the order outlined in the fuselage reference for your carrier. + +![G-A1 PWM Motor Servo](../../assets/flight_controller/accton-godwit/ga1/motor_servo.png "G-A1 PWM Motor Servo") + +## RC Input + +For DSM/SBUS receivers, connect them to the DSM/SBUS interface which provides dedicated 3.3V and 5V power pins respectively, and check above "Pinout" for detailed pin definition. +PPM receivers should be connected to the PPM interface. And other RC systems can be connected via other spare telemetry ports. + +![G-A1 Radio](../../assets/flight_controller/accton-godwit/ga1/radio.png "G-A1 Radio") + +## GPS/Compass + +The Godwit G-A1 has a built-in compass +Due to potential interference, the autopilot is usually used with an external I2C compass as part of a GPS/Compass combination. + +![G-A1 GPS](../../assets/flight_controller/accton-godwit/ga1/gps.png "G-A1 GPS") + +## Power Connection and Battery Monitor + +This universal controller features a CAN PMU module that supports 3 to 14s lithium batteries. +To ensure proper connection, attach the module's 6-pin connector to the flight control Power C1 and/or Power C2 interface. + +This universal controller does not provide power to the servos. +To power them, an external BEC must be connected to the positive and negative terminals of any A1–A8 or M1–M8 port. + +![G-A1 Power](../../assets/flight_controller/accton-godwit/ga1/power.png "G-A1 Power") + +## SD Card + +The SD card is NOT included in the package, you need to prepare the SD card and insert it into the slot. + +![G-A1 SD Card](../../assets/flight_controller/accton-godwit/ga1/sdcard.png "G-A1 SD Card") + +## 固件 + +The autopilot is compatible with PX4 firmware. And G-A1 can be detected by QGroundControl automatically. Users can also build it with target "accton-godwit_ga1" + +To [build PX4](../dev_setup/building_px4.md) for this target, open up the terminal and enter: + +```sh +make accton-godwit_ga1 +``` + +## More Information and Support + +- [Accton-IoT Godwit](https://www.accton-iot.com/godwit/) +- [sales@accton-iot.com](sales@accton-iot.com) +- [support@accton-iot.com](mailto:support@accton-iot.com) diff --git a/docs/zh/flight_controller/ark_pab.md b/docs/zh/flight_controller/ark_pab.md index bbdf2081e1..da170835ec 100644 --- a/docs/zh/flight_controller/ark_pab.md +++ b/docs/zh/flight_controller/ark_pab.md @@ -320,6 +320,6 @@ For information about using this port see: ![ARKPAB Bottom Photo](../../assets/flight_controller/arkpab/ark_pab_back.jpg) -## See Also +## 另见 - [ARK Pixhawk Autopilot Bus Carrier](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier) (ARK Docs) diff --git a/docs/zh/flight_controller/ark_pi6x.md b/docs/zh/flight_controller/ark_pi6x.md index 053e282c98..a8073e2658 100644 --- a/docs/zh/flight_controller/ark_pi6x.md +++ b/docs/zh/flight_controller/ark_pi6x.md @@ -297,6 +297,6 @@ Order this module from: | 21 | SDA0 | 3.3V | | 22 | 3.3V_RPI | 3.3V | -## See Also +## 另见 - [ARK Pi6X Flow Documentation](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pi6x-flow) (ARK Docs) diff --git a/docs/zh/flight_controller/ark_v6x.md b/docs/zh/flight_controller/ark_v6x.md index d03215834f..ffa3f4e172 100644 --- a/docs/zh/flight_controller/ark_v6x.md +++ b/docs/zh/flight_controller/ark_v6x.md @@ -65,7 +65,7 @@ For pinout of the ARKV6X see the [DS-10 Pixhawk Autopilot Bus Standard](https:// | ------ | ---------- | ------------------------------- | | USART1 | /dev/ttyS0 | GPS | | USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | UART4 & I2C | | UART5 | /dev/ttyS4 | TELEM2 | | USART6 | /dev/ttyS5 | PX4IO/RC | @@ -78,6 +78,6 @@ For pinout of the ARKV6X see the [DS-10 Pixhawk Autopilot Bus Standard](https:// make ark_fmu-v6x_default ``` -## See Also +## 另见 - [ARK Electronics ARKV6X](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/arkv6x) (ARK Docs) diff --git a/docs/zh/flight_controller/auav_x2.md b/docs/zh/flight_controller/auav_x2.md index 04db108057..1e458c1d25 100644 --- a/docs/zh/flight_controller/auav_x2.md +++ b/docs/zh/flight_controller/auav_x2.md @@ -82,11 +82,11 @@ As a CC-BY-SA 3.0 licensed Open Hardware design, all schematics and design files ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | IO debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | IO debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/autopilot_manufacturer_supported.md b/docs/zh/flight_controller/autopilot_manufacturer_supported.md index 97e54edd3b..10d0093619 100644 --- a/docs/zh/flight_controller/autopilot_manufacturer_supported.md +++ b/docs/zh/flight_controller/autopilot_manufacturer_supported.md @@ -12,6 +12,7 @@ This category includes boards that are not fully compliant with the pixhawk stan The boards in this category are: +- [Accton Godwit GA1](../flight_controller/accton-godwit_ga1.md) - [AirMind MindPX](../flight_controller/mindpx.md) - [AirMind MindRacer](../flight_controller/mindracer.md) - [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) (and [ARK Electronics Pixhawk Autopilot Bus Carrier](../flight_controller/ark_pab.md)) @@ -29,9 +30,13 @@ The boards in this category are: - [Holybro Kakute H7](../flight_controller/kakuteh7.md) - [Holybro Durandal](../flight_controller/durandal.md) - [Holybro Pix32 v5](../flight_controller/holybro_pix32_v5.md) +- [MicoAir H743 Lite](../flight_controller/micoair743-lite.md) - [ModalAI VOXL 2](../flight_controller/modalai_voxl_2.md) - [mRo Control Zero](../flight_controller/mro_control_zero_f7.md) +- [Radiolink PIX6](../flight_controller/radiolink_pix6.md) - [Sky-Drones AIRLink](../flight_controller/airlink.md) - [SPRacing SPRacingH7EXTREME](../flight_controller/spracingh7extreme.md) +- [Svehicle E2](../flight_controller/svehicle_e2.md) - [ThePeach FCC-K1](../flight_controller/thepeach_k1.md) - [ThePeach FCC-R1](../flight_controller/thepeach_r1.md) +- [X-MAV AP-H743-R1](../flight_controller/x-mav_ap-h743r1.md) diff --git a/docs/zh/flight_controller/cuav_pixhawk_v6x.md b/docs/zh/flight_controller/cuav_pixhawk_v6x.md index 867935b932..ab6bf390fa 100644 --- a/docs/zh/flight_controller/cuav_pixhawk_v6x.md +++ b/docs/zh/flight_controller/cuav_pixhawk_v6x.md @@ -122,16 +122,16 @@ The [Pixhawk V6X Wiring Quick Start](../assembly/quick_start_cuav_pixhawk_v6x.md ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | -| UART4 | /dev/ttyS3 | UART4 | -| UART5 | /dev/ttyS4 | TELEM2 | -| USART6 | /dev/ttyS5 | PX4IO/RC | -| UART7 | /dev/ttyS6 | TELEM1 | -| UART8 | /dev/ttyS7 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | -------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | 调试控制台 | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | PX4IO/RC | +| UART7 | /dev/ttyS6 | TELEM1 | +| UART8 | /dev/ttyS7 | GPS2 | ## 额定电压 diff --git a/docs/zh/flight_controller/cuav_v5.md b/docs/zh/flight_controller/cuav_v5.md index 5136fa5116..ff0e71024c 100644 --- a/docs/zh/flight_controller/cuav_v5.md +++ b/docs/zh/flight_controller/cuav_v5.md @@ -123,11 +123,11 @@ The pinout is as shown. | UART | 设备 | Port | | ------ | ---------- | ---------------------------------------------------------- | | UART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | | UART4 | /dev/ttyS3 | TELEM4 | | USART6 | /dev/ttyS4 | TX is RC input from SBUS_RC connector | -| UART7 | /dev/ttyS5 | Debug Console | +| UART7 | /dev/ttyS5 | 调试控制台 | | UART8 | /dev/ttyS6 | PX4IO | diff --git a/docs/zh/flight_controller/cuav_v5_nano.md b/docs/zh/flight_controller/cuav_v5_nano.md index 70e48783aa..61e70fd514 100644 --- a/docs/zh/flight_controller/cuav_v5_nano.md +++ b/docs/zh/flight_controller/cuav_v5_nano.md @@ -135,11 +135,11 @@ For more information see [Using JTAG for hardware debugging](#using-jtag-for-har | UART | 设备 | Port | | ------ | ---------- | ---------------------------------------------------------- | | UART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | | UART4 | /dev/ttyS3 | TELEM4 | | USART6 | /dev/ttyS4 | TX is RC input from SBUS_RC connector | -| UART7 | /dev/ttyS5 | Debug Console | +| UART7 | /dev/ttyS5 | 调试控制台 | | UART8 | /dev/ttyS6 | Not connected (no PX4IO) | diff --git a/docs/zh/flight_controller/cuav_v5_plus.md b/docs/zh/flight_controller/cuav_v5_plus.md index 29f628ead0..1825d829f8 100644 --- a/docs/zh/flight_controller/cuav_v5_plus.md +++ b/docs/zh/flight_controller/cuav_v5_plus.md @@ -161,11 +161,11 @@ For more information see [Using JTAG for hardware debugging](#using-jtag-for-har | UART | 设备 | Port | | ------ | ---------- | ---------------------------------------------------------- | | UART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | | UART4 | /dev/ttyS3 | TELEM4 | | USART6 | /dev/ttyS4 | TX is RC input from SBUS_RC connector | -| UART7 | /dev/ttyS5 | Debug Console | +| UART7 | /dev/ttyS5 | 调试控制台 | | UART8 | /dev/ttyS6 | PX4IO | diff --git a/docs/zh/flight_controller/cuav_x25-evo.md b/docs/zh/flight_controller/cuav_x25-evo.md index baa18091b4..4741da8858 100644 --- a/docs/zh/flight_controller/cuav_x25-evo.md +++ b/docs/zh/flight_controller/cuav_x25-evo.md @@ -99,15 +99,15 @@ Order from [CUAV](https://store.cuav.net/). ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | GPS1 | -| USART2 | /dev/ttyS1 | GPS2 | -| USART3 | /dev/ttyS2 | Debug Console | -| UART4 | /dev/ttyS3 | UART4 | -| UART5 | /dev/ttyS4 | TELEM2 | -| USART6 | /dev/ttyS5 | RC | -| UART7 | /dev/ttyS6 | TELEM1 | +| UART | 设备 | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | 调试控制台 | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | RC | +| UART7 | /dev/ttyS6 | TELEM1 | ## 额定电压 diff --git a/docs/zh/flight_controller/cubepilot_cube_orange.md b/docs/zh/flight_controller/cubepilot_cube_orange.md index 5af04e96a0..7e57746a70 100644 --- a/docs/zh/flight_controller/cubepilot_cube_orange.md +++ b/docs/zh/flight_controller/cubepilot_cube_orange.md @@ -204,14 +204,14 @@ The manufacturer [Cube User Guide](https://docs.cubepilot.org/user-guides/autopi ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| USART2 | /dev/ttyS0 | TELEM1 (flow control) | -| USART3 | /dev/ttyS1 | TELEM2 (flow control) | -| UART4 | /dev/ttyS2 | GPS1 | -| USART6 | /dev/ttyS3 | PX4IO | -| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | -| UART8 | /dev/ttyS5 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| USART2 | /dev/ttyS0 | TELEM1 (流控) | +| USART3 | /dev/ttyS1 | TELEM2 (流控) | +| UART4 | /dev/ttyS2 | GPS1 | +| USART6 | /dev/ttyS3 | PX4IO | +| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | +| UART8 | /dev/ttyS5 | GPS2 | diff --git a/docs/zh/flight_controller/cubepilot_cube_orangeplus.md b/docs/zh/flight_controller/cubepilot_cube_orangeplus.md index c117bea8aa..41af5783d1 100644 --- a/docs/zh/flight_controller/cubepilot_cube_orangeplus.md +++ b/docs/zh/flight_controller/cubepilot_cube_orangeplus.md @@ -205,14 +205,14 @@ The manufacturer [Cube User Guide](https://docs.cubepilot.org/user-guides/autopi ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| USART2 | /dev/ttyS0 | TELEM1 (flow control) | -| USART3 | /dev/ttyS1 | TELEM2 (flow control) | -| UART4 | /dev/ttyS2 | GPS1 | -| USART6 | /dev/ttyS3 | PX4IO | -| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | -| UART8 | /dev/ttyS5 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| USART2 | /dev/ttyS0 | TELEM1 (流控) | +| USART3 | /dev/ttyS1 | TELEM2 (流控) | +| UART4 | /dev/ttyS2 | GPS1 | +| USART6 | /dev/ttyS3 | PX4IO | +| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | +| UART8 | /dev/ttyS5 | GPS2 | diff --git a/docs/zh/flight_controller/cubepilot_cube_yellow.md b/docs/zh/flight_controller/cubepilot_cube_yellow.md index cbdc917433..d7bcc3f4e5 100644 --- a/docs/zh/flight_controller/cubepilot_cube_yellow.md +++ b/docs/zh/flight_controller/cubepilot_cube_yellow.md @@ -98,14 +98,14 @@ Board schematics and other documentation can be found here: [The Cube Project](h ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| USART2 | /dev/ttyS0 | TELEM1 (flow control) | -| USART3 | /dev/ttyS1 | TELEM2 (flow control) | -| UART4 | /dev/ttyS2 | GPS1 | -| USART6 | /dev/ttyS3 | PX4IO | -| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | -| UART8 | /dev/ttyS5 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| USART2 | /dev/ttyS0 | TELEM1 (流控) | +| USART3 | /dev/ttyS1 | TELEM2 (流控) | +| UART4 | /dev/ttyS2 | GPS1 | +| USART6 | /dev/ttyS3 | PX4IO | +| UART7 | /dev/ttyS4 | CONSOLE/ADSB-IN | +| UART8 | /dev/ttyS5 | GPS2 | diff --git a/docs/zh/flight_controller/durandal.md b/docs/zh/flight_controller/durandal.md index 6c552d2f62..0024c79fa5 100644 --- a/docs/zh/flight_controller/durandal.md +++ b/docs/zh/flight_controller/durandal.md @@ -168,15 +168,15 @@ make holybro_durandal-v1_default ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | GPS1 | -| USART2 | /dev/ttyS1 | TELEM1 | -| USART3 | /dev/ttyS2 | TELEM2 | -| UART4 | /dev/ttyS3 | TELEM4/GPS2 | -| USART6 | /dev/ttyS4 | TELEM3 | -| UART7 | /dev/ttyS5 | Debug Console | -| UART8 | /dev/ttyS6 | PX4IO | +| UART | 设备 | Port | +| ------ | ---------- | ----------- | +| USART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM1 | +| USART3 | /dev/ttyS2 | TELEM2 | +| UART4 | /dev/ttyS3 | TELEM4/GPS2 | +| USART6 | /dev/ttyS4 | TELEM3 | +| UART7 | /dev/ttyS5 | 调试控制台 | +| UART8 | /dev/ttyS6 | PX4IO | diff --git a/docs/zh/flight_controller/holybro_pix32.md b/docs/zh/flight_controller/holybro_pix32.md index 1f35c44ca1..2f5e598943 100644 --- a/docs/zh/flight_controller/holybro_pix32.md +++ b/docs/zh/flight_controller/holybro_pix32.md @@ -94,13 +94,13 @@ As a CC-BY-SA 3.0 licensed Open Hardware design, all schematics and design files ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | IO debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | IO debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/holybro_pix32_v6.md b/docs/zh/flight_controller/holybro_pix32_v6.md index 383938b43c..81cae7c034 100644 --- a/docs/zh/flight_controller/holybro_pix32_v6.md +++ b/docs/zh/flight_controller/holybro_pix32_v6.md @@ -104,15 +104,15 @@ Order from [Holybro](https://holybro.com/products/pix32-v6). ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | GPS1 | -| USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | -| UART5 | /dev/ttyS3 | TELEM2 | -| USART6 | /dev/ttyS4 | PX4IO | -| UART7 | /dev/ttyS5 | TELEM1 | -| UART8 | /dev/ttyS6 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | 调试控制台 | +| UART5 | /dev/ttyS3 | TELEM2 | +| USART6 | /dev/ttyS4 | PX4IO | +| UART7 | /dev/ttyS5 | TELEM1 | +| UART8 | /dev/ttyS6 | GPS2 | ## 尺寸 diff --git a/docs/zh/flight_controller/kakutef7.md b/docs/zh/flight_controller/kakutef7.md index 9f928b43b3..85877b99b1 100644 --- a/docs/zh/flight_controller/kakutef7.md +++ b/docs/zh/flight_controller/kakutef7.md @@ -115,7 +115,7 @@ In addition to the [basic configuration](../config/index.md), the following para | ------ | ---------- | ---------------------------------------- | | USART1 | /dev/ttyS0 | TELEM1 | | USART2 | /dev/ttyS1 | TELEM2 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | GPS1 | | USART6 | /dev/ttyS4 | RC SBUS | | UART7 | /dev/ttyS5 | ESC telemetry (DShot) | diff --git a/docs/zh/flight_controller/kakuteh7.md b/docs/zh/flight_controller/kakuteh7.md index a48a394490..333fe8d674 100644 --- a/docs/zh/flight_controller/kakuteh7.md +++ b/docs/zh/flight_controller/kakuteh7.md @@ -119,7 +119,7 @@ In addition to the [basic configuration](../config/index.md), the following para | ------ | ---------- | ---------------------------------------- | | USART1 | /dev/ttyS0 | TELEM1 | | USART2 | /dev/ttyS1 | TELEM2 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | GPS1 | | USART6 | /dev/ttyS4 | RC SBUS | | UART7 | /dev/ttyS5 | ESC telemetry (DShot) | diff --git a/docs/zh/flight_controller/kakuteh7mini.md b/docs/zh/flight_controller/kakuteh7mini.md index d23416130f..dbb3c96192 100644 --- a/docs/zh/flight_controller/kakuteh7mini.md +++ b/docs/zh/flight_controller/kakuteh7mini.md @@ -126,7 +126,7 @@ In addition to the [basic configuration](../config/index.md), the following para | ------ | ---------- | ---------------------------------------- | | USART1 | /dev/ttyS0 | TELEM1 | | UART2 | /dev/ttyS1 | TELEM2 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | GPS1 | | USART6 | /dev/ttyS4 | RC SBUS | | UART7 | /dev/ttyS5 | ESC telemetry (DShot) | diff --git a/docs/zh/flight_controller/kakuteh7v2.md b/docs/zh/flight_controller/kakuteh7v2.md index cdd2f07aa7..60a591e8db 100644 --- a/docs/zh/flight_controller/kakuteh7v2.md +++ b/docs/zh/flight_controller/kakuteh7v2.md @@ -122,7 +122,7 @@ In addition to the [basic configuration](../config/index.md), the following para | UART | 设备 | Port | | ------ | ---------- | ---------------------------------------- | | USART1 | /dev/ttyS0 | TELEM1 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | GPS1 | | USART6 | /dev/ttyS4 | RC SBUS | | UART7 | /dev/ttyS5 | ESC telemetry (DShot) | diff --git a/docs/zh/flight_controller/micoair743-lite.md b/docs/zh/flight_controller/micoair743-lite.md new file mode 100644 index 0000000000..43eea95fdb --- /dev/null +++ b/docs/zh/flight_controller/micoair743-lite.md @@ -0,0 +1,153 @@ +# MicoAir743-Lite + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://micoair.com/) for hardware support or compliance issues. +::: + +MicoAir743-Lite is an ultra-high performance H743 flight controller with an unbeatable price, featuring the ICM45686 IMU sensor and integrated Bluetooth telemetry. + +![MicoAir743-Lite Front View](../../assets/flight_controller/micoair743_lite/front_view.png) + +Equipped with a high-performance H7 processor, the MicoAir743-Lite features a compact form factor with SH1.0 connectors (which are more suitable than Pixhawk-standard GH1.25 for this board size). +When paired with with Bluetooth telemetry, the board can be debugged with a phone or PC. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## MicoAir743-Lite (v1.1) + +![MicoAir743-Lite Back View](../../assets/flight_controller/micoair743_lite/back_view.png) + +## 总览 + +### Processors & Sensors + +- FMU Processor: STM32H743 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- On-board sensors + - Accel/Gyro: ICM-45686 (with BalancedGyro™ Technology) + - Barometer: SPA06 +- On-board Bluetooth Telemetry + - Connected to UART8 internally, baudrate 115200 + - Connecting to QGC (PC or Android phone) via Bluetooth +- 其它特性: + - Operating & storage temperature: -20 ~ 85°c + +### 接口 + +- 8 UART (TELEM / GPS / RC) +- 14 PWM outputs (10 supports DShot) +- Support multiple RC inputs (SBUS / CRSF / DSM) +- 1 GPS port +- 1 I2C port +- 2 ADC port2 (VBAT, Current) +- 1 DJI O3/O4 VTX connector +- 1 MicroSD Card Slot +- 1 USB Type-C + +### Electrical data + +- VBAT Input: + - 2\~6S (6\~27V) +- USB Power Input: + - 4.75\~5.25V +- BEC Output: + - 5V 2A (for controller, receiver, GPS, optical flow or other devices) + - 9V 2A (for video transmitter, camera) + +### Mechanical data + +- Mounting: 30.5 x 30.5mm, Φ4mm +- Dimensions: 36 x 36 x 8 mm +- Weight: 10g + +![MicoAir743-Lite Size](../../assets/flight_controller/micoair743_lite/size.png) + +## 购买渠道 + +Order from [MicoAir Tech Store](https://store.micoair.com/product/micoair743-lite/). + +## 针脚定义 + +Pinouts definition can be found in the [MicoAir743-Lite_pinout.xlsx](https://raw.githubusercontent.com/PX4/PX4-Autopilot/refs/heads/main/docs/assets/flight_controller/micoair743_lite/micoair743_lite_pinout.xlsx) file. + +## 串口映射 + +| UART | 设备 | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | TELEM1 | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | GPS1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART5 | /dev/ttyS4 | TELEM3 | +| USART6 | /dev/ttyS5 | RC | +| UART7 | /dev/ttyS6 | URT6 | +| UART8 | /dev/ttyS7 | TELEM4 | + +## Interfaces Diagram + +:::note +All the connectors used on the board are SH1.0 +::: + +![MicoAir743-Lite Interface Diagram](../../assets/flight_controller/micoair743_lite/interfaces_diagram.png) + +## Sample Wiring Diagram + +![MicoAir743-Lite Wiring Diagram](../../assets/flight_controller/micoair743_lite/wiring_diagram.png) + +## 编译固件 + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make micoair_h743-lite_default +``` + +## Installing PX4 Firmware + +The firmware can be installed in any of the normal ways: + +- Build and upload the source + + ```sh + make micoair_h743-lite_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## 遥控器 + +A [Radio Control (RC) system](../getting_started/rc_transmitter_receiver.md) is required if you want to manually control your vehicle (PX4 does not require a radio system for autonomous flight modes). + +The RC port is connected to the FMU and you can attach a receiver that uses the protocols `DSM`, `SBUS`, `CSRF`, `GHST`, or other protocol listed in [Radio Control modules](../modules/modules_driver_radio_control.md). +You will need to enable the protocol by setting the corresponding parameter `RC_xxxx_PRT_CFG`, such as [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) for a [CRSF receiver](../telemetry/crsf_telemetry.md). + +## 支持的平台/机身 + +Any multicopter / airplane / rover or boat that can be controlled with normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be seen in the [Airframes Reference](../airframes/airframe_reference.md). + +## 外部设备 + +- [MicoAir Telemetry Radio Modules](https://micoair.com/radio_telemetry/) +- [MicoAir Optical & Range Sensor](https://micoair.com/optical_range_sensor/) +- [MicoAir GPS](https://micoair.com/gps/) +- [MicoAir ESC Modules](https://micoair.com/esc/) + +## 更多信息 + +- [MicoAir Tech.](https://micoair.com/) +- [Details about MicoAir743-Lite](https://micoair.com/flightcontroller_micoair743lite/) +- [QGroundControl Download and Install](https://docs.qgroundcontrol.com/Stable_V5.0/en/qgc-user-guide/getting_started/download_and_install.html) diff --git a/docs/zh/flight_controller/mindpx.md b/docs/zh/flight_controller/mindpx.md index d69ba6d89b..51ad77c014 100644 --- a/docs/zh/flight_controller/mindpx.md +++ b/docs/zh/flight_controller/mindpx.md @@ -111,15 +111,15 @@ You can also find MindRacer at Amazon® or eBay®. ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | RC | -| USART2 | /dev/ttyS1 | TELEM1 | -| USART3 | /dev/ttyS2 | TELEM2 | -| UART4 | /dev/ttyS3 | GPS1 | -| USART6 | /dev/ttyS4 | ? | -| UART7 | /dev/ttyS5 | Debug Console | -| UART8 | /dev/ttyS6 | ? | +| UART | 设备 | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | RC | +| USART2 | /dev/ttyS1 | TELEM1 | +| USART3 | /dev/ttyS2 | TELEM2 | +| UART4 | /dev/ttyS3 | GPS1 | +| USART6 | /dev/ttyS4 | ? | +| UART7 | /dev/ttyS5 | 调试控制台 | +| UART8 | /dev/ttyS6 | ? | diff --git a/docs/zh/flight_controller/mindracer.md b/docs/zh/flight_controller/mindracer.md index 14aedd78c0..a520ffd967 100644 --- a/docs/zh/flight_controller/mindracer.md +++ b/docs/zh/flight_controller/mindracer.md @@ -44,7 +44,7 @@ The main hardware documentation is [here](http://mindpx.net/assets/accessories/m | IMU | 10DOF | | IMU isolation | YES/Optional | | Radio Receiver | S.BUS/PPM/DSM/DSM2/DSMX/SUMD | -| Telemetry | FrSky® D.Port, S.Port, Wifi, 3DR radio | +| 数传 | FrSky® D.Port, S.Port, Wifi, 3DR radio | | On board TF card for flight data recording | YES | | OneShot ESC Support | YES | | Expansion Slots | 2x7(pin)x2 | diff --git a/docs/zh/flight_controller/modalai_fc_v1.md b/docs/zh/flight_controller/modalai_fc_v1.md index 1b8239b84d..1e9562b83d 100644 --- a/docs/zh/flight_controller/modalai_fc_v1.md +++ b/docs/zh/flight_controller/modalai_fc_v1.md @@ -40,7 +40,7 @@ This flight controller is [manufacturer supported](../flight_controller/autopilo | microSD Card | [Information on supported cards](../dev_log/logging.md#sd-cards) | | 输入 | GPS/Mag | | | Spektrum | -| | Telemetry | +| | 数传 | | | CAN bus | | | PPM | | Outputs | 6 LEDs (2xRGB) | diff --git a/docs/zh/flight_controller/modalai_voxl_2.md b/docs/zh/flight_controller/modalai_voxl_2.md index 8787ac7fd4..f1c64f0607 100644 --- a/docs/zh/flight_controller/modalai_voxl_2.md +++ b/docs/zh/flight_controller/modalai_voxl_2.md @@ -74,7 +74,6 @@ This board supported in QGroundControl 4.0 and later. ## 访问链接 -- [PX4 Autonomy Developer Kit](https://www.modalai.com/products/px4-autonomy-developer-kit) - [Starling 2](https://www.modalai.com/products/starling-2) - [Starling 2 MAX](https://www.modalai.com/products/starling-2-max) - [Sentinel Development Drone powered by VOXL 2](https://www.modalai.com/pages/sentinel) diff --git a/docs/zh/flight_controller/modalai_voxl_flight.md b/docs/zh/flight_controller/modalai_voxl_flight.md index c77e143538..352fd22892 100644 --- a/docs/zh/flight_controller/modalai_voxl_flight.md +++ b/docs/zh/flight_controller/modalai_voxl_flight.md @@ -67,7 +67,7 @@ This flight controller is [manufacturer supported](../flight_controller/autopilo | microSD Card | [Information on supported cards](../dev_log/logging.md#sd-cards) | | 输入 | GPS/Mag | | | Spektrum | -| | Telemetry | +| | 数传 | | | CAN bus | | | PPM | | Outputs | 6 LEDs (2xRGB) | diff --git a/docs/zh/flight_controller/mro_control_zero_f7.md b/docs/zh/flight_controller/mro_control_zero_f7.md index f17ce6a8f4..0e2c41e68c 100644 --- a/docs/zh/flight_controller/mro_control_zero_f7.md +++ b/docs/zh/flight_controller/mro_control_zero_f7.md @@ -106,8 +106,8 @@ There is also an [ARM20-CTX 20-Pin to TC2030-IDC adapter](https://www.tag-connec | UART | 设备 | Port | | ------ | ---------- | -------------------------------------------------------------------------------------------------- | -| USART2 | /dev/ttyS0 | TELEM1 (flow control) | -| USART3 | /dev/ttyS1 | TELEM2 (flow control) | +| USART2 | /dev/ttyS0 | TELEM1 (流控) | +| USART3 | /dev/ttyS1 | TELEM2 (流控) | | UART4 | /dev/ttyS2 | GPS1 | | USART6 | /dev/ttyS3 | Flex port (can be configured as SPI or UART with Flow Control). | | UART7 | /dev/ttyS4 | CONSOLE | diff --git a/docs/zh/flight_controller/mro_pixhawk.md b/docs/zh/flight_controller/mro_pixhawk.md index 7ff5c5cd9c..0cc954f889 100644 --- a/docs/zh/flight_controller/mro_pixhawk.md +++ b/docs/zh/flight_controller/mro_pixhawk.md @@ -86,14 +86,14 @@ See [3DR Pixhawk 1 > Pinouts](../flight_controller/pixhawk.md#pinouts) ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | IO debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | IO debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/pixhack_v3.md b/docs/zh/flight_controller/pixhack_v3.md index e9f48ca3c5..ac3566c88b 100644 --- a/docs/zh/flight_controller/pixhack_v3.md +++ b/docs/zh/flight_controller/pixhack_v3.md @@ -78,11 +78,11 @@ make px4_fmu-v3_default ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | IO debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | | CONSOLE | -| UART8 | | SERIAL4 | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | IO debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | | CONSOLE | +| UART8 | | SERIAL4 | diff --git a/docs/zh/flight_controller/pixhawk-2.md b/docs/zh/flight_controller/pixhawk-2.md index c92f721c6b..51dd87718f 100644 --- a/docs/zh/flight_controller/pixhawk-2.md +++ b/docs/zh/flight_controller/pixhawk-2.md @@ -124,15 +124,15 @@ Board schematics and other documentation can be found here: [The Cube Project](h ### 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| USART1 | /dev/ttyS0 | | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | /dev/ttyS3 | GPS1 | -| USART6 | /dev/ttyS4 | PX4IO | -| UART7 | /dev/ttyS5 | CONSOLE | -| UART8 | /dev/ttyS6 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| USART1 | /dev/ttyS0 | | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | /dev/ttyS3 | GPS1 | +| USART6 | /dev/ttyS4 | PX4IO | +| UART7 | /dev/ttyS5 | CONSOLE | +| UART8 | /dev/ttyS6 | | diff --git a/docs/zh/flight_controller/pixhawk.md b/docs/zh/flight_controller/pixhawk.md index cbe395c9b0..4cdae9634f 100644 --- a/docs/zh/flight_controller/pixhawk.md +++ b/docs/zh/flight_controller/pixhawk.md @@ -245,14 +245,14 @@ Due to space constraints two ports are on one connector. ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | IO debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | IO debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/pixhawk3_pro.md b/docs/zh/flight_controller/pixhawk3_pro.md index 38a10f1cd3..7947f34a9f 100644 --- a/docs/zh/flight_controller/pixhawk3_pro.md +++ b/docs/zh/flight_controller/pixhawk3_pro.md @@ -75,13 +75,13 @@ For information about wiring and using this port see: ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | WiFi | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | WiFi | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/pixhawk4.md b/docs/zh/flight_controller/pixhawk4.md index 5930e4db48..c23bbc082b 100644 --- a/docs/zh/flight_controller/pixhawk4.md +++ b/docs/zh/flight_controller/pixhawk4.md @@ -75,15 +75,15 @@ The exception is the [debug port(s)](#debug_port) (pin 1 is the right-most, as s ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | /dev/ttyS3 | TELEM4 | -| USART6 | /dev/ttyS4 | RC SBUS | -| UART7 | /dev/ttyS5 | Debug Console | -| UART8 | /dev/ttyS6 | PX4IO | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | /dev/ttyS3 | TELEM4 | +| USART6 | /dev/ttyS4 | RC SBUS | +| UART7 | /dev/ttyS5 | 调试控制台 | +| UART8 | /dev/ttyS6 | PX4IO | ## 尺寸 diff --git a/docs/zh/flight_controller/pixhawk5x.md b/docs/zh/flight_controller/pixhawk5x.md index 456b61315f..f78e8ef9e4 100644 --- a/docs/zh/flight_controller/pixhawk5x.md +++ b/docs/zh/flight_controller/pixhawk5x.md @@ -142,7 +142,7 @@ Connector pin assignments are left to right (i.e. Pin 1 is the left-most pin). | ------ | ---------- | ------------------------------- | | USART1 | /dev/ttyS0 | GPS | | USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | UART4 & I2C | | UART5 | /dev/ttyS4 | TELEM2 | | USART6 | /dev/ttyS5 | PX4IO/RC | diff --git a/docs/zh/flight_controller/pixhawk6c.md b/docs/zh/flight_controller/pixhawk6c.md index d344238d42..9b2eaa5c76 100644 --- a/docs/zh/flight_controller/pixhawk6c.md +++ b/docs/zh/flight_controller/pixhawk6c.md @@ -110,15 +110,15 @@ The [Pixhawk 6C Wiring Quick Start](../assembly/quick_start_pixhawk6c.md) provid ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ------------- | -| USART1 | /dev/ttyS0 | GPS1 | -| USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | -| UART5 | /dev/ttyS3 | TELEM2 | -| USART6 | /dev/ttyS4 | PX4IO | -| UART7 | /dev/ttyS5 | TELEM1 | -| UART8 | /dev/ttyS6 | GPS2 | +| UART | 设备 | Port | +| ------ | ---------- | ------ | +| USART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | 调试控制台 | +| UART5 | /dev/ttyS3 | TELEM2 | +| USART6 | /dev/ttyS4 | PX4IO | +| UART7 | /dev/ttyS5 | TELEM1 | +| UART8 | /dev/ttyS6 | GPS2 | ## 尺寸 diff --git a/docs/zh/flight_controller/pixhawk6c_mini.md b/docs/zh/flight_controller/pixhawk6c_mini.md index 1973aa00b6..5c5069b5ee 100644 --- a/docs/zh/flight_controller/pixhawk6c_mini.md +++ b/docs/zh/flight_controller/pixhawk6c_mini.md @@ -205,7 +205,7 @@ For information about using this port see: Any multicopter / airplane / rover or boat that can be controlled with normal RC servos or Futaba S-Bus servos. The complete set of supported configurations can be seen in the [Airframes Reference](../airframes/airframe_reference.md). -## See Also +## 另见 - [Holybro Docs](https://docs.holybro.com/) (Holybro) - [Pixhawk 4 Mini Wiring Quick Start](../assembly/quick_start_pixhawk4_mini.md) (and [Pixhawk 6C Wiring QuickStart](../assembly/quick_start_pixhawk6c.md)) diff --git a/docs/zh/flight_controller/pixhawk6x.md b/docs/zh/flight_controller/pixhawk6x.md index 8212476581..81d456b8f4 100644 --- a/docs/zh/flight_controller/pixhawk6x.md +++ b/docs/zh/flight_controller/pixhawk6x.md @@ -190,7 +190,7 @@ Sample Wiring Diagram | ------ | ---------- | ------------------------------- | | USART1 | /dev/ttyS0 | GPS | | USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | UART4 & I2C | | UART5 | /dev/ttyS4 | TELEM2 | | USART6 | /dev/ttyS5 | PX4IO/RC | diff --git a/docs/zh/flight_controller/pixhawk6x_pro.md b/docs/zh/flight_controller/pixhawk6x_pro.md index 02b3d67618..6d5a0fcdbb 100644 --- a/docs/zh/flight_controller/pixhawk6x_pro.md +++ b/docs/zh/flight_controller/pixhawk6x_pro.md @@ -150,7 +150,7 @@ The [Pixhawk 6X Wiring Quick Start](../assembly/quick_start_pixhawk6x.md) provid | ------ | ---------- | ------------------------------- | | USART1 | /dev/ttyS0 | GPS | | USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | UART4 & I2C | | UART5 | /dev/ttyS4 | TELEM2 | | USART6 | /dev/ttyS5 | PX4IO/RC | @@ -244,7 +244,7 @@ The complete set of supported configurations can be seen in the [Airframes Refer Download [here](https://docs.holybro.com/autopilot/pixhawk-6x-pro/download). -## See Also +## 另见 - [Holybro Docs](https://docs.holybro.com/autopilot/pixhawk-6x-pro) (Holybro) - [Pixhawk 6X Wiring QuickStart](../assembly/quick_start_pixhawk6x.md) diff --git a/docs/zh/flight_controller/pixhawk_series.md b/docs/zh/flight_controller/pixhawk_series.md index 6e98320632..20b01255b5 100644 --- a/docs/zh/flight_controller/pixhawk_series.md +++ b/docs/zh/flight_controller/pixhawk_series.md @@ -100,6 +100,24 @@ At very high level, the main differences are: +### FMUv6 Comparison + +| 特性 | **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 Pixhawk project schematics and reference designs are licensed under [CC BY-SA 3](https://creativecommons.org/licenses/by-sa/3.0/legalcode). diff --git a/docs/zh/flight_controller/pixracer.md b/docs/zh/flight_controller/pixracer.md index 2af7add617..cc508f2839 100644 --- a/docs/zh/flight_controller/pixracer.md +++ b/docs/zh/flight_controller/pixracer.md @@ -188,14 +188,14 @@ For information about using this port see: ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | WiFi (ESP8266) | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | | | -| UART7 | CONSOLE | | -| UART8 | SERIAL4 | | +| UART | 设备 | Port | +| ------ | ---------- | --------------------------------- | +| UART1 | /dev/ttyS0 | WiFi (ESP8266) | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | | | +| UART7 | CONSOLE | | +| UART8 | SERIAL4 | | diff --git a/docs/zh/flight_controller/raccoonlab_fmu6x.md b/docs/zh/flight_controller/raccoonlab_fmu6x.md index 844a685878..656331f732 100644 --- a/docs/zh/flight_controller/raccoonlab_fmu6x.md +++ b/docs/zh/flight_controller/raccoonlab_fmu6x.md @@ -105,7 +105,7 @@ This autopilot is [supported](../flight_controller/autopilot_pixhawk_standard.md | ------ | ---------- | ------------------------------- | | USART1 | /dev/ttyS0 | GPS | | USART2 | /dev/ttyS1 | TELEM3 | -| USART3 | /dev/ttyS2 | Debug Console | +| USART3 | /dev/ttyS2 | 调试控制台 | | UART4 | /dev/ttyS3 | UART4 & I2C | | UART5 | /dev/ttyS4 | TELEM2 | | USART6 | /dev/ttyS5 | PX4IO/RC | diff --git a/docs/zh/flight_controller/radiolink_pix6.md b/docs/zh/flight_controller/radiolink_pix6.md new file mode 100644 index 0000000000..73c70f12cf --- /dev/null +++ b/docs/zh/flight_controller/radiolink_pix6.md @@ -0,0 +1,347 @@ +# RadiolinkPIX6 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +Contact the [manufacturer](https://radiolink.com.cn/) for hardware support or compliance issues. +::: + +The autopilot is recommended for commercial systems integration, but is also suitable for academic research and any other use. + +![RadiolinkPIX6](http://www.radiolink.com.cn/firmware/wiki/RadiolinkPIX6/RadiolinkPIX6.png) + +The Radiolink PIX6 is a high-performance flight controller. +Featuring STM32F7 CPU, vibration isolation of IMUs, redundant IMUs, integrated OSD chip, IMU heating, and DShot. + +:::info +This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +## 总览 + +- 处理器 + - 32-bit ARM Cortex M7 core with DPFPU - STM32F765VIT6 + - 216 MHz/512 KB RAM/2 MB Flash + - 32-bit IOMCU co-processor - STM32F100 + - 32KB FRAM - FM25V02A + - AT7456E OSD +- 传感器 + - Bosh BMI088 IMU (accel, gyro) + - InvenSense ICM-42688 IMU (accel, gyro) + - SPA06 barometer + - IST8310 magnetometer +- 电源 + - SMBUS/I2C Power Module Inputs (I2C) + - voltage and current monitor inputs (Analog) +- 接口 + - 16 PWM Outputs with independent power rail for external power source + - 5x UART serial ports, 2 with HW flow control + - Camera Input and Video Output + - PPM/SBUS input, DSM/SBUS input + - RSSI (PWM or voltage) input + - I2C, SPI, 2x CAN, USB + - 3.3V and 6.6V ADC inputs + - 蜂鸣器与安全开关 + - microSD card +- 重量和尺寸: + - Weight 80g + - Size 94mm x 51.5mm x 14.5mm + +## 购买渠道 + +[Radiolink Amazon](https://www.radiolink.com.cn/pix6_where_to_buy)(International users) + +[Radiolink Taobao](https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bNMdSqV&ft=t&id=815993357068&skuId=5515756705284)(China Mainland user) + +## Connector assignments + +### Top View + +![Pix6 top view](../../assets/flight_controller/radiolink_pix6/top_view.png) + +### Left View + +![Pix6 left view](../../assets/flight_controller/radiolink_pix6/left_view.png) + +### Right View + +![Pix6 right view](../../assets/flight_controller/radiolink_pix6/right_view.png) + +### Rear View + +![Pix6 rear view](../../assets/flight_controller/radiolink_pix6/rear_view.png) + +## 针脚定义 + +Unless noted otherwise all connectors are JST GH. + +### TELEM1,TELEM2 接口 + +| 针脚 | 信号 | 电压 | +| -- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | CTS | +3.3V | +| 5 | RTS: | +3.3V | +| 6 | GND | GND | + +### OSD + +| 针脚 | 信号 | 电压 | +| -- | ---- | --------------------- | +| 1 | GND | GND | +| 2 | VOUT | +3.3V | +| 3 | VCC | +5V | +| 4 | GND | GND | +| 5 | VCC | +5V | +| 6 | VIN | +3.3V | + +### I2C port + +| 针脚 | 信号 | 电压 | +| -- | --- | -------------------------------------------------- | +| 1 | VCC | +5V | +| 2 | SCL | +3.3V (pullups) | +| 3 | SDA | +3.3V (pullups) | +| 4 | GND | GND | + +### CAN1, CAN2 ports + +| 针脚 | 信号 | 电压 | +| -- | -------------------------- | ---- | +| 1 | VCC | +5V | +| 2 | CAN_H | +12V | +| 3 | CAN_L | +12V | +| 4 | GND | GND | + +### GPS1 port + +| 针脚 | 信号 | 电压 | +| -- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### GPS2 Port + +| 针脚 | 信号 | 电压 | +| -- | -------------------------- | --------------------- | +| 1 | VCC | +5V | +| 2 | TX(OUT) | +3.3V | +| 3 | RX(IN) | +3.3V | +| 4 | SCL | +3.3V | +| 5 | SDA | +3.3V | +| 6 | GND | GND | + +### SPI + +| 针脚 | 信号 | 电压 | +| -- | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | SPI_SCK | +3.3V | +| 3 | SPI_MISO | +3.3V | +| 4 | SPI_MOSI | +3.3V | +| 5 | !SPI_NSS1 | +3.3V | +| 6 | !SPI_NSS2 | +3.3V | +| 7 | DRDY | +3.3V | +| 8 | GND | GND | + +### POWER1 (HY2.0-6P) + +Port for analog power monitors. + +| 针脚 | 信号 | 电压 | +| -- | --- | --------------------------- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | 电流 | up to +3.3V | +| 4 | 电压 | up to +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### POWER2 (HY2.0-6P) + +Port for digital (I2C) power monitor. + +| 针脚 | 信号 | 电压 | +| -- | --- | --------------------- | +| 1 | VCC | +5V | +| 2 | VCC | +5V | +| 3 | SCL | +3.3V | +| 4 | SDA | +3.3V | +| 5 | GND | GND | +| 6 | GND | GND | + +### ADC 3.3V + +| 针脚 | 信号 | 电压 | +| -- | ------- | --------------------------- | +| 1 | VCC | +5V | +| 2 | ADC IN1 | up to +3.3V | +| 3 | GND | GND | +| 4 | ADC IN2 | up to +3.3v | +| 5 | GND | GND | + +### ADC 6.6V + +| 针脚 | 信号 | 电压 | +| -- | ------ | -------------------------- | +| 1 | VCC | +5V | +| 2 | ADC IN | up to 6.6V | +| 3 | GND | GND | + +### USB remote port + +| 针脚 | 信号 | 电压 | +| -- | ------- | --------------------- | +| 1 | USB VDD | +5V | +| 2 | DM | +3.3V | +| 3 | DP | +3.3V | +| 4 | GND | GND | + +### SWITCH + +| 针脚 | 信号 | 电压 | +| -- | -------------------------------------------------------- | --------------------- | +| 1 | VCC | +3.3V | +| 2 | !IO_LED_SAFETY | GND | +| 3 | SAFETY | GND | + +### Buzzer port + +| 针脚 | 信号 | 电压 | +| -- | ------- | --- | +| 1 | VCC | +5V | +| 2 | BUZZER- | +5V | + +### Spektrum/DSM Port (PH1.25-3P) + +| 针脚 | 信号 | 电压 | +| -- | --- | --------------------- | +| 1 | VCC | +3.3V | +| 2 | GND | GND | +| 3 | 信号 | +3.3V | + +### Debug port (SH1.0-8P) + +| 针脚 | 信号 | 电压 | +| -- | ------------------------------ | --------------------- | +| 1 | VCC | +5V | +| 2 | FMU_SWCLK | +3.3V | +| 3 | FMU_SWDIO | +3.3V | +| 4 | TX(UART7) | +3.3V | +| 5 | RX(UART7) | +3.3V | +| 6 | IO_SWCLK | +3.3V | +| 7 | IO_SWDIO | +3.3V | +| 8 | GND | GND | + +## 编译固件 + +To [build PX4](../dev_setup/building_px4.md) for this target: + +```sh +make radiolink_PIX6_default +``` + +## Installing PX4 Firmware + +The firmware can be installed in any of the normal ways: + +- Build and upload the source + + ```sh + make radiolink_PIX6_default upload + ``` + +- [Load the firmware](../config/firmware.md) using _QGroundControl_. + You can use either pre-built firmware or your own custom firmware. + + ::: info + At time of writing the only pre-built software is `PX4 main` (see [Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)). + Release builds will be supported for PX4 v1.17 and later. + +::: + +## PX4 配置 + +In addition to the [basic configuration](../config/index.md), the following parameters are important: + +| 参数 | 设置 | +| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG) | This should be disabled since the board does not have an internal mag. You can enable it if you attach an external mag. | + +### Powering the PIX6 + +The PIX6 has 2 dedicated power monitor ports, each with a 6 pin connector. +One is the Analog power monitor (`POWER1`), and the others is the I2C power monitor (`POWER2`). + +The power module that comes with the flight controller with a wide voltage input range of 2-12S (7.4-50.4V), a maximum detection current of 90A (single ESC maximum detection current is 22.5A), a BEC output voltage of 5.3±0.2V, and a BEC output current of 2A. + +![Radiolink power modules MODULES](../../assets/flight_controller/radiolink_pix6/radiolink_power_modules.png) + +The PIX6 also supports power modules from other manufacturers, such as [holybro_pm02d](../power_module/holybro_pm02d.md). + +## Recommended Accessories + +### GPS Modules + +Radiolink manufactures a variety of high-performance GPS,Dual Anti-interference Technology Worry-free of UAV High-power Image Transmission, High-Voltage Lines, or Other Strong Signal Interference. + +The PIX6 has 2 dedicated GPS ports, `GPS1` and `GPS2`, each with a 6 pin connector. + +Recommended modules include: + +- [Radiolink SE100](https://radiolink.com.cn/se100) +- [Radiolink TS100](https://radiolink.com.cn/ts100v2) +- [Radiolink RTK F9P](https://radiolink.com.cn/rtk_f9p) + +## 串口映射 + +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | GPS1 | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | /dev/ttyS3 | GPS2 | +| UART7 | /dev/ttyS4 | 调试控制台 | +| UART8 | /dev/ttyS5 | PX4IO | + +## Analog inputs + +The Radiolink PIX6 has 3 analog inputs, one 6V tolerant and two 3.3V tolerant. + +- ADC Pin12 -> ADC 6.6V Sense +- ADC Pin4 -> ADC IN1 3.3V Sense +- ADC Pin13 -> ADC IN2 3.3V Sense + +## 遥控器 + +A [Radio Control (RC)](../getting_started/rc_transmitter_receiver.md) 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](../getting_started/rc_transmitter_receiver.md) and then _bind_ them so that they communicate (read the instructions that come with your specific transmitter/receiver). + +- Spektrum/DSM receivers connect to the **DSM/SBUS RC** input. +- PPM or SBUS receivers connect to the **RC IN** input port. +- CRSF receiver must be wired to a spare port (UART) on the Flight Controller. + Then you can bind the transmitter and receiver together. + +#### CRSF Parameter Configuration + +[Find and set](../advanced_config/parameters.md) the following parameters: + +1. Set [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) to the port that is connected to the CRSF receiver (such as `TELEM1`). + + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + + There is no need to set the baud rate for the port, as this is configured by the driver. + +2. Enable [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) to activate Crossfire telemetry. + +For more information about selecting a radio system, receiver compatibility, and binding your transmitter/receiver pair, see: [Remote Control Transmitters & Receivers](../getting_started/rc_transmitter_receiver.md). diff --git a/docs/zh/flight_controller/svehicle_e2.md b/docs/zh/flight_controller/svehicle_e2.md new file mode 100644 index 0000000000..13baec27c3 --- /dev/null +++ b/docs/zh/flight_controller/svehicle_e2.md @@ -0,0 +1,176 @@ +# S-Vehicle E2 + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The _E2_ is an advanced autopilot manufactured by S-Vehicle®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![SVehicle-E2](../../assets/flight_controller/svehicle_e2/main.png) + +:::info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H753IIK6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- On-board sensors + - Accel/Gyro: BMI088 + - Accel/Gyro: ICM-42688-P + - Accel/Gyro: ICM-20649 + - Mag: RM3100 + - Barometer: 2x ICP-20100 + +### 接口 + +- 14x PWM Servo Outputs +- 1x Dedicated R/C Input for Spektrum / DSM and S.Bus +- 1x Analog/PWM RSSI Input +- 2x TELEM Ports (with full flow control) +- 1x UART4 Port +- 2x GPS Ports + - 1x Full GPS plus Safety Switch Port (GPS1) + - 1x Basic GPS Port (with I2C, GPS2) +- 1x USB Port (TYPE-C) +- 1x Ethernet Port + - Transformerless application + - 100Mbps +- 3x I2C Bus Ports +- 1x SPI Bus + - 1x Chip Select Line + - 1x Data Ready Line + - 1x SPI Reset Line +- 2x CAN Ports +- 3x Power Input Ports + - ADC Power Input + - I2C Power Input + - DroneCAN/UAVCAN Power Input +- 2x AD Ports + - Analog Input (3.3V) + - Analog Input (6.6V - not supported by PX4) +- 1x Dedicated Debug Port + - FMU Debug + +## Purchase Channels + +Order from [S-Vehicle](https://svehicle.cn/). + +## 遥控器 + +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). + +将 HW\\u PM 模块的6针连接器连接到飞控的电源接口。 + +Spektrum/DSM receivers connect to the DSM/SBUS RC input. +PPM or SBUS receivers connect to the RC IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## 串口映射 + +| UART | 设备 | Port | +| ------ | ---------- | -------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM3 | +| USART3 | /dev/ttyS2 | 调试控制台 | +| UART4 | /dev/ttyS3 | UART4 | +| UART5 | /dev/ttyS4 | TELEM2 | +| USART6 | /dev/ttyS5 | PX4IO/RC | +| UART7 | /dev/ttyS6 | TELEM1 | +| UART8 | /dev/ttyS7 | GPS2 | + +## PWM Output + +The E2-Plus flight controller supports up to 14 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 6 outputs (labelled 9 to 14) are the "auxiliary" outputs. +These are directly attached to the STM32H753 FMU controller . + +The 14 PWM outputs are: + +M1 - M8 are connected to the IOMCU +A1 - A6 are connected to the FMU + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 6 FMU PWM outputs are in 2 groups: + +A1 - A4 are in one group. +A5, A6 are in a 2nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.7V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V +- Current Ratings: + - TELEM1 and GPS2 combined output current limiter: 1.5A + - All other port combined output current limiter: 1.5A + +## Battery Monitoring + +The board has connectors for 3 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN +- POWER3 -- I2C + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor and I2C defaults configured which is enabled. + +The default PDB included with the E2+ is analog and must be connected to `POWER1`. + +## 编译固件 + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make svehicle_e2_default +``` + +## 调试接口 + +The [PX4 System Console](../debug/system_console.md) and [SWD Interface](../debug/swd_debug.md) operate on the **FMU Debug** port. + +| 针脚 | 信号 | 电压 | +| ---- | --------------------------------- | --------------------- | +| 1(红) | 5V+ | +5V | +| 2 | DEBUG TX (OUT) | +3.3V | +| 3 | DEBUG RX (IN) | +3.3V | +| 4(黑) | FMU_SWDIO | +3.3V | +| 6 | FMU_SWCLK | +3.3V | +| 6 | GND | GND | + +For information about using this port see: + +- [SWD Debug Port](../debug/swd_debug.md) +- [PX4 System Console](../debug/system_console.md) (Note, the FMU console maps to USART3). +- All ports use GH1.25 ,power ports use ports on E2 uses the 6 circuit [2.00mm Pitch CLIK-Mate Wire-to-Board PCB Receptacle](https://www.molex.com/en-us/products/part-detail/5024430670). + +## 针脚定义 + +![SVehicle-E2 Top Down Photo](../../assets/flight_controller/svehicle_e2/top.png) + +![SVehicle-E2 Bottom Photo](../../assets/flight_controller/svehicle_e2/back.jpeg) + +![SVehicle-E2 left Photo](../../assets/flight_controller/svehicle_e2/left.png) + +![SVehicle-E2 right Photo](../../assets/flight_controller/svehicle_e2/right.png) + +## 支持的平台/机身 + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). diff --git a/docs/zh/flight_controller/thepeach_k1.md b/docs/zh/flight_controller/thepeach_k1.md index 8f831afaba..aefdcb3033 100644 --- a/docs/zh/flight_controller/thepeach_k1.md +++ b/docs/zh/flight_controller/thepeach_k1.md @@ -50,15 +50,15 @@ It is based on the **Pixhawk-project FMUv3** open hardware design and runs **PX4 ## 串口映射 -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| USART1 | /dev/ttyS0 | IO Processor Debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | /dev/ttyS3 | GPS1 | -| USART6 | /dev/ttyS4 | PX4IO | -| UART7 | /dev/ttyS5 | Debug Console | -| UART8 | /dev/ttyS6 | TELEM4 | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| USART1 | /dev/ttyS0 | IO Processor Debug | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | /dev/ttyS3 | GPS1 | +| USART6 | /dev/ttyS4 | PX4IO | +| UART7 | /dev/ttyS5 | 调试控制台 | +| UART8 | /dev/ttyS6 | TELEM4 | ## 额定电压 diff --git a/docs/zh/flight_controller/thepeach_r1.md b/docs/zh/flight_controller/thepeach_r1.md index 1be40738ba..39bbc2f635 100644 --- a/docs/zh/flight_controller/thepeach_r1.md +++ b/docs/zh/flight_controller/thepeach_r1.md @@ -57,7 +57,7 @@ It is based on the **Pixhawk-project FMUv3** open hardware design and runs **PX4 | UART | 设备 | Port | | ------ | ---------- | --------------------------------------------- | | USART1 | /dev/ttyS0 | IO Processor Debug | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | | USART3 | /dev/ttyS2 | TELEM2 (Raspberry pi cm3+) | | UART4 | /dev/ttyS3 | GPS1 | | USART6 | /dev/ttyS4 | PX4IO | diff --git a/docs/zh/flight_controller/x-mav_ap-h743r1.md b/docs/zh/flight_controller/x-mav_ap-h743r1.md new file mode 100644 index 0000000000..9370f785d3 --- /dev/null +++ b/docs/zh/flight_controller/x-mav_ap-h743r1.md @@ -0,0 +1,147 @@ +# AP-H743-R1 Flight Controller + + + +:::warning +PX4 does not manufacture this (or any) autopilot. +::: + +The AP-H743-R1 is an advanced autopilot manufactured by X-MAV®. + +The autopilot is recommended for commercial system integration, but is also suitable for academic research and any other applications. +It brings you ultimate performance, stability, and reliability in every aspect. + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-main.png) + +:::info +These flight controllers are [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md). +::: + +### Processors & Sensors + +- FMU Processor: STM32H743VIT6 + - 32 Bit Arm® Cortex®-M7, 480MHz, 2MB flash memory, 1MB RAM +- IO Processor: STM32F103 + - 32 Bit Arm® Cortex®-M3, 72MHz, 20KB SRAM +- On-board sensors + - Accel/Gyro: ICM-42688-P\*2(Version1), BMI270\*2(Version2) + - Mag: QMC5883P + - Barometer: DPS310(Version1),SPL06(Version2) + +### 接口 + +- 15x PWM Servo Outputs +- 1x Dedicated S.Bus Input +- 3x TELEM Ports +- 1x SERIAL4 Port +- 2x GPS Ports +- 1x USB Port (TYPE-C) +- 3x I2C Bus Ports +- 2x CAN Ports +- 2x Power Input Ports + - ADC Power Input + - DroneCAN/UAVCAN Power Input +- 2x Dedicated Debug Port + - FMU Debug + - IO Debug + +## Purchase Channels + +Order from [X-MAV](https://www.x-mav.cn/). + +## 遥控器 + +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). + +将 HW\\u PM 模块的6针连接器连接到飞控的电源接口。 + +SBUS receivers connect to the SBUS-IN input port. +CRSF receiver must be wired to a spare port (UART) on the Flight Controller. Then you can bind the transmitter and receiver together. + +## 串口映射 + +| UART | 设备 | Port | +| ------ | ---------- | ------- | +| USART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | GPS2 | +| USART3 | /dev/ttyS2 | TELEM1 | +| UART4 | /dev/ttyS3 | TELEM2 | +| UART7 | /dev/ttyS4 | TELEM3 | +| UART8 | /dev/ttyS5 | SERIAL4 | + +## PWM Output + +The AP-H743-R1 flight controller supports up to 15 PWM outputs. +The first 8 outputs (labelled M1 to M8) are controlled by a dedicated STM32F103 IOMCU controller. +The remaining 7 outputs (labelled A1 to A7) are the "auxiliary" outputs. +These are directly attached to the STM32H743 FMU controller . + +The 15 PWM outputs are: + +M1 - M8 are connected to the IOMCU. +A1 - A7 are connected to the FMU. + +M1 - M8 support DShot and are in 3 groups: + +- M1, M2 in group 1 +- M3, M4 in group 2 +- M5, M6, M7, M8 in group 3 + +The 7 FMU PWM outputs are in 3 groups: + +- A1 - A4 are in one group. +- A5, A6 are in a 2nd group. +- A7 is in a 3nd group. + +Channels within the same group need to use the same output rate. +If any channel in a group uses DShot then all channels in the group need to use DShot. + +### Electrical data + +- Voltage Ratings: + - Max input voltage: 5.4V + - USB Power Input: 4.75\~5.25V + - Servo Rail Input: 0\~9.9V + +## Battery Monitoring + +The board has connectors for 2 power monitors. + +- POWER1 -- ADC +- POWER2 -- DroneCAN + +The board is configure by default for a analog power monitor, and also has DroneCAN power monitor configured which is enabled. + +## 编译固件 + +To [build PX4](../dev_setup/building_px4.md) for this target, execute: + +```sh +make x-mav_ap-h743r1_default +``` + +## Pinouts and Size + +![AP-H743-R1 pinouts](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-pinouts.png) + +![AP-H743-R1](../../assets/flight_controller/x-mav_ap-h743r1/ap-h743r1-size.png) + +## 支持的平台/机身 + +Any multirotor/airplane/rover or boat that can be controlled using normal RC servos or Futaba S-Bus servos. +The complete set of supported configurations can be found in the [Airframe Reference](../airframes/airframe_reference.md). + +## 调试接口 + +### SWD + +The [SWD interface](../debug/swd_debug.md) operate on the **FMU-DEBUG** port (`FMU-DEBUG`). + +The debug port (`FMU-DEBUG`) uses a [JST SM04B-GHS-TB](https://www.digikey.com/en/products/detail/jst-sales-america-inc/SM04B-GHS-TB/807788) connector and has the following pinout: + +| 针脚 | 信号 | 电压 | +| ---- | ------------------------------ | --------------------- | +| 1(红) | 5V+ | +5V | +| 2 | FMU_SWDIO | +3.3V | +| 3 | FMU_SWCLK | +3.3V | +| 4(黑) | GND | GND | diff --git a/docs/zh/flight_modes/offboard.md b/docs/zh/flight_modes/offboard.md index 63e474ed76..9560407f2c 100644 --- a/docs/zh/flight_modes/offboard.md +++ b/docs/zh/flight_modes/offboard.md @@ -62,6 +62,11 @@ bool thrust_and_torque bool direct_actuator ``` +:::warning +The following list shows the `OffboardControlMode` options for copter, fixed-wing, and VTOL. +For rovers see the [rover section](#rover). +::: + The fields are ordered in terms of priority such that `position` takes precedence over `velocity` and later fields, `velocity` takes precedence over `acceleration`, and so on. 第一个非零字段(从上到下) 定义了Offboard模式所需的有效估计以及可用的设定值消息。 For example, if the `acceleration` field is the first non-zero value, then PX4 requires a valid `velocity estimate`, and the setpoint must be specified using the `TrajectorySetpoint` message. @@ -90,20 +95,93 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - Velocity setpoint (`velocity` different from `NaN` and `position` set to `NaN`). Non-`NaN` values acceleration are used as feedforward terms for the inner loop controllers. - Acceleration setpoint (`acceleration` different from `NaN` and `position` and `velocity` set to `NaN`) - - 所有值都是基于NED(北, 东, 地)坐标系,位置、速度和加速的单位分别为\[m\], \[m/s\] 和\[m/s^2\] 。 + - All values are interpreted in NED (Nord, East, Down) coordinate system and the units are `[m]`, `[m/s]` and `[m/s^2]` for position, velocity and acceleration, respectively. - [px4_msgs::msg::VehicleAttitudeSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleAttitudeSetpoint.msg) - 支持以下输入组合: - quaternion `q_d` + thrust setpoint `thrust_body`. - Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in \[rad/s\]. + Non-`NaN` values of `yaw_sp_move_rate` are used as feedforward terms expressed in Earth frame and in `[rad/s]`. - - 姿态四元数表示无人机机体坐标系FRD(前、右、下) 与NED坐标系之间的旋转。 这个推力是在无人机体轴FRD坐标系下,并归一化为 \[-1, 1\] 。 + - 姿态四元数表示无人机机体坐标系FRD(前、右、下) 与NED坐标系之间的旋转。 + 这个推力是在无人机体轴FRD坐标系下,并归一化为 \[-1, 1\] 。 - [px4_msgs::msg::VehicleRatesSetpoint](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleRatesSetpoint.msg) - 支持以下输入组合: - `roll`, `pitch`, `yaw` and `thrust_body`. - - 所有值都表示在无人机体轴FRD坐标系下。 角速率(roll, pitch, yaw) 单位为\[rad/s\] ,thrust_body归一化为 \[-1, 1\]。 + - 所有值都表示在无人机体轴FRD坐标系下。 + The rates are in `[rad/s]` while thrust_body is normalized in `[-1, 1]`. + +### 无人车 + +Rover modules must set the control mode using `OffboardControlMode` and use the appropriate messages to configure the corresponding setpoints. +The approach is similar to other vehicle types, but the allowed control mode combinations and setpoints are different: + +| Category | 用法 | Setpoints | +| -------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| (Recommended) [Rover Setpoints](#rover-setpoints) | General rover control | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md), [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md), [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md), [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md), [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md), [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| [Actuator Setpoints](#actuator-setpoints) | Direct actuator control | [ActuatorMotors](../msg_docs/ActuatorMotors.md), [ActuatorServos](../msg_docs/ActuatorServos.md) | +| (Deprecated) [Trajectory Setpoint](#deprecated-trajectory-setpoint) | General vehicle control | [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) | + +#### Rover 设置点 + +滚动模块使用层次结构来传播设置点: + +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) + +The "highest" setpoint that is provided will be used within the PX4 rover modules to generate the setpoints that are below it (overriding them!). +这个层次结构有提供有效控制输入的明确规则: + +- Provide a position setpoint **or** +- “左”上的设置点之一(速度 **或** 节点) **和** “右”上的设置点之一(态度、速率 **或** 节点)。 + 所有“左”和“右”设置点的组合都是有效的。 + +The following are all valid setpoint combinations and their respective control flags that must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md) (set all others to _false_). +Additionally, for some combinations we require certain setpoints to be published with `NAN` values so that the setpoints of interest are not overridden by the rover module (due to the hierarchy above). +✓ are the relevant setpoints we publish, and ✗ are the setpoint that need to be published with `NAN` values. + +| Setpoint Combination | Control Flag | [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | [RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| -------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | +| 安装位置 | 位置 | ✓ | | | | | | +| Speed + Attitude | 速度 | | ✓ | | ✓ | | | +| Speed + Rate | 速度 | | ✓ | | ✗ | ✓ | | +| Speed + Steering | 速度 | | ✓ | | ✗ | ✗ | ✓ | +| Throttle + Attitude | attitude | | | ✓ | ✓ | | | +| Throttle + Rate | body_rate | | | ✓ | | ✓ | | +| Throttle + Steering | thrust_and_torque | | | ✓ | | | ✓ | + +:::info +If you intend to use the rover setpoints, we recommend using the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) instead since it simplifies the publishing of these setpoints. +::: + +#### Actuator Setpoints + +Instead of controlling the vehicle using position, speed, rate and other setpoints, you can directly control the motors and actuators using [ActuatorMotors](../msg_docs/ActuatorMotors.md) and [ActuatorServos](../msg_docs/ActuatorServos.md). +In [OffboardControlMode](../msg_docs/OffboardControlMode.md) set `direct_actuator` to _true_ and all other flags to _false_. + +:::info +This bypasses the rover modules including any limits on steering rates or accelerations and the inverse kinematics step. +We recommend using [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) and [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) instead for low level control (see [Rover Setpoints](#rover-setpoints)). +::: + +#### (Deprecated) Trajectory Setpoint + +:::warning +The [Rover Setpoints](#rover-setpoints) are a replacement for the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) and we highly recommend using those instead as they have a well defined behaviour and offer more flexibility. +::: + +The rover modules support the _position_, _velocity_ and _yaw_ fields of the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md). +However, only one of the fields is active at a time and is defined by the flags of [OffboardControlMode](../msg_docs/OffboardControlMode.md): + +| Control Mode Flag | Active Trajectory Setpoint Field | +| ----------------- | -------------------------------- | +| 位置 | 位置 | +| 速度 | 速度 | +| attitude | yaw | + +:::info +Ackermann rovers do not support the yaw setpoint. +::: ### Generic Vehicle @@ -116,8 +194,10 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding - [px4_msgs::msg::ActuatorMotors](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorMotors.msg) + [px4_msgs::msg::ActuatorServos](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ActuatorServos.msg) - 直接控制电机输出和/或伺服系统(舵机)输出。 - - Currently works at lower level than then `control_allocator` module. Do not publish these messages when not in offboard mode. - - 所有值归一化为\[-1, 1\]。 For outputs that do not support negative values, negative entries map to `NaN`. + - Currently works at lower level than then `control_allocator` module. + Do not publish these messages when not in offboard mode. + - All the values normalized in `[-1, 1]`. + For outputs that do not support negative values, negative entries map to `NaN`. - `NaN` maps to disarmed. ## MAVLink 消息 @@ -207,41 +287,7 @@ Before using offboard mode with ROS 2, please spend a few minutes understanding ### 无人车 -- [SET_POSITION_TARGET_LOCAL_NED](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `x`, `y`, `z`) - - Specify the _type_ of the setpoint in `type_mask`: - - ::: info - The _setpoint type_ values below are not part of the MAVLink standard for the `type_mask` field. - :: - - 值为: - - - 12288:悬停设定值(无人机足够接近设定值时会停止)。 - - - Velocity setpoint (only `vx`, `vy`, `vz`) - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) and [MAV_FRAME_BODY_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_BODY_NED). - -- [SET_POSITION_TARGET_GLOBAL_INT](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_GLOBAL_INT) - - The following input combinations are supported (in `type_mask`): - - Position setpoint (only `lat_int`, `lon_int`, `alt`) - - - Specify the _type_ of the setpoint in `type_mask` (not part of the MAVLink standard). - 值为: - - 下面的比特位没有置位,是正常表现。 - - 12288:悬停设定值(无人机足够接近设定值时会停止)。 - - - PX4 supports the coordinate frames (`coordinate_frame` field): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL). - -- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET) - - 支持以下输入组合: - - Attitude/orientation (`SET_ATTITUDE_TARGET.q`) with thrust setpoint (`SET_ATTITUDE_TARGET.thrust`). - ::: info - Only the yaw setting is actually used/extracted. - -::: +Rover does not support a MAVLink offboard API (ROS2 is supported). ## Offboard参数 diff --git a/docs/zh/flight_modes_fw/hold.md b/docs/zh/flight_modes_fw/hold.md index 437613fbb0..f47d5873e8 100644 --- a/docs/zh/flight_modes_fw/hold.md +++ b/docs/zh/flight_modes_fw/hold.md @@ -2,11 +2,14 @@ -The _Hold_ flight mode causes the vehicle to loiter (circle) around its current GPS position and maintain its current altitude. +The _Hold_ flight mode causes the vehicle to loiter around its current GPS position and maintain its current altitude. + +The mode supports a [number of distinct loiter modes](#loiter-modes), which are triggered using different QGC controls or MAVLink commands. +These allow loitering with circular and figure 8 flight paths. :::tip _Hold mode_ can be used to pause a mission or to help you regain control of a vehicle in an emergency. -It is usually activated with a pre-programmed switch. +It is usually activated with a pre-programmed RC switch. ::: ::: info @@ -24,24 +27,80 @@ It is usually activated with a pre-programmed switch. ::: -## 技术总结 +## Loiter modes -The aircraft circles around the GPS hold position at the current altitude. -The vehicle will first ascend to [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT) if the mode is engaged below this altitude. +### Default Loiter -RC stick movement is ignored. +The aircraft circles around the position at which the mode was triggered and maintain its current altitude. +The loiter radius is set by the parameter [NAV_LOITER_RAD](#NAV_LOITER_RAD). +Note that if the vehicle altitude is below [NAV_MIN_LTR_ALT](#NAV_MIN_LTR_ALT), it will ascend to that minimum altitude before circling. -### 参数 +The default loiter mode is entered when you switch to Hold mode without explicitly specifying any loiter behaviour. +For example, if you switch to Hold mode using an RC switch, select **Hold** on the QGC flight mode selector, or activate the mode using the MAVLink [MAV_CMD_DO_SET_MODE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) command. + +### Orbit Loiter Mode + + + +The aircraft travels towards a _specified_ orbit center position, then circles it with a given direction and radius. + +This behaviour can be accessed in QGroundControl by clicking on the map in Fly view, selecting **Orbit at Location**, and configuring the radius. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) command. +Note that PX4 respects the specified centre point (`param5`, `param6`, `param7`), and the radius and direction (`param1`). +PX4 ignores `param3` (Yaw behaviour) and `param4` (Orbits). +The value of `param2` (velocity) is also ignored, but the speed can be controlled using the [MAV_CMD_DO_CHANGE_SPEED](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) command (constrained between `FW_AIRSPD_MAX` and `FW_AIRSPD_MIN`). +PX4 outputs orbit status using the [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) message. + +### Figure 8 Loiter Mode + + + +The aircraft flys towards the closest point on a specified figure 8 path and then follows it. +The path is defined by the figure 8 centre position, orientation, and radius of two circles. + +The feature is experimental, and is not present in PX4 firmware by default (on most flight controller boards). +It can be included by setting the `CONFIG_FIGURE_OF_EIGHT` key in the [PX4 board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) for your board and rebuilding. +For example, this is enabled on the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/auterion/fmu-v6s/default.px4board#L46) file for the `auterion/fmu-v6s` board. + +The behavior can be triggered using the MAVLink [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) command (PX4 respects all the parameters). +PX4 outputs the figure 8 status using the [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) message. + +:::info +Figure 8 loitering is not currently supported by QGC: [QGC#12778: Need Support Figure of eight (8 figure) loitering by QGC](https://github.com/mavlink/qgroundcontrol/issues/12778). +::: + +Figure 8 loitering is also available in the simulator. +You can test it in [Gazebo](../sim_gazebo_gz/index.md) using a fixed wing frame: + +```sh +make px4_sitl gz_rc_cessna +``` + +## 参数 Hold mode behaviour can be configured using the parameters below. | 参数 | 描述 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | +| [NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The radius of the loiter circle. | | [NAV_MIN_LTR_ALT](../advanced_config/parameter_reference.md#NAV_MIN_LTR_ALT) | Minimum height for loiter mode (vehicle will ascend to this altitude if mode is engaged at a lower altitude). | -## See Also +## MAVLink Commands -[Hold Mode (MC)](../flight_modes_mc/hold.md) +The following commands are relevant to this mode: + +- [MAV_CMD_DO_ORBIT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_ORBIT) - Switch to Hold mode and start the specified [Orbit loiter](#orbit-loiter-mode). + Params 2 (velocity), 3 (yaw), 4 (orbits) are ignored. + [ORBIT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#ORBIT_EXECUTION_STATUS) is emitted. +- [MAV_CMD_DO_FIGURE_EIGHT](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_FIGURE_EIGHT) - Switch to Hold mode and start the specified [Figure 8 loiter](#figure-8-loiter-mode). + All params are respected. + [FIGURE_EIGHT_EXECUTION_STATUS](https://mavlink.io/en/messages/common.html#FIGURE_EIGHT_EXECUTION_STATUS) is emitted. + +Note, other commands may be supported. + +## 另见 + +- [Hold Mode (MC)](../flight_modes_mc/hold.md) diff --git a/docs/zh/flight_modes_fw/index.md b/docs/zh/flight_modes_fw/index.md index d6fd66e2f5..0c9f655ad4 100644 --- a/docs/zh/flight_modes_fw/index.md +++ b/docs/zh/flight_modes_fw/index.md @@ -17,6 +17,8 @@ Manual-Easy: Airspeed is actively controlled if an airspeed sensor is installed. - [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). - [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. diff --git a/docs/zh/flight_modes_fw/land.md b/docs/zh/flight_modes_fw/land.md index 0a4220437d..2bb388a0a7 100644 --- a/docs/zh/flight_modes_fw/land.md +++ b/docs/zh/flight_modes_fw/land.md @@ -48,7 +48,7 @@ Land mode behaviour can be configured using the parameters below. | [FW_LND_AIRSPD](../advanced_config/parameter_reference.md#FW_LND_AIRSPD) | The airspeed setpoint. | | [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 +## 另见 - [Land Mode (MC)](../flight_modes_mc/land.md) - [Land Mode (VTOL)](../flight_modes_vtol/land.md) diff --git a/docs/zh/flight_modes_fw/mission.md b/docs/zh/flight_modes_fw/mission.md index 991a4bb846..ee19cd8b22 100644 --- a/docs/zh/flight_modes_fw/mission.md +++ b/docs/zh/flight_modes_fw/mission.md @@ -29,32 +29,32 @@ At high level all vehicle types behave in the same way when MISSION mode is enga 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". + - If flying the vehicle will loiter. + - If landed the vehicle will "wait". 2. If a mission is stored and PX4 is flying it will execute the [mission/flight plan](../flying/missions.md) from the current step. - - A takeoff mission item will be treated as a normal waypoint. + - A takeoff mission item will be treated as a normal waypoint. 3. If a mission is stored and the vehicle is landed it will only takeoff if the active waypoint is a `Takeoff`. - If configured for catapult launch, the vehicle must also be launched (see [FW Takeoff/Landing in Mission](#mission-takeoff)). + If configured for catapult launch, the vehicle must also be launched (see [FW Takeoff/Landing in Mission](#mission-takeoff)). 4. If no mission is stored, or if PX4 has finished executing all mission commands: - - If flying the vehicle will loiter. - - If landed the vehicle will "wait". + - If flying the vehicle will loiter. + - If landed the vehicle will "wait". 5. You can manually change the current mission command by selecting it in _QGroundControl_. - ::: info - If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. - One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. + ::: info + If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. + One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. ::: 6. The mission will only reset when the vehicle is disarmed or when a new mission is uploaded. - :::tip - To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. - Enter the time to wait after landing before disarming the vehicle. + :::tip + To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. + Enter the time to wait after landing before disarming the vehicle. ::: @@ -167,6 +167,10 @@ Mission Items: - [MAV_CMD_OBLIQUE_SURVEY](https://mavlink.io/en/messages/common.html#MAV_CMD_OBLIQUE_SURVEY) - [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. GeoFence Definitions @@ -261,7 +265,7 @@ This pattern results in the following landing sequence: 1. **Fly to landing location**: The aircraft flies at its current altitude towards the loiter waypoint. 2. **Descending orbit to approach altitude**: On reaching the loiter radius of the waypoint, the vehicle performs a descending orbit until it reaches the "approach altitude" (the altitude of the loiter waypoint). - The vehicle continues to orbit at this altitude until it has a tanjential path towards the land waypoint, at which point the landing approach is initiated. + The vehicle continues to orbit at this altitude until it has a tanjential path towards the land waypoint, at which point the landing approach is initiated. 3. **Landing approach**: The aircraft follows the landing approach slope towards the land waypoint until the flare altitude is reached. 4. **Flare**: The vehicle flares until it touches down. @@ -374,7 +378,7 @@ In landing mode, the distance sensor is used to determine proximity to the groun | [FW_WING_SPAN](../advanced_config/parameter_reference.md#FW_WING_SPAN) | Wing span of the airframe. | | [FW_WING_HEIGHT](../advanced_config/parameter_reference.md#FW_WING_HEIGHT) | Height of wing from bottom of gear (or belly if no gear). | -## See Also +## 另见 - [Missions](../flying/missions.md) - [包裹投递任务](../flying/package_delivery_mission.md) diff --git a/docs/zh/flight_modes_fw/return.md b/docs/zh/flight_modes_fw/return.md index 62eefc6e2d..db71badb10 100644 --- a/docs/zh/flight_modes_fw/return.md +++ b/docs/zh/flight_modes_fw/return.md @@ -61,7 +61,7 @@ The others are relevant if the destination is a rally point or the home location | [RTL_LOITER_RAD](../advanced_config/parameter_reference.md#RTL_LOITER_RAD) | [Fixed-wing Only] The radius of the loiter circle (at [RTL_LAND_DELAY](#RTL_LAND_DELAY)). | | [MIS_TKO_LAND_REQ](../advanced_config/parameter_reference.md#MIS_TKO_LAND_REQ) | Specify whether a mission landing or takeoff pattern is required. Fixed wings generally require this. | -## See Also +## 另见 - [Return Mode (Generic)](../flight_modes/return.md) - [Return Mode (Multicopter)](../flight_modes_mc/return.md) diff --git a/docs/zh/flight_modes_fw/takeoff.md b/docs/zh/flight_modes_fw/takeoff.md index 010e4793ff..92f085c721 100644 --- a/docs/zh/flight_modes_fw/takeoff.md +++ b/docs/zh/flight_modes_fw/takeoff.md @@ -49,8 +49,8 @@ If the local position is invalid or becomes invalid while executing the takeoff, ::: info -- Takeoff towards a target position was added in . -- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . +- Takeoff towards a target position was added in . +- Holding wings level and ascending to clearance attitude when local position is invalid during takeoff was added in . - QGroundControl does not support `MAV_CMD_NAV_TAKEOFF` (at time of writing). ::: @@ -93,7 +93,7 @@ To launch in this mode: 1. Arm the vehicle 2. Put the vehicle into _Takeoff mode_ 3. Launch/throw the vehicle (firmly) directly into the wind. - You can also shake the vehicle first, wait till the motor spins up and then throw it + You can also shake the vehicle first, wait till the motor spins up and then throw it ### Parameters (Launch Detector) @@ -142,7 +142,7 @@ Runway takeoff is affected by the following parameters: | [FW_WING_SPAN](../advanced_config/parameter_reference.md#FW_WING_SPAN) | The wingspan of the vehicle. Used to prevent wingstrikes. | | [FW_WING_HEIGHT](../advanced_config/parameter_reference.md#FW_WING_HEIGHT) | The height of the wings above ground (ground clearance). Used to prevent wingstrikes. | -## See Also +## 另见 - [Takeoff Mode (MC)](../flight_modes_mc/takeoff.md) - [Planning a mission takeoff](../flight_modes_fw/mission.md#mission-takeoff) diff --git a/docs/zh/flight_modes_mc/altitude.md b/docs/zh/flight_modes_mc/altitude.md index 3e1af11c58..4ff9b639e8 100644 --- a/docs/zh/flight_modes_mc/altitude.md +++ b/docs/zh/flight_modes_mc/altitude.md @@ -21,7 +21,7 @@ The diagram below shows the mode behaviour visually (for a [mode 2 transmitter]( RC/manual mode like [Stabilized mode](../flight_modes_mc/manual_stabilized.md) but with _altitude stabilization_ (centred sticks level vehicle and hold it to fixed altitude). The horizontal position of the vehicle can move due to wind (or pre-existing momentum). -- 回正摇杆(内带死区): +- Centered sticks: - RPY摇杆使飞机水平。 - 油门(~50%)抗风保持当前姿态。 - 外部中心: @@ -43,9 +43,8 @@ The horizontal position of the vehicle can move due to wind (or pre-existing mom 该模式受以下参数影响: -| 参数 | 描述 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 最大垂直上升速度。 默认:3m/s。 | -| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 最大垂直下降速度。 默认:1m/s。 | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | -| `MPC_XXXX` | 大多数 MPC_xxx参数会影响此模式下的飞行行为(至少在某种程度上)。 For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | +| 参数 | 描述 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 最大垂直上升速度。 默认:3m/s。 | +| [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 最大垂直下降速度。 默认:1m/s。 | +| `MPC_XXXX` | 大多数 MPC_xxx参数会影响此模式下的飞行行为(至少在某种程度上)。 For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | diff --git a/docs/zh/flight_modes_mc/altitude_cruise.md b/docs/zh/flight_modes_mc/altitude_cruise.md new file mode 100644 index 0000000000..eda1cf30ce --- /dev/null +++ b/docs/zh/flight_modes_mc/altitude_cruise.md @@ -0,0 +1,45 @@ +# Altitude Cruise Mode (Multicopter) + +   + +_Altitude Cruise mode_ is a _relatively_ easy-to-fly manual control mode in which roll and pitch sticks control vehicle movement in the left-right and forward-back directions (relative to the "front" of the vehicle), yaw stick controls rate of rotation over the horizontal plane, and throttle controls speed of ascent-descent. + +When the sticks are released/centered the vehicle will keep the current tilt and heading angle and maintain the current _altitude_. +If moving in the horizontal plane the vehicle will accelerate until the wind resistance equals the acceleration caused by the set tilt angle. +The vehicle will then continue to move with a constant velocity (unlike for Altitude mode, in which the vehicle will eventually slow down and stop). +If the wind blows the aircraft will drift in the direction of the wind even if flying perfectly level. + +:::tip +_Altitude Cruise mode_ is intended for long distance flights where the same tilt angle is kept for a long period of time. It is just like [Altitude](../flight_modes_mc/altitude.md) mode but does not go back to level tilt when the sticks are released. +::: + +The diagram below shows the mode behaviour visually (for a [mode 2 transmitter](../getting_started/rc_transmitter_receiver.md#transmitter_modes)). + +![Altitude Control MC - Mode2 RC Controller](../../assets/flight_modes/altitude_mc.png) + +## 技术总结 + +A manual mode that is similar to [Altitude mode](../flight_modes_mc/altitude.md) but with different interpretation of roll and pitch sticks. + +- Centered sticks: + - Roll/Pitch sticks: the current tilt is kept. + - Yaw: the current heading is kept. + - Throttle (~50%) holds current altitude. +- 外部中心: + - Roll/Pitch sticks control the rate of change of the tilt angle, resulting in corresponding left-right and forward-back movement. A maximum stick deflection results in a tilting rate setpoint to go from level to max tilt within 0.5 seconds. + - Yaw stick deflection rotates the tilt angle either left or right, causing the vehicle to change course. It is _not_ causing a direct rotation around the body yaw axis like in [Acro mode](../flight_modes_mc/acro.md). + - 油门摇杆以预定的最大速率(和其他轴上的移动速度)控制上升速度。 +- 起飞: + - 降落时,如果将油门杆抬高至 62.5%(从油门杆最低开始的整个范围),无人机将起飞。 +- Manual control input is required (such as RC control, joystick) to enter this mode. Other than in all other manual modes, it's though possible to disable the manual control loss failsafe by setting the corresponding flag in [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT). In that case the current altitude, tilt and heading 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, and to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT). + +## 参数 + +Most of the relevant parameters are already covered in the corresponding section in the [Altitude mode](../flight_modes_mc/altitude.md). Here a list of parameters of particular importance for Altitude Cruise. + +| 参数 | 描述 | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | The manual control failsafe can be disabled for Altitude Cruise by setting the corresponding bit in this parameter. | +| [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Data link lost failsafe action. Recommended to set if the manual control failsafe is disabled to avoid fly-aways. | +| [MPC_MAN_TILT_MAX](../advanced_config/parameter_reference.md#MPC_MAN_TILT_MAX) | The maximum tilt angle the vehicle will go to. At max stick deflection, it will take 0.5 seconds from level flight to this tilt angle. | diff --git a/docs/zh/flight_modes_mc/follow_me.md b/docs/zh/flight_modes_mc/follow_me.md index 3e8b4ecab5..a356ffd919 100644 --- a/docs/zh/flight_modes_mc/follow_me.md +++ b/docs/zh/flight_modes_mc/follow_me.md @@ -151,19 +151,19 @@ The follow-me behavior can be configured using the following parameters: 1. Set the [follow distance](#FLW_TGT_DST) to more than 12 meters (8 meters is a "recommended minimum"). - There is an inherent position bias (3 ~ 5 meters) between the target and the drone's GPS sensor, which makes the drone follow a 'ghost target' somewhere near the actual target. This is more obvious when the follow distance is very small. We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. - This is more obvious when the follow distance is very small. - We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. + There is an inherent position bias (3 ~ 5 meters) between the target and the drone's GPS sensor, which makes the drone follow a 'ghost target' somewhere near the actual target. This is more obvious when the follow distance is very small. We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. + This is more obvious when the follow distance is very small. + We recommend that the follow distance is set to be large enough such that the GPS bias is not significant. 2. The speed at which you can change the follow angle depends on the [maximum tangential velocity](#FLW_TGT_MAX_VEL) setting. - Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. + Experimentation shows that values between `5 m/s` are `10 m/s` are usually suitable. 3. Using the RC Adjustment for height, distance and angle, you can get some creative camera shots. - + - 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. + 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. ## 已知的问题 diff --git a/docs/zh/flight_modes_mc/hold.md b/docs/zh/flight_modes_mc/hold.md index e65feb8774..605746c6f0 100644 --- a/docs/zh/flight_modes_mc/hold.md +++ b/docs/zh/flight_modes_mc/hold.md @@ -43,6 +43,6 @@ Hold mode behaviour can be configured using the parameters below. -## See Also +## 另见 [Hold Mode (FW)](../flight_modes_fw/hold.md) diff --git a/docs/zh/flight_modes_mc/index.md b/docs/zh/flight_modes_mc/index.md index 806046c6e7..1b407d6239 100644 --- a/docs/zh/flight_modes_mc/index.md +++ b/docs/zh/flight_modes_mc/index.md @@ -21,10 +21,12 @@ Manual-Easy: - [Stabilized mode](../flight_modes_mc/manual_stabilized.md) — Releasing the sticks levels and maintains the vehicle horizontal posture (but not altitude or position). The vehicle will continue to move with momentum, and both altitude and horizontal position may be affected by wind. This mode is also used if "Manual mode" is selected in a ground station. +- [Altitude Cruise mode](../flight_modes_mc/altitude_cruise.md) — Very similar to _Altitude mode_, with the difference that when the roll and pitch sticks are released the vehicle does not level out but keeps the tilt until further inputs are given. + Additionally it is possible to disable the manual control failsafe for this mode, having the vehicle continue on it's set path even if there are no new control inputs. Manual-Acrobatic -- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic maneuvers, such as rolls and loops. +- [Acro](../flight_modes_mc/acro.md) — Manual mode for performing acrobatic manoeuvrers, such as rolls and loops. Releasing the sticks stops the vehicle rotating in the roll, pitch, yaw axes, but does not otherwise stabilise the vehicle. Autonomous: diff --git a/docs/zh/flight_modes_mc/land.md b/docs/zh/flight_modes_mc/land.md index f3cfe60a07..70f6c5d843 100644 --- a/docs/zh/flight_modes_mc/land.md +++ b/docs/zh/flight_modes_mc/land.md @@ -38,7 +38,7 @@ Land mode behaviour can be configured using the parameters below. | [COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). 可以分别为自动模式和 offboard 模式启用此功能,默认情况下在自动模式下启用此功能。 | | [COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). | -## See Also +## 另见 - [Land Mode (FW)](../flight_modes_fw/land.md) - [Land Mode (VTOL)](../flight_modes_vtol/land.md) diff --git a/docs/zh/flight_modes_mc/manual_stabilized.md b/docs/zh/flight_modes_mc/manual_stabilized.md index 671368ee82..b1f9de1f78 100644 --- a/docs/zh/flight_modes_mc/manual_stabilized.md +++ b/docs/zh/flight_modes_mc/manual_stabilized.md @@ -31,7 +31,7 @@ Throttle is rescaled (see [below](#params)) and passed directly to control alloc 自动驾驶仪控制着飞机的姿态角,这意味着当 RC 摇杆居中时自驾仪调整飞机的滚转和俯仰角为零(从而实现飞机姿态的改平)。 自动驾驶仪不能补偿由于风(或其他来源)引起的漂移。 -- 回正摇杆(内带死区): +- Centered sticks: - Roll/Pitch sticks level vehicle. - 外部中心: - Roll/Pitch sticks control tilt angle in those orientations, resulting in corresponding left-right and forward-back movement. diff --git a/docs/zh/flight_modes_mc/mission.md b/docs/zh/flight_modes_mc/mission.md index 5f6088aded..9d30914129 100644 --- a/docs/zh/flight_modes_mc/mission.md +++ b/docs/zh/flight_modes_mc/mission.md @@ -31,33 +31,33 @@ At high level all vehicle types behave in the same way when MISSION mode is enga 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". + - If flying the vehicle will hold. + - If landed the vehicle will "wait". 2. If a mission is stored and PX4 is flying it will execute the [mission/flight plan](../flying/missions.md) from the current step. - - A `TAKEOFF` item is treated as a normal waypoint. + - A `TAKEOFF` item is treated as a normal waypoint. 3. If a mission is stored and PX4 is landed: - - PX4 will execute the [mission/flight plan](../flying/missions.md). - - If the mission does not have a `TAKEOFF` item then PX4 will fly the vehicle to the minimum altitude before executing the remainder of the flight plan from the current step. + - PX4 will execute the [mission/flight plan](../flying/missions.md). + - If the mission does not have a `TAKEOFF` item then PX4 will fly the vehicle to the minimum altitude before executing the remainder of the flight plan from the current step. 4. If no mission is stored, or if PX4 has finished executing all mission commands: - - If flying the vehicle will hold. - - If landed the vehicle will "wait". + - If flying the vehicle will hold. + - If landed the vehicle will "wait". 5. You can manually change the current mission command by selecting it in _QGroundControl_. - ::: info - If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. - One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. + ::: info + If you have a _Jump to item_ command in the mission, moving to another item will **not** reset the loop counter. + One implication is that if you change the current mission command to 1 this will not "fully restart" the mission. ::: 6. The mission will only reset when the vehicle is disarmed or when a new mission is uploaded. - :::tip - To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. - Enter the time to wait after landing before disarming the vehicle. + :::tip + To automatically disarm the vehicle after it lands, in _QGroundControl_ go to [Vehicle Setup > Safety](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/safety.html), navigate to _Land Mode Settings_ and check the box labeled _Disarm after_. + Enter the time to wait after landing before disarming the vehicle. ::: @@ -171,6 +171,9 @@ Mission Items: - [MAV_CMD_NAV_VTOL_TAKEOFF](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_VTOL_TAKEOFF) - `MAV_CMD_NAV_VTOL_TAKEOFF.param2` (transition heading) is ignored. Instead the heading to the next waypoint is used for the transition heading. +- [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) . GeoFence Definitions @@ -228,7 +231,7 @@ If a mission with no takeoff mission item is started, the vehicle will ascend to If the vehicle is already flying when the mission is started, a takeoff mission item is treated as a normal waypoint. -## See Also +## 另见 - [Missions](../flying/missions.md) - [包裹投递任务](../flying/package_delivery_mission.md) diff --git a/docs/zh/flight_modes_mc/position.md b/docs/zh/flight_modes_mc/position.md index fa70ad7997..f32b4f357b 100644 --- a/docs/zh/flight_modes_mc/position.md +++ b/docs/zh/flight_modes_mc/position.md @@ -43,7 +43,7 @@ While very rare on a well calibrated vehicle, sometimes there may be problems wi 遥控模式下,横滚、俯仰、油门 (RPT) 杆控制相应轴/方向的运动。 摇杆居中使机体水平并将其保持在固定的高度和位置并抗风。 -- Centered roll, pitch, throttle sticks (within RC deadzone [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ)) hold x, y, z position steady against any disturbance like wind. +- Centered roll, pitch, throttle sticks (within RC deadzone [MAN_DEADZONE](#MAN_DEADZONE)) hold x, y, z position steady against any disturbance like wind. - 外部中心: - Roll/Pitch sticks control horizontal acceleration over ground in the vehicle's left-right and forward-back directions (respectively). - Throttle stick controls speed of ascent-descent. @@ -62,12 +62,11 @@ All the parameters in the [Multicopter Position Control](../advanced_config/para | 参数 | 描述 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [MPC_HOLD_DZ](../advanced_config/parameter_reference.md#MPC_HOLD_DZ) | 启用位置保持的摇杆死区。 默认值:0.1(摇杆全行程的 10%)。 | +| [MAN_DEADZONE](../advanced_config/parameter_reference.md#MAN_DEADZONE) | 启用位置保持的摇杆死区。 默认值:0.1(摇杆全行程的 10%)。 | | [MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | 最大垂直上升速度。 默认:3m/s。 | | [MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | 最大垂直下降速度。 默认:1m/s。 | | [MPC_LAND_ALT1](../advanced_config/parameter_reference.md#MPC_LAND_ALT1) | 触发第一阶段降速的高度。 Below this altitude descending velocity gets limited to a value between [MPC_Z_VEL_MAX_DN](#MPC_Z_VEL_MAX_DN) (or `MPC_Z_V_AUTO_DN`) and [MPC_LAND_SPEED](#MPC_LAND_SPEED). Value needs to be higher than [MPC_LAND_ALT2](#MPC_LAND_ALT2). Default 10m. | | [MPC_LAND_ALT2](../advanced_config/parameter_reference.md#MPC_LAND_ALT2) | 触发第二阶段降速的高度。 Below this altitude descending velocity gets limited to [`MPC_LAND_SPEED`](#MPC_LAND_SPEED). Value needs to be lower than "MPC_LAND_ALT1". Default 5m. | -| `RCX_DZ` | RC dead zone for channel X. The value of X for throttle will depend on the value of [RC_MAP_THROTTLE](../advanced_config/parameter_reference.md#RC_MAP_THROTTLE). For example, if the throttle is channel 4 then [RC4_DZ](../advanced_config/parameter_reference.md#RC4_DZ) specifies the deadzone. | | `MPC_XXXX` | 大多数 MPC_xxx参数会影响此模式下的飞行行为(至少在某种程度上)。 For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. | | [MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | 从摇杆输入到机体动作的转换策略。 From PX4 v1.12 the default (`Acceleration based`) is that stick position controls acceleration (in a similar way to a car accelerator pedal). 其他选项允许操纵杆偏转直接控制地面速度,有或没有平滑和加速度限制。 | | [MPC_ACC_HOR_MAX](../advanced_config/parameter_reference.md#MPC_ACC_HOR_MAX) | 最大水平加速度。 | @@ -82,6 +81,6 @@ All the parameters in the [Multicopter Position Control](../advanced_config/para If the estimate falls below acceptable levels, for example due to GPS loss, this may trigger a [Position (GPS) Loss Failsafe](../config/safety.md#position-gnss-loss-failsafe). 如果估计值低于可接受的水平,例如由于 GPS 丢失,这可能会触发位置 (GPS) 丢失故障保护 根据配置,是否有遥控器,以及是否有足够的高度估计,PX4 可能会切换到高度模式、手动模式、降落模式或终止。 -## See Also +## 另见 - [Position Slow Mode](../flight_modes_mc/position_slow.md) diff --git a/docs/zh/flight_modes_mc/position_slow.md b/docs/zh/flight_modes_mc/position_slow.md index d89bf42aff..24a81c5985 100644 --- a/docs/zh/flight_modes_mc/position_slow.md +++ b/docs/zh/flight_modes_mc/position_slow.md @@ -88,6 +88,6 @@ The value can be updated from a message at any time, and is latched until either Note that PX4 does not provide velocity limit telemetry (i.e. it does not support streaming the [VELOCITY_LIMITS](https://mavlink.io/en/messages/development.html#VELOCITY_LIMITS) message). -## See Also +## 另见 - [Position Slow Mode](../flight_modes_mc/position.md) diff --git a/docs/zh/flight_modes_mc/return.md b/docs/zh/flight_modes_mc/return.md index a933ab4567..f24fd32ddc 100644 --- a/docs/zh/flight_modes_mc/return.md +++ b/docs/zh/flight_modes_mc/return.md @@ -70,7 +70,7 @@ The parameters that are relevant to multicopter (assuming the [RTL_TYPE](../adva | [COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md) (except when vehicle is handling a critical battery failsafe). 可以分别为自动模式和 offboard 模式启用此功能,默认情况下在自动模式下启用此功能。 | | [COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled). | -## See Also +## 另见 - [Return Mode (Generic)](../flight_modes/return.md) - [Return Mode (Fixed-Wing)](../flight_modes_fw/return.md) diff --git a/docs/zh/flight_modes_mc/takeoff.md b/docs/zh/flight_modes_mc/takeoff.md index beed798c98..0cb1d3460f 100644 --- a/docs/zh/flight_modes_mc/takeoff.md +++ b/docs/zh/flight_modes_mc/takeoff.md @@ -36,7 +36,7 @@ Takeoff is affected by the following parameters: | [COM_RC_OVERRIDE](../advanced_config/parameter_reference.md#COM_RC_OVERRIDE) | Controls whether stick movement on a multicopter (or VTOL in MC mode) causes a mode change to [Position mode](../flight_modes_mc/position.md). 可以分别为自动模式和 offboard 模式启用此功能,默认情况下在自动模式下启用此功能。 | | [COM_RC_STICK_OV](../advanced_config/parameter_reference.md#COM_RC_STICK_OV) | The amount of stick movement that causes a transition to [Position mode](../flight_modes_mc/position.md) (if [COM_RC_OVERRIDE](#COM_RC_OVERRIDE) is enabled) | -## See Also +## 另见 - [Throw Launch (MC)](../flight_modes_mc/throw_launch.md) - [Takeoff Mode (FW)](../flight_modes_fw/takeoff.md) diff --git a/docs/zh/flight_modes_mc/throw_launch.md b/docs/zh/flight_modes_mc/throw_launch.md index 68454dc735..d421442b5f 100644 --- a/docs/zh/flight_modes_mc/throw_launch.md +++ b/docs/zh/flight_modes_mc/throw_launch.md @@ -43,16 +43,16 @@ Also ensure that the propellers do not spin on arming after enabling the feature In addition: 1. Wear safety equipment. - Eye protection and work gloves are recommended. + Eye protection and work gloves are recommended. 2. Have an easily accessible and tested [kill switch](../config/safety.md#kill-switch). - Remind the operator to be attentive and use the kill switch if needed. - Pilots tend to forget that vehicles are replaceable, but they are not! + Remind the operator to be attentive and use the kill switch if needed. + Pilots tend to forget that vehicles are replaceable, but they are not! 3. Test as much as possible without propellers. - Keep the tools for removing propellers nearby/readily accessible. + Keep the tools for removing propellers nearby/readily accessible. 4. Test this feature with at least two people — one handling the aircraft, the other one the remote control. 5. Keep in mind that after the throw, the exact behavior of the aircraft might be hard to predict as it depends heavily on the way it is thrown. - Sometimes it will stay perfectly in place, but sometimes (e.g., due to extensive roll), it might drift to one side while stabilizing. - Keep a safe distance! + Sometimes it will stay perfectly in place, but sometimes (e.g., due to extensive roll), it might drift to one side while stabilizing. + Keep a safe distance! On first flight of a new vehicle we recommend performing a [Throw Launch test without propellers](#throw-launch-pretest) (see below). @@ -65,13 +65,13 @@ The steps for this test are: 1. Dismount the propellers. 2. Set [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) to `Enabled`. 3. Arm the aircraft. - The engines should not spin, but the vehicle should be armed and keep playing the arming tune. + The engines should not spin, but the vehicle should be armed and keep playing the arming tune. 4. Throw the aircraft about 2m into the air. - If the aircraft is not thrown high enough, the motors will not turn on. + If the aircraft is not thrown high enough, the motors will not turn on. 5. The engines should start just after crossing the apex. 6. Engage the kill switch (ideally a second person operating the RC should do this). 7. Catch the drone. - Remember to use safety gloves! + Remember to use safety gloves! ## Throw Launch @@ -79,12 +79,12 @@ The steps for a throw launch are: 1. Set [COM_THROW_EN](../advanced_config/parameter_reference.md#COM_THROW_EN) to `Enabled`. 2. Arm the aircraft. - The propellers should not spin, but the vehicle should be armed and keep playing the arming tune. + The propellers should not spin, but the vehicle should be armed and keep playing the arming tune. 3. Throw the aircraft away from you, forward and up (about 2m away and 2m up is recommended). - - The vehicle must reach the speed of [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED) to detect launch, which by default is set to 5 m/s. - If this speed is not achieved, the motors will not start and the aircraft will fall to the ground. - - Try to avoid excessive rotation during the throw, as this might cause the drone to fail or behave unpredictably. - The exact meaning of "excessive rotation" depends on the platform: for instance, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md) used for the testing, still managed to recover after 2-3 full rotations. + - The vehicle must reach the speed of [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED) to detect launch, which by default is set to 5 m/s. + If this speed is not achieved, the motors will not start and the aircraft will fall to the ground. + - Try to avoid excessive rotation during the throw, as this might cause the drone to fail or behave unpredictably. + The exact meaning of "excessive rotation" depends on the platform: for instance, [PX4Vision](../complete_vehicles_mc/px4_vision_kit.md) used for the testing, still managed to recover after 2-3 full rotations. 4. After a downward velocity is detected (the vehicle reaches its apex and starts falling down), the motors should turn on and the vehicle will start flying in the current mode. ## 参数 @@ -95,7 +95,7 @@ The following parameters can be used to enable and configure throw launch: - [COM_THROW_SPEED](../advanced_config/parameter_reference.md#COM_THROW_SPEED) determines the minimum speed the aircraft should reach to detect the throw. If it is not reached, the engines will not turn on. -## See Also +## 另见 - [Takeoff Mode (Fixed-Wing) > Catapult/Hand Launch](../flight_modes_fw/takeoff.md#catapult-hand-launch). diff --git a/docs/zh/flight_modes_rover/api.md b/docs/zh/flight_modes_rover/api.md new file mode 100644 index 0000000000..1783ee9344 --- /dev/null +++ b/docs/zh/flight_modes_rover/api.md @@ -0,0 +1,29 @@ +# Apps & API + +The rover modules have been tested and integrated with a subset of the available [Apps & API](../middleware/index.md) methods. +We specifically provide guides for using [ROS 2](../ros2/index.md) to interface a companion computer with PX4 via [uXRCE-DDS](../middleware/uxrce_dds.md). + +| Method | 描述 | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [PX4 ROS 2 Interface](#px4-ros-2-interface) (Recommended) | Register a custom mode and publish [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). | +| [ROS 2 Offboard Control](#ros-2-offboard-control) | Use the PX4 internal [Offboard Mode](../flight_modes/offboard.md) and publish messages defined in [dds_topics.yaml](../middleware/dds_topics.md). | + +## PX4 ROS 2 Interface + +We recommend the use of the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) which allows you to register a custom drive mode and exposes [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints). + +By using these setpoints (instead of the PX4 internal rover setpoints), you are guaranteed to send valid control inputs to your vehicle and the control flags for the setpoints you are using are automatically set for you. +Registering a custom drive mode instead of using [ROS 2 Offboard Control](#ros-2-offboard-control) additionally provides the advantages listed [here](../concept/flight_modes.md#internal-vs-external-modes). + +To get familiar with this method, read through the guide for the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) where we also provide an example app for rover. + +## ROS 2 Offboard Control + +[ROS 2 Offboard Control](../ros2/offboard_control.md) uses the PX4 internal [Offboard Mode](../flight_modes/offboard.md). + +While you can subscribe/publish to all topics specified in [dds_topics.yaml](../middleware/dds_topics.md), not all rover modules support all of these topics (see [Supported Setpoints](../flight_modes/offboard.md#rover)). +Unlike the [RoverSetpointTypes](../ros2/px4_ros2_control_interface.md#rover-setpoints) exposed through the [PX4 ROS 2 Interface](#px4-ros-2-interface), there is no guarantee that the published setpoints lead to a valid control input. + +In addition, the correct control mode flags must be set through [OffboardControlMode](../msg_docs/OffboardControlMode.md). +This requires a deeper understanding of PX4 and the structure of the rover modules. +For general information on setting up offboard mode read through [Offboard Mode](../flight_modes/offboard.md) and then consult [Supported Setpoints](../flight_modes/offboard.md#rover). diff --git a/docs/zh/flight_modes_rover/index.md b/docs/zh/flight_modes_rover/index.md index 38f185f784..567fb20460 100644 --- a/docs/zh/flight_modes_rover/index.md +++ b/docs/zh/flight_modes_rover/index.md @@ -12,7 +12,7 @@ Selecting any other mode than those listed below will either stop the rover or c ## Manual Modes -| Mode | 描述 | +| 模式 | 描述 | | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Manual](manual.md#manual-mode) | No autopilot support. User is responsible for keeping the rover on the desired course and maintaining speed and rate of turn. | | [Acro](manual.md#acro-mode) | + Maintains the yaw rate (feels more like driving a car than manual mode).
+ Allows maximum yaw rate to be limited (protects against roll over). | @@ -21,7 +21,7 @@ Selecting any other mode than those listed below will either stop the rover or c ## Auto Modes -| Mode | 描述 | +| 模式 | 描述 | | ------------------------------- | --------------------------------------------------------------------------------------- | | [Mission](auto.md#mission-mode) | Automatic mode that causes the vehicle to execute a predefined mission. | | [Return](auto.md#return-mode) | Automatic mode that returns the vehicle to the launch position. | diff --git a/docs/zh/flight_modes_rover/manual.md b/docs/zh/flight_modes_rover/manual.md index 6363cd9baf..2f0cecdf04 100644 --- a/docs/zh/flight_modes_rover/manual.md +++ b/docs/zh/flight_modes_rover/manual.md @@ -14,7 +14,7 @@ The sticks provide the same "high level" control effects over direction and rate The manual modes provide progressively increasing levels of autopilot support for maintaining a course, speed, and rate of turn, compensating for external factors such as slopes or uneven terrain. -| Mode | 描述 | +| 模式 | 描述 | | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Manual](manual.md#manual-mode) | No autopilot support. User is responsible for keeping the rover on the desired course and maintaining speed and rate of turn. | | [Acro](manual.md#acro-mode) | + Maintains the yaw rate (feels more like driving a car than manual mode).
+ Allows maximum yaw rate to be limited (protects against roll over). | @@ -24,7 +24,7 @@ The manual modes provide progressively increasing levels of autopilot support fo :::details Overview mode mapping to control effect -| Mode | Speed | Turning | Required measurements | +| 模式 | Speed | Turning | Required measurements | | ------------------------------ | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | [Manual](#manual-mode) | Directly map stick input to motor command. | Directly map stick input to steering angle/speed difference. | None. | | [Acro](#acro-mode) | Directly map stick input to motor command. | Stick input creates a yaw rate setpoint for the control system to regulate. | yaw rate. | diff --git a/docs/zh/flight_modes_vtol/land.md b/docs/zh/flight_modes_vtol/land.md index 681bcf18fd..3da643d652 100644 --- a/docs/zh/flight_modes_vtol/land.md +++ b/docs/zh/flight_modes_vtol/land.md @@ -17,7 +17,7 @@ The VTOL-specific parameters are: | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | [NAV_FORCE_VT](../advanced_config/parameter_reference.md#NAV_FORCE_VT) | Force VTOL to takeoff and land as a multicopter (default: true) | -## See Also +## 另见 - [Land Mode (MC)](../flight_modes_mc/land.md) - [Land Mode (FW)](../flight_modes_fw/land.md) diff --git a/docs/zh/flight_modes_vtol/mission.md b/docs/zh/flight_modes_vtol/mission.md index ed4ffa878d..ca31540873 100644 --- a/docs/zh/flight_modes_vtol/mission.md +++ b/docs/zh/flight_modes_vtol/mission.md @@ -49,7 +49,7 @@ After transitioning the vehicle heads towards the 3D position defined in the mis A VTOL mission requires a `VTOL Takeoff` mission item (`MAV_CMD_NAV_VTOL_TAKEOFF`) to takeoff (or a `MAV_CMD_NAV_TAKEOFF` when the vehicle is in MC mode); if however the vehicle is already flying when the mission is started the takeoff item will be treated as a normal waypoint. -## See Also +## 另见 - [Mission Mode (MC)](../flight_modes_mc/mission.md) - [Mission Mode (FW)](../flight_modes_fw/mission.md) diff --git a/docs/zh/flight_modes_vtol/return.md b/docs/zh/flight_modes_vtol/return.md index 4905e2654e..34876f9f68 100644 --- a/docs/zh/flight_modes_vtol/return.md +++ b/docs/zh/flight_modes_vtol/return.md @@ -81,7 +81,7 @@ The others are relevant if the destination is a rally point or the home location | [RTL_LOITER_RAD](../advanced_config/parameter_reference.md#RTL_LOITER_RAD) | [Fixed-wing Only] The radius of the loiter circle (at [RTL_LAND_DELAY](#RTL_LAND_DELAY). | | [MIS_TKO_LAND_REQ](../advanced_config/parameter_reference.md#MIS_TKO_LAND_REQ) | Specify whether a mission landing or takeoff pattern is _required_. Generally fixed-wing vehicles set this to require a landing pattern but VTOL do not. | -## See Also +## 另见 - [Return Mode (Generic)](../flight_modes/return.md) - [Return Mode (Multicopter)](../flight_modes_mc/return.md) diff --git a/docs/zh/flying/basic_flying_mc.md b/docs/zh/flying/basic_flying_mc.md index 8bda6719e8..2f2cd8ac60 100644 --- a/docs/zh/flying/basic_flying_mc.md +++ b/docs/zh/flying/basic_flying_mc.md @@ -94,7 +94,7 @@ The following three modes are highly recommended for new users: You can also engage automatic modes on the _QGroundControl_ main flight screen. ::: -## See Also +## 另见 - [Terrain Follow/Hold & Range Assistance](../flying/terrain_following_holding.md) — How to enable terrain following - [Missions](../flying/missions.md) diff --git a/docs/zh/flying/geofence.md b/docs/zh/flying/geofence.md index 14f87a4a75..28f29608ce 100644 --- a/docs/zh/flying/geofence.md +++ b/docs/zh/flying/geofence.md @@ -43,7 +43,7 @@ Geofence planning is fully documented in [Plan View > GeoFence](https://docs.qgr - 围栏中心的圆点可以用来调整围栏的位置。 - 边界上的圆点可以用来调整半径。 - 角(顶点)上的圆点可以用来改变多边形的形状。 - 点击线段中间可以在两个顶点中添加新的顶点。 + 点击线段中间可以在两个顶点中添加新的顶点。 5. Use the _Geofence Editor_ to set a fence as an inclusion or exclusion, and to select a fence to edit (**Edit** radio button) or Delete (**Del** button). 6. 可添加任意数量的围栏 7. Once finished, click on the **Upload** button (top right) to send the fence (along with rally points and mission) to the vehicle. diff --git a/docs/zh/flying/package_delivery_mission.md b/docs/zh/flying/package_delivery_mission.md index 7579495f9e..a04437f19f 100644 --- a/docs/zh/flying/package_delivery_mission.md +++ b/docs/zh/flying/package_delivery_mission.md @@ -37,9 +37,9 @@ To create a package delivery mission (with a Gripper): - 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. - Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. + Do this by selecting the mission item heading, then selecting `Land` in the popup dialog. - ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) + ![Waypoint to Land mission item](../../assets/flying/package_delivery_land_waypoint.png) 3. Add a waypoint on the map (anywhere) for the gripper release. To change this to a `Gripper Mechanism` select the "Waypoint" heading, and in the popup changing the group to "Advanced", then selecting `Gripper Mechanism`. diff --git a/docs/zh/frames_multicopter/dji_f450_cuav_5nano.md b/docs/zh/frames_multicopter/dji_f450_cuav_5nano.md index 43f4d0e036..325680e123 100644 --- a/docs/zh/frames_multicopter/dji_f450_cuav_5nano.md +++ b/docs/zh/frames_multicopter/dji_f450_cuav_5nano.md @@ -43,8 +43,8 @@ This section lists all hardware for the frame. | DJI F450 Bottom plate | 1 | | DJI F450 Top plate | 1 | | DJI F450 legs with landing gear | 4 | -| M3\*8 screws | 18 | -| M2 5\*6 screws | 24 | +| M3\*8螺丝 | 18 | +| M2.5\*6 螺丝 | 24 | | Velcro Battery Strap | 1 | | DJI Phantom Built-in Nut Upgrade Propellers 9.4x5 | 1 | @@ -106,52 +106,52 @@ Estimated time to assemble is approximately 90 minutes (about 45 minutes for the 1. Attach the 4 arms to the bottom plate using the provided screws. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5nano/1_attach_arms_bottom_plate.jpg) 2. Solder ESC (Electronic Speed Controller) to the board, positive (red) and negative (black). - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/2_solder_esc.jpg) 3. Solder the Power Module, positive (red) and negative (black). - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5nano/3_solder_power_module.jpg) 4. Plug in the motors to the ESCs according to their positions. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5nano/4_plug_in_motors.jpg) 5. Attach the motors to the corresponding arms. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5nano/5b_attach_motors_to_arms.jpg) 6. Add the top board (screw into the top of the legs). - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5nano/6_add_top_board.jpg) 7. Add damping foam to the _CUAV V5 nano_ flight controller. - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) - ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7a_attach_cuav5nano.jpg) + ![Damping foam](../../assets/airframes/multicopter/dji_f450_cuav_5nano/7b_attach_cuav5nano.jpg) 8. Attach the FrSky receiver to the bottom board with double-sided tape. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5nano/8_attach_frsky.jpg) 9. Attach the telemetry module to the vehicle’s bottom board using double-sided tape. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5nano/9b_telemtry_radio.jpg) 10. Put the aluminium standoffs on the button plate and attach GPS. - ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) + ![Aluminium standoffs](../../assets/airframes/multicopter/dji_f450_cuav_5nano/10_aluminium_standoffs.jpg) 11. Plug in Telemetry (`TELEM1`), GPS module (`GPS/SAFETY`), RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5nano/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/zh/frames_multicopter/dji_f450_cuav_5plus.md b/docs/zh/frames_multicopter/dji_f450_cuav_5plus.md index 4c42eaa365..60e86e05be 100644 --- a/docs/zh/frames_multicopter/dji_f450_cuav_5plus.md +++ b/docs/zh/frames_multicopter/dji_f450_cuav_5plus.md @@ -43,8 +43,8 @@ This section lists all hardware for the frame. | DJI F450 Bottom plate | 1 | | DJI F450 Top plate | 1 | | DJI F450 legs with landing gear | 4 | -| M3\*8 screws | 18 | -| M2 5\*6 screws | 24 | +| M3\*8螺丝 | 18 | +| M2.5\*6 螺丝 | 24 | | Velcro Battery Strap | 1 | | DJI Phantom Built-in Nut Upgrade Propellers 9.4x5 | 1 | @@ -108,53 +108,53 @@ Estimated time to assemble is approximately 90 minutes (about 45 minutes for the 1. Attach the 4 arms to the bottom plate using the provided screws. - ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) + ![Arms to bottom plate](../../assets/airframes/multicopter/dji_f450_cuav_5plus/1_attach_arms_bottom_plate.jpg) 2. Solder ESC (Electronic Speed Controller) to the board, positive (red) and negative (black). - ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) + ![Solder ESCs](../../assets/airframes/multicopter/dji_f450_cuav_5plus/2_solder_esc.jpg) 3. Solder the Power Module, positive (red) and negative (black). - ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) + ![Solder power module](../../assets/airframes/multicopter/dji_f450_cuav_5plus/3_solder_power_module.jpg) 4. Plug in the motors to the ESCs according to their positions. - ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) + ![Plug in motors](../../assets/airframes/multicopter/dji_f450_cuav_5plus/4_plug_in_motors.jpg) 5. Attach the motors to the corresponding arms. - ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) - ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) + ![Attach motors to arms (white)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5a_attach_motors_to_arms.jpg) + ![Attach motors to arms (red)](../../assets/airframes/multicopter/dji_f450_cuav_5plus/5b_attach_motors_to_arms.jpg) 6. Add the top board (screw into the top of the legs). - ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) + ![Add top board](../../assets/airframes/multicopter/dji_f450_cuav_5plus/6_add_top_board.jpg) 7. Add double-sided tape (3M) to the CUAV V5+ flight controller (it has internal vibration damping, so no need to use foam). - ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) + ![Tape CUAV v5+](../../assets/airframes/multicopter/dji_f450_cuav_5plus/7_attach_cuav5plus.jpg) 8. Attach the FrSky receiver to the bottom board with double-sided tape. - ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) + ![Attach FrSky receiver with double-sided tape](../../assets/airframes/multicopter/dji_f450_cuav_5plus/8_attach_frsky.jpg) 9. Attach the telemetry module to the vehicle’s bottom board using double-sided tape. - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) - ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9a_telemtry_radio.jpg) + ![Attach telemetry radio](../../assets/airframes/multicopter/dji_f450_cuav_5plus/9b_telemtry_radio.jpg) 10. Put the aluminium standoffs on the button plate. 11. Plug in Telemetry (`TELEM1`) and GPS module (`GPS/SAFETY`) to the flight controller. - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) - ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11a_gps.jpg) + ![Attach GPS](../../assets/airframes/multicopter/dji_f450_cuav_5plus/11b_gps.jpg) 12. Plug in the RC receiver (`RC`), all 4 ESC’s (`M1-M4`), and the power module (`Power1`) into the flight controller. - ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) + ![Attach peripherals to flight controller](../../assets/airframes/multicopter/dji_f450_cuav_5plus/12_fc_attach_periperhals.jpg) - ::: info - The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) + ::: info + The motor order is defined in the [Airframe Reference > Quadrotor x](../airframes/airframe_reference.md#quadrotor-x) ::: diff --git a/docs/zh/frames_multicopter/holybro_qav250_pixhawk4_mini.md b/docs/zh/frames_multicopter/holybro_qav250_pixhawk4_mini.md index d229c04192..b211ecf724 100644 --- a/docs/zh/frames_multicopter/holybro_qav250_pixhawk4_mini.md +++ b/docs/zh/frames_multicopter/holybro_qav250_pixhawk4_mini.md @@ -103,78 +103,78 @@ The following tools are used in this assembly: 1. Attach arms to the button plate with the 15mm screws as shown: - ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) + ![QAV250 Add arms to button plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/1_button_plate_add_arms.jpg) 2. Put the short plate over the arms - ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) + ![QAV250 Add short plate over arms](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/2_short_plate_over_arms.jpg) 3. Put the nuts on the 15mm screws (shown next step) 4. Insert the plastic screws into the indicated holes (note that this part of the frame faces down when the vehicle is complete). - ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) + ![QAV250 Add nuts to 15mm screws and put plastic nuts in holes](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/3_nuts_screws_holes.jpg) 5. Add the plastic nuts to the screws (turn over, as shown) - ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) + ![QAV250 Plastic nuts onto screws](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/4_plastic_nuts_on_screws.jpg) 6. Lower the power module over the plastic screws and then add the plastics standoffs - ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) + ![QAV250 Add power module and standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/5_power_module_on_screws.jpg) 7. Put the flight controller plate on the standoffs (over the power module) - ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) + ![QAV250 Add flight controller plate](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/6_flight_controller_plate.jpg) 8. Attach the motors. The motors have an arrow indicating the direction of rotation. - ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) + ![QAV250 Add motors](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/7_motors.jpg) 9. Use double sided tape from kit to attach the _Pixhawk 4 Mini_ to the flight controller plate. - ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) + ![QAV250 Add doublesided tape](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/8_double_sided_tape_controller.jpg) 10. Connect the power module's "power" cable to _Pixhawk 4 mini_. - ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) + ![QAV250 Power Pixhawk](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/9_power_module_power_pixhawk.jpg) 11. Attach the aluminium standoffs to the button plate - ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) + ![QAV250 Aluminium standoffs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/10_aluminium_standoffs.jpg) 12. Connect the Esc’s with the motors and hold. In this image shown the order of the motors and direction of the rotation. - ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) + ![QAV250 Connect ESCs](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11_escs.jpg) - Connect the motors on the ESC’s, make sure the motors turns to the correct side, if the motor turns of the opposite side change the cable A to the pad C and C to the pad A of the ESC. + Connect the motors on the ESC’s, make sure the motors turns to the correct side, if the motor turns of the opposite side change the cable A to the pad C and C to the pad A of the ESC. - :::warning - Test motor directions with propellers removed. + :::warning + Test motor directions with propellers removed. ::: - ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) + ![QAV250 Connect ESCs to Power](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/11b_escs.jpg) 13. Connect the signal ESC cables to the PWM outputs of the Pixhawk in the correct order (see previous image) - ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) + ![QAV250 Connect ESCs to Pixhawk PWM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/12_escs_pixhawk.jpg) 14. Connect the receiver. - - If using a PPM receiver connect to the PPM port. + - If using a PPM receiver connect to the PPM port. - ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) + ![QAV250 Connect Receiver PPM](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_ppm.jpg) - - If using the SBUS receiver connect to the RC IN port + - If using the SBUS receiver connect to the RC IN port - ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) + ![QAV250 Connect Receiver SBUS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/13_rc_receiver_sbus.jpg) 15. Connect the telemetry module. Paste the module with double tape and connect on the port of the telemetry. - ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) + ![QAV250 Telemetry module](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/14_telemetry.jpg) 16. Connect the GPS module - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15a_connect_gps.jpg) - Attach the module on the top plate (using provided 3M tape, or paste). Then put the top plate on the standoffs as shown + Attach the module on the top plate (using provided 3M tape, or paste). Then put the top plate on the standoffs as shown - ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) + ![QAV250 Connect GPS](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/15b_attach_gps.jpg) 17. The last "mandatory" assembly step is to add the velcro to hold the battery - ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) + ![QAV250 Velcro battery strap](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/16_velcro_strap.jpg) The "basic" frame build is now complete (though if you need them, you can find more information about connecting components in the [Pixhawk 4 Wiring Quickstart](../assembly/quick_start_pixhawk4.md)). @@ -189,17 +189,17 @@ The "Complete" version of the kit additionally comes with an FPV system, which i The steps to install the kit are: 1. Install the camera bracket on the frame - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_bracket.jpg) 2. Install the camera on the bracket - ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) + ![Camera on Bracket](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_on_bracket.jpg) 3. The power module on the complete kit comes with wiring ready to connect the Video Transmitter and Camera: - ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) - - Attach the camera connector - ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) - The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. - - Connect the Video Transmitter (VTX) connector - ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) - The wires are: yellow=video out, black=ground, red=+voltage. + ![Connecting FPV](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_connection_board.jpg) + - Attach the camera connector + ![Camera Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_camera_connection.jpg) + The wires are: blue=voltage sensor, yellow=video out, black=ground, red=+voltage. + - Connect the Video Transmitter (VTX) connector + ![Video Transmitter Connection](../../assets/airframes/multicopter/qav250_holybro_pixhawk4_mini/fpv_video_transmitter_connection.jpg) + The wires are: yellow=video out, black=ground, red=+voltage. 4. Secure the Video Transmitter and OSD board to the frame using tape. :::info diff --git a/docs/zh/frames_multicopter/holybro_s500_v2_pixhawk4.md b/docs/zh/frames_multicopter/holybro_s500_v2_pixhawk4.md index ab696b1c26..5f1a97d4ff 100644 --- a/docs/zh/frames_multicopter/holybro_s500_v2_pixhawk4.md +++ b/docs/zh/frames_multicopter/holybro_s500_v2_pixhawk4.md @@ -3,88 +3,88 @@ This topic provides full instructions for building the kit and configuring PX4 using _QGroundControl_. :::info -Holybro initially supplied this kit with a [Holybro Pixhawk 4](../flight_controller/pixhawk4.md), but at time of writing this has been upgraded to a more recent Pixhawk (6C). -This build log is still relevant as the kit assembly is virtually the same, and likely to remain so as the flight controller is upgraded. +Holybro最初提供了和[Holybro Pixhawk 4](../flight_controller/pixhawk4.md)飞控一起提供这个套件, 但在撰写本文档时,这个系统已升级为较新的 Pixhawk (6C)。 +这个构建记录仍然具有相关性,因为套装组件几乎是一样的,而且随着飞行控制器升级,很可能仍然如此。 ::: ## Key information -- **Frame:** Holybro S500 -- **Flight controller:** [Pixhawk 4](../flight_controller/pixhawk4.md) -- **Assembly time (approx.):** 90 minutes (45 minutes for frame, 45 minutes for autopilot installation/configuration) +- **机架:** Holybro S500 +- **飞行控制器:** [Pixhawk 4](../flight_controller/pixhawk4.md) +- **大约组装时间:** 90 分钟 (机架组装45分钟,飞控安装和配置45分钟) -![Full S500 Kit](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_hero.png) +![完整的S500套件](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_hero.png) ## Bill of materials -The Holybro [S500 V2 Kit](https://holybro.com/collections/s500/products/s500-v2-development-kit) includes almost all the required components: +Holybro [S500 V2 套件](https://holybro.com/collections/s500/products/s500-v2-development-kit) 包含几乎所有需要的组件: -- A recent Pixhawk autopilot - - For this log it was Pixhawk 4 but far more recent versions are now included. -- Power Management PM02(Assembled) -- ARM adopts high strength plastics -- Motors - 2216 KV880( V2 Update) -- Propeller 1045( V2 Update) -- Pixhawk4 GPS +- 一个近期发布的 Pixhawk 飞控 + - 对于这个装机日志,它是 Pixhawk 4,但是现在的套件包含了更新的版本。 +- 电源管理模块 PM02(已组装) +- 采用高强度塑料的机臂 +- 马达 - 2216 KV880(V2 版本) +- 1045桨叶(V2 版本) +- Pixhawk4 GPS模组 - Fully assembled Power Management Board with ESCs -- 433 MHz / 915 MHz [Holybro Telemetry Radio](../telemetry/holybro_sik_radio.md) -- Power and Radio Cables -- Battery Straps -- Dimensions:383_385_240mm -- Wheelbase:480mm +- 433 MHz / 915 MHz [Holybro数传电台](../telemetry/holybro_sik_radio.md) +- 电源线和信号线 +- 电池绑带 +- 尺寸:383_385_240毫米 +- 轴距:480毫米 :::info -No LiPo battery is included. -In addition, we use a FrSky Taranis controller. +不包含锂电池。 +此外,我们使用一个FrSky Taranis遥控。 ::: ## 硬件 -| Item Description | Quantity | -| --------------------------------------------- | -------- | -| Wheelbase: 480mm | 1 | -| Arms | 4 | -| Set of Landing Gear | 2 | -| M3\*8 screws | 18 | -| M2 5\*6 screws | 24 | -| Battery Straps | 1 | -| Propeller 1045 (V2 Update) | 1 | +| 物品描述 | Quantity | +| -------------------------------- | -------- | +| 轴距:480毫米 | 1 | +| 机臂 | 4 | +| 起落架 | 2 | +| M3\*8螺丝 | 18 | +| M2.5\*6 螺丝 | 24 | +| 电池绑带 | 1 | +| 1045桨叶(V2 版本) | 1 | -![S500 Hardware](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_hardware.jpg) +![S500硬件](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_hardware.jpg) -## Package +## 包装 -| Items | Package | -| ---------------------------------------------------- | ------- | -| Pixhawk 4 | 1 | -| Pixhawk4 GPS MODULE | 1 | -| I2C splitter Board | 2 | -| 6 to 6 pin cable (power) | 3 | -| 4 to 4 pin cable (CAN) | 2 | -| 6 to 4 pin cable (Data) | 1 | -| 10 to 10 pin cable (PWM) | 2 | -| 8 to 8 pin cable(AUX) | 1 | -| 7 to 7 pin cable(SPI) | 1 | -| 6 to 6 pin cable(Debug) | 1 | -| PPM/SBUS out cable | 1 | -| XSR receiver cable | 1 | -| DSMX receiver cable | 1 | -| SBUS receiver cable | 1 | -| USB cable | 1 | -| 'X'type folding pedestal mount | 1 | -| 70mm & 140mm carbon rod standoff | 2 | -| 6\*3 2.54mm pitch Horizontal Pin | 1 | -| 8\*3 2.54mm pitch Horizontal Pin | 2 | -| Foam Set | 1 | -| Pixhawk4 Quick Start Guide | 1 | -| Pixhawk4 Pinouts | 1 | -| GPS Quick Start Guide | 1 | +| 物品 | 包装 | +| ---------------------------------------------------- | -- | +| Pixhawk 4 | 1 | +| Pixhawk4 GPS MODULE | 1 | +| I2C splitter Board | 2 | +| 6 to 6 pin cable (power) | 3 | +| 4 to 4 pin cable (CAN) | 2 | +| 6 to 4 pin cable (Data) | 1 | +| 10 to 10 pin cable (PWM) | 2 | +| 8 to 8 pin cable(AUX) | 1 | +| 7 to 7 pin cable(SPI) | 1 | +| 6 to 6 pin cable(Debug) | 1 | +| PPM/SBUS out cable | 1 | +| XSR receiver cable | 1 | +| DSMX receiver cable | 1 | +| SBUS receiver cable | 1 | +| USB cable | 1 | +| 'X'type folding pedestal mount | 1 | +| 70mm & 140mm carbon rod standoff | 2 | +| 6\*3 2.54mm pitch Horizontal Pin | 1 | +| 8\*3 2.54mm pitch Horizontal Pin | 2 | +| Foam Set | 1 | +| Pixhawk4 Quick Start Guide | 1 | +| Pixhawk4 Pinouts | 1 | +| GPS Quick Start Guide | 1 | ![S500 Package Contents](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_package.jpg) ### Electronics -| Item Description | Quantity | +| 物品描述 | Quantity | | ---------------------------------------------------------- | -------- | | Pixhawk 4 autopilot (PM06 not included) | 1 | | Power Management PM02 (Assembled) | 1 | @@ -112,154 +112,154 @@ The following tools are used in this assembly: ## 组装 -Estimate time to assemble is 90 minutes, about 45 minutes for frame assembly and 45 minutes installing and configuring the autopilot in QGroundControl. +估计的组装时间是90分钟,组装机架约45分钟,安装和在QGroundControl配置飞控约45分钟。 -1. Assembling the Landing Gear. - We are going to start by assembling the landing gear to the vertical pole. Unscrew the landing gear screws and insert the vertical pole as shown below. +1. 安装起落架。 + We are going to start by assembling the landing gear to the vertical pole. Unscrew the landing gear screws and insert the vertical pole as shown below. - ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) + ![Figure 1](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig1.jpg) - ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) + ![Figure 2](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig2.jpg) 2. Assemble the Power Management Board to the landing gear. Screw the landing gear with a vertical pole to the Fully assembled Power Management Board. -The Board has 4 holes (see arrows below). +板子有4个洞(见下面的箭头)。 ![Figure 3](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig3.jpg) -Connect with the M3X8 screws, a total of 8 pieces, 4 on each side. +用 M3X8 螺丝连接,总共8个,每侧4个。 ![Figure 4](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig4.jpg) -1. Assemble the arms to the Power Management Board. - Attach the arm to the Power Management Board. +1. 把机臂装到电源管理板上。 + 把机臂装到电源管理板上。 - ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) + ![Figure 6](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig7.jpg) - ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) + ![Figure 7](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig8.jpg) - Use M2 5X6 screws a total of 2 in each arm. - Insert the screws from the bottom of the plate. + 在每个臂上使用2个M2.5X6螺丝。 + 从板块底部插入螺丝。 - ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) + ![Figure 8](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig9.jpg) - Make sure the ESC cables run through the middle of the arm. + 确保电调的电线穿过机臂中间。 - ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) + ![Figure 9](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig91.jpg) 2. Assemble the 8_3 2.54mm pitch Horizontal Pin to the 10 to 10 pin cable (PWM) to the Power Management Board. - Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. + Connect the 10 to 10 pin cable (PWM) to the 8_3 2.54mm pitch Horizontal Pin. - ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) + ![Figure 10](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig10.jpg) - Cut a piece of 3M Tape and attach to the bottom of the Horizontal Pin: + Cut a piece of 3M Tape and attach to the bottom of the Horizontal Pin: - ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) + ![Figure 11](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig11.jpg) - Stick the Horizontal Pin to the Power Management Board: + Stick the Horizontal Pin to the Power Management Board: - ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) + ![Figure 12](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig12.jpg) - ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) + ![Figure 13](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig13.jpg) 3. Assemble the motors to the arms. For this, we will need the 16 screws M3X7, 4 motors, and the 4 arms. - Mount the motors in each arm put the screw through the bottom of the arm: + Mount the motors in each arm put the screw through the bottom of the arm: - ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) + ![Figure 14](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig14.jpg) - ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) + ![Figure 15](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig15.jpg) - After the 4 motors are mounted on the arm grab the cables(red, blue, black) and put them through the arm thread. - The 3 cables that are color-coded go connected to the ESC. + After the 4 motors are mounted on the arm grab the cables(red, blue, black) and put them through the arm thread. + The 3 cables that are color-coded go connected to the ESC. - ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) + ![Figure 16](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig16.jpg) - ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) + ![Figure 17](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig17.jpg) 4. Mounting the GPS on the frame. - For this, we will need the Pixhawk 4 GPS and the mounting plate. + For this, we will need the Pixhawk 4 GPS and the mounting plate. - ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) + ![GPS Parts](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_gpskit.png) - Mount the GPS mast to the back of the Board, use the 4 screws: + Mount the GPS mast to the back of the Board, use the 4 screws: - ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) + ![Figure 18](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig18.jpg) - ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) + ![Figure 19](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig19.jpg) - Use the tape and stick the GPS to the top of the GPS mast: + Use the tape and stick the GPS to the top of the GPS mast: - ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) + ![Figure 20](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig20.jpg) 5. Paste the FrSky to the Board. Paste FrSky with double-sided tape (3M) to the bottom board. - Attach the FrSky to the frame: + Attach the FrSky to the frame: - ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) + ![Figure 21](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig21.jpg) - ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) + ![Figure 22](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig22.jpg) 6. Attach the Telemetry to the frame. - The next step is to take the Holybro telemetry radio and attach it onto the frame, use 3M tape. + The next step is to take the Holybro telemetry radio and attach it onto the frame, use 3M tape. - ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) + ![Figure 23](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig23.jpg) - ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) + ![Figure 24](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig24.jpg) - This assembly attached it inside the frame facing outwards to the front of the vehicle. - A picture is shown below of the radio sitting inside the bottom of the frame. + This assembly attached it inside the frame facing outwards to the front of the vehicle. + A picture is shown below of the radio sitting inside the bottom of the frame. - ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) + ![Figure 25](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig25.jpg) 7. Mounting the Pixhawk 4 to the plate. - Use double-sided tape to attach the Pixhawk 4 to the center plate: + Use double-sided tape to attach the Pixhawk 4 to the center plate: - ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) + ![Figure 26](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig26.jpg) - ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) + ![Figure 27](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig27.jpg) - ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) + ![Figure 28](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig28.jpg) - The next step is to mount the Pixhawk 4 with the plate to the frame. - For this, we will need the M2 5X6 screws. - Align the plate to the frame and insert the screws. - Before you mount the plate we recommend putting tape on the Power Module (that way it's tight). + The next step is to mount the Pixhawk 4 with the plate to the frame. + For this, we will need the M2 5X6 screws. + Align the plate to the frame and insert the screws. + Before you mount the plate we recommend putting tape on the Power Module (that way it's tight). - ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) + ![Figure 29](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig29.jpg) - ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) + ![Figure 30](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig30.jpg) 8. Assembling the Battery Mount to the frame. - For this we will need the M2 5X6 screws and the battery mount: + For this we will need the M2 5X6 screws and the battery mount: - ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) + ![Figure 31](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig31.jpg) - Insert the long rods to the small rings: + Insert the long rods to the small rings: - ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) + ![Figure 32](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig32.png) - ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) + ![Figure 33](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig33.png) - Attach that to the frame, make sure all four sides are aligned to insert the screws: + Attach that to the frame, make sure all four sides are aligned to insert the screws: - ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) + ![Figure 34](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig34.jpg) - Assemble the small plate to the legs and screw on all four sides. + Assemble the small plate to the legs and screw on all four sides. - ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) + ![Figure 35](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig35.jpg) - The final step is to attach the plate: + The final step is to attach the plate: - ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) + ![Figure 36](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig36.jpg) 9. Pixhawk 4 wiring. The Pixhawk 4, which has several different wires and connections with it. - Included below is a picture of every wire needed with the Pixhawk and how it looks when connected. + Included below is a picture of every wire needed with the Pixhawk and how it looks when connected. -10. Plugin Telemetry and GPS module to the flight controller as seen in Figure 37; plug in the RC receiver, all 4 ESCs to the flight controller as well as the power module. +10. 如图37所示,把数传模块和GPS模块接到飞行控制器上;连接遥控接收器、4 个电调以及电源模块到飞行控制器上。 - ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) + ![Figure 37](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_fig37.png) -Fully assembled, the kit looks as shown below: +装好以后套件看起来像下面这样: ![Pixhawk Assembled](../../assets/airframes/multicopter/s500_holybro_pixhawk4/s500_pixhawk.jpg) @@ -274,16 +274,16 @@ _QGroundControl_ is used to install the PX4 autopilot and configure/tune it for Full instructions for installing and configuring PX4 can be found in [Basic Configuration](../config/index.md). ::: -First update the firmware and airframe: +首先更新固件和机架配置: - [Firmware](../config/firmware.md) - [Airframe](../config/airframe.md) - You will need to select the _Holybro S500_ airframe (**Quadrotor x > Holybro S500**). + 您需要选择 _Holybro S500_ 机架(**Quadrotor x > Holybro S500**)。 ![QGroundControl - Select HolyBro X500 airframe](../../assets/airframes/multicopter/s500_holybro_pixhawk4/qgc_airframe_holybro_s500.png) -Then set the actuator outputs: +然后设置执行器输出: - [Actuators](../config/actuators.md) - You should not need to update the vehicle geometry (as this is a preconfigured airframe). @@ -308,7 +308,7 @@ Ideally you should also do: ## 调试 Airframe selection sets _default_ autopilot parameters for the frame. -These are good enough to fly with, but it is a good idea to tune the parameters for a specific frame build. +这些足以让它起飞,但是为你的特定框架调整专有参数是一个好主意。 For instructions on how, start from [Autotune](../config/autotune_mc.md). diff --git a/docs/zh/frames_multicopter/holybro_x500V2_pixhawk5x.md b/docs/zh/frames_multicopter/holybro_x500V2_pixhawk5x.md index 42ec97bd34..a898733d96 100644 --- a/docs/zh/frames_multicopter/holybro_x500V2_pixhawk5x.md +++ b/docs/zh/frames_multicopter/holybro_x500V2_pixhawk5x.md @@ -2,7 +2,7 @@ :::info Holybro initially supplied this kit with a [Pixhawk 5X](../flight_controller/pixhawk5x.md), but at time of writing this has been upgraded to a [Holybro Pixhawk 6C](../flight_controller/pixhawk6c.md). -This build log is still relevant as the kit assembly is virtually the same, and likely to remain so as the flight controller is upgraded. +这个构建记录仍然具有相关性,因为套装组件几乎是一样的,而且随着飞行控制器升级,很可能仍然如此。 ::: This topic provides full instructions for building the [Holybro X500 V2 ARF Kit](https://holybro.com/collections/x500-kits) and configuring PX4 using _QGroundControl_. @@ -71,15 +71,15 @@ _Figure 1_: X500 V2 ARF Kit what's inside ### Electronics -| Item Description | Quantity | -| ------------------------------------------------------------------------------ | -------- | -| Pixhawk5x & Assorted Cables | 1 | -| M8N GPS Module | 1 | -| Power Module PM02D (with pre-soldered ESC power cables) | 1 | -| Motors 2216 KV880(V2 Update) | 4 | -| Holybro BLHeli S ESC 20A x4 | 1 | -| Holybro BLHeli S ESC 20A x4 | 1 | -| 433 MHz / 915 MHz [Holybro Telemetry Radio](../telemetry/holybro_sik_radio.md) | 1 | +| 物品描述 | Quantity | +| -------------------------------------------------------------------------- | -------- | +| Pixhawk5x & Assorted Cables | 1 | +| M8N GPS Module | 1 | +| Power Module PM02D (with pre-soldered ESC power cables) | 1 | +| Motors 2216 KV880(V2 Update) | 4 | +| Holybro BLHeli S ESC 20A x4 | 1 | +| Holybro BLHeli S ESC 20A x4 | 1 | +| 433 MHz / 915 MHz [Holybro数传电台](../telemetry/holybro_sik_radio.md) | 1 | ### Tools needed @@ -93,92 +93,92 @@ Tools are included to do the assembly, however you may need: Estimate time to assemble is 55 min (25 minutes for frame, 30 minutes for autopilot installation/configuration) 1. Start by assembling the payload & battery holder. - Push the rubbers into grippers (Do not use sharp items to push them in!). - Next, pass the holders through the holder bars with the battery holder bases as Figure 3. + Push the rubbers into grippers (Do not use sharp items to push them in!). + Next, pass the holders through the holder bars with the battery holder bases as Figure 3. - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_required_stuff.png) - _Figure 2_: Payload holder components + _Figure 2_: Payload holder components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/payload_holder_assembled.png) - _Figure 3_: Payload holder assembled + _Figure 3_: Payload holder assembled 2. The next is to go for attaching the bottom plate to the payload holder. - You will need the parts as shown in Figure 4. - Then mount the base for power distribution board using nylon nuts as Figure 5. - Finally using 8 hex screws you can join the bottom plate to the payload holder (Figure 7) + You will need the parts as shown in Figure 4. + Then mount the base for power distribution board using nylon nuts as Figure 5. + Finally using 8 hex screws you can join the bottom plate to the payload holder (Figure 7) - ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) + ![Materials to attach bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/topplate_holder_stuff.png) - _Figure 4_: Needed Materials + _Figure 4_: Needed Materials - ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) + ![PDB mountbase](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/powerboard-mountbase.png) - _Figure 5_: PDB mount base + _Figure 5_: PDB mount base - ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) + ![PDB attachment](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pdb_bottom_plate.png) - _Figure 6_: Mounted pdb with nylon nuts + _Figure 6_: Mounted pdb with nylon nuts - ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) + ![Bottom plate Final](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/bottom_plate_holder_final.png) - _Figure 7_: Mounted Plate on payload holder + _Figure 7_: Mounted Plate on payload holder 3. Let's gather the stuff needed for mounting landing gear as Figure 8. - Use the hex screws to join landing gears to the bottom plate. - You also need to open three hex screws on each of the leg stands so you can push them into carbon fiber pipes. - Do not forget to tighten them back again. + Use the hex screws to join landing gears to the bottom plate. + You also need to open three hex screws on each of the leg stands so you can push them into carbon fiber pipes. + Do not forget to tighten them back again. - ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) + ![Attach Landing Gear Stuff](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/landing_gear_materials.png) - _Figure 8_: Required parts for landing gear attachment + _Figure 8_: Required parts for landing gear attachment - ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) + ![Lanfing great to bottom plate](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/attached_landing_gear.png) - _Figure 9_: Landing gear attachment to the body + _Figure 9_: Landing gear attachment to the body 4. We will gather all the arms now to mount the top plate. - Please pay attention that the motor numbers on arms are a match with the ones mentioned on the top plate. - Fortunately, motors are mounted and ESCs have been connected in advance. - Start by passing through all the screws as you have the arms fixed in their own places (They have a guide as shown in Figure 11 to ensure they are in place) and tighten all nylon nuts a bit. - Then you can connect XT30 power connectors to the power board. - Please keep in mind that the signal wires have to be passed through the top plate such that we can connect them later to Pixhawk. + Please pay attention that the motor numbers on arms are a match with the ones mentioned on the top plate. + Fortunately, motors are mounted and ESCs have been connected in advance. + Start by passing through all the screws as you have the arms fixed in their own places (They have a guide as shown in Figure 11 to ensure they are in place) and tighten all nylon nuts a bit. + Then you can connect XT30 power connectors to the power board. + Please keep in mind that the signal wires have to be passed through the top plate such that we can connect them later to Pixhawk. - + - _Figure 10_: Connecting arms needed materials. + _Figure 10_: Connecting arms needed materials. - + - _Figure 11_: Guide for the arms mount + _Figure 11_: Guide for the arms mount 5. Tighten all 16 screws and nuts by using both hex wrench and nut driver. - ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) + ![Top plae mounted](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/finalized_top_plate.png) - _Figure 12_: Mounted top plate + _Figure 12_: Mounted top plate 6. Next you can mount your pixhawk on the top plate by using the stickers. - It is recommended to have the direction of your Pixhawk's arrow the same as the one mentioned on the top plate. + It is recommended to have the direction of your Pixhawk's arrow the same as the one mentioned on the top plate. - ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) + ![Flight controller mounting stickers](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk5x/pixhawk5x_stickertapes.png) - _Figure 13_: Sticker tapes on Pixhawk + _Figure 13_: Sticker tapes on Pixhawk 7. If you want to mount the GPS on the companion computer plate, you can now secure the GPS mount onto it using 4 screws and nuts. - + - _Figure 14_: Secure GPS mount onto companion plate + _Figure 14_: Secure GPS mount onto companion plate 8. Use the tape and stick the GPS to the top of the GPS mast and mount the GPS mast. - Make sure the arrow on the gps is pointing forward (Figure 15). + Make sure the arrow on the gps is pointing forward (Figure 15). - + - _Figure 15_: GPS and mast + _Figure 15_: GPS and mast 9. Finally, you can connect the Pixhawk interfaces such as telemetry radio to 'TELEM1' and motors signal cables accordingly. @@ -231,7 +231,7 @@ Ideally you should also do: ## 调试 Airframe selection sets _default_ autopilot parameters for the frame. -These are good enough to fly with, but it is a good idea to tune the parameters for a specific frame build. +这些足以让它起飞,但是为你的特定框架调整专有参数是一个好主意。 For instructions on how, start from [Autotune](../config/autotune_mc.md). diff --git a/docs/zh/frames_multicopter/holybro_x500_pixhawk4.md b/docs/zh/frames_multicopter/holybro_x500_pixhawk4.md index c49543f094..e9c021c823 100644 --- a/docs/zh/frames_multicopter/holybro_x500_pixhawk4.md +++ b/docs/zh/frames_multicopter/holybro_x500_pixhawk4.md @@ -2,7 +2,7 @@ :::info Holybro initially supplied this kit with a [Holybro Pixhawk 4](../flight_controller/pixhawk4.md)), but at time of writing this has been upgraded to a [Holybro Pixhawk 6C](../flight_controller/pixhawk6c.md). -This build log is still relevant as the kit assembly is virtually the same, and likely to remain so as the flight controller is upgraded. +这个构建记录仍然具有相关性,因为套装组件几乎是一样的,而且随着飞行控制器升级,很可能仍然如此。 ::: This topic provides full instructions for building the kit and configuring PX4 using _QGroundControl_. @@ -10,7 +10,7 @@ This topic provides full instructions for building the kit and configuring PX4 u ## Key information - **Full Kit:** [Holybro X500 Kit](https://holybro.com/products/px4-development-kit-x500-v2) -- **Flight controller:** [Pixhawk 4](../flight_controller/pixhawk4.md) +- **飞行控制器:** [Pixhawk 4](../flight_controller/pixhawk4.md) - **Assembly time (approx.):** 3.75 hours (180 minutes for frame, 45 minutes for autopilot installation/configuration) ![Full X500 Kit](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_hero.png) @@ -26,10 +26,10 @@ The Holybro [X500 Kit](https://holybro.com/products/px4-development-kit-x500-v2) - Holybro BLHeli S ESC 20A x4 (superseded - check [spare parts list](https://holybro.com/products/spare-parts-x500-v2-kit) for current version). - Propellers - 1045 x4 (superseded - check [spare parts list](https://holybro.com/products/spare-parts-x500-v2-kit) for current version). - Battery Strap -- Power and Radio Cables +- 电源线和信号线 - Wheelbase - 500 mm - Dimensions - 410x410x300 mm -- 433 MHz / 915 MHz [Holybro Telemetry Radio](../telemetry/holybro_sik_radio.md) +- 433 MHz / 915 MHz [Holybro数传电台](../telemetry/holybro_sik_radio.md) Additionally you will need a battery and receiver ([compatible radio system](../getting_started/rc_transmitter_receiver.md)) if you want to control the drone manually. @@ -55,14 +55,14 @@ This section lists all hardware for the frame and the autopilot installation. ### Electronics -| Item Description | Quantity | -| ------------------------------------------------------------------------------ | -------- | -| Pixhawk4 & Assorted Cables | 1 | -| Pixhawk4 GPS Module | 1 | -| Power Management PM07 (with pre-soldered ESC power cables) | 1 | -| Motors 2216 KV880(V2 Update) | 4 | -| Holybro BLHeli S ESC 20A x4 | 1 | -| 433 MHz / 915 MHz [Holybro Telemetry Radio](../telemetry/holybro_sik_radio.md) | 1 | +| 物品描述 | Quantity | +| ----------------------------------------------------------------------------- | -------- | +| Pixhawk4 & Assorted Cables | 1 | +| Pixhawk4 GPS Module | 1 | +| Power Management PM07 (with pre-soldered ESC power cables) | 1 | +| Motors 2216 KV880(V2 Update) | 4 | +| Holybro BLHeli S ESC 20A x4 | 1 | +| 433 MHz / 915 MHz [Holybro数传电台](../telemetry/holybro_sik_radio.md) | 1 | ### Tools needed @@ -81,125 +81,125 @@ The following tools are used in this assembly: Estimate time to assemble is 3.75 hours (180 minutes for frame, 45 minutes for autopilot installation/configuration) 1. Start by assembling the landing gear. - Unscrew the landing gear screws and insert the vertical pole (figures 1 and 2). + Unscrew the landing gear screws and insert the vertical pole (figures 1 and 2). - ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) + ![Landing Figure 1: Components](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig1.jpg) - _Figure 2_: Landing gear components + _Figure 2_: Landing gear components - ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) + ![Landing Figure 2: Assembled](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_1_fig2.jpg) - _Figure 2_: Landing gear assembled + _Figure 2_: Landing gear assembled 2. Then put the 4 arms through the 4 motor bases shown in figure 3. - Make sure the rods protrude the base slightly and are consistent throughout all 4 arms, and be sure to have the motor wires facing outward. + Make sure the rods protrude the base slightly and are consistent throughout all 4 arms, and be sure to have the motor wires facing outward. - ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) + ![Attach arms to motor bases](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_step_2_fig3.png) - _Figure 3_: Attach arms to motor bases + _Figure 3_: Attach arms to motor bases 3. Insert 4 nylon screws and nylon standoffs and attach the power module PM07 to the bottom plate using 4 nylon nuts as shown in Figures 4. - ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) + ![Attach power module](../../assets/airframes/multicopter/x500_holybro_pixhawk4/power_module.jpg) - _Figure 4_: Attach power module + _Figure 4_: Attach power module 4. Feed the 4 motor ESCs through each of the arms and connect the 3-wires end to the motors shown in Figure 5. - + - _Figure 5_: Connect motors + _Figure 5_: Connect motors 5. Connect the ESCs power wires onto the power module PM07, black->black and red->red, ESC PWM signal wires goes to "FMU-PWM-Out". - Make sure you connect the motor ESC PWM wires in the correct order. - Refer to Figure 7 for airframe motor number and connect to the corresponding number on the PM07 board. + Make sure you connect the motor ESC PWM wires in the correct order. + Refer to Figure 7 for airframe motor number and connect to the corresponding number on the PM07 board. - ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) - _Figure 7_: ESC power module and signal wiring + ![ESC power module and signal wiring](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_pwm.jpg) + _Figure 7_: ESC power module and signal wiring - The color on top of the motor indicate the spin direction (figure 7-1), black tip is clockwise, and white tip is counter-clockwise. - Make sure the follow the px4 quadrotor x airframe reference for motor direction (figure 7-2). + The color on top of the motor indicate the spin direction (figure 7-1), black tip is clockwise, and white tip is counter-clockwise. + Make sure the follow the px4 quadrotor x airframe reference for motor direction (figure 7-2). - + - _Figure 7_: Motor order/direction diagram + _Figure 7_: Motor order/direction diagram - + - _Figure 7-1_: Motor direction + _Figure 7-1_: Motor direction 6. Connect the 10 pin cables to FMU-PWM-in, the 6 pin cables to the PWR1 on the PM07 power module. - ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) + ![Flight controller/Power module PWM and Power connections](../../assets/airframes/multicopter/x500_holybro_pixhawk4/pm07_cable.jpg) - _Figure 8_: Power module PWM and power wiring + _Figure 8_: Power module PWM and power wiring 7. If you want to mount the GPS on the top plate, you can now secure the GPS mount onto the top plate using 4 screws and nuts. - + - _Figure 9_: Secure GPS mount onto top plate + _Figure 9_: Secure GPS mount onto top plate 8. Feed the PM07 cables through the top plate. - Connect the top and bottom plate by using 4 U-shaped nylon straps, screws, and nuts on each side, ensure that the motor ESC cables are inside the U-shape nylon straps like Figure 10, keep the nut loose. + Connect the top and bottom plate by using 4 U-shaped nylon straps, screws, and nuts on each side, ensure that the motor ESC cables are inside the U-shape nylon straps like Figure 10, keep the nut loose. - + - _Figure 10-1_: Feed power module cables through top plate + _Figure 10-1_: Feed power module cables through top plate - + - _Figure 10-2_: Connecting top and bottom plate + _Figure 10-2_: Connecting top and bottom plate 9. Push the arm tubes a bit into the frame and make sure the amount of protrusion (red square from Figure 11) are consistent on all 4 arms. - Ensure all the motors are pointed directly upward, then tighten all the nuts and screws. + Ensure all the motors are pointed directly upward, then tighten all the nuts and screws. - ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) + ![Arms 3](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig16.jpg) 10. Put the hanger gaskets into the 4 hangers and mount them onto the bottom plate using 8 hex screws (Figure 11). - The screw holes are noted by the white arrow in Figure 12. - We recommend tilting the drone sideway to make the installation easier. + The screw holes are noted by the white arrow in Figure 12. + We recommend tilting the drone sideway to make the installation easier. - + - _Figure 11_: Hanger gaskets + _Figure 11_: Hanger gaskets - ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) + ![Battery Mount 4](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig10.jpg) - _Figure 12_: Screw holes + _Figure 12_: Screw holes 11. Insert the slide bars onto the hanger rings (Figure 13). - Assemble the battery mount and platform board and mount them onto the slide bars as shown in Figure 14. + Assemble the battery mount and platform board and mount them onto the slide bars as shown in Figure 14. - ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) + ![Battery Mount 2: Slide bars](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig8.png) - _Figure 13_: Slide bars + _Figure 13_: Slide bars - + - _Figure 14_: Battery mount on slide bars + _Figure 14_: Battery mount on slide bars 12. Mount the landing gear onto the bottom plate. - We recommend tilting the drone sideway to make this installation process easier. + We recommend tilting the drone sideway to make this installation process easier. - ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) + ![Landing Gear](../../assets/airframes/multicopter/x500_holybro_pixhawk4/x500_fig5.jpg) - _Figure 15_: Landing Gear + _Figure 15_: Landing Gear 13. Use the tape and stick the GPS to the top of the GPS mast and mount the GPS mast. - Make sure the arrow on the gps is pointing forward (Figure 16). + Make sure the arrow on the gps is pointing forward (Figure 16). - + - _Figure 16_: GPS and mast + _Figure 16_: GPS and mast 14. Mount the telemetry radio onto the top plate. - Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. - Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. + Plug the telemetry cable into `TELEM1` port and GPS module to `GPS MODULE` port on the flight controller. + Plug the cable from PM07 `FMU-PWM-in` to `I/O-PWM-out`on the FC and PM07 `PWR1` to `POWER1` on the FC, as shown in Figure 17. - ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) + ![Pixhawk 4 wiring 1](../../assets/airframes/multicopter/x500_holybro_pixhawk4/fc_connections.jpg) - _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. + _Figure 17_: Mount telemetry radio/plug in PWM and Power cables to Flight controller. Please refer to [Pixhawk 4 Quick Start](../assembly/quick_start_pixhawk4.md) for more information. @@ -223,7 +223,7 @@ First update the firmware, airframe, and actuator mappings: - [Airframe](../config/airframe.md) - You will need to select the _Holybro S500_ airframe (**Quadrotor x > Holybro S500**). + 您需要选择 _Holybro S500_ 机架(**Quadrotor x > Holybro S500**)。 ![QGroundControl - Select HolyBro X500 airframe](../../assets/airframes/multicopter/s500_holybro_pixhawk4/qgc_airframe_holybro_s500.png) @@ -250,7 +250,7 @@ Ideally you should also do: ## 调试 Airframe selection sets _default_ autopilot parameters for the frame. -These are good enough to fly with, but it is a good idea to tune the parameters for a specific frame build. +这些足以让它起飞,但是为你的特定框架调整专有参数是一个好主意。 For instructions on how, start from [Autotune](../config/autotune_mc.md). diff --git a/docs/zh/frames_multicopter/holybro_x500v2_pixhawk6c.md b/docs/zh/frames_multicopter/holybro_x500v2_pixhawk6c.md index 3b07a691d6..4b45fdeeab 100644 --- a/docs/zh/frames_multicopter/holybro_x500v2_pixhawk6c.md +++ b/docs/zh/frames_multicopter/holybro_x500v2_pixhawk6c.md @@ -18,21 +18,21 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] **Screw**- Sunk Screw M2.5\*6 12pcs 1. Insert the hanger rubber ring gasket in each of their respective hangers. - Do not use sharp objects to press the rubbers inside. + Do not use sharp objects to press the rubbers inside. - [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) + [![Assembly1](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly1.png)](https://www.youtube.com/watch?v=4Tid-FCP_aI) 2. Take the battery mounting board and screw it with the slide bar clip using the Sunk Screw M2.5\*6. - [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) + [![Assembly2](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly2.png)](https://youtu.be/9E-rld6tPWQ) 3. Screw 4 hangers to the Platform Board using Sunk Screw M2.5\*6. - [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) + [![Assembly3](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly3.png)](https://youtu.be/4qIBABc9KsY)) 4. Take the slide bar and insert 4 hangers to screw to the bottom plate later. - [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) + [![Assembly4](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly4.png)](https://youtu.be/CFx6Ct7FCIc)) 5. Now insert the battery holder and payload holders assembled in step 2 & 3 @@ -44,11 +44,11 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. Take the bottom plate and insert 4 M3\*14 screws and fasten the nylon standoffs on the same. - [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) + [![Assembly6](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly6.png)](https://youtu.be/IfsMXTr3Uy4) 2. Place the Power distribution board and use the locknuts to assemble them. The power module PM02 (for Pixhawk 6C) would power this board - [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) + [![Assembly7](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly7.png)](https://youtu.be/Qjs6pqarRIY) 3. Use Socket Cap Screws M2.5\*6 and screw the bottom plate on the 4 hangers (that we inserted in the 2 bars on the 3rd step of the payload holder assembly) @@ -56,15 +56,15 @@ This topic provides full instructions for building the [Holybro X500 V2 ARF Kit] 1. To assemble the landing gear, loosen the pre-assembled screws of the Landing Gear-Cross Bar and insert the Landing Gear-Vertical Pole and fasten the same. - [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) + [![Assembly8](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly8.png)](https://youtu.be/mU4vm4zyjcY) - [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) + [![Assembly9](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly9.png)](https://youtu.be/7REaF3YAqLg) 2. Use the Socket Cap Screw M3\*8 to screw the landing gears to the bottom plate - [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) + [![Assembly11](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly11.png)](https://youtu.be/iDxzWeyCN54) - [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) + [![Assembly12](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly12.png)](https://youtu.be/3fNJQraCJx0) Because it’s cumbersome to insert the wires once the top plate is assembled, do the wiring beforehand. Although the design is well built such that you can do this later as well. @@ -84,7 +84,7 @@ Note that the ESC connectors are color-coded and must be inserted in the PWM out ![esc_connector_pixhawk6c](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/esc_connector.jpg) -### Arms +### 机臂 **Screw-** Socket Cap Screw M3\*38 16pcs | Flange Locknut M3 16pcs @@ -92,28 +92,28 @@ Note that the ESC connectors are color-coded and must be inserted in the PWM out 1. Putting the arms is quite simple as the motors come pre-assembled. - - Ensure that you have the right numbered arm with its motor on the respective side. + - Ensure that you have the right numbered arm with its motor on the respective side. - [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) + [![Assembly15](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly15.png)](https://youtu.be/45KCey3WiJ4) - :::tip - Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. + :::tip + Use your allen keys/ any elongated item and insert it on the opposite side of the bolt that you're trying to fasten. ::: 2. Take one arm and insert the rectangle extrusion inside the rectangular hollow on the bottom plate. - [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) + [![Assembly16](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly16.png)](https://youtu.be/GOTqmjq9_3s) 3. While inserting the top plate on top of this the 3 piece assembly (bottom plate, top plate & arms) have to screwed using Socket Cap Screw M3\*38 and Flange Locknut M3. 4. Hold one side using the mini cross wrench provided in the developer kit. - [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) + [![Assembly17](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly17.png)](https://youtu.be/2rcNVekJQd0) 5. Do not fasten any screws before all 3 motors are in place as this might make it difficult while you’re assembling the 3rd and 4th motor. - [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) + [![Assembly18](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly18.png)](https://youtu.be/SlKRuNoE_AY) ### Propellers @@ -132,13 +132,13 @@ The following parts can be placed as per usual. 1. Assemble the GPS by following the video. - [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) + [![Assembly20](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly20.png)](https://youtu.be/aiFxVJFjlos) - This guide uses the GPS mount location suggested in Holybro’s guide. + This guide uses the GPS mount location suggested in Holybro’s guide. 2. Screw the GPS mount’s bottom end on the payload holder side using Locknut M3 & Screw M3\*10 - [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) + [![Assembly21](../../assets/airframes/multicopter/x500_v2_holybro_pixhawk6c/assembly21.png)](https://youtu.be/uG5UKy3FrIc) ### Pixhawk 6C @@ -207,7 +207,7 @@ Ideally you should also do: ## 调试 Airframe selection sets _default_ autopilot parameters for the frame. -These are good enough to fly with, but it is a good idea to tune the parameters for a specific frame build. +这些足以让它起飞,但是为你的特定框架调整专有参数是一个好主意。 For instructions on how, start from [Auto-tune](../config/autotune_mc.md). diff --git a/docs/zh/frames_multicopter/qav_r_5_kiss_esc_racer.md b/docs/zh/frames_multicopter/qav_r_5_kiss_esc_racer.md index 9fbeb29890..31a05cffaf 100644 --- a/docs/zh/frames_multicopter/qav_r_5_kiss_esc_racer.md +++ b/docs/zh/frames_multicopter/qav_r_5_kiss_esc_racer.md @@ -270,6 +270,6 @@ Ideally you should also do: ### 调试 Airframe selection sets _default_ autopilot parameters for the frame. -These are good enough to fly with, but it is a good idea to tune the parameters for a specific frame build. +这些足以让它起飞,但是为你的特定框架调整专有参数是一个好主意。 For instructions on how, start from [Autotune](../config/autotune_mc.md). diff --git a/docs/zh/frames_rover/index.md b/docs/zh/frames_rover/index.md index 59537ab34e..7c6b4bffbc 100644 --- a/docs/zh/frames_rover/index.md +++ b/docs/zh/frames_rover/index.md @@ -55,17 +55,19 @@ Each wheel is driven by its own motor, and by controlling the speed and directio ![Mecanum rover](../../assets/airframes/rover/rover_mecanum.png) -## See Also +## 另见 -- [Drive Modes](../flight_modes_rover/index.md). +- [Drive Modes](../flight_modes_rover/index.md) - [Configuration/Tuning](../config_rover/index.md) +- [Apps & API](../flight_modes_rover/api.md) - [Complete Vehicles](../complete_vehicles_rover/index.md) ## 仿真 -[Gazebo](../sim_gazebo_gz/index.md) provides simulations for ackermann and differential rovers: +PX4 provides synthetic simulation models for [Gazebo](../sim_gazebo_gz/index.md) of all three rover types to test the software and validate changes and new features: - [Ackermann rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) - [Differential rover](../sim_gazebo_gz/vehicles.md#differential-rover) +- [Mecanum rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) ![Rover gazebo simulation](../../assets/airframes/rover/rover_simulation.png) diff --git a/docs/zh/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md b/docs/zh/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md index c88c3d223c..a24076acec 100644 --- a/docs/zh/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md +++ b/docs/zh/frames_vtol/vtol_quadplane_falcon_vertigo_hybrid_rtf_dropix.md @@ -67,45 +67,45 @@ The RTF kit requires the following assembly. 1. Spread gorilla glue inside the wing brackets as shown. - ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) + ![Add glue on wing brackets](../../assets/airframes/vtol/falcon_vertigo/wing_brackets_glue.jpg) 2. Attach the carbon tube in the brackets. The bracket and tube must be aligned using the white mark (as shown in the picture). - ::: info - This is very important because the white mark indicates the center of gravity. + ::: info + This is very important because the white mark indicates the center of gravity. ::: - + 3. The following images show the alignment of rods from other viewpoints: - ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) - ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) + ![quad motor frame rod alignment from bottom](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_9_bottom_view_rod_alignment.jpg) + ![quad motor frame rod alignment schematic](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_11_rod_alignment_schamatic.jpg) ### Step 2: Attach the wings 1. Insert both carbon tubes into the fuselage. - + 2. Spread gorilla glue between the two white marks on each tube (indicated by the red arrows). The white mark in the center (blue arrow) will be placed in the center of the fuselage and the other marks on the sides. - + 3. Once the carbon tubes are inside the fuselage, spread gorilla glue on the rest of the tube and attach the wings. 4. The fuselage has two holes for the motor and servo cables. Pass the cables through the holes and then join the wings to the fuselage. - + 5. Within the fuselage connect the signal cables you just passed through from the wings to the ESC using the provided connectors. The ESC are already connected to the motors and set up to turn in the correct order (you will need to connect the ESC PDB to a power module in a later step). - + 6. As with the ESCs, the servos are already installed. Connect the signal cable from the wing (passed through the fuselage) to the flight controller. - + 7. Repeat these steps for the other wing. @@ -123,11 +123,11 @@ General information about connecting Dropix can be found in [Dropix Flight Contr 1. Connect the ESC to the power module using the XT60 connector - + 2. Pass the signals cables through to the flight controller - + #### Motor Wiring @@ -162,7 +162,7 @@ The image below shows back of the dropix flight controller, highlighting the out 3. Connect the throttle motor signal cable from the ESC to the appropriate flight controller auxiliary port. Connect the ESC to the throttle motor. - + 4. Connect the receiver (RC IN). @@ -176,7 +176,7 @@ The sensor inputs, telemetry, buzzer and safety switch are located in the front 1. Connect the telemetry, airspeed sensor, GPS, buzzer and safety switch as shown. - + #### Flight Controller: Connect power module and external USB @@ -184,7 +184,7 @@ The inputs for the USB port, power module and external USB are located on the ri 1. Connect power and USB as shown - + :::tip The external USB is optional. @@ -201,27 +201,27 @@ It is important that nothing obstructs airflow to the Pitot tube. This is critic 1. Install the Pitot tube in the front of the plane - + 2. Secure the connecting tubing and ensure that it is not bent/kinked. - + 3. Connect the tubes to the airspeed sensor. - + #### Install/connect receiver and telemetry module 1. Paste the receiver and telemetry module to the outside of the vehicle frame. - + 2. Connect the receiver to the RC IN port on the _back_ of the dropix, as shown above (also see the [flight controller instructions](#dropix_back)). 3. Connect the telemetry module to the _front_ of the flight controller as shown below (see the [flight controller instructions](#dropix_front) for more detail on the pins). - + @@ -237,7 +237,7 @@ The GPS/Compass module is already mounted on the wing, in the default orientatio 1. Set your flight controller orientation to 270 degrees. - + 2. Secure the controller in place using vibration damping foam. @@ -247,21 +247,21 @@ The final assembly step is to check the vehicle is stable and that the motors ha 1. Check that the motors turn in the correct directions (as in the QuadX diagram below). - + - ::: info - If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). + ::: info + If necessary the servo direction can be reversed using the `Rev Range (for servos)` checkbox associated with each servo output in the QGroundControl [Actuator Output](../config/actuators.md#actuator-outputs) configuration (for servos only) (this sets the [PWM_AUX_REV](../advanced_config/parameter_reference.md#PWM_AUX_REV) or [PWM_AUX_MAIN](../advanced_config/parameter_reference.md#PWM_MAIN_REV) parameter). ::: 2. Check the vehicle is balanced around the expected centre of gravity - - Hold the vehicle with your fingers at the center of gravity and check that the vehicle remains stable. + - Hold the vehicle with your fingers at the center of gravity and check that the vehicle remains stable. - ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) + ![Level Centre of Gravity](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_57_level_centre_of_gravity.jpg) - - If the vehicle leans forward or backwards, move the motors to balance it. + - If the vehicle leans forward or backwards, move the motors to balance it. - ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) + ![Level Motors](../../assets/airframes/vtol/falcon_vertigo/falcon_vertigo_55_level_motors.jpg) ## 配置 @@ -271,7 +271,7 @@ Perform the normal [Basic Configuration](../config/index.md). 1. For [Airframe](../config/airframe.md) select the vehicle group/type as _Standard VTOL_ and the specific vehicle as [Generic Standard VTOL](../airframes/airframe_reference.md#vtol_standard_vtol_generic_standard_vtol) as shown below. - ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) + ![QCG - Select Generic Standard VTOL](../../assets/qgc/setup/airframe/px4_frame_generic_standard_vtol.png) 2. Set the [Autopilot Orientation](../config/flight_controller_orientation.md) to `ROTATION_YAW_270` as the autopilot is mounted [sideways](#flight_controller_orientation) with respect to the front of the vehicle. The compass is oriented forward, so you can leave that at the default (`ROTATION_NONE`). diff --git a/docs/zh/frames_vtol/vtol_quadplane_foxtech_loong_2160.md b/docs/zh/frames_vtol/vtol_quadplane_foxtech_loong_2160.md index cc6418299f..660531d13d 100644 --- a/docs/zh/frames_vtol/vtol_quadplane_foxtech_loong_2160.md +++ b/docs/zh/frames_vtol/vtol_quadplane_foxtech_loong_2160.md @@ -80,7 +80,7 @@ The following tools were used for this build. - 3D-Printer - [Blue Loctite](https://www.amazon.com/Loctite-Heavy-Duty-Threadlocker-Single/dp/B000I1RSNS?th=1) -## Hardware Integration +## 硬件集成 In this documentation the integration of a Auterion Skynode is described. The installation of a Pixhawk can be done similarly. @@ -99,33 +99,33 @@ Use a soldering iron to press the threaded inserts into the 3D-Printed parts. 1. Insert 10x M3 threaded inserts into the baseplate as shown in the picture: - ![Baseplate with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) + ![Baseplate with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/03-baseplate.jpg) 2. Insert 2x M3 threaded inserts into the stack fixture as shown in the picture below: - ![Stack fixture with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) + ![Stack fixture with threaded inserts](../../assets/airframes/vtol/foxtech_loong_2160/04-stack-fixture.jpg) 3. Insert 2x M4 threaded inserts into the fan mount and radio mount as shown in the picture below. - ![Radio-mount](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) + ![Radio-mount](../../assets/airframes/vtol/foxtech_loong_2160/05-radio-mount.jpg) - If you would like to add a 40mm 5V fan to the fan mount, insert 4x M3 inserts. + If you would like to add a 40mm 5V fan to the fan mount, insert 4x M3 inserts. - ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) + ![Fan-mount](../../assets/airframes/vtol/foxtech_loong_2160/06-fan-mount.jpg) 4. Change the cable connector to a servo connector so it can be plugged into the servo rail to be powered. - ::: info - A fan might be needed if a powerful radio is used. + ::: info + A fan might be needed if a powerful radio is used. ::: - ![Fan-mount with fan](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) + ![Fan-mount with fan](../../assets/airframes/vtol/foxtech_loong_2160/07-fan-mount.jpg) 5. Remove the original mounting plate from the vehicle. - Tape the cables to the outside of the fuselage. + Tape the cables to the outside of the fuselage. - ![Empty fuselage](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) + ![Empty fuselage](../../assets/airframes/vtol/foxtech_loong_2160/08-preparations.jpg) 6. Slide the baseplate into the vehicle. @@ -142,9 +142,9 @@ The 40A power module provides power for the avionics when using Skynode (and com 1. Remove the case from the 40A PM. 2. Screw the PM with 2x M2x6mm to the bottom of the baseplate. 3. Create a cable to extend the XT60 connector to an XT30 that is mounted on the baseplate. - With that, the 6S battery power can be directly plugged into the XT30 connector with the pre-configured cable that comes with the vehicle. + With that, the 6S battery power can be directly plugged into the XT30 connector with the pre-configured cable that comes with the vehicle. - ![40A Power Module installation](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) + ![40A Power Module installation](../../assets/airframes/vtol/foxtech_loong_2160/10-40a-power-module.jpg) If necessary, the 10V output of the radio port on the PM can also be exposed via an XT30 that can be mounted next to the 6S battery input XT60. @@ -153,17 +153,17 @@ If necessary, the 10V output of the radio port on the PM can also be exposed via #### Pitot Tube 1. The sensor can be installed with 2x M3x16mm screws in the front right corner of the baseplate. - Take care that the connector is facing the center of the fuselage. + Take care that the connector is facing the center of the fuselage. - ![Mounted airspeed sensor](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) + ![Mounted airspeed sensor](../../assets/airframes/vtol/foxtech_loong_2160/11-airspeed-sensor.jpg) - Only the front tube (not as shown in the picture) is used; the other tube can be removed since our experience showed that the pressure inside the fuselage is sufficient as static pressure. + Only the front tube (not as shown in the picture) is used; the other tube can be removed since our experience showed that the pressure inside the fuselage is sufficient as static pressure. 2. When the stack is mounted inside the fuselage, the tube coming from the wing and the one from the airspeed sensor need to be spliced together. - Use some spit (that's the easiest way) to push them together and afterward use a heat shrink tube to reinforce the connection. + Use some spit (that's the easiest way) to push them together and afterward use a heat shrink tube to reinforce the connection. - :::warning - Use a heat source carefully since the foam starts to melt at high temperatures. + :::warning + Use a heat source carefully since the foam starts to melt at high temperatures. ::: @@ -175,22 +175,22 @@ If no lidar is mounted you should disable using fixed-wing actuation in hover to ::: 1. Mark the location to install the lidar with some tape or a pen. - Cut a hole inside the PVC shell and the foam, so that the lidar fits in place. + Cut a hole inside the PVC shell and the foam, so that the lidar fits in place. - ![Prepared lidar hole](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) + ![Prepared lidar hole](../../assets/airframes/vtol/foxtech_loong_2160/12-lidar-01.jpg) 2. Secure the lidar with hot glue. - ![Installed lidar](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) + ![Installed lidar](../../assets/airframes/vtol/foxtech_loong_2160/13-lidar-02.jpg) #### GPS/Compass 1. Use double sided tape to mount the GPS in the rear of the vehicle underneath the rear latch. - ![Installed GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) + ![Installed GPS](../../assets/airframes//vtol/foxtech_loong_2160/14-gps.jpg) - The arrow on the GPS for the orientation can be ignored. - The orientation will be detected by the flight controller during the calibration. + The arrow on the GPS for the orientation can be ignored. + The orientation will be detected by the flight controller during the calibration. ### Flight Controller @@ -203,15 +203,15 @@ Install either the Pixhawk or Skynode onto the baseplate. #### Skynode 1. Use 4x M3x8 screws to mount the Skynode to the baseplate. - Make sure that the top of the "A" is facing to the front of the vehicle. + Make sure that the top of the "A" is facing to the front of the vehicle. 2. Plug the 40A Power Module into the upper one of the two power connectors. 3. Plug one (or if needed two) USB adapters into the 4-pin JST-GH connectors into the back of the Skynode and feed them to the front of the plate. - Fix the cables with zip ties in place. + Fix the cables with zip ties in place. 4. Tape a I2C splitter to the front right side of the baseplate (The splitter can be used to plug in ETH devices such as a radio link.) 5. Connect the I2C splitter with the ETH port in the back of the Skynode. 6. Plug in the two 40-pin cables into the front of the Skynode. 7. Plug in the USB-C extension cable and bend it over to the front. - The bend needs to be very tight, so that the plate will fit into the vehicle. + The bend needs to be very tight, so that the plate will fit into the vehicle. ![Installed Skynode](../../assets/airframes/vtol/foxtech_loong_2160/15-skynode.jpg) @@ -223,17 +223,17 @@ Install either the Pixhawk or Skynode onto the baseplate. 1. Tape the Skynode LTE antennas to the side of the fuselage as shown in the picture: - ![LTE-Antennas](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) + ![LTE-Antennas](../../assets/airframes/vtol/foxtech_loong_2160/16-lte-antennas.jpg) 2. If you are using a radio telemetry module you can mount the antennas to the top of the fuselage. - In the front you can mount the antenna extension cable directly. + In the front you can mount the antenna extension cable directly. - ![WIFI-Antennas-Front](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) + ![WIFI-Antennas-Front](../../assets/airframes/vtol/foxtech_loong_2160/17-antenna-front.jpg) - In the back you can use the 3D-Printed antenna adapter. - The adapter can be glued in place with hot glue. + In the back you can use the 3D-Printed antenna adapter. + The adapter can be glued in place with hot glue. - ![WIFI-Antenna-Back](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) + ![WIFI-Antenna-Back](../../assets/airframes/vtol/foxtech_loong_2160/19-rear-antenna.jpg) ### 12S Power Module diff --git a/docs/zh/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md b/docs/zh/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md index d61a2e32b8..0903bed592 100644 --- a/docs/zh/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md +++ b/docs/zh/frames_vtol/vtol_tiltrotor_omp_hobby_zmo_fpv.md @@ -74,7 +74,7 @@ The following tools were used for this build. - Sandpaper - 3D-Printer -## Hardware Integration +## 硬件集成 ### Preparations @@ -93,7 +93,7 @@ Flight controller and wing connectors removed from the vehicle. ### ESCs 1. Unsolder the ESC PWM-signal and ground pins and solder some servo extension wire to the pins. - The cable should be long enough to connect the wire to the FMU pins of the flight controller. + The cable should be long enough to connect the wire to the FMU pins of the flight controller. 2. Unsolder the 3 female banana plug connectors of the rear motor (might not be necessary for the Pixhawk 6 integration). @@ -103,17 +103,17 @@ Flight controller and wing connectors removed from the vehicle. 5. Solder signal and GND wires to the PWM input ot the ESC. - ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) + ![ESC 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-01.jpg) 6. Remove the female banana plug on the ESC. - This will give you more space to install the flight controller. + This will give you more space to install the flight controller. - ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) + ![ESC 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-02.jpg) 7. Solder the rear motor wires to the ESC. - Make sure to connect such that the motor spins in the correct direction. + Make sure to connect such that the motor spins in the correct direction. - ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) + ![ESC 03](../../assets/airframes/vtol/omp_hobby_zmo_fpv/esc-03.jpg) ### Wing Connector @@ -122,9 +122,9 @@ This step is not essential, but makes the handling much easier and there is one 1. Glue the wing connectors into the 3D-Printed part with hot-glue or 5 min epoxy. 2. Glue the 3D-printed part with the connector in to the fuselage. - Make sure to properly align the connector while the glue cures. + Make sure to properly align the connector while the glue cures. - The easiest way to align the connector is to mount the wing while the glue is curing, but make sure that no glue is between the fuselage and the wing, otherwise the wing might get stuck. + The easiest way to align the connector is to mount the wing while the glue is curing, but make sure that no glue is between the fuselage and the wing, otherwise the wing might get stuck. The connector glued into the 3D-Printed part @@ -137,58 +137,58 @@ The connector glued into the fuselage. Make sure to properly align the connector ### Pixhawk Adapter Boards and BEC 1. Cut the foam as shown in the pictures to create space to mount the Pixhawk adapter boards and BEC with double sided tape. - The FMU board is placed on the left side (in flight direction) of the fuselage. - Solder a servo connector and a cable for the battery voltage to the BEC. + The FMU board is placed on the left side (in flight direction) of the fuselage. + Solder a servo connector and a cable for the battery voltage to the BEC. - ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) - ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) + ![Foam cutout 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/foam-cut-01.png) + ![Pixhawk adapter board mount 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pixhawk-adapter-01.jpg) 2. Prepare the BEC to connect to the IO board and to the battery. - The BEC can also be soldered directly to the battery pads of the ESC. + The BEC can also be soldered directly to the battery pads of the ESC. - ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) + ![BEC preparation](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-01.jpg) 3. Mount the BEC with double sided tape. - ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) + ![BEC mounting](../../assets/airframes/vtol/omp_hobby_zmo_fpv/bec-02.jpg) ### Cables 1. Cut the connectors off the servos and solder the servo extension cables to the cables. - Make sure that the cables are long enough to reach the Pixhawk adapter board. - If you own a crimp tool, then you can also directly add the connectors without soldering. + Make sure that the cables are long enough to reach the Pixhawk adapter board. + If you own a crimp tool, then you can also directly add the connectors without soldering. 2. Plug the servo cables into the adapter IO board in the following order: - - 1 - Aileron left - - 2 - Aileron right - - 3 - V-Tail left - - 4 - V-Tail right - - 5 - Tilt left - - 6 - Tilt right + - 1 - Aileron left + - 2 - Aileron right + - 3 - V-Tail left + - 4 - V-Tail right + - 5 - Tilt left + - 6 - Tilt right 3. Plug in the motor signal cables into the FMU adapter board in the following order: - - 1 - Front left - - 2 - Front right - - 3 - Rear + - 1 - Front left + - 2 - Front right + - 3 - Rear ### 传感器 #### Pitot Tube 1. First check if the pitot tube fits into the 3D-Printed mount. - If this is the case, glue the pitot tube mount into place. + If this is the case, glue the pitot tube mount into place. - To align the tube feed it through the second hole from the right of the FPV front plate. - The mount will enable you to push the tube back into the fuselage to protect it during transportation and handling. - The sensor unit can be mounted on top of the 3D-Printed mount with double sided tape. + To align the tube feed it through the second hole from the right of the FPV front plate. + The mount will enable you to push the tube back into the fuselage to protect it during transportation and handling. + The sensor unit can be mounted on top of the 3D-Printed mount with double sided tape. 2. Glue the 3D-Printed mount into place. - ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) + ![Pitot tube 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-01.png) 3. The sensor can be mounted on top of the 3D-Printed mount. - ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) + ![Pitot tube 02](../../assets/airframes/vtol/omp_hobby_zmo_fpv/pitot-tube-02.png) #### Lidar @@ -209,9 +209,9 @@ To mount the GPS: 2. Take the GPS out of the plastic case and unplug the connector. 3. Feed the cable through the carbon spar. 4. Glue the 3D-Printed part with 5 min epoxy in place. - ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) + ![Glue the GPS mount into place](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-01.jpg) 5. After the glue has cured, screw the GPS with 4x M2.5x10 screws to the plate. - ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) + ![Screw the GPS to the mount2](../../assets/airframes/vtol/omp_hobby_zmo_fpv/gps-02.jpg) #### USB Camera @@ -219,9 +219,9 @@ To mount the GPS: 2. Cut the USB-Adapter cable to be 25 cm and solder the two cables together. 3. To install the camera you need to cut a hole into the foam of the wall. - ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) + ![USB Camera 01: Hole to feed the USB cable through the wall.](../../assets/airframes/vtol/omp_hobby_zmo_fpv/camera-01.jpg) - Then you can mount the camera with double sided tape to the wall. + Then you can mount the camera with double sided tape to the wall. ### Flight Controller @@ -237,7 +237,7 @@ If a Skynode is used: 1. Place it at the on top of the ESCs and mark the 2 rear mounting locations on the injection molded plastic part of the ZMO. 2. Remove the Skynode from the vehicle and drill 2 holes with a 2.8 mm drill bit into the plastic part. - ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) + ![Mounting holes for the Skynode in the back](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-01.jpg) 3. Put the Skynode back into place and screw it down with 2x M3x10 screws. Another option is to add some threaded inserts into the holes. @@ -245,9 +245,9 @@ Since the injection molded part of the ZMO is very thin, they need to be glued i 1. Screw the front Skynode mount with 2x M3x10 screws at the Skynode. 2. Then add some 5 min epoxy at the bottom of the mount and put a weight on top of the Skynode until the glue is cured. - To access the 2 mounting screws at the front, poke 2 holes from the top through the foam. + To access the 2 mounting screws at the front, poke 2 holes from the top through the foam. - ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) + ![Skynode mount in the front](../../assets/airframes/vtol/omp_hobby_zmo_fpv/flight-controller-02.jpg) ### Antennas and RC Receiver @@ -258,14 +258,14 @@ An inexpensive example would be a [SiK Telemetry Radio](../telemetry/sik_radio.m ::: 1. One LTE antenna can be installed on the bottom of the vehicle. - For that you can feed the antenna wire through the opening for the ESC heat-sink. + For that you can feed the antenna wire through the opening for the ESC heat-sink. - ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) + ![LTE antenna 01](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-01.jpg) 2. The second antenna can be installed on the inside of the vehicle on the left side of the battery compartment. - The RC receiver can also be placed at the left side of the battery compartment. + The RC receiver can also be placed at the left side of the battery compartment. - ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) + ![LTE antenna 2 and RC receiver](../../assets/airframes/vtol/omp_hobby_zmo_fpv/lte-antenna-02.jpg) ## 软件设置 @@ -332,9 +332,9 @@ If motors/servos were connected to different outputs than suggested, you will ne 1. Switch the vehicle into manual mode (either via the flight mode switch or type `commander mode manual` into the MAVLink shell). 2. Check if the motors point upwards. - If the motors point forwards then their associated Tilt servos need to be reversed (selecting the checkbox next to each servo). + If the motors point forwards then their associated Tilt servos need to be reversed (selecting the checkbox next to each servo). - ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) + ![Tilt Servo adjustment](../../assets/airframes/vtol/omp_hobby_zmo_fpv/tilt-limits-01.jpg) 3. Adjust the minimum (or, if revesed: maximum) value such that the rotor thrust can point backward (needed for proper yaw allocation in Multicopter mode). diff --git a/docs/zh/gps_compass/ark_dan_gps.md b/docs/zh/gps_compass/ark_dan_gps.md new file mode 100644 index 0000000000..e6e80d0a43 --- /dev/null +++ b/docs/zh/gps_compass/ark_dan_gps.md @@ -0,0 +1,62 @@ +# ARK DAN GPS + +[ARK DAN GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox DAN-F10N GPS and industrial magnetometer. + +![ARK DAN GPS](../../assets/hardware/gps/ark/ark_dan_gps.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-dan-gps/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_DAN_GPS) +- 传感器 + - [u-blox DAN-F10N](https://www.u-blox.com/en/product/dan-f10n-module) + - L1/L5/E5a/B2a bands + - Consistently strong performance regardless of installation + - Integrated SAW-LNA-SAW for exceptional out-of-band jamming immunity + - u-blox F10 proprietary dual-band multipath mitigation technology + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 25mA Average + - 44mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## 硬件设置 + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 配置 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## 针脚定义 + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Voltage | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## 另见 + +- [ARK DAN GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-dan-gps) (ARK Docs) diff --git a/docs/zh/gps_compass/ark_sam_gps.md b/docs/zh/gps_compass/ark_sam_gps.md index 8354054a20..49059705f3 100644 --- a/docs/zh/gps_compass/ark_sam_gps.md +++ b/docs/zh/gps_compass/ark_sam_gps.md @@ -1,6 +1,6 @@ # ARK SAM GPS -[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps>) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. +[ARK SAM GPS](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. ![ARK SAM GPS](../../assets/hardware/gps/ark/ark_sam_gps.jpg) @@ -56,6 +56,6 @@ The module should be plug-n-play when used with the `GPS2` port on most flight c | 5 | SDA | 3.3V | | 6 | GND | GND | -## See Also +## 另见 - [ARK SAM GPS Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) (ARK Docs) diff --git a/docs/zh/gps_compass/ark_sam_gps_mini.md b/docs/zh/gps_compass/ark_sam_gps_mini.md new file mode 100644 index 0000000000..572130e6b8 --- /dev/null +++ b/docs/zh/gps_compass/ark_sam_gps_mini.md @@ -0,0 +1,61 @@ +# ARK SAM GPS MINI + +[ARK SAM GPS MINI](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) is a made in the USA and NDAA-compliant [GNSS/GPS](../gps_compass/index.md) u-blox SAM-M10Q GPS and industrial magnetometer. + +![ARK SAM GPS MINI](../../assets/hardware/gps/ark/ark_sam_gps_mini.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-sam-gps-mini/) (US) + +## Hardware Specifications + +- [Open Source Schematic and BOM](https://github.com/ARK-Electronics/ARK_SAM_GPS/tree/main) +- 传感器 + - [u-blox SAM-M10Q](https://www.u-blox.com/en/product/sam-m10q-module) + - Less than 38 mW power consumption without compromising GNSS performance + - Maximum position availability with 4 concurrent GNSS reception + - Advanced spoofing and jamming detection + - [ST IIS2MDC Magnetometer](https://www.st.com/en/mems-and-sensors/iis2mdc.html) +- Pixhawk Standard UART/I2C Connector (6 Pin JST SH) +- Power Requirements + - 5V + - 15mA Average + - 20mA Max +- LED Indicators + - GPS Fix +- USA Built +- NDAA Compliant +- 6 Pin Pixhawk Standard UART/I2C Cable + +## 硬件设置 + +The module comes with a Pixhawk-standard 6pin connector that will plug into the `GPS2` port on recent Pixhawk flight controllers. +It should be mounted front facing, as far away from the flight controller and other electronics as possible. + +For more information see [Mounting the GNSS/Compass](../gps_compass/index.md#mounting-the-gnss-compass) and [Hardware Setup](../gps_compass/index.md#hardware-setup). + +## PX4 配置 + +The module should be plug-n-play when used with the `GPS2` port on most flight controllers. + +[Secondary GPS Configuration (UART)](../gps_compass/index.md#secondary-gps-configuration-uart) explains how you can configure the port if the GPS is not detected (note, that the configuration is the same, even if you are using GPS 2 as the primary compass). + +## 针脚定义 + +### Pixhawk Standard UART/I2C Connector - 6 Pin JST-SH + +| Pin Number | Signal Name | Voltage | +| ---------- | ----------- | -------------------- | +| 1 | 5V | 5.0V | +| 2 | RX | 3.3V | +| 3 | TX | 3.3V | +| 4 | SCL | 3.3V | +| 5 | SDA | 3.3V | +| 6 | GND | GND | + +## 另见 + +- [ARK SAM GPS MINI Documentation](https://arkelectron.gitbook.io/ark-documentation/gps/ark-sam-gps) (ARK Docs) diff --git a/docs/zh/gps_compass/index.md b/docs/zh/gps_compass/index.md index d4d5a030bd..0419f27c1d 100644 --- a/docs/zh/gps_compass/index.md +++ b/docs/zh/gps_compass/index.md @@ -25,7 +25,9 @@ PX4 also supports [Real Time Kinematic (RTK)](../gps_compass/rtk_gps.md) and **P | 设备 | GPS | 罗盘 | [CAN](../dronecan/index.md) | Buzzer / SafeSw / LED | 备注 | | :----------------------------------------------------------- | :-------------------------: | :-------------------------: | :-------------------------: | :-------------------------: | :---------------------------------------------------------- | | [ARK GPS](../dronecan/ark_gps.md) | M9N | BMM150 | ✓ | ✓ | + Baro, IMU | +| [ARK DAN GPS](../gps_compass/ark_dan_gps.md) | DAN-F10N | IIS2MDC | | ✓ | | | [ARK SAM GPS](../gps_compass/ark_sam_gps.md) | SAM-M10Q | IIS2MDC | | ✓ | | +| [ARK SAM GPS MINI ](../gps_compass/ark_sam_gps_mini.md) | SAM-M10Q | IIS2MDC | | ✓ | | | [ARK TESEO GPS](../dronecan/ark_teseo_gps.md) | Teseo-LIV4F | BMM150 | ✓ | ✓ | + Baro, IMU | | [Avionics Anonymous UAVCAN GNSS/Mag][avionics_anon_can_gnss] | SAM-M8Q | MMC5983MA | ✓ | ✘ | | | [CUAV NEO 3 GPS](../gps_compass/gps_cuav_neo_3.md) | M9N | IST8310 | | ✓ | | @@ -145,21 +147,21 @@ To ensure the port is set up correctly perform a [Serial Port Configuration](../ The following steps show how to configure a secondary GPS on the `GPS 2` port in _QGroundControl_: 1. [Find and set](../advanced_config/parameters.md) the parameter [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) to **GPS 2**. - - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. - - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. + - Open _QGroundControl_ and navigate to the **Vehicle Setup > Parameters** section. + - Select the **GPS** tab, then open the [GPS_2_CONFIG](../advanced_config/parameter_reference.md#GPS_2_CONFIG) parameter and select `GPS 2` from the dropdown list. - ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) + ![QGC Serial Example](../../assets/peripherals/qgc_serial_config_example.png) 2. Reboot the vehicle in order to make the other parameters visible. 3. Select the **Serial** tab, and open the [SER_GPS2_BAUD](../advanced_config/parameter_reference.md#SER_GPS2_BAUD) parameter (`GPS 2` port baud rate): set it to _Auto_ (or 115200 for the Trimble). - ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) + ![QGC Serial Baudrate Example](../../assets/peripherals/qgc_serial_baudrate_example.png) After setting up the second GPS port: 1. Configure the ECL/EKF2 estimator to blend data from both GPS systems. - For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). + For detailed instructions see: [Using the ECL EKF > Dual Receivers](../advanced_config/tuning_the_ecl_ekf.md#dual-receivers). ### DroneCAN GNSS Configuration @@ -197,11 +199,21 @@ It is possible to have low DOP (good satellite geometry) but still have high EPH EPH/EPV values therefore provide a more immediate and practical estimate of the actual GPS accuracy you can expect under current conditions. +### GNSS Position Fusion + +GNSS position fusion will not begin until yaw alignment is established. +If a magnetometer is available, the EKF aligns yaw using the magnetic heading, allowing GPS position fusion to start soon after boot. +If no magnetometer is present, the system must rely on GPS yaw (from a dual-antenna setup) or movement-based yaw estimation. +Until one of these provides a valid heading, the EKF will not start GPS position fusion, and the vehicle will remain in a “no position” state even though attitude data is valid. +This behavior prevents large position errors that could occur when the yaw reference is uncertain. + ## 开发人员信息 - GPS/RTK-GPS - [RTK-GPS](../advanced/rtk_gps.md) + - [PPS Time Synchronization](../advanced/pps_time_sync.md) - [GPS driver](../modules/modules_driver.md#gps) + - [PPS driver](../modules/modules_driver.md#pps-capture) - [DroneCAN Example](../dronecan/index.md) - 罗盘 - [Driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/magnetometer) (Compasses) diff --git a/docs/zh/gps_compass/magnetometer.md b/docs/zh/gps_compass/magnetometer.md index 4fd06a5cc1..0435210bec 100644 --- a/docs/zh/gps_compass/magnetometer.md +++ b/docs/zh/gps_compass/magnetometer.md @@ -40,6 +40,7 @@ This list contains stand-alone magnetometer modules (without GNSS). | 设备 | 罗盘 | DroneCan | | :--------------------------------------------------------------------------------------------------------------- | :----: | :-------------------------: | +| [ARK MAG](https://arkelectron.com/product/ark-mag/) | RM3100 | ✓ | | [Avionics Anonymous UAVCAN Magnetometer](https://www.tindie.com/products/avionicsanonymous/uavcan-magnetometer/) | ? | | | [Holybro DroneCAN RM3100 Compass/Magnetometer](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | | [RaccoonLab DroneCAN/Cyphal Magnetometer RM3100](https://holybro.com/products/dronecan-rm3100-compass) | RM3100 | ✓ | diff --git a/docs/zh/gps_compass/rtk_gps.md b/docs/zh/gps_compass/rtk_gps.md index ced9490167..2b12d8208a 100644 --- a/docs/zh/gps_compass/rtk_gps.md +++ b/docs/zh/gps_compass/rtk_gps.md @@ -20,50 +20,59 @@ The RTK compatible devices below that are expected to work with PX4 (it omits di The table indicates devices that also output yaw, and that can provide yaw when two on-vehicle units are used. It also highlights devices that connect via the CAN bus, and those which support PPK (Post-Processing Kinematic). -| 设备 | GPS | 罗盘 | [DroneCAN](../dronecan/index.md) | [GPS Yaw](#configuring-gps-as-yaw-heading-source) | PPK | -| :------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------: | :-------------------------: | :------------------------------: | :-----------------------------------------------: | :-------------------------: | -| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna][SeptDualAnt] | | -| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | -| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | -| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | -| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | -| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P](https://docs.datagnss.com/gnss/gnss_module/D10P_RTK) | IST8310 | | ✘ | | -| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | -| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | -| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | -| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P][DualF9P] | | -| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P][DualF9P] | | -| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | -| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P][DualF9P] | | -| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | -| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna][UnicoreDualAnt] | | -| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | -| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | -| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | -| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | -| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | -| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna][SeptDualAnt] | ✓ | -| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P][DualF9P] | | -| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | +| 设备 | GPS | 罗盘 | [DroneCAN] | [GPS Yaw] | PPK | +| :------------------------------------------------------------------------------------------------------------------- | :------------------: | :-------------------------: | :-------------------------: | :---------------------------------: | :-------------------------: | +| [ARK G5 RTK GPS](../dronecan/ark_g5_rtk_gps.md) | [mosaic-G5 P3] | IIS2MDC | ✓ | | | +| [ARK G5 RTK HEADING GPS](../dronecan/ark_g5_rtk_heading_gps.md) | [mosaic-G5 P3H] | IIS2MDC | ✓ | [Heading Capability][mosaic-G5 P3H] | | +| [ARK RTK GPS](../dronecan/ark_rtk_gps.md) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [ARK RTK GPS L1 L5](../dronecan/ark_rtk_gps_l1_l2.md) | F9P | BMM150 | ✓ | | | +| [ARK MOSAIC-X5 RTK GPS](../dronecan/ark_mosaic__rtk_gps.md) | Mosaic-X5 | IIS2MDC | ✓ | [Septentrio Dual Antenna] | | +| [ARK X20 RTK GPS](../dronecan/ark_x20_rtk_gps.md) | X20P | IIS2MDC | ✓ | | | +| [CUAV C-RTK GPS](../gps_compass/rtk_gps_cuav_c-rtk.md) | M8P/M8N | ✓ | | | | +| [CUAV C-RTK2](../gps_compass/rtk_gps_cuav_c-rtk2.md) | F9P | ✓ | | [Dual F9P] | | +| [CUAV C-RTK 9Ps GPS](../gps_compass/rtk_gps_cuav_c-rtk-9ps.md) | F9P | RM3100 | | [Dual F9P] | | +| [CUAV C-RTK2 PPK/RTK GNSS](../gps_compass/rtk_gps_cuav_c-rtk.md) | F9P | RM3100 | | | ✓ | +| [CubePilot Here+ RTK GPS](../gps_compass/rtk_gps_hex_hereplus.md) | M8P | HMC5983 | | | | +| [CubePilot Here3 CAN GNSS GPS (M8N)](https://www.cubepilot.org/#/here/here3) | M8P | ICM20948 | ✓ | | | +| [Drotek SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | RM3100 | | [Dual F9P] | | +| [DATAGNSS NANO HRTK Receiver](../gps_compass/rtk_gps_datagnss_nano_hrtk.md) | [D10P] | IST8310 | | ✘ | | +| [DATAGNSS GEM1305 RTK Receiver](../gps_compass/rtk_gps_gem1305.md) | TAU951M | IST8310 | | ✘ | | +| [Femtones MINI2 Receiver](../gps_compass/rtk_gps_fem_mini2.md) | FB672, FB6A0 | ✓ | | | | +| [Freefly RTK GPS](../gps_compass/rtk_gps_freefly.md) | F9P | IST8310 | | | | +| [Holybro H-RTK ZED-F9P RTK Rover (DroneCAN variant)](../dronecan/holybro_h_rtk_zed_f9p_gps.md) | F9P | RM3100 | ✓ | [Dual F9P] | | +| [Holybro H-RTK ZED-F9P RTK Rover](https://holybro.com/collections/h-rtk-gps/products/h-rtk-zed-f9p-rover) | F9P | RM3100 | | [Dual F9P] | | +| [Holybro H-RTK F9P Ultralight](https://holybro.com/products/h-rtk-f9p-ultralight) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro H-RTK F9P Helical or Base](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | [Dual F9P] | | +| [Holybro DroneCAN H-RTK F9P Helical](https://holybro.com/products/dronecan-h-rtk-f9p-helical) | F9P | BMM150 | ✓ | [Dual F9P] | | +| [Holybro H-RTK F9P Rover Lite](../gps_compass/rtk_gps_holybro_h-rtk-f9p.md) | F9P | IST8310 | | | | +| [Holybro DroneCAN H-RTK F9P Rover](https://holybro.com/products/dronecan-h-rtk-f9p-rover) | F9P | BMM150 | | [Dual F9P] | | +| [Holybro H-RTK M8P GNSS](../gps_compass/rtk_gps_holybro_h-rtk-m8p.md) | M8P | IST8310 | | | | +| [Holybro H-RTK Unicore UM982 GPS](../gps_compass/rtk_gps_holybro_unicore_um982.md) | UM982 | IST8310 | | [Unicore Dual Antenna] | | +| [LOCOSYS Hawk R1](../gps_compass/rtk_gps_locosys_r1.md) | MC-1612-V2b | | | | | +| [LOCOSYS Hawk R2](../gps_compass/rtk_gps_locosys_r2.md) | MC-1612-V2b | IST8310 | | | | +| [mRo u-blox ZED-F9 RTK L1/L2 GPS](https://store.mrobotics.io/product-p/m10020d.htm) | F9P | ✓ | | [Dual F9P] | | +| [Navisys L1/L2 ZED-F9P RTK - Base only](https://www.navisys.com.tw/productdetail?name=GR901&class=RTK) | F9P | | | | | +| [RaccoonLab L1/L2 ZED-F9P][RaccoonLab L1/L2 ZED-F9P] | F9P | RM3100 | ✓ | | | +| [RaccoonLab L1/L2 ZED-F9P with external antenna][RaccnLabL1L2ZED-F9P ext_ant] | F9P | RM3100 | ✓ | | | +| [Septentrio AsteRx-m3 Pro](../gps_compass/septentrio_asterx-rib.md) | AsteRx | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [Septentrio mosaic-go](../gps_compass/septentrio_mosaic-go.md) | mosaic X5 / mosaic H | ✓ | | [Septentrio Dual Antenna] | ✓ | +| [SIRIUS RTK GNSS ROVER (F9P)](https://store-drotek.com/911-sirius-rtk-gnss-rover-f9p.html) | F9P | ✓ | | [Dual F9P] | | +| [SparkFun GPS-RTK2 Board - ZED-F9P](https://www.sparkfun.com/products/15136) | F9P | ✓ | | [Dual F9P] | | +| [Trimble MB-Two](../gps_compass/rtk_gps_trimble_mb_two.md) | F9P | ✓ | | ✓ | | [RaccnLabL1L2ZED-F9P ext_ant]: https://docs.raccoonlab.co/guide/gps_mag_baro/gnss_external_antenna_f9p_v320.html [RaccoonLab L1/L2 ZED-F9P]: https://docs.raccoonlab.co/guide/gps_mag_baro/gps_l1_l2_zed_f9p.html -[DualF9P]: ../gps_compass/u-blox_f9p_heading.md -[SeptDualAnt]: ../gps_compass/septentrio.md#gnss-based-heading -[UnicoreDualAnt]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw +[Dual F9P]: ../gps_compass/u-blox_f9p_heading.md +[Septentrio Dual Antenna]: ../gps_compass/septentrio.md#gnss-based-heading +[Unicore Dual Antenna]: ../gps_compass/rtk_gps_holybro_unicore_um982.md#enable-gps-heading-yaw [DATAGNSS GEM1305 RTK]: ../gps_compass/rtk_gps_gem1305.md +[DroneCAN]: ../dronecan/index.md +[GPS Yaw]: #configuring-gps-as-yaw-heading-source +[mosaic-G5 P3]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3 +[mosaic-G5 P3H]: https://www.septentrio.com/en/products/gnss-receivers/gnss-receiver-modules/mosaic-G5-P3H +[D10P]: https://docs.datagnss.com/gnss/gnss_module/D10P_RTK 备注: @@ -122,35 +131,36 @@ This should be set by default, but if not, follow the [MAVLink2 configuration in The RTK GPS connection is essentially plug and play: 1. Start _QGroundControl_ and attach the base RTK GPS via USB to the ground station. - 电脑会自动识别设备。 + 电脑会自动识别设备。 2. Start the vehicle and make sure it is connected to _QGroundControl_. - :::tip - _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). - The icon is red while RTK is being set up, and then changes to white once RTK GPS is active. - You can click the icon to see the current state and RTK accuracy. + :::tip + _QGroundControl_ displays an RTK GPS status icon in the top icon bar while an RTK GPS device is connected (in addition to the normal GPS status icon). + The icon is red while RTK is being set up, and then changes to white once RTK GPS is active. + You can click the icon to see the current state and RTK accuracy. ::: 3. _QGroundControl_ then starts the RTK setup process (known as "Survey-In"). - 测量是一个获得基站准确位置的设置过程。 - The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). + 测量是一个获得基站准确位置的设置过程。 + The process typically takes several minutes (it ends after reaching the minimum time and accuracy specified in the [RTK settings](#rtk-gps-settings)). - 你也可以点击 RTK状态按钮查看。 + 你也可以点击 RTK状态按钮查看。 - ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) + ![survey-in](../../assets/qgc/setup/rtk/qgc_rtk_survey-in.png) 4. 测量完成: - - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) + - The RTK GPS icon changes to white and _QGroundControl_ starts to stream position data to the vehicle: - - Vehicle GPS switches to RTK mode. - The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + ![RTK streaming](../../assets/qgc/setup/rtk/qgc_rtk_streaming.png) - ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) + - Vehicle GPS switches to RTK mode. + The new mode is displayed in the _normal_ GPS status icon (`3D RTK GPS Lock`): + + ![RTK GPS Status](../../assets/qgc/setup/rtk/qgc_rtk_gps_status.png) ### Configuring GPS as Yaw/Heading Source @@ -205,7 +215,7 @@ This should be enabled by default on recent builds. To ensure MAVLink2 is used: - Update the telemetry module firmware to the latest version (see [QGroundControl > Setup > Firmware](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/firmware.html)). -- Set [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) +- Ensure [MAV_PROTO_VER](../advanced_config/parameter_reference.md#MAV_PROTO_VER) is set to 2 (see [QGroundControl Setup > Parameters](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/parameters.html)) #### 调试 diff --git a/docs/zh/hardware/board_support_guide.md b/docs/zh/hardware/board_support_guide.md index e9f3309f16..f54739bde3 100644 --- a/docs/zh/hardware/board_support_guide.md +++ b/docs/zh/hardware/board_support_guide.md @@ -33,8 +33,8 @@ The general requirements for all supported boards are: 6. Adequate documentation, which includes, but is not limited to: - A complete pinout made available publicly that maps PX4 pin definitions to: - 1. Microcontroller pins - 2. Physical external connectors + 1. Microcontroller pins + 2. Physical external connectors - A block diagram or full schematic of the main components (sensors, power supply, etc.) that allows to infer software requirements and boot order - A manual of the finished product detailing its use diff --git a/docs/zh/hardware/drone_parts.md b/docs/zh/hardware/drone_parts.md index 405b79b08e..640852b21b 100644 --- a/docs/zh/hardware/drone_parts.md +++ b/docs/zh/hardware/drone_parts.md @@ -1,19 +1,19 @@ -# Hardware Hardware Selection & Setup +# 硬件选择和设置 -This section contains information the components that might be used in a drone, and how they are set up. +本节包含可以用在无人机中的组件以及它们是如何设置的。 -- [Flight Controllers (Autopilots)](../flight_controller/index.md) - Pixhawk and other FCs, firmware updates, other bootloaders -- [Sensors](../sensor/index.md) — accelerometer, gyroscope, compass, airspeed, barometer, rangefinders, GNSS, RTK GNSS, Optical Flow, Tachometers, Factory calibration, thermal calibration. -- [Actuators](../actuators/index.md) — Allocation, ESC, motors, servos -- [Radio Control (RC)](../getting_started/rc_transmitter_receiver.md) — Manual control using an RC system -- [Joysticks](../config/joystick.md) — Manual control using a Joystick connected to QGroundControl -- [Data Links](../data_links/index.md) — MAVLink, telemetry radios, satellite comms -- [Power Systems](../power_systems/index.md) — Battery estimation tuning, power modules, smart batteries -- [Peripherals](../peripherals/index.md) — camera, gimbal, grippers, parachute, RemoteID, traffic avoidance etc. -- [I2C Peripherals](../sensor_bus/i2c_general.md) -- [CAN Peripherals](../can/index.md) -- [DroneCAN Peripherals](../dronecan/index.md) -- [Cable Wiring](../assembly/cable_wiring.md) -- [Companion Computers](../companion_computer/index.md) — Setup, peripherals, computer vision, etc. -- [Serial Port Configuration](../peripherals/serial_configuration.md) -- [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) +- [飞行控制器(自动驾驶仪)](../flight_controller/index.md) - Pixhawk及其他飞行控制器、固件更新、其他引导程序 +- [Sensors](../sensor/index.md) - 加速计、健身范围、指南、气速、气速、气压计、测距器、全球导航卫星系统、RTK GNSS、光流、转速计、工厂校准、热校准。 +- [执行器](../actuators/index.md) — 分配、ESC、电机、伺服电机 +- [无线电控制 (RC)](../getting_started/rc_transmitter_receiver.md) - 使用 RC 系统手动控制 +- [Joysticks](../config/joystick.md) — 使用连接到 QGroundControl的手动控制 +- [数据链路](../data_links/index.md) — MAVLink、遥测无线电、卫星通信 +- [电源系统](../power_systems/index.md) - 电池估计调整、电源模块、智能电池 +- [外设](../peripherals/index.md) — 相机、云台、机械手、降落伞、远程标识、避障系统等。 +- [I2C 外设](../sensor_bus/i2c_general.md) +- [CAN 外设](../can/index.md) +- [DroneCAN 外设](../dronecan/index.md) +- [CAN 布线](../assembly/cable_wiring.md) +- [记载计算机](../companion_computer/index.md) — 设置、外设、计算机视觉等。 +- [串口配置](../peripherals/serial_configuration.md) +- [PX4 以太网设置](../advanced_config/ethernet_setup.md) diff --git a/docs/zh/hardware/index.md b/docs/zh/hardware/index.md index 98034cfac6..f6bf6e2fb7 100644 --- a/docs/zh/hardware/index.md +++ b/docs/zh/hardware/index.md @@ -1,17 +1,17 @@ -# Hardware Integration +# 硬件集成 -This section contains topics about integrating PX4 with _new_ autopilot and peripheral hardware, including: +本节包含关于将PX4与新型自动驾驶仪和外围硬件集成的主题,包括: -- [Flight Controller Reference Design](../hardware/reference_design.md) -- [Manufacturer’s Board Support Guide](../hardware/board_support_guide.md) -- [Flight Controller Porting Guide](../hardware/porting_guide.md) -- [Serial Port Mapping](../hardware/serial_port_mapping.md) -- [Airframes](../dev_airframes/index.md) -- [Device Drivers](../middleware/drivers.md) -- [Telemetry Radio/Modems](../data_links/telemetry.md) and other communications links -- [Sensor and Actuator I/O](../sensor_bus/index.md) -- [RTK GPS (Integration)](../advanced/rtk_gps.md) +- [飞控参考设计](../hardware/reference_design.md) +- [制造商主板支持指南](../hardware/board_support_guide.md) +- [飞控移植指南](../hardware/porting_guide.md) +- [串口映射](../hardware/serial_port_mapping.md) +- [机架](../dev_airframes/index.md) +- [设备驱动](../middleware/drivers.md) +- [远程无线电/调制解调器](../data_links/telemetry.md) 和其他通信链接 +- [传感器和执行器 I/O](../sensor_bus/index.md) +- [RTK GPS (集成)](../advanced/rtk_gps.md) :::tip -Other sections show how to _use_ and _configure_ supported [autopilot](../flight_controller/index.md), [companion computer](../companion_computer/index.md) and [peripheral](../peripherals/index.md) hardware. +其他章节显示如何使用 _use_ 和 _configure_ 支持的 [autopilot](../flight_controller/index.md), [配对计算机] (../companion_computer/index.md) 和 [peripheral](../peripherals/index.md) 硬件。 ::: diff --git a/docs/zh/hardware/porting_guide.md b/docs/zh/hardware/porting_guide.md index a3cf2ec5df..3a763ed73f 100644 --- a/docs/zh/hardware/porting_guide.md +++ b/docs/zh/hardware/porting_guide.md @@ -1,26 +1,26 @@ # 飞行控制器移植指南 -This topic is for developers who want to port PX4 to work with _new_ flight controller hardware. +本主题主要针对希望将 PX4 移植到 _新_ 飞控硬件平台上的开发人员。 ## PX4 架构 -PX4 consists of two main layers: The [board support and middleware layer](../middleware/index.md) on top of the host OS (NuttX, Linux or any other POSIX platform like Mac OS), and the applications (Flight Stack in [src/modules](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules)\). Please reference the [PX4 Architectural Overview](../concept/architecture.md) for more information. +PX4 由两个主要层组成: 基于主机操作系统(NuttX、Linux 或任何其他 POSIX 平台如 Mac OS)的[板级支持与中间件层](../middleware/index.md),以及应用程序(位于[src/modules](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules)目录下的飞行栈)。 更多信息请参阅[PX4架构概述](../concept/architecture.md)。 本指南仅关注主机操作系统和中间件,因为 应用层/飞行控制栈 可以在任何目标平台上运行。 ## 飞行控制器配置文件分布位置 -Board startup and configuration files are located under [/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards/) in each board's vendor-specific directory (i.e. **boards/_VENDOR_/_MODEL_/**). +板卡启动和配置文件位于每个板卡厂商专属目录下的 [/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards/) 路径中(即 **boards/_VENDOR_/_MODEL_/**)。 例如,对于 FMUv5 飞控硬件平台: -- (All) Board-specific files: [/boards/px4/fmu-v5](https://github.com/PX4/PX4-Autopilot/tree/main/boards/px4/fmu-v5). -- Build configuration: [/boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board). -- Board-specific initialisation file: [/boards/px4/fmu-v5/init/rc.board_defaults](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/init/rc.board_defaults) - - A board-specific initialisation file is automatically included in startup scripts if found under the boards directory at **init/rc.board**. +- (所有) 板卡专用文件:[/boards/px4/fmu-v5](https://github.com/PX4/PX4-Autopilot/tree/main/boards/px4/fmu-v5)。 +- 构建配置:[/boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board)。 +- 板卡专用初始化文件:[/boards/px4/fmu-v5/init/rc.board_defaults](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/init/rc.board_defaults) + - 如果在主板目录下找到位于**init/rc.board**的文件,则该主板专用的初始化文件会自动包含在启动脚本中。 - 该文件用于启动仅存在于特定主板上的传感器 (和其他东西)。 - It may also be used to set a board's default parameters, UART mappings, and any other special cases. - - For FMUv5 you can see all the Pixhawk 4 sensors being started, and it also sets a larger LOGGER_BUF. + 它也可用于设置电路板的默认参数、UART映射以及任何其他特殊情况。 + - 对于FMUv5,您可以看到所有Pixhawk 4传感器均已启动,同时它还设置了更大的LOGGER_BUF缓冲区。 ## 主机操作系统配置 @@ -28,14 +28,14 @@ Board startup and configuration files are located under [/boards](https://github ### NuttX -See [NuttX Board Porting Guide](porting_guide_nuttx.md). +参见[NuttX 板移植指南](porting_guide_nuttx.md)。 ### Linux 基于 Linux 的飞控板不包含任何 操作系统和内核的配置。 -Linux boards do not include the OS and kernel configuration. These are already provided by the Linux image available for the board (which needs to support the inertial sensors out of the box). +这些功能已由该开发板可用的Linux镜像提供(该镜像需开箱即支持惯性传感器)。 -- [boards/px4/raspberrypi/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/raspberrypi/default.px4board) - RPi cross-compilation. +- [boards/px4/raspberrypi/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/raspberrypi/default.px4board) - RPi 交叉编译。 ## 中间件组件和配置 @@ -43,56 +43,56 @@ Linux boards do not include the OS and kernel configuration. These are already p ### QuRT / Hexagon -- The start script is located in [posix-configs/](https://github.com/PX4/PX4-Autopilot/tree/main/posix-configs). +- 启动脚本位于 [posix-configs/](https://github.com/PX4/PX4-Autopilot/tree/main/posix-configs)。 - 操作系统配置是默认 Linux 镜像的一部分(TODO: 需要提供 LINUX 镜像文件位置和程序烧写指南)。 -- The PX4 middleware configuration is located in [src/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards). TODO: ADD BUS CONFIG +- PX4 中间件配置位于[src/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards)。 TODO: 添加BUS CONFIG ## RC UART 接线建议 -It is generally recommended to connect RC via separate RX and TX pins to the microcontroller. If however RX and TX are connected together, the UART has to be put into singlewire mode to prevent any contention. This is done via board config and manifest files. One example is px4fmu-v5. +通常建议通过独立的RX和TX引脚将RC连接至微控制器。但若RX和TX引脚连接在一起,则必须将UART置于单线模式以避免竞争冲突。此操作需通过板级配置文件和清单文件实现。示例可参考px4fmu-v5。 如果 RX 和 TX 连在了一起,那么 UART 需要设置为单线模式以防止出现争用。 这可以用过对飞控板的配置文件和 manifest 文件进行更改来实现。 -One example is [px4fmu-v5](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/src/manifest.c). +一个例子是 [px4fmu-v5](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/src/manifest.c)。 ## 官方支持的硬件 -The PX4 project supports and maintains the [FMU standard reference hardware](../hardware/reference_design.md) and any boards that are compatible with the standard. -This includes the [Pixhawk-series](../flight_controller/pixhawk_series.md) (see the user guide for a [full list of officially supported hardware](../flight_controller/index.md)). +PX4项目支持并维护[FMU标准参考硬件](../hardware/reference_design.md)以及任何符合该标准的开发板。 +这包括[Pixhawk系列](../flight_controller/pixhawk_series.md)(详见用户指南中的[官方支持硬件完整列表](../flight_controller/index.md))。 每个受官方支持的飞控板平台都将受益于: - PX4 项目仓库中可用的 PX4 移植 -- Automatic firmware builds that are accessible from _QGroundControl_ +- 可通过_QGroundControl_访问的自动固件构建 - 与生态系统其余部分的兼容性 - 可通过 CI 进行自动检查 — 安全仍是这个社区的重中之重 -- [Flight testing](../test_and_ci/test_flights.md) +- [飞行测试](../test_and_ci/test_flights.md) -We encourage board manufacturers to aim for full compatibility with the [FMU spec](https://pixhawk.org/). -We encourage board manufacturers to aim for full compatibility with the FMU spec. With full compatibility you benefit from the ongoing day-to-day development of PX4, but have none of the maintenance costs that come from supporting deviations from the specification. +我们鼓励电路板制造商致力于实现与[FMU规范](https://pixhawk.org/)的完全兼容。 +我们鼓励电路板制造商致力于实现与FMU规范的完全兼容。通过完全兼容,您既能受益于PX4持续的日常开发成果,又无需承担因支持偏离规范而产生的维护成本。 :::tip -Manufacturers should carefully consider the cost of maintenance before deviating from the specification (the cost to the manufacturer is proportional to the level of divergence). +制造商在偏离规格时应仔细考虑维护成本(制造商的成本与偏离程度成正比)。 ::: -We welcome any individual or company to submit their port for inclusion in our supported hardware, provided they are willing to follow our [Code of Conduct](https://github.com/PX4/PX4-Autopilot/blob/main/CODE_OF_CONDUCT.md) and work with the Dev Team to provide a safe and fulfilling PX4 experience to their customers. +我们欢迎任何个人或公司提交其移植版本,将其纳入我们支持的硬件范围。前提是他们愿意遵守我们的[行为准则](https://github.com/PX4/PX4-Autopilot/blob/main/CODE_OF_CONDUCT.md),并与开发团队协作,为用户提供安全且令人满意的PX4体验。 + +值得注意的是,PX4开发团队有责任发布安全的软件。因此,我们要求所有主板制造商投入必要资源,确保其移植版本保持最新且处于可运行状态。 如果你想让你的飞控板被 PX4 项目正式支持: -If you want to have your board officially supported in PX4: - - 你的硬件必须在市场上可用(例如它可以被任何开发人员不受限制地购买到) 。 -- Hardware must be made available to the PX4 Dev Team so that they can validate the port (contact [lorenz@px4.io](mailto:lorenz@px4.io) for guidance on where to ship hardware for testing). -- The board must pass full [test suite](../test_and_ci/index.md) and [flight testing](../test_and_ci/test_flights.md). +- 必须向PX4开发团队提供硬件设备,以便他们验证移植工作(有关硬件寄送地址的指导,请联系[lorenz@px4.io](mailto:lorenz@px4.io))。 +- 该板必须通过完整的[测试套件](../test_and_ci/index.md)和[飞行测试](../test_and_ci/test_flights.md)。 -**The PX4 project reserves the right to refuse acceptance of new ports (or remove current ports) for failure to meet the requirements set by the project.** +**PX4项目保留拒绝接受不符合项目要求的新端口(或移除现有端口)的权利。** -You can reach out to the core developer team and community on the [official support channels](../contribute/support.md). +您可通过[官方支持渠道](../contribute/support.md)联系核心开发团队及社区。 ## 相关信息 -- [Device Drivers](../middleware/drivers.md) - How to support new peripheral hardware (device drivers) -- [Building the Code](../dev_setup/building_px4.md) - How to build source and upload firmware +- [设备驱动程序](../middleware/drivers.md) - 如何支持新的外围硬件(设备驱动程序) +- [构建代码](../dev_setup/building_px4.md) - 如何构建源代码并上传固件 - 受支持的飞行控制器: - - [Autopilot Hardware](../flight_controller/index.md) - - [Supported boards list](https://github.com/PX4/PX4-Autopilot/#supported-hardware) (Github) - Boards for which PX4-Autopilot has specific code -- [Supported Peripherals](../peripherals/index.md) + - [自动驾驶仪硬件](../flight_controller/index.md) + - [支持的主板列表](https://github.com/PX4/PX4-Autopilot/#supported-hardware) (Github) - PX4-Autopilot 拥有专用代码的开发板 +- [支持的外设](../peripherals/index.md) diff --git a/docs/zh/hardware/porting_guide_nuttx.md b/docs/zh/hardware/porting_guide_nuttx.md index fb1c22d0ac..dbdf5c54b6 100644 --- a/docs/zh/hardware/porting_guide_nuttx.md +++ b/docs/zh/hardware/porting_guide_nuttx.md @@ -62,30 +62,30 @@ First you will need a bootloader, which depends on the hardware target: 2. Download the source code and make sure you can build an existing target: - ```sh - git clone --recursive https://github.com/PX4/PX4-Autopilot.git - cd PX4-Autopilot - make px4_fmu-v5 - ``` + ```sh + git clone --recursive https://github.com/PX4/PX4-Autopilot.git + cd PX4-Autopilot + make px4_fmu-v5 + ``` 3. Find an existing target that uses the same (or a closely related) CPU type and copy it. - For example for STM32F7: + For example for STM32F7: - ```sh - mkdir boards/manufacturer - cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 - ``` + ```sh + mkdir boards/manufacturer + cp -r boards/px4/fmu-v5 boards/manufacturer/my-target-v1 + ``` - Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. + Change **manufacturer** to the manufacturer name and **my-target-v1** to your board name. Next you need to go through all files under **boards/manufacturer/my-target-v1** and update them according to your board. 1. **firmware.prototype**: update the board ID and name 2. **default.px4board**: update the **VENDOR** and **MODEL** to match the directory names (**my-target-v1**). - Configure the serial ports. + Configure the serial ports. 3. Configure NuttX (**defconfig**) via `make manufacturer_my-target-v1 menuconfig`: Adjust the CPU and chip, configure the peripherals (UART's, SPI, I2C, ADC). 4. **nuttx-config/include/board.h**: Configure the NuttX pins. - For all peripherals with multiple pin options, NuttX needs to know the pin. - They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). + For all peripherals with multiple pin options, NuttX needs to know the pin. + They are defined in the chip-specific pinmap header file, for example [stm32f74xx75xx_pinmap.h](https://github.com/PX4/NuttX/blob/px4_firmware_nuttx-8.2/arch/arm/src/stm32f7/hardware/stm32f74xx75xx_pinmap.h). 5. **src**: go through all files under **src** and update them as needed, in particular **board_config.h**. 6. **init/rc.board_sensors**: start the sensors that are attached to the board. diff --git a/docs/zh/hardware/serial_port_mapping.md b/docs/zh/hardware/serial_port_mapping.md index 9799e398b4..e5ffa8552b 100644 --- a/docs/zh/hardware/serial_port_mapping.md +++ b/docs/zh/hardware/serial_port_mapping.md @@ -1,27 +1,27 @@ # 串口映射 -This topic shows how to determine the mapping between USART/UART serial port device names (e.g. "ttyS0") and the associated ports on a flight controller, such as `TELEM1`, `TELEM2`, `GPS1`, `RC SBUS`, `Debug console`. +本主题说明如何确定USART/UART串行端口(下称串口)设备名称(例如“ttyS0”)与飞行控制器上对应端口(如`TELEM1`、`TELEM2`、`GPS1`、`RC SBUS`、`调试控制台(Debug console)`)之间的映射关系。 -The instructions are used to generate serial port mapping tables in flight controller documentation. -For example: [Pixhawk 4 > Serial Port Mapping](../flight_controller/pixhawk4.md#serial-port-mapping). +这份说明用于在飞行控制器文档中生成串行端口映射表。 +例如: [Pixhawk 4 > Serial Port Mapping](../flight_controller/pixhawk4.md#serial-port-mapping)。 :::info -The function assigned to each port does not _have to_ match the name (in most cases), and is set using a [Serial Port Configuration](../peripherals/serial_configuration.md). -Usually the port function is configured to match the name, which is why the port labelled `GPS1` will work with a GPS out of the box. +每个端口分配的功能不必与名称匹配(大多数情况下),并通过[串行端口配置](../peripherals/serial_configuration.md)。 +通常情况下端口功能是与名称相匹配的,因此标记为`GPS1`的端口可直接连接GPS设备。 ::: -## NuttX on STMxxyyy +## NuttX 在 STMxxyyy 上 -This section shows how to get the mappings for NuttX builds on STMxxyyy architectures by inspecting the board configuration files. -The instructions use FMUv5, but can similarly be extended for other FMU versions/NuttX boards. +本节将展示如何通过检查板载配置文件,获取在 STMxxyyy 架构上构建 NuttX 所需的映射信息。 +该说明使用 FMUv5,但同样可扩展至其他FMU版本/NuttX开发板。 -### default.px4board +### -The **default.px4board** lists a number of serial port mappings (search for the text "SERIAL_PORTS"). +**default.px4board** 文件列出了若干串行端口映射(搜索文本“SERIAL_PORTS”)。 -From [/boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board): +来自 [/boards/px4/fmu-v5/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/default.px4board): ``` CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0" @@ -30,7 +30,7 @@ CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS2" CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3" ``` -Alternatively you can launch boardconfig using `make px4_fmu-v5 boardconfig` and access the serial port menu +或者,您可以通过执行 `make px4_fmu-v5 boardconfig` 启动板配置工具,并进入串口菜单。 ``` Serial ports ---> @@ -48,12 +48,12 @@ Alternatively you can launch boardconfig using `make px4_fmu-v5 boardconfig` and ### nsh/defconfig -The _nsh/defconfig_ allows you to determine which ports are defined, whether they are UART or USARTs, and the mapping between USART/UART and device. -You can also determine which port is used for the [serial/debug console](../debug/system_console.md). +_nsh/defconfig_ 允许您确定哪些端口被定义,它们是 UART 还是 USART,以及 USART/UART 与设备之间的映射关系。 +您还可以确定用于该功能的端口[串口/调试控制台](../debug/system_console.md)。 -Open the board's defconfig file, for example: [/boards/px4/fmu-v5/nuttx-config/nsh/defconfig](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/nuttx-config/nsh/defconfig#L215-L221) +打开板载的 defconfig 配置文件,例如:[/boards/px4/fmu-v5/nuttx-config/nsh/defconfig](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/nuttx-config/nsh/defconfig#L215-L221) -Search for the text "ART" until you find a section like with entries formatted like `CONFIG_STM32xx_USARTn=y` (where `xx` is a processor type and `n` is a port number). +搜索文本“ART”,直到找到类似以下格式的条目:`CONFIG_STM32xx_USARTn=y`(其中`xx`表示处理器类型,`n`表示端口号)。 例如: ``` @@ -66,10 +66,10 @@ CONFIG_STM32F7_USART3=y CONFIG_STM32F7_USART6=y ``` -The entries tell you which ports are defined, and whether they are UART or USART. +这些条目会告知您哪些端口已被定义,以及它们属于UART还是USART。 -Copy the section above and reorder numerically by "n". -Increment the device number _ttyS**n**_ alongside (zero based) to get the device-to-serial-port mapping. +复制上方段落,按“n”进行数字排序。 +同时递增设备编号 _ttyS**n**_(从零开始计数),以获取设备到串行端口的映射关系。 ``` ttyS0 CONFIG_STM32F7_USART1=y @@ -81,8 +81,8 @@ ttyS5 CONFIG_STM32F7_UART7=y ttyS6 CONFIG_STM32F7_UART8=y ``` -To get the DEBUG console mapping we search the [defconfig file](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/nuttx-config/nsh/defconfig#L212) for `SERIAL_CONSOLE`. -Below we see that the console is on UART7: +要获取调试控制台映射,我们需在[defconfig file](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/nuttx-config/nsh/defconfig#L212) 搜索 `SERIAL_CONSOLE`。 +下面我们看到控制台位于UART7: ``` CONFIG_UART7_SERIAL_CONSOLE=y @@ -90,9 +90,9 @@ CONFIG_UART7_SERIAL_CONSOLE=y ### board_config.h -For flight controllers that have an IO board, determine the PX4IO connection from **board_config.h** by searching for `PX4IO_SERIAL_DEVICE`. +对于配备IO板的飞行控制器,请通过在**board_config.h**文件中搜索`PX4IO_SERIAL_DEVICE`来确定PX4IO连接。 -For example, [/boards/px4/fmu-v5/src/board_config.h](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/src/board_config.h#L59): +例如 [/boards/px4/fmu-v5/src/board_config.h](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/src/board_config.h#L59): ``` #define PX4IO_SERIAL_DEVICE "/dev/ttyS6" @@ -101,11 +101,11 @@ For example, [/boards/px4/fmu-v5/src/board_config.h](https://github.com/PX4/PX4- #define PX4IO_SERIAL_BASE STM32_UART8_BASE ``` -So the PX4IO is on `ttyS6` (we can also see that this maps to UART8, which we already knew from the preceding section). +PX4IO 位于 `ttyS6` 上(我们还可以看到它映射到 UART8,这一点我们从前一节已经知道)。 -### Putting it all together +### 整合所有内容 -The final mapping is: +最终映射表如下: ``` ttyS0 CONFIG_STM32F7_USART1=y GPS1 @@ -117,17 +117,17 @@ ttyS5 CONFIG_STM32F7_UART7=y DEBUG ttyS6 CONFIG_STM32F7_UART8=y PX4IO ``` -In the [flight controller docs](../flight_controller/pixhawk4.md#serial-port-mapping) the resulting table is: +在 [flight controller docs](../flight_controller/pixhawk4.md#serial-port-mapping) 最终生成的表格如下: -| UART | 设备 | Port | -| ------ | ---------- | ---------------------------------------- | -| UART1 | /dev/ttyS0 | GPS | -| USART2 | /dev/ttyS1 | TELEM1 (flow control) | -| USART3 | /dev/ttyS2 | TELEM2 (flow control) | -| UART4 | /dev/ttyS3 | TELEM4 | -| USART6 | /dev/ttyS4 | RC SBUS | -| UART7 | /dev/ttyS5 | Debug Console | -| UART8 | /dev/ttyS6 | PX4IO | +| UART | 设备 | Port | +| ------ | ---------- | ------------------------------ | +| UART1 | /dev/ttyS0 | GPS | +| USART2 | /dev/ttyS1 | TELEM1 (流控) | +| USART3 | /dev/ttyS2 | TELEM2 (流控) | +| UART4 | /dev/ttyS3 | TELEM4 | +| USART6 | /dev/ttyS4 | RC SBUS | +| UART7 | /dev/ttyS5 | 调试控制台 | +| UART8 | /dev/ttyS6 | PX4IO | ## Other Architectures @@ -135,7 +135,7 @@ In the [flight controller docs](../flight_controller/pixhawk4.md#serial-port-map Contributions welcome! ::: -## See Also +## 另见 -- [Serial Port Configuration](../peripherals/serial_configuration.md) +- [串口配置](../peripherals/serial_configuration.md) - [MAVLink Telemetry (OSD/GCS)](../peripherals/mavlink_peripherals.md) diff --git a/docs/zh/index.md b/docs/zh/index.md index 08346a3c55..e7fea0a665 100644 --- a/docs/zh/index.md +++ b/docs/zh/index.md @@ -1,3 +1,8 @@ + +
# PX4 自动驾驶仪用户指南 @@ -8,17 +13,22 @@ _PX4_ 是一款专业级飞控。 它由来自业界和学术界的世界级开发商开发,并得到活跃的全球社区的支持,为从竞速和物流无人机到地面车辆和潜水艇的各种载具提供动力。 :::tip -这份指南包含组装、配置、安全使用 PX4 的设备的各种只是。 对贡献感兴趣吗 查看 [Development](development/development.md) 部分。 - +这份指南包含组装、配置、安全使用 PX4 的设备的各种只是。 +对贡献感兴趣吗 查看 [Development](development/development.md) 部分。 ::: +
+ :::warning + 本指南适用于_development_ version of PX4 (`main` 分支)。 使用 **版本** 选择器查找当前的 _稳定_ 版本。 自稳定版本发布以来的已记录变更,收录在不断更新的(releases/main.md ) 中。 ::: +
+ ## 如何开始? 所有用户都应该先阅读[基本概念](getting_started/px4_basic_concepts.md) ! @@ -28,7 +38,7 @@ _PX4_ 是一款专业级飞控。 ### 我想要一个能与PX4配合使用的载具 -在 [多旋翼](frames_multicopter/index.md), [VTOL](frames_vtol/index.md), 和 [平面(固定翼)](frames_plane/index.md)部分你会找到如下主题(这些链接针对多旋翼飞行器): +在 [多旋翼](frames_multicopter/index.md), [VTOL](frames_vtol/index.md), 和 [飞机(固定翼)](frames_plane/index.md)部分你会找到如下主题(这些链接针对多旋翼飞行器): - [完整的载具](complete_vehicles_mc/index.md)列出了到手飞(RTF)的硬件 - [套件(frames_multicopter/kits.md) 列出了需要你利用一组预先选定的部件自行组装的无人机。 @@ -46,7 +56,7 @@ _PX4_ 是一款专业级飞控。 ### 我想添加一个有效载荷/相机 -[有效载荷](payloads/index.md部分描述了如何添加相机,以及如何配置 PX4 以实现交付包裹。 +[有效载荷](payloads/index.md)部分描述了如何添加相机,以及如何配置 PX4 以实现交付包裹。 ### 我正在修改一个支持的载具 @@ -66,7 +76,7 @@ _PX4_ 是一款专业级飞控。 ## 获取帮助 -[支持](contribute/support.md页解释了如何从核心开发团队和更广泛的社区获得帮助。 +[支持](contribute/support.md)页解释了如何从核心开发团队和更广泛的社区获得帮助。 除此以外,它还包括了: @@ -101,7 +111,7 @@ _PX4_ 是一款专业级飞控。 ## 许可证 -PX4 code is free to use and modify under the terms of the permissive [BSD 3-clause license](https://opensource.org/license/BSD-3-Clause). +PX4 代码可依据宽松的 [BSD 3-clause license](https://opensource.org/license/BSD-3-Clause) 免费使用和修改。 此文档已使用 [CC BY 4.0]授权。(https://creativecommons.org/licenses/by/4.0/)。 详情见: [Licences](contribute/licenses.md)。 @@ -127,11 +137,11 @@ _Dronecode 日历_ 展示了面向平台用户和开发者的重要社区活动 _placeholder_icon 由 Smashicons 通过 www.flaticon.com 创作,使用 CC 3.0 By 授权。 - _camera-automatic-mode_ icon made by Freepik from www.flaticon.com is licensed by CC 3.0 BY. + _camera-automatic-mode_ 图标由 Freepikwww.flaticon.com 是由 CC 3.0 By 授权的。 ## 治理 -The PX4 flight stack is hosted under the governance of the [Dronecode Project](https://dronecode.org/). +PX4 飞行控制架构由[Dronecode Project](https://dronecode.org/)负责管理。 Dronecode Logo Linux Foundation Logo diff --git a/docs/zh/mavlink/standard_modes.md b/docs/zh/mavlink/standard_modes.md index 404e8e97c8..f04314dafd 100644 --- a/docs/zh/mavlink/standard_modes.md +++ b/docs/zh/mavlink/standard_modes.md @@ -2,7 +2,7 @@ -PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.md) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). +PX4 implements the MAVLink [Standard Modes Protocol](https://mavlink.io/en/services/standard_modes.html) from PX4 v1.15, with a corresponding implementation in QGroundControl Daily builds (and future release builds). The protocol allows you to discover all flight modes available to the vehicle, including PX4 External modes created using the [PX4 ROS 2 Control Interface](../ros2/px4_ros2_control_interface.md), and get or set the current mode. diff --git a/docs/zh/middleware/dds_topics.md b/docs/zh/middleware/dds_topics.md index 73c45b3bf7..062ba2ff01 100644 --- a/docs/zh/middleware/dds_topics.md +++ b/docs/zh/middleware/dds_topics.md @@ -10,32 +10,35 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git ## Publications -| Topic | 类型 | Rate Limit | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | -| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | -| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | -| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | -| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | -| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | -| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | -| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | -| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | -| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | -| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | -| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | -| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | -| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | | -| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | -| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | -| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | -| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | -| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | -| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | | -| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | -| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | -| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | -| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| Topic | 类型 | Rate Limit | +| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| `/fmu/out/register_ext_component_reply` | [px4_msgs::msg::RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md) | | +| `/fmu/out/arming_check_request` | [px4_msgs::msg::ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) | 5.0 | +| `/fmu/out/mode_completed` | [px4_msgs::msg::ModeCompleted](../msg_docs/ModeCompleted.md) | 50.0 | +| `/fmu/out/battery_status` | [px4_msgs::msg::BatteryStatus](../msg_docs/BatteryStatus.md) | 1.0 | +| `/fmu/out/collision_constraints` | [px4_msgs::msg::CollisionConstraints](../msg_docs/CollisionConstraints.md) | 50.0 | +| `/fmu/out/estimator_status_flags` | [px4_msgs::msg::EstimatorStatusFlags](../msg_docs/EstimatorStatusFlags.md) | 5.0 | +| `/fmu/out/failsafe_flags` | [px4_msgs::msg::FailsafeFlags](../msg_docs/FailsafeFlags.md) | 5.0 | +| `/fmu/out/manual_control_setpoint` | [px4_msgs::msg::ManualControlSetpoint](../msg_docs/ManualControlSetpoint.md) | 25.0 | +| `/fmu/out/message_format_response` | [px4_msgs::msg::MessageFormatResponse](../msg_docs/MessageFormatResponse.md) | | +| `/fmu/out/position_setpoint_triplet` | [px4_msgs::msg::PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) | 5.0 | +| `/fmu/out/sensor_combined` | [px4_msgs::msg::SensorCombined](../msg_docs/SensorCombined.md) | | +| `/fmu/out/timesync_status` | [px4_msgs::msg::TimesyncStatus](../msg_docs/TimesyncStatus.md) | 10.0 | +| `/fmu/out/transponder_report` | [px4_msgs::msg::TransponderReport](../msg_docs/TransponderReport.md) | | +| `/fmu/out/vehicle_land_detected` | [px4_msgs::msg::VehicleLandDetected](../msg_docs/VehicleLandDetected.md) | 5.0 | +| `/fmu/out/vehicle_attitude` | [px4_msgs::msg::VehicleAttitude](../msg_docs/VehicleAttitude.md) | 50.0 | +| `/fmu/out/vehicle_control_mode` | [px4_msgs::msg::VehicleControlMode](../msg_docs/VehicleControlMode.md) | 50.0 | +| `/fmu/out/vehicle_command_ack` | [px4_msgs::msg::VehicleCommandAck](../msg_docs/VehicleCommandAck.md) | | +| `/fmu/out/vehicle_global_position` | [px4_msgs::msg::VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) | 50.0 | +| `/fmu/out/vehicle_gps_position` | [px4_msgs::msg::SensorGps](../msg_docs/SensorGps.md) | 50.0 | +| `/fmu/out/vehicle_local_position` | [px4_msgs::msg::VehicleLocalPosition](../msg_docs/VehicleLocalPosition.md) | 50.0 | +| `/fmu/out/vehicle_odometry` | [px4_msgs::msg::VehicleOdometry](../msg_docs/VehicleOdometry.md) | 100.0 | +| `/fmu/out/vehicle_status` | [px4_msgs::msg::VehicleStatus](../msg_docs/VehicleStatus.md) | 5.0 | +| `/fmu/out/airspeed_validated` | [px4_msgs::msg::AirspeedValidated](../msg_docs/AirspeedValidated.md) | 50.0 | +| `/fmu/out/vtol_vehicle_status` | [px4_msgs::msg::VtolVehicleStatus](../msg_docs/VtolVehicleStatus.md) | | +| `/fmu/out/home_position` | [px4_msgs::msg::HomePosition](../msg_docs/HomePosition.md) | 5.0 | +| `/fmu/out/wind` | [px4_msgs::msg::Wind](../msg_docs/Wind.md) | 1.0 | +| `/fmu/out/gimbal_device_attitude_status` | [px4_msgs::msg::GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) | 20.0 | ## Subscriptions @@ -72,6 +75,13 @@ This document shows a markdown-rendered version of [dds_topics.yaml](https://git | /fmu/in/fixed_wing_lateral_setpoint | [px4_msgs::msg::FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) | | /fmu/in/longitudinal_control_configuration | [px4_msgs::msg::LongitudinalControlConfiguration](../msg_docs/LongitudinalControlConfiguration.md) | | /fmu/in/lateral_control_configuration | [px4_msgs::msg::LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) | +| /fmu/in/rover_position_setpoint | [px4_msgs::msg::RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) | +| /fmu/in/rover_speed_setpoint | [px4_msgs::msg::RoverSpeedSetpoint](../msg_docs/RoverSpeedSetpoint.md) | +| /fmu/in/rover_attitude_setpoint | [px4_msgs::msg::RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) | +| /fmu/in/rover_rate_setpoint | [px4_msgs::msg::RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) | +| /fmu/in/rover_throttle_setpoint | [px4_msgs::msg::RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) | +| /fmu/in/rover_steering_setpoint | [px4_msgs::msg::RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) | +| /fmu/in/landing_gear | [px4_msgs::msg::LandingGear](../msg_docs/LandingGear.md) | ## Subscriptions Multi @@ -85,193 +95,192 @@ They are not build into the module, and hence are neither published or subscribe :::details See messages -- [SensorCorrection](../msg_docs/SensorCorrection.md) -- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) -- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) -- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) -- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) -- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) -- [Px4ioStatus](../msg_docs/Px4ioStatus.md) -- [SatelliteInfo](../msg_docs/SatelliteInfo.md) -- [GeofenceResult](../msg_docs/GeofenceResult.md) -- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) -- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) -- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) -- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) -- [EventV0](../msg_docs/EventV0.md) -- [QshellRetval](../msg_docs/QshellRetval.md) -- [RoverThrottleSetpoint](../msg_docs/RoverThrottleSetpoint.md) -- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) -- [RcChannels](../msg_docs/RcChannels.md) -- [SensorAccel](../msg_docs/SensorAccel.md) -- [GimbalDeviceAttitudeStatus](../msg_docs/GimbalDeviceAttitudeStatus.md) -- [EscStatus](../msg_docs/EscStatus.md) -- [RoverAttitudeSetpoint](../msg_docs/RoverAttitudeSetpoint.md) -- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) -- [AirspeedWind](../msg_docs/AirspeedWind.md) -- [InputRc](../msg_docs/InputRc.md) -- [GpioIn](../msg_docs/GpioIn.md) -- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) -- [VehicleImu](../msg_docs/VehicleImu.md) -- [Event](../msg_docs/Event.md) -- [SensorUwb](../msg_docs/SensorUwb.md) -- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) -- [DatamanResponse](../msg_docs/DatamanResponse.md) -- [OrbTest](../msg_docs/OrbTest.md) -- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) -- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) -- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) -- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) -- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [BatteryInfo](../msg_docs/BatteryInfo.md) - [TakeoffStatus](../msg_docs/TakeoffStatus.md) -- [UlogStreamAck](../msg_docs/UlogStreamAck.md) -- [OrbTestLarge](../msg_docs/OrbTestLarge.md) -- [RoverSteeringSetpoint](../msg_docs/RoverSteeringSetpoint.md) +- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md) +- [Airspeed](../msg_docs/Airspeed.md) +- [PpsCapture](../msg_docs/PpsCapture.md) +- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) - [CameraCapture](../msg_docs/CameraCapture.md) -- [VehicleRoi](../msg_docs/VehicleRoi.md) -- [ActuatorArmed](../msg_docs/ActuatorArmed.md) -- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) -- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) -- [GeofenceStatus](../msg_docs/GeofenceStatus.md) -- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) -- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) -- [PowerMonitor](../msg_docs/PowerMonitor.md) -- [RoverVelocityStatus](../msg_docs/RoverVelocityStatus.md) -- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) -- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) -- [TecsStatus](../msg_docs/TecsStatus.md) -- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) -- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) -- [Ping](../msg_docs/Ping.md) -- [LedControl](../msg_docs/LedControl.md) -- [Wind](../msg_docs/Wind.md) -- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) -- [ActuatorTest](../msg_docs/ActuatorTest.md) -- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) -- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) -- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) -- [Gripper](../msg_docs/Gripper.md) -- [SensorMag](../msg_docs/SensorMag.md) -- [DebugValue](../msg_docs/DebugValue.md) -- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) -- [RcParameterMap](../msg_docs/RcParameterMap.md) -- [LandingGear](../msg_docs/LandingGear.md) -- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) +- [Px4ioStatus](../msg_docs/Px4ioStatus.md) +- [FuelTankStatus](../msg_docs/FuelTankStatus.md) +- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md) - [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md) -- [UlogStream](../msg_docs/UlogStream.md) -- [GimbalControls](../msg_docs/GimbalControls.md) -- [RoverRateSetpoint](../msg_docs/RoverRateSetpoint.md) -- [LogMessage](../msg_docs/LogMessage.md) -- [RoverVelocitySetpoint](../msg_docs/RoverVelocitySetpoint.md) +- [AirspeedWind](../msg_docs/AirspeedWind.md) +- [OrbTest](../msg_docs/OrbTest.md) +- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md) - [GpioOut](../msg_docs/GpioOut.md) -- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md) +- [Gripper](../msg_docs/Gripper.md) +- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [TuneControl](../msg_docs/TuneControl.md) +- [DebugVect](../msg_docs/DebugVect.md) +- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) +- [HomePositionV0](../msg_docs/HomePositionV0.md) +- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) +- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) +- [EstimatorBias](../msg_docs/EstimatorBias.md) +- [GpioConfig](../msg_docs/GpioConfig.md) +- [SystemPower](../msg_docs/SystemPower.md) +- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md) +- [MissionResult](../msg_docs/MissionResult.md) +- [PowerButtonState](../msg_docs/PowerButtonState.md) +- [EscStatus](../msg_docs/EscStatus.md) +- [HealthReport](../msg_docs/HealthReport.md) +- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) +- [SensorGyro](../msg_docs/SensorGyro.md) +- [GpioRequest](../msg_docs/GpioRequest.md) +- [DebugKeyValue](../msg_docs/DebugKeyValue.md) +- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) +- [ParameterUpdate](../msg_docs/ParameterUpdate.md) +- [SensorAirflow](../msg_docs/SensorAirflow.md) +- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) +- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) +- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md) +- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) +- [ActionRequest](../msg_docs/ActionRequest.md) +- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) +- [PwmInput](../msg_docs/PwmInput.md) +- [PowerMonitor](../msg_docs/PowerMonitor.md) +- [Mission](../msg_docs/Mission.md) +- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) +- [FigureEightStatus](../msg_docs/FigureEightStatus.md) +- [RadioStatus](../msg_docs/RadioStatus.md) +- [VehicleRoi](../msg_docs/VehicleRoi.md) +- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) +- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md) +- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md) +- [Rpm](../msg_docs/Rpm.md) +- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md) +- [Ping](../msg_docs/Ping.md) +- [QshellReq](../msg_docs/QshellReq.md) +- [SensorMag](../msg_docs/SensorMag.md) +- [EstimatorStates](../msg_docs/EstimatorStates.md) +- [SensorUwb](../msg_docs/SensorUwb.md) +- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) +- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) +- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) +- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md) +- [SensorHygrometer](../msg_docs/SensorHygrometer.md) +- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md) +- [AdcReport](../msg_docs/AdcReport.md) +- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md) +- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) +- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) +- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md) +- [SensorCorrection](../msg_docs/SensorCorrection.md) +- [UlogStream](../msg_docs/UlogStream.md) +- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) +- [GpsInjectData](../msg_docs/GpsInjectData.md) +- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) +- [LoggerStatus](../msg_docs/LoggerStatus.md) +- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) +- [SensorBaro](../msg_docs/SensorBaro.md) +- [OrbTestMedium](../msg_docs/OrbTestMedium.md) +- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md) +- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md) +- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) +- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) +- [UlogStreamAck](../msg_docs/UlogStreamAck.md) +- [DatamanRequest](../msg_docs/DatamanRequest.md) +- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) +- [PositionSetpoint](../msg_docs/PositionSetpoint.md) +- [DatamanResponse](../msg_docs/DatamanResponse.md) +- [LedControl](../msg_docs/LedControl.md) +- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) +- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md) +- [Event](../msg_docs/Event.md) +- [ActuatorArmed](../msg_docs/ActuatorArmed.md) +- [GpioIn](../msg_docs/GpioIn.md) +- [SensorGyroFft](../msg_docs/SensorGyroFft.md) +- [SensorAccel](../msg_docs/SensorAccel.md) +- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) +- [GeneratorStatus](../msg_docs/GeneratorStatus.md) +- [DifferentialPressure](../msg_docs/DifferentialPressure.md) +- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md) +- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md) +- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) +- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md) +- [RoverRateStatus](../msg_docs/RoverRateStatus.md) +- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md) +- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md) - [VelocityLimits](../msg_docs/VelocityLimits.md) - [MagWorkerData](../msg_docs/MagWorkerData.md) -- [ParameterUpdate](../msg_docs/ParameterUpdate.md) -- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md) -- [SensorBaro](../msg_docs/SensorBaro.md) -- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) -- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) -- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) -- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) -- [Rpm](../msg_docs/Rpm.md) -- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md) -- [MountOrientation](../msg_docs/MountOrientation.md) -- [ActionRequest](../msg_docs/ActionRequest.md) -- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md) -- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md) -- [LoggerStatus](../msg_docs/LoggerStatus.md) -- [GeneratorStatus](../msg_docs/GeneratorStatus.md) -- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md) -- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) -- [LandingTargetPose](../msg_docs/LandingTargetPose.md) -- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md) -- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md) -- [OrbitStatus](../msg_docs/OrbitStatus.md) -- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md) -- [EstimatorStatus](../msg_docs/EstimatorStatus.md) -- [DatamanRequest](../msg_docs/DatamanRequest.md) -- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md) -- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) -- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) - [Cpuload](../msg_docs/Cpuload.md) -- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md) -- [RoverRateStatus](../msg_docs/RoverRateStatus.md) -- [EscReport](../msg_docs/EscReport.md) -- [DebugArray](../msg_docs/DebugArray.md) -- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md) -- [SensorHygrometer](../msg_docs/SensorHygrometer.md) -- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md) -- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) -- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) -- [QshellReq](../msg_docs/QshellReq.md) -- [CameraStatus](../msg_docs/CameraStatus.md) -- [GpsInjectData](../msg_docs/GpsInjectData.md) -- [FigureEightStatus](../msg_docs/FigureEightStatus.md) -- [TransponderReport](../msg_docs/TransponderReport.md) -- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md) +- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md) - [MavlinkLog](../msg_docs/MavlinkLog.md) -- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) -- [FuelTankStatus](../msg_docs/FuelTankStatus.md) -- [Mission](../msg_docs/Mission.md) -- [PositionSetpoint](../msg_docs/PositionSetpoint.md) -- [MissionResult](../msg_docs/MissionResult.md) -- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) -- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md) -- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md) -- [DifferentialPressure](../msg_docs/DifferentialPressure.md) -- [CellularStatus](../msg_docs/CellularStatus.md) -- [GpsDump](../msg_docs/GpsDump.md) -- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md) -- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md) -- [NavigatorStatus](../msg_docs/NavigatorStatus.md) -- [RoverPositionSetpoint](../msg_docs/RoverPositionSetpoint.md) -- [FollowTarget](../msg_docs/FollowTarget.md) -- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md) -- [EstimatorStates](../msg_docs/EstimatorStates.md) -- [SensorGyro](../msg_docs/SensorGyro.md) -- [SensorAirflow](../msg_docs/SensorAirflow.md) -- [ButtonEvent](../msg_docs/ButtonEvent.md) -- [DebugKeyValue](../msg_docs/DebugKeyValue.md) -- [GpioConfig](../msg_docs/GpioConfig.md) -- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [SensorTemp](../msg_docs/SensorTemp.md) - [LandingGearWheel](../msg_docs/LandingGearWheel.md) -- [VehicleConstraints](../msg_docs/VehicleConstraints.md) -- [HealthReport](../msg_docs/HealthReport.md) -- [PowerButtonState](../msg_docs/PowerButtonState.md) -- [RadioStatus](../msg_docs/RadioStatus.md) -- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) -- [EstimatorBias](../msg_docs/EstimatorBias.md) -- [DebugVect](../msg_docs/DebugVect.md) -- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md) -- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md) -- [PpsCapture](../msg_docs/PpsCapture.md) -- [SensorSelection](../msg_docs/SensorSelection.md) -- [SystemPower](../msg_docs/SystemPower.md) -- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md) -- [SensorGyroFft](../msg_docs/SensorGyroFft.md) -- [VehicleAirData](../msg_docs/VehicleAirData.md) +- [OrbTestLarge](../msg_docs/OrbTestLarge.md) - [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md) -- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md) -- [GpioRequest](../msg_docs/GpioRequest.md) -- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) -- [RtlStatus](../msg_docs/RtlStatus.md) -- [Airspeed](../msg_docs/Airspeed.md) -- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) -- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md) -- [IrlockReport](../msg_docs/IrlockReport.md) -- [HeaterStatus](../msg_docs/HeaterStatus.md) -- [AdcReport](../msg_docs/AdcReport.md) -- [PwmInput](../msg_docs/PwmInput.md) -- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md) -- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) -- [OrbTestMedium](../msg_docs/OrbTestMedium.md) -- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md) -- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md) -- [TuneControl](../msg_docs/TuneControl.md) -- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [CellularStatus](../msg_docs/CellularStatus.md) +- [QshellRetval](../msg_docs/QshellRetval.md) +- [OrbitStatus](../msg_docs/OrbitStatus.md) +- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md) +- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md) +- [LogMessage](../msg_docs/LogMessage.md) +- [SatelliteInfo](../msg_docs/SatelliteInfo.md) +- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md) +- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md) +- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md) +- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md) +- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md) +- [EstimatorStatus](../msg_docs/EstimatorStatus.md) +- [NeuralControl](../msg_docs/NeuralControl.md) +- [TaskStackInfo](../msg_docs/TaskStackInfo.md) +- [RcParameterMap](../msg_docs/RcParameterMap.md) +- [SensorSelection](../msg_docs/SensorSelection.md) +- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md) +- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md) +- [ActuatorTest](../msg_docs/ActuatorTest.md) +- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md) +- [MountOrientation](../msg_docs/MountOrientation.md) +- [CameraStatus](../msg_docs/CameraStatus.md) - [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md) -- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md) -- [SensorsStatus](../msg_docs/SensorsStatus.md) +- [FollowTarget](../msg_docs/FollowTarget.md) +- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md) +- [ButtonEvent](../msg_docs/ButtonEvent.md) +- [DebugArray](../msg_docs/DebugArray.md) +- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md) +- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md) +- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md) +- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md) +- [VehicleImu](../msg_docs/VehicleImu.md) +- [GpsDump](../msg_docs/GpsDump.md) +- [WheelEncoders](../msg_docs/WheelEncoders.md) +- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md) +- [DebugValue](../msg_docs/DebugValue.md) +- [LandingTargetPose](../msg_docs/LandingTargetPose.md) +- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md) +- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md) +- [RtlStatus](../msg_docs/RtlStatus.md) +- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md) +- [GimbalControls](../msg_docs/GimbalControls.md) +- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md) +- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md) +- [HeaterStatus](../msg_docs/HeaterStatus.md) +- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md) +- [RcChannels](../msg_docs/RcChannels.md) +- [TecsStatus](../msg_docs/TecsStatus.md) +- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md) +- [InputRc](../msg_docs/InputRc.md) +- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md) +- [GeofenceResult](../msg_docs/GeofenceResult.md) +- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md) +- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md) +- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md) +- [NavigatorStatus](../msg_docs/NavigatorStatus.md) +- [CameraTrigger](../msg_docs/CameraTrigger.md) +- [EscReport](../msg_docs/EscReport.md) +- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md) +- [GeofenceStatus](../msg_docs/GeofenceStatus.md) +- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md) +- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) +- [EventV0](../msg_docs/EventV0.md) +- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md) +- [VehicleConstraints](../msg_docs/VehicleConstraints.md) +- [IrlockReport](../msg_docs/IrlockReport.md) ::: diff --git a/docs/zh/middleware/uorb.md b/docs/zh/middleware/uorb.md index 54af3bd7e9..8307da5923 100644 --- a/docs/zh/middleware/uorb.md +++ b/docs/zh/middleware/uorb.md @@ -278,7 +278,9 @@ For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggl -## See Also +## 另见 + +- [uORB Documentation Standard](../uorb/uorb_documentation.md) - _PX4 uORB Explained_ Blog series - [Part 1](https://px4.io/px4-uorb-explained-part-1/) diff --git a/docs/zh/middleware/uxrce_dds.md b/docs/zh/middleware/uxrce_dds.md index 365473334f..d5edfd4561 100644 --- a/docs/zh/middleware/uxrce_dds.md +++ b/docs/zh/middleware/uxrce_dds.md @@ -65,7 +65,7 @@ PX4 Micro XRCE-DDS Client is based on version `v2.x` which is not compatible wit On Ubuntu you can build from source and install the Agent standalone using the following commands: ```sh -git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git +git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build @@ -106,90 +106,146 @@ The development version, fetched using `--edge` above, does work. ### Build/Run within ROS 2 Workspace -The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace. +The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace). You must already have installed ROS 2 following the instructions in: [ROS 2 User Guide > Install ROS 2](../ros2/user_guide.md#install-ros-2). :::warning This approach will use the existing ROS 2 versions of the Agent dependencies, such as `fastcdr` and `fastdds`. -This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones. +This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones: + +| ROS 2 version | Micro-XRCE-DDS-Agent version | +| ------------- | -------------------------------------- | +| Foxy | v2.4.2 | +| Humble | v2.4.2 | +| Jazzy | v2.4.3 | + ::: To build the agent within ROS: 1. Create a workspace directory for the agent: - ```sh - mkdir -p ~/px4_ros_uxrce_dds_ws/src - ``` + ```sh + mkdir -p ~/px4_ros_uxrce_dds_ws/src + ``` 2. Clone the source code for the eProsima [Micro-XRCE-DDS-Agent](https://github.com/eProsima/Micro-XRCE-DDS-Agent) to the `/src` directory (the `main` branch is cloned by default): - ```sh - cd ~/px4_ros_uxrce_dds_ws/src - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - ``` + ::::tabs + + ::: tab jazzy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab humble + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + ::: tab foxy + + ```sh + cd ~/px4_ros_uxrce_dds_ws/src + git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + ``` + + +::: + + :::: 3. Source the ROS 2 development environment, and compile the workspace using `colcon`: - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + source /opt/ros/jazzy/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - :::: + ::: tab foxy - This builds all the folders under `/src` using the sourced toolchain. + ```sh + source /opt/ros/foxy/setup.bash + colcon build + ``` + + +::: + + :::: + + 该操作会使用已加载的工具链对 /src 目录下的所有文件夹进行构建。 To run the micro XRCE-DDS agent in the workspace: 1. Source the `local_setup.bash` to make the executables available in the terminal (also `setup.bash` if using a new terminal). - :::: tabs + :::: tabs - ::: tab humble + ::: tab jazzy - ```sh - source /opt/ros/humble/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/jazzy/setup.bash + source install/local_setup.bash + ``` ::: - ::: tab foxy + ::: tab humble - ```sh - source /opt/ros/foxy/setup.bash - source install/local_setup.bash - ``` + ```sh + source /opt/ros/humble/setup.bash + source install/local_setup.bash + ``` ::: - :::: + ::: tab foxy + + ```sh + source /opt/ros/foxy/setup.bash + source install/local_setup.bash + ``` + + +::: + + :::: 1) 启动代理并设置以连接运行在模拟器上的 uXRCE-DDS客户端(Client): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` ## Starting Agent and Client @@ -235,7 +291,6 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_CFG](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG): Set the port to connect on, such as `TELEM2`, `Ethernet`, or `Wifi`. - If using an Ethernet connection: - - [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT): Use this to specify the agent UDP listening port. The default value is `8888`. @@ -259,14 +314,12 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi ``` - If using a serial connection: - - [SER_TEL2_BAUD](../advanced_config/parameter_reference.md#SER_TEL2_BAUD), [SER_URT6_BAUD](../advanced_config/parameter_reference.md#SER_URT6_BAUD) (and so on): Use the `_BAUD` parameter associated with the serial port to set the baud rate. For example, you'd set a value for `SER_TEL2_BAUD` if you are connecting to the companion using `TELEM2`. For more information see [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration). - Some setups might also need these parameters to be set: - - [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): The uXRCE-DDS key. If you're working in a multi-client, single agent configuration, each client should have a unique non-zero key. This is primarily important for multi-vehicle simulations, where all clients are connected in UDP to the same agent. @@ -279,6 +332,11 @@ The configuration can be done using the [UXRCE-DDS parameters](../advanced_confi - [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable. The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge. This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled. + - [UXRCE_DDS_NS_IDX](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) : Index-based namespace definition. + Setting this parameter to any value other than `-1` creates a namespace with the prefix `uav_` and the specified value, e.g. `uav_0`, `uav_1`, etc. + See [namespace](#customizing-the-namespace) for methods to define richer or arbitrary namespaces. + - [`UXRCE_DDS_FLCTRL`](../advanced_config/parameter_reference.md#UXRCE_DDS_FLCTRL) : Serial port hardware flow control enable. + To use hardware flow control, a custom MicroXRCE Agent needs to be adopted. Please refer to [this PR](https://github.com/eProsima/Micro-XRCE-DDS-Agent/pull/407) for the required changes, cherry-pick them on top of the [agent version](#build-run-within-ros-2-workspace) you need to use and then run the agent with the additional `--flow-control` option. :::info Many ports are already have a default configuration. @@ -333,12 +391,12 @@ While most releases should support a very similar set of messages, to be certain Note that ROS 2/DDS needs to have the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware in order to interpret the messages. The message definitions are stored in the ROS 2 interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs), and they are automatically synchronized by CI on the `main` and release branches. -Note that all the messages from PX4 source code are present in the repository, but only those listed in `dds_topics.yaml` will be available as ROS 2 topics. -Therefore, +需要注意的是,PX4 源代码中的所有消息均存在于该代码仓库中,但只有在dds_topics.yaml文件中列出的消息,才会作为 ROS 2 话题可用。 +因此 -- If you're using a main or release version of PX4 you can get the message definitions by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your workspace. -- If you're creating or modifying uORB messages you must manually update the messages in your workspace from your PX4 source tree. - Generally this means that you would update [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml), clone the interface package, and then manually synchronize it by copying the new/modified message definitions from [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg) to its `msg` folders. +- 如果您正在使用 PX4 的主要版本或发布版本,您可以通过克隆接口包[PX4/px4_msgs](https://github.com/PX4/px4_msgs)获得消息定义。 +- 如果您要创建或修改 uORB 消息,必须从 PX4 源代码树中手动更新工作空间中的消息。 + 一般来说,这意味着您将更新 [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml),克隆接口包。 然后手动同步,将新的/修改的消息定义从 [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg)复制到它的 `msg` 文件夹。 Assuming that PX4-Autopilot is in your home directory `~`, while `px4_msgs` is in `~/px4_ros_com/src/`, then the command might be: ```sh @@ -354,15 +412,15 @@ Therefore, ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)) or at runtime (which is useful for multi vehicle operations): +Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](../middleware/dds_topics.md)), at runtime, or through a parameter (which is useful for multi vehicle operations): -- One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. - This technique can be used both in simulation and real vehicles. -- A custom namespace can be provided for simulations (only) by setting the environment variable `PX4_UXRCE_DDS_NS` before starting the simulation. +- 一种可能性是在从命令行启动[uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client)时使用 "-n" 选项。 + 这种技术既可用于模拟,也可用于实际机体。 +- 在开始模拟前,可以通过设置环境变量 `PX4_UXRCE_DDS_NS`来提供自定义命名空间 (仅限) :::info Changing the namespace at runtime will append the desired namespace as a prefix to all `topic` fields in [dds_topics.yaml](../middleware/dds_topics.md) and all [service servers](#dds-ros-2-services). -Therefore, commands like: +因此,命令如下: ```sh uxrce_dds_client start -n uav_1 @@ -374,7 +432,7 @@ uxrce_dds_client start -n uav_1 PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500 ``` -will generate topics under the namespaces: +将在以下命名空间下生成话题: ```sh /uav_1/fmu/in/ # for subscribers @@ -383,6 +441,23 @@ will generate topics under the namespaces: ::: +- A simple index-based namespace can be applied by setting the parameter [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to a value between 0 and 9999. + This will generate a namespace such as `/uav_0`, `/uav_1`, and so on. + This technique is ideal if vehicles must be persistently associated with namespaces because their clients are automatically started through PX4. + +:::info +PX4 parameters cannot carry rich text strings. +Therefore, you cannot use [`UXRCE_DDS_NS_IDX`](../advanced_config/parameter_reference.md#UXRCE_DDS_NS_IDX) to automatically start a client with an arbitrary message namespace through PX4. +You can however specify a namespace when starting the client, using the `-n` argument: + +```sh +# In etc/extras.txt on the MicroSD card +uxrce_dds_client start -n fancy_uav +``` + +This can be included in `etc/extras.txt` as part of a custom [System Startup](../concept/system_startup.md). +::: + ## PX4 ROS 2 QoS Settings PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers. @@ -443,6 +518,11 @@ publications: - topic: /fmu/out/vehicle_trajectory_waypoint_desired type: px4_msgs::msg::VehicleTrajectoryWaypoint + - topic: /fmu/out/vehicle_imu + type: px4_msgs::msg::VehicleImu + rate_limit: 50. + instance: 1 # OPTIONAL + subscriptions: - topic: /fmu/in/offboard_control_mode @@ -466,15 +546,18 @@ Each (`topic`,`type`) pairs defines: 1. A new `publication`, `subscription`, or `subscriptions_multi`, depending on the list to which it is added. 2. The topic _base name_, which **must** coincide with the desired uORB topic name that you want to publish/subscribe. - It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. - `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. + It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it. + `vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names. 3. The topic [namespace](https://design.ros2.org/articles/topic_and_service_names.html#namespaces). - By default it is set to: - - `/fmu/out/` for topics that are _published_ by PX4. - - `/fmu/in/` for topics that are _subscribed_ by PX4. + By default it is set to: + - `/fmu/out/` for topics that are _published_ by PX4. + - `/fmu/in/` for topics that are _subscribed_ by PX4. 4. The message type (`VehicleOdometry`, `VehicleStatus`, `OffboardControlMode`, etc.) and the ROS 2 package (`px4_msgs`) that is expected to provide the message definition. 5. **(Optional)**: An additional `rate_limit` field (only for publication entries), which specifies the maximum rate (Hz) at which messages will be published on this topic by PX4 to ROS 2. - If left unspecified, the maximum publication rate limit is set to 100 Hz. + If left unspecified, the maximum publication rate limit is set to 100 Hz. +6. **(Optional)**: An additional `instance` field (only for publication entries), which lets you select which instance of a [multi-instance topic](./uorb.md#multi-instance) you want to be published to ROS 2. + If provided, this option changes the ROS 2 topic name of the advertised uORB topic appending the instance number: `fmu/out/[uorb topic name][instance]` (plus eventual namespace and message version). + In the example above the final topic name would be `/fmu/out/vehicle_imu1`. `subscriptions` and `subscriptions_multi` allow us to choose the uORB topic instance that ROS 2 topics are routed to: either a shared instance that may also be getting updates from internal PX4 uORB publishers, or a separate instance that is reserved for ROS2 publications, respectively. Without this mechanism all ROS 2 messages would be routed to the _same_ uORB topic instance (because ROS 2 does not have the concept of [multiple topic instances](../middleware/uorb.md#multi-instance)), and it would not be possible for PX4 subscribers to differentiate between streams from ROS 2 or PX4 publishers. diff --git a/docs/zh/middleware/zenoh.md b/docs/zh/middleware/zenoh.md new file mode 100644 index 0000000000..f3d90420d6 --- /dev/null +++ b/docs/zh/middleware/zenoh.md @@ -0,0 +1,201 @@ +# Zenoh (PX4 ROS 2 rmw_zenoh) + + + +:::warning +Experimental +At the time of writing, PX4 Zenoh-pico is experimental, and hence subject to change. +::: + +PX4 supports Zenoh as an alternative mechanism (to DDS) for bridging uORB topics to [ROS 2](../ros2/user_guide.md) (via the ROS 2 [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh) middleware). +This allows uORB messages to be published and subscribed on a companion computer as though they were ROS 2 topics. +It provides a fast and lightweight way to connect PX4 to ROS 2, making it easier for applications to access vehicle telemetry and send control commands. + +The following guide describes the architecture and various options for setting up the Zenoh client and router. +In particular, it covers the options that are most important to PX4 users exploring Zenoh as an alternative communication layer for ROS 2. + +## 软件架构 + +The Zenoh-based middleware consists of a client running on PX4 and a Zenoh router running on the companion computer, with bi-directional data exchange between them over a UART, TCP, UDP, or multicast-UDP link. +The router acts as a broker and discovery service, enabling PX4 to publish and subscribe to topics in the global Zenoh data space. +This allows seamless integration with ROS 2 nodes using [`rmw_zenoh`](https://github.com/ros2/rmw_zenoh), and supports flexible deployment across distributed systems. + +![Architecture PX4 Zenoh-Pico with ROS 2](../../assets/middleware/zenoh/architecture-px4-zenoh.svg) + +The client is the _PX4 Zenoh-Pico Node_ referred to above, which is implemented in the [PX4 `zenoh` module](../modules/modules_driver.md#zenoh). +This is based on Zenoh-Pico, a minimalistic version of [Eclipse Zenoh](https://zenoh.io/) (a data-centric protocol designed for real-time, distributed, and resource-constrained environments). + +The router suggested above is [zenohd](https://github.com/eclipse-zenoh/zenoh/tree/main/zenohd). + +:::info +UART is supported by Zenoh but has not yet implemented in the PX4 Zenoh-Pico node. +::: + +## ROS 2 Zenoh Bring-up on Linux Companion + +In order for PX4 uORB topics to be shared with ROS 2 applications, you will need the PX4 Zenoh-Pico Node client running on your FMU, connected to a Zenoh router running on the companion computer (or elsewhere in the network). + +First select Zenoh as the ROS 2 transport by setting the `RMW_IMPLEMENTATION` environment variable as shown: + +```sh +export RMW_IMPLEMENTATION=rmw_zenoh_cpp +``` + +Then start the Zenoh router using the command: + +```sh +ros2 run rmw_zenoh_cpp rmw_zenohd +``` + +For more information about the Zenoh Router see the [rmw_zenoh](https://github.com/ros2/rmw_zenoh?tab=readme-ov-file#start-the-zenoh-router) documentation. + +## PX4 Zenoh-Pico Node Setup + +### PX4 Firmware + +Before setting up the Zenoh communication, first make sure that your firmware contains the driver that implements the [`zenoh` driver](../modules/modules_driver.md#zenoh), which provides the implementation of the _PX4 Zenoh-Pico Node_. + +You can check if the module is present on your board by searching for the key `CONFIG_MODULES_ZENOH=y` in your board's `default.px4board` KConfig file. +For example, you can see that the module is present in `px4_fmu-v6xrt` build targets from [/boards/px4/fmu-v6xrt/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6xrt/default.px4board#L91). + +If `CONFIG_MODULES_ZENOH=y` is not preset you can add this key to your board configuration and rebuild. +Note that due to flash constraints you may need to remove other components in order to include the module (such as the [`uxrce_dds_client` module](../modules/modules_system.md#uxrce-dds-client), which you will not need if you are using Zenoh). + +The table below shows some of the PX4 targets that include Zenoh by default. + +| PX4 Target | 备注 | +| ---------------------- | -------------------------------------------------------------------------------------------------------------- | +| `px4_fmu-v6xrt` | For [FMUv6X-RT](../flight_controller/nxp_mr_vmu_rt1176.md) (reference platform for testing) | +| `nxp_tropic-community` | | +| `nxp_mr-tropic` | | +| `nxp_mr-canhubk344` | | +| `px4_sitl_zenoh` | Zenoh-enabled simulation build | +| `px4_fmu-v6x_zenoh` | Zenoh-enabled firmware for FMUv6X | + +Zenoh is not included in the default `px4_fmu-` targets for any firmware other than `px4_fmu-v6xrt` (`px4_sitl_zenoh` and `px4_fmu-v6x_zenoh` [are build variants](../dev_setup/building_px4.md#px4-make-build-targets)). + +:::tip +You can check if Zenoh is present at runtime by using QGroundControl to [find the parameter](../advanced_config/parameters.md#finding-a-parameter) [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE). +If present, the module is installed. +::: + +### Enable Zenoh on PX4 Startup + +Set the [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE) parameter to `1` to enable Zenoh on PX4 startup. + +### Configure Zenoh Network + +Set up PX4 to connect to the companion computer running `zenohd`. + +PX4's default IP address of the Zenoh daemon host is `10.41.10.1`. +If you're using a different IP for the Zenoh daemon, run the following command (replacing the address) in a PX4 shell and then reboot: + +```sh +zenoh config net client tcp/10.41.10.1:7447#iface=eth0 +``` + +Note that for the simulation target with Zeroh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. + +:::warning +Any changes to the network configuration require a PX4 system reboot to take effect. +::: + +:::tip +See [PX4 Ethernet Setup](../advanced_config/ethernet_setup.md) for more information about Ethernet configuration. +::: + +### PX4 Zenoh-pico Node configuration + +The **default configuration** is auto-generated from the [dds_topics.yaml](../middleware/dds_topics.md) file in the PX4 repository. +This file specifies which uORB message definitions are to be published/subscribed by ROS 2 applications, and hence (indirectly) which topics are compiled into the zenoh module. + +To inspect the current Zenoh configuration: + +```sh +zenoh config +``` + +The PX4 Zenoh-pico node stores its configuration on the **SD card** under the `zenoh` folder. +This folder contains three key files: + +- **`net.txt`** – Defines the **Zenoh network configuration**. +- **`pub.csv`** – Maps **uORB topics to ROS2 topics** (used for publishing). +- **`sub.csv`** – Maps **ROS2 topics to uORB topics** (used for subscribing). + +### 4. Modifying Topic Mappings + +Zenoh topic mappings define how data flows between PX4's internal uORB topics and external ROS2 topics via Zenoh. +These mappings are stored in `pub.csv` and `sub.csv` on the SD card, and can be modified at runtime using the `zenoh config` CLI tool. + +:::warning +Any changes to the topic mappings require a PX4 system reboot to take effect. +::: + +There are two types of mappings you can modify: + +- **Publisher mappings**: Forward data from a uORB topic to a Zenoh topic. +- **Subscriber mappings**: Receive data from a Zenoh topic and publish it to a uORB topic. + +The main operations and their commands are: + +- Publish a uORB topic to a Zenoh topic: + + ```sh + zenoh config add publisher [uorb_instance] + ``` + +- Subscribe to a Zenoh topic and forward it to a uORB topic: + + ```sh + zenoh config add subscriber [uorb_instance] + ``` + +- Remove existing mappings: + + ```sh + zenoh config delete publisher + zenoh config delete subscriber + ``` + +After modifying the mappings, reboot PX4 to apply the changes. +The updated configuration will be loaded from the SD card during startup. + +## Communicating with PX4 from ROS 2 via Zenoh + +Once your PX4 FMU is publishing data into ROS 2, you can inspect the available topics and their contents using standard ROS 2 CLI tools: + +```sh +ros2 topic list(ROS 2 话题列表命令) +``` + +Check topic type and publishers/subscribers: + +```sh +ros2 topic info -v /fmu/out/vehicle_status +Type: px4_msgs/msg/VehicleStatus + +Publisher count: 1 + +Node name: px4_aabbcc00000000000000000000000000 +Node namespace: / +Topic type: px4_msgs/msg/VehicleStatus +Topic type hash: RIHS01_828bddbb7d4c2aa6ad93757955f6893be1ec5d8f11885ec7715bcdd76b5226c9 +Endpoint type: PUBLISHER +GID: 82.99.74.2c.b6.7d.93.44.91.4d.fe.14.93.58.40.16 +QoS profile: + Reliability: RELIABLE + History (Depth): KEEP_LAST (7) + Durability: VOLATILE + Lifespan: Infinite + Deadline: Infinite + Liveliness: AUTOMATIC + Liveliness lease duration: Infinite + +Subscription count: 0 +``` + +### PX4 ROS 2 Interface with Zenoh + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) works out of the box with Zenoh as a transport backend. +This means you can publish and subscribe to PX4 topics over Zenoh without changing your ROS 2 nodes or dealing with DDS configuration. +For setup details and supported message types, refer to the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). diff --git a/docs/zh/modules/hello_sky.md b/docs/zh/modules/hello_sky.md index 24646f3517..87e4ebffa4 100644 --- a/docs/zh/modules/hello_sky.md +++ b/docs/zh/modules/hello_sky.md @@ -28,151 +28,155 @@ This consists of a single _C_ file and a _cmake_ definition (which tells the too 1. Create a new directory **PX4-Autopilot/src/examples/px4_simple_app**. 2. Create a new C file in that directory named **px4_simple_app.c**: - - Copy in the default header to the top of the page. - 该注释应出现在所有贡献的文件中! + - Copy in the default header to the top of the page. + 该注释应出现在所有贡献的文件中! - ```c - /**************************************************************************** - * - * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - ``` + ```c + /**************************************************************************** + * + * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + ``` - - 将下面的代码复制到头部注释的下方, - 该注释应出现在所有贡献的文件中! + - 将下面的代码复制到头部注释的下方, + 该注释应出现在所有贡献的文件中! - ```c - /** - * @file px4_simple_app.c - * Minimal application example for PX4 autopilot - * - * @author Example User - */ + ```c + /** + * @file px4_simple_app.c + * Minimal application example for PX4 autopilot + * + * @author Example User + */ - #include + #include - __EXPORT int px4_simple_app_main(int argc, char *argv[]); + __EXPORT int px4_simple_app_main(int argc, char *argv[]); - int px4_simple_app_main(int argc, char *argv[]) - { - PX4_INFO("Hello Sky!"); - return OK; - } - ``` + int px4_simple_app_main(int argc, char *argv[]) + { + PX4_INFO("Hello Sky!"); + return OK; + } + ``` + + :::tip + + The main function must be named `_main` and exported from the module as shown. - :::tip - The main function must be named `_main` and exported from the module as shown. ::: - :::tip - `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). - There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. - Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + :::tip + + `PX4_INFO` is the equivalent of `printf` for the PX4 shell (included from **px4_platform_common/log.h**). + There are different log levels: `PX4_INFO`, `PX4_WARN`, `PX4_ERR`, `PX4_DEBUG`. + Warnings and errors are additionally added to the [ULog](../dev_log/ulog_file_format.md) and shown on [Flight Review](https://logs.px4.io/). + ::: 3. Create and open a new _cmake_ definition file named **CMakeLists.txt**. - 复制下面的文本: + 复制下面的文本: - ```cmake - ############################################################################ - # - # Copyright (c) 2015 PX4 Development Team. All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions - # are met: - # - # 1. Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # 2. Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in - # the documentation and/or other materials provided with the - # distribution. - # 3. Neither the name PX4 nor the names of its contributors may be - # used to endorse or promote products derived from this software - # without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - # POSSIBILITY OF SUCH DAMAGE. - # - ############################################################################ - px4_add_module( - MODULE examples__px4_simple_app - MAIN px4_simple_app - STACK_MAIN 2000 - SRCS - px4_simple_app.c - DEPENDS - ) - ``` + ```cmake + ############################################################################ + # + # Copyright (c) 2015 PX4 Development Team. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in + # the documentation and/or other materials provided with the + # distribution. + # 3. Neither the name PX4 nor the names of its contributors may be + # used to endorse or promote products derived from this software + # without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + ############################################################################ + px4_add_module( + MODULE examples__px4_simple_app + MAIN px4_simple_app + STACK_MAIN 2000 + SRCS + px4_simple_app.c + DEPENDS + ) + ``` - The `px4_add_module()` method builds a static library from a module description. + The `px4_add_module()` method builds a static library from a module description. - - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). - - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. + - The `MODULE` block is the Firmware-unique name of the module (by convention the module name is prefixed by parent directories back to `src`). + - The `MAIN` block lists the entry point of the module, which registers the command with NuttX so that it can be called from the PX4 shell or SITL console. - :::tip - The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). + :::tip + The `px4_add_module()` format is documented in [PX4-Autopilot/cmake/px4_add_module.cmake](https://github.com/PX4/PX4-Autopilot/blob/main/cmake/px4_add_module.cmake). ::: - ::: info - If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). - Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. - You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` + ::: info + If you specify `DYNAMIC` as an option to `px4_add_module`, a _shared library_ is created instead of a static library on POSIX platforms (these can be loaded without having to recompile PX4, and shared to others as binaries rather than source code). + Your app will not become a builtin command, but ends up in a separate file called `examples__px4_simple_app.px4mod`. + You can then run your command by loading the file at runtime using the `dyn` command: `dyn ./examples__px4_simple_app.px4mod` ::: 4. Create and open a new _Kconfig_ definition file named **Kconfig** and define your symbol for naming (see [Kconfig naming convention](../hardware/porting_guide_config.md#px4-kconfig-symbol-naming-convention)). - 复制下面的文本: + 复制下面的文本: - ``` - menuconfig EXAMPLES_PX4_SIMPLE_APP - bool "px4_simple_app" - default n - ---help--- - Enable support for px4_simple_app - ``` + ```text + menuconfig EXAMPLES_PX4_SIMPLE_APP + bool "px4_simple_app" + default n + ---help--- + Enable support for px4_simple_app + ``` ## 编译应用程序/固件 @@ -440,6 +444,7 @@ The [complete example code](https://github.com/PX4/PX4-Autopilot/blob/main/src/e */ #include +#include #include #include #include diff --git a/docs/zh/modules/module_template.md b/docs/zh/modules/module_template.md index 1e1cd84ed1..4e41399412 100644 --- a/docs/zh/modules/module_template.md +++ b/docs/zh/modules/module_template.md @@ -22,27 +22,27 @@ PX4-Autopilot contains a template for writing a new application (module) that ru 总结: 1. Specify the dependency on the work queue library in the cmake definition file ([CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/CMakeLists.txt)): - ``` - ... - DEPENDS - px4_work_queue - ``` + ``` + ... + DEPENDS + px4_work_queue + ``` 2. In addition to `ModuleBase`, the task should also derive from `ScheduledWorkItem` (included from [ScheduledWorkItem.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp)) 3. 在构造函数初始化中指定要添加任务的队列。 - The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: + The [work_item](https://github.com/PX4/PX4-Autopilot/blob/main/src/examples/work_item/WorkItemExample.cpp#L42) example adds itself to the `wq_configurations::test1` work queue as shown below: - ```cpp - WorkItemExample::WorkItemExample() : - ModuleParams(nullptr), - ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) - { - } - ``` + ```cpp + WorkItemExample::WorkItemExample() : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) + { + } + ``` - ::: info - The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). + ::: info + The available work queues (`wq_configurations`) are listed in [WorkQueueManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp#L49). ::: diff --git a/docs/zh/modules/modules_communication.md b/docs/zh/modules/modules_communication.md index 86a9eb78a6..03ca66aa5e 100644 --- a/docs/zh/modules/modules_communication.md +++ b/docs/zh/modules/modules_communication.md @@ -35,7 +35,7 @@ Source: [modules/mavlink](https://github.com/PX4/PX4-Autopilot/tree/main/src/mod This module implements the MAVLink protocol, which can be used on a Serial link or UDP network connection. It communicates with the system via uORB: some messages are directly handled in the module (eg. mission protocol), others are published via uORB (eg. vehicle_command). 流(Stream)被用来以特定速率发送周期性的消息,例如飞机姿态信息。 -Streams are used to send periodic messages with a specific rate, such as the vehicle attitude. When starting the mavlink instance, a mode can be specified, which defines the set of enabled streams with their rates. For a running instance, streams can be configured via mavlink stream command. +When starting the mavlink instance, a mode can be specified, which defines the set of enabled streams with their rates. For a running instance, streams can be configured via `mavlink stream` command. 可以存在多个该模块的实例,每个实例连接到一个串口设备或者网络端口。 diff --git a/docs/zh/modules/modules_driver.md b/docs/zh/modules/modules_driver.md index 531c5acbae..9d2534d052 100644 --- a/docs/zh/modules/modules_driver.md +++ b/docs/zh/modules/modules_driver.md @@ -2,6 +2,7 @@ 子分类 +- [Adc](modules_driver_adc.md) - [Airspeed Sensor](modules_driver_airspeed_sensor.md) - [Baro](modules_driver_baro.md) - [Camera](modules_driver_camera.md) @@ -14,98 +15,6 @@ - [Rpm Sensor](modules_driver_rpm_sensor.md) - [Transponder](modules_driver_transponder.md) -## MCP23009 - -Source: [drivers/gpio/mcp23009](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/gpio/mcp23009) - -### Usage {#MCP23009_usage} - -``` -MCP23009 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 37 - [-D ] Direction - default: 0 - [-O ] Output - default: 0 - [-P ] Pullups - default: 0 - [-U ] Update Interval [ms] - default: 0 - - stop - - status print status info -``` - -## adc - -Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) - -### 描述 - -ADC driver. - -### Usage {#adc_usage} - -``` -adc [arguments...] - Commands: - start - - test - [-n] Do not publish ADC report, only system power - - stop - - status print status info -``` - -## ads1115 - -Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) - -### 描述 - -Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. - -The driver is included by default in firmware for boards that do not have an internal analog to digital converter, -such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) -(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). - -It is enabled/disabled using the -[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) -parameter, and is disabled by default. -If enabled, internal ADCs are not used. - -### Usage {#ads1115_usage} - -``` -ads1115 [arguments...] - Commands: - start - [-I] Internal I2C bus(es) - [-X] External I2C bus(es) - [-b ] board-specific bus (default=all) (external SPI: n-th bus - (default=1)) - [-f ] bus frequency in kHz - [-q] quiet startup (no message if no device found) - [-a ] I2C address - default: 72 - - stop - - status print status info -``` - ## atxxxx Source: [drivers/osd/atxxxx](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/atxxxx) @@ -808,6 +717,64 @@ lsm303agr [arguments...] status print status info ``` +## mcp230xx + +Source: [lib/drivers/mcp_common](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/mcp_common) + +### Usage {#mcp230xx_usage} + +``` +mcp230xx [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 39 + [-D ] Direction (1=Input, 0=Output) + default: 0 + [-O ] Output + default: 0 + [-P ] Pullups + default: 0 + [-U ] Update Interval [ms] + default: 0 + [-M ] First minor number + default: 0 + + stop + + status print status info +``` + +## mcp9808 + +Source: [drivers/temperature_sensor/mcp9808](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/temperature_sensor/mcp9808) + +### Usage {#mcp9808_usage} + +``` +mcp9808 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 24 + + stop + + status print status info +``` + ## msp_osd Source: [drivers/osd/msp_osd](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/osd/msp_osd) diff --git a/docs/zh/modules/modules_driver_adc.md b/docs/zh/modules/modules_driver_adc.md new file mode 100644 index 0000000000..64209decad --- /dev/null +++ b/docs/zh/modules/modules_driver_adc.md @@ -0,0 +1,107 @@ +# Modules Reference: Adc (Driver) + +## TLA2528 + +Source: [drivers/adc/tla2528](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/tla2528) + +### Usage {#TLA2528_usage} + +``` +TLA2528 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` + +## adc + +Source: [drivers/adc/board_adc](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/board_adc) + +### 描述 + +ADC driver. + +### Usage {#adc_usage} + +``` +adc [arguments...] + Commands: + start + + test + [-n] Do not publish ADC report, only system power + + stop + + status print status info +``` + +## ads1115 + +Source: [drivers/adc/ads1115](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads1115) + +### 描述 + +Driver to enable an external [ADS1115](https://www.adafruit.com/product/1085) ADC connected via I2C. + +The driver is included by default in firmware for boards that do not have an internal analog to digital converter, +such as [PilotPi](../flight_controller/raspberry_pi_pilotpi.md) or [CUAV Nora](../flight_controller/cuav_nora.md) +(search for `CONFIG_DRIVERS_ADC_ADS1115` in board configuration files). + +It is enabled/disabled using the +[ADC_ADS1115_EN](../advanced_config/parameter_reference.md#ADC_ADS1115_EN) +parameter, and is disabled by default. +If enabled, internal ADCs are not used. + +### Usage {#ads1115_usage} + +``` +ads1115 [arguments...] + Commands: + start + [-I] Internal I2C bus(es) + [-X] External I2C bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + [-a ] I2C address + default: 72 + + stop + + status print status info +``` + +## ads7953 + +Source: [drivers/adc/ads7953](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/adc/ads7953) + +### Usage {#ads7953_usage} + +``` +ads7953 [arguments...] + Commands: + start + [-s] Internal SPI bus(es) + [-S] External SPI bus(es) + [-b ] board-specific bus (default=all) (external SPI: n-th bus + (default=1)) + [-c ] chip-select pin (for internal SPI) or index (for external SPI) + [-m ] SPI mode + [-f ] bus frequency in kHz + [-q] quiet startup (no message if no device found) + + stop + + status print status info +``` diff --git a/docs/zh/modules/modules_driver_distance_sensor.md b/docs/zh/modules/modules_driver_distance_sensor.md index a1a88411f2..f330f01947 100644 --- a/docs/zh/modules/modules_driver_distance_sensor.md +++ b/docs/zh/modules/modules_driver_distance_sensor.md @@ -104,7 +104,7 @@ Source: [drivers/distance_sensor/lightware_laser_i2c](https://github.com/PX4/PX4 ### 描述 -I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20. +I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20, SF30/d. Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html diff --git a/docs/zh/modules/modules_driver_ins.md b/docs/zh/modules/modules_driver_ins.md index 25978210ef..6d023b4d31 100644 --- a/docs/zh/modules/modules_driver_ins.md +++ b/docs/zh/modules/modules_driver_ins.md @@ -45,6 +45,41 @@ MicroStrain [arguments...] status Driver status ``` +## eulernav_bahrs + +Source: [drivers/ins/eulernav_bahrs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/eulernav_bahrs) + +### 描述 + +Serial bus driver for the EULER-NAV Baro-Inertial AHRS. + +### 示例 + +Attempt to start driver on a specified serial device. + +``` +eulernav_bahrs start -d /dev/ttyS1 +``` + +Stop driver + +``` +eulernav_bahrs stop +``` + +### Usage {#eulernav_bahrs_usage} + +``` +eulernav_bahrs [arguments...] + Commands: + start Start driver + -d Serial device + + status Print driver status + + stop Stop driver +``` + ## ilabs Source: [drivers/ins/ilabs](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/ilabs) @@ -90,6 +125,31 @@ ilabs [arguments...] status Print driver status ``` +## sbgecom + +Source: [drivers/ins/sbgecom](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/sbgecom) + +Description du module + +### Usage {#sbgecom_usage} + +``` +sbgecom [arguments...] + Commands: + start Start driver + [-d ] Serial device + default: /dev/ttyS0 + [-b ] Baudrate device + default: 921600 + [-f ] Config JSON file path + default: /etc/extras/sbg_settings\.json + [-s ] Config JSON string + + status Driver status + + stop Stop driver +``` + ## vectornav Source: [drivers/ins/vectornav](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/ins/vectornav) diff --git a/docs/zh/modules/modules_driver_radio_control.md b/docs/zh/modules/modules_driver_radio_control.md index e49199d3ec..f896b4ea78 100644 --- a/docs/zh/modules/modules_driver_radio_control.md +++ b/docs/zh/modules/modules_driver_radio_control.md @@ -17,6 +17,8 @@ crsf_rc [arguments...] [-d ] RC device values: , default: /dev/ttyS3 + inject Inject frame data bytes (for testing) + stop status print status info diff --git a/docs/zh/modules/modules_system.md b/docs/zh/modules/modules_system.md index 24246827fe..b23833af58 100644 --- a/docs/zh/modules/modules_system.md +++ b/docs/zh/modules/modules_system.md @@ -127,6 +127,10 @@ commander [arguments...] check Run preflight checks + safety Change prearm safety state + on|off [on] to activate safety, [off] to deactivate safety and allow + control surface movements + arm [-f] Force arming (do not run preflight checks) @@ -140,9 +144,9 @@ commander [arguments...] transition VTOL transition mode Change flight mode - manual|acro|offboard|stabilized|altctl|posctl|position:slow|auto:mission|au - to:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1 - Flight mode + manual|acro|offboard|stabilized|altctl|posctl|altitude_cruise|position:slow + |auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto: + precland|ext1 Flight mode pair @@ -154,6 +158,9 @@ commander [arguments...] lat|lon|alt Origin latitude longitude altitude + set_heading Set current heading + heading degrees from True North [0 360] + poweroff Power off board (if supported) stop @@ -1062,7 +1069,9 @@ uxrce_dds_client [arguments...] values: [-p ] Agent listening port. If not provided, defaults to UXRCE_DDS_PRT - [-n ] Client DDS namespace + [-n ] Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is + between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will + be used stop diff --git a/docs/zh/msg_docs/ActionRequest.md b/docs/zh/msg_docs/ActionRequest.md index 3579870754..1c724dabb7 100644 --- a/docs/zh/msg_docs/ActionRequest.md +++ b/docs/zh/msg_docs/ActionRequest.md @@ -15,25 +15,25 @@ Request are published by `manual_control` and subscribed by the `commander` and # It allows mapping triggers from various external interfaces like RC channels or MAVLink to cause an action. # Request are published by `manual_control` and subscribed by the `commander` and `vtol_att_control` modules. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint8 action # [@enum ACTION] Requested action -uint8 ACTION_DISARM = 0 # Disarm vehicle -uint8 ACTION_ARM = 1 # Arm vehicle -uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming -uint8 ACTION_UNKILL = 3 # Revert a kill action -uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) -uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. -uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight -uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight -uint8 ACTION_TERMINATION = 8 # Irreversably output failsafe values on all outputs, trigger parachute +uint8 action # [@enum ACTION] Requested action +uint8 ACTION_DISARM = 0 # Disarm vehicle +uint8 ACTION_ARM = 1 # Arm vehicle +uint8 ACTION_TOGGLE_ARMING = 2 # Toggle arming +uint8 ACTION_UNKILL = 3 # Revert a kill action +uint8 ACTION_KILL = 4 # Kill vehicle (instantly stop the motors) +uint8 ACTION_SWITCH_MODE = 5 # Switch mode. The target mode is set in the `mode` field. +uint8 ACTION_VTOL_TRANSITION_TO_MULTICOPTER = 6 # Transition to hover flight +uint8 ACTION_VTOL_TRANSITION_TO_FIXEDWING = 7 # Transition to fast forward flight +uint8 ACTION_TERMINATION = 8 # Irreversibly output failsafe values on all outputs, trigger parachute -uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture -uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position -uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position -uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held -uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism +uint8 source # [@enum SOURCE] Request trigger type, such as a switch, button or gesture +uint8 SOURCE_STICK_GESTURE = 0 # Triggered by holding the sticks in a certain position +uint8 SOURCE_RC_SWITCH = 1 # Triggered by an RC switch moving into a certain position +uint8 SOURCE_RC_BUTTON = 2 # Triggered by a momentary button on the RC being pressed or held +uint8 SOURCE_RC_MODE_SLOT = 3 # Mode change through the RC mode selection mechanism -uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. +uint8 mode # Requested mode. Only applies when `action` is `ACTION_SWITCH_MODE`. Values for this field are defined by the `vehicle_status_s::NAVIGATION_STATE_*` enumeration. ``` diff --git a/docs/zh/msg_docs/ActuatorMotors.md b/docs/zh/msg_docs/ActuatorMotors.md index 06fbd1b908..701465d6ea 100644 --- a/docs/zh/msg_docs/ActuatorMotors.md +++ b/docs/zh/msg_docs/ActuatorMotors.md @@ -15,14 +15,14 @@ Published by the vehicle's allocation and consumed by the ESC protocol drivers e uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint16 reversible_flags # Bitset indicating which motors are configured to be reversible +uint16 reversible_flags # [-] Bitset indicating which motors are configured to be reversible -uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 # -uint8 NUM_CONTROLS = 12 -float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) +uint8 NUM_CONTROLS = 12 # +float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) ``` diff --git a/docs/zh/msg_docs/ActuatorServos.md b/docs/zh/msg_docs/ActuatorServos.md index ffe01e2f49..ea053f67a3 100644 --- a/docs/zh/msg_docs/ActuatorServos.md +++ b/docs/zh/msg_docs/ActuatorServos.md @@ -15,10 +15,10 @@ Published by the vehicle's allocation and consumed by the actuator output driver uint32 MESSAGE_VERSION = 0 -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint8 NUM_CONTROLS = 8 -float32[8] control # [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. +uint8 NUM_CONTROLS = 8 # +float32[8] control # [-] [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. ``` diff --git a/docs/zh/msg_docs/AdcReport.md b/docs/zh/msg_docs/AdcReport.md index f4e3cea36d..50fde63ff5 100644 --- a/docs/zh/msg_docs/AdcReport.md +++ b/docs/zh/msg_docs/AdcReport.md @@ -1,13 +1,21 @@ # AdcReport (UORB message) +ADC raw data. + +Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AdcReport.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint32 device_id # unique device ID for the sensor that does not change between power cycles -int16[12] channel_id # ADC channel IDs, negative for non-existent, TODO: should be kept same as array index -int32[12] raw_data # ADC channel raw value, accept negative value, valid if channel ID is positive -uint32 resolution # ADC channel resolution -float32 v_ref # ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) +# ADC raw data. +# +# Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + +uint64 timestamp # [us] Time since system start +uint32 device_id # [-] unique device ID for the sensor that does not change between power cycles +int16[16] channel_id # [-] ADC channel IDs, negative for non-existent, TODO: should be kept same as array index +int32[16] raw_data # [-] ADC channel raw value, accept negative value, valid if channel ID is positive +uint32 resolution # [-] ADC channel resolution +float32 v_ref # [V] ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) ``` diff --git a/docs/zh/msg_docs/Airspeed.md b/docs/zh/msg_docs/Airspeed.md index 7309747f66..949af8d5e7 100644 --- a/docs/zh/msg_docs/Airspeed.md +++ b/docs/zh/msg_docs/Airspeed.md @@ -13,10 +13,10 @@ It is subscribed by the airspeed selector module, which validates the data from # This is published by airspeed sensor drivers, CAN airspeed sensors, simulators. # It is subscribed by the airspeed selector module, which validates the data from multiple sensors and passes on a single estimation to the EKF, controllers and telemetry providers. -uint64 timestamp # [us] Time since system start -uint64 timestamp_sample # [us] Timestamp of the raw data -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed -float32 true_airspeed_m_s # [m/s] True airspeed -float32 confidence # [@range 0,1] Confidence value for this sensor +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +float32 indicated_airspeed_m_s # [m/s] Indicated airspeed +float32 true_airspeed_m_s # [m/s] True airspeed +float32 confidence # [@range 0,1] Confidence value for this sensor ``` diff --git a/docs/zh/msg_docs/AirspeedValidated.md b/docs/zh/msg_docs/AirspeedValidated.md index 9034960626..61f607e7fa 100644 --- a/docs/zh/msg_docs/AirspeedValidated.md +++ b/docs/zh/msg_docs/AirspeedValidated.md @@ -1,29 +1,39 @@ # AirspeedValidated (UORB message) +Validated airspeed + +Provides information about airspeed (indicated, true, calibrated) and the source of the data. +Used by controllers, estimators and for airspeed reporting to operator. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/AirspeedValidated.msg) ```c +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + + uint32 MESSAGE_VERSION = 1 -uint64 timestamp # time since system start (microseconds) +uint64 timestamp # [us] Time since system start -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed (IAS), set to NAN if invalid -float32 calibrated_airspeed_m_s # [m/s] Calibrated airspeed (CAS), set to NAN if invalid -float32 true_airspeed_m_s # [m/s] True airspeed (TAS), set to NAN if invalid +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) -int8 airspeed_source # Source of currently published airspeed values -int8 DISABLED = -1 -int8 GROUND_MINUS_WIND = 0 -int8 SENSOR_1 = 1 -int8 SENSOR_2 = 2 -int8 SENSOR_3 = 3 -int8 SYNTHETIC = 4 +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed -# debug states -float32 calibrated_ground_minus_wind_m_s # CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid -float32 calibraded_airspeed_synth_m_s # synthetic airspeed in m/s, set to NAN if invalid -float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] -float32 throttle_filtered # filtered fixed-wing throttle [-] -float32 pitch_filtered # filtered pitch [rad] +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch ``` diff --git a/docs/zh/msg_docs/ArmingCheckReply.md b/docs/zh/msg_docs/ArmingCheckReply.md index d5e3322506..14af54f0d1 100644 --- a/docs/zh/msg_docs/ArmingCheckReply.md +++ b/docs/zh/msg_docs/ArmingCheckReply.md @@ -1,6 +1,6 @@ # ArmingCheckReply (UORB message) -Arming check reply. +Arming check reply This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -12,7 +12,7 @@ The message is not used by internal/FMU components, as their mode requirements a [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckReply.msg) ```c -# Arming check reply. +# Arming check reply # # This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. # The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -21,39 +21,39 @@ The message is not used by internal/FMU components, as their mode requirements a # Note that the external component is identified by its registration_id, which is allocated to the component during registration (arming_check_id in RegisterExtComponentReply). # The message is not used by internal/FMU components, as their mode requirements are known at compile time. -uint32 MESSAGE_VERSION = 1 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # [us] Time since system start. -uint8 request_id # Id of ArmingCheckRequest for which this is a response. -uint8 registration_id # Id of external component emitting this response. +uint8 request_id # [-] Id of ArmingCheckRequest for which this is a response +uint8 registration_id # [-] Id of external component emitting this response -uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies. +uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies -uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] -bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json). +uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] +bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json) -bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed. +bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed -uint8 num_events # Number of queued failure messages (Event) in the events field. +uint8 num_events # Number of queued failure messages (Event) in the events field -Event[5] events # Arming failure reasons (Queue of events to report to GCS). +Event[5] events # Arming failure reasons (Queue of events to report to GCS) # Mode requirements -bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope). -bool mode_req_attitude # Requires an attitude estimate. -bool mode_req_local_alt # Requires a local altitude estimate. -bool mode_req_local_position # Requires a local position estimate. -bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate. -bool mode_req_global_position # Requires a global position estimate. -bool mode_req_global_position_relaxed # Requires a relaxed global position estimate. -bool mode_req_mission # Requires an uploaded mission. -bool mode_req_home_position # Requires a home position (such as RTL/Return mode). -bool mode_req_prevent_arming # Prevent arming (such as in Land mode). -bool mode_req_manual_control # Requires a manual controller +bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope) +bool mode_req_attitude # Requires an attitude estimate +bool mode_req_local_alt # Requires a local altitude estimate +bool mode_req_local_position # Requires a local position estimate +bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate +bool mode_req_global_position # Requires a global position estimate +bool mode_req_global_position_relaxed # Requires a relaxed global position estimate +bool mode_req_mission # Requires an uploaded mission +bool mode_req_home_position # Requires a home position (such as RTL/Return mode) +bool mode_req_prevent_arming # Prevent arming (such as in Land mode) +bool mode_req_manual_control # Requires a manual controller -uint8 ORB_QUEUE_LENGTH = 4 # +uint8 ORB_QUEUE_LENGTH = 4 ``` diff --git a/docs/zh/msg_docs/ArmingCheckRequest.md b/docs/zh/msg_docs/ArmingCheckRequest.md index cfa4b52c23..d093dfb5e1 100644 --- a/docs/zh/msg_docs/ArmingCheckRequest.md +++ b/docs/zh/msg_docs/ArmingCheckRequest.md @@ -1,6 +1,6 @@ # ArmingCheckRequest (UORB message) -Arming check request. +Arming check request Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -12,7 +12,7 @@ The reply will also include the registration_id for each external component, pro [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/ArmingCheckRequest.msg) ```c -# Arming check request. +# Arming check request # # Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. # All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -21,10 +21,12 @@ The reply will also include the registration_id for each external component, pro # The reply will include the published request_id, allowing correlation of all arming check information for a particular request. # The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 -uint64 timestamp # [us] Time since system start. +uint64 timestamp # [us] Time since system start -uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint8 request_id # [-] Id of this request. Allows correlation with associated ArmingCheckReply messages. + +uint32 valid_registrations_mask # [-] Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) ``` diff --git a/docs/zh/msg_docs/ArmingCheckRequestV0.md b/docs/zh/msg_docs/ArmingCheckRequestV0.md new file mode 100644 index 0000000000..f5680c11f2 --- /dev/null +++ b/docs/zh/msg_docs/ArmingCheckRequestV0.md @@ -0,0 +1,30 @@ +# ArmingCheckRequestV0 (UORB message) + +Arming check request. + +Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. + +The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ArmingCheckRequestV0.msg) + +```c +# Arming check request. +# +# Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. +# All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. +# The request is sent regularly, even while armed, so that the FMU always knows the current arming state for external modes, and can forward it to ground stations. +# +# The reply will include the published request_id, allowing correlation of all arming check information for a particular request. +# The reply will also include the registration_id for each external component, provided to it during the registration process (RegisterExtComponentReply). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start. + +uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. + +``` diff --git a/docs/zh/msg_docs/AutotuneAttitudeControlStatus.md b/docs/zh/msg_docs/AutotuneAttitudeControlStatus.md index 734a671ffd..31a47ef204 100644 --- a/docs/zh/msg_docs/AutotuneAttitudeControlStatus.md +++ b/docs/zh/msg_docs/AutotuneAttitudeControlStatus.md @@ -1,42 +1,59 @@ # AutotuneAttitudeControlStatus (UORB message) +Autotune attitude control status + +This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +and is subscribed to by the respective attitude controllers to command rate setpoints. + +The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/AutotuneAttitudeControlStatus.msg) ```c -uint64 timestamp # time since system start (microseconds) +# Autotune attitude control status +# +# This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +# and is subscribed to by the respective attitude controllers to command rate setpoints. +# +# The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. -float32[5] coeff # coefficients of the identified discrete-time model -float32[5] coeff_var # coefficients' variance of the identified discrete-time model -float32 fitness # fitness of the parameter estimate -float32 innov -float32 dt_model +uint64 timestamp # [us] Time since system start -float32 kc -float32 ki -float32 kd -float32 kff -float32 att_p +float32[5] coeff # [-] Coefficients of the identified discrete-time model +float32[5] coeff_var # [-] Coefficients' variance of the identified discrete-time model +float32 fitness # [-] Fitness of the parameter estimate +float32 innov # [rad/s] Innovation (residual error between model and measured output) +float32 dt_model # [s] Model sample time used for identification -float32[3] rate_sp -float32 u_filt -float32 y_filt +float32 kc # [-] Proportional rate-loop gain (ideal form) +float32 ki # [-] Integral rate-loop gain (ideal form) +float32 kd # [-] Derivative rate-loop gain (ideal form) +float32 kff # [-] Feedforward rate-loop gain +float32 att_p # [-] Proportional attitude gain -uint8 STATE_IDLE = 0 -uint8 STATE_INIT = 1 -uint8 STATE_ROLL = 2 -uint8 STATE_ROLL_PAUSE = 3 -uint8 STATE_PITCH = 4 -uint8 STATE_PITCH_PAUSE = 5 -uint8 STATE_YAW = 6 -uint8 STATE_YAW_PAUSE = 7 -uint8 STATE_VERIFICATION = 8 -uint8 STATE_APPLY = 9 -uint8 STATE_TEST = 10 -uint8 STATE_COMPLETE = 11 -uint8 STATE_FAIL = 12 -uint8 STATE_WAIT_FOR_DISARM = 13 +float32[3] rate_sp # [rad/s] Rate setpoint commanded to the attitude controller. -uint8 state +float32 u_filt # [-] Filtered input signal (normalized torque setpoint) used in system identification. +float32 y_filt # [rad/s] Filtered output signal (angular velocity) used in system identification. + +uint8 state # [@enum STATE] Current state of the autotune procedure. +uint8 STATE_IDLE = 0 # Idle (not running) +uint8 STATE_INIT = 1 # Initialize filters and setup +uint8 STATE_ROLL_AMPLITUDE_DETECTION = 2 # FW only: determine required excitation amplitude (roll) +uint8 STATE_ROLL = 3 # Roll-axis excitation and model identification +uint8 STATE_ROLL_PAUSE = 4 # Pause to return to level flight +uint8 STATE_PITCH_AMPLITUDE_DETECTION = 5 # FW only: determine required excitation amplitude (pitch) +uint8 STATE_PITCH = 6 # Pitch-axis excitation and model identification +uint8 STATE_PITCH_PAUSE = 7 # Pause to return to level flight +uint8 STATE_YAW_AMPLITUDE_DETECTION = 8 # FW only: determine required excitation amplitude (yaw) +uint8 STATE_YAW = 9 # Yaw-axis excitation and model identification +uint8 STATE_YAW_PAUSE = 10 # Pause to return to level flight +uint8 STATE_VERIFICATION = 11 # Verify model and candidate gains +uint8 STATE_APPLY = 12 # Apply gains +uint8 STATE_TEST = 13 # Test gains in closed-loop +uint8 STATE_COMPLETE = 14 # Tuning completed successfully +uint8 STATE_FAIL = 15 # Tuning failed (model invalid or controller unstable) +uint8 STATE_WAIT_FOR_DISARM = 16 # Waiting for disarm before finalizing ``` diff --git a/docs/zh/msg_docs/BatteryStatus.md b/docs/zh/msg_docs/BatteryStatus.md index 7204a2a12f..ec2c19c59e 100644 --- a/docs/zh/msg_docs/BatteryStatus.md +++ b/docs/zh/msg_docs/BatteryStatus.md @@ -2,7 +2,7 @@ Battery status -Battery status information for up to 4 battery instances. +Battery status information for up to 3 battery instances. These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. Battery instance information is also logged and streamed in MAVLink telemetry. @@ -11,81 +11,82 @@ Battery instance information is also logged and streamed in MAVLink telemetry. ```c # Battery status # -# Battery status information for up to 4 battery instances. +# Battery status information for up to 3 battery instances. # These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. # Battery instance information is also logged and streamed in MAVLink telemetry. uint32 MESSAGE_VERSION = 1 -uint8 MAX_INSTANCES = 4 +uint8 MAX_INSTANCES = 3 -uint64 timestamp # [us] Time since system start -bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. -float32 voltage_v # [V] [@invalid 0] Battery voltage -float32 current_a # [A] [@invalid -1] Battery current -float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) -float32 discharged_mah # [mAh] [@invalid -1] Discharged amount -float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity -float32 scale # [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag -float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load -float32 temperature # [°C] [@invalid NaN] Temperature of the battery -uint8 cell_count # [@invalid 0] Number of cells +uint64 timestamp # [us] Time since system start + +bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. +float32 voltage_v # [V] [@invalid 0] Battery voltage +float32 current_a # [A] [@invalid -1] Battery current +float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) +float32 discharged_mah # [mAh] [@invalid -1] Discharged amount +float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity +float32 scale # [-] [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag +float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load +float32 temperature # [°C] [@invalid NaN] Temperature of the battery +uint8 cell_count # [-] [@invalid 0] Number of cells -uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 source # [@enum SOURCE] Battery source +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) -uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 -uint16 capacity # [mAh] Capacity of the battery when fully charged -uint16 cycle_count # Number of discharge cycles the battery has experienced -uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge -uint16 manufacture_date # Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 -uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity -uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation -uint8 id # ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed -uint16 interface_error # Interface error counter +uint8 priority # [-] Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 +uint16 capacity # [mAh] Capacity of the battery when fully charged +uint16 cycle_count # [-] Number of discharge cycles the battery has experienced +uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge +uint16 manufacture_date # [-] Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 +uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity +uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation +uint8 id # [-] ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed +uint16 interface_error # [-] Interface error counter -float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages -float32 max_cell_voltage_delta # Max difference between individual cell voltages +float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages +float32 max_cell_voltage_delta # [V] Max difference between individual cell voltages -bool is_powering_off # Power off event imminent indication, false if unknown -bool is_required # Set if the battery is explicitly required before arming +bool is_powering_off # Power off event imminent indication, false if unknown +bool is_required # Set if the battery is explicitly required before arming -uint8 warning # [@enum WARNING STATE] Current battery warning -uint8 WARNING_NONE = 0 # No battery low voltage warning active -uint8 WARNING_LOW = 1 # Low voltage warning -uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately -uint8 WARNING_EMERGENCY = 3 # Immediate landing required -uint8 WARNING_FAILED = 4 # Battery has failed completely -uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field -uint8 STATE_CHARGING = 7 # Battery is charging +uint8 warning # [@enum WARNING STATE] Current battery warning +uint8 WARNING_NONE = 0 # No battery low voltage warning active +uint8 WARNING_LOW = 1 # Low voltage warning +uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately +uint8 WARNING_EMERGENCY = 3 # Immediate landing required +uint8 WARNING_FAILED = 4 # Battery has failed completely +uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field +uint8 STATE_CHARGING = 7 # Battery is charging -uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication -uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged -uint8 FAULT_SPIKES = 1 # Voltage spikes -uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed -uint8 FAULT_OVER_CURRENT = 3 # Over-current -uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature -uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault -uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) -uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware -uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system -uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem -uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming -uint8 FAULT_COUNT = 11 # Counter. Keep this as last element +uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication +uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged +uint8 FAULT_SPIKES = 1 # Voltage spikes +uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed +uint8 FAULT_OVER_CURRENT = 3 # Over-current +uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature +uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault +uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) +uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware +uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system +uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem +uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming +uint8 FAULT_COUNT = 11 # Counter. Keep this as last element -float32 full_charge_capacity_wh # [Wh] Compensated battery capacity -float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining -uint16 over_discharge_count # Number of battery overdischarge -float32 nominal_voltage # [V] Nominal voltage of the battery pack +float32 full_charge_capacity_wh # [Wh] Compensated battery capacity +float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining +uint16 over_discharge_count # [-] Number of battery overdischarge +float32 nominal_voltage # [V] Nominal voltage of the battery pack -float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate -float32 ocv_estimate # [V] Open circuit voltage estimate -float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate -float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of charge estimate -float32 voltage_prediction # [V] Predicted voltage -float32 prediction_error # [V] Prediction error -float32 estimation_covariance_norm # Norm of the covariance matrix +float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate +float32 ocv_estimate # [V] Open circuit voltage estimate +float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate +float32 volt_based_soc_estimate # [-] [@range 0, 1] Normalized volt based state of charge estimate +float32 voltage_prediction # [V] Predicted voltage +float32 prediction_error # [V] Prediction error +float32 estimation_covariance_norm # [-] Norm of the covariance matrix ``` diff --git a/docs/zh/msg_docs/BatteryStatusV0.md b/docs/zh/msg_docs/BatteryStatusV0.md index 86500d17a6..cd900a1f17 100644 --- a/docs/zh/msg_docs/BatteryStatusV0.md +++ b/docs/zh/msg_docs/BatteryStatusV0.md @@ -32,9 +32,9 @@ uint8 cell_count # [@invalid 0] Number of cells uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 uint16 capacity # [mAh] Capacity of the battery when fully charged diff --git a/docs/zh/msg_docs/CellularStatus.md b/docs/zh/msg_docs/CellularStatus.md index 6579d3fe85..04ca0a65dc 100644 --- a/docs/zh/msg_docs/CellularStatus.md +++ b/docs/zh/msg_docs/CellularStatus.md @@ -11,39 +11,39 @@ This is currently used only for logging cell status from MAVLink. # # This is currently used only for logging cell status from MAVLink. -uint64 timestamp # [us] Time since system start +uint64 timestamp # [us] Time since system start -uint16 status # [@enum STATUS_FLAG] Status bitmap -uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable -uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable -uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized -uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked -uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down -uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state -uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state -uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections -uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register -uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use -uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated -uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered -uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected +uint16 status # [@enum STATUS_FLAG] Status bitmap +uint16 STATUS_FLAG_UNKNOWN = 1 # State unknown or not reportable +uint16 STATUS_FLAG_FAILED = 2 # Modem is unusable +uint16 STATUS_FLAG_INITIALIZING = 4 # Modem is being initialized +uint16 STATUS_FLAG_LOCKED = 8 # Modem is locked +uint16 STATUS_FLAG_DISABLED = 16 # Modem is not enabled and is powered down +uint16 STATUS_FLAG_DISABLING = 32 # Modem is currently transitioning to the STATUS_FLAG_DISABLED state +uint16 STATUS_FLAG_ENABLING = 64 # Modem is currently transitioning to the STATUS_FLAG_ENABLED state +uint16 STATUS_FLAG_ENABLED = 128 # Modem is enabled and powered on but not registered with a network provider and not available for data connections +uint16 STATUS_FLAG_SEARCHING = 256 # Modem is searching for a network provider to register +uint16 STATUS_FLAG_REGISTERED = 512 # Modem is registered with a network provider, and data connections and messaging may be available for use +uint16 STATUS_FLAG_DISCONNECTING = 1024 # Modem is disconnecting and deactivating the last active packet data bearer. This state will not be entered if more than one packet data bearer is active and one of the active bearers is deactivated +uint16 STATUS_FLAG_CONNECTING = 2048 # Modem is activating and connecting the first packet data bearer. Subsequent bearer activations when another bearer is already active do not cause this state to be entered +uint16 STATUS_FLAG_CONNECTED = 4096 # One or more packet data bearers is active and connected -uint8 failure_reason # [@enum FAILURE_REASON] Failure reason -uint8 FAILURE_REASON_NONE = 0 # No error -uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown -uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing -uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection +uint8 failure_reason # [@enum FAILURE_REASON] Failure reason +uint8 FAILURE_REASON_NONE = 0 # No error +uint8 FAILURE_REASON_UNKNOWN = 1 # Error state is unknown +uint8 FAILURE_REASON_SIM_MISSING = 2 # SIM is required for the modem but missing +uint8 FAILURE_REASON_SIM_ERROR = 3 # SIM is available, but not usable for connection -uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type -uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None -uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM -uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA -uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE +uint8 type # [@enum CELLULAR_NETWORK_RADIO_TYPE] Cellular network radio type +uint8 CELLULAR_NETWORK_RADIO_TYPE_NONE = 0 # None +uint8 CELLULAR_NETWORK_RADIO_TYPE_GSM = 1 # GSM +uint8 CELLULAR_NETWORK_RADIO_TYPE_CDMA = 2 # CDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_WCDMA = 3 # WCDMA +uint8 CELLULAR_NETWORK_RADIO_TYPE_LTE = 4 # LTE -uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value -uint16 mcc # [@invalid UINT16_MAX] Mobile country code -uint16 mnc # [@invalid UINT16_MAX] Mobile network code -uint16 lac # [@invalid 0] Location area code +uint8 quality # [dBm] Cellular network RSSI/RSRP, absolute value +uint16 mcc # [@invalid UINT16_MAX] Mobile country code +uint16 mnc # [@invalid UINT16_MAX] Mobile network code +uint16 lac # [@invalid 0] Location area code ``` diff --git a/docs/zh/msg_docs/ConfigOverrides.md b/docs/zh/msg_docs/ConfigOverrides.md index 37f88d4923..caa4d0816b 100644 --- a/docs/zh/msg_docs/ConfigOverrides.md +++ b/docs/zh/msg_docs/ConfigOverrides.md @@ -7,7 +7,7 @@ Configurable overrides by (external) modes or mode executors ```c # Configurable overrides by (external) modes or mode executors -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -15,7 +15,7 @@ bool disable_auto_disarm # Prevent the drone from automatically disarmin bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout - +bool disable_auto_set_home # Prevent the drone from automatically setting the home position on arm or takeoff int8 SOURCE_TYPE_MODE = 0 int8 SOURCE_TYPE_MODE_EXECUTOR = 1 diff --git a/docs/zh/msg_docs/ConfigOverridesV0.md b/docs/zh/msg_docs/ConfigOverridesV0.md new file mode 100644 index 0000000000..91e2cf5b48 --- /dev/null +++ b/docs/zh/msg_docs/ConfigOverridesV0.md @@ -0,0 +1,30 @@ +# ConfigOverridesV0 (UORB message) + +Configurable overrides by (external) modes or mode executors + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/ConfigOverridesV0.msg) + +```c +# Configurable overrides by (external) modes or mode executors + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +bool disable_auto_disarm # Prevent the drone from automatically disarming after landing (if configured) + +bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) +int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout + + +int8 SOURCE_TYPE_MODE = 0 +int8 SOURCE_TYPE_MODE_EXECUTOR = 1 +int8 source_type + +uint8 source_id # ID depending on source_type + +uint8 ORB_QUEUE_LENGTH = 4 + +# TOPICS config_overrides config_overrides_request + +``` diff --git a/docs/zh/msg_docs/ControlAllocatorStatus.md b/docs/zh/msg_docs/ControlAllocatorStatus.md index b355b772b6..4068e7b4f4 100644 --- a/docs/zh/msg_docs/ControlAllocatorStatus.md +++ b/docs/zh/msg_docs/ControlAllocatorStatus.md @@ -24,5 +24,6 @@ int8[16] actuator_saturation # Indicates actuator saturation status. # Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value. uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/zh/msg_docs/DeviceInformation.md b/docs/zh/msg_docs/DeviceInformation.md new file mode 100644 index 0000000000..d415461f94 --- /dev/null +++ b/docs/zh/msg_docs/DeviceInformation.md @@ -0,0 +1,45 @@ +# DeviceInformation (UORB message) + +Device information + +Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +as well as tracking of the used firmware versions on the devices. + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DeviceInformation.msg) + +```c +# Device information +# +# Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +# as well as tracking of the used firmware versions on the devices. + +uint64 timestamp # time since system start (microseconds) + +uint8 device_type # [@enum DEVICE_TYPE] Type of the device. Matches MAVLink DEVICE_TYPE enum + +uint8 DEVICE_TYPE_GENERIC = 0 # Generic/unknown sensor +uint8 DEVICE_TYPE_AIRSPEED = 1 # Airspeed sensor +uint8 DEVICE_TYPE_ESC = 2 # ESC +uint8 DEVICE_TYPE_SERVO = 3 # Servo +uint8 DEVICE_TYPE_GPS = 4 # GPS +uint8 DEVICE_TYPE_MAGNETOMETER = 5 # Magnetometer +uint8 DEVICE_TYPE_PARACHUTE = 6 # Parachute +uint8 DEVICE_TYPE_RANGEFINDER = 7 # Rangefinder +uint8 DEVICE_TYPE_WINCH = 8 # Winch +uint8 DEVICE_TYPE_BAROMETER = 9 # Barometer +uint8 DEVICE_TYPE_OPTICAL_FLOW = 10 # Optical flow +uint8 DEVICE_TYPE_ACCELEROMETER = 11 # Accelerometer +uint8 DEVICE_TYPE_GYROSCOPE = 12 # Gyroscope +uint8 DEVICE_TYPE_DIFFERENTIAL_PRESSURE = 13 # Differential pressure +uint8 DEVICE_TYPE_BATTERY = 14 # Battery +uint8 DEVICE_TYPE_HYGROMETER = 15 # Hygrometer + +char[32] vendor_name # Name of the device vendor +char[32] model_name # Name of the device model + +uint32 device_id # [-] [@invalid 0 if not available] Unique device ID for the sensor. Does not change between power cycles. +char[24] firmware_version # [-] [@invalid empty if not available] Firmware version. +char[24] hardware_version # [-] [@invalid empty if not available] Hardware version. +char[33] serial_number # [-] [@invalid empty if not available] Device serial number or unique identifier. + +``` diff --git a/docs/zh/msg_docs/DifferentialPressure.md b/docs/zh/msg_docs/DifferentialPressure.md index f5fd908df9..83adb2d03e 100644 --- a/docs/zh/msg_docs/DifferentialPressure.md +++ b/docs/zh/msg_docs/DifferentialPressure.md @@ -1,17 +1,24 @@ # DifferentialPressure (UORB message) +Differential-pressure (airspeed) sensor + +This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/DifferentialPressure.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Differential-pressure (airspeed) sensor +# +# This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 differential_pressure_pa # differential pressure reading in Pascals (may be negative) - -float32 temperature # Temperature provided by sensor in degrees Celsius, NAN if unknown - -uint32 error_count # Number of errors detected by driver +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 differential_pressure_pa # [Pa] Differential pressure reading (may be negative) +float32 temperature # [degC] [@invalid NaN if unknown] Temperature +uint32 error_count # [-] Number of errors detected by driver ``` diff --git a/docs/zh/msg_docs/EscReport.md b/docs/zh/msg_docs/EscReport.md index 5fc5456bbd..277402ae69 100644 --- a/docs/zh/msg_docs/EscReport.md +++ b/docs/zh/msg_docs/EscReport.md @@ -16,6 +16,19 @@ uint8 esc_state # State of ESC - depend on Vendor uint8 actuator_function # actuator output function (one of Motor1...MotorN) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR2 = 102 +uint8 ACTUATOR_FUNCTION_MOTOR3 = 103 +uint8 ACTUATOR_FUNCTION_MOTOR4 = 104 +uint8 ACTUATOR_FUNCTION_MOTOR5 = 105 +uint8 ACTUATOR_FUNCTION_MOTOR6 = 106 +uint8 ACTUATOR_FUNCTION_MOTOR7 = 107 +uint8 ACTUATOR_FUNCTION_MOTOR8 = 108 +uint8 ACTUATOR_FUNCTION_MOTOR9 = 109 +uint8 ACTUATOR_FUNCTION_MOTOR10 = 110 +uint8 ACTUATOR_FUNCTION_MOTOR11 = 111 +uint8 ACTUATOR_FUNCTION_MOTOR12 = 112 + uint16 failures # Bitmask to indicate the internal ESC faults int8 esc_power # Applied power 0-100 in % (negative values reserved) diff --git a/docs/zh/msg_docs/EstimatorStatus.md b/docs/zh/msg_docs/EstimatorStatus.md index e36871df1a..aca77484b9 100644 --- a/docs/zh/msg_docs/EstimatorStatus.md +++ b/docs/zh/msg_docs/EstimatorStatus.md @@ -21,6 +21,7 @@ uint8 GPS_CHECK_FAIL_MAX_VERT_DRIFT = 7 # 7 : maximum allowed vertical position uint8 GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR = 8 # 8 : maximum allowed horizontal speed fail - requires stationary vehicle uint8 GPS_CHECK_FAIL_MAX_VERT_SPD_ERR = 9 # 9 : maximum allowed vertical velocity discrepancy fail uint8 GPS_CHECK_FAIL_SPOOFED = 10 # 10 : GPS signal is spoofed +uint8 GPS_CHECK_FAIL_JAMMED = 11 # 11 : GPS signal is jammed uint64 control_mode_flags # Bitmask to indicate EKF logic state uint8 CS_TILT_ALIGN = 0 # 0 - true if the filter tilt alignment is complete @@ -52,7 +53,9 @@ uint8 CS_SYNTHETIC_MAG_Z = 25 # 25 - true when we are using a synthesized measur uint8 CS_VEHICLE_AT_REST = 26 # 26 - true when the vehicle is at rest uint8 CS_GPS_YAW_FAULT = 27 # 27 - true when the GNSS heading has been declared faulty and is no longer being used uint8 CS_RNG_FAULT = 28 # 28 - true when the range finder has been declared faulty and is no longer being used -uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurements are being fused +uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurement fusion is intended +uint8 CS_GNSS_FAULT = 45 # 45 - true if GNSS measurements have been declared faulty and are no longer used +uint8 CS_YAW_MANUAL = 46 # 46 - true if yaw has been set manually uint32 filter_fault_flags # Bitmask to indicate EKF internal faults # 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error diff --git a/docs/zh/msg_docs/EstimatorStatusFlags.md b/docs/zh/msg_docs/EstimatorStatusFlags.md index 19a6a00d23..aa7250fe1e 100644 --- a/docs/zh/msg_docs/EstimatorStatusFlags.md +++ b/docs/zh/msg_docs/EstimatorStatusFlags.md @@ -54,6 +54,9 @@ bool cs_valid_fake_pos # 41 - true if a valid constant position is bein bool cs_constant_pos # 42 - true if the vehicle is at a constant position bool cs_baro_fault # 43 - true when the current baro has been declared faulty and is no longer being used bool cs_gnss_vel # 44 - true if GNSS velocity measurement fusion is intended +bool cs_gnss_fault # 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty +bool cs_yaw_manual # 46 - true if yaw has been set manually +bool cs_gnss_hgt_fault # 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty # fault status uint32 fault_status_changes # number of filter fault status (fs) changes diff --git a/docs/zh/msg_docs/FailureDetectorStatus.md b/docs/zh/msg_docs/FailureDetectorStatus.md index 88e3ca4c24..a112a1e642 100644 --- a/docs/zh/msg_docs/FailureDetectorStatus.md +++ b/docs/zh/msg_docs/FailureDetectorStatus.md @@ -17,5 +17,6 @@ bool fd_motor float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed) uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection ``` diff --git a/docs/zh/msg_docs/GainCompression.md b/docs/zh/msg_docs/GainCompression.md new file mode 100644 index 0000000000..e26c1e8fcc --- /dev/null +++ b/docs/zh/msg_docs/GainCompression.md @@ -0,0 +1,12 @@ +# GainCompression (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/GainCompression.msg) + +```c +uint64 timestamp # Time since system start (microseconds) + +float32[3] compression_gains # [-] [@frame FRD] [@range 0, 1] Multiplicative gain to modify the output of the controller per axis +float32[3] spectral_damper_hpf # [-] [@frame FRD] Squared output of spectral damper high-pass filter +float32[3] spectral_damper_out # [-] [@frame FRD] Spectral damper output squared + +``` diff --git a/docs/zh/msg_docs/GimbalDeviceAttitudeStatus.md b/docs/zh/msg_docs/GimbalDeviceAttitudeStatus.md index 2c8c6eca9b..0935029087 100644 --- a/docs/zh/msg_docs/GimbalDeviceAttitudeStatus.md +++ b/docs/zh/msg_docs/GimbalDeviceAttitudeStatus.md @@ -14,6 +14,9 @@ uint16 DEVICE_FLAGS_NEUTRAL = 2 uint16 DEVICE_FLAGS_ROLL_LOCK = 4 uint16 DEVICE_FLAGS_PITCH_LOCK = 8 uint16 DEVICE_FLAGS_YAW_LOCK = 16 +uint16 DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32 +uint16 DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64 + float32[4] q float32 angular_velocity_x diff --git a/docs/zh/msg_docs/GpioIn.md b/docs/zh/msg_docs/GpioIn.md index 039ed02851..589e7d7841 100644 --- a/docs/zh/msg_docs/GpioIn.md +++ b/docs/zh/msg_docs/GpioIn.md @@ -6,6 +6,7 @@ GPIO mask and state ```c # GPIO mask and state +uint8 MAX_INSTANCES = 8 uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id diff --git a/docs/zh/msg_docs/GpsDump.md b/docs/zh/msg_docs/GpsDump.md index 1f96901671..03910da906 100644 --- a/docs/zh/msg_docs/GpsDump.md +++ b/docs/zh/msg_docs/GpsDump.md @@ -9,11 +9,15 @@ This message is used to dump the raw gps communication to the log. uint64 timestamp # time since system start (microseconds) +uint8 INSTANCE_MAIN = 0 +uint8 INSTANCE_SECONDARY = 1 + uint8 instance # Instance of GNSS receiver +uint32 device_id uint8 len # length of data, MSB bit set = message to the gps device, # clear = message from the device uint8[79] data # data to write to the log -uint8 ORB_QUEUE_LENGTH = 8 +uint8 ORB_QUEUE_LENGTH = 16 ``` diff --git a/docs/zh/msg_docs/InputRc.md b/docs/zh/msg_docs/InputRc.md index d116542a6b..fbae6e0254 100644 --- a/docs/zh/msg_docs/InputRc.md +++ b/docs/zh/msg_docs/InputRc.md @@ -37,11 +37,13 @@ bool rc_lost # RC receiver connection status: True,if no frame has arrived in uint16 rc_lost_frame_count # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_total_frame_count # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_ppm_frame_length # Length of a single PPM frame. Zero for non-PPM systems +uint16 rc_frame_rate # RC frame rate in msg/second. 0 = invalid uint8 input_source # Input source uint16[18] values # measured pulse widths for each of the supported channels int8 link_quality # link quality. Percentage 0-100%. -1 = invalid float32 rssi_dbm # Actual rssi in units of dBm. NaN = invalid +int8 link_snr # link signal to noise ratio in units of dB. -1 = invalid ``` diff --git a/docs/zh/msg_docs/PurePursuitStatus.md b/docs/zh/msg_docs/PurePursuitStatus.md index 96577a0220..8d54ba473e 100644 --- a/docs/zh/msg_docs/PurePursuitStatus.md +++ b/docs/zh/msg_docs/PurePursuitStatus.md @@ -7,11 +7,11 @@ Pure pursuit status ```c # Pure pursuit status -uint64 timestamp # [us] Time since system start -float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller -float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller -float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path -float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint -float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint +uint64 timestamp # [us] Time since system start +float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller +float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller +float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path +float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint +float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint ``` diff --git a/docs/zh/msg_docs/RegisterExtComponentReply.md b/docs/zh/msg_docs/RegisterExtComponentReply.md index 860fa6ecb5..119703472a 100644 --- a/docs/zh/msg_docs/RegisterExtComponentReply.md +++ b/docs/zh/msg_docs/RegisterExtComponentReply.md @@ -3,7 +3,7 @@ [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/RegisterExtComponentReply.msg) ```c -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -17,6 +17,8 @@ int8 arming_check_id # arming check registration ID (-1 if invalid) int8 mode_id # assigned mode ID (-1 if invalid) int8 mode_executor_id # assigned mode executor ID (-1 if invalid) +bool not_user_selectable # mode cannot be selected by the user + uint8 ORB_QUEUE_LENGTH = 2 ``` diff --git a/docs/zh/msg_docs/RegisterExtComponentReplyV0.md b/docs/zh/msg_docs/RegisterExtComponentReplyV0.md new file mode 100644 index 0000000000..cceec88d5c --- /dev/null +++ b/docs/zh/msg_docs/RegisterExtComponentReplyV0.md @@ -0,0 +1,22 @@ +# RegisterExtComponentReplyV0 (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg) + +```c +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID from the request +char[25] name # name from the request + +uint16 px4_ros2_api_version + +bool success +int8 arming_check_id # arming check registration ID (-1 if invalid) +int8 mode_id # assigned mode ID (-1 if invalid) +int8 mode_executor_id # assigned mode executor ID (-1 if invalid) + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/zh/msg_docs/RegisterExtComponentRequest.md b/docs/zh/msg_docs/RegisterExtComponentRequest.md index 545737c64a..814ea6e51b 100644 --- a/docs/zh/msg_docs/RegisterExtComponentRequest.md +++ b/docs/zh/msg_docs/RegisterExtComponentRequest.md @@ -7,7 +7,7 @@ Request to register an external component ```c # Request to register an external component -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -26,7 +26,7 @@ bool register_mode_executor # registering an executor also requires a mod bool enable_replace_internal_mode # set to true if an internal mode should be replaced uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) - +bool not_user_selectable # mode cannot be selected by the user uint8 ORB_QUEUE_LENGTH = 2 diff --git a/docs/zh/msg_docs/RegisterExtComponentRequestV0.md b/docs/zh/msg_docs/RegisterExtComponentRequestV0.md new file mode 100644 index 0000000000..58e99a484e --- /dev/null +++ b/docs/zh/msg_docs/RegisterExtComponentRequestV0.md @@ -0,0 +1,33 @@ +# RegisterExtComponentRequestV0 (UORB message) + +Request to register an external component + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg) + +```c +# Request to register an external component + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID, set this to a random value +char[25] name # either the requested mode name, or component name + +uint16 LATEST_PX4_ROS2_API_VERSION = 1 # API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. + +uint16 px4_ros2_api_version # Set to LATEST_PX4_ROS2_API_VERSION + +# Components to be registered +bool register_arming_check +bool register_mode # registering a mode also requires arming_check to be set +bool register_mode_executor # registering an executor also requires a mode to be registered (which is the owned mode by the executor) + +bool enable_replace_internal_mode # set to true if an internal mode should be replaced +uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* +bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) + + +uint8 ORB_QUEUE_LENGTH = 2 + +``` diff --git a/docs/zh/msg_docs/RoverAttitudeSetpoint.md b/docs/zh/msg_docs/RoverAttitudeSetpoint.md index bd436278ca..ca75a6e3e2 100644 --- a/docs/zh/msg_docs/RoverAttitudeSetpoint.md +++ b/docs/zh/msg_docs/RoverAttitudeSetpoint.md @@ -7,7 +7,7 @@ Rover Attitude Setpoint ```c # Rover Attitude Setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint ``` diff --git a/docs/zh/msg_docs/RoverAttitudeStatus.md b/docs/zh/msg_docs/RoverAttitudeStatus.md index e6df929abd..f5a9ce1f02 100644 --- a/docs/zh/msg_docs/RoverAttitudeStatus.md +++ b/docs/zh/msg_docs/RoverAttitudeStatus.md @@ -7,8 +7,8 @@ Rover Attitude Status ```c # Rover Attitude Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw -float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) +uint64 timestamp # [us] Time since system start +float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw +float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) ``` diff --git a/docs/zh/msg_docs/RoverPositionSetpoint.md b/docs/zh/msg_docs/RoverPositionSetpoint.md index b45aa0515f..751536e7f9 100644 --- a/docs/zh/msg_docs/RoverPositionSetpoint.md +++ b/docs/zh/msg_docs/RoverPositionSetpoint.md @@ -7,11 +7,11 @@ Rover Position Setpoint ```c # Rover Position Setpoint -uint64 timestamp # [us] Time since system start -float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position -float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track -float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed -float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with -float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel +uint64 timestamp # [us] Time since system start +float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position +float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track +float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed +float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with +float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel ``` diff --git a/docs/zh/msg_docs/RoverRateSetpoint.md b/docs/zh/msg_docs/RoverRateSetpoint.md index 9bffa41b80..9bb844e802 100644 --- a/docs/zh/msg_docs/RoverRateSetpoint.md +++ b/docs/zh/msg_docs/RoverRateSetpoint.md @@ -7,7 +7,7 @@ Rover Rate setpoint ```c # Rover Rate setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint ``` diff --git a/docs/zh/msg_docs/RoverRateStatus.md b/docs/zh/msg_docs/RoverRateStatus.md index 684e4c458a..70345fe315 100644 --- a/docs/zh/msg_docs/RoverRateStatus.md +++ b/docs/zh/msg_docs/RoverRateStatus.md @@ -7,9 +7,9 @@ Rover Rate Status ```c # Rover Rate Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate -float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) -float32 pid_yaw_rate_integral # [] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller +uint64 timestamp # [us] Time since system start +float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate +float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) +float32 pid_yaw_rate_integral # [-] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller ``` diff --git a/docs/zh/msg_docs/RoverSpeedSetpoint.md b/docs/zh/msg_docs/RoverSpeedSetpoint.md new file mode 100644 index 0000000000..84176cd1c3 --- /dev/null +++ b/docs/zh/msg_docs/RoverSpeedSetpoint.md @@ -0,0 +1,14 @@ +# RoverSpeedSetpoint (UORB message) + +Rover Speed Setpoint + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedSetpoint.msg) + +```c +# Rover Speed Setpoint + +uint64 timestamp # [us] Time since system start +float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction +float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction + +``` diff --git a/docs/zh/msg_docs/RoverSpeedStatus.md b/docs/zh/msg_docs/RoverSpeedStatus.md new file mode 100644 index 0000000000..4213e1e5df --- /dev/null +++ b/docs/zh/msg_docs/RoverSpeedStatus.md @@ -0,0 +1,18 @@ +# RoverSpeedStatus (UORB message) + +Rover Velocity Status + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverSpeedStatus.msg) + +```c +# Rover Velocity Status + +uint64 timestamp # [us] Time since system start +float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction +float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_x_integral # [-] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction +float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction +float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_y_integral # [-] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction + +``` diff --git a/docs/zh/msg_docs/RoverSteeringSetpoint.md b/docs/zh/msg_docs/RoverSteeringSetpoint.md index 3e40a3986b..974f3fc4c9 100644 --- a/docs/zh/msg_docs/RoverSteeringSetpoint.md +++ b/docs/zh/msg_docs/RoverSteeringSetpoint.md @@ -7,7 +7,7 @@ Rover Steering setpoint ```c # Rover Steering setpoint -uint64 timestamp # [us] Time since system start -float32 normalized_steering_setpoint # [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels +uint64 timestamp # [us] Time since system start +float32 normalized_steering_setpoint # [-] [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels ``` diff --git a/docs/zh/msg_docs/RoverThrottleSetpoint.md b/docs/zh/msg_docs/RoverThrottleSetpoint.md index f1c4f7f653..bd5ee93d55 100644 --- a/docs/zh/msg_docs/RoverThrottleSetpoint.md +++ b/docs/zh/msg_docs/RoverThrottleSetpoint.md @@ -7,8 +7,8 @@ Rover Throttle setpoint ```c # Rover Throttle setpoint -uint64 timestamp # [us] Time since system start -float32 throttle_body_x # [] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis -float32 throttle_body_y # [] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis +uint64 timestamp # [us] Time since system start +float32 throttle_body_x # [-] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis +float32 throttle_body_y # [-] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis ``` diff --git a/docs/zh/msg_docs/RoverVelocitySetpoint.md b/docs/zh/msg_docs/RoverVelocitySetpoint.md deleted file mode 100644 index 65103082b8..0000000000 --- a/docs/zh/msg_docs/RoverVelocitySetpoint.md +++ /dev/null @@ -1,15 +0,0 @@ -# RoverVelocitySetpoint (UORB message) - -Rover Velocity Setpoint - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocitySetpoint.msg) - -```c -# Rover Velocity Setpoint - -uint64 timestamp # [us] Time since system start -float32 speed # [m/s] [@range -inf (Backwards), inf (Forwards)] Speed setpoint -float32 bearing # [rad] [@range -pi,pi] [@frame NED] [@invalid: NaN, speed is defined in body x direction] Bearing setpoint -float32 yaw # [rad] [@range -pi, pi] [@frame NED] [@invalid NaN, Defaults to vehicle yaw] Mecanum only: Yaw setpoint - -``` diff --git a/docs/zh/msg_docs/RoverVelocityStatus.md b/docs/zh/msg_docs/RoverVelocityStatus.md deleted file mode 100644 index dfd7756afa..0000000000 --- a/docs/zh/msg_docs/RoverVelocityStatus.md +++ /dev/null @@ -1,18 +0,0 @@ -# RoverVelocityStatus (UORB message) - -Rover Velocity Status - -[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/RoverVelocityStatus.msg) - -```c -# Rover Velocity Status - -uint64 timestamp # [us] Time since system start -float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction -float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_x_integral # [] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction -float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction -float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_y_integral # [] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction - -``` diff --git a/docs/zh/msg_docs/SensorBaro.md b/docs/zh/msg_docs/SensorBaro.md index cf834ccf36..ef4d7a8f28 100644 --- a/docs/zh/msg_docs/SensorBaro.md +++ b/docs/zh/msg_docs/SensorBaro.md @@ -1,18 +1,25 @@ # SensorBaro (UORB message) +Barometer sensor + +This is populated by barometer drivers and used by the EKF2 estimator. +The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorBaro.msg) ```c -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Barometer sensor +# +# This is populated by barometer drivers and used by the EKF2 estimator. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 pressure # static pressure measurement in Pascals - -float32 temperature # temperature in degrees Celsius - -uint32 error_count +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 pressure # [Pa] Static pressure measurement +float32 temperature # [degC] Temperature. +uint32 error_count # [-] Number of errors detected by driver. uint8 ORB_QUEUE_LENGTH = 4 diff --git a/docs/zh/msg_docs/SensorGnssStatus.md b/docs/zh/msg_docs/SensorGnssStatus.md new file mode 100644 index 0000000000..70602b85fc --- /dev/null +++ b/docs/zh/msg_docs/SensorGnssStatus.md @@ -0,0 +1,19 @@ +# SensorGnssStatus (UORB message) + +Gnss quality indicators + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorGnssStatus.msg) + +```c +# Gnss quality indicators + +uint64 timestamp # time since system start (microseconds) +uint32 device_id # unique device ID for the sensor that does not change between power cycles + +bool quality_available # Set to true if quality indicators are available +uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available +uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available +uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available +uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available + +``` diff --git a/docs/zh/msg_docs/SensorGps.md b/docs/zh/msg_docs/SensorGps.md index c8d09e9472..1b5fb3cf41 100644 --- a/docs/zh/msg_docs/SensorGps.md +++ b/docs/zh/msg_docs/SensorGps.md @@ -38,18 +38,26 @@ float32 vdop # Vertical dilution of precision int32 noise_per_ms # GPS noise per millisecond uint16 automatic_gain_control # Automatic gain control monitor -uint8 JAMMING_STATE_UNKNOWN = 0 -uint8 JAMMING_STATE_OK = 1 -uint8 JAMMING_STATE_WARNING = 2 -uint8 JAMMING_STATE_CRITICAL = 3 -uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical -int32 jamming_indicator # indicates jamming is occurring +uint8 JAMMING_STATE_UNKNOWN = 0 #default +uint8 JAMMING_STATE_OK = 1 +uint8 JAMMING_STATE_MITIGATED = 2 +uint8 JAMMING_STATE_DETECTED = 3 +uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected +int32 jamming_indicator # indicates jamming is occurring -uint8 SPOOFING_STATE_UNKNOWN = 0 -uint8 SPOOFING_STATE_NONE = 1 -uint8 SPOOFING_STATE_INDICATED = 2 -uint8 SPOOFING_STATE_MULTIPLE = 3 -uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical +uint8 SPOOFING_STATE_UNKNOWN = 0 #default +uint8 SPOOFING_STATE_OK = 1 +uint8 SPOOFING_STATE_MITIGATED = 2 +uint8 SPOOFING_STATE_DETECTED = 3 +uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected + +# Combined authentication state (e.g. Galileo OSNMA) +uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default +uint8 AUTHENTICATION_STATE_INITIALIZING = 1 +uint8 AUTHENTICATION_STATE_ERROR = 2 +uint8 AUTHENTICATION_STATE_OK = 3 +uint8 AUTHENTICATION_STATE_DISABLED = 4 +uint8 authentication_state # GPS signal authentication state float32 vel_m_s # GPS ground speed, (metres/sec) float32 vel_n_m_s # GPS North velocity, (metres/sec) @@ -63,6 +71,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi uint8 satellites_used # Number of satellites used +uint32 SYSTEM_ERROR_OK = 0 #default +uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1 +uint32 SYSTEM_ERROR_CONFIGURATION = 2 +uint32 SYSTEM_ERROR_SOFTWARE = 4 +uint32 SYSTEM_ERROR_ANTENNA = 8 +uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16 +uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32 +uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64 +uint32 system_error # General errors with the connected GPS receiver + float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) float32 heading_accuracy # heading accuracy (rad, [0, 2PI]) diff --git a/docs/zh/msg_docs/SensorTemp.md b/docs/zh/msg_docs/SensorTemp.md new file mode 100644 index 0000000000..5ed50541fe --- /dev/null +++ b/docs/zh/msg_docs/SensorTemp.md @@ -0,0 +1,11 @@ +# SensorTemp (UORB message) + +[source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/SensorTemp.msg) + +```c +uint64 timestamp # time since system start (microseconds) + +uint32 device_id # unique device ID for the sensor that does not change between power cycles +float32 temperature # Temperature provided by sensor (Celsius) + +``` diff --git a/docs/zh/msg_docs/VehicleAirData.md b/docs/zh/msg_docs/VehicleAirData.md index 75363b8571..dccfefc095 100644 --- a/docs/zh/msg_docs/VehicleAirData.md +++ b/docs/zh/msg_docs/VehicleAirData.md @@ -1,22 +1,26 @@ # VehicleAirData (UORB message) +Vehicle air data + +Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +Includes calculated data such as barometric altitude and air density. + [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/VehicleAirData.msg) ```c +# Vehicle air data +# +# Data from the currently selected barometer (plus ambient temperature from the source specified in temperature_source). +# Includes calculated data such as barometric altitude and air density. -uint64 timestamp # time since system start (microseconds) - -uint64 timestamp_sample # the timestamp of the raw data (microseconds) - -uint32 baro_device_id # unique device ID for the selected barometer - -float32 baro_alt_meter # Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH. -float32 baro_pressure_pa # Absolute pressure in Pascals -float32 ambient_temperature # Abient temperature in degrees Celsius -uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed - -float32 rho # air density - -uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp of the raw data +uint32 baro_device_id # Unique device ID for the selected barometer +float32 baro_alt_meter # [m] [@frame MSL] Altitude above MSL calculated from temperature compensated baro sensor data using an ISA corrected for sea level pressure SENS_BARO_QNH +float32 baro_pressure_pa # [Pa] Absolute pressure +float32 ambient_temperature # [degC] Ambient temperature +uint8 temperature_source # Source of temperature data: 0: Default Temperature (15°C), 1: External Baro, 2: Airspeed +float32 rho # [kg/m^3] Air density +uint8 calibration_count # Calibration changed counter. Monotonically increases whenever calibration changes. ``` diff --git a/docs/zh/msg_docs/VehicleCommand.md b/docs/zh/msg_docs/VehicleCommand.md index 19557cf496..225f680857 100644 --- a/docs/zh/msg_docs/VehicleCommand.md +++ b/docs/zh/msg_docs/VehicleCommand.md @@ -28,7 +28,7 @@ uint16 VEHICLE_CMD_DO_ORBIT = 34 # Start orbiting on the circumference of a circ uint16 VEHICLE_CMD_DO_FIGUREEIGHT = 35 # Start flying on the outline of a figure eight defined by the parameters. |[m] Major radius|[m] Minor radius|[m/s] Velocity|Orientation|Latitude/X|Longitude/Y|Altitude/Z| uint16 VEHICLE_CMD_NAV_ROI = 80 # Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |[@enum VEHICLE_ROI] Region of interest mode.|MISSION index/ target ID.|ROI index (allows a vehicle to manage multiple ROI's)|Unused|x the location of the fixed ROI (see MAV_FRAME)|y|z| uint16 VEHICLE_CMD_NAV_PATHPLANNING = 81 # Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning|0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid|Unused|[deg] [@range 0, 360] Yaw angle at goal, in compass degrees|Latitude/X of goal|Longitude/Y of goal|Altitude/Z of goal| -uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Unused|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| +uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Transition heading, 0: Default, 3: Use specified transition heading|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_VTOL_LAND = 85 # Transition to MC and land at location. |Unused|Unused|Unused|Desired yaw angle.|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_GUIDED_LIMITS = 90 # Set limits for external control. |[s] Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout|[m] Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit|[m] Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit|[m] Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit|Unused|Unused|Unused| uint16 VEHICLE_CMD_NAV_GUIDED_MASTER = 91 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -69,6 +69,7 @@ uint16 VEHICLE_CMD_DO_PARACHUTE=208 # Mission command to trigger a parachute. |a uint16 VEHICLE_CMD_DO_MOTOR_TEST=209 # Motor test command. |Instance (@range 1, )|throttle type|throttle|timeout [s]|Motor count|Test order|Unused| uint16 VEHICLE_CMD_DO_INVERTED_FLIGHT=210 # Change to/from inverted flight. |inverted (0=normal, 1=inverted)|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GRIPPER = 211 # Command to operate a gripper. +uint16 VEHICLE_CMD_DO_AUTOTUNE_ENABLE = 212 # Enable autotune module. |1 to enable|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL=214 # Mission command to set TRIG_INTERVAL for this flight. |[m] Camera trigger distance|Shutter integration time (ms)|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT=220 # Mission command to control a camera or antenna mount, using a quaternion as reference. |q1 - quaternion param #1, w (1 in null-rotation)|q2 - quaternion param #2, x (0 in null-rotation)|q3 - quaternion param #3, y (0 in null-rotation)|q4 - quaternion param #4, z (0 in null-rotation)|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GUIDED_MASTER=221 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -96,6 +97,7 @@ uint16 VEHICLE_CMD_REQUEST_CAMERA_INFORMATION = 521 # Request camera information uint16 VEHICLE_CMD_SET_CAMERA_MODE = 530 # Set camera capture mode (photo, video, etc.). uint16 VEHICLE_CMD_SET_CAMERA_ZOOM = 531 # Set camera zoom. uint16 VEHICLE_CMD_SET_CAMERA_FOCUS = 532 +uint16 VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE = 620 # Set an external estimate of vehicle attitude in degrees. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000 # Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE = 1001 # Gimbal configuration to set which sysid/compid is in primary and secondary control. uint16 VEHICLE_CMD_IMAGE_START_CAPTURE = 2000 # Start image capture sequence. @@ -106,6 +108,7 @@ uint16 VEHICLE_CMD_LOGGING_START = 2510 # Start streaming ULog data. uint16 VEHICLE_CMD_LOGGING_STOP = 2511 # Stop streaming ULog data. uint16 VEHICLE_CMD_CONTROL_HIGH_LATENCY = 2600 # Control starting/stopping transmitting data over the high latency link. uint16 VEHICLE_CMD_DO_VTOL_TRANSITION = 3000 # Command VTOL transition. +uint16 VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE = 5300 # Command safety on/off. |1 to activate safety, 0 to deactivate safety and allow control surface movements|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST = 3001 # Request arm authorization. uint16 VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY = 30001 # Prepare a payload deployment in the flight plan. uint16 VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY = 30002 # Control a pre-programmed payload deployment. @@ -185,6 +188,10 @@ int8 ARMING_ACTION_ARM = 1 uint8 GRIPPER_ACTION_RELEASE = 0 uint8 GRIPPER_ACTION_GRAB = 1 +# Used as param1 in DO_SET_SAFETY_SWITCH_STATE command. +uint8 SAFETY_OFF = 0 +uint8 SAFETY_ON = 1 + uint8 ORB_QUEUE_LENGTH = 8 float32 param1 # Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. diff --git a/docs/zh/msg_docs/VehicleOdometry.md b/docs/zh/msg_docs/VehicleOdometry.md index d559ded6c7..4213c23337 100644 --- a/docs/zh/msg_docs/VehicleOdometry.md +++ b/docs/zh/msg_docs/VehicleOdometry.md @@ -1,41 +1,44 @@ # VehicleOdometry (UORB message) -Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +Vehicle odometry data + +Fits ROS REP 147 for aerial vehicles [source file](https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleOdometry.msg) ```c -# Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +# Vehicle odometry data +# +# Fits ROS REP 147 for aerial vehicles uint32 MESSAGE_VERSION = 0 -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp sample -uint8 POSE_FRAME_UNKNOWN = 0 -uint8 POSE_FRAME_NED = 1 # NED earth-fixed frame -uint8 POSE_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 pose_frame # Position and orientation frame of reference +uint8 pose_frame # [@enum POSE_FRAME] Position and orientation frame of reference +uint8 POSE_FRAME_UNKNOWN = 0 # Unknown frame +uint8 POSE_FRAME_NED = 1 # North-East-Down (NED) navigation frame. Aligned with True North. +uint8 POSE_FRAME_FRD = 2 # Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. -float32[3] position # Position in meters. Frame of reference defined by local_frame. NaN if invalid/unknown -float32[4] q # Quaternion rotation from FRD body frame to reference frame. First value NaN if invalid/unknown +float32[3] position # [m] [@frame local frame] [@invalid NaN If invalid/unknown] Position. Origin is position of GC at startup. +float32[4] q # [-] [@invalid NaN First value if invalid/unknown] Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) -uint8 VELOCITY_FRAME_UNKNOWN = 0 -uint8 VELOCITY_FRAME_NED = 1 # NED earth-fixed frame -uint8 VELOCITY_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -uint8 velocity_frame # Reference frame of the velocity data +uint8 velocity_frame # [@enum VELOCITY_FRAME] Reference frame of the velocity data +uint8 VELOCITY_FRAME_UNKNOWN = 0 # Unknown frame +uint8 VELOCITY_FRAME_NED = 1 # NED navigation frame at current position. +uint8 VELOCITY_FRAME_FRD = 2 # FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. +uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -float32[3] velocity # Velocity in meters/sec. Frame of reference defined by velocity_frame variable. NaN if invalid/unknown +float32[3] velocity # [m/s] [@frame @velocity_frame] [@invalid NaN If invalid/unknown] Velocity. +float32[3] angular_velocity # [rad/s] [@frame @VELOCITY_FRAME_BODY_FRD] [@invalid NaN If invalid/unknown] Angular velocity in body-fixed frame -float32[3] angular_velocity # Angular velocity in body-fixed frame (rad/s). NaN if invalid/unknown +float32[3] position_variance # [m^2] Variance of position error +float32[3] orientation_variance # [rad^2] Variance of orientation/attitude error (expressed in body frame) +float32[3] velocity_variance # [m^2/s^2] Variance of velocity error -float32[3] position_variance -float32[3] orientation_variance -float32[3] velocity_variance - -uint8 reset_counter -int8 quality +uint8 reset_counter # [-] Reset counter. Counts reset events on attitude, velocity and position. +int8 quality # [-] [@invalid 0] Quality. Unused. # TOPICS vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry # TOPICS estimator_odometry diff --git a/docs/zh/msg_docs/VehicleStatus.md b/docs/zh/msg_docs/VehicleStatus.md index d1deeb0500..05e3f98bbb 100644 --- a/docs/zh/msg_docs/VehicleStatus.md +++ b/docs/zh/msg_docs/VehicleStatus.md @@ -20,20 +20,16 @@ uint8 ARMING_STATE_ARMED = 2 uint8 latest_arming_reason uint8 latest_disarming_reason -uint8 ARM_DISARM_REASON_TRANSITION_TO_STANDBY = 0 uint8 ARM_DISARM_REASON_STICK_GESTURE = 1 uint8 ARM_DISARM_REASON_RC_SWITCH = 2 uint8 ARM_DISARM_REASON_COMMAND_INTERNAL = 3 uint8 ARM_DISARM_REASON_COMMAND_EXTERNAL = 4 uint8 ARM_DISARM_REASON_MISSION_START = 5 -uint8 ARM_DISARM_REASON_SAFETY_BUTTON = 6 -uint8 ARM_DISARM_REASON_AUTO_DISARM_LAND = 7 -uint8 ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT = 8 -uint8 ARM_DISARM_REASON_KILL_SWITCH = 9 -uint8 ARM_DISARM_REASON_LOCKDOWN = 10 -uint8 ARM_DISARM_REASON_FAILURE_DETECTOR = 11 -uint8 ARM_DISARM_REASON_SHUTDOWN = 12 -uint8 ARM_DISARM_REASON_UNIT_TEST = 13 +uint8 ARM_DISARM_REASON_LANDING = 6 +uint8 ARM_DISARM_REASON_PREFLIGHT_INACTION = 7 +uint8 ARM_DISARM_REASON_KILL_SWITCH = 8 +uint8 ARM_DISARM_REASON_RC_BUTTON = 13 +uint8 ARM_DISARM_REASON_FAILSAFE = 14 uint64 nav_state_timestamp # time when current nav_state activated @@ -48,7 +44,7 @@ uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode uint8 NAVIGATION_STATE_POSITION_SLOW = 6 uint8 NAVIGATION_STATE_FREE5 = 7 -uint8 NAVIGATION_STATE_FREE4 = 8 +uint8 NAVIGATION_STATE_ALTITUDE_CRUISE = 8 # Altitude with Cruise mode uint8 NAVIGATION_STATE_FREE3 = 9 uint8 NAVIGATION_STATE_ACRO = 10 # Acro mode uint8 NAVIGATION_STATE_FREE2 = 11 diff --git a/docs/zh/msg_docs/index.md b/docs/zh/msg_docs/index.md index c35c9f1399..10c21f35f0 100644 --- a/docs/zh/msg_docs/index.md +++ b/docs/zh/msg_docs/index.md @@ -15,9 +15,9 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorMotors](ActuatorMotors.md) — Motor control message - [ActuatorServos](ActuatorServos.md) — Servo control message -- [AirspeedValidated](AirspeedValidated.md) -- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply. -- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request. +- [AirspeedValidated](AirspeedValidated.md) — Validated airspeed +- [ArmingCheckReply](ArmingCheckReply.md) — Arming check reply +- [ArmingCheckRequest](ArmingCheckRequest.md) — Arming check request - [BatteryStatus](BatteryStatus.md) — Battery status - [ConfigOverrides](ConfigOverrides.md) — Configurable overrides by (external) modes or mode executors - [Event](Event.md) — Events interface @@ -70,7 +70,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [VehicleLandDetected](VehicleLandDetected.md) - [VehicleLocalPosition](VehicleLocalPosition.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. -- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +- [VehicleOdometry](VehicleOdometry.md) — Vehicle odometry data - [VehicleRatesSetpoint](VehicleRatesSetpoint.md) - [VehicleStatus](VehicleStatus.md) — Encodes the system state of the vehicle published by commander - [VtolVehicleStatus](VtolVehicleStatus.md) — VEHICLE_VTOL_STATE, should match 1:1 MAVLinks's MAV_VTOL_STATE @@ -84,10 +84,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [ActuatorOutputs](ActuatorOutputs.md) - [ActuatorServosTrim](ActuatorServosTrim.md) — Servo trims, added as offset to servo outputs - [ActuatorTest](ActuatorTest.md) -- [AdcReport](AdcReport.md) +- [AdcReport](AdcReport.md) — ADC raw data. - [Airspeed](Airspeed.md) — Airspeed data from sensors - [AirspeedWind](AirspeedWind.md) — Wind estimate (from airspeed_selector) -- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) +- [AutotuneAttitudeControlStatus](AutotuneAttitudeControlStatus.md) — Autotune attitude control status - [BatteryInfo](BatteryInfo.md) — Battery information - [ButtonEvent](ButtonEvent.md) - [CameraCapture](CameraCapture.md) @@ -105,7 +105,8 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [DebugKeyValue](DebugKeyValue.md) - [DebugValue](DebugValue.md) - [DebugVect](DebugVect.md) -- [DifferentialPressure](DifferentialPressure.md) +- [DeviceInformation](DeviceInformation.md) — Device information +- [DifferentialPressure](DifferentialPressure.md) — Differential-pressure (airspeed) sensor - [DistanceSensor](DistanceSensor.md) — DISTANCE_SENSOR message data - [DistanceSensorModeChangeRequest](DistanceSensorModeChangeRequest.md) - [DronecanNodeStatus](DronecanNodeStatus.md) @@ -140,6 +141,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [FollowTargetEstimator](FollowTargetEstimator.md) - [FollowTargetStatus](FollowTargetStatus.md) - [FuelTankStatus](FuelTankStatus.md) +- [GainCompression](GainCompression.md) - [GeneratorStatus](GeneratorStatus.md) - [GeofenceResult](GeofenceResult.md) - [GeofenceStatus](GeofenceStatus.md) @@ -229,10 +231,10 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [RoverPositionSetpoint](RoverPositionSetpoint.md) — Rover Position Setpoint - [RoverRateSetpoint](RoverRateSetpoint.md) — Rover Rate setpoint - [RoverRateStatus](RoverRateStatus.md) — Rover Rate Status +- [RoverSpeedSetpoint](RoverSpeedSetpoint.md) — Rover Speed Setpoint +- [RoverSpeedStatus](RoverSpeedStatus.md) — Rover Velocity Status - [RoverSteeringSetpoint](RoverSteeringSetpoint.md) — Rover Steering setpoint - [RoverThrottleSetpoint](RoverThrottleSetpoint.md) — Rover Throttle setpoint -- [RoverVelocitySetpoint](RoverVelocitySetpoint.md) — Rover Velocity Setpoint -- [RoverVelocityStatus](RoverVelocityStatus.md) — Rover Velocity Status - [Rpm](Rpm.md) - [RtlStatus](RtlStatus.md) - [RtlTimeEstimate](RtlTimeEstimate.md) @@ -240,12 +242,13 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [SensorAccel](SensorAccel.md) - [SensorAccelFifo](SensorAccelFifo.md) - [SensorAirflow](SensorAirflow.md) -- [SensorBaro](SensorBaro.md) +- [SensorBaro](SensorBaro.md) — Barometer sensor - [SensorCombined](SensorCombined.md) — Sensor readings in SI-unit form. These fields are scaled and offset-compensated where possible and do not change with board revisions and sensor updates. - [SensorCorrection](SensorCorrection.md) — Sensor corrections in SI-unit form for the voted sensor - [SensorGnssRelative](SensorGnssRelative.md) — GNSS relative positioning information in NED frame. The NED frame is defined as the local topological system at the reference station. +- [SensorGnssStatus](SensorGnssStatus.md) — Gnss quality indicators - [SensorGps](SensorGps.md) — GPS position in WGS84 coordinates. the field 'timestamp' is for the position & velocity (microseconds) - [SensorGyro](SensorGyro.md) @@ -258,6 +261,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m The topic will not be updated when the vehicle is armed - [SensorSelection](SensorSelection.md) — Sensor ID's for the voted sensors output on the sensor_combined topic. Will be updated on startup of the sensor module and when sensor selection changes +- [SensorTemp](SensorTemp.md) - [SensorUwb](SensorUwb.md) — UWB distance contains the distance information measured by an ultra-wideband positioning system, such as Pozyx or NXP Rddrone. - [SensorsStatus](SensorsStatus.md) — Sensor check metrics. This will be zero for a sensor that's primary or unpopulated. @@ -281,7 +285,7 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [UlogStreamAck](UlogStreamAck.md) — Ack a previously sent ulog_stream message that had the NEED_ACK flag set - [VehicleAcceleration](VehicleAcceleration.md) -- [VehicleAirData](VehicleAirData.md) +- [VehicleAirData](VehicleAirData.md) — Vehicle air data - [VehicleAngularAccelerationSetpoint](VehicleAngularAccelerationSetpoint.md) - [VehicleConstraints](VehicleConstraints.md) — Local setpoint constraints in NED frame setting something to NaN means that no limit is provided @@ -301,10 +305,14 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m - [YawEstimatorStatus](YawEstimatorStatus.md) - [AirspeedValidatedV0](AirspeedValidatedV0.md) - [ArmingCheckReplyV0](ArmingCheckReplyV0.md) +- [ArmingCheckRequestV0](ArmingCheckRequestV0.md) — Arming check request. - [BatteryStatusV0](BatteryStatusV0.md) — Battery status +- [ConfigOverridesV0](ConfigOverridesV0.md) — Configurable overrides by (external) modes or mode executors - [EventV0](EventV0.md) — this message is required here in the msg_old folder because other msg are depending on it Events interface - [HomePositionV0](HomePositionV0.md) — GPS home position in WGS84 coordinates. +- [RegisterExtComponentReplyV0](RegisterExtComponentReplyV0.md) +- [RegisterExtComponentRequestV0](RegisterExtComponentRequestV0.md) — Request to register an external component - [VehicleAttitudeSetpointV0](VehicleAttitudeSetpointV0.md) - [VehicleLocalPositionV0](VehicleLocalPositionV0.md) — Fused local position in NED. The coordinate system origin is the vehicle position at the time when the EKF2-module was started. diff --git a/docs/zh/neural_networks/index.md b/docs/zh/neural_networks/index.md new file mode 100644 index 0000000000..af62fb983d --- /dev/null +++ b/docs/zh/neural_networks/index.md @@ -0,0 +1,21 @@ +# Neural Network Control + +PX4 supports the following mechanisms for using neural networks for multirotor control: + +- [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) — A generic neural network module that you can modify to use different underlying neural network and training models and compile into the firmware. +- [RAPTOR: A Neural Network Module for Adaptive Quadrotor Control](../neural_networks/raptor.md) — An adaptive RL NN module that works well with different Quad configurations without additional training. + +Generally you will select the former if you wish to experiment with custom neural network architectures and train them using PyTorch or TensorFlow, and the latter if you want to use a pre-trained neural-network controller that works out-of-the-box (without training for your particular platform) or if you train your own policies using [RLtools](https://rl.tools). + +Note that both modules are experimental and provided for experimentation. +The table below provides more detail on the differences. + +| Use Case | [`mc_raptor`](../neural_networks/raptor.md) | [`mc_nn_control`](../neural_networks/mc_neural_network_control.md) | +| ---------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ | +| Pre-trained policy that adapts to any quadrotor without training | ✓ RAPTOR | ✘ | +| Train policy in PyTorch/TF | ✘ | ✓ TF Lite | +| Train policy in RLtools | ✓ | ✘ | +| Use manual control (remote) with NN policy | ✘ GPS/MoCap | ✓ Manual attitude commands | +| Load policy checkpoints from SD card | ✓ Upload via MAVLink FTP | ✘ Compiled into firmware | +| Offboard setpoints | ✓ MAVLink | ✘ | +| Internal Trajectory Generator | ✓ (Position, Lissajous) | ✘ | diff --git a/docs/zh/neural_networks/mc_neural_network_control.md b/docs/zh/neural_networks/mc_neural_network_control.md new file mode 100644 index 0000000000..8e0e94c327 --- /dev/null +++ b/docs/zh/neural_networks/mc_neural_network_control.md @@ -0,0 +1,123 @@ +# MC Neural Networks Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +The Multicopter Neural Network (NN) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) is an example module that allows you to experiment with using a pre-trained neural network on PX4. +It might be used, for example, to experiment with controllers for non-traditional drone morphologies, computer vision tasks, and so on. + +The module integrates a pre-trained neural network based on the [TensorFlow Lite Micro (TFLM)](./tflm.md) module. +The module is trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md) multicopter frame. +While the controller is fairly robust, and might work on other platforms, we recommend [Training your own Network](#training-your-own-network) if you use a different vehicle. +Note that after training the network you will need to update and rebuild PX4. + +TLFM is a mature inference library intended for use on embedded devices. +It has support for several architectures, so there is a high likelihood that you can build it for the board you want to use. +If not, there are other possible NN frameworks, such as [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) and [Executorch](https://pytorch.org/executorch-overview). + +This document explains how you can include the module in your PX4 build, and provides a broad overview of how it works. +The other documents in the section provide more information about the integration, allowing you to replace the NN with a version trained on different data, or even to replace the TLFM library altogether. + +:::tip +For more information, see the Masters thesis from which this module was created: [Deep Reinforcement Learning for Embedded Control Policies for Aerial Vehicles](https://nva.sikt.no/registration/019b26689144-efeebae8-84d6-4413-ad7f-9aceb4ff7374). + +In addition, the (Norwegian) website [A Neural Network Mode for PX4 on Embedded Flight Controllers](https://ntnu-arl.github.io/px4-nns/) has a youtube video and a workshop paper . +::: + +## Neural Network PX4 Firmware + +:::warning +This module requires Ubuntu 24.04 or newer (it is not supported in Ubuntu 22.04). +::: + +The module has been tested on a number of configurations, which can be build locally using the commands: + +```sh +make px4_sitl_neural +``` + +```sh +make px4_fmu-v6c_neural +``` + +```sh +make mro_pixracerpro_neural +``` + +You can add the module to other board configurations by modifying their `default.px4board file` configuration to include these lines: + +```sh +CONFIG_LIB_TFLM=y +CONFIG_MODULES_MC_NN_CONTROL=y +``` + +:::tip +The `mc_nn_control` module takes up roughly 50KB, and many of the `default.px4board file` are already close to filling all the flash on their boards. To make room for the neural control module you can remove the include statements for other modules, such as FW, rover, VTOL and UUV. +::: + +## Example Module Overview + +The example module replaces the entire controller structure as well as the control allocator, as shown in the diagram below: + +![neural_control](../../assets/advanced/neural_control.png) + +In the [controller diagram](../flight_stack/controller_diagrams.md) you can see the [uORB message](../middleware/uorb.md) flow. +We hook into this flow by subscribing to messages at particular points, using our neural network to calculate outputs, and then publishing them into the next point in the flow. +We also need to stop the module publishing the topic to be replaced, which is covered in [Neural Network Module: System Integration](nn_module_utilities.md) + +### Input + +The input can be changed to whatever you want. +Set up the input you want to use during training and then provide the same input in PX4. +In the Neural Control module the input is an array of 15 numbers, and consists of these values in this order: + +- [3] Local position error. (goal position - current position) +- [6] The first 2 rows of a 3 dimensional rotation matrix. +- [3] Linear velocity +- [3] Angular velocity + +All the input values are collected from uORB topics and transformed into the correct representation in the `PopulateInputTensor()` function. +PX4 uses the NED frame representation, while the Aerial Gym Simulator, in which the NN was trained, uses the ENU representation. +Therefore two rotation matrices are created in the function and all the inputs are transformed from the NED representation to the ENU one. + +![ENU-NED](../../assets/advanced/ENU-NED.png) + +ENU and NED are just rotation representations, the translational difference is only there so both can be seen in the same figure. + +### 输出 + +The output consists of 4 values, the motor forces, one for each motor. +These are transformed in the `RescaleActions()` function. +This is done because PX4 expects normalized motor commands while the Aerial Gym Simulator uses physical values. +So the output from the network needs to be normalized before they can be sent to the motors in PX4. + +The commands are published to the [ActuatorMotors](../msg_docs/ActuatorMotors.md) topic. +The publishing is handled in `PublishOutput(float* command_actions)` function. + +:::tip +If the neural control mode is too aggressive or unresponsive the [MC_NN_THRST_COEF](../advanced_config/parameter_reference.md#MC_NN_THRST_COEF) parameter can be tuned. +Decrease it for more thrust. +::: + +## Training your own Network + +The network is currently trained for the [X500 V2](../frames_multicopter/holybro_x500v2_pixhawk6c.md). +But the controller is somewhat robust, so it could work directly on other platforms, but performing system identification and training a new network is recommended. + +Since the Aerial Gym Simulator is open-source you can download it and train your own networks as long as you have access to an NVIDIA GPU. +If you want to train a control network optimized for your platform you can follow the instructions in the [Aerial Gym Documentation](https://ntnu-arl.github.io/aerial_gym_simulator/9_sim2real/). + +You should do one system identification flight for this and get an approximate inertia matrix for your platform. +On the `sys-id` flight you need ESC telemetry, you can read more about that in [DSHOT](../peripherals/dshot.md). + +Then do the following steps: + +- Do a hover flight +- Read of the logs what RPM is required for the drone to hover. +- Use the weight of each motor, length of the motor arms, total weight of the platform with battery to calculate an approximate inertia matrix for the platform. +- Insert these values into the Aerial Gym configuration and train your network. +- Convert the network as explained in [TFLM](tflm.md). diff --git a/docs/zh/neural_networks/nn_module_utilities.md b/docs/zh/neural_networks/nn_module_utilities.md new file mode 100644 index 0000000000..7c9054ed17 --- /dev/null +++ b/docs/zh/neural_networks/nn_module_utilities.md @@ -0,0 +1,86 @@ +# Neural Network Module: System Integration + +The neural control module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) implements an end-to-end controller utilizing neural networks. + +The parts of the module directly concerned with generating the code for the trained neural network and integrating it into the module are covered in [TensorFlow Lite Micro (TFLM)](./tflm.md). +This page covers the changes that were made to integrate the module into PX4, both within the module, and in larger system configuration. + +:::tip +This topic should help you to shape the module to your own needs. + +You will need some familiarity with PX4 development. +For more information see the developer [Getting Started](../dev_setup/getting_started.md). +::: + +## Autostart + +A line to autostart the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module has been added in the [`ROMFS/px4fmu_common/init.d/rc.mc_apps`](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rc.mc_apps) startup script. + +It checks whether the module is included by looking for the parameter [MC_NN_EN](../advanced_config/parameter_reference.md#MC_NN_EN). +If this is set to `1` (the default value), the module will be started when booting PX4. +Similarly you could create other parameters in the [`mc_nn_control_params.c`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/mc_nn_control_params.c) file for other startup script checks. + +## Custom Flight Mode + +The module creates its own flight mode "Neural Control" which lets you choose it from the flight mode menu in QGC and bind it to a switch on you RC controller. +This is done by using the [ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) internally. +This involves several steps and is visualized here: + +:::info +The module does not actually use ROS 2, it just uses the API exposed through uORB topics. +::: + +:::info +In some QGC versions the flight mode does not show up, so make sure to update to the newest version. +This only works for some flight controllers, so you might have to use an RC controller to switch to the correct external flight mode. +::: + +![neural_mode_registration](../../assets/advanced/neural_mode_registration.png) + +1. Publish a [RegisterExtComponentRequest](../msg_docs/RegisterExtComponentRequest.md). + This specifies what you want to create, you can read more about this in the [Control Interface](../ros2/px4_ros2_control_interface.md). + In this case we register an arming check and a mode. +2. Wait for a [RegisterExtComponentReply](../msg_docs/RegisterExtComponentReply.md). + This will give feedback on wether the mode registration was successful, and what the mode and arming check id is for the new mode. +3. [Optional] With the mode id, publish a [VehicleControlMode](../msg_docs/VehicleControlMode.md) message on the `config_control_setpoints` topic. + Here you can configure what other modules run in parallel. + The example controller replaces everything, so it turns off allocation. + If you want to replace other parts you can enable or disable the modules accordingly. +4. [Optional] With the mode id, publish a [ConfigOverrides](../msg_docs/ConfigOverrides.md) on the `config_overrides_request` topic. + (This is not done in the example module) This will let you defer failsafes or stop it from automatically disarming. +5. When the mode has been registered a [ArmingCheckRequest](../msg_docs/ArmingCheckRequest.md) will be sent, asking if your mode has everything it needs to run. + This message must be answered with a [ArmingCheckReply](../msg_docs/ArmingCheckReply.md) so the mode is not flagged as unresponsive. + In this response it is possible to set what requirements the mode needs to run, like local position. + If any of these requirements are set the commander will stop you from switching to the mode if they are not fulfilled. + It is also important to set health_component_index and num_events to 0 to not get a segmentation fault. + Unless you have a health component or events. +6. Listen to the [VehicleStatus](../msg_docs/VehicleStatus.md) topic. + If the nav_state equals the assigned `mode_id`, then the Neural Controller is activated. +7. When active the module will run the controller and publish to [ActuatorMotors](../msg_docs/ActuatorMotors.md). + If you want to replace a different part of the controller, you should find the appropriate topic to publish to. + +To see how the requests are handled you can check out [src/modules/commander/ModeManagement.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeManagement.cpp). + +## 日志 + +To add module-specific logging a new topic has been added to [uORB](../middleware/uorb.md) called [NeuralControl](../msg_docs/NeuralControl.md). +The message definition is also added in `msg/CMakeLists.txt`, and to [`src/modules/logger/logged_topics.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/logger/logged_topics.cpp) under the debug category. +For these messages to be saved in your logs you need to include `debug` in the [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) parameter. + +## Timing + +The module has two includes for measuring the inference times. +The first one is a driver that works on the actual flight controller units, but a second one, `chrono`, is loaded for SITL testing. +Which timing library is included and used is based on wether PX4 is built with NUTTX or not. + +## Changing the setpoint + +The module uses the [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message's position fields to define its target. +To follow a trajectory, you can send updated setpoints. +For an example of how to do this in a PX4 module, see the [mc_nn_testing](https://github.com/SindreMHegre/PX4-Autopilot-public/tree/main/src/modules/mc_nn_testing) module in this fork. +Note that this is not included in upstream PX4. +To use it, copy the module folder from the linked repository into your workspace, and enable it by adding the following line to your `.px4board` file: + +```sh +CONFIG_MODULES_MC_NN_TESTING=y +``` diff --git a/docs/zh/neural_networks/raptor.md b/docs/zh/neural_networks/raptor.md new file mode 100644 index 0000000000..e7b9c60d68 --- /dev/null +++ b/docs/zh/neural_networks/raptor.md @@ -0,0 +1,221 @@ +# RAPTOR: A Neural Network Module for Adaptive Quadrotor Control + + + +:::warning +This is an experimental module. +Use at your own risk. +::: + +RAPTOR is a tiny reinforcement-learning based neural network module for quadrotor control that can be used to control a wide variety of quadrotors without retuning. + +This topic provides an overview of the fundamental concepts, and explains how you can use the module in simulation and real hardware. + +## 综述 + +![Visual Abstract](../../assets/advanced/neural_networks/raptor/visual_abstract.jpg) + +RAPTOR is an adaptive policy for end-to-end quadrotor control. +It is motivated by the human ability to adapt learned behaviours to similar situations. +For example, while humans may initially require many hours of driving experience to be able to smoothly control the car and blend into traffic, when faced with a new vehicle they do not need to re-learn how to drive — they only need to experience a few rough braking/acceleration/steering responses to adjust their previously learned behavior. + +Reinforcement Learning (RL) is a machine learning technique that uses trial and error to learn decision making/control behaviors, which is similar to the way that humans learn to drive. +RL is interesting for controlling robots (and particularly UAVs) because it overcomes some fundamental limitations of classic, modular control architectures (information loss at module boundaries, requirement for expert tuning, etc). +RL has been very successful in [high-performance quadrotor flight](https://doi.org/10.1038/s41586-023-06419-4), but previous designs have not been particularly adaptable to new frames and vehicle types. + +RAPTOR fills this gap and demonstrates a single, tiny neural-network control policy that can control a wide variety of quadrotors (tested on real quadrotors from 32 g to 2.4 kg). + +For more details please refer to this video: + + + +The method we developed for training the RAPTOR policy is called Meta-Imitation Learning: + +![Diagram showing the Method Overview](../../assets/advanced/neural_networks/raptor/method.jpg) + +You can torture test the RAPTOR policy in your browser at [https://raptor.rl.tools](https://raptor.rl.tools) or in the embedded app here: + + + +For more information please refer to the paper at [https://arxiv.org/abs/2509.11481](https://arxiv.org/abs/2509.11481). + +## Structure + +The RAPTOR control policy is an end-to-end policy that takes position, orientation, linear velocity and angular velocity as inputs and outputs motor commands (`actuator_motors`). +To integrate it into PX4 we use the external mode registration facilities in PX4 (which also works well for internal modes as demonstrated in `mc_nn_control`). +Because of this architecture the `mc_raptor` module is completely decoupled from all other PX4 logic. + +By default, the RAPTOR module expects setpoints via `trajectory_setpoint` messages. +If no `trajectory_setpoint` messages are received or if no `trajectory_setpoint` is received within 200 ms, the current position and orientation (with zero velocity) is used as the setpoint. +Since feeding setpoints reliably via telemetry is still a challenge, we also implement a simple option to generate internal reference trajectories (controlled through the `MC_RAPTOR_INTREF` parameter) for demonstration and benchmarking purposes. + +## 特性 + +- Tiny neural network (just 2084 parameters) => minimal CPU usage +- Easily maintainable + - Simple CMake setup + - Self-contained (no interference with other modules) + - Single, simple and well-maintained dependency (RLtools) +- Loading neural network parameters from SD card + - Minimal flash usage (for possible inclusion into default build configurations) + - Easy development: Train new neural network and just upload it via MAVLink FTP without requiring to re-flash the firmware +- Tested on 10+ different real platforms (including flexible frames, brushed motors) +- Actively developed and maintained + +## 用法 + +### SITL + +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate + +```sh +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 # Enable the mc_raptor module +param save +``` + +Upload the RAPTOR checkpoint to the "SD card": Separate terminal + +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` + +Restart (Ctrl+C) + +```sh +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```sh +commander mode ext{RAPTOR_MODE_ID} +``` + +#### Internal Reference Trajectory Generation + +In our experience, feeding the `trajectory_setpoint` via MAVLink (even via WiFi telemetry) is unreliable. +But we do not want to constrain this module to only platforms that have a companion board. + +For this reason we have integrated a simple internal reference trajectory generator for testing and benchmarking purposes. +It supports position (constant position and yaw setpoint) as well as configurable [Lissajous trajectories](https://en.wikipedia.org/wiki/Lissajous_curve). + +The Lissajous generator can, for example, generate smooth figure-eight trajectories that contain interesting accelerations for benchmarking and testing purposes. +Please refer to the embedded configurator later in this section to explore the Lissajous parameters and view the resulting trajectories. + +To use the internal reference generator, select the mode: `0`: Off/activation position tracking, `1`: Lissajous + +```sh +param set MC_RAPTOR_INTREF 1 +``` + +Restart (ctrl+c) + +```sh +commander takeoff +commander mode ext{RAPTOR_MODE_ID} +mc_raptor intref lissajous 0.5 1 0 2 1 1 10 3 +``` + +The trajectory is relative to the position and yaw of the vehicle at the point where the RAPTOR mode is activated (or the position and yaw where the parameters are changed if it is already activated). + +You can adjust the parameters of the trajectory with the following tool. +Make sure to copy the generated CLI string at the end: + + + +### Real-World + +#### 设置 + +The `mc_raptor` module has been mostly tested with the Holybro X500 V2 but it should also work out-of-the-box with other platforms (see the [Other Platforms](#other-platforms) section). + +```sh +make px4_fmu-v6c_raptor upload +``` + +We recommend initially testing the RAPTOR mode using a dead man's switch. +For this we configure the mode selection to be connected to a push button or a switch with a spring that automatically switches back. +In the default position we configure e.g. `Stabilized Mode` and in the pressed configuration we select `External Mode 1` (since the name of the external mode is only transmitted at runtime). +This allows to take off manually and then just trigger the RAPTOR mode for a split-second to see how it behaves. +In our experiments it has been exceptionally stable (zero crashes) but we still think progressively activating it for longer is the safest way to build confidence. + +:::warning +Make sure that your platform uses the standard PX4 quadrotor motor layout: + +1: front-right, 2: back-left, 3: front-left, 4: back-right +::: + +##### Other Platforms + +To enable the `mc_raptor` module in other platforms, just add `CONFIG_MODULES_MC_RAPTOR=y` and `CONFIG_LIB_RL_TOOLS=y` + +```diff ++++ b/boards/px4/fmu-v6c/raptor.px4board +@@ -35,2 +35,3 @@ + CONFIG_DRIVERS_UAVCAN=y ++CONFIG_LIB_RL_TOOLS=y + CONFIG_MODULES_AIRSPEED_SELECTOR=y +@@ -64,2 +65,3 @@ + CONFIG_MODULES_MC_POS_CONTROL=y ++CONFIG_MODULES_MC_RAPTOR=y + CONFIG_MODULES_MC_RATE_CONTROL=y +``` + +#### Results + +Even though there were moderate winds (~ 5 m/s) during the test, we found good figure-eight tracking performance at velocities up to 12 m/s: + +![Lissajous](../../assets/advanced/neural_networks/raptor/results_figure_eight.svg) + +We also tested the linear velocity in a straight line and found that the RAPTOR policy can reliably fly at > 17 m/s (the wind direction was orthogonal to the line): + +![Linear Oscillation](../../assets/advanced/neural_networks/raptor/results_line.svg) + +### 故障处理 + +#### 日志 + +Use this logging configuration to log all relevant topics at maximum rate: + +```sh +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` + +Use mavproxy FTP to upload it: + +```sh +mavproxy.py +``` + +##### Real + +```sh +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +##### SITL + +```sh +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/docs/zh/neural_networks/tflm.md b/docs/zh/neural_networks/tflm.md new file mode 100644 index 0000000000..ce37aae59b --- /dev/null +++ b/docs/zh/neural_networks/tflm.md @@ -0,0 +1,77 @@ +# TensorFlow Lite Micro (TFLM) + +The PX4 [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md) module ([mc_nn_control](../modules/modules_controller.md#mc-nn-control)) integrates a neural network that uses the [TensorFlow Lite Micro (TFLM)](https://github.com/tensorflow/tflite-micro) inference library. + +This is a mature inference library intended for use on embedded devices, and is hence a suitable choice for PX4. + +This guide explains how the TFLM library is integrated into the [mc_nn_control](../modules/modules_controller.md#mc-nn-control) module, and the changes you would have to make to use it for your own neural network. + +:::tip +For more information, see the [TFLM guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). +::: + +## TLMF NN Formats + +TFLM uses networks in its own [tflite format](https://ai.google.dev/edge/litert/models/convert). +However, since many microcontrollers do not have native filesystem support, a tflite file can be converted to a C++ source and header file. + +This is what is done in `mc_nn_control`. +The tflight neural network is represented in code by the files [`control_net.cpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.cpp) and [`control_net.hpp`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_nn_control/control_net.hpp). + +### Getting a Network in tflite Format + +There are many online resource for generating networks in the `.tflite` format. + +For this example we trained the network in the open source [Aerial Gym Simulator](https://ntnu-arl.github.io/aerial_gym_simulator/). +Aerial Gym includes a guide, and supports RL both for control and vision-based navigation tasks. + +The project includes conversion code for `PyTorch -> TFLM` in the [resources/conversion](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/conversion) folder. + +### Updating `mc_nn_control` with your own NN + +You can convert a `.tflite` network into a `.cc` file in the ubuntu terminal with this command: + +```sh +xxd -i converted_model.tflite > model_data.cc +``` + +You will then have to modify the `control_net.hpp` and `control_net.cpp` to include the data from `model_data.cc`: + +- Take the size of the network in the bottom of the `.cc` file and replace the size in `control_net.hpp`. +- Take the data in the model array in the `cc` file, and replace the ones in `control_net.cpp`. + +You are now ready to run your own network. + +## Code Explanation + +This section explains the code used to integrate the NN in `control_net.cpp`. + +### Operations and Resolver + +Firstly we need to create the resolver and load the needed operators to run inference on the NN. +This is done in the top of `mc_nn_control.cpp`. +The number in `MicroMutableOpResolver<3>` represents how many operations you need to run the inference. + +A full list of the operators can be found in the [micro_mutable_op_resolver.h](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/micro_mutable_op_resolver.h) file. +There are quite a few supported operators, but you will not find the most advanced ones. +In the control example the network is fully connected so we use `AddFullyConnected()`. +Then the activation function is ReLU, and we `AddAdd()` for the bias on each neuron. + +### Interpreter + +In the `InitializeNetwork()` we start by setting up the model that we loaded from the source and header file. +Next is to set up the interpreter, this code is taken from the TFLM documentation and is thoroughly explained there. +The end state is that the `_control_interpreter` is set up to later run inference with the `Invoke()` member function. +The `_input_tensor` is also defined, it is fetched from `_control_interpreter->input(0)`. + +### 输入 + +The `_input_tensor` is filled in the `PopulateInputTensor()` function. +`_input_tensor` works by accessing the `->data.f` member array and fill in the required inputs for your network. +The inputs used in the control network is covered in [MC Neural Networks Control](../neural_networks/mc_neural_network_control.md). + +### Outputs + +For the outputs the approach is fairly similar to the inputs. +After setting the correct inputs, calling the `Invoke()` function the outputs can be found by getting `_control_interpreter->output(0)`. +And from the output tensor you get the `->data.f` array. diff --git a/docs/zh/payloads/generic_actuator_control.md b/docs/zh/payloads/generic_actuator_control.md index 03564f35ba..127d59c99f 100644 --- a/docs/zh/payloads/generic_actuator_control.md +++ b/docs/zh/payloads/generic_actuator_control.md @@ -60,7 +60,7 @@ To use a generic actuator in a mission: - Select the header on the waypoint mission editor to open the **Select Mission Command** editor. - Select the category **Advanced**, and then the **Set actuator** item (if the item is not present, try a more recent version of _QGroundControl_ or a daily build). - This will change the mission item type to "Set actuator". + This will change the mission item type to "Set actuator". 3. Select the actuators that are connected and set their values (these are normalized between -1 and 1). diff --git a/docs/zh/peripherals/adsb_flarm.md b/docs/zh/peripherals/adsb_flarm.md index ade37ae24b..36d2c728be 100644 --- a/docs/zh/peripherals/adsb_flarm.md +++ b/docs/zh/peripherals/adsb_flarm.md @@ -11,7 +11,7 @@ PX4 traffic avoidance works with ADS-B or FLARM products that supply transponder It has been tested with the following devices: - [PingRX ADS-B Receiver](https://uavionix.com/product/pingrx-pro/) (uAvionix) -- [FLARM](https://flarm.com/products/uav/atom-uav-flarm-for-drones/) +- [FLARM](https://www.flarm.com/en/drones/) ## 硬件安装 @@ -179,4 +179,4 @@ The method creates a simulated transponder message near the vehicle, using follo ## 更多信息 - [MAVLink Peripherals](../peripherals/mavlink_peripherals.md) -- [Serial Port Configuration](../peripherals/serial_configuration.md) +- [串口配置](../peripherals/serial_configuration.md) diff --git a/docs/zh/peripherals/dshot.md b/docs/zh/peripherals/dshot.md index a957c031ed..8ea59236a7 100644 --- a/docs/zh/peripherals/dshot.md +++ b/docs/zh/peripherals/dshot.md @@ -11,6 +11,10 @@ DShot is an alternative ESC protocol that has several advantages over [PWM](../p 本章介绍了如何连接和配置 DShot 电调。 +## Supported ESC + +[ESCs & Motors > Supported ESCs](../peripherals/esc_motors#supported-esc) has a list of supported ESC (check "Protocols" column for DShot ESC). + ## Wiring/Connections {#wiring} DShot ESC are wired the same way as [PWM ESCs](pwm_escs_and_servo.md). diff --git a/docs/zh/peripherals/esc_motors.md b/docs/zh/peripherals/esc_motors.md index 059374dd8b..c372d04192 100644 --- a/docs/zh/peripherals/esc_motors.md +++ b/docs/zh/peripherals/esc_motors.md @@ -3,80 +3,44 @@ Many PX4 drones use brushless motors that are driven by the flight controller via an Electronic Speed Controller (ESC). The ESC takes a signal from the flight controller and uses it to set control the level of power delivered to the motor. -PX4 supports a number of common protocols for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). +PX4 supports a number of [common protocols](../esc/esc_protocols.md) for sending the signals to ESCs: [PWM ESCs](../peripherals/pwm_escs_and_servo.md), [OneShot ESCs](../peripherals/oneshot.md), [DShot ESCs](../peripherals/dshot.md), [DroneCAN ESCs](../dronecan/escs.md), PCA9685 ESC (via I2C), and some UART ESCs (from Yuneec). + +## Supported ESC + +The following list is non-exhaustive. + +| ESC Device | Protocols | Firmwares | 备注 | +| ------------------------------ | ------------------------------------ | ------------------------ | ----------------------------------------------------- | +| [ARK 4IN1 ESC] | [Dshot], [PWM] | [AM32] | Has versions with/without connnectors | +| [Holybro Kotleta 20] | [DroneCAN], [PWM] | [PX4 Sapog ESC Firmware] | | +| [Vertiq Motor & ESC modules] | [Dshot], [OneShot], Multishot, [PWM] | Vertiq firmware | Larger modules support DroneCAN, ESC and Motor in one | +| [RaccoonLab CAN PWM ESC nodes] | [DroneCAN], Cyphal | | Cyphal and DroneCAN notes for PWM ESC | +| [VESC ESCs] | [DroneCAN], [PWM] | VESC project firmware | | +| [Zubax Telega] | [DroneCAN], [PWM] | Telega-based | ESC and Motor in one | + + + +[ARK 4IN1 ESC]: ../esc/ark_4in1_esc.md +[AM32]: https://am32.ca/ +[PX4 Sapog ESC Firmware]: ../dronecan/sapog.md +[VESC ESCs]: ../peripherals/vesc.md +[DroneCAN]: ../dronecan/escs.md +[Dshot]: ../peripherals/dshot.md +[OneShot]: ../peripherals/oneshot.md +[PWM]: ../peripherals/pwm_escs_and_servo.md +[Holybro Kotleta 20]: ../dronecan/holybro_kotleta.md +[Vertiq Motor & ESC modules]: ../peripherals/vertiq.md +[RaccoonLab CAN PWM ESC nodes]: ../dronecan/raccoonlab_nodes.md +[Zubax Telega]: ../dronecan/zubax_telega.md + +## 另见 有关详细信息,请参阅︰ +- [ESC Protocols](../esc/esc_protocols.md) — overview of main ESC/Servo protocols supported by PX4 - [PWM ESCs and Servos](../peripherals/pwm_escs_and_servo.md) - [OneShot ESCs and Servos](../peripherals/oneshot.md) - [DShot](../peripherals/dshot.md) - [DroneCAN ESCs](../dronecan/escs.md) - [ESC Calibration](../advanced_config/esc_calibration.md) - [ESC Firmware and Protocols Overview](https://oscarliang.com/esc-firmware-protocols/) (oscarliang.com) - -A high level overview of the main ESC/Servo protocols supported by PX4 is given below. - -## ESC Protocols - -### PWM - -[PWM ESCs](../peripherals/pwm_escs_and_servo.md) are commonly used for fixed-wing vehicles and ground vehicles (vehicles that require a lower latency like multicopters typically use oneshot or dshot ESCs). - -PWM ESCs communicate using a periodic pulse, where the _width_ of the pulse indicates the desired power level. -The pulse wdith typically ranges between 1000uS for zero power and 2000uS for full power. -The periodic frame rate of the signal depends on the capability of the ESC, and commonly ranges between 50Hz and 490 Hz (the theoretical maximum being 500Hz for a very small "off" cycle). -A higher rate is better for ESCs, in particular where a rapid response to setpoint changes is needed. -For PWM servos 50Hz is usually sufficient, and many don't support higher rates. - -![duty cycle for PWM](../../assets/peripherals/esc_pwm_duty_cycle.png) - -In addition to being a relatively slow protocol PWM ESCs require [calibration](../advanced_config/esc_calibration.md) because the range values representing low and high values can vary significantly. -Unlike [dshot](#dshot) and [DroneCAN ESC](#dronecan) they do not have the ability to provide telemetry and feedback on ESC (or servo) state. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) -- [PX4 Configuration](../peripherals/pwm_escs_and_servo.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### Oneshot 125 - -[OneShot 125 ESCs](../peripherals/oneshot.md) are usually much faster than PWM ESCs, and hence more responsive and easier to tune. -They are preferred over PWM for multicopters (but not as much as [DShot ESCs](#dshot), which do not require calibration, and may provide telemetry feedback). -There are a number of variants of the OneShot protocol, which support different rates. -PX4 only supports OneShot 125. - -OneShot 125 is the same as PWM but uses pulse widths that are 8 times shorter (from 125us to 250us for zero to full power). -This allows OneShot 125 ESCs to have a much shorter duty cycle/higher rate. -For PWM the theoretical maximum is close to 500 Hz while for OneShot it approaches 4 kHz. -The actual supported rate depends on the ESC used. - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [PX4 Configuration](../peripherals/oneshot.md#px4-configuration) -- [ESC Calibration](../advanced_config/esc_calibration.md) - -### DShot - -[DShot](../peripherals/dshot.md) is a digital ESC protocol that is highly recommended for vehicles that can benefit from reduce latency, in particular racing multicopters, VTOL vehicles, and so on. - -It has reduced latency and is more robust than both [PWM](#pwm) and [OneShot](#oneshot-125). -In addition it does not require ESC calibration, telemetry is available from some ESCs, and you can revers motor spin directions - -PX4 configuration is done in the [Actuator Configuration](../config/actuators.md). -Selecting a higher rate DShot ESC in the UI result in lower latency, but lower rates are more robust (and hence more suitable for large aircraft with longer leads); some ESCs only support lower rates (see datasheets for information). - -Setup: - -- [ESC Wiring](../peripherals/pwm_escs_and_servo.md) (same as for PWM ESCs) -- [DShot](../peripherals/dshot.md) also contains information about how to send commands etc. - -### DroneCAN - -[DroneCAN ESCs](../dronecan/escs.md) are recommended when DroneCAN is the primary bus used for your vehicle. -The PX4 implementation is currently limited to update rates of 200Hz. - -DroneCAN shares many similar benefits to [Dshot](#dshot) including high data rates, robust connection over long leads, telemetry feedback, no need for calibration of the ESC itself. - -[DroneCAN ESCs](../dronecan/escs.md) are connected via the DroneCAN bus (setup and configuration are covered at that link). diff --git a/docs/zh/peripherals/gripper.md b/docs/zh/peripherals/gripper.md index a3f0ebbc88..d655300a25 100644 --- a/docs/zh/peripherals/gripper.md +++ b/docs/zh/peripherals/gripper.md @@ -75,13 +75,13 @@ To set the actuation timeout: - Run the `payload_deliverer` test in the QGC [MAVLink Shell](../debug/mavlink_shell.md): - ```sh - > payload_deliverer gripper_test - ``` + ```sh + > payload_deliverer gripper_test + ``` - ::: info - If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. - You might also run the `payload_deliverer start` command in the Nuttx shell. + ::: info + If you get an error message like "[payload_deliverer] not running", repeat the setup procedures above. + You might also run the `payload_deliverer start` command in the Nuttx shell. ::: diff --git a/docs/zh/peripherals/mavlink_peripherals.md b/docs/zh/peripherals/mavlink_peripherals.md index ed88794411..b344857a2d 100644 --- a/docs/zh/peripherals/mavlink_peripherals.md +++ b/docs/zh/peripherals/mavlink_peripherals.md @@ -119,8 +119,8 @@ Links to setup instructions for specific MAVLink components: - [MAVLink Cameras (Camera Protocol v2) > PX4 Configuration](../camera/mavlink_v2_camera.md#px4-configuration) - [Gimbal Configuration > MAVLink Gimbal (MNT_MODE_OUT=MAVLINK)](../advanced/gimbal_control.md#mavlink-gimbal-mnt-mode-out-mavlink) -## See Also +## 另见 -- [Serial Port Configuration](../peripherals/serial_configuration.md) +- [串口配置](../peripherals/serial_configuration.md) - [PX4 Ethernet Setup > PX4 MAVLink Serial Port Configuration](../advanced_config/ethernet_setup.md#px4-mavlink-serial-port-configuration) -- [Serial Port Mapping](../hardware/serial_port_mapping.md) +- [串口映射](../hardware/serial_port_mapping.md) diff --git a/docs/zh/peripherals/remote_id.md b/docs/zh/peripherals/remote_id.md index 711a8e47e3..3cfc7bcde4 100644 --- a/docs/zh/peripherals/remote_id.md +++ b/docs/zh/peripherals/remote_id.md @@ -245,11 +245,11 @@ If the Remote ID CAN node is present and the messages are not being received, th 2. Navigate to the [Application settings](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/settings_view/general.html): **Application Settings > General > Miscellaneous**. 3. Select `Enable Remote ID`. - The Remote ID tab should appear. + The Remote ID tab should appear. - ::: info - If this option is not present you may be in a very recent version of QGC. - In that case, open the view at: **Application Settings > Remote ID**. + ::: info + If this option is not present you may be in a very recent version of QGC. + In that case, open the view at: **Application Settings > Remote ID**. ::: @@ -257,6 +257,6 @@ If the Remote ID CAN node is present and the messages are not being received, th Once configured, check the MAVLink Inspector again and check that the `OPEN_DRONE_ID_BASIC_ID` and `OPEN_DRONE_ID_LOCATION` messages are now present. -## See Also +## 另见 - [Remote Identification of Drones](https://www.faa.gov/uas/getting_started/remote_id) (FAA) diff --git a/docs/zh/peripherals/serial_configuration.md b/docs/zh/peripherals/serial_configuration.md index c77bb243a5..267d8c4d31 100644 --- a/docs/zh/peripherals/serial_configuration.md +++ b/docs/zh/peripherals/serial_configuration.md @@ -148,4 +148,4 @@ You will then need to build the firmware for your platform, as described in [Bui - [MAVLink Peripherals (OSD/GCS/Companion Computers/etc.)](../peripherals/mavlink_peripherals.md) - [PX4 Ethernet Setup > PX4 MAVLink Serial Port Configuration](../advanced_config/ethernet_setup.md#px4-mavlink-serial-port-configuration) -- [Serial Port Mapping](../hardware/serial_port_mapping.md) +- [串口映射](../hardware/serial_port_mapping.md) diff --git a/docs/zh/power_module/ark_12s_pab_power_module.md b/docs/zh/power_module/ark_12s_pab_power_module.md index 21c3e5ca77..4f262920bd 100644 --- a/docs/zh/power_module/ark_12s_pab_power_module.md +++ b/docs/zh/power_module/ark_12s_pab_power_module.md @@ -47,6 +47,6 @@ Order this module from: - Set the `INA238_SHUNT` parameter to 0.0001. - Reboot the flight controller. -## See Also +## 另见 - [ARK 12S PAB Power Module Documentation](https://arkelectron.gitbook.io/ark-documentation/power/ark-12s-pab-power-module) (ARK Docs) diff --git a/docs/zh/power_module/ark_12s_payload_power_module.md b/docs/zh/power_module/ark_12s_payload_power_module.md new file mode 100644 index 0000000000..8f809afd2c --- /dev/null +++ b/docs/zh/power_module/ark_12s_payload_power_module.md @@ -0,0 +1,56 @@ +# ARK 12S Payload Power Module + +The [ARK 12S Payload Power Module](https://arkelectron.com/product/ark-12s-payload-power-module/) is a dual 5V 6A and 12V 6A power supply and digital power monitor designed for the Pixhawk Autopilot Bus Carrier boards. + +This is similar to the [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) except that the additional 12V 6A supply allows easier powering of a payload. + +![ARK 12S Payload Power Module](../../assets/hardware/power_module/ark_power_modules//ark_12s_payload_power.jpg) + +## 购买渠道 + +Order this module from: + +- [ARK Electronics](https://arkelectron.com/product/ark-12s-payload-power-module/) (US) + +## Hardware Specifications + +- **TI INA238 Digital Power Monitor** + - 0.0001 Ohm Shunt + - I2C Interface + +- **5.2V 6A Step-Down Regulator** + - 10V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **12.0V 6A Step-Down Regulator** + - 15V Minimum Input Voltage at 6A Out + - Output Over-Current Protection + +- **75V Maximum Input Voltage** + +- **Connections** + - Solder Pads Battery Input + - Solder Pads Battery Output + - 6 Pin Molex CLIK-Mate Output + - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) + - 4 Pin Molex CLIK-Mate 12V Output + +- **Other** + - USA Built + - Includes 6 Pin Molex CLIK-Mate Cable + +- **Additional Information** + - Weight: 20.5 g + - Dimensions: 3.7 cm x 3.5 cm x 1.3 cm + +## PX4 Setup + +- Disable the `SENS_EN_INA226` parameter if it is enabled. +- Enable the `SENS_EN_INA238` parameter. +- Reboot the flight controller. +- Set the `INA238_SHUNT` parameter to 0.0001. +- Reboot the flight controller. + +## 另见 + +- [ARK 12S Payload Power Module Documentation](https://docs.arkelectron.com/power/ark-12s-payload-power-module) (ARK Docs) diff --git a/docs/zh/power_module/ark_pab_power_module.md b/docs/zh/power_module/ark_pab_power_module.md index 24bd243862..042e7aa826 100644 --- a/docs/zh/power_module/ark_pab_power_module.md +++ b/docs/zh/power_module/ark_pab_power_module.md @@ -6,35 +6,36 @@ Note that at 60A and 20°C without cooling, the 5V regulator is de-rated to a 3A ![ARK PAB Power Module](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_module.jpg) +This power module is also available without connectors: + +![ARK PAB Power Module No Connector](../../assets/hardware/power_module/ark_power_modules//ark_pab_power_no_connector.jpg) + ## 购买渠道 Order this module from: -- [ARK Electronics](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module](https://arkelectron.com/product/ark-pab-power-module/) (US) +- [ARK Electronics - ARK PAB Power Module No Connector](https://arkelectron.com/product/ark-pab-power-module-no-connector/) (US) ## Hardware Specifications - **TI INA226 Digital Power Monitor** - - 0.0005 Ohm Shunt - I2C Interface - **5.2V 6A Step-Down Regulator** - - 33V Maximum Input Voltage - 5.8V Minimum Input Voltage at 6A Out - Output Over-Voltage Protection - Output Over-Current Protection - **Connections** - - - XT60 Battery Input - - XT60 Battery Output + - XT60 Battery Input / Solder Pad Battery Input (No Connector version) + - XT60 Battery Output / Solder Pad Battery Output (No Connector version) - 6 Pin Molex CLIK-Mate Output - [Matches ARK PAB Carrier Power Pinout](https://arkelectron.gitbook.io/ark-documentation/flight-controllers/ark-pixhawk-autopilot-bus-carrier/pinout) - **Other** - - USA Built - FCC Compliant - Includes 6 Pin Molex CLIK-Mate Cable @@ -48,6 +49,6 @@ Order this module from: - Enable the SENS_EN_INA226 parameter if it not enabled. - Reboot the flight controller. -## See Also +## 另见 - [ARK PAB Power Module Documentation](https://arkelectron.gitbook.io/ark-documentation/power/ark-pab-power-module) (ARK Docs) diff --git a/docs/zh/power_module/holybro_pm02d.md b/docs/zh/power_module/holybro_pm02d.md index 1de3c25724..5660abda66 100644 --- a/docs/zh/power_module/holybro_pm02d.md +++ b/docs/zh/power_module/holybro_pm02d.md @@ -49,6 +49,6 @@ For this module you must instead enable parameter [SENS_EN_INA226](../advanced_c Note that the current divider and voltage divider should not be set in the [Battery Configuration](../config/battery.md) (the default values are accurate within 5%). -## See Also +## 另见 - [Digital Power Module (PM) Setup](https://docs.holybro.com/power-module-and-pdb/power-module/digital-power-module-pm-setup#px4-setup) (Manufacturer guide) diff --git a/docs/zh/power_module/index.md b/docs/zh/power_module/index.md index 0c11f625f0..d8df4ce2ec 100644 --- a/docs/zh/power_module/index.md +++ b/docs/zh/power_module/index.md @@ -27,6 +27,7 @@ This section provides information about a number of power modules and power dist - Digital (I2C) voltage and current power modules (for Pixhawk FMUv6X and FMUv5X derived controllers): - [ARK PAB Power Module](../power_module/ark_pab_power_module.md) - [ARK 12S PAB Power Module](../power_module/ark_12s_pab_power_module.md) + - [ARK 12S Payload Power Module](../power_module/ark_12s_payload_power_module.md) - [Holybro PM02D](../power_module/holybro_pm02d.md) - [Holybro PM03D](../power_module/holybro_pm03d.md) - [DroneCAN](../dronecan/index.md) power modules diff --git a/docs/zh/releases/1.14.md b/docs/zh/releases/1.14.md index e240b36709..bf1e8982e4 100644 --- a/docs/zh/releases/1.14.md +++ b/docs/zh/releases/1.14.md @@ -72,18 +72,18 @@ For users upgrading from previous versions, please take a moment to review the f 1. The actuator changes require you to verify vehicle geometry and motors/servos mappings match your vehicle. In QGC, find the [Actuator Configuration Dashboard](../config/actuators.md), and make sure to confirm the airframe geometry matches actuals from your vehicle, as well as update motor and ensure motors and servos are mapped to outputs as they are wired to the frame and with the correct ESC type specified. Note: take advantage of the sliders in the UI. They can be used to confirm motor wiring. - We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). + We highly recommend running an [ESC Calibration](../advanced_config/esc_calibration.md) if using PWM ESC motors and then setting appropriate disarmed minimum and maximum values for the motors (in the actuator UI). - The calibration is critical if you are using a custom mixer file or the airframe you assigned in an earlier version is not present in PX4 v1.14. + The calibration is critical if you are using a custom mixer file or the airframe you assigned in an earlier version is not present in PX4 v1.14. - However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. + However, an ESC Calibration is still recommended **even if** you are using an airframe that precisely matches a specific vehicle in the [Airframe Reference](../airframes/airframe_reference.md) (such as the [Holybro X500 V2](../airframes/airframe_reference.md#copter_quadrotor_x_holybro_x500_v2)) as your wiring and ESCs calibration may not match the defaults. 2. Default disarmed PWM was changed from 900us to 1000us. - Verify if you previously used the default PWM disarmed values and if the changes impact your setup. - For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. + Verify if you previously used the default PWM disarmed values and if the changes impact your setup. + For details, you can find related information in the [step 7 of ESC calibration](../advanced_config/esc_calibration.md#steps) document. 3. Fast-RTPS users must port their code to the new uXRCE-DDS interface. - Application code should only require minor modifications. These include (minimally): + Application code should only require minor modifications. These include (minimally): Modifying topic names to match the new naming pattern, which changed from `fmu//out` to `fmu/out/`, and [Adusting the QoS settings](../ros2/user_guide.md#ros-2-subscriber-qos-settings). diff --git a/docs/zh/releases/1.16.md b/docs/zh/releases/1.16.md index fee1f6288f..66b64f9f5b 100644 --- a/docs/zh/releases/1.16.md +++ b/docs/zh/releases/1.16.md @@ -151,6 +151,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### uXRCE-DDS / ROS2 - [PX4-Autopilot#24113](https://github.com/PX4/PX4-Autopilot/pull/24113): [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to translate PX4 messages from one definition version to another dynamically +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [ROS-based waypoint missions](../ros2/px4_ros2_waypoint_missions.md). - dds_topics: add vtol_vehicle_status ([PX4-Autopilot#24582](https://github.com/PX4/PX4-Autopilot/pull/24582)) - dds_topics: add home_position ([PX4-Autopilot#24583](https://github.com/PX4/PX4-Autopilot/pull/24583)) diff --git a/docs/zh/releases/1.17.md b/docs/zh/releases/1.17.md new file mode 100644 index 0000000000..1d32628731 --- /dev/null +++ b/docs/zh/releases/1.17.md @@ -0,0 +1,134 @@ +# PX4-Autopilot v1.17.0 Release Notes + + + + + +
+
+

This page is on a release branch, and hence probably out of date. See the latest version.

+
+
+ +This contains changes to PX4 planned for PX4 v1.17 (since the last major release [PX v1.16](../releases/1.16.md)). + +:::warning +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in PX4 v1.17 release. +New features that are not expected to go into the v1.17 release are in [PX4-Autopilot `main` Release Notes](../releases/main.md). +::: + +## Read Before Upgrading + +TBD … + +Please continue reading for [upgrade instructions](#upgrade-guide). + +## Major Changes + +- TBD + +## Upgrade Guide + +## Other changes + +### Hardware Support + +- **[New Hardware]** boards: [MicoAir743-Lite FC](../flight_controller/micoair743-lite.md) +- **[New Hardware]** boards: [RadiolinkPIX6 FC](../flight_controller/radiolink_pix6.md) +- **[New Hardware]** boards: [AP-H743-R1 FC](../flight_controller/x-mav_ap-h743r1.md) + + + +### Control + + + +- [MC Neural Network Module](../advanced/neural_networkss.md) + +### Estimation + +- TBD + + + +### 仿真 + +- Overhaul rover simulation: + - Add synthetic differential rover model: [PX4-gazebo-models#107](https://github.com/PX4/PX4-gazebo-models/pull/107) + - Add synthetic mecanum rover model: [PX4-gazebo-models#113](https://github.com/PX4/PX4-gazebo-models/pull/113) + - Update synthetic ackermann rover model: [PX4-gazebo-models#117](https://github.com/PX4/PX4-gazebo-models/pull/117) + +- [Simulation-in-Hardware (SIH)](../sim_sih/index.md#compatibility) + - New simulation: MC Hexacopter X + - New simulation: Ackermann Rover + +### Debug & Logging + +- TBD + +### Ethernet + +- TBD + +### uXRCE-DDS / Zenoh / ROS2 + +- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_control_interface.md) support for [Fixed Wing lateral/longitudinal setpoint](../ros2/px4_ros2_control_interface.md#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype) (`FwLateralLongitudinalSetpointType`) and [VTOL transitions](../ros2/px4_ros2_control_interface.md#controlling-a-vtol). ([PX4-Autopilot#24056](https://github.com/PX4/PX4-Autopilot/pull/24056)). +- [UXRCE_DDS: Simple index based namespace (UXRCE_DDS_NS_IDX)](../middleware/uxrce_dds.md#customizing-the-namespace) +- [Zenoh (PX4 ROS 2 rmw_zenoh)](../middleware/zenoh.md) + +### MAVLink + +- TBD + + + +### 垂直起降 + +- TBD + +### Fixed-wing + +- [Fixed Wing Takeoff mode](../flight_modes_fw/takeoff.md) will now keep climbing with level wings on position loss. + A target takeoff waypoint can be set to control takeoff course and loiter altitude. ([PX4-Autopilot#25083](https://github.com/PX4/PX4-Autopilot/pull/25083)). +- Automatically suppress angular rate oscillations using [Gain compression](../features_fw/gain_compression.md). ([PX4-Autopilot#25840: FW rate control: add gain compression algorithm](https://github.com/PX4/PX4-Autopilot/pull/25840)) + +### 无人车 + +- Removed deprecated rover module ([PX4-Autopilot#25054](https://github.com/PX4/PX4-Autopilot/pull/25054)). +- Add support for [Apps & API](../flight_modes_rover/api.md) including [Rover Setpoints](../ros2/px4_ros2_control_interface.md#rover-setpoints) ([PX4-Autopilot#25074](https://github.com/PX4/PX4-Autopilot/pull/25074), [PX4-ROS2-Interface-Lib#140](https://github.com/Auterion/px4-ros2-interface-lib/pull/140)). +- Update [rover simulation](../frames_rover/index.md#simulation) ([PX4-Autopilot#25644](https://github.com/PX4/PX4-Autopilot/pull/25644)) (see [Simulation](#simulation) release note for details). + +### ROS 2 + +- TBD diff --git a/docs/zh/releases/index.md b/docs/zh/releases/index.md index e8c4dcc49e..1e07e34cde 100644 --- a/docs/zh/releases/index.md +++ b/docs/zh/releases/index.md @@ -2,7 +2,8 @@ 这是一份 PX4 发行说明列表,其中包含每次发布所做更改的清单,详细说明了新增功能、漏洞修复、弃用内容以及更新情况。 -- [main](../releases/main.md) (changes since v1.16) +- [main](../releases/main.md) (changes planned for v1.18 or later) +- [v1.17](../releases/1.17.md) (changes planned for v1.17, since v1.16) - [v1.16](../releases/1.16.md) - [v1.15](../releases/1.15.md) - [v1.14](../releases/1.14.md) diff --git a/docs/zh/releases/main.md b/docs/zh/releases/main.md index 47f39e4554..b8a4d4a467 100644 --- a/docs/zh/releases/main.md +++ b/docs/zh/releases/main.md @@ -16,13 +16,13 @@ const { site } = useData(); This contains changes to PX4 `main` branch since the last major release ([PX v1.16](../releases/1.16.md)). :::warning -PX4 v1.16 is in candidate-release testing, pending release. -Update these notes with features that are going to be in `main` but not the PX4 v1.16 release. +PX4 v1.17 is in alpha/beta testing. +Update these notes with features that are going to be in `main` (PX4 v1.18 or later) but not the PX4 v1.17 release. ::: ## Read Before Upgrading -TBD … +- TBD … Please continue reading for [upgrade instructions](#upgrade-guide). @@ -44,7 +44,8 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Control -- TBD +- Added new flight mode(s): [Altitude Cruise (MC)](../flight_modes_mc/altitude_cruise.md), Altitude Cruise (FW). + For fixed-wing the mode behaves the same as Altitude mode but you can disable the manual control loss failsafe. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### Estimation @@ -52,27 +53,52 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### 传感器 -- TBD +- Add [sbgECom INS driver](../sensor/sbgecom.md) ([PX4-Autopilot#24137](https://github.com/PX4/PX4-Autopilot/pull/24137)) +- Quick magnetometer calibration now supports specifying an arbitrary initial heading ([PX4-Autopilot#24637](https://github.com/PX4/PX4-Autopilot/pull/24637)) ### 仿真 - TBD + + +### Debug & Logging + +- [Asset Tracking](../debug/asset_tracking.md): Automatic tracking and logging of external device information including vendor name, firmware and hardware version, serial numbers. Currently supports DroneCAN devices. ([PX4-Autopilot#25617](https://github.com/PX4/PX4-Autopilot/pull/25617)) + ### Ethernet - TBD -### uXRCE-DDS / ROS2 +### uXRCE-DDS / Zenoh / ROS2 + +- TBD + + ### MAVLink - TBD +### RC + +- Parse ELRS Status and Link Statistics TX messages in the CRSF parser. + ### Multi-Rotor -- TBD +- Removed parameters `MPC_{XY/Z/YAW}_MAN_EXPO` and use default value instead, as they were not deemed necessary anymore. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). +- Renamed `MPC_HOLD_DZ` to `MAN_DEADZONE` to have it globally available in modes that allow for a dead zone. ([PX4-Autopilot#25435: Add new flight mode: Altitude Cruise](https://github.com/PX4/PX4-Autopilot/pull/25435)). ### 垂直起降 @@ -80,12 +106,25 @@ Please continue reading for [upgrade instructions](#upgrade-guide). ### Fixed-wing +- TBD + + ### 无人车 +- TBD + + ### ROS 2 diff --git a/docs/zh/ros/mavros_custom_messages.md b/docs/zh/ros/mavros_custom_messages.md index ed4f017440..946ab08715 100644 --- a/docs/zh/ros/mavros_custom_messages.md +++ b/docs/zh/ros/mavros_custom_messages.md @@ -110,7 +110,7 @@ Follow _Source Installation_ instructions from [mavlink/mavros](https://github.c - `PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0` - `workspace/src/mavlink/message_definitions/v1.0` - are exactly the same. + are exactly the same. ::: diff --git a/docs/zh/ros/mavros_installation.md b/docs/zh/ros/mavros_installation.md index 26add434e3..6568e755d3 100644 --- a/docs/zh/ros/mavros_installation.md +++ b/docs/zh/ros/mavros_installation.md @@ -148,21 +148,21 @@ Now you are ready to do the build: 2. 安装MAVROS最新的版本: - 发行版 / 稳定版 - ```sh - rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream mavros | tee -a /tmp/mavros.rosinstall + ``` - Latest source - ```sh - rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall - ``` + ```sh + rosinstall_generator --upstream-development mavros | tee -a /tmp/mavros.rosinstall + ``` - ```sh - # For fetching all the dependencies into your catkin_ws, - # just add '--deps' to the above scripts, E.g.: - # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall - ``` + ```sh + # For fetching all the dependencies into your catkin_ws, + # just add '--deps' to the above scripts, E.g.: + # rosinstall_generator --upstream mavros --deps | tee -a /tmp/mavros.rosinstall + ``` 3. Create workspace & deps @@ -201,7 +201,7 @@ The [MAVROS Offboard Example (C++)](../ros/mavros_offboard_cpp.md), will show yo If you have an example app using the PX4 Autopilot and MAVROS, we can help you get it on our docs. ::: -## See Also +## 另见 - [mavros ROS Package Summary](https://wiki.ros.org/mavros#mavros.2BAC8-Plugins.sys_status) - [mavros source](https://github.com/mavlink/mavros/) diff --git a/docs/zh/ros/offboard_control.md b/docs/zh/ros/offboard_control.md index ddb3d1caff..48cc2bf339 100644 --- a/docs/zh/ros/offboard_control.md +++ b/docs/zh/ros/offboard_control.md @@ -38,9 +38,9 @@ Enable MAVLink on the serial port that you connect to the companion computer (se 1. 一端连接飞控的 UART 2. 一端连接地面站电脑 - 参考电台包括: + 参考电台包括: - - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) + - [Digi International XBee Pro](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules/sub-1-ghz-rf-modules) [![Mermaid graph: mavlink channel](https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVEQ7XG4gIGduZFtHcm91bmQgU3RhdGlvbl0gLS1NQVZMaW5rLS0-IHJhZDFbR3JvdW5kIFJhZGlvXTtcbiAgcmFkMSAtLVJhZGlvUHJvdG9jb2wtLT4gcmFkMltWZWhpY2xlIFJhZGlvXTtcbiAgcmFkMiAtLU1BVkxpbmstLT4gYVtBdXRvcGlsb3RdOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9) diff --git a/docs/zh/ros2/index.md b/docs/zh/ros2/index.md index 25e075eaf8..0e35981d71 100644 --- a/docs/zh/ros2/index.md +++ b/docs/zh/ros2/index.md @@ -1,45 +1,45 @@ # ROS 2 -[ROS 2](https://docs.ros.org/en/humble/#) is a powerful general purpose robotics library that can be used with the PX4 Autopilot to create powerful drone applications. +[ROS 2](https://docs.ros.org/en/humble/#)是一款功能强大的通用机器人开发库,可与 PX4 自动驾驶仪搭配使用,以开发功能丰富的无人机应用程序。 :::warning -Tip -The PX4 development team highly recommend that you use/migrate to this version of ROS! +小提示 +PX4 开发团队强烈建议您使用此 ROS 版本,或将现有系统迁移至此 ROS 版本! -This is the newest version of [ROS](https://www.ros.org/) (Robot Operating System). -It significantly improves on ROS "1", and in particular allows a much deeper and lower-latency integration with PX4. +这是最新版本的 [ROS](https://www.ros.org/)(机器人操作系统)。 +它在 ROS “1” 的基础上进行了显著改进,尤其能够实现与 PX4 更深度、更低延迟的集成。 ::: -ROS得益于一个活跃的生态系统,在这个生态系统里,开发者会解决常见的机器人问题,他们也有权使用为Linux编写的其他软件库。 -It can be used, for example, for [computer vision](../computer_vision/index.md) solutions. +ROS的优势在于拥有活跃的开发者生态系统 —— 该生态系统致力于解决各类常见的机器人技术问题,同时还能调用其他为 Linux 系统编写的软件库。 +例如,它可以用于 [计算机试图](../computer_vision/index.md) 解决问题。 -ROS 2 enables a very deep integration with PX4, to the extent that you can create flight modes in ROS 2 that are indistinguisable from internal PX4 modes, and directly read from and write to internal uORB topics at high rate. -It is recommended (in particular) for control and communication from a companion computer where low latency is important, when leveraging existing libraries from Linux, or when writing new high level flight modes. +ROS 2 能够实现与 PX4 极深度的集成,你可以在 ROS 2 中创建飞行模式,这些模式与 PX4 内部原生飞行模式毫无区别;同时还能以高速率直接读取和写入 PX4 内部的 uORB 主题。 +(尤其)建议在以下场景中使用:从伴飞计算机进行控制与通信(且低延迟至关重要时)、需借助 Linux 系统的现有库时,或编写新的高级飞行模式时。 -Communication between ROS 2 and PX4 uses middleware that implements the [XRCE-DDS protocol](../middleware/uxrce_dds.md). -This middleware exposes PX4 [uORB messages](../msg_docs/index.md) as ROS 2 messages and types, effectively allowing direct access to PX4 from ROS 2 workflows and nodes. +ROS 2 与 PX4 之间的通信使用的中间件需实现 [XRCE-DDS protocol](../middleware/uxrce_dds.md). +这个中间件将以 ROS 2 消息和类型显示 PX4 [uORB messages](../msg_docs/index.md) 会转换为 ROS 2 消息和数据类型,从而切实支持从 ROS 2 工作流与节点直接访问 PX4。 中间件使用 uORB 消息定义生成代码来序列化和反序列化来处理PX4 的收发消息。 -These same message definitions are used in ROS 2 applications to allow the messages to be interpreted. +这些相同的消息定义也用于 ROS 2 应用程序中以便能够解析这些消息。 :::info -ROS 2 can also connect with PX4 using [MAVROS](https://github.com/mavlink/mavros/tree/ros2/mavros) instead of XRCE-DDS. -This option is supported by the MAVROS project (it is not documented here). +ROS 2 也可以使用 [MAVROS](https://github.com/mavlink/mavros/tree/ros2/mavros)而不是 XRCE-DDS连接到 PX4。 +该选项受 MAVROS 项目支持(本文档未对此进行说明)。 ::: -To use the [ROS 2](../ros2/user_guide.md) over XRCE-DDS effectively, you must (at time of writing) have a reasonable understanding of the PX4 internal architecture and conventions, which differ from those used by ROS. +要通过 XRCE-DDS 有效使用 [ROS 2](../ros2/user_guide.md) ,(在撰写本文时)你必须对 PX4 的内部架构及约定有一定了解,而这些架构与约定和 ROS 所使用的存在差异。 我们计划近期提供ROS 2 API 以对 PX4 的特性进行封装,并举例说明它们的用途。 ## Topics 本节的主要主题是: -- [ROS 2 User Guide](../ros2/user_guide.md): A PX4-centric overview of ROS 2, covering installation, setup, and how to build ROS 2 applications that communicate with PX4. -- [ROS 2 Offboard Control Example](../ros2/offboard_control.md): A C++ tutorial examples showing how to do position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. -- [ROS 2 Multi Vehicle Simulation](../ros2/multi_vehicle.md): Instructions for connecting to multipole PX4 simulations via single ROS 2 agent. -- [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md): A C++ library that simplies interacting with PX4 from ROS 2. - Can be used to create and register flight modes wrtten using ROS2 and send position estimates from ROS2 applications such as a VIO system. -- [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md): A ROS 2 message translation node that enables communcation between PX4 and ROS 2 applications that were compiled with different sets of messages versions. +- [ROS 2 用户指南](../ros2/user_guide.md): PX4 视角下的 ROS 2,包括安装、设置和如何构建与 PX4 通信的 ROS 2 应用。 +- [ROS 2 离板控制实例](../ros2/offboard_control.md):一个 C++ 教程示例显示如何在 [离板模式] (../flight_modes/offboard.md) 中使用 ROS 2 节点进行位置控制。 +- [ROS 2 多载具模拟](../ros2/multi_vehicle.md):通过单独的ROS2 代理商连接到多极PX4 模拟的说明。 +- [PX4 ROS2 接口库](../ros2/px4_ros2_interface_lib.md):一个C++ 库,它与ROS2的 PX4 交互。 + 可以使用 ROS 2 创建和注册飞行模式,并从 ROS2 应用程序如VIO 系统发送位置估计数。 +- [ROS 2 消息翻译节点](../ros2/px4_ros2_msg_translation_node.md):一个 ROS 2 消息翻译节点,它允许在 PX4 和 ROS 2 应用程序之间共享,这些应用程序被编译成不同的消息版本。 ## 更多信息 -- [XRCE-DDS (PX4-ROS 2/DDS Bridge)](../middleware/uxrce_dds.md): PX4 middleware for connecting to ROS 2. +- [XRCE-DDS (PX4-ROS 2/DDS Bridge)](../middleware/uxrce_dds.md): PX4 使用中间件链接到 ROS 2。 diff --git a/docs/zh/ros2/multi_vehicle.md b/docs/zh/ros2/multi_vehicle.md index 9af8e2a777..16f02d9deb 100644 --- a/docs/zh/ros2/multi_vehicle.md +++ b/docs/zh/ros2/multi_vehicle.md @@ -1,42 +1,42 @@ -# Multi-Vehicle Simulation with ROS 2 +# 使用 ROS 2 的多载具模拟 -[XRCE-DDS](../middleware/uxrce_dds.md) allows for multiple clients to be connected to the same agent over UDP. -This is particular useful in simulation as only one agent needs to be started. +[XRCE-DDS](../middleware/uxrce_dds.md)支持多个客户端通过 UDP 协议连接到同一个代理。 +这在模拟中特别有用,因为只有一个代理需要启动。 -## Setup and Requirements +## 设置和要求 -The only requirements are +唯一的要求是 -- To be able to run [multi-vehicle simulation](../simulation/multi-vehicle-simulation.md) without ROS 2 with the desired simulator ([Gazebo](../sim_gazebo_gz/multi_vehicle_simulation.md), [Gazebo Classic](../sim_gazebo_classic/multi_vehicle_simulation.md#multiple-vehicle-with-gazebo-classic), [FlightGear](../sim_flightgear/multi_vehicle.md) and [JMAVSim](../sim_jmavsim/multi_vehicle.md)). -- To be able to use [ROS 2](../ros2/user_guide.md) in a single vehicle simulation. +- 能够在不依赖 ROS 2 的情况下,使用所需的仿真器([Gazebo](../sim_gazebo_gz/multi_vehicle_simulation.md), [Gazebo Classic](../sim_gazebo_classic/multi_vehicle_simulation.md#multiple-vehicle-with-gazebo-classic), [FlightGear](../sim_flightgear/multi_vehicle.md) and [JMAVSim](../sim_jmavsim/multi_vehicle.md))运行多载具模拟 [multi-vehicle simulation](../simulation/multi-vehicle-simulation.md) 。 +- 能够在单一载具模拟中使用 [ROS 2](../ros2/user_guide.md) -## Principle of Operation +## 工作原理 -In simulation each PX4 instance receives a unique `px4_instance` number starting from `0`. -This value is used to assign a unique value to [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): +在模拟中,每个 PX4 实例都会获得一个唯一的`px4_instance`编号,编号从`0`开始。 +该值用于为 [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY)分配一个唯一值: ```sh -param set UXRCE_DDS_KEY $((px4_instance+1)) +参数设置UXRCE_DDS_KEY $((px4_instance+1)) ``` :::info -By doing so, `UXRCE_DDS_KEY` will always coincide with [MAV_SYS_ID](../advanced_config/parameter_reference.md#MAV_SYS_ID). +通过这种方式, `UXRCE_DDS_KEY` 将始终与 [MAV_SYS_ID] 保持一致(../advanced_config/parameter_reference.md#MAV_SYS_ID) ::: -Moreover, when `px4_instance` is greater than zero, a unique ROS 2 [namespace prefix](../middleware/uxrce_dds.md#customizing-the-namespace) in the form `px4_$px4_instance` is added: +此外,当 `px4_instance` 大于 0 时,会添加一个格式为 `px4_$px4_instance` 的唯一 ROS 2[namespace prefix](../middleware/uxrce_dds.md#customizing-the-namespace): ```sh uxrce_dds_ns="-n px4_$px4_instance" ``` :::info -The environment variable `PX4_UXRCE_DDS_NS`, if set, will override the namespace behavior described above. +环境变量`PX4_UXRCE_DDS_NS` 若已设置,将覆盖上文所述的命名空间行为。 ::: -The first instance (`px4_instance=0`) does not have an additional namespace in order to be consistent with the default behavior of the `xrce-dds` client on a real vehicle. -This mismatch can be fixed by manually using `PX4_UXRCE_DDS_NS` on the first instance or by starting adding vehicles from index `1` instead of `0` (this is the default behavior adopted by [sitl_multiple_run.sh](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/simulation/gazebo-classic/sitl_multiple_run.sh) for Gazebo Classic). +第一个实例(`px4_instance=0`)没有额外的命名空间,此举是为了与真实载具上 xrce-dds 客户端的默认行为保持一致。 +这种不匹配可以通过手动使用 `PX4_UXRCE_DDS_NS` 来修复,或者通过从索引 `1` 中添加车辆而不是 `0` (这是Gazebo Classic的 [sitl_multiple_run.sh](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/simulation/gazebo-classic/sitl_multiple_run.sh) 的默认行为)。 -The default client configuration in simulation is summarized as follows: +模拟中的默认客户端配置概述如下: | `PX4_UXRCE_DDS_NS` | `px4_instance` | `UXRCE_DDS_KEY` | client namespace | | ------------------ | -------------- | ---------------- | --------------------- | @@ -45,10 +45,10 @@ The default client configuration in simulation is summarized as follows: | not provided | > 0 | `px4_instance+1` | `px4_${px4_instance}` | | provided | > 0 | `px4_instance+1` | `PX4_UXRCE_DDS_NS` | -## Adjusting the `target_system` value +## 调整 `target_system` 值 -PX4 accepts [VehicleCommand](../msg_docs/VehicleCommand.md) messages only if their `target_system` field is zero (broadcast communication) or coincides with `MAV_SYS_ID`. -In all other situations, the messages are ignored. -Therefore, when ROS 2 nodes want to send `VehicleCommand` to PX4, they must ensure that the messages are filled with the appropriate `target_system` value. +PX4 只在他们的 `target_system` 字段为 0`(路由通信) 或与`MAV_SYS_ID` 一致时,才接受[VehicleCommand](../msg_docs/VehicleCommand.md)。 +在所有其他情况下,信息都被忽视。 +因此,当 ROS 2 节点需向 PX4 发送`VehicleCommand`消息时,必须确保消息中填写了合适的`target_system\`字段值。 -For example, if you want to send a command to your third vehicle, which has `px4_instance=2`, you need to set `target_system=3` in all your `VehicleCommand` messages. +例如,若你想向 `px4_instance=2` 的第三台飞行器发送指令,则需要在所有`VehicleCommand`消息中设置 `target_system=3`。 diff --git a/docs/zh/ros2/offboard_control.md b/docs/zh/ros2/offboard_control.md index 438b02df09..07945ac9ea 100644 --- a/docs/zh/ros2/offboard_control.md +++ b/docs/zh/ros2/offboard_control.md @@ -1,11 +1,11 @@ # ROS 2 Offboard 控制示例 -The following C++ example shows how to do position control in [offboard mode](../flight_modes/offboard.md) from a ROS 2 node. +以下的 C++ 示例展示了如何在[offboard mode](../flight_modes/offboard.md) 中从 ROS 2 节点进行多轴位置控制。 示例将首先发送设置点、进入offboard模式、解锁、起飞至5米,并悬停等待。 虽然简单,但它显示了如何使用offboard控制以及如何向无人机发送指令。 -It has been tested on Ubuntu 20.04 with ROS 2 Foxy and PX4 v1.14. +该内容已在搭载 ROS 2 Foxy 与 PX4 v1.14 的 Ubuntu 20.04 系统上完成测试。 :::warning _Offboard_ control is dangerous. @@ -13,27 +13,27 @@ _Offboard_ control is dangerous. ::: :::info -ROS and PX4 make a number of different assumptions, in particular with respect to [frame conventions](../ros/external_position_estimation.md#reference-frames-and-ros). +ROS 与 PX4 存在若干不同的预设(假设),尤其是在 [frame conventions](../ros/external_position_estimation.md#reference-frames-and-ros) 当主题发布或订阅时,坐标系类型之间没有隐含转换! -这个例子按照PX4的定义在NED坐标系下发布位置。 -To subscribe to data coming from nodes that publish in a different frame (for example the ENU, which is the standard frame of reference in ROS/ROS 2), use the helper functions in the [frame_transforms](https://github.com/PX4/px4_ros_com/blob/main/src/lib/frame_transforms.cpp) library. +这个例子按照 PX4 的预期在NED坐标系下发布位置。 +若要订阅来自在不同框架内发布的节点的数据(例如ENU, 这是ROS/ROS 2中的标准参考框架),使用[frame_transforms](https://github.com/PX4/px4_ros_com/blob/main/src/lib/frame_transforms.cpp)库中的辅助函数。 ::: -## 尝试一下 +## 小试身手 -Follow the instructions in [ROS 2 User Guide](../ros2/user_guide.md) to install PX and run the simulator, install ROS 2, and start the XRCE-DDS Agent. +按照 [ROS 2 用户指南](../ros2/user_guide.md)中的说明来安装PX 并运行多轴模拟器,安装ROS 2, 并启动XRCE-DDS代理。 -After that we can follow a similar set of steps to those in [ROS 2 User Guide > Build ROS 2 Workspace](../ros2/user_guide.md#build-ros-2-workspace) to run the example. +之后,我们可参照 [ROS 2 用户指南 > 构建 ROS 2 工作空间](../ros2/user_guide.md#build-ros-2-workspace)中的相似的步骤来运行这个例子。 :::tip -Make sure that QGC is connected to PX4 before running the ROS 2 node. -This is needed because, by default, you cannot arm a vehicle without a connection to ground station (QGC) or an established RC connection (this ensures there is always the option to regain manual control). +运行 ROS 2 节点前,请确保 QGC已连接到 PX4。 +之所以需要这样做,是因为默认情况下,若未连接地面控制站(QGC)或已建立的RC连接,飞行器无法解锁(这一机制可确保始终存在重新获得手动控制权的途径)。 ::: 构建并运行示例: -1. Open a new terminal. +1. 打开一个新的终端。 2. 使用以下方法创建并切换至新的 colcon工作目录: @@ -42,20 +42,20 @@ This is needed because, by default, you cannot arm a vehicle without a connectio cd ~/ws_offboard_control/src/ ``` -3. Clone the [px4_msgs](https://github.com/PX4/px4_msgs) repo to the `/src` directory (this repo is needed in every ROS 2 PX4 workspace!): +3. 将[px4_msgs](https://github.com/PX4/px4_msgs)代码仓库克隆到 /src 目录下(每个 ROS 2 PX4 工作空间都需要该仓库!): ```sh git clone https://github.com/PX4/px4_msgs.git # checkout the matching release branch if not using PX4 main. ``` -4. Clone the example repository [px4_ros_com](https://github.com/PX4/px4_ros_com) to the `/src` directory: +4. 将示例代码仓库 [px4_ros_com](https://github.com/PX4/px4_ros_com)克隆到 /src 目录下: ```sh git clone https://github.com/PX4/px4_ros_com.git ``` -5. Source the ROS 2 development environment into the current terminal and compile the workspace using `colcon`: +5. 在当前终端中加载 ROS 2 开发环境,并使用 colcon 工具编译工作空间: :::: tabs @@ -83,7 +83,7 @@ This is needed because, by default, you cannot arm a vehicle without a connectio :::: -6. Source the `local_setup.bash`: +6. 来源 `local_setup.bash`: ```sh source install/local_setup.bash @@ -95,85 +95,85 @@ This is needed because, by default, you cannot arm a vehicle without a connectio ros2 run px4_ros_com offboard_control ``` -飞行器将解锁、起飞至5米并悬停等待(永久)。 +飞行器将解锁、起飞至 5 米并悬停等待(永久)。 ## 实现 -The source code of the offboard control example can be found in [PX4/px4_ros_com](https://github.com/PX4/px4_ros_com) in the directory [/src/examples/offboard/offboard_control.cpp](https://github.com/PX4/px4_ros_com/blob/main/src/examples/offboard/offboard_control.cpp). +离板控制示例的源代码可以在[ PX4/px4_ros_com ]目录里 [/src/examples/offboard/offboard_control.cpp](https://github.com/PX4/px4_ros_com/blob/main/src/examples/offboard/offboard_control.cpp)中找到 [X4/px4_ros_com](https://github.com/PX4/px4_ros_com)。 :::info -PX4 publishes all the messages used in this example as ROS topics by default (see [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml)). +PX4 默认情况下将此示例中使用的所有消息以ROS为话题发布(详见 [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml))。 ::: -PX4 requires that the vehicle is already receiving `OffboardControlMode` messages before it will arm in offboard mode, or before it will switch to offboard mode when flying. -In addition, PX4 will switch out of offboard mode if the stream rate of `OffboardControlMode` messages drops below approximately 2Hz. +PX4 要求,飞行器需先持续接收 OffboardControlMode(离板控制模式)消息,之后才能在离板模式下解锁(arm),或在飞行过程中切换至离板模式。 +此外,若 OffboardControlMode(离板控制模式)消息的数据流速率降至约 2Hz 以下,PX4 将会退出离板模式。 该行为在ROS 2 节点的主循环中实现的,如下所示: ```cpp -auto timer_callback = [this]() -> void { +auto timer_callback = [this]() -> void { - if (offboard_setpoint_counter_ == 10) { - // Change to Offboard mode after 10 setpoints - this->publish_vehicle_command(VehicleCommand::VEHICLE_CMD_DO_SET_MODE, 1, 6); + if (offboard_setpoint_counter_ == 10) { + // Change to Offboard mode after 10 setpoints + this->publish_vehicle_command(VehicleCommand::VEHICLE_CMD_DO_SET_MODE, 1, 6); - // Arm the vehicle - this->arm(); - } + // Arm the vehicle + this->arm(); + } - // OffboardControlMode needs to be paired with TrajectorySetpoint - publish_offboard_control_mode(); - publish_trajectory_setpoint(); + // OffboardControlMode needs to be paired with TrajectorySetpoint + publish_offboard_control_mode(); + publish_trajectory_setpoint(); - // stop the counter after reaching 11 - if (offboard_setpoint_counter_ < 11) { - offboard_setpoint_counter_++; - } + // stop the counter after reaching 11 + if (offboard_setpoint_counter_ < 11) { + offboard_setpoint_counter_++; + } }; -timer_ = this->create_wall_timer(100ms, timer_callback); +timer_ = this->create_wall_timer(100ms, timer_callback); ``` 循环运行在一个100毫秒计时器。 -For the first 10 cycles it calls `publish_offboard_control_mode()` and `publish_trajectory_setpoint()` to send [OffboardControlMode](../msg_docs/OffboardControlMode.md) and [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) messages to PX4. -The `OffboardControlMode` messages are streamed so that PX4 will allow arming once it switches to offboard mode, while the `TrajectorySetpoint` messages are ignored (until the vehicle is in offboard mode). +在最初的 10 个循环中,它会调用 `publish_offboard_control_mode()` 和 `publish_trajectory_setpoint()` 这两个函数,向 PX4 发送 OffboardControlMode[OffboardControlMode](../msg_docs/OffboardControlMode.md) 和 [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) 消息。 +OffboardControlMode消息会持续发送,以便 PX4 切换到离板模式后允许解锁;而 TrajectorySetpoint消息会被忽略(直到载具处于离板模式) -After 10 cycles `publish_vehicle_command()` is called to change to offboard mode, and `arm()` is called to arm the vehicle. -在飞行器解锁并和切换模式后,它将开始跟踪位置设定值。 -在每个周期内仍然发送设定值,确保飞行器不会切换出offboard模式。 +10 个循环后,会调用 publish_vehicle_command() 函数切换至离板模式,并调用 arm() 函数对载具进行解锁。 +在载具解锁并和切换模式后,它将开始跟踪位置设定值。 +在每个周期内仍然发送设定值,确保载具不会切换出offboard模式。 -The implementations of the `publish_offboard_control_mode()` and `publish_trajectory_setpoint()` methods are shown below. -These publish the [OffboardControlMode](../msg_docs/OffboardControlMode.md) and [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) messages to PX4 (respectively). +publish_offboard_control_mode() 和 publish_trajectory_setpoint() 这两个方法的实现代码如下所示。 +这些方法会分别发布到 PX4 的 [OffboardControlMode](../msg_docs/OffboardControlMode.md和 [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) 消息。 -The `OffboardControlMode` is required in order to inform PX4 of the _type_ of offboard control behing used. -Here we're only using _position control_, so the `position` field is set to `true` and all the other fields are set to `false`. +OffboardControlMode(离板控制模式)消息是必需的,其作用是告知 PX4 当前所使用的离板控制类型。 +此处我们仅使用位置控制,因此将 `position` 字段设为`true`,而所有其他字段均设为 `false`。 ```cpp /** - * @brief Publish the offboard control mode. - * For this example, only position and altitude controls are active. + * @short 发布离板控制模式。 + *在本示例中,仅位置控制和高度控制处于激活状态 */ -void OffboardControl::publish_offboard_control_mode() -{ - OffboardControlMode msg{}; - msg.position = true; - msg.velocity = false; - msg.acceleration = false; +无效的离板控制::publish_offboard_control_mode() +Power + OffboardControlModel msg{}; + msg.position = true; + msg.veocity = false; + msg. cceleration = false; msg.attitude = false; msg.body_rate = false; - msg.thrust_and_torque = false; - msg.direct_actuator = false; - msg.timestamp = this->get_clock()->now().nanoseconds() / 1000; + msg.subust_and_torque = false; + msg. irect_actuator = false; + msg.timestamp = this->get_clock()->now ().nanoseconds() / 1000; offboard_control_mode_publisher_->publish(msg); } ``` -`TrajectorySetpoint` provides the position setpoint. -In this case, the `x`, `y`, `z` and `yaw` fields are hardcoded to certain values, but they can be updated dynamically according to an algorithm or even by a subscription callback for messages coming from another node. +`TrattorySettpoint` 提供了位置设定点。 +在这种情况下,`x`、`y`、`z`和`yaw`字段的值是硬编码为特定数值的。 但它们可以根据算法动态更新,甚至可以通过订阅回调函数来从另一个节点进行更新。 ```cpp /** - * @brief Publish a trajectory setpoint - * For this example, it sends a trajectory setpoint to make the - * vehicle hover at 5 meters with a yaw angle of 180 degrees. + *@brief 发布轨迹设定点 + + 在本示例中,该函数会发送一个轨迹设定点,使载具在 5 米高度悬停,并保持 180 度的偏航角。 */ void OffboardControl::publish_trajectory_setpoint() { @@ -185,9 +185,9 @@ void OffboardControl::publish_trajectory_setpoint() } ``` -The `publish_vehicle_command()` sends [VehicleCommand](../msg_docs/VehicleCommand.md) messages with commands to the flight controller. -We use it above to change the mode to offboard mode, and also in `arm()` to arm the vehicle. -While we don't call `disarm()` in this example, it is also used in the implementation of that function. +`publish_vehicle_command()` 将带有命令的 [VehicleCommand](../msg_docs/VehicleCommand.md)消息发送给载具。 +我们使用上面的方法将模式切换为 offboard 模式,同时也在 arm() 函数中用它来对载具进行解锁。 +我们在此示例中不调用 `disarm()` ,但它也用于执行此功能。 ```cpp /** @@ -198,25 +198,25 @@ While we don't call `disarm()` in this example, it is also used in the implement */ void OffboardControl::publish_vehicle_command(uint16_t command, float param1, float param2) { - VehicleCommand msg{}; - msg.param1 = param1; - msg.param2 = param2; - msg.command = command; - msg.target_system = 1; - msg.target_component = 1; - msg.source_system = 1; - msg.source_component = 1; - msg.from_external = true; - msg.timestamp = this->get_clock()->now().nanoseconds() / 1000; - vehicle_command_publisher_->publish(msg); + VehicleCommand msg{}; + msg.param1 = param1; + msg.param2 = param2; + msg.command = command; + msg.target_system = 1; + msg.target_component = 1; + msg.source_system = 1; + msg.source_component = 1; + msg.from_external = true; + msg.timestamp = this->get_clock()->now().nanoseconds() / 1000; + vehicle_command_publisher_->publish(msg); } ``` :::info -[VehicleCommand](../msg_docs/VehicleCommand.md) is one of the simplest and most powerful ways to command PX4, and by subscribing to [VehicleCommandAck](../msg_docs/VehicleCommandAck.md) you can also confirm that setting a particular command was successful. -The param and command fields map to [MAVLink commands](https://mavlink.io/en/messages/common.html#mav_commands) and their parameter values. +[VehicleCommand](../msg_docs/VehicleCommand.md) 是命令PX4的最简单和最高效的方式之一。 通过订阅 [VehicleCommandAck](../msg_docs/VehicleCommandAck.md),您也可以确认设置特定命令是否成功。 +参数字段和 指令字段对应于 [MAVLink commands](https://mavlink.io/en/messages/common.html#mav_commands)以及他们的参数值 ::: -## See Also +## 另见 - [Python ROS2 offboard examples with PX4](https://github.com/Jaeyoung-Lim/px4-offboard) (Jaeyoung-Lim/px4-offboard). diff --git a/docs/zh/ros2/px4_ros2_control_interface.md b/docs/zh/ros2/px4_ros2_control_interface.md index a31d7d5880..182b18b45a 100644 --- a/docs/zh/ros2/px4_ros2_control_interface.md +++ b/docs/zh/ros2/px4_ros2_control_interface.md @@ -1,212 +1,218 @@ -# PX4 ROS 2 Control Interface +# PX4 ROS 2 控制接口 :::warning Experimental -At the time of writing, parts of the PX4 ROS 2 Control Interface are experimental, and hence subject to change: +在撰写本文时,PX4 ROS 2 控制接口的部分内容仍处于实验阶段,因此可能会发生变动: -- The architecture and core interfaces for defining modes in ROS 2 modes are largely stable, and are tested in CI. - The library offers significant benefits over using offboard mode in its current state. -- Only a few setpoint types have settled (the others are still under development). - You may need to use internal PX4 topics which may not remain backwards-compatible over time. -- The API is not fully documented. +- ROS 2 模式中用于定义模式的架构及核心接口在很大程度上已趋于稳定,且会在CI中进行测试 + 相比当前状态下的离板模式,该代码库具有显著优势 +- 仅有少数几种设定点类型已趋于稳定。(其余设定点类型仍在开发中) + 您可能需要使用内部的 PX4 主题,这些主题可能不会随着时间的推移而保持与后方兼容。 +- 该 API没有完整的文档 ::: -The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library that simplifies controlling PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) is a C++ library (with Python bindings) that simplifies controlling PX4 from ROS 2. -Developers use the library to create and dynamically register modes written using ROS 2. -These modes are dynamically registered with PX4, and appear to be part of PX4 to a ground station or other external system. -They can even replace the default modes in PX4 with enhanced ROS 2 versions, falling back to the original version if the ROS2 mode fails. +开发者可使用该库创建并动态注册以 ROS 2 编写的模式。 +这些模式会动态注册到 PX4 中,并且对于地面站或其他外部系统而言,它们看起来就像是 PX4 的一部分。 +开发者甚至可以用功能增强的 ROS 2 版本模式替换 PX4 中的默认模式,且若 ROS 2 模式失效,系统会回退到原始版本的模式。 -The library also provides classes for sending different types of setpoints, ranging from high-level navigation tasks all the way down to direct actuator controls. -These classes abstract the internal setpoints used by PX4, and that can therefore be used to provide a consistent ROS 2 interface for future PX4 and ROS releases. +该库还提供了用于发送不同类型设定点的类,其涵盖范围从高层级的导航任务一直到直接的执行器控制。 +这些类对 PX4 所使用的内部设定点进行了抽象处理,因此可用于为未来的 PX4 和 ROS 版本提供统一的 ROS 2 接口。 -PX4 ROS 2 modes are easier to implement and maintain than PX4 internal modes, and provide more resources for developers in terms of processing power and pre-existing libraries. -Unless the mode is safety-critical, requires strict timing or very high update rates, or your vehicle doesn't have a companion computer, you should [consider using PX4 ROS 2 modes in preference to PX4 internal modes](../concept/flight_modes.md#internal-vs-external-modes). +PX4 ROS 2 模式相较于 PX4 内部模式,更易于实现和维护,并且在处理能力与既有代码库资源方面,能为开发者提供更丰富的支持。 +除非该模式属于安全关键型、对时序有严格要求或需要极高的更新速率,或者你的飞行器没有搭载伴随计算机,否则你应优先[考虑使用 PX4 ROS 2 模式,而非 PX4 内部模式](../concept/flight_modes.md#internal-vs-external-modes)。 + +:::tip +If you want to use Python, check out the [examples in the repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/python). +Not all classes have Python bindings yet — the [supported bindings are here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_py/src/px4_ros2). +You are welcome to add and contribute missing classes. +::: ## 综述 -This diagram provides a conceptual overview of how the control interface modes and mode executors interact with PX4. +该图从概念层面概述了控制接口模式与模式执行器如何与 PX4 进行交互。 -![ROS2 modes overview diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg) +![ROS2 模式概览图](../../assets/middleware/ros2/px4_ros2_interface_lib/ros2_modes_overview.svg) -The following sections define and explain the terms used in the diagram. +以下章节对图表中使用的术语进行定义和解释。 -### Definitions +### 定义 -#### Mode +#### 模式 -A mode defined using the interface library has the following properties: +使用接口库定义的模式具有以下特性: -- A mode is a component that can send setpoints to the vehicle in order to control its motion (such as velocity or direct actuator commands). -- A mode selects a setpoint type and sends it while it is active. - It can switch between multiple setpoint types. -- A mode can't activate other modes, and must be activated by the user (through RC/GCS), the flight controller in a failsafe situation, a _mode executor_, or some other external system. -- Has a name displayed by the GCS. -- Can configure its mode requirements (for example that it requires a valid position estimate). -- A mode can perform different tasks, such as flying to a target, lowering a winch, releasing a payload and then fly back. -- A mode can replace a mode defined in PX4. +- 模式是一种组件,它可以向载具发送设定值以控制其运动(例如速度指令或直接执行器指令)。 +- 模式在激活状态下会选择一种设定值类型并发送该设定值。 + 它能够在多种设定值类型之间进行切换。 +- 一种模式无法激活其他模式,其必须由以下对象激活:用户(通过RC/GCS)、处于故障保护状态下的飞控、mode executor_,或其他某种外部系统。 +- 具有一个由GCS显示的名称。 +- 可配置其模式要求(例如,要求具备有效的位置估算值) +- 一种模式可执行不同任务,例如飞往目标点、下放绞盘、释放有效载荷,之后返航。 +- 一种模式可替换 PX4 中已定义的模式。 -#### Mode Executor +#### 模式执行器 -A mode executor is an optional component for scheduling modes. -For example, the mode executor for a custom payload delivery or survey mode might first trigger a take-off, then switch to the custom mode, and when that completes trigger an RTL. +模式执行器是用于调度模式的可选组件。 +例如,用于自定义有效载荷投放或测绘模式的模式执行器,可能会先触发起飞,随后切换至该自定义模式,待模式完成后再触发RTL。 -Specifically, it has the following properties: +具体而言,它具有以下特性: -- A mode executor is an optional component one level higher than a mode. - It is a state machine that can activate modes, and wait for their completion. -- It can only do so while it is in charge. - For that, an executor has exactly one _owned mode_ (and a mode can be owned by at most one executor). - This mode serves as activation for the executor: when the user selects the mode, the owning executor gets activated and can select any mode. - It stays in charge until the user switches modes (by RC or from a GCS), or a failsafe triggers a mode switch. - Should the failsafe clear, the executor gets reactivated. -- This allows multiple executors to coexist. -- Executors cannot activate other executors. -- Within the library, a mode executor is always implemented in combination with a custom mode. +- 模式执行器是一种可选组件,其层级比模式高一级。 + 它是一种状态机,能够激活模式并等待模式完成。 +- 它仅能在负责状态下执行此操作。 + 为此,一个执行器恰好拥有一个_owned mode_(且一个模式最多只能被一个执行器拥有)。 + 该模式可作为执行器的激活触发条件:当用户选择此模式时,其所属的执行器会被激活,进而能够选择任意模式。 + 它会一直处于管控状态,直至用户(通过遥控器或从地面控制站)切换模式,或故障保护机制触发模式切换。 + 若故障保护状态解除,执行器将重新激活。 +- 这允许多个执行器共存。 +- 执行器无法激活其他执行器。 +- 在该库中,模式执行器始终需结合自定义模式来实现。 ::: info -- These definitions guarantee that a user can take away control from a custom mode or executor at any point in time by commanding a mode switch through RC or a GCS. -- A mode executor is transparent to the user. - It gets indirectly selected and activated through the owning mode, and thus the mode should be named accordingly. +- 这些定义确保用户可在任意时刻通过RC或GCS发送模式切换指令,从而夺回对自定义模式或执行器的控制权。 +- 模式执行器对用户而言是透明的。 + 它通过所属模式被间接选择并激活,因此该模式应相应地命名。 ::: -#### Configuration Overrides +#### 配置覆盖 -Both modes and executors can define configuration overrides, allowing customisation of certain behaviors while the mode or executor is active. +模式和执行器均可定义配置覆盖,从而能在模式或执行器处于激活状态时,对特定行为进行自定义设置。 -These are currently implemented: +这些措施目前正在实施: - _Disabling auto-disarm_. - This permits landing and then taking off again (e.g. to release a payload). + 这允许着陆,然后再次起飞(例如释放有效载荷)。 - _Ability to defer non-essential failsafes_. - This allows an executor to run an action without being interrupted by non-critical failsafe. - For example, ignoring a low-battery failsafe so that a winch operation can complete. + 这使得执行器能够执行某项操作,且不会被非关键故障保护中断。 + 例如,忽略低电量故障保护(机制),以便绞车操作能够完成。 -### Comparison to Offboard Control +### 与离板控制的比较 -The above concepts provide a number of advantages over traditional [offboard control](../ros/offboard_control.md): +上述概念提供了一些优点,而不是传统的[离板控制](../ros/offboard_control.md): -- Multiple nodes or applications can coexist and even run at the same time. - But only one node can _control the vehicle_ at a given time, and this node is well defined. -- Modes have a distinct name and be displayed/selected in the GCS. -- Modes are integrated with the failsafe state machine and arming checks. -- The setpoint types that can be sent are well defined. -- ROS 2 modes can replace flight controller internal modes (such as [Return mode](../flight_modes/return.md)). +- 多个节点或应用程序可以共存,甚至能同时运行。 + 但在特定时刻,仅能有一个节点对载具进行控制,且该节点的定义是明确的。 +- 模式具有独特的名称,并且可在GCS中显示 / 选择。 +- 模式与故障保护状态机及解锁检查功能相集成。 +- 可发送的设定值类型定义明确。 +- ROS 2 模式可以替换飞行控制器内部模式(如[返回模式](../flight_modes/return.md))。 -## Installation and First Test +## 安装与首次测试 -The following steps are required to get started: +开始使用前,需完成以下步骤: -1. Make sure you have a working [ROS 2 setup](../ros2/user_guide.md), with [`px4_msgs`](https://github.com/PX4/px4_msgs) in the ROS 2 workspace. +1. 请确保您在 ROS 2 工作区中有 [ROS 2 设置](../ros2/user_guide.md) 与 [`px4_msgs`](https://github.com/PX4/px4_msgs]。 -2. Clone the repository into the workspace: +2. 将代码仓库克隆到工作空间中 - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - ::: info - To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. - See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + 提示信息 + 为确保兼容性,请使用 PX4、px4_msgs(PX4 消息包)及该库的最新 main 分支。 + 另请参阅 [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4) ::: -3. Build the workspace: +3. 构建工作空间: - ```sh - cd .. - colcon build - source install/setup.bash - ``` + ```sh + cd .. + colcon building + source install/setup.bash + ``` -4. In a different shell, start PX4 SITL: +4. 在另一个外壳中,启动 PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (here we use Gazebo-Classic, but you can use any model or simulator) + (这里我们使用Gazebo-Classic,但你可以使用任何模型或模拟器) -5. Run the micro XRCE agent in a new shell (you can keep it running afterward): +5. 在新的 shell 中运行微XRCE 代理 (您可以在以后继续运行): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` -6. Start QGroundControl. +6. 启动QGroundControl。 - ::: info - Use QGroundControl Daily, which supports dynamically updating the list of modes. + ::: info + Use QGroundControl Daily, which supports dynamically updating the list of modes. ::: -7. Back in the ROS 2 terminal, run one of the example modes: +7. 回到ROS2终端,运行一个示例模式: - ```sh - ros2 run example_mode_manual_cpp example_mode_manual - ``` + ```sh + ros2 运行 example_mode_manual_cpp example_mode_manual + ``` - You should get an output like this showing 'My Manual Mode' mode being registered: + 你应会看到类似如下的输出,其中显示 “我的手动模式"已注册: - ```sh - [DEBUG] [example_mode_manual]: Checking message compatibility... - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) - [DEBUG] [example_mode_manual]: Subscriber found, continuing - [DEBUG] [example_mode_manual]: Publisher found, continuing - [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply - [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) - ``` + ```sh + [DEBUG] [example_mode_manual]: Checking message compatibility... + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Registering 'My Manual Mode' (arming check: 1, mode: 1, mode executor: 0) + [DEBUG] [example_mode_manual]: Subscriber found, continuing + [DEBUG] [example_mode_manual]: Publisher found, continuing + [DEBUG] [example_mode_manual]: Got RegisterExtComponentReply + [DEBUG] [example_mode_manual]: Arming check request (id=1, only printed once) + ``` -8. On the PX4 shell, you can check that PX4 registered the new mode: +8. 在 PX4 外壳上,您可以检查 PX4 是否注册了新模式: - ```sh - commander status - ``` + ```sh + 指挥官状态 + ``` - The output should contain: + 输出应包含: - ```plain - INFO [commander] Disarmed - INFO [commander] navigation mode: Position - INFO [commander] user intended navigation mode: Position - INFO [commander] in failsafe: no - INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode - ``` + ```plain + INFO [commander] Disarmed + INFO [commander] navigation mode: Position + INFO [commander] user intended navigation mode: Position + INFO [commander] in failsafe: no + INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode + ``` -9. At this point you should be able to see the mode in QGroundControl as well: +9. 在这一点上,您也应该能够在 QGroundControl 中看到模式: - ![QGC Modes](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_modes.png) + ![QGC Modes](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_modes.png) -10. Select the mode, make sure you have a manual control source (physical or virtual joystick), and arm the vehicle. - The mode will then activate, and it should print the following output: +10. 选择该模式,确保你拥有手动控制源(物理或虚拟操纵杆),并为载具解锁 + 然后模式将激活,它将打印以下输出: - ```sh - [DEBUG] [example_mode_manual]: Mode 'My Manual Mode' activated - ``` + ```sh + [DEBUG] [example_mode_manual]: 模式“我的手动模式” 已激活 + ``` -11. Now you are ready to create your own mode. +11. 现在您已准备好创建自己的模式。 -## How to use the Library +## 如何使用代码库 -The following sections describe specific functionality provided by this library. -In addition, any other PX4 topic can be subscribed or published. +以下各节介绍该库提供的特定功能。 +此外,任何其他PX4主题都可以订阅或发布。 -### Mode Class Definition +### 模式类定义 -This section steps through an example of how to create a class for a custom mode. +此部分通过如何为自定义模式创建类的示例。 -For a complete application, check out the [examples in the `Auterion/px4-ros2-interface-lib` repository](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp), such as [examples/cpp/modes/manual](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/modes/manual/include/mode.hpp). +若要完整的应用程序,请查看[示例在 `Auterion/px4-ros2-interfacee-lib` 仓库中](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp),例如[示例/cpp/mod/manual](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/modes/manual/include/mode.hpp)。 ```cpp{1,5,7-9,24-31} class MyMode : public px4_ros2::ModeBase // [1] @@ -248,27 +254,27 @@ private: }; ``` -- `[1]`: First we create a class that inherits from [`px4_ros2::ModeBase`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeBase.html). -- `[2]`: In the constructor, we pass the mode name. This also allows us to configure some other things, like replacing a flight controller internal mode. -- `[3]`: This is where we create all objects that we want to use later on. - This can be RC input, setpoint type(s), or telemetry. `*this` is passed as a `Context` to each object, which associates the object with the mode. -- `[4]`: Whenever the mode is active, this method gets called regularly (the update rate depends on the setpoint type). - Here is where we can do our work and generate a new setpoint. +- `[1]`: 首先创建一个从 [`px4_ros2::ModeBase`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeBase.html)继承的类。 +- `[2]`: 在构造函数中,我们传递模式名称。 这也使我们能够配置一些其他内容,例如替换飞行控制器的内置模式。 +- `[3]`:我们在此处创建后续想要使用的所有对象。 + 这可以是 RC 输入、设置点类型(s)或遥测数据。 `*this` 作为`Context`传递给每个对象,将对象与模式联系起来。 +- `[4]`:每当该模式处于激活状态时,此方法会定期被调用(更新频率取决于设定值类型)。 + 我们可以在这里开展工作并产生一个新的设定点。 -After creating an instance of that mode, `mode->doRegister()` must be called which does the actual registration with the flight controller and returns `false` if it fails. -In case a mode executor is used, `doRegister()` must be called on the mode executor, instead of for the mode. +创建此模式的实例后, `mode->doRegister()` 必须被调用,在飞行控制器中进行实际注册,如果失败则返回 `false` 。 +如果使用模式执行器,`doRegister()`必须调用模式执行器而不是模式。 -### Mode Executor Class Definition +### 模式执行器类定义 -This section steps through an example of how to create a mode executor class. +本节逐步讲解如何创建模式执行器类的示例。 ```cpp{1,4-5,9-16,20,33-57} class MyModeExecutor : public px4_ros2::ModeExecutorBase // [1] { public: - MyModeExecutor(rclcpp::Node & node, px4_ros2::ModeBase & owned_mode) // [2] - : ModeExecutorBase(node, px4_ros2::ModeExecutorBase::Settings{}, owned_mode), - _node(node) + MyModeExecutor(px4_ros2::ModeBase & owned_mode) // [2] + : ModeExecutorBase(px4_ros2::ModeExecutorBase::Settings{}, owned_mode), + _node(owned_mode.node()) { } enum class State // [3] @@ -327,74 +333,81 @@ private: }; ``` -- `[1]`: First we create a class that inherits from [`px4_ros2::ModeExecutorBase`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html). -- `[2]`: The constructor takes our custom mode that is associated with the executor and passes it to the constructor of `ModeExecutorBase`. -- `[3]`: We define an enum for the states we want to run through. -- `[4]`: `onActivate` gets called when the executor becomes active. At this point we can start to run through our states. - How you do this is up to you, in this example a method `runState` is used to execute the next state. -- `[5]`: On switching to a state we call an asynchronous method from `ModeExecutorBase` to start the desired mode: `run`, `takeoff`, `rtl`, and so on. - These methods are passed a function that is called on completion; the callback provides a `Result` argument that tells you whether the operation succeeded or not. - The callback runs the next state on success. -- `[6]`: We use the `scheduleMode()` method to start the executor's "owned mode", following the same pattern as the other state handlers. +- `[1]`: 首先创建一个继承 [`px4_ros2::ModeExecutorBase`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html)。 +- `[2]`: 构造函数采用与执行器相关联的自定义模式,并传递给`ModeExecutorBase`的构造函数。 +- `[3]`: 我们为想要运行的状态定义一个枚举。 +- `[4]`: `onActivate` 在执行器激活时被调用。 此时,我们可以开始遍历这些状态了。 + 你是如何操作的,在这个示例中使用 `runState` 方法来执行下一个状态。 +- `[5]`: 在切换到状态时,我们会调用 `ModeExecutorBase` 中的异步方法来启动所需的模式:`run`, `eff`、`rtl`、“等等”。 + 这些方法被传递了一个被要求完成的函数; 回调提供一个 `Result` 参数,告诉您操作是否成功。 + 回调运行下一个成功状态。 +- `[6]`: 我们使用 `scheduleMode()` 方法来启动执行者"拥有模式", 遵循与其他状态处理器相同的模式。 -### Setpoint Types +### 设置点类型 -A mode can choose its setpoint type(s) it wants to use to control the vehicle. -The used types also define the compatibility with different vehicle types. +模式可选择其用于控制载具的设定值类型。 +所用类型还界定了与不同类型载具的兼容性。 -The following sections provide a list of supported setpoint types: +以下章节提供了支持的设置点类型列表: -- [GotoSetpointType](#go-to-setpoint-gotosetpointtype): Smooth position and (optionally) heading control -- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics -- [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype): Direct control of motors and flight surface servo setpoints +- [MulticopterGotoSetpointType](#go-to-setpoint-multicoptergotosetpointtype): 平滑的位置控制以及(可选的)航向控制 +- [FwLateralLongitudinalSetpointType](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype): Direct control of lateral and longitudinal fixed wing dynamics +- [DirectActuatorsSetpointType](#direct-actuator-control-setpoint-directactuatorssetpointtype):直接控制发动机和飞行地面servo setpoints +- [Rover Setpoints](#rover-setpoints): Direct access to rover control setpoints (Position, Speed, Attitude, Rate, Throttle and Steering). :::tip -The other setpoint types are currently experimental, and can be found in: [px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental). +其他设置点类型目前是实验性的,可在以下网址找到:[px4_ros2/control/setpoint_types/experimental](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/experimental)。 -You can add your own setpoint types by adding a class that inherits from `px4_ros2::SetpointBase`, sets the configuration flags according to what the setpoint requires, and then publishes any topic containing a setpoint. +您可以通过添加一个从 `px4_ros2::SetpointBase` 继承的类来添加您自己的 setpoint 类型, 根据设置点的要求设置配置标志,然后发布任何包含设置点的主题。 ::: -#### Go-to Setpoint (GotoSetpointType) +#### 转到设置点 (MulticopterGotoSetpointType) + + + + :::info -This setpoint type is currently only supported for multicopters. +当前,此设定点类型仅支持多旋翼飞行器。 ::: -Smoothly control position and (optionally) heading setpoints with the [`px4_ros2::GotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/goto.hpp) setpoint type. -The setpoint type is streamed to FMU based position and heading smoothers formulated with time-optimal, maximum-jerk trajectories, with velocity and acceleration constraints. +可通过[`px4_ros2::MulticopterGotoSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp) 设定点类型,对位置设定点以及(可选的)航向设定点进行平滑控制。 +设定点类型会被传输至飞控主模块(FMU),该模块基于采用时间最优、最大加加速度轨迹构建的位置及航向平滑器。 -The most trivial use is simply inputting a 3D position into the update method: +还有一个 [`px4_ros2::MulticopterGotoGlobalSetpointType`](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/control/setpoint_types/multicopter/goto.hpp), 该类支持在全局坐标系下发送设定点。 + +最简单的用法就是直接向update method中输入一个3D 位置 ```cpp const Eigen::Vector3f target_position_m{-10.F, 0.F, 3.F}; _goto_setpoint->update(target_position_m); ``` -In this case, heading will remain _uncontrolled_. -To additionally control heading, specify it as the second input argument: +在这种情况下,航向将保持不受控制的状态。 +若要额外控制航向,可将其指定为第二个输入参数: ```cpp -const Eigen::Vector3f target_position_m{-10.F, 0.F, 3.F}; +const Eigen:::Vector3f target_position_m{-10.F, 0.F, 3.F}; const float heading_rad = 3.14F; _goto_setpoint->update( target_position_m, heading_rad); ``` -An additional feature of the go-to setpoint is dynamic control on the underlying smoothers' speed limits (i.e. maximum horizontal and vertical translational velocities as well as heading rate). -If, as above, left unspecified, the smoothers will default to the vehicle's default maximums (typically set to the physical limitations). -The smoothers will _only_ decrease speed limits, never increase. +“前往设定值”(go-to setpoint)的一项额外功能是,可对底层平滑控制器的速度限制进行动态控制(即对最大水平和平动速度、最大垂直平动速度以及航向速率进行动态控制)。 +若如上文所述未指定(该参数),则平滑控制器将默认采用设备的默认最大值(通常设定为其物理极限值) +平滑控制器仅会降低速度限制,绝不会提高速度限制。 ```cpp _goto_setpoint->update( target_position_m, heading_rad, - max_horizontal_velocity_m_s, + max_水平_velocity_m_s, max_vertical_velocity_m_s, max_heading_rate_rad_s); ``` -All arguments in the update method except the position are templated as `std::optional`, meaning that if one desires constraining the heading rate, but not the translating velocities, this is possible using a `std::nullopt`: +更新方法中,除位置外的所有参数均被模板化为 `std::optional` 类型。这意味着,若需限制航向速率但不限制平动速度,可通过 `std::nullopt` 实现这一需求。 ```cpp _goto_setpoint->update( @@ -405,58 +418,58 @@ _goto_setpoint->update( max_heading_rate_rad_s); ``` -#### Fixed-Wing Lateral and Longitudinal Setpoint (FwLateralLongitudinalSetpointType) +#### 固定翼横向与纵向设定值(FwLateralLongitudinalSetpointType,固定翼横向纵向设定值类型) - + :::info -This setpoint type is supported for fixed-wing vehicles and for VTOLs in fixed-wing mode. +此设定值类型支持固定翼飞行器,以及处于固定翼模式下的垂直起降飞行器(VTOL)。 ::: -Use the [`px4_ros2::FwLateralLongitudinalSetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1FwLateralLongitudinalSetpointType.html) to directly control the lateral and longitudinal dynamics of a fixed-wing vehicle — that is, side-to-side motion (turning/banking) and forward/vertical motion (speeding up and climbing/descending), respectively. -This setpoint is streamed to the PX4 [_FwLateralLongitudinalControl_ module](../modules/modules_controller.md#fw-lat-lon-control), which decouples lateral and longitudinal inputs while ensuring that vehicle limits are respected. +使用[`px4_ros2::FwLateralLongitudinalSetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1FwLateralLongitudinalSetpointType.html)直接控制固定翼飞行器的横向与纵向动力学特性,即分别控制其侧向运动(转弯 / 倾斜)和前向 / 垂直运动(加速及爬升 / 下降)。 +这个设置点被传输到 PX4 [_FwLateralLongitudinalControl_ module](../modules/modules_controller.md#fw-lat-lon-control),该模块会对横向与纵向输入进行解耦处理,同时确保不超出飞行器的各项限制范围。 -To control the vehicle, at least one lateral **and** one longitudinal setpoint must be provided: +为了控制载具,必须提供至少一个横向**和**一个纵向设定值: -1. Of the longitudinal inputs: either `altitude` or `height_rate` must be finite to control vertical motion. - If both are set to `NAN`, the vehicle will maintain its current altitude. -2. Of the lateral inputs: at least one of `course`, `airspeed_direction`, or `lateral_acceleration` must be finite. +1. 在纵向输入中:必须至少有一个 “高度”(altitude)或 “高度速率”(height_rate)为有限值,才能实现垂直运动控制。 + 若二者均设为 NAN,则载具将保持当前高度。 +2. 在横向输入中:“航线角”(course)、“空速方向”(airspeed_direction)或 “横向加速度”(lateral_acceleration)这三者中,至少有一个必须为有限值。 -For a detailed description of the controllable parameters, please refer to message definitions ([FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) and [FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md)). +关于可控参数的详细说明,请参考消息定义([FixedWingLateralSetpoint](../msg_docs/FixedWingLateralSetpoint.md) 和 [FixedWingLongitudinalSetpoint](../msg_docs/FixedWingLongitudinalSetpoint.md))。 ##### 基本用法 -This type has a number of update methods, each allowing you to specify an increasing number of setpoints. +该类型包含多个更新方法,每种方法可支持你指定的设定值数量逐步增加。 -The simplest method is `updateWithAltitude()`, which allows you to specify a `course` and `altitude` target setpoint: +最简单的方法是 updateWithAltitude(),该方法可让你指定 “航线角”(course)和 “高度”(altitude)这两个目标设定值。 ```cpp -const float altitude_msl = 500.F; +const float altextede_msl = 500.F; const float course = 0.F; // due North -_fw_lateral_longitudinal_setpoint->updateWithAltitude(altitude_msl, course); +_fw_later_longitudinal_setpoint->updateWAltitude(altyde_msl, course); ``` -PX4 uses the setpoints to compute the _roll angle_, _pitch angle_ and _throttle_ setpoints that are sent to lower level controllers. -Note that the commanded flight is expected to be relatively gentle/unaggressive when using this method. -This is done as follows: +PX4 会利用这些设定值计算出横滚角(roll angle)、俯仰角(pitch angle)和油门(throttle)设定值,并将其发送至底层控制器。 +需注意,使用此方法时,预期的指令飞行会相对平缓 / 不激进。 +此操作按如下方式执行: -- Lateral control output: +- 横向控制输出: - course setpoint (set by user) → airspeed direction (heading) setpoint → lateral acceleration setpoint → roll angle setpoint. + 航线角设定值(由用户设定)→ 空速方向 (航向) 设定值 → 横向加速设定值 → 滚动角度设定值 -- Longitudinal control output: +- 纵向控制输出: - altitude setpoint (set by user) → height rate setpoint → pitch angle setpoint and throttle settings. + 高度设定值(由用户设定) → 高度速率设定值 → 俯仰角设定值及油门设定。 -The `updateWithHeightRate()` method allows you to set a target `course` and `height_rate` (this is useful if the speed of ascent or descent matters, or needs to be dynamically controlled): +updateWithHeightRate() 方法允许你设置目标 “航线角”(course)和 “高度速率”(height_rate)(当爬升或下降速度至关重要,或需要对其进行动态控制时,此方法非常实用): ```cpp const float height_rate = 2.F; -const float course = 0.F; // due North -_fw_lateral_longitudinal_setpoint->updateWithHeightRate(height_rate, course); +const float course = 0.F; //due North +_fw_lateral_longitudinal_setpoint->updateWheightRate(high_rate course); ``` -The `updateWithAltitude()` and `updateWithHeightRate()` methods allow you to additionally control the equivalent airspeed or lateral acceleration by specifying them as the third and fourth arguments, respectively: +updateWithAltitude() 和 updateWithHeightRate() 这两种方法还允许你分别将 “等效空速”(equivalent airspeed)或 “横向加速度”(lateral acceleration)指定为第三个和第四个参数,从而对其进行控制: ```cpp const float altitude_msl = 500.F; @@ -470,44 +483,44 @@ _fw_lateral_longitudinal_setpoint->updateWithAltitude(altitude_msl, lateral_acceleration); ``` -The equivalent airspeed and lateral acceleration arguments are defined as `std::optional`, so you can omit any of them by passing `std::nullopt`. +等效的空速和横向加速参数定义为 `std::optional`, 所以你可以通过 `std::nullopt` 省略其中任何一个。 :::tip -If both lateral acceleration and course setpoints are provided, the lateral acceleration setpoint will be used as feedforward. +若同时提供了横向加速度设定值和航线角设定值,横向加速度设定值将被用作前馈(feedforward) ::: -##### Full Control Using the Setpoint Struct +##### 使用设定值结构体实现完全控制 -For full flexibility, you can create and pass a [`FwLateralLongitudinalSetpoint`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1FwLateralLongitudinalSetpoint.html) struct. -Each field is templated with `std::optional`. +为实现充分的灵活性,你可以创建并传递一个[`FwLateralLongitudinalSetpoint` ](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1FwLateralLongitudinalSetpoint.html) 结构体。 +每个字段都使用 `std::optional` 模板。 :::tip -If both course and airspeed direction are set: airspeed direction takes precedence, course is not controlled. -Lateral acceleration is treated as feedforward if either course or airspeed direction are also finite. -If both altitude and height rate are set: height rate takes precedence, altitude is not controlled. +若同时设置了航线角(course)和空速方向(airspeed direction),则空速方向优先,航线角不进行控制。 +若航线角或空速方向中任意一个为有限值,则横向加速度会被视为前馈。 +若同时设置了高度和高度速率,则高度速率优先,高度不进行控制。 ::: ```cpp -px4_ros2::FwLateralLongitudinalSetpoint setpoint_s; +px4_ros2:::FwLateralLongitudinalSetpoint setpoint_s; -setpoint_s.withCourse(0.F); -// setpoint_s.withAirspeedDirection(0.2F); // uncontrolled -setpoint_s.withLateralAcceleration(2.F); // feedforward -//setpoint_s.withAltitude(500.F); // uncontrolled -setpoint_s.withHeightRate(2.F); -setpoint_s.withEquivalentAirspeed(15.F); +settpoint_s.withCourse(0.F); +// setpoint_s.withAirspeedDirection(0.2F); // 失控 +setpoint_s.withLateralActivation(2.F); // feedforward +/setpoint_s.withAltude(500.F); // 失控 +setpoint_s.withightRate(2.F); +settpoint_s.withequivalentAirspeed(15.F); -_fw_lateral_longitudinal_setpoint->update(setpoint_s); +_fw_lateral_longitudinal_sett->upate(settpoint_ ``` -The diagram below illustrates the interaction between the `FwLateralLongitudinalSetpointType` and PX4 when all inputs are set. +下图展示了在所有输入均已设定的情况下,FwLateralLongitudinalSetpointType 与 PX4 之间的交互关系。 -![FW ROS Interaction](../../assets/middleware/ros2/px4_ros2_interface_lib/fw_lat_long_ros_interaction.svg) +![FW ROS交互](../../assets/middleware/ros2/px4_ros2_interface_lib/fw_lat_long_ros_interaction.svg) -##### Advanced Configuration (Optional) +##### 高级配置(可选) -You can also pass a [`FwControlConfiguration`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1FwControlConfiguration.html) struct along with the setpoint to override default controller settings and constraints such as pitch limits, throttle limits, and target sink/climb rates. -This is intended for advanced users: +你还可以传递一个[`FwControlConfiguration`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1FwControlConfiguration.html)结构体以及设定值,以覆盖默认的控制器设置和约束条件,例如俯仰角限制、油门限制以及目标下降 / 爬升速率。 +这是针对高级用户的: ```cpp px4_ros2::FwLateralLongitudinalSetpoint setpoint_s; @@ -526,93 +539,127 @@ config_s.withThrottleLimits(0.4F, 0.6F); _fw_lateral_longitudinal_setpoint->update(setpoint_s, config_s); ``` -All configuration fields are defined as `std::optional`. -Unset values will default to the PX4 configuration. -See [LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md) and [FixedWingLongitudinalConfiguration](../msg_docs/LongitudinalControlConfiguration.md) for more information on configuration options. +所有配置字段都定义为 `std::optional`。 +未设置的值将默认采用 PX4 的配置。 +更多关于配置选项的信息,请参阅 [LateralControlConfiguration](../msg_docs/LateralControlConfiguration.md)和 [FixedWingLongitudinalConfiguration](../msg_docs/LongitudinalControlConfiguration.md)。 :::info -For safety, PX4 automatically limits configuration values to stay within the vehicle’s constraints. -For example, throttle overrides are clamped to remain between [`FW_THR_MIN`](../advanced_config/parameter_reference.md#FW_THR_MIN) -and [`FW_THR_MAX`](../advanced_config/parameter_reference.md#FW_THR_MAX). +为保障安全,PX4 会自动将配置值限制在飞行器的约束范围内。 +例如,油门覆盖值会被限制在 [`FW_THR_MIN`](../advanced_config/parameter_reference.md#FW_THR_MIN) +和[`FW_THR_MAX`](../advanced_config/parameter_reference.md#FW_THR_MAX)之间。 ::: -#### Direct Actuator Control Setpoint (DirectActuatorsSetpointType) +#### 直接执行器控制设定点(DirectActuatorsSetpointType) -Actuators can be directly controlled using the [px4_ros2::DirectActuatorsSetpointType](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1DirectActuatorsSetpointType.html) setpoint type. -Motors and servos can be set independently. -Be aware that the assignment is vehicle and setup-specific. -For example to control a quadrotor, you need to set the first 4 motors according to its [output configuration](../concept/control_allocation.md). +可以使用 [px4_ros2::DirectActuatorsSetpointType](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1DirectActuatorsSetpointType.html) 设置点类型直接控制执行器。 +电机和舵机可独立设置。 +请注意,该分配(设置 / 指派)具有载具和配置特定性。 +例如,要控制一架四旋翼飞行器,你需要根据其 [输出配置] (../concept/control_allocation.md)来设置前 4 个电机。 :::info -If you want to control an actuator that does not control the vehicle's motion, but for example a payload servo, see [below](#controlling-an-independent-actuator-servo). +若你想控制的执行器并非用于控制飞行器的运动(例如,而是用于控制有效载荷舵机),请参阅 [below](#controlling-an-independent-actuator-servo)。 ::: -### Controlling a VTOL +#### Rover 设置点 - + -To control a VTOL in an external flight mode, ensure you're returning the correct setpoint type based on the current flight configuration: +滚动模块使用层次结构来传播设置点: -- Multicopter mode: use a setpoint type that is compatible with multicopter control. For example: either the [`GotoSetpointType`](#go-to-setpoint-gotosetpointtype) or the [`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html). -- Fixed-wing mode: Use the [`FwLateralLongitudinalSetpointType`](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype). +![Rover Control Structure](../../assets/middleware/ros2/px4_ros2_interface_lib/rover_control_structure.svg) -As long as the VTOL remains in either multicopter or fixed-wing mode throughout the external mode, no additional handling is required. +:::info +所提供的“highest”设定值将被用于 PX4 机器人模块中,以生成低于该值的设定值(并对其进行覆盖!)。 +这个层次结构有提供有效控制输入的明确规则: -If you would like to command a VTOL transition in your external mode, you need to use the [VTOL API](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1VTOL.html). The VTOL API provides the functionality to command a transition and query the current state of the vehicle. +- 提供一个位置集点,**or** +- “左”上的设置点之一(速度 **或** 节点) **和** “右”上的设置点之一(态度、速率 **或** 节点)。 所有“左”和“右”设置点的组合都是有效的。 -Use this API with caution! -Commanding transitions externally makes the user partially responsible for ensuring smooth and safe behavior, unlike onboard transitions (e.g. via RC switch) where PX4 handles the full process: +为了便于使用,我们以新的 SettpointType 的形式揭示这些有效的组合。 +::: -1. Ensure that both the `TrajectorySetpointType` and the `FwLateralLongitudinalSetpointType` are available to your mode. -2. Create an instance of `px4_ros2::VTOL` in the constructor of your mode. -3. To command a transition, you can use the `toMulticopter()` or `toFixedwing()` methods on your VTOL object to set the desired state. -4. During transition, send the following combination of setpoints: +通过控制界面暴露的 RoverSetpointTypes 是这些设置点的组合,导致有效的控制输入: - ```cpp - // Assuming the instance of the px4_ros2::VTOL object is called vtol +| SetpointType | 安装位置 | Speed | 油门 | Attitude | 频率 | Steering | Control Flags | +| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------ | +| [RoverPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverPositionSetpointType.html#details) | ✓ | (✓) | (✓) | (✓) | (✓) | (✓) | Position, Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedAttitudeSetpointType.html) | | ✓ | (✓) | ✓ | (✓) | (✓) | Velocity, Attitude, Rate, Control Allocation | +| [RoverSpeedRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedRateSetpointType.html) | | ✓ | (✓) | | ✓ | (✓) | Velocity, Rate, Control Allocation | +| [RoverSpeedSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverSpeedSteeringSetpointType.html) | | ✓ | (✓) | | | ✓ | Velocity, Control Allocation | +| [RoverThrottleAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleAttitudeSetpointType.html) | | | ✓ | ✓ | (✓) | (✓) | Attitude, Rate, Control Allocation | +| [RoverThrottleRate](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleRateSetpointType.html) | | | ✓ | | ✓ | (✓) | Rate, Control Allocation | +| [RoverThrottleSteering](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1RoverThrottleSteeringSetpointType.html) | | | ✓ | | | ✓ | Control Allocation | - // Send TrajectorySetpointType as follows: - Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); - Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; +✓ 是我们发布的设置点,(✓) 是根据上面的层次结构由 PX4 旋转模块内部生成的。 - _trajectory_setpoint->update(velocity_sp, acceleration_sp); +使用 `RoverSpeedAttitude SettpointType` 的特定驱动器模式示例为 [here](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/rover_velocity)。 - // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired +### 控制VTOL - float course_sp = 0.F; // North + - _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) - ``` +要在外部飞行模式下控制VTOL,需确保根据当前飞行配置返回正确的设定值类型: - This will ensure that the transition is handled properly within PX4. - You can optionally pass a deceleration setpoint to `computeAccelerationSetpointDuringTransition()` to be used during back-transitions. +- 多旋翼模式:使用与多旋翼控制兼容的设定值类型。 例如:要么[`MulticopterGotoSetpointType`](#go-to-setpoint-multicoptergotosetpointtype)要么[`TrajectorySetpointType`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1TrajectorySetpointType.html)。 +- 固定翼形模式:使用 [`FwLateralLongitudinalSetpointType`](#fixed-wing-lateral-and-longitudinal-setpoint-fwlaterallongitudinalsetpointtype)。 -To check the current state of the vehicle, use the `getCurrentState()` method on your `px4_ros2::VTOL` object. +只要VTOL在整个外部模式期间始终处于多旋翼模式或固定翼模式中的任意一种,就无需额外处理。 -See [this external flight mode implementation](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/vtol) for a practical example on how to use this API. +如果您想要在您的外部模式中命令一个 VTAL 过渡,您需要使用 [VTOL API](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1VTOL.html)。 VTAL API具备下达转换指令和查询载具当前状态的功能。 -### Controlling an Independent Actuator/Servo +谨慎使用此 API ! +通过外部下达转换指令时,用户需部分负责确保(飞行器)运行平稳且安全;这与机上转换(例如通过遥控器开关实现)不同,在机上转换模式下,整个过程由 PX4 全权处理。 -If you want to control an independent actuator (a servo), follow these steps: +1. 确保你的模式可调用 TrajectorySetpointType(轨迹设定值类型)和 FwLateralLongitudinalSetpointType(固定翼横纵向设定值类型)这两种设定值类型。 +2. 在您模式的构造函数中创建 `px4_ros2::VTOL` 的实例。 +3. 要下达转换指令,你可以在 VTOL 对象上调用 toMulticopter() 或 toFixedwing() 方法,以设置所需状态。 +4. 在转换过程中,发送以下设定值组合: + + ```cpp + // Assuming the instance of the px4_ros2::VTOL object is called vtol + + // Send TrajectorySetpointType as follows: + Eigen::Vector3f acceleration_sp = vtol.computeAccelerationSetpointDuringTransition(); + Eigen::Vector3f velocity_sp{NAN, NAN, 0.f}; + + _trajectory_setpoint->update(velocity_sp, acceleration_sp); + + // Send FwLateralLongitudinalSetpointType with lateral input to realign vehicle as desired + + float course_sp = 0.F; // North + + _fw_lateral_longitudinal_setpoint->updateWithAltitude(NAN, course_sp) + ``` + + 这将确保转换过程在 PX4 系统内部得到妥善处理。 + 你可以选择性地将一个减速度设定值传递给 computeAccelerationSetpointDuringTransition(),以便在反向转换过程中使用。 + +要查询载具的当前状态,可在 px4_ros2::VTOL 对象上调用 getCurrentState() 方法。 + +请参阅[此外部飞行模式实现](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/vtol) 有关如何使用此 API 的实际示例。 + +### 控制独立执行器/Servo + +如果您想要控制一个独立执行器(aservo),遵循以下步骤: 1. [Configure the output](../payloads/generic_actuator_control.md#generic-actuator-control-with-mavlink). -2. Create an instance of [px4_ros2::PeripheralActuatorControls](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1PeripheralActuatorControls.html) in the constructor of your mode. -3. Call the `set()` method to control the actuator(s). - This can be done independently of any active setpoints. +2. 在您的模式的构造函数中创建一个实例[px4_ros2::PeripheralActorControls](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1PeripheralActuatorControls.html)。 +3. 调用`set()` 方法以控制执行器 + 此操作可独立于任何活跃的设定点执行。 -### Telemetry +### 数传 -You can access PX4 telemetry topics directly via the following classes: +你可以通过以下类直接访问 PX4 遥测主题: -- [OdometryGlobalPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryGlobalPosition.html): Global position -- [OdometryLocalPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryLocalPosition.html): Local position, velocity, acceleration, and heading -- [OdometryAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryAttitude.html): Vehicle attitude -- [OdometryAirspeed](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryAirspeed.html): Airspeed +- [OdometryGlobalPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryGlobalPosition.html): 全球位置 +- [OdometryLocalPosition](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryLocalPosition.html): 本地位置、速度、加速度和航向 +- [OdometryAttitude](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryAttitude.html): 载具状态 +- [OdometryAirspeed](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1OdometryAirspeed.html):空速 -For example, you can query the vehicle's current position estimate as follows: +例如,你可以通过以下方式查询飞行器当前的位置估算值: ```cpp -std::shared_ptr _vehicle_local_position; +std::shared_ptr<0> _vehicle_local_position; ... // Get vehicle's last local position @@ -623,55 +670,55 @@ _vehicle_local_position->positionXYValid(); ``` :::info -These topics provide a wrapper around the internal PX4 topics, allowing the library to maintain compatibility if the internal topics change. -Check [px4_ros2/odometry](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/odometry) for new topics, and of course you can use any ROS 2 topic published from PX4. +这些主题围绕内部的 PX4 主题提供了一个包装程序,使代码库能够在内部主题发生变化时保持兼容性。 +检查 [px4_ros2/odometry](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/px4_ros2_cpp/include/px4_ros2/odometry) 新主题,当然你也可以使用任何由 PX4 发布的 ROS 2 主题。 ::: -### Failsafes and Mode Requirements +### 故障保护与模式要求 -Each mode has a set of requirement flags. -These are generally automatically set, depending on which objects are used within the context of a mode. -For example when adding manual control input with the code below the requirement flag for manual control gets set: +每种模式都有一组需求标志。 +这些(需求标志)通常会根据模式语境下所使用的对象自动设置。 +例如,当通过以下代码添加手动控制输入时,手动控制的需求标志会被设置: ```cpp _manual_control_input = std::make_shared(*this); ``` -Specifically, setting a flag has the following consequences in PX4, if the condition is not met: +具体而言,在 PX4 中,若条件未满足,设置某个标志会产生以下结果: -- arming is not allowed, while the mode is selected -- when already armed, the mode cannot be selected -- when armed and the mode is selected, the relevant failsafe is triggered (e.g. RC loss for the manual control requirement). - Check the [safety page](../config/safety.md) for how to configure failsafe behavior. - A failsafe is also triggered when the mode crashes or becomes unresponsive while it is selected. +- 在选定模式时不允许进行解锁操作 +- 当已处于武装状态时,该模式无法被选择。 +- 当载具已解锁且该模式被选中时,相关的故障保护机制会被触发(例如,针对手动控制需求的遥控器信号丢失故障保护)。 + 检查 [safety page] (../config/safety.md) 如何配置故障安全行为。 + 当某模式已被选中,且该模式发生崩溃或失去响应时,也会触发故障保护机制。 -This is the corresponding flow diagram for the manual control flag: +这是手动控制标志对应的流程图: ![Mode requirements diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/mode_requirements_diagram.png) -It is possible to manually update any mode requirement after the mode is registered. -For example to add home position as requirement: +在模式注册后,可以手动更新任意模式要求。 +例如,要将返航点(home position)添加为一项要求: ```cpp modeRequirements().home_position = true; ``` -The full list of flags can be found in [requirement_flags.hpp](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/common/requirement_flags.hpp). +标记的完整列表可以在 [requirement_flags.hpp](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/include/px4_ros2/common/requirement_flags.hpp 中找到。 -#### Deferring Failsafes +#### 延迟故障保护 -A mode or mode executor can temporarily defer non-essential failsafes by calling the method [`deferFailsafesSync()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html#a16ec5be6ebe70e1d0625bf696c3e29ae). -To get notified when a failsafe would be triggered, override the method [`void onFailsafeDeferred()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html#ad80a234c8cb2f4c186fa2b7bffd1a1dd). +模式或模式执行器可以通过调用该方法暂时延迟非必要的故障保护。 [`deferFailsafesSync()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html#a16ec5be6ebe70e1d0625bf696c3e29ae). +若想在故障保护即将被触发时收到通知,需重写该方法。 [`void onFailsafeDeferred()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1ModeExecutorBase.html#ad80a234c8cb2f4c186fa2b7bffd1a1dd). -Check the [integration test](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/test/integration/overrides.cpp) for an example. +例如检查[integration test](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/px4_ros2_cpp/test/integration/overrides.cpp)。 -### Assigning a Mode to an RC Switch or Joystick Action +### 将模式指派给 RC 切换或操纵动作 -External modes can be assigned to [RC switches](../config/flight_mode.md) or joystick actions. -When assigning a mode to an RC switch, you need to know the index (because the parameter metadata does not contain the dynamic mode name). -Use `commander status` while the mode is running to get that information. +外部模式可以被分配给[RC switches](../config/flight_mode.md) 或操纵杆动作。 +当将模式分配给RC开关时,你需要知道其索引(因为参数元数据中不包含动态模式名称)。 +在模式运行期间,使用 'commander status'(指令状态)来获取该信息。 例如: @@ -679,23 +726,23 @@ Use `commander status` while the mode is running to get that information. INFO [commander] External Mode 1: nav_state: 23, name: My Manual Mode ``` -means you would select **External Mode 1** in QGC: +意味着你需要在 QGC中选择外部模式 1(External Mode 1) : -![QGC Mode Assignment](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_mode_assignment.png) +![QGC Modes](../../assets/middleware/ros2/px4_ros2_interface_lib/qgc_mode_assignment.png) :::info -PX4 ensures a given mode is always assigned to the same index by storing a hash of the mode name. -This makes it independent of startup ordering in case of multiple external modes. +PX4通过存储模式名称的散列确保指定模式始终分配到同一索引。 +这使它独立于多个外部模式下的启动订购。 ::: -### Replacing an Internal Mode +### 替换内部模式 -An external mode can replace an existing internal mode, such as [Return](../flight_modes/return.md) mode (RTL). -By doing so, whenever RTL gets selected (through the user or a failsafe situation), the external mode is used instead of the internal one. -The internal one is only used as a fallback when the external one becomes unresponsive or crashes. +外部模式可替换现有的内部模式,例如[Return](../flight_modes/return.md) mode (RTL). +这样做,每当选择RTL(通过用户或故障安全情况),就使用外部模式而不是内部模式。 +当外部模式失去响应或发生崩溃时,内部模式仅用作备用模式。 -The replacement mode can be set in the settings of the `ModeBase` constructor: +替换模式可在' ModeBase '构造函数的设置中进行配置: ```cpp -Settings{kName, false, ModeBase::kModeIDRtl} +设置{kName, false, ModeBase::kModeIDRtl} ``` diff --git a/docs/zh/ros2/px4_ros2_interface_lib.md b/docs/zh/ros2/px4_ros2_interface_lib.md index 00cb138ebc..215c9c14f7 100644 --- a/docs/zh/ros2/px4_ros2_interface_lib.md +++ b/docs/zh/ros2/px4_ros2_interface_lib.md @@ -1,48 +1,45 @@ -# PX4 ROS 2 Interface Library +# PX4 ROS 2 接口库 :::warning Experimental -At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. +在撰写本文时,PX4 ROS 2 接口库的部分内容仍处于试验阶段,因此可能会发生变动。 ::: -The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library that simplifies controlling and interacting with PX4 from ROS 2. +The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. -The library provides two high-level interfaces for developers: +该库为开发者提供了两个高级接口。 -1. The [Control Interface](./px4_ros2_control_interface.md) allows developers to create and dynamically register modes written using ROS 2. - It provides classes for sending different types of setpoints, ranging from high-level navigation tasks all the way down to direct actuator controls. -2. The [Navigation Interface](./px4_ros2_navigation_interface.md) enables sending vehicle position estimates to PX4 from ROS 2 applications, such as a VIO system. +1. [Control Interface](./px4_ros2_control_interface.md) 允许开发者创建并动态注册使用 ROS2 编写的模式。 + 它为发送不同类型的设置点提供了课程,涵盖范围从高级导航任务一直到直接执行器控制。 +2. [导航界面](./px4_ros2_navigation_interface.md) 允许从ROS 2应用程序(如VIO系统)向PX4发送车辆位置估计数。 +3. [Waypoint Missions](./px4_ros2_waypoint_missions.md) 允许航点飞行任务完全在ROS2中运行。 - +## 在 ROS 2 工作区中安装 -## Installation in a ROS 2 Workspace +要开始使用现有ROS2工作空间内的库: -To get started using the library within an existing ROS 2 workspace: +1. 请确保您在 ROS 2 工作区中有 [ROS 2 设置](../ros2/user_guide.md) 与 [`px4_msgs`](https://github.com/PX4/px4_msgs]。 -1. Make sure you have a working [ROS 2 setup](../ros2/user_guide.md), with [`px4_msgs`](https://github.com/PX4/px4_msgs) in the ROS 2 workspace. - -2. Clone the repository into the workspace: +2. 将代码仓库克隆到工作空间中 ```sh cd $ros_workspace/src git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib ``` - ::: info - To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. - See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + 提示信息 + 为确保兼容性,请使用 PX4、px4_msgs(PX4 消息包)及该库的最新 main 分支。 + 另请参阅 [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4) ::: -3. Build the workspace: +3. 构建工作空间: ```sh cd .. - colcon build + colcon building source install/setup.bash ``` @@ -50,9 +47,9 @@ To get started using the library within an existing ROS 2 workspace: ## How to Use the Library --> -## CI: Integration Tests +## ROS集成测试 -When opening a pull request to PX4, CI runs the library integration tests. -These test that mode registration, failsafes, and mode replacement, work as expected. +向 PX4 提交拉取请求(pull request)时,持续集成(CI)会运行该库的集成测试 +这些测试用于验证模式注册、故障保护(failsafes)和模式替换功能是否按预期工作。 -For more information see [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md). +欲了解更多信息,请访问[PX4 ROS2 接口库集成测试](../test_and_ci/integration_testing_px4_ros2_interface.md)。 diff --git a/docs/zh/ros2/px4_ros2_msg_translation_node.md b/docs/zh/ros2/px4_ros2_msg_translation_node.md index 2e999b28c1..f60083a53e 100644 --- a/docs/zh/ros2/px4_ros2_msg_translation_node.md +++ b/docs/zh/ros2/px4_ros2_msg_translation_node.md @@ -1,81 +1,82 @@ -# PX4 ROS 2 Message Translation Node +# PX4 ROS 2 消息翻译节点 -The message translation node allows ROS 2 applications that were compiled against different versions of the PX4 messages to interwork with newer versions of PX4, and vice versa, without having to change either the application or the PX4 side. +消息翻译节点允许针对不同版本的 PX4 消息编译的 ROS 2 应用程序与更新版本的 PX4 交互。 反之亦然,而不必更改应用程序或PX4一侧。 ## 综述 -The translation of messages from one definition version to another is possible thanks to the introduction of [message versioning](../middleware/uorb.md#message-versioning). +由于引入了[消息版本](../middleware/uorb.md#message-versioning),将消息从一个定义版本翻译成另一个定义版本是可能的。 -The translation node has access to all message versions previously defined by PX4. -It dynamically observes the DDS data space, monitoring the publications, subscriptions and services originating from either PX4 via the [uXRCE-DDS Bridge](../middleware/uxrce_dds.md), or ROS 2 applications. -When necessary, it converts messages to the current versions expected by both applications and PX4, ensuring compatibility. +翻译节点可以访问之前由 PX4 定义的所有消息版本。 +它积极观察了光盘系统的数据空间,监测出版物。 通过[uXRCE-DDS桥](../middleware/uxrce_dds.md)或外空委2应用源于PX4的订阅和服务。 +必要时,它会将消息转换到应用程序和PX4预期的当前版本,确保兼容性。 -![Overview ROS 2 Message Translation Node](../../assets/middleware/ros2/px4_ros2_interface_lib/translation_node.svg) +![概述ROS 2消息转换节点] +(../../assets/middleware/ros2/px4_ros2_interface_lib/translation_node.svg) -To support the coexistence of different versions of the same messages within the ROS 2 domain, the ROS 2 topic-names for publications, subscriptions, and services include their respective message version as a suffix. -This naming convention takes the form `_v`, as shown in the diagram above. +支持不同版本的同一消息在交战规则2域内共存, 出版、订阅和服务的ROS 2主题名称包括各自的信息版本的后缀。 +这个命名协议的形式为`_v`。 ## 用法 ### 安装 -The following steps describe how to install and run the translation node on your machine. +以下步骤描述如何在您的机器上安装和运行翻译节点。 -1. (Optional) Create a new ROS 2 workspace in which to build the message translation node and its dependencies: +1. (可选) 创建一个新的 ROS2 工作空间,用于构建消息翻译节点及其依赖: - ```sh - mkdir -p /path/to/ros_ws/src - ``` + ```sh + mkdir -p /path/to/ros_ws/src + ``` -2. Run the following helper script to copy the message definitions and translation node into your ROS workspace directory. +2. 运行下面的帮助脚本来复制消息定义并将节点翻译到您的ROS工作区目录。 - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` -3. Build and source the workspace. +3. 构建并源自工作区。 - ```sh - colcon build - source /path/to/ros_ws/install/setup.bash - ``` + ```sh + colcon build + source /path/to/ros_ws/install/setup.bash + ``` -4. Finally, run the translation node. +4. 最后,运行翻译节点。 - ```sh - ros2 run translation_node translation_node_bin - ``` + ```sh + ros2 run translation_node translation_node_bin + ``` - You should see an output similar to: + 您应该看到一个相似的输出: - ```sh - [INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: - [INFO] [1734525720.729594413] [translation_node]: Registered services and versions: - ``` + ```sh + [INFO] [1734525720.729530513] [translation_node]: 注册的 pub/子主题和版本: + [INFO] [1734525720.729594413] [translation_node]: 注册的服务和版本: + ``` -With the translation node running, any simultaneously running ROS 2 application designed to communicate with PX4 can do so, as long as it uses message versions recognized by the node. -The translation node will print a warning if it encounters an unknown topic version. +在正在运行翻译节点时,任何同时运行旨在与 PX4 通信的 ROS 2 应用程序都可以这样做。 只要它使用节点承认的消息版本。 +翻译节点如果遇到未知的主题版本,将打印警告。 :::info -After making a modification in PX4 to the message definitions and/or translation node code, you will need to rerun the steps above from point 2 to update your ROS workspace accordingly. +在 PX4 修改消息定义和/或翻译节点代码后, 您需要从点2重新运行以上步骤来相应更新您的ROS工作区。 ::: -### In ROS Applications +### 在ROS 应用中 -While developing a ROS 2 application that communicates with PX4, it is not necessary to know the specific version of a message being used. -The message version can be added generically to a topic name like this: +开发与 PX4 通信的 ROS 2 应用程序时,不必知道正在使用的消息的特定版本。 +消息版本可以以如以下方式一般添加到主题名称中: :::: tabs :::tab C++ ```c++ -topic_name + "_v" + std::to_string(T::MESSAGE_VERSION) +主题名称+ "_v" + std::to_string(T::MESSAGE_VERSION) ``` ::: @@ -83,30 +84,30 @@ topic_name + "_v" + std::to_string(T::MESSAGE_VERSION) :::tab Python ```python -topic_name + "_v" + VehicleAttitude.MESSAGE_VERSION +主题名称 + "_v" + VehicleAttitude.MESSAGE_VERSION ``` ::: :::: -where `T` is the message type, e.g. `px4_msgs::msg::VehicleAttitude`. +其中‘T’消息类型,例如`px4_msgs::msg::VehicleAttitude`. -For example, the following implements a minimal subscriber and publisher node that uses two versioned PX4 messages and topics: +例如,以下是一个实现最小化订阅者和发布者节点的示例,该节点使用两个带版本的 PX4 消息和主题: :::: tabs :::tab C++ ```c++ -#include -#include -#include -#include +#include <0> +#include <1> +#include <2> +#include <3> // Template function to get the message version suffix // The correct message version is directly inferred from the message defintion -template +template <4> std::string getMessageNameVersion() { if (T::MESSAGE_VERSION == 0) return ""; return "_v" + std::to_string(T::MESSAGE_VERSION); @@ -116,13 +117,13 @@ class MinimalPubSub : public rclcpp::Node { public: MinimalPubSub() : Node("minimal_pub_sub") { // Use template function to define the correct topics automatically - const std::string sub_topic = "/fmu/out/vehicle_attitude" + getMessageNameVersion(); - const std::string pub_topic = "/fmu/in/vehicle_command" + getMessageNameVersion(); + const std::string sub_topic = "/fmu/out/vehicle_attitude" + getMessageNameVersion<5>(); + const std::string pub_topic = "/fmu/in/vehicle_command" + getMessageNameVersion<6>(); - _subscription = this->create_subscription( + _subscription = this->create_subscription<5>( sub_topic, 10, std::bind(&MinimalPubSub::attitude_callback, this, std::placeholders::_1)); - _publisher = this->create_publisher(pub_topic, 10); + _publisher = this->create_publisher<6>(pub_topic, 10); } private: @@ -130,8 +131,8 @@ class MinimalPubSub : public rclcpp::Node { RCLCPP_INFO(this->get_logger(), "Received attitude message."); } - rclcpp::Publisher::SharedPtr _publisher; - rclcpp::Subscription::SharedPtr _subscription; + rclcpp::Publisher<6>::SharedPtr _publisher; + rclcpp::Subscription<5>::SharedPtr _subscription; }; ``` @@ -180,34 +181,34 @@ class MinimalPubSub(Node): :::: -On the PX4 side, the DDS client automatically adds the version suffix if a message definition contains the field `uint32 MESSAGE_VERSION = x`. +在 PX4 侧,如果消息定义包含字段`uint32 MESSAGE_VERSION = x`,DDS客户端自动添加版本后缀。 :::info -Version 0 of a topic means that no `_v` suffix should be added. +主题版本0意味着不应添加`_v`后缀。 ::: -## Development +## 开发 -### Definitions +### 定义 -A **message** defines the data format used for communication, whether over a topic or a service. -Therefore a message can be either a _topic_ message defined by a `.msg` file, or a _service_ message defined by a `.srv` file. +**消息** 定义了用于通信的数据格式,无论是主题还是服务。 +因此,消息可以是 ".msg" 文件定义的 _topic_ 消息,也可以是 ".srv" 文件定义的 _service_ 消息。 -A **versioned message** is a message for which changes are tracked and each change results in a version bump, with the previous state of the definition being stored in history. -The latest version of every message is stored in `msg/versioned/` for topics (or `srv/versioned` for services), and all older versions are stored in `msg/px4_msgs_old/msg/` (or `msg/px4_msgs_old/srv/`). +**版本信息** 是指跟踪更改的消息,每次变更都会导致版本号递增,且定义的历史状态会被保存下来。 +每个消息的最新版本都存储在 `msg/versioned/` 中,用于主题(或`srv/versioned` 用于服务), 所有旧版本都存储在`msg/px4_msgs_old/msg/`(或`msg/px4_msgs_old/srv/`)中。 -A **version translation** defines a bidirectional mapping of the contents of one or more message definition across different versions. -Each translation is stored as a separate `.h` header file under `msg/translation_node/translations/`. -Message translations can be either _direct_ or _generic_. +**版本翻译**定义了一个或多个消息定义的内容在不同版本之间的双向映射。 +每个翻译以单独的 .h 头文件形式存储在 msg/translation_node/translations/ 目录下。 +消息翻译可以是 _direct_或 _generic_。 -- A **direct translation** defines a bidirectional mapping of the contents of a _single_ message between two of its versions. - This is the simpler case and should be preferred if possible. -- A **generic translation** defines a bidirectional mapping of the contents of `n` input messages to `m` output messages across different versions. - This can be used for merging or splitting a message, or when moving a field from one message to another. +- **直接翻译** 定义一个双向映射其两个版本之间消息的内容。 + 这是更简单的情况,在可能的情况下应优先选择。 +- **通用翻译** 定义了双向映射`n`输入消息的内容到不同版本的`m`输出消息。 + 这可用于合并或拆分消息,也可用于将某个字段从一个消息迁移至另一个消息。 ### File Structure -Starting from PX4 v1.16, the PX4-Autopilot `msg/` and `srv/` directories are structured as follows: +从 PX4 v1.16 版本开始,PX4-Autopilot(PX4 自动驾驶系统)的 msg/ 和 srv/ 目录结构如下: ``` PX4-Autopilot @@ -222,15 +223,15 @@ PX4-Autopilot └── versioned/ # Latest versioned service message files ``` -This structure introduces new directories: `versioned/`, `px4_msgs_old/`, and `translation_node/`. +这个结构引入了新的目录:“versioned/`,`px4_msgs_old/`,以及`translation_node/\`。 -#### Directories `msg/versioned/` and `srv/versioned/` +#### 目录`msg/versioned/` 和 `srv/versioned/` -- Contain the current latest version of each message. -- Files in these directories must include a `MESSAGE_VERSION` field to indicate that they are versioned. -- File names follow the conventional naming scheme (without a version suffix). +- 包含每条消息当前的最新版本。 +- 这些目录中的文件必须包含 `MESSAGE_VERSION` 字段以表明它们是版本控制。 +- 文件名遵循常规命名规则(不带版本后缀)。 -Example directory structure: +示例目录结构: ``` PX4-Autopilot @@ -244,13 +245,13 @@ PX4-Autopilot └── VehicleCommand.srv # e.g. MESSAGE_VERSION = 2 ``` -#### Directory `px4_msgs_old/` +#### 目录`px4_msgs_old/` -- Archives the history of all versioned messages, including both topic and service messages (resp. under `msg/` and `srv/` subdirectories). -- Each file includes a `MESSAGE_VERSION` field. -- File names reflect the message's version with a suffix (e.g., `V1`, `V2`). +- 将所有版本信息的历史记录存档,包括主题和服务信息(resp. under `msg/`和`srv/`子目录)。 +- 每个文件都包含一个 MESSAGE_VERSION 字段。 +- 文件名反映了带有后缀的消息版本(如:`V1`、`V2`)。 -Example directory structure (matching the example above): +示例目录结构(匹配上面的示例): ``` ... @@ -264,13 +265,13 @@ Example directory structure (matching the example above): └── VehicleCommandV1.srv ``` -#### Directory `translation_node/` +#### 目录`translation_node/` -- Contains headers for translating between all different versions of messages. -- Each translation (direct or generic) is a single `.h` header file. -- The header `all_translation.h` acts as the main header, and includes all subsequent translation headers. +- 包含用于在所有不同版本的消息之间进行翻译的标题。 +- 每个翻译 (直接或通用) 都是单个的 `.h` 标题文件。 +- 标题`all_translation.h`是主标题,包含所有其后的翻译标题。 -Example directory structure (matching the example above): +示例目录结构(匹配上面的示例): ``` ... @@ -287,166 +288,163 @@ Example directory structure (matching the example above): └── translation_vehicle_command_v2.h # Direct translation v1 <-> latest (v2) ``` -### Updating a Versioned Message +### 正在更新版本信息... -This section provides a step-by-step walkthrough and a basic working example of what the process of changing a versioned message looks like. +本节提供了分步操作指南以及一个基础的可运行示例,以展示修改版本化消息的流程具体是怎样的。 -The example describes the process of updating the `VehicleAttitude` message definition to contain an additional `new_field` entry, incrementing the message version from `3` to `4`, and creating a new direct translation in the process. +该示例描述了更新VehicleAttitude消息定义的流程,具体包括:为其添加一个额外的new_field字段、将消息版本从3递增至4,并在此过程中创建一个新的直接转换。 -1. **Create an Archived Definition of the Current Versioned Message** +1. **创建当前版本信息的存档定义** - Copy the versioned `.msg` topic message file (or `.srv` service message file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`), and append its message version to the file name. + 将版本号的`.msg`主题消息文件(或`.srv`服务消息文件)复制到`px4_msgs_old/msg/`(或`px4_msgs_old/srv/`),并将其消息版本附加到文件名。 - For example:
- Copy `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` + 例如:
+ 复制 `msg/versioned/VehicleAttitude.msg` → `msg/versioned/px4_msgs_old/msg/VehicleAttitudeV3.msg` -2. **Update Translation References to the Archived Definition** +2. **更新对存档定义的转化引用** - Update the existing translations header files `msg/translation_node/translations/*.h` to reference the newly archived message definition. + 更新现有翻译标头文件 `msg/translation_node/translations/*.h` 以参考新存档的消息定义。 - For example, update references in those files:
+ 例如,更新这些文件中的引用:
- - Replace `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` - - Replace `#include ` → `#include ` + - 替换 `px4_msgs::msg::VehicleAttitude` → `px4_msgs_old::msg::VehicleAttitudeV3` + - 替换`#include ` -> \`#include -3. **Update the Versioned Definition** +3. **更新版本定义** - Update the versioned `.msg` topic message file (or `.srv` service message file) with required changes. + 更新版本的 `.msg` 主题消息文件 (或`.srv` 服务消息文件) 并进行必要的更改。 - First increment the `MESSAGE_VERSION` field. - Then update the message fields that prompted the version change. + 第一次递增`MESSAGE_VERSION`字段。 + 然后更新促使版本变更的消息字段。 - For example, update `msg/versioned/VehicleAttitude.msg` from: + 例如,更新 `msg/versioned/vehicleAttitde.msg` 从: - ```txt - uint32 MESSAGE_VERSION = 3 - uint64 timestamp - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 3 + uint64 timestamp + ... + ``` - to + 到 - ```txt - uint32 MESSAGE_VERSION = 4 # Increment - uint64 timestamp - float32 new_field # Make definition changes - ... - ``` + ```txt + uint32 MESSAGE_VERSION = 4 # Increment + uint64 timestamp + float32 new_field # Make definition changes + ``` -4. **Add a New Translation Header** +4. **添加新的翻译标头** - Add a new version translation to bridge the archived version and the updated current version, by creating a new translation header. + 通过创建一个新的翻译标头来添加一个新的版本翻译来连接存档版本和更新的当前版本。 - For example, create a direct translation header `translation_node/translations/translation_vehicle_attitude_v4.h`: + 例如,创建一个直接翻译标题`translation_node/translation_vaille_attitude_v4.h`: - ```c++ - // Translate VehicleAttitude v3 <--> v4 - #include - #include + ```c++ + // Translate VehicleAttitude v3 <--> v4 + #include + #include - class VehicleAttitudeV4Translation { - public: - using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; - static_assert(MessageOlder::MESSAGE_VERSION == 3); + class VehicleAttitudeV4Translation { + public: + using MessageOlder = px4_msgs_old::msg::VehicleAttitudeV3; + static_assert(MessageOlder::MESSAGE_VERSION == 3); - using MessageNewer = px4_msgs::msg::VehicleAttitude; - static_assert(MessageNewer::MESSAGE_VERSION == 4); + using MessageNewer = px4_msgs::msg::VehicleAttitude; + static_assert(MessageNewer::MESSAGE_VERSION == 4); - static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; + static constexpr const char* kTopic = "fmu/out/vehicle_attitude"; - static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { - msg_newer.timestamp = msg_older.timestamp; - msg_newer.timestamp_sample = msg_older.timestamp_sample; - msg_newer.q[0] = msg_older.q[0]; - msg_newer.q[1] = msg_older.q[1]; - msg_newer.q[2] = msg_older.q[2]; - msg_newer.q[3] = msg_older.q[3]; - msg_newer.delta_q_reset = msg_older.delta_q_reset; - msg_newer.quat_reset_counter = msg_older.quat_reset_counter; + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.timestamp_sample = msg_older.timestamp_sample; + msg_newer.q[0] = msg_older.q[0]; + msg_newer.q[1] = msg_older.q[1]; + msg_newer.q[2] = msg_older.q[2]; + msg_newer.q[3] = msg_older.q[3]; + msg_newer.delta_q_reset = msg_older.delta_q_reset; + msg_newer.quat_reset_counter = msg_older.quat_reset_counter; - // Populate `new_field` with some value - msg_newer.new_field = -1; - } + // Populate `new_field` with some value + msg_newer.new_field = -1; + } - static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { - msg_older.timestamp = msg_newer.timestamp; - msg_older.timestamp_sample = msg_newer.timestamp_sample; - msg_older.q[0] = msg_newer.q[0]; - msg_older.q[1] = msg_newer.q[1]; - msg_older.q[2] = msg_newer.q[2]; - msg_older.q[3] = msg_newer.q[3]; - msg_older.delta_q_reset = msg_newer.delta_q_reset; - msg_older.quat_reset_counter = msg_newer.quat_reset_counter; + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.timestamp_sample = msg_newer.timestamp_sample; + msg_older.q[0] = msg_newer.q[0]; + msg_older.q[1] = msg_newer.q[1]; + msg_older.q[2] = msg_newer.q[2]; + msg_older.q[3] = msg_newer.q[3]; + msg_older.delta_q_reset = msg_newer.delta_q_reset; + msg_older.quat_reset_counter = msg_newer.quat_reset_counter; - // Discards `new_field` from MessageNewer - } - }; + // Discards `new_field` from MessageNewer + } + }; + ``` - REGISTER_TOPIC_TRANSLATION_DIRECT(VehicleAttitudeV4Translation); - ``` + 版本翻译模板在此提供: - Version translation templates are provided here: + - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) + - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) + - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) - - [Direct Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_direct_v1.h) - - [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) - - [Direct Service Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_service_v1.h) +5. **在`all_translations.h`中包含新标头** -5. **Include New Headers in `all_translations.h`** + 将所有新创建的标题添加到[`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h),以便翻译节点能够找到它们。 - Add all newly created headers to [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/all_translations.h) so that the translation node can find them. + 例如,在`all_translation.h`上加上以下一行: - For example, append the following line to `all_translation.h`: + ```c++ + #include "translation_vehicle_attitude_v4.h" + ``` - ```c++ - #include "translation_vehicle_attitude_v4.h" - ``` +请注意,在上述示例中以及在大多数情况下,步骤 4 仅要求开发者针对此次定义变更创建一个直接转换。 +这是因为更改只涉及一个消息。 +在更复杂的分割、合并和/或移动定义的情况下,必须创建一个通用转化。 -Note that in the example above and in most cases, step 4 only requires the developer to create a direct translation for the definition change. -This is because the changes only involved a single message. -In more complex cases of splitting, merging and/or moving definitions then a generic translation must be created. +例如,当一个字段从一个消息移动到另一个消息时。 应增加一个单一通用翻译,两个较旧的信息版本作为输入,两个较新的版本作为输出。 +这就确保了在向前或向后翻译时不会丢失信息。 -For example when moving a field from one message to another, a single generic translation should be added with the two older message versions as input, and the two newer versions as output. -This ensures there is no information lost when translating forward or backward. - -This is exactly the approach shown by the [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h), omitting only the code for actually modifying fields in the `fromOlder()` and `toOlder()` methods. +这正是 [Generic Topic Message Translation Template](https://github.com/PX4/PX4-Autopilot/blob/main/msg/translation_node/translations/example_translation_multi_v2.h) 所显示的方法。 只省略`fromOlder()` 和 `toOlder()` 方法中的字段的代码。 :::warning -If a nested message definition changes, all messages including that message also require a version update. -For example this would be the case for message [PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md) if it were versioned. -This is primarily important for services which are more likely reference other message definitions. +如果嵌套消息定义发生了变化,包括该消息在内的所有消息也需要版本更新。 +例如,如果消息 [PositionSetpointTriplet](../msg_docs/PositionSetpointTriplet.md)有版本,将会出现这种情况。 +这一点对于服务而言尤为重要,因为服务更有可能引用其他消息定义。 ::: -## Implementation Details +## 实现细节 -The translation node dynamically monitors the topics and services. -It then instantiates the counterside of the publications and subscribers as required. -For example if there is an external publisher for version 1 of a topic and subscriber for version 2. +转换节点动态监测主题和服务。 +然后视需要举例说明出版物和订阅者的对应情况。 +例如,如果主题第1版有外部发行商,第2版则有订阅商。 -Internally, it maintains a graph of all known topic and version tuples (which are the graph nodes). -The graph is connected by the message translations. -As arbitrary message translations can be registered, the graph can have cycles and multiple paths from one node to another. -Therefore on a topic update, the graph is traversed using a shortest path algorithm. -When moving from one node to the next, the message translation method is called with the current topic data. -If a node contains an instantiated publisher (because it previously detected an external subscriber), the data is published. -Thus, multiple subscribers of any version of the topic can be updated with the correct version of the data. +在内部,它保存一份所有已知主题和版本管束的图表(即图节点)。 +该图通过消息转换实现连接。 +由于任意的消息转换可以注册,图可以有周期和从一个节点到另一个节点的多个路径。 +因此,在主题更新中,图形使用最短路径算法。 +当从一个节点移动到另一个节点时,消息翻译方法将与当前主题数据调用。 +如果节点包含实例化发布器 (因为它先前检测到外部订阅者),数据将被发布。 +这样,本专题任何版本的多个订阅者都可以用正确的数据更新数据。 -For translations with multiple input topics, the translation continues once all input messages are available. +对于有多个输入主题的转化,转化将在所有输入消息都可用后继续。 ## 局限 -- Translation of service messages does not work on ROS Humble, but does on ROS Jazzy. - This is because the current implementation depends on a service API that is not yet available in ROS Humble. - Translation of topic messages is fully supported. -- Services messages only support a linear history, i.e. no message splitting or merging. -- Having both publishers and subscribers for two different versions of the same topic is currently not handled by the translation node and would trigger infinite circular publications. - This refers to the following problematic configuration: +- 服务消息的转化不适用于 ROS Humble,而是适用于ROSJazzy。 + 这是因为当前的实现取决于尚未在ROS人类中提供的服务 API 。 + 完全支持主题信息转化。 +- 服务消息只支持线性历史记录,即没有消息拆分或合并。 +- 两个不同版本的同一主题的出版商和订户目前都不是由转化节点处理的,会引发无限的循环出版物。 + 这是指下列有问题的配置: ``` app 1: pub topic_v1, sub topic_v1 app 2: pub topic_v2, sub topic_v2 ``` - In practice this configuration is unlikely to occur because ROS topics shared with the FMU are intended to be directional (e.g. `/fmu/out/vehicle_status` or `/fmu/in/trajectory_setpoint`), therefore apps typically do not publish and subscribe simultaneously to the same topic. - The translation node could be extended to handle this corner-case if required. + 实际上,这种配置不大可能发生,因为与金融监督单位共享的外空系统专题是指向的(例如)。 `/fmu/out/vehicle_status` 或 `/fmu/in/tracjectory_setpoint` ,因此应用通常不会同时发布和订阅相同的主题。 + 如果需要,可以扩展翻译节点来处理这个卷轴。 -Original document with requirements: https://docs.google.com/document/d/18_RxV1eEjt4haaa5QkFZAlIAJNv9w5HED2aUEiG7PVQ/edit?usp=sharing +需要原始文件:https://docs.google.com/document/d/18_RxV1eEjt4haaa5QkFZAlIAJNv9w5HED2aUEiG7PVQ/edit?usp=sharing diff --git a/docs/zh/ros2/px4_ros2_navigation_interface.md b/docs/zh/ros2/px4_ros2_navigation_interface.md index f96d2683fe..5ef18c1879 100644 --- a/docs/zh/ros2/px4_ros2_navigation_interface.md +++ b/docs/zh/ros2/px4_ros2_navigation_interface.md @@ -1,127 +1,127 @@ -# PX4 ROS 2 Navigation Interface +# PX4 ROS2 导航接口 :::warning Experimental -At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. +在撰写本文时,PX4 ROS 2 接口库的部分内容仍处于试验阶段,因此可能会发生变动。 ::: -The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) navigation interface enables developers to send their position measurements to PX4 directly from ROS 2 applications, such as a VIO system or a map matching system. -The interface provides a layer of abstraction from PX4 and the uORB messaging framework, and introduces a few sanity checks on the requested state estimation updates sent via the interface. -These measurements are then fused into the EKF just as though they were internal PX4 measurements. +[PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) 中的导航接口,支持开发者直接从 ROS 2 应用(如视觉惯性里程计系统或地图匹配系统)向 PX4 发送位置测量数据。 +该接口提供了对 PX4 和 uORB 消息框架的抽象层,并对通过该接口发送的请求状态估计更新引入了一些合理性检查。 +这些测量数据随后会被融合到扩展EKF中,其处理方式与 PX4 内部生成的测量数据完全一致。 -The library provides two classes, [`LocalPositionMeasurementInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html) and [`GlobalPositionMeasurementInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html), which both expose a similar `update` method to provide either a local position or global position update to PX4, respectively. -The `update` method expects a position measurement `struct` ([`LocalPositionMeasurement`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1LocalPositionMeasurement.html) or [`GlobalPositionMeasurement`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1GlobalPositionMeasurement.html)) which developers can populate with their own generated position measurements. +库提供两个类,[`LocalPositionMeasurementInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html) 和 [`GlobalPositionMeasureInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html) 它都会暴露出一个类似的 "update" 方法来提供一个本地位置或全球位置更新到 PX4。 +`update`方法需要一个位置测量`struct`(`LocalPositionMeasure`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1LocalPositionMeasurement.html)或[\`GlobalPositionMeasure\`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1GlobalPositionMeasurement.html)],开发者可以在其中填入自己生成的位置测量数据。 -## Installation and First Test +## 安装与首次测试 -The following steps are required to get started: +开始使用前,需完成以下步骤: -1. Make sure you have a working [ROS 2 setup](../ros2/user_guide.md), with [`px4_msgs`](https://github.com/PX4/px4_msgs) in the ROS 2 workspace. +1. 请确保您在 ROS 2 工作区中有 [ROS 2 设置](../ros2/user_guide.md) 与 [`px4_msgs`](https://github.com/PX4/px4_msgs]。 -2. Clone the repository into the workspace: +2. 将代码仓库克隆到工作空间中 - ```sh - cd $ros_workspace/src - git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib - ``` + ```sh + cd $ros_workspace/src + git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib + ``` - ::: info - To ensure compatibility, use the latest _main_ branches for PX4, _px4_msgs_ and the library. - See also [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4). + 提示信息 + 为确保兼容性,请使用 PX4、px4_msgs(PX4 消息包)及该库的最新 main 分支。 + 另请参阅 [here](https://github.com/Auterion/px4-ros2-interface-lib#compatibility-with-px4) ::: -3. Build the workspace: +3. 构建工作空间: - ```sh - cd .. - colcon build - ``` + ```sh + cd .. + colcon版本 + ``` -4. In a different shell, start PX4 SITL: +4. 在另一个外壳中,启动 PX4 SITL: - ```sh - cd $px4-autopilot - make px4_sitl gazebo-classic - ``` + ```sh + cd $px4-autopilot + make px4_sitl gazebo-classic + ``` - (here we use Gazebo-Classic, but you can use any model or simulator) + (这里我们使用Gazebo-Classic,但你可以使用任何模型或模拟器) -5. In yet a different shell, run the micro XRCE agent (you can keep it running afterward): +5. 在另一个独立的终端中,运行 micro XRCE 代理(运行后可保持后台持续运行): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` -6. Back in the ROS 2 terminal, source the workspace you just built (in step 3) and run the [global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation/global_navigation) example, which periodically sends dummy global position updates: +6. 返回ROS2终端,为您刚刚构建的工作空间(步骤3),运行 [global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation/global_navigation) 示例。 它会周期性地发送虚拟的全球位置更新(数据): - ```sh - source install/setup.bash - ros2 run example_global_navigation_cpp example_global_navigation - ``` + ```sh + source install/setup.bash + ros2 run example_global_navigation_cpp example_global_navigation + ``` - You should get an output like this showing that the global interface is successfully sending position updates: + 你应会看到如下所示的输出,该输出表明全球位置接口正成功发送位置更新: - ```sh - [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! - [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. - [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. - ``` + ```sh + [INFO] [1702030701.836897756] [example_global_navigation_node]: example_global_navigation_node running! + [DEBUG] [1702030702.837279784] [example_global_navigation_node]: Successfully sent position update to navigation interface. + [DEBUG] [1702030703.837223884] [example_global_navigation_node]: Successfully sent position update to navigation interface. + ``` -7. In the PX4 shell, you can check that PX4 receives global position updates: +7. 在 PX4 终端(PX4 shell)中,你可以通过以下操作检查 PX4 是否接收到全球位置更新(数据) - ```sh - listener aux_global_position - ``` + ```sh + listener aux_global_position + ``` - The output should look like: + 输出内容应如下所示: - ```sh - TOPIC: aux_global_position - aux_global_position - timestamp: 46916000 (0.528000 seconds ago) - timestamp_sample: 46916000 (0 us before timestamp) - lat: 12.343210 - lon: 23.454320 - alt: 12.40000 - alt_ellipsoid: 0.00000 - delta_alt: 0.00000 - eph: 0.31623 - epv: 0.44721 - terrain_alt: 0.00000 - lat_lon_reset_counter: 0 - alt_reset_counter: 0 - terrain_alt_valid: False - dead_reckoning: False - ``` + ```sh + TOPIC: aux_global_position + aux_global_position + timestamp: 46916000 (0.528000 seconds ago) + timestamp_sample: 46916000 (0 us before timestamp) + lat: 12.343210 + lon: 23.454320 + alt: 12.40000 + alt_ellipsoid: 0.00000 + delta_alt: 0.00000 + eph: 0.31623 + epv: 0.44721 + terrain_alt: 0.00000 + lat_lon_reset_counter: 0 + alt_reset_counter: 0 + terrain_alt_valid: False + dead_reckoning: False + ``` -8. Now you are ready to use the navigation interface to send your own position updates. +8. 现在你已准备好使用该导航接口发送自己的位置更新数据了。 -## How to use the Library +## 如何使用代码库 -To send a position measurement, you populate the position struct with the values you have measured. -Then call the interface's update function with that struct as the argument. +要发送位置测量数据,你需要用所测量的值填充位置结构体。 +然后以此结构调用接口的更新功能作为参数。 -For a basic example of how to use this interface, check out the [examples](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation) in the `Auterion/px4-ros2-interface-lib` repository, such as [examples/cpp/navigation/local_navigation](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/navigation/local_navigation/include/local_navigation.hpp) or [examples/cpp/navigation/global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/navigation/local_navigation/include/global_navigation.hpp). +关于如何使用此接口的基本示例,请在“Auterion/px4-ros2-interface-lib”仓库中查看 [examples](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/navigation) 例如[示例/cpp/navigation/local_navigation](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/navigation/local_navigation/include/local_navigation.hpp)或[示例/cpp/navigation/global_navigation](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/examples/cpp/navigation/local_navigation/include/global_navigation.hpp)。 -### Local Position Updates +### 局部位置更新 -First ensure that the PX4 parameter [`EKF2_EV_CTRL`](../advanced_config/parameter_reference.md#EKF2_EV_CTRL) is properly configured to fuse external local measurements, by setting the appropriate bits to `true`: +首先确保正确配置 PX4 参数[`EKF2_EV_CTRL`](../advanced_config/parameter_reference.md#EKF2_EV_CTRL)通过将相应的位设置为true,可以正确配置(系统)以融合外部局部测量数据: -- `0`: Horizontal position data -- `1`: Vertical position data -- `2`: Velocity data -- `3`: Yaw data +- `0`: 水平位置数据 +- `1`:垂直位置数据 +- `2`:速度数据 +- `3`:偏航角数据 -To send a local position measurement to PX4: +向PX4发送局部位置测量: -1. Create a [`LocalPositionMeasurementInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html) instance by providing it with: a ROS node, and the pose and velocity reference frames of your measurements. -2. Populate a [`LocalPositionMeasurement`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1LocalPositionMeasurement.html) `struct` with your measurements. -3. Pass the `struct` to the `LocalPositionMeasurementInterface` [`update()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html#a6fd180b944710716d418b2cfe1c0c8e3) method. +1. 通过提供一个 ROS节点,创建一个 [`localPositionMeasureInterface` ](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html) 实例:您测量的位置和速度参考框架。 +2. 包含一个[`本地定位测量`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1LocalPositionMeasurement.html) `structt` ,包含你测量的数据。 +3. 将 `struct` 传入 `LocalPositionMeasurementInterface` [`update()`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1LocalPositionMeasurementInterface.html#a6fd180b944710716d418b2cfe1c0c8e3) 方法中。 -The available pose and velocity reference frames for your measurements are defined by the following `enum`: +你的测量数据可用的位置和速度参考坐标系由以下枚举(enum)定义: ```cpp enum class PoseFrame @@ -140,36 +140,36 @@ enum class VelocityFrame }; ``` -The `LocalPositionMeasurement` struct is defined as follows: +`LocalPositionMeasurement`结构定义如下: ```cpp struct LocalPositionMeasurement { rclcpp::Time timestamp_sample {}; - std::optional position_xy {std::nullopt}; - std::optional position_xy_variance {std::nullopt}; - std::optional position_z {std::nullopt}; - std::optional position_z_variance {std::nullopt}; + std::optional<0> position_xy {std::nullopt}; + std::optional<0> position_xy_variance {std::nullopt}; + std::optional<1> position_z {std::nullopt}; + std::optional<1> position_z_variance {std::nullopt}; - std::optional velocity_xy {std::nullopt}; - std::optional velocity_xy_variance {std::nullopt}; - std::optional velocity_z {std::nullopt}; - std::optional velocity_z_variance {std::nullopt}; + std::optional<0> velocity_xy {std::nullopt}; + std::optional<0> velocity_xy_variance {std::nullopt}; + std::optional<1> velocity_z {std::nullopt}; + std::optional<1> velocity_z_variance {std::nullopt}; - std::optional attitude_quaternion {std::nullopt}; - std::optional attitude_variance {std::nullopt}; + std::optional<2> attitude_quaternion {std::nullopt}; + std::optional<3> attitude_variance {std::nullopt}; }; ``` -The `update()` method of the local interface expects the following conditions to hold for `LocalPositionMeasurement`: +局部接口的update()方法要求LocalPositionMeasurement(局部位置测量结构体)满足以下条件: -- The sample timestamp is defined. -- Values do not have a \`NAN\`\`. -- If a measurement value is provided, its associated variance value is well defined (e.g. if `position_xy` is defined, then `position_xy_variance` must be defined). -- If a measurement value is provided, its associated reference frame is not unknown (e.g. if `position_xy` is defined, then the interface was initialised with a pose frame different from `PoseFrame::Unknown`). +- 示例时间戳已定义。 +- 数值不得包含 `NAN` 。 +- 如果提供了某个测量值,则其关联的方差值必须明确定义(例如,若position_xy已定义,则position_xy_variance也必须定义)。 +- 如果提供了某个测量值,那么其关联的参考坐标系不得为 “未知”(例如,若position_xy已定义,则接口必须以不同于PoseFrame::Unknown的位置坐标系进行初始化)。 -The following code snippet is an example of a ROS 2 node which uses the local navigation interface to send 3D pose updates in the North-East-Down (NED) reference frame to PX4: +以下是一个 ROS 2 节点的示例代码片段,该节点使用局部导航接口向 PX4 发送东北天(NED)参考坐标系下的 3D 位姿更新: ```cpp class MyLocalMeasurementUpdateNode : public rclcpp::Node @@ -185,7 +185,7 @@ public: const px4_ros2::VelocityFrame velocity_frame = px4_ros2::VelocityFrame::Unknown; // Initialize local interface [1] _local_position_measurement_interface = - std::make_shared(*this, pose_frame, velocity_frame); + std::make_shared(*this, pose_frame, velocity_frame); } void sendUpdate() @@ -217,45 +217,44 @@ public: } private: - std::shared_ptr _local_position_measurement_interface; + std::shared_ptr _local_position_measurement_interface; }; ``` -### Global Position Updates +### 全局位置更新 -First ensure that the PX4 parameter [`EKF2_AGP_CTRL`](../advanced_config/parameter_reference.md#EKF2_AGP_CTRL) is properly configured to fuse external global measurements, by setting the appropriate bits to `true`: +首先确保正确配置 PX4 参数[`EKF2_EV_CTRL`](../advanced_config/parameter_reference.md#EKF2_AGP_CTRL)通过将相应的位设置为true,可以正确配置(系统)以融合外部全部测量数据: -- `0`: Horizontal position data -- `1`: Vertical position data +- `0`: 水平位置数据 +- `1`:垂直位置数据 -To send a global position measurement to PX4: +向PX4发送全局位置测量: -1. Create a [`GlobalPositionMeasurementInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html) instance by providing it with a ROS node. -2. Populate a [`GlobalPositionMeasurement`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1GlobalPositionMeasurement.html) `struct` with your measurements. -3. Pass the struct to the `GlobalPositionMeasurementInterface` [update()](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html#a1a183b595ef7f6a22f3a83ba543fe86d) method. +1. 创建一个 [`GlobalPositionMeasureInterface`](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html) 实例,并提供一个 ROS节点。 +2. 包含一个[`GlobalPositionMeasurement`](https://auterion.github.io/px4-ros2-interface-lib/structpx4__ros2_1_1GlobalPositionMeasurement.html) `struct` ,包含你测量的数据。 +3. 将结构移至`GlobalPositionMeasurementInterface` [update()](https://auterion.github.io/px4-ros2-interface-lib/classpx4__ros2_1_1GlobalPositionMeasurementInterface.html#a1a183b595ef7f6a22f3a83ba543fe86d) 方法中。 -The `GlobalPositionMeasurement` struct is defined as follows: +`GlobalPositionMeasurement`结构定义如下: ```cpp struct GlobalPositionMeasurement { rclcpp::Time timestamp_sample {}; - std::optional lat_lon {std::nullopt}; - std::optional horizontal_variance {std::nullopt}; + std::optional lat_lon {std::nullopt}; + std::optional<1> horizontal_variance {std::nullopt}; - std::optional altitude_msl {std::nullopt}; - std::optional vertical_variance {std::nullopt}; -}; + std::optional<1> altitude_msl {std::nullopt}; + std::optional<1> vertical_variance {std::nullopt}; ``` -The `update()` method of the global interface expects the following conditions to hold for `GlobalPositionMeasurement`: +全局接口的 `update()` 方法预计在 `GlobalPositionMeasurement` 中保留以下条件: -- The sample `timestamp_sample` is defined. -- Values do not have a NAN. -- If a measurement value is provided, its associated variance value is well defined (e.g. if `lat_lon` is defined, then `horizontal_variance` must be defined). +- 样本`timestamp_sample`已定义。 +- 数据不得包含NAN。 +- 如果提供了某个测量值,那么其关联的方差值必须明确定义(例如,若lat_lon(经纬度)已定义,则horizontal_variance(水平方差)也必须定义)。 -The following code snippet is an example of a ROS 2 node which uses the global navigation interface to send a measurement with latitude, longitude and altitude to PX4: +下面的代码片段是一个 ROS 2 节点的示例,该节点使用全局导航接口来发送一个测量纬度。 经度和高度到 PX4: ```cpp class MyGlobalMeasurementUpdateNode : public rclcpp::Node @@ -266,7 +265,7 @@ public: { // Initialize global interface [1] _global_position_measurement_interface = - std::make_shared(*this); + std::make_shared(*this); } void sendUpdate() @@ -298,11 +297,11 @@ public: } private: - std::shared_ptr _global_position_measurement_interface; + std::shared_ptr<0> _global_position_measurement_interface; }; ``` -## Multiple Instances of an Interface +## 接口的多个实例 -Using multiple instances of the same interface (e.g. local and local) to send estimation updates will stream all update messages to the same topic and result in cross-talk. -This should not affect measurement fusion into the EKF, but different measurement sources will become indistinguishable. +使用同一接口的多个实例(例如,多个局部接口实例)发送估计更新时,会将所有更新消息发送到同一个主题,从而导致串扰。 +这不应影响计量并入EKF,但不同的计量来源将无法区分。 diff --git a/docs/zh/ros2/px4_ros2_waypoint_missions.md b/docs/zh/ros2/px4_ros2_waypoint_missions.md new file mode 100644 index 0000000000..d82fc2d543 --- /dev/null +++ b/docs/zh/ros2/px4_ros2_waypoint_missions.md @@ -0,0 +1,190 @@ +# PX4 ROS 2 Waypoint Missions + + + +The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) provides a high-level interface for executing ROS-based waypoint missions in ROS 2. +The main use-case is for creating missions where a custom behavior is required, such as a pickup action within a mission. + +:::warning +ROS 2 missions are not compatible with MAVLink mission definitions, plan files, or ground stations. +They completely bypass the existing PX4 mission mode and waypoint logic, and cannot be planned or displayed within a ground station. +::: + +ROS 2 waypoint missions are effectively special PX4 ROS 2 custom modes that are run based on the content of a [JSON mission definition](#mission-definition). +Mission definitions can contain actions that reference existing PX4 modes, such as Takeoff mode or RTL, and can also be extended with arbitrary custom actions written in ROS. +A [mode executor](px4_ros2_control_interface.md#mode-executor) is used to schedule the modes. + +Mission definitions can be hard coded in the custom mission mode (either in code or statically loaded from a JSON string), or directly generated within the application. +They can also be dynamically loaded based on modification of a particular JSON file — this allows for building a more generic mission framework with a fixed set of custom actions. +The file can then be written by any other application, for example a HTTP or MAVFTP server. + +The current implementation only supports multicopters but is designed to be extendable to any other vehicle type. + +## Comparison to PX4/MAVLink Missions + +There are some benefits and drawbacks to using ROS-based missions, which are provided in the following paragraphs. + +### Benefits + +- Allows to extend mission capabilities by registering custom actions. +- More control over how the mission is executed. + A custom trajectory executor can be implemented, which can use any of the existing PX4 setpoint types to track the trajectory. +- Reduced complexity on the flight controller side by running non-safety-critical and non-real-time code on a more high-level companion computer. +- It can be extended to support other trajectory types, like Bezier or Dubin curves. + +### Drawbacks + +- QGroundControl currently does not display the mission or progress during execution, and cannot upload or download a mission. + Therefore you will need another mechanism to provide a mission, such as from a web server, a custom GCS, or by generating it directly inside the application. +- The current implementation only supports multicopters (it uses the [GotoSetpointType](../ros2/px4_ros2_control_interface.md#go-to-setpoint-multicoptergotosetpointtype), which only works for multicopters, and VTOL in MC mode). + It is designed to be extendable to any other vehicle type. + +## 综述 + +This diagram provides a conceptual overview of the main classes and their interactions: + +![Waypoint missions overview diagram](../../assets/middleware/ros2/px4_ros2_interface_lib/waypoint_missions.svg) + + + +Missions can be defined in [JSON](#mission-definition), either as a file, or directly inside the application. +There is a file change monitor (`MissionFileMonitor`), that can be used to automatically load a mission from a specific file whenever it is created by another application (e.g. upload via MAVFTP or a cloud service). + +The **`MissionExecutor`** class contains the state machine to progress the mission index, and is at the core of the implementation: + +- Internally, it builds on top of the [Modes and Mode Executors](px4_ros2_control_interface.md#overview) and registers itself through a custom mode and executor with PX4. +- It handles switching in and out of missions: it gets activated when the user switches to the custom mode that represents the mission and the vehicle is armed. + The mode name can be customized (`My Mission` in the example below). + The mission can be paused, which makes the vehicle switch into _Hold mode_. + To resume the mission, the custom mode has to be selected again. +- When an action switches into another mode (for example Takeoff), QGroundControl will display this mode until it is completed. + The mission executor will then automatically continue. +- Custom actions can be registered. +- The mission can be set. + It then checks that all the actions which the mission defines are available and can be run. +- The state can be stored persistently by providing a file name, allowing for battery swapping. + +The **`ActionInterface`** is an interface class for custom actions. +They are identified by a name, and any number of these can be registered with the `MissionExecutor`. +A custom action is then run whenever a mission item with matching name is executed, and any extra arguments from the JSON definition are passed as arguments (for example an altitude for a takeoff action). +Actions can call other actions, run any mode (PX4 or external by its ID), run a trajectory, or run any other external action before deciding when to continue the mission. + +There is a set of default actions, for example for RTL, Land, etc. +These simply trigger the corresponding PX4 mode. +They can be disabled or replaced with custom implementations. +There are also some special actions (which can be replaced as well): + +- `OnFailure`: this is called in case of a failure, e.g. a mode switch failed, a non-existing action is called (by another action) or by an explicit call to `MissionExecutor::abort()`. + The default is to run RTL, with fallback to Land. +- `OnResume`: this is called when resuming a mission (either from the ground or in-air). + It handles a number of cases: + - when called with an argument `action="storeState"`: this can be used to store the current position when the mission is deactivated, so it can be resumed from the same position. + Currently it does not store anything. + - otherwise, when called without a valid mission index or 0, it directly continues. + - otherwise, when called while in-air, it also directly continues. + - otherwise, if landed and if the current mission item is an action that supports resuming from landed, it continues to let the action handle the resuming. + - otherwise, if landed, it finds the takeoff action from the mission, runs it, and then flies to the previous waypoint from the current index to continue the mission. +- `ChangeSettings`: this can be used to change the mission settings, such as the velocity. + The settings are applied to all following items in the mission. + +The **`TrajectoryExecutorInterface`** is an interface class to execute segments of a trajectory. +It can use any setpoint that PX4 and the current vehicle supports for tracking the trajectory. +This class is vehicle-type specific. +The current default implementation (`multicopter::WaypointTrajectoryExecutor`) uses a Goto setpoint (and thus is limited to multicopters). +The default can be replaced with a custom implementation. + +## 用法 + +The following provides a small example. +It defines a custom action and a mission that uses it. + +```c++ +class CustomAction : public px4_ros2::ActionInterface { +public: + CustomAction(px4_ros2::ModeBase & mode) : _node(mode.node()) { } + + std::string name() const override {return "customAction";} + + void run( + const std::shared_ptr & handler, + const px4_ros2::ActionArguments & arguments, + const std::function & on_completed) override + { + RCLCPP_INFO(_node.get_logger(), "Running custom action"); + // Do something... + + on_completed(); + } +private: + rclcpp::Node & _node; +}; + +class MyMission { +public: + MyMission(const std::shared_ptr & node) : _node(node) + { + const auto mission = px4_ros2::Mission(nlohmann::json::parse(R"( + { + "version": 1, + "mission": { + "items": [ + { + "type": "takeoff" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.3977419, + "y": 8.5455939, + "z": 500, + "frame": "global" + }, + { + "type": "navigation", + "navigationType": "waypoint", + "x": 47.39791657, + "y": 8.54595214, + "z": 500, + "frame": "global" + }, + { + "type": "customAction" + }, + { + "type": "rtl" + } + ] + } + } +)")); + _mission_executor = std::make_unique("My Mission", + px4_ros2::MissionExecutor::Configuration().addCustomAction(), *node); + + if (!_mission_executor->doRegister()) { + throw std::runtime_error("Failed to register mission executor"); + } + _mission_executor->setMission(mission); + + _mission_executor->onProgressUpdate([&](int current_index) { + RCLCPP_INFO(_node->get_logger(), "Current mission index: %i", current_index); + }); + _mission_executor->onCompleted([&] { + RCLCPP_INFO(_node->get_logger(), "Mission completed callback"); + }); + } + +private: + std::shared_ptr _node; + std::unique_ptr _mission_executor; +}; +``` + +A full example with a few custom actions can be found under [github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include](https://github.com/Auterion/px4-ros2-interface-lib/tree/main/examples/cpp/modes/mission/include). + +## Mission Definition + +The mission JSON file can contain mission defaults and a list of mission items, including user-defined types with custom arguments. +Waypoint coordinates currently need to be defined in global frame, and other frame types might be added in future. + +The schema can be found under [github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml](https://github.com/Auterion/px4-ros2-interface-lib/blob/main/mission/schema.yaml). +It provides more details and can be used to validate a JSON file. diff --git a/docs/zh/ros2/user_guide.md b/docs/zh/ros2/user_guide.md index 222ea662fa..1820e623c3 100644 --- a/docs/zh/ros2/user_guide.md +++ b/docs/zh/ros2/user_guide.md @@ -5,11 +5,11 @@ ROS 2-PX4 架构在ROS 2和PX4之间进行了深度整合。 允许 ROS 2 订阅 本指南介绍了系统架构和应用程序流程,并解释了如何与PX4一起安装和使用ROS2。 :::info -From PX4 v1.14, ROS 2 uses [uXRCE-DDS](../middleware/uxrce_dds.md) middleware, replacing the _FastRTPS_ middleware that was used in version 1.13 (v1.13 does not support uXRCE-DDS). +从 PX4 v1.14, ROS 2 使用 [uXRCE-DDS](../middleware/uxrce_dds.md) 中间件替换版本 1 中使用的 _FastRTPS_ 中间件. 3 (v1.13不支持uXRCE-DDS)。 -The [migration guide](../middleware/uxrce_dds.md#fast-rtps-to-uxrce-dds-migration-guidelines) explains what you need to do in order to migrate ROS 2 apps from PX4 v1.13 to PX4 v1.14. +[migration guide](../middleware/uxrce_dds.md#fast-rtps-to-uxrce-dds-migration-guidelines) 解释您需要做什么来将ROS2 应用程序从 PX4 v1.13 迁移到 PX4 v1.14。 -If you're still working on PX4 v1.13, please follow the instructions in the [PX4 v1.13 Docs](https://docs.px4.io/v1.13/en/ros/ros2_comm.html). +如果您仍然在 PX4 v1.13 上工作,请按照[PX4 v1.13 Docs](https://docs.px4.io/v1.13/en/ros/ros2_comm.html)中的说明操作。 @@ -17,66 +17,66 @@ If you're still working on PX4 v1.13, please follow the instructions in the [PX4 ## 综述 -The application pipeline for ROS 2 is very straightforward, thanks to the use of the [uXRCE-DDS](../middleware/uxrce_dds.md) communications middleware. +得益于 [uXRCE-DDS](../middleware/uxrce_dds.md) 通信中间件的使用,ROS 2 的应用流程非常简单直接。 ![Architecture uXRCE-DDS with ROS 2](../../assets/middleware/xrce_dds/architecture_xrce-dds_ros2.svg) -The uXRCE-DDS middleware consists of a client running on PX4 and an agent running on the companion computer, with bi-directional data exchange between them over a serial, UDP, TCP or custom link. -The agent acts as a proxy for the client to publish and subscribe to topics in the global DDS data space. +uXRCE-DDS 中间件由两部分组成:一部分是运行在 PX4 上的客户端,另一部分是运行在机载计算机上的代理;二者之间通过串口、UDP、TCP或自定义链路进行双向数据交换。 +代理充当客户端的代理角色,以便在全局 DDS 数据空间中发布和订阅主题。 -The PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) is generated at build time and included in PX4 firmware by default. -It includes both the "generic" micro XRCE-DDS client code, and PX4-specific translation code that it uses to publish to/from uORB topics. -The subset of uORB messages that are generated into the client are specified in [dds_topics.yaml](../middleware/dds_topics.md). -The generator uses the uORB message definitions in the source tree: [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg) to create the code for sending ROS 2 messages. +PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) 是在构建时生成,并且默认包含在 PX4 固件中。 +它包含“通用”XRCE-DDS客户端代码和它用来发布到来自uORB主题的 PX4 特定转换代码。 +生成到客户端中的 uORB 消息子集在 [dds_topics.yaml](../middleware/dds_topics.md)中说明。 +生成器使用源代码树中的 uORB 消息定义:[PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg) 用于生成发送 ROS 2 消息的代码。 -ROS 2 applications need to be built in a workspace that has the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware. -You can include these by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your ROS 2 workspace (branches in the repo correspond to the messages for different PX4 releases). +ROS 2 应用程序需要在一个工作空间中构建,该工作空间需包含与 PX4 固件中创建 uXRCE-DDS 客户端模块时所用完全相同的消息定义。 +您可以通过克隆接口包[PX4/px4_msgs](https://github.com/PX4/px4_msgs)将这些内容纳入您的 ROS 2 工作空间(repo 中的范围与不同的 PX4 版本的消息相对应)。 -Starting from PX4 v1.16, in which [message versioning](../middleware/uorb.md#message-versioning) was introduced, ROS2 applications may use a different version of message definitions than those used to build PX4. -This requires the [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to be running to ensure that messages can be converted and exchanged correctly. +从 PX4 v1.16 版本开始[message versioning](../middleware/uorb.md#message-versioning),ROS 2 应用程序所使用的消息定义版本,可与构建 PX4 时所用的消息定义版本不同。 +这需要[ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md)运行ROS 2 消息转换节点,以确保消息能够正确转换和交互。 -Note that the micro XRCE-DDS _agent_ itself has no dependency on client-side code. -It can be built from [source](https://github.com/eProsima/Micro-XRCE-DDS-Agent) either standalone or as part of a ROS build, or installed as a snap. +需要注意的是,微型XRCE-DDS _agent_ 本身并不依赖客户端代码。 +它可以从 [source](https://github.com/eProsima/Micro-XRCE-DDS-Agent) 中单独构建,或者作为ROS构建的一部分,或者作为snap包安装。 -You will normally need to start both the client and agent when using ROS 2. -Note that the uXRCE-DDS client is built into firmware by default but not started automatically except for simulator builds. +在使用 ROS 2 时,您通常需要同时启动客户端和代理。 +需要注意的是,uXRCE-DDS 客户端默认已内置到固件中,但除仿真器构建版本外,不会自动启动。 :::info -In PX4v1.13 and earlier, ROS 2 was dependent on definitions in [px4_ros_com](https://github.com/PX4/px4_ros_com). -This repo is no longer needed, but does contain useful examples. +在 PX4 v1.13 及更早版本中,ROS 2 依赖于 [px4_ros_com](https://github.com/PX4/px4_ros_com) 中的消息定义。 +该代码仓库已不再需要,但其中包含一些实用的示例。 ::: -## Installation & Setup +## 安装与设置 -The supported and recommended ROS 2 platform for working with PX4 is ROS 2 "Humble" LTS on Ubuntu 22.04. +支持和推荐使用 PX4 的 ROS 2 平台是 Ubuntu 的 ROS 2 “简易” LTS 22.04。 :::tip -If you're working on Ubuntu 20.04 we recommend you update to Ubuntu 22.04. -In the meantime you can use ROS 2 "Foxy" with [Gazebo Classic](../sim_gazebo_classic/index.md) on Ubuntu 20.04. -Note that ROS 2 "Foxy" reached end-of-life in May 2023, but is (at time of writing) still stable and works with PX4. +如果您在 Ubuntu 20.04 上工作,我们建议您更新到 Ubuntu 22.04。 +同时,你可以在 Ubuntu 20.04 上使用 [Gazebo Class](../sim_gazebo_classic/index.md) 的 ROS 2 "Foxy" 。 +请注意,第二号外空系统“Foxy”在2023年5月到达寿命终结,但在撰写本报告时仍然稳定并与PX4合作。 ::: -To setup ROS 2 for use with PX4: +安装使用 PX4 的 ROS 2: - [Install PX4](#install-px4) (to use the PX4 simulator) - [Install ROS 2](#install-ros-2) - [Setup Micro XRCE-DDS Agent & Client](#setup-micro-xrce-dds-agent-client) - [Build & Run ROS 2 Workspace](#build-ros-2-workspace) -Other dependencies of the architecture that are installed automatically, such as _Fast DDS_, are not covered. +该架构中会自动安装的其他依赖项(如 Fast DDS)未在此处提及。 ### 安装PX4 -You need to install the PX4 development toolchain in order to use the simulator. +若要使用该仿真器,你需要安装 PX4 开发工具链。 :::info -The only dependency ROS 2 has on PX4 is the set of message definitions, which it gets from [px4_msgs](https://github.com/PX4/px4_msgs). -You only need to install PX4 if you need the simulator (as we do in this guide), or if you are creating a build that publishes custom uORB topics. +唯一依赖于ROS2的 PX4 是一组信息定义,它从[px4_msgs](https://github.com/PX4/px4_msgs)获取。 +您只需要安装 PX4 当您需要模拟器时(如我们在本指南中所做的那样), 或者如果您正在创建一个发布自定义uORB主题的构建。 ::: -Set up a PX4 development environment on Ubuntu in the normal way: +通过以下方式在 Ubuntu 上配置一个 PX4 开发环境: ```sh cd @@ -86,137 +86,137 @@ cd PX4-Autopilot/ make px4_sitl ``` -Note that the above commands will install the recommended simulator for your version of Ubuntu. -If you want to install PX4 but keep your existing simulator installation, run `ubuntu.sh` above with the `--no-sim-tools` flag. +请注意,上述命令将为您的Ubuntu版本安装推荐的模拟器。 +如果您想要安装 PX4,但保留您现有的模拟器安装,请使用 "--no-sim-tools" 标志运行 `ubuntu.sh`。 -For more information and troubleshooting see: [Ubuntu Development Environment](../dev_setup/dev_env_linux_ubuntu.md) and [Download PX4 source](../dev_setup/building_px4.md). +欲了解更多信息和故障排除,请参阅:[Ubuntu 开发环境](../dev_setup/dev_env_linux_ubuntu.md) 和 [下载 PX4 源](../dev_setup/building_px4.md)。 ### 安装 ROS 2 -To install ROS 2 and its dependencies: +安装 ROS 2 及其依赖: -1. Install ROS 2. +1. 安装 ROS 2. - :::: tabs + :::: tabs - ::: tab humble - To install ROS 2 "Humble" on Ubuntu 22.04: + ::: tab humble + To install ROS 2 "Humble" on Ubuntu 22.04: - ```sh - sudo apt update && sudo apt install locales - sudo locale-gen en_US en_US.UTF-8 - sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 - export LANG=en_US.UTF-8 - sudo apt install software-properties-common - sudo add-apt-repository universe - sudo apt update && sudo apt install curl -y - sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null - sudo apt update && sudo apt upgrade -y - sudo apt install ros-humble-desktop - sudo apt install ros-dev-tools - source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc - ``` + ```sh + sudo apt update && sudo apt install locales + sudo locale-gen en_US en_US.UTF-8 + sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 + export LANG=en_US.UTF-8 + sudo apt install software-properties-common + sudo add-apt-repository universe + sudo apt update && sudo apt install curl -y + sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null + sudo apt update && sudo apt upgrade -y + sudo apt install ros-humble-desktop + sudo apt install ros-dev-tools + source /opt/ros/humble/setup.bash && echo "source /opt/ros/humble/setup.bash" >> .bashrc + ``` - The instructions above are reproduced from the official installation guide: [Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). + 以上说明转载自官方安装指南:[Install ROS 2 Humble](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html)。 + 您可以安装 _either_ the desktop (`ros-humble-desktop`) _or_ bare-bones versions (`ros-humble-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - ::: tab foxy - To install ROS 2 "Foxy" on Ubuntu 20.04: + ::: tab foxy + To install ROS 2 "Foxy" on Ubuntu 20.04: - - Follow the official installation guide: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). + - 按照官方安装指南: [Install ROS 2 Foxy](https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html). - You can install _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). + 您可以安装 _either_ the desktop (`ros-foxy-desktop`) _or_ bare-bones versions (`ros-foxy-ros-base`), _and_ the development tools (`ros-dev-tools`). ::: - :::: + :::: -2. Some Python dependencies must also be installed (using **`pip`** or **`apt`**): +2. 一些Python 依赖关系也必须安装 (使用 **`pip`** 或 **`apt`**): - ```sh - pip install --user -U empy==3.3.4 pyros-genmsg setuptools - ``` + ```sh + pip install --user -U empy==3.3.4 pyros-genmsg setuptools + ``` -### Setup Micro XRCE-DDS Agent & Client +### 配置微型 XRCE-DDS 代理与客户端 -For ROS 2 to communicate with PX4, [uXRCE-DDS client](../modules/modules_system.md#uxrce-dds-client) must be running on PX4, connected to a micro XRCE-DDS agent running on the companion computer. +要实现 ROS 2 与 PX4 的通信,[uXRCE-DDS client](../modules/modules_system.md#uxrce-dds-client)必须在 PX4 上运行,且需与运行在机载计算机上的微型 XRCE-DDS 代理建立连接。 #### 设置代理(Agent) -The agent can be installed onto the companion computer in a [number of ways](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation). -Below we show how to build the agent "standalone" from source and connect to a client running on the PX4 simulator. +代理可以安装在机载计算机上 [number of ways](../middleware/uxrce_dds.md#micro-xrce-dds-agent-installation)。 +下文将介绍如何从源代码 “独立” 构建代理,并连接到运行在 PX4 仿真器上的客户端。 -To setup and start the agent: +设置并启动代理: 1. 打开一个终端。 2. 输入以下命令从仓库获取源代码并构建代理(Agent): - ```sh - git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git - cd Micro-XRCE-DDS-Agent - mkdir build - cd build - cmake .. - make - sudo make install - sudo ldconfig /usr/local/lib/ - ``` + ```sh + git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git + cd Micro-XRCE-DDS-Agent + mkdir build + cd build + cmake .. + make + sudo make install + sudo ldconfig /usr/local/lib/ + ``` 3. 启动代理并设置以连接运行在模拟器上的 uXRCE-DDS客户端(Client): - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` -The agent is now running, but you won't see much until we start PX4 (in the next step). +代理现已启动,但在我们启动 PX4(下一步) 之前,你不会看到太多。 :::info -You can leave the agent running in this terminal! -Note that only one agent is allowed per connection channel. +你可以让代理在这个终端中保持运行状态! +需注意,每个连接通道仅允许运行一个代理 ::: #### 启动客户端(Client) -The PX4 simulator starts the uXRCE-DDS client automatically, connecting to UDP port 8888 on the local host. +PX4 仿真器会自动启动 uXRCE-DDS 客户端,并连接到本地主机上的 UDP 8888 端口。 -To start the simulator (and client): +启动模拟器(和客户端): -1. Open a new terminal in the root of the **PX4 Autopilot** repo that was installed above. +1. 在之前安装好的 PX4 自动驾驶仪 代码仓库的根目录下,打开一个新的终端。 - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - - Start a PX4 [Gazebo](../sim_gazebo_gz/index.md) simulation using: + - 使用 PX4 [Gazebo](../sim_gazebo_gz/index.md) 模拟: - ```sh - make px4_sitl gz_x500 - ``` + ```sh + make px4_sitl gz_x500 + ``` ::: - ::: tab foxy + ::: tab foxy - - Start a PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) simulation using: + - 使用 PX4 [Gazebo Classic](../sim_gazebo_classic/index.md) 模拟: - ```sh - make px4_sitl gazebo-classic - ``` + ```sh + make px4_sitl gazebo-classic + ``` ::: - :::: + :::: -The agent and client are now running they should connect. +代理和客户端现已运行并二者应已建立连接。 -The PX4 terminal displays the [NuttShell/PX4 System Console](../debug/system_console.md) output as PX4 boots and runs. -As soon as the agent connects the output should include `INFO` messages showing creation of data writers: +PX4 终端会显示 [NuttShell/PX4 System Console](../debug/system_console.md) 系统控制台 的输出内容,该输出会在 PX4 启动和运行过程中实时呈现。 +代理一建立连接,输出内容中就应包含 INFO 级别的消息,这些消息会显示数据撰写器的创建情况: ```sh ... @@ -224,142 +224,140 @@ INFO [uxrce_dds_client] synchronized with time offset 1675929429203524us INFO [uxrce_dds_client] successfully created rt/fmu/out/failsafe_flags data writer, topic id: 83 INFO [uxrce_dds_client] successfully created rt/fmu/out/sensor_combined data writer, topic id: 168 INFO [uxrce_dds_client] successfully created rt/fmu/out/timesync_status data writer, topic id: 188 -... ``` -The micro XRCE-DDS agent terminal should also start to show output, as equivalent topics are created in the DDS network: +微型 XRCE-DDS 代理终端也应开始显示输出内容,因为在 DDS 网络中会创建对应的主题: ```sh ... [1675929445.268957] info | ProxyClient.cpp | create_publisher | publisher created | client_key: 0x00000001, publisher_id: 0x0DA(3), participant_id: 0x001(1) [1675929445.269521] info | ProxyClient.cpp | create_datawriter | datawriter created | client_key: 0x00000001, datawriter_id: 0x0DA(5), publisher_id: 0x0DA(3) [1675929445.270412] info | ProxyClient.cpp | create_topic | topic created | client_key: 0x00000001, topic_id: 0x0DF(2), participant_id: 0x001(1) -... ``` -### Build ROS 2 Workspace +### 构建ROS 2 工作空间 -This section shows how to create a ROS 2 workspace hosted in your home directory (modify the commands as needed to put the source code elsewhere). +本节介绍如何在你的主目录中创建一个 ROS 2 工作空间(可根据需要修改命令,将源代码放置到其他位置)。 -The [px4_ros_com](https://github.com/PX4/px4_ros_com) and [px4_msgs](https://github.com/PX4/px4_msgs) packages are cloned to a workspace folder, and then the `colcon` tool is used to build the workspace. -The example is run using `ros2 launch`. +[px4_ros_com](https://github.com/PX4/px4_ros_com) 和 [px4_msgs](https://github.com/PX4/px4_msgs) 这两个功能包会被克隆到工作空间文件夹中,之后使用 colcon 工具对该工作空间进行构建 +此示例使用 "ros2 launch" 运行。 -You should use a version of the px4_msgs package with the \_same_ message definitions as the PX4 firmware you have installed in the step above. -Branches in the px4_msgs repo are named to correspond to the message definitions for different PX4 releases. -If for any reason you cannot ensure the same message definitions between your PX4 firmware and ROS 2 px4_msgs package, you will additionally need to [start the message translation node](#optional-starting-the-translation-node) as part of your setup process. +您应该使用一个 px4_msgs 包的版本与 \_same_ 消息定义作为您已经安装在上面步骤中的 PX4 固件。 +px4_msgs 代码仓库中的分支均以特定名称命名,这些名称与不同 PX4 版本的消息定义一一对应。 +如果出于任何原因,您不能确保您的 PX4 固件和 ROS 2 px4_msgs 包之间具有相同的消息定义。 您还需要 [start the message translation node](#optional-starting-the-translation-node),作为您设置过程的一部分。 :::info -The example builds the [ROS 2 Listener](#ros-2-listener) example application, located in [px4_ros_com](https://github.com/PX4/px4_ros_com). -[px4_msgs](https://github.com/PX4/px4_msgs) is needed too so that the example can interpret PX4 ROS 2 topics. +该示例会构建 [ROS 2 Listener](#ros-2-listener) 示例应用程序,该程序位于 [px4_ros_com](https://github.com/PX4/px4_ros_com)中。 +[px4_msgs](https://github.com/PX4/px4_msgs) 也是需要的,以便示例能够解释PX4 ROS 2 主题。 ::: -#### Building the Workspace +#### 构建工作空间 -To create and build the workspace: +要创建和构建工作空间: -1. Open a new terminal. +1. 打开一个新的终端。 -2. Create and navigate into a new workspace directory using: +2. 使用以下方式创建并进入一个新的工作空间目录: - ```sh - mkdir -p ~/ws_sensor_combined/src/ - cd ~/ws_sensor_combined/src/ - ``` + ```sh + mkdir -p ~/ws_sensor_combined/src/ + cd ~/ws_sensor_combined/src/ + ``` - ::: info - A naming convention for workspace folders can make it easier to manage workspaces. + ::: info + 一个为工作空间文件夹制定命名规范,有助于更轻松地管理工作空间。 ::: -3. Clone the example repository and [px4_msgs](https://github.com/PX4/px4_msgs) to the `/src` directory (the `main` branch is cloned by default, which corresponds to the version of PX4 we are running): +3. 将示例代码仓库和 [px4_msgs](https://github.com/PX4/px4_msgs) 克隆到 /src 目录下(默认克隆 main 分支,该分支与我们当前运行的 PX4 版本相对应): - ```sh - git clone https://github.com/PX4/px4_msgs.git - git clone https://github.com/PX4/px4_ros_com.git - ``` + ```sh + git clone https://github.com/PX4/px4_msgs.git + git clone https://github.com/PX4/px4_ros_com.git + ``` -4. Source the ROS 2 development environment into the current terminal and compile the workspace using `colcon`: +4. 在当前终端中加载 ROS 2 开发环境,并使用 colcon 工具编译工作空间: - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd .. - source /opt/ros/humble/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/humble/setup.bash + colcon build + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd .. - source /opt/ros/foxy/setup.bash - colcon build - ``` + ```sh + cd .. + source /opt/ros/foxy/setup.bash + colcon build + ``` ::: - :::: + :::: - This builds all the folders under `/src` using the sourced toolchain. + 该操作会使用已加载的工具链对 /src 目录下的所有文件夹进行构建。 -#### Running the Example +#### 运行示例 -To run the executables that you just built, you need to source `local_setup.bash`. -This provides access to the "environment hooks" for the current workspace. -In other words, it makes the executables that were just built available in the current terminal. +要运行你刚刚构建好的可执行文件,需加载local_setup.bash 。 +这提供了当前工作空间的 "environment hooks"访问权限。 +换句话说,它会让刚刚构建好的可执行文件在当前终端中可用。 :::info -The [ROS2 beginner tutorials](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html#source-the-overlay) recommend that you _open a new terminal_ for running your executables. +[ROS2 初学者教程](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html#source-the-overlay)建议您_打开一个新的终端来运行您的可执行文件。 ::: -In a new terminal: +在新终端中: -1. Navigate into the top level of your workspace directory and source the ROS 2 environment (in this case "Humble"): +1. 进入工作空间目录的顶层,并加载 ROS 2 环境(本例中为 “Humble” 版本): - :::: tabs + :::: tabs - ::: tab humble + ::: tab humble - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/humble/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/humble/setup.bash + ``` ::: - ::: tab foxy + ::: tab foxy - ```sh - cd ~/ws_sensor_combined/ - source /opt/ros/foxy/setup.bash - ``` + ```sh + cd ~/ws_sensor_combined/ + source /opt/ros/foxy/setup.bash + ``` ::: - :::: + :::: -2. Source the `local_setup.bash`. +2. 加载 local_setup.bash - ```sh - source install/local_setup.bash - ``` + ```sh + source install/local_setup.bash + ``` -3. Now launch the example. - Note here that we use `ros2 launch`, which is described below. +3. 现在启动示例。 + 请注意,此处我们使用的是 ros2 launch,其相关说明如下。 - ```sh - ros2 launch px4_ros_com sensor_combined_listener.launch.py - ``` + ```sh + ros2 launch px4_ros_com sensor_combined_listener.launch.py + ``` -If this is working you should see data being printed on the terminal/console where you launched the ROS listener: +若此功能正常运行,你应能在启动 ROS 监听器的终端 / 控制台上看到数据正在打印输出 ```sh RECEIVED DATA FROM SENSOR COMBINED @@ -376,72 +374,71 @@ accelerometer_m_s2[2]: -9.76044 accelerometer_integral_dt: 4739 ``` -#### (Optional) Starting the Translation Node +#### (可选) 启动转化节点 -This example is built with PX4 and ROS2 versions that use the same message definitions. -If you were to use incompatible [message versions](../middleware/uorb.md#message-versioning) you would need to install and run the [Message Translation Node](./px4_ros2_msg_translation_node.md) as well, before running the example: +此示例由 PX4 和ROS 2 版本构建,它们使用相同的消息定义。 +若你要使用不兼容的 [message versions](../middleware/uorb.md#message-versioning),则在运行示例之前,还需要安装并运行[Message Translation Node](./px4_ros2_msg_translation_node.md): -1. Include the [Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) into the example workspace or a separate workspace by running the following script: +1. 通过运行以下脚本,将 [Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) 纳入示例工作空间或单独的工作空间中 - ```sh - cd /path/to/ros_ws - /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . - ``` + ```sh + cd /path/to/ros_ws + /path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . + ``` -2. Build and run the translation node: +2. 构建并运行转化节点: - ```sh - colcon build - source install/local_setup.bash - ros2 run translation_node translation_node_bin - ``` + ```sh + colcon build + source install/local_setup.bash + ros2 run translation_node translation_node_bin + ``` -## Controlling a Vehicle +## 控制机体 -To control applications, ROS 2 applications: +要控制应用,ROS 2 应用程序: -- subscribe to (listen to) telemetry topics published by PX4 -- publish to topics that cause PX4 to perform some action. +- 订阅 (聆听) PX4 发布的数传主题 +- 发布到导致PX4执行某些操作的主题。 -The topics that you can use are defined in [dds_topics.yaml](../middleware/dds_topics.md), and you can get more information about their data in the [uORB Message Reference](../msg_docs/index.md). -For example, [VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) can be used to get the vehicle global position, while [VehicleCommand](../msg_docs/VehicleCommand.md) can be used to command actions such as takeoff and land. +您可以使用的主题定义在[dds_topics.yaml](../middleware/dds_topics.md), 并且您可以在 [uORB Message Reference](../msg_docs/index.md)获取更多关于他们数据的信息。 +例如,[VehicleGlobalPosition](../msg_docs/VehicleGlobalPosition.md) 可以用来获得机体的全局位置。 [VehicleCommand](../msg_docs/VehicleCommand.md) 可以用于命令诸如起飞和降落等操作。 -The [ROS 2 Example applications](#ros-2-example-applications) examples below provide concrete examples of how to use these topics. +下面的 [ROS 2 Example applications](#ros-2-example-applications) 示例提供了如何使用这些主题的具体例子。 -## Compatibility Issues +## 兼容性问题 -This section contains information that may affect how you write your ROS code. +本节包含的信息可能会影响你编写 ROS 代码的方式。 -### ROS 2 Subscriber QoS Settings +### ROS 2 订阅者QoS 设置 -ROS 2 code that subscribes to topics published by PX4 _must_ specify a appropriate (compatible) QoS setting in order to listen to topics. -Specifically, nodes should subscribe using the ROS 2 predefined QoS sensor data (from the [listener example source code](#ros-2-listener)): +用于订阅 PX4 发布的话题的 ROS 2 代码,必须指定合适(兼容)的 QoS(服务质量)设置,才能监听这些话题。 +具体而言,节点应使用 ROS 2 预定义的 QoS 传感器数据(可参考[listener example source code](#ros-2-listener))进行订阅: ```cpp ... rmw_qos_profile_t qos_profile = rmw_qos_profile_sensor_data; auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, 5), qos_profile); -subscription_ = this->create_subscription("/fmu/out/sensor_combined", qos, +subscription_ = this->create_subscription<0>("/fmu/out/sensor_combined", qos, ... ``` -This is needed because the ROS 2 default [Quality of Service (QoS) settings](https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html#qos-profiles) are different from the settings used by PX4. -Not all combinations of publisher-subscriber [Qos settings are possible](https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html#qos-compatibilities), and it turns out that the default ROS 2 settings for subscribing are not! -Note that ROS code does not have to set QoS settings when publishing (the PX4 settings are compatible with ROS defaults in this case). +需要这样做的原因是,ROS 2 的默认 [Quality of Service (QoS) settings](https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html#qos-profiles)与 PX4 所使用的设置不同。 +并非所有发布者 - 订阅者的 [Qos settings are possible](https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html#qos-compatibilities),而事实证明,ROS 2 默认的订阅者设置就属于不可行的情况!需注意,ROS 代码在发布时无需设置 QoS参数(在此场景下,PX4 的 QoS 设置与 ROS 的默认 QoS 设置是兼容的)。 -### ROS 2 & PX4 Frame Conventions +### ROS 2 & PX4 坐标系公约 -The local/world and body frames used by ROS and PX4 are different. +ROS与 PX4所使用的本地 / 世界坐标系和机体坐标系存在差异。 -| 框架 | ROS | ROS | -| ----- | ------------------------------------------------------------------- | ----------------------------------------------------------------- | -| 机体 | FRD (X **F**orward, Y **R**ight, Z **D**own) | FLU (X **F**orward, Y **L**eft, Z **U**p) | -| 世界坐标系 | FRD or NED (X **N**orth, Y **E**ast, Z **D**own) | FLU or ENU (X **E**ast, Y **N**orth, Z **U**p) | +| 框架 | ROS | ROS | +| ----- | ------------------------------------------------------------------- | ---------------------------------------------------------------- | +| 机体 | FRD (X **F**orward, Y **R**ight, Z **D**own) | FLU (X **F**orward, Y **L**eft, Z **U**p) | +| 世界坐标系 | FRD or NED (X **N**orth, Y **E**ast, Z **D**own) | FLU 或 ENU (X **E**ast, Y **N**orth, Z **U**p) | :::tip See [REP105: Coordinate Frames for Mobile Platforms](https://www.ros.org/reps/rep-0105.html) for more information about ROS frames. @@ -451,60 +448,60 @@ See [REP105: Coordinate Frames for Mobile Platforms](https://www.ros.org/reps/re ![Reference frames](../../assets/lpe/ref_frames.png) -The FRD (NED) conventions are adopted on **all** PX4 topics unless explicitly specified in the associated message definition. -Therefore, ROS 2 nodes that want to interface with PX4 must take care of the frames conventions. +除非在相关消息定义中明确指定,否则所有PX4 话题均采用 FRD(即 NED)坐标系约定。 +因此,想要与 PX4 进行交互的 ROS 2 节点,必须妥善处理坐标系约定问题。 -- To rotate a vector from ENU to NED two basic rotations must be performed: - - first a pi/2 rotation around the `Z`-axis (up), - - then a pi rotation around the `X`-axis (old East/new North). +- 要将一个向量从ENU坐标系旋转到NED坐标系,必须执行两个基本旋转操作: + - 首先是绕 Z 轴(朝上方向)旋转 π/2 弧度。 + - 然后是绕 X 轴(原东向 / 新北向)旋转 π 弧度 -- To rotate a vector from NED to ENU two basic rotations must be performed: +- 要将一个向量从NED坐标系旋转到ENU坐标系,必须执行两个基本旋转操作: -- - first a pi/2 rotation around the `Z`-axis (down), - - then a pi rotation around the `X`-axis (old North/new East). Note that the two resulting operations are mathematically equivalent. +- - 首先是绕 Z 轴(朝下方向)旋转 π/2 弧度。 + - 然后是绕 X 轴(原北向 / 新东向)旋转 π 弧度。 需注意,这两种最终得到的操作在数学上是等效的 -- To rotate a vector from FLU to FRD a pi rotation around the `X`-axis (front) is sufficient. +- 将向量从 FLU坐标系旋转到 FRD坐标系,仅需绕 X 轴(朝前方向)旋转 π 弧度即可。 -- To rotate a vector from FRD to FLU a pi rotation around the `X`-axis (front) is sufficient. +- 将向量从 FRD坐标系旋转到 FLU坐标系,仅需绕 X 轴(朝前方向)旋转 π 弧度即可。 -Examples of vectors that require rotation are: +需要进行旋转处理的向量示例包括: -- all fields in [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) message; ENU to NED conversion is required before sending them. -- all fields in [VehicleThrustSetpoint](../msg_docs/VehicleThrustSetpoint.md) message; FLU to FRD conversion is required before sending them. +- [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md)消息中的所有字段;发送这些字段前,需先将其从 ENU坐标系转换为 NED坐标系。 +- [VehicleThrustSetpoint](../msg_docs/VehicleThrustSetpoint.md)消息中的所有字段;发送这些字段前,需先将其从 FLU坐标系转换为 FRD坐标系。 -Similarly to vectors, also quaternions representing the attitude of the vehicle (body frame) w.r.t. the world frame require conversion. +与向量类似,用于表示飞行器(机体坐标系)相对于(w.r.t.)姿态的四元数也是如此。 (相对于)世界坐标系(的四元数)需要进行转换。 -[PX4/px4_ros_com](https://github.com/PX4/px4_ros_com) provides the shared library [frame_transforms](https://github.com/PX4/px4_ros_com/blob/main/include/px4_ros_com/frame_transforms.h) to easily perform such conversions. +[PX4/px4_ros_com](https://github.com/PX4/px4_ros_com) 提供了名为 [frame_transforms](https://github.com/PX4/px4_ros_com/blob/main/include/px4_ros_com/frame_transforms.h)的共享库,可便捷地执行此类转换操作。 -### ROS, Gazebo and PX4 time synchronization +### ROS, Gazebo 和 PX4 时间同步 -By default, time synchronization between ROS 2 and PX4 is automatically managed by the [uXRCE-DDS middleware](https://micro-xrce-dds.docs.eprosima.com/en/latest/time_sync.html) and time synchronization statistics are available listening to the bridged topic `/fmu/out/timesync_status`. -When the uXRCE-DDS client runs on a flight controller and the agent runs on a companion computer this is the desired behavior as time offsets, time drift, and communication latency, are computed and automatically compensated. +默认情况下,ROS 2 与 PX4 之间的时间同步由[uXRCE-DDS middleware](https://micro-xrce-dds.docs.eprosima.com/en/latest/time_sync.html) 自动管理;若需查看时间同步统计信息,可监听已桥接的话题 /fmu/out/timesync_status。 +当 uXRCE-DDS 客户端运行在飞控器上,且代理运行在机载计算机上时,这便是理想的运行状态 —— 此时时间偏移、时间漂移以及通信延迟会被自动计算并补偿。 -For Gazebo simulations the GZBridge sets the PX4 time on every sim step (see [Change simulation speed](../sim_gazebo_gz/index.md#change-simulation-speed)). -Note that this is different from the [simulation lockstep](../sim_gazebo_classic/index.md#lockstep) procedure adopted with Gazebo Classic. +在 Gazebo 仿真中,GZBridge 会在每个仿真步长(sim step)为 PX4 设置时间[Change simulation speed](../sim_gazebo_gz/index.md#change-simulation-speed)。 +需注意,这与 Gazebo Classic所采用的仿真锁步[simulation lockstep](../sim_gazebo_classic/index.md#lockstep)流程不同。 -ROS2 users have then two possibilities regarding the [time source](https://design.ros2.org/articles/clock_and_time.html) of their nodes. +对于 ROS 2 用户而言,其节点的[time source](https://design.ros2.org/articles/clock_and_time.html)有两种选择。 -#### ROS2 nodes use the OS clock as time source +#### ROS2 节点使用操作系统时钟作为时间源 -This scenario, which is the one considered in this page and in the [offboard_control](./offboard_control.md) guide, is also the standard behaviour of the ROS2 nodes. -The OS clock acts as time source and therefore it can be used only when the simulation real time factor is very close to one. -The time synchronizer of the uXRCE-DDS client then bridges the OS clock on the ROS2 side with the Gazebo clock on the PX4 side. -No further action is required by the user. +本文档以及[offboard_control](./offboard_control.md)指南中所采用的便是此场景,同时,该场景也是 ROS 2 节点的标准行为 +操作系统时钟作为时间来源,因此它只能在模拟实时系数非常接近时才能使用。 +uXRCE-DDS 客户端的时间同步器随后会将 ROS 2 端的操作系统时钟(OS clock)与 PX4 端的 Gazebo 时钟进行桥接同步。 +用户不需要进一步操作。 -#### ROS2 nodes use the Gazebo clock as time source +#### ROS2 节点使用 Gazebo 时钟作为时间源 -In this scenario, ROS2 also uses the Gazebo `/clock` topic as time source. -This approach makes sense if the Gazebo simulation is running with real time factor different from one, or if ROS2 needs to directly interact with Gazebo. -On the ROS2 side, direct interaction with Gazebo is achieved by the [ros_gz_bridge](https://github.com/gazebosim/ros_gz) package of the [ros_gz](https://github.com/gazebosim/ros_gz) repository. +在这种情况下,ROS2还使用Gazebo\`/时钟主题作为时间来源。 +若 Gazebo 仿真的实时因子不为 1,或 ROS 2 需直接与 Gazebo 交互,则该方法具有合理性。 +在 ROS 2 端,可通过[ros_gz](https://github.com/gazebosim/ros_gz)代码仓库中的[ros_gz_bridge](https://github.com/gazebosim/ros_gz) 功能包,实现与 Gazebo 的直接交互。 -Use the following commands to install the correct ROS 2/gz interface packages (not just the bridge) for the ROS2 and Gazebo version(s) supported by PX4. +请使用以下命令,为 PX4 所支持的 ROS 2 和 Gazebo 版本安装正确的 ROS 2/gz 接口功能包(不仅限于桥接功能包)。 :::: tabs :::tab humble -To install the bridge for use with ROS 2 "Humble" and Gazebo Harmonic (on Ubuntu 22.04): +在 Ubuntu 22.04 系统上,若需安装用于搭配 ROS 2 “Humble”与 Gazebo Harmonic的桥接功能包,可执行以下操作: ```sh sudo apt install ros-humble-ros-gzharmonic @@ -513,9 +510,9 @@ sudo apt install ros-humble-ros-gzharmonic ::: :::tab foxy -First you will need to [install Gazebo Garden](../sim_gazebo_gz/index.md#installation-ubuntu-linux), as by default Foxy comes with Gazebo Classic 11. +首先,您需要 [install Gazebo Garden](../sim_gazebo_gz/index.md#installation-ubuntu-linux),因为默认情况下,Foxy预装的是 Gazebo Classic 11 -Then to install the interface packages for use with ROS 2 "Foxy" and Gazebo (Ubuntu 20.04): +接下来,若要在 Ubuntu 20.04 系统上安装用于搭配 ROS 2 "Foxy"与 Gazebo的桥接功能包,操作如下: ```sh sudo apt install ros-foxy-ros-gzgarden @@ -526,40 +523,40 @@ sudo apt install ros-foxy-ros-gzgarden :::: :::info -The [repo](https://github.com/gazebosim/ros_gz#readme) and [package](https://github.com/gazebosim/ros_gz/tree/ros2/ros_gz_bridge#readme) READMEs show the package versions that need to be installed depending on your ROS2 and Gazebo versions. +[repo](https://github.com/gazebosim/ros_gz#readme) 和 [package](https://github.com/gazebosim/ros_gz/tree/ros2/ros_gz_bridge#readme) README显示了需要安装的软件包版本,取决于您的 ROS2 和 Gazebo 版本。 ::: -Once the packages are installed and sourced, the node `parameter_bridge` provides the bridging capabilities and can be used to create an unidirectional `/clock` bridge: +功能包安装并完成环境配置后,parameter_bridge节点会提供桥接能力,可用于创建一个单向的/clock桥接。 ```sh ros2 run ros_gz_bridge parameter_bridge /clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock ``` -At this point, every ROS2 node must be instructed to use the newly bridged `/clock` topic as time source instead of the OS one, this is done by setting the parameter `use_sim_time` (of _each_ node) to `true` (see [ROS clock and Time design](https://design.ros2.org/articles/clock_and_time.html)). +此时,必须指示每个 ROS 2 节点使用新桥接的/clock话题作为时间源,而非操作系统时钟(OS clock);要实现这一点,需将(每个节点的)use_sim_time参数设置为true(详见[ROS clock and Time design](https://design.ros2.org/articles/clock_and_time.html))。 -This concludes the modifications required on the ROS2 side. On the PX4 side, you are only required to stop the uXRCE-DDS time synchronization, setting the parameter [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT) to `false`. -By doing so, Gazebo will act as main and only time source for both ROS2 and PX4. +至此,ROS 2 端所需的修改已全部完成。 在 PX4 端,你只需停止 uXRCE-DDS 时间同步功能,将参数[UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT)设置为false即可。 +通过此操作,Gazebo 将成为 ROS 2 和 PX4 两者共同的、唯一的主时间源。 -## ROS 2 Example Applications +## ROS 2 示例应用程序 ### ROS 2 Listener -The ROS 2 [listener examples](https://github.com/PX4/px4_ros_com/tree/main/src/examples/listeners) in the [px4_ros_com](https://github.com/PX4/px4_ros_com) repo demonstrate how to write ROS nodes to listen to topics published by PX4. +[px4_ros_com](https://github.com/PX4/px4_ros_com中的 ROS 2 [listener examples](https://github.com/PX4/px4_ros_com/tree/main/src/examples/listeners) repo展示了如何编写 ROS 节点,以监听由 PX4 发布的话题 -Here we consider the [sensor_combined_listener.cpp](https://github.com/PX4/px4_ros_com/blob/main/src/examples/listeners/sensor_combined_listener.cpp) node under `px4_ros_com/src/examples/listeners`, which subscribes to the [SensorCombined](../msg_docs/SensorCombined.md) message. +此处我们以 px4_ros_com/src/examples/listeners 路径下的 [sensor_combined_listener.cpp](https://github.com/PX4/px4_ros_com/blob/main/src/examples/listeners/sensor_combined_listener.cpp) 节点为例,该节点会订阅 [SensorCombined](../msg_docs/SensorCombined.md) 消息。 :::info -[Build ROS 2 Workspace](#build-ros-2-workspace) shows how to build and run this example. +[Build ROS 2 Workspace](#build-ros-2-workspace) 显示如何构建和运行这个例子。 ::: -The code first imports the C++ libraries needed to interface with the ROS 2 middleware and the header file for the `SensorCombined` message to which the node subscribes: +代码首先导入了与 ROS 2 中间件进行交互所需的 C++ 库,以及该节点所订阅的SensorCombined消息对应的头部文件: ```cpp #include #include ``` -Then it creates a `SensorCombinedListener` class that subclasses the generic `rclcpp::Node` base class. +随后,代码创建了一个 SensorCombinedListener 类,该类继承自通用的 rclcpp::Node 基类。 ```cpp /** @@ -569,7 +566,7 @@ class SensorCombinedListener : public rclcpp::Node { ``` -This creates a callback function for when the `SensorCombined` uORB messages are received (now as micro XRCE-DDS messages), and outputs the content of the message fields each time the message is received. +这会创建一个回调函数,用于处理SensorCombined uORB 消息(当前以微型 XRCE-DDS 消息格式传输)的接收事件;每当接收到该消息时,该函数会输出消息字段的内容 ```cpp public: @@ -598,16 +595,16 @@ public: ``` :::info -The subscription sets a QoS profile based on `rmw_qos_profile_sensor_data`. -This is needed because the default ROS 2 QoS profile for subscribers is incompatible with the PX4 profile for publishers. -For more information see: [ROS 2 Subscriber QoS Settings](#ros-2-subscriber-qos-settings), +该订阅会基于 rmw_qos_profile_sensor_data 设置一个 QoS 配置文件。 +之所以需要这样做,是因为 ROS 2 订阅者的默认 QoS(服务质量)配置文件,与 PX4 发布者的配置文件不兼容。 +欲了解更多信息,请参阅:[ROS 2 Subscriber QoS Settings](#ros-2-subscriber-qos-settings), ::: -The lines below create a publisher to the `SensorCombined` uORB topic, which can be matched with one or more compatible ROS 2 subscribers to the `fmu/sensor_combined/out` ROS 2 topic. +以下代码行创建了一个发布者,用于向 SensorCombined uORB 话题发布数据;该发布者可与一个或多个兼容的 ROS 2 订阅者匹配,这些订阅者监听的是 fmu/sensor_combined/out ROS 2 话题。 ````cpp private: - rclcpp::Subscription::SharedPtr subscription_; + rclcpp::Subscription::SharedPtr subscription_; }; ```s @@ -619,21 +616,21 @@ int main(int argc, char *argv[]) std::cout << "Starting sensor_combined listener node..." << std::endl; setvbuf(stdout, NULL, _IONBF, BUFSIZ); rclcpp::init(argc, argv); - rclcpp::spin(std::make_shared()); + rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; } ```` -This particular example has an associated launch file at [launch/sensor_combined_listener.launch.py](https://github.com/PX4/px4_ros_com/blob/main/launch/sensor_combined_listener.launch.py). -This allows it to be launched using the [`ros2 launch`](#ros2-launch) command. +此特殊示例在[launch/sensor_combined_listener.launch.py](https://github.com/PX4/px4_ros_com/blob/main/launch/sensor_combined_listener.launch.py).有一个相关的启动文件。 +这使得它可以通过 [`ros2 launch`](#ros2-launch) 命令启动 -### ROS 2 Advertiser +### ROS 2 发布者 -A ROS 2 advertiser node publishes data into the DDS/RTPS network (and hence to the PX4 Autopilot). +一个 ROS 2 发布者节点会将数据发布到 DDS/RTPS 网络中(进而传递给 PX4 自动驾驶仪)。 -Taking as an example the `debug_vect_advertiser.cpp` under `px4_ros_com/src/advertisers`, first we import required headers, including the `debug_vect` msg header. +以 px4_ros_com/src/advertisers 路径下的 debug_vect_advertiser.cpp(文件)为例,首先我们会导入所需的headers,其中包括 `debug_vect` msg header。 ```cpp #include @@ -643,15 +640,15 @@ Taking as an example the `debug_vect_advertiser.cpp` under `px4_ros_com/src/adve using namespace std::chrono_literals; ``` -Then the code creates a `DebugVectAdvertiser` class that subclasses the generic `rclcpp::Node` base class. +随后,代码创建了一个 DebugVectAdvertiser 类,该类继承自通用的 rclcpp::Node 基类。 ```cpp class DebugVectAdvertiser : public rclcpp::Node { ``` -The code below creates a function for when messages are to be sent. -The messages are sent based on a timed callback, which sends two messages per second based on a timer. +这段代码创建了一个用来发送消息的回调函数。 +发送消息的回调函数由定时器触发的,每秒钟发送两次消息。 ```cpp public: @@ -679,7 +676,7 @@ private: }; ``` -The instantiation of the `DebugVectAdvertiser` class as a ROS node is done on the `main` function. +这段代码在 main 函数中将 DebugVectAdvertiser 类实例化成一个ROS节点。 ```cpp int main(int argc, char *argv[]) @@ -696,31 +693,31 @@ int main(int argc, char *argv[]) ### Offboard控制 -[ROS 2 Offboard control example](../ros2/offboard_control.md) provides a complete C++ reference example of how to use [offboard control](../flight_modes/offboard.md) of PX4 with ROS2. +[ROS 2 Offboard control example](../ros2/offboard_control.md)提供了一个完整的 C++ 参考示例,说明如何使用 PX4 的 [offboard control](../flight_modes/offboard.md) 与 ROS 2。 -[Python ROS2 offboard examples with PX4](https://github.com/Jaeyoung-Lim/px4-offboard) (Jaeyoung-Lim/px4-offboard) provides a similar example for Python, and includes the scripts: +[Python ROS2 offboard examples with PX4](https://github.com/Jaeyoung-Lim/px4-offboard) (Jaeyoung-Lim/px4-offboard) 为Python 提供了一个类似的示例,并包含脚本: -- `offboard_control.py`: Example of offboard position control using position setpoints -- `visualizer.py`: Used for visualizing vehicle states in Rviz +- `offboard_control.py`: 使用位置设定值进行离板位置控制的示例 +- “visualizer.py\`:用于可视化载体状态的 Rviz -## Using Flight Controller Hardware +## 使用飞行控制器硬件 -ROS 2 with PX4 running on a flight controller is almost the same as working with PX4 on the simulator. -The only difference is that you need to start both the agent _and the client_, with settings appropriate for the communication channel. +在飞行控制器上运行的 PX4 号ROS2与在模拟器上运行的 PX4 几乎相同。 +唯一的区别是您需要同时启动agent _and the client_,并设置适合通信频道。 -For more information see [Starting uXRCE-DDS](../middleware/uxrce_dds.md#starting-agent-and-client). +更多信息详见[Starting uXRCE-DDS](../middleware/uxrce_dds.md#starting-agent-and-client) -## Custom uORB Topics +## 自定义 uORB 主题 -ROS 2 needs to have the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware in order to interpret the messages. -The definition are stored in the ROS 2 interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) and they are automatically synchronized by CI on the `main` and release branches. -Note that all the messages from PX4 source code are present in the repository, but only those listed in `dds_topics.yaml` will be available as ROS 2 topics. -Therefore, +ROS 2需要有用于在 PX4 固件中创建 uXRCE-DDS客户端模块的 _sam_message 定义,以便解释消息。 +这些定义存储在 ROS 2 接口包[PX4/px4_msgs](https://github.com/PX4/px4_msgs)中,并且会通过CI在 main(主)分支和发布分支上自动同步。 +需要注意的是,PX4 源代码中的所有消息均存在于该代码仓库中,但只有在dds_topics.yaml文件中列出的消息,才会作为 ROS 2 话题可用。 +因此 -- If you're using a main or release version of PX4 you can get the message definitions by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your workspace. -- If you're creating or modifying uORB messages you must manually update the messages in your workspace from your PX4 source tree. - Generally this means that you would update [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml), clone the interface package, and then manually synchronize it by copying the new/modified message definitions from [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg) to its `msg` folders. - Assuming that PX4-Autopilot is in your home directory `~`, while `px4_msgs` is in `~/ros2_ws/src/`, then the command might be: +- 如果您正在使用 PX4 的主要版本或发布版本,您可以通过克隆接口包[PX4/px4_msgs](https://github.com/PX4/px4_msgs)获得消息定义。 +- 如果您要创建或修改 uORB 消息,必须从 PX4 源代码树中手动更新工作空间中的消息。 + 一般来说,这意味着您将更新 [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml),克隆接口包。 然后手动同步,将新的/修改的消息定义从 [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg)复制到它的 `msg` 文件夹。 + 假定PX4-Autopilot在你的主目录`~`中,而`px4_msgs`则在`~/ros2_ws/src/`中,命令可能是: ```sh rm ~/ros2_ws/src/px4_msgs/msg/*.msg @@ -728,22 +725,22 @@ Therefore, ``` ::: info - Technically, [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) completely defines the relationship between PX4 uORB topics and ROS 2 messages. - For more information see [uXRCE-DDS > DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml). + 从技术角度而言,[dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) 这个文件完整定义了 PX4 uORB 话题与 ROS 2 消息之间的对应关系。 + 欲了解更多信息,请参阅[uXRCE-DDS > DDS Topics YAML](../middleware/uxrce_dds.md#dds-topics-yaml)。 ::: ## Customizing the Namespace -Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml)) or at runtime (useful for multi vehicle operations): +自定义主题和服务命名空间可以在构建时间(更改 [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml))或运行时间(对多载体操作有用): -- One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line. - This technique can be used both in simulation and real vehicles. -- A custom namespace can be provided for simulations (only) by setting the environment variable `PX4_UXRCE_DDS_NS` before starting the simulation. +- 一种可能性是在从命令行启动[uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client)时使用 "-n" 选项。 + 这种技术既可用于模拟,也可用于实际机体。 +- 在开始模拟前,可以通过设置环境变量 `PX4_UXRCE_DDS_NS`来提供自定义命名空间 (仅限) :::info -Changing the namespace at runtime will append the desired namespace as a prefix to all `topic` fields in [dds_topics.yaml](../middleware/dds_topics.md) and all [service servers](#px4-ros-2-service-servers). -Therefore, commands like: +更改运行时的命名空间将会将所需的命名空间作为一个前缀附加到 [dds_topics.yaml](../middleware/dds_topics.md) 中所有的 "topic " 字段和所有 [service servers](#px4-ros-2-service-servers)。 +因此,命令如下: ```sh uxrce_dds_client start -n uav_1 @@ -755,7 +752,7 @@ uxrce_dds_client start -n uav_1 PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500 ``` -will generate topics under the namespaces: +将在以下命名空间下生成话题: ```sh /uav_1/fmu/in/ # for subscribers @@ -769,27 +766,27 @@ will generate topics under the namespaces: PX4 uXRCE-DDS middleware supports [ROS 2 services](https://docs.ros.org/en/jazzy/Concepts/Basic/About-Services.html). -Services are remote procedure calls, from one node to another, that return a result. +服务(Services)是一种远程过程调用(remote procedure calls),由一个节点发起,向另一个节点请求调用,最终会返回一个结果。 A service server is the entity that will accept a remote procedure request, perform some computation on it, and return the result. They simplify communication between ROS 2 nodes and PX4 by grouping the request and response behaviour, and ensuring that replies are only returned to the specific requesting user. -This is much easier that publishing the request, subscribing to the reply, and filtering out any unwanted responses. +这比发布请求、订阅回复并过滤掉所有不需要的响应要容易得多。 -The service servers that are built into the PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module include: +构建在 PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) 模块中的服务服务器包括: - `/fmu/vehicle_command` (definition: [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv).) - This service can be called by ROS 2 applications to send PX4 [VehicleCommand](../msg_docs/VehicleCommand.md) uORB messages and receive PX4 [VehicleCommandAck](../msg_docs/VehicleCommandAck.md) uORB messages in response. + 此服务可以被 ROS 2 应用程序调用来发送 PX4[VehicleCommand](../msg_docs/VehicleCommand.md) uORB 消息,并相应接收 PX4 [VehicleCommandAck](../msg_docs/VehicleCommandAck.md)uORB 消息。 -All PX4 service names follow the convention `{extra_namespace}/fmu/{server_specific_name}` where `{extra_namespace}` is the same [custom namespace](#customizing-the-namespace) that can be given to the PX4 topics. +所有 PX4 服务名称均遵循 `{extra_namespace}/fmu/{server_specific_name}` 这一约定,其中 {extra_namespace} 与可分配给 PX4 话题的 [custom namespace](#customizing-the-namespace)相同。 -Details and specific examples are provided in the following sections. +具体细节和示例将在以下章节中提供。 -### VehicleCommand service +### 载体指挥服务 -This can be used to send commands to the vehicle, such as "take off", "land", change mode, and "orbit", and receive a response. +这可用于向飞行器发送指令(例如 “起飞”“着陆”“切换模式” 和 “盘旋”),并接收响应。 -The service type is defined in [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv) as: +服务类型在 [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv) 中定义如下: ```txt VehicleCommand request @@ -797,30 +794,30 @@ VehicleCommand request VehicleCommandAck reply ``` -Users can make service requests by sending [VehicleCommand](../msg_docs/VehicleCommand.md) messages, and receive a [VehicleCommandAck](../msg_docs/VehicleCommandAck.md) message in response. -The service ensures that only the `VehicleCommandAck` reply generated for the specific request made by the user is sent back. +用户可通过发送 [VehicleCommand](../msg_docs/VehicleCommand.md)消息发起服务请求,并会收到一条[VehicleCommandAck](../msg_docs/VehicleCommandAck.md) 消息作为响应。 +该服务可确保仅将针对用户发起的特定请求所生成的 VehicleCommandAck回复返回。 -#### VehicleCommand Service Offboard Control Example +#### 载体指挥服务离板控制示例 -A complete _offboard control_ example using the VehicleCommand service is provided by the [offboard_control_srv](https://github.com/PX4/px4_ros_com/blob/main/src/examples/offboard/offboard_control_srv.cpp) node available in the `px4_ros_com` package. +在 px4_ros_com 功能包中,有一个[offboard_control_srv](https://github.com/PX4/px4_ros_com/blob/main/src/examples/offboard/offboard_control_srv.cpp) 节点,该节点提供了一个完整的、使用 VehicleCommand 服务实现离板控制的示例。 -The example closely follows the _offboard control_ example described in [ROS 2 Offboard Control Example](../ros2/offboard_control.md) but uses the `VehicleCommand` service to request mode changes, vehicle arming and vehicle disarming. +该示例与[ROS 2 Offboard Control Example](../ros2/offboard_control.md) 中描述的离板控制示例高度相似,但使用 VehicleCommand 服务来请求模式切换、飞行器上锁和飞行器解锁。 -First the ROS 2 application declares a service client of type `px4_msgs::srv::VehicleCommand` using `rclcpp::Client()` as shown (this is the same approach used for all ROS2 service clients): +首先,ROS 2 应用程序会使用 rclcpp::Client() 声明一个类型为 px4_msgs::srv::VehicleCommand 的服务客户端,具体如下(所有 ROS 2 服务客户端均采用此方法) ```cpp -rclcpp::Client::SharedPtr vehicle_command_client_; +rclcpp::Client<0>::SharedPtr vehicle_command_client_; ``` -Then the client is initialized to the right ROS 2 service (`/fmu/vehicle_command`). -As the application assumes the standard PX4 namespace is used, the code to do this looks like this: +然后客户端初始化到正确的 ROS 2 服务 (`/fmu/vehicle_command` )。 +当应用程序假设使用标准的 PX4 命名空间时,这样做的代码看起来就像这样: ```cpp vehicle_command_client_{this->create_client("/fmu/vehicle_command")} ``` -After that, the client can be used to send any vehicle command request. -For example, the `arm()` function is used to request the vehicle to arm: +此后,客户可以用来发送任何机体命令请求。 +例如,`arm()`函数用于请求机体放置: ```cpp void OffboardControl::arm() @@ -830,12 +827,12 @@ void OffboardControl::arm() } ``` -where `request_vehicle_command` handles formatting the request and sending it over in _asynchronous_ [mode](https://docs.ros.org/en/humble/How-To-Guides/Sync-Vs-Async.html#asynchronous-calls): +`request_vehicle_command`处理请求格式化并在_asynchronous_ [mode](https://docs.ros.org/en/humble/How-To-Guides/Sync-Vs-Async.html#asynchronous-calls): ```cpp void OffboardControl::request_vehicle_command(uint16_t command, float param1, float param2) { - auto request = std::make_shared(); + auto request = std::make_shared(); VehicleCommand msg{}; msg.param1 = param1; @@ -856,11 +853,11 @@ void OffboardControl::request_vehicle_command(uint16_t command, float param1, fl } ``` -The response is finally captured asynchronously by the `response_callback` method which checks for the request result: +最终,响应由 response_callback 方法以异步方式捕获,该方法会检查请求结果: ```cpp void OffboardControl::response_callback( - rclcpp::Client::SharedFuture future) { + rclcpp::Client<0>::SharedFuture future) { auto status = future.wait_for(1s); if (status == std::future_status::ready) { auto reply = future.get()->reply; @@ -875,20 +872,20 @@ void OffboardControl::response_callback( ## ros2 CLI -The [ros2 CLI](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools.html) is a useful tool for working with ROS. -You can use it, for example, to quickly check whether topics are being published, and also inspect them in detail if you have `px4_msg` in the workspace. -The command also lets you launch more complex ROS systems via a launch file. -A few possibilities are demonstrated below. +[ros2 CLI](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools.html)是一个有用的工具来处理ROS。 +例如,您可以使用它快速检查话题是否正在发布;如果您的工作空间中包含 px4_msg,还可以详细查看这些话题的内容。 +该命令还允许您通过启动文件(launch file)启动更复杂的 ROS 系统。 +下文显示了几种可能性。 -### ros2 topic list +### ros2 topic list(ROS 2 话题列表命令) -Use `ros2 topic list` to list the topics visible to ROS 2: +使用 ros2 topic list 命令列出 ROS 2 可识别的话题: ```sh -ros2 topic list +ros2 topic list(ROS 2 话题列表命令) ``` -If PX4 is connected to the agent, the result will be a list of topic types: +若 PX4 已连接至代理,输出结果将是一份话题类型列表: ```sh /fmu/in/obstacle_distance @@ -897,19 +894,19 @@ If PX4 is connected to the agent, the result will be a list of topic types: ... ``` -Note that the workspace does not need to build with `px4_msgs` for this to succeed; topic type information is part of the message payload. +请注意,工作区不需要使用 px4_msgs 构建才能成功;主题类型信息是消息有效载荷的一部分。 ### ros2 topic echo -Use `ros2 topic echo` to show the details of a particular topic. +使用 `ros2 topic echo`"来显示特定主题的详细信息。 -Unlike with `ros2 topic list`, for this to work you must be in a workspace has built the `px4_msgs` and sourced `local_setup.bash` so that ROS can interpret the messages. +与 ros2 topic list 命令不同,要让该功能正常工作,你必须处于一个已编译 px4_msgs且已执行 local_setup.bash 脚本的工作空间中,这样 ROS 才能解析相关消息 ```sh ros2 topic echo /fmu/out/vehicle_status ``` -The command will echo the topic details as they update. +该命令将在主题细节更新时响应它们的详细信息。 ```sh --- @@ -930,56 +927,56 @@ hil_state: 0 ### ros2 topic hz -You can get statistics about the rates of messages using `ros2 topic hz`. -For example, to get the rates for `SensorCombined`: +你可以使用 ros2 topic hz 命令获取消息速率相关的统计信息。 +例如,获取`SensorCombined`速率: ```sh ros2 topic hz /fmu/out/sensor_combined ``` -The output will look something like: +输出会看起来像这样: ```sh average rate: 248.187 - min: 0.000s max: 0.012s std dev: 0.00147s window: 2724 +min: 0.000s max: 0.012s std dev: 0.00147s window: 2724 average rate: 248.006 - min: 0.000s max: 0.012s std dev: 0.00147s window: 2972 +min: 0.000s max: 0.012s std dev: 0.00147s window: 2972 average rate: 247.330 - min: 0.000s max: 0.012s std dev: 0.00148s window: 3212 +min: 0.000s max: 0.012s std dev: 0.00148s window: 3212 average rate: 247.497 - min: 0.000s max: 0.012s std dev: 0.00149s window: 3464 +min: 0.000s max: 0.012s std dev: 0.00149s window: 3464 average rate: 247.458 - min: 0.000s max: 0.012s std dev: 0.00149s window: 3712 +min: 0.000s max: 0.012s std dev: 0.00149s window: 3712 average rate: 247.485 - min: 0.000s max: 0.012s std dev: 0.00148s window: 3960 +min: 0.000s max: 0.012s std dev: 0.00148s window: 3960 ``` ### ros2 launch -The `ros2 launch` command is used to start a ROS 2 launch file. -For example, above we used `ros2 launch px4_ros_com sensor_combined_listener.launch.py` to start the listener example. +ros2 launch 命令用于启动一个 ROS 2 启动文件 +例如,前面我们使用 ros2 launch px4_ros_com sensor_combined_listener.launch.py 命令启动了监听器示例。 -You don't need to have a launch file, but they are very useful if you have a complex ROS 2 system that needs to start several components. +你并非必须使用启动文件,但如果你的 ROS 2 系统较为复杂,需要启动多个组件,那么启动文件会非常实用。 -For information about launch files see [ROS 2 Tutorials > Creating launch files](https://docs.ros.org/en/humble/Tutorials/Intermediate/Launch/Creating-Launch-Files.html) +关于启动文件的信息,请参阅 [ROS 2 Tutorials > Creating launch files](https://docs.ros.org/en/humble/Tutorials/Intermediate/Launch/Creating-Launch-Files.html) ## 故障处理 -### Missing dependencies +### 缺少依赖项 -The standard installation should include all the tools needed by ROS 2. +标准安装应包含 ROS 2 所需的所有工具。 -If any are missing, they can be added separately: +如果有任何缺失,可以单独添加: -- **`colcon`** build tools should be in the development tools. - It can be installed using: +- **`colcon`** 构建工具应该在开发工具中。 + 可以使用以下方式安装它: ```sh sudo apt install python3-colcon-common-extensions ``` -- The Eigen3 library used by the transforms library should be in the both the desktop and base packages. - It should be installed as shown: +- 变换库(transforms library)所使用的 Eigen3 库,应同时存在于桌面版(desktop)功能包和基础版(base)功能包中。 + 它应该安装在显示中: :::: tabs @@ -1005,10 +1002,10 @@ If any are missing, they can be added separately: ### ros_gz_bridge not publishing on the \clock topic -If your [ROS2 nodes use the Gazebo clock as time source](../ros2/user_guide.md#ros2-nodes-use-the-gazebo-clock-as-time-source) but the `ros_gz_bridge` node doesn't publish anything on the `/clock` topic, you may have the wrong version installed. -This might happen if you install ROS 2 Humble with the default "Ignition Fortress" packages, rather than using those for PX4, which uses "Gazebo Harmonic". +如果你的[ROS2 nodes use the Gazebo clock as time source](../ros2/user_guide.md#ros2-nodes-use-the-gazebo-clock-as-time-source) 但`ros_gz_bridge` 节点没有发布任何关于\`/时钟' 主题的内容。 您可能安装了错误的版本。 +若你在安装 ROS 2 Humble 时,使用的是默认的 “Ignition Fortress” 功能包,而非 PX4 所使用的、适配 “Gazebo Harmonic” 的功能包,就可能出现这种情况。 -The following commands uninstall the default Ignition Fortress topics and install the correct bridge and other interface topics for **Gazebo Harmonic** with ROS2 **Humble**: +以下命令会卸载默认的 Ignition Fortress 功能包,并为搭配 ROS 2 Humble 版本的 Gazebo Harmonic 安装正确的桥接功能包及其他接口功能包: ```bash # Remove the wrong version (for Ignition Fortress) @@ -1018,7 +1015,7 @@ sudo apt remove ros-humble-ros-gz sudo apt install ros-humble-ros-gzharmonic ``` -## Additional information +## 更多信息 - [ROS 2 in PX4: Technical Details of a Seamless Transition to XRCE-DDS](https://www.youtube.com/watch?v=F5oelooT67E) - Pablo Garrido & Nuno Marques (youtube) - [DDS and ROS middleware implementations](https://github.com/ros2/ros2/wiki/DDS-and-ROS-middleware-implementations) diff --git a/docs/zh/sensor/accelerometer.md b/docs/zh/sensor/accelerometer.md index 5aebbe6aae..126b56c53d 100644 --- a/docs/zh/sensor/accelerometer.md +++ b/docs/zh/sensor/accelerometer.md @@ -5,7 +5,7 @@ PX4使用加速计数据进行速度估计。 你无需将加速度计作为独立的外部设备进行连接。 - 大多数飞行控制器,例如[Pixhawk系列](../flight_controller/pixhawk_series.md)中的飞行控制器,都将加速度计作为飞行控制器[惯性测量单元(IMU)](https://en.wikipedia.org/wiki/Inertial_measurement_unit)的一部分。 -- 陀螺仪作为[外部惯性导航系统、姿态与航向参考系统或惯性导航增强型全球导航卫星系统](../sensor/inertial_navigation_systems.md)的一部分而存在。 +- Gyroscopes are present as part of an [external INS, AHRS or INS-enhanced GNSS system](../sensor/inertial_navigation_systems.md). 在首次使用载具之前必须校准加速计: diff --git a/docs/zh/sensor/airspeed.md b/docs/zh/sensor/airspeed.md index 6e5a796164..0442aae34f 100644 --- a/docs/zh/sensor/airspeed.md +++ b/docs/zh/sensor/airspeed.md @@ -73,7 +73,7 @@ Airspeed sensors should be calibrated by following the instructions: [Basic Conf For more advanced validation, configuration and debugging see [Airspeed Validation](../advanced_config/airspeed_validation.md). -## See Also +## 另见 - [Using PX4's Navigation Filter (EKF2) > Airspeed](../advanced_config/tuning_the_ecl_ekf.md#airspeed) - [Airspeed drivers](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/differential_pressure) (source code) diff --git a/docs/zh/sensor/barometer.md b/docs/zh/sensor/barometer.md index e024de62b1..f9fd0496bd 100644 --- a/docs/zh/sensor/barometer.md +++ b/docs/zh/sensor/barometer.md @@ -30,17 +30,51 @@ If needed, you can: - Change the selection order of barometers using the [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) parameters for each barometer. - Disable a barometer by setting its [CAL_BAROx_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) value to `0`. -## Calibration +## Baro Auto-Calibration (Developers) -Barometers don't require calibration. +:::tip +This section documents the automated calibration mechanisms that ensure accurate altitude measurements throughout flight operations. +It is intended primarily for a developer audience who want to understand the underlying mechanisms. +::: - +The system implements two complementary calibration approaches that work together to maintain altitude measurement precision. +Both calibrations are initiated at the beginning after a system boot. +Relative calibration is performed first, followed by GNSS-barometric calibration. -## 开发人员信息 +### Relative Calibration + +Relative baro calibration is **always enabled** and operates automatically during system initialization. +This calibration establishes offset corrections for all secondary baro sensors relative to the primary (selected) sensor. + +This calibration: + +- Eliminates altitude jumps when switching between baro sensors during flight. +- Ensures consistent altitude readings across all available baro sensors. +- Maintains seamless sensor redundancy and failover capability. + +### GNSS-Baro Calibration + +:::info +GNSS-baro calibration requires an operational GNSS receiver with vertical accuracy (EPV) ≤ 8 meters. +Relative calibration must already have completed. +::: + +GNSS-baro calibration adjusts baro sensor offsets to align with absolute altitude measurements from the GNSS receiver. +This calibration is controlled by the [SENS_BAR_AUTOCAL](../advanced_config/parameter_reference.md#SENS_BAR_AUTOCAL) parameter (enabled by default). + +The algorithm monitors GNSS quality, collects altitude differences over a 2-second filtered window, and verifies stability within 4m tolerance. +Once stable, it uses binary search to calculate pressure offsets that align baro altitude with GNSS altitude (0.1m precision), then applies the offset to all sensors and saves the parameters. + +备注: + +- **EKF Independence**: GNSS-baro calibration operates independently of EKF2 altitude fusion settings. +- **Execution Timing**: Calibration runs even when [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL) altitude fusion is disabled. +- **One-Time Process**: Each calibration session completes once per system startup. +- **Persistence**: Calibration offsets are saved to parameters and persist across reboots. +- **Faulty GNSS Vulnerability**: If GNSS data is faulty during boot, the calibration will use incorrect altitude reference. + See [Faulty GNSS Data During Boot](../advanced_config/tuning_the_ecl_ekf.md#faulty-gnss-data-during-boot) for mitigation strategies. + +## 另见 - [Baro driver source code](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers/barometer) - [Modules Reference: Baro (Driver)](../modules/modules_driver_baro.md) documentation. diff --git a/docs/zh/sensor/inertial_navigation_systems.md b/docs/zh/sensor/inertial_navigation_systems.md index 29faaa7347..36b0fb97e8 100644 --- a/docs/zh/sensor/inertial_navigation_systems.md +++ b/docs/zh/sensor/inertial_navigation_systems.md @@ -2,13 +2,34 @@ PX4 typically runs on flight controllers that include an IMU, such as the Pixhawk series, and fuse the sensor data along with GNSS information in the EKF2 estimator to determine vehicle attitude, heading, position, and velocity. -However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing the EKF. +However PX4 can also use some INS devices as either sources of raw data, or as an external estimator, replacing EKF2. -Systems that can be used in this way include: +## Supported INS Systems + +INS systems that can be used as a replacement for EKF2 in PX4: - [InertialLabs](../sensor/inertiallabs.md) +- [MicroStrain](../sensor/microstrain.md): Includes VRU, AHRS, INS, and GNSS/INS devices. +- [SBG Systems](../sensor/sbgecom.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. - [VectorNav](../sensor/vectornav.md): IMU/AHRS, GNSS/INS, Dual GNSS/INS systems that can be used as an external INS or as a source of raw sensor data. +## PX4 Firmware + +The driver module for your INS system may not be included in the PX4 firmware for your flight controller by default. + +You can check by searching the [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6c/default.px4board#L25) configuration file for your target board for either: + +- `CONFIG_COMMON_INS`, which includes drivers for [all INS systems](https://github.com/PX4/PX4-Autopilot/blob/main/src/drivers/ins/Kconfig). +- The key for the particular INS system you are using, such as: + - `CONFIG_DRIVERS_INS_ILABS` + - `CONFIG_DRIVERS_INS_MICROSTRAIN` + - `CONFIG_DRIVERS_INS_VECTORNAV` + +If the required key is not present you can include the module in firmware by adding the key to the `default.px4board` file, or using the [kconfig board configuration tool](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) and then select the driver you want (`Drivers -> INS`). +Note that if you're working on a flight controller where flash memory is limited, you're better off installing just the modules you need. + +You will then need to rebuild the firmware. + ## Glossary ### Inertial Measurement Unit (IMU) diff --git a/docs/zh/sensor/inertiallabs.md b/docs/zh/sensor/inertiallabs.md index 00f77141a6..68e231041b 100644 --- a/docs/zh/sensor/inertiallabs.md +++ b/docs/zh/sensor/inertiallabs.md @@ -57,11 +57,11 @@ To use the Inertial Labs driver: - For external INS, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `INS`. - For raw inertial sensors, set [ILABS_MODE](../advanced_config/parameter_reference.md#ILABS_MODE) to `Sensors Only`. - You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). + You can then prioritize inertial labs sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where `n` is the instance number of the IMU component (0, 1, etc.). - ::: tip - In most cases the external IMU is the highest-numbered. - You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + ::: tip + In most cases the external IMU is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. ::: diff --git a/docs/zh/sensor/microstrain.md b/docs/zh/sensor/microstrain.md new file mode 100644 index 0000000000..c3191ed484 --- /dev/null +++ b/docs/zh/sensor/microstrain.md @@ -0,0 +1,219 @@ +# MicroStrain (INS, IMU, VRU, AHRS) + +MicroStrain by HBK provides high-performance inertial sensors engineered for reliability and precision in challenging environments. +Widely used across industries like aerospace, robotics, industrial automation, and research, MicroStrain sensors are optimized for real-time, accurate motion tracking and orientation data. + +![CV7](../../assets/hardware/sensors/inertial/microstrain_3dm_cv7_hbk.png) + +The driver currently supports the following hardware: + +- [`MicroStrain CV7-AR`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/vertical-reference-units--vru-/3dm-cv7-ar): Inertial Measurement Unit (IMU) and Vertical Reference Unit (VRU) +- [`MicroStrain CV7-AHRS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/attitude-and-heading-reference-systems--ahrs-/3dm-cv7-ahrs): Inertial Measurement Unit (IMU) and Attitude Heading Reference System (AHRS) +- [`MicroStrain CV7-INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS). +- [`MicroStrain CV7-GNSS/INS`](https://www.hbkworld.com/en/products/transducers/inertial-sensors/inertial-navigation-systems--ins-/3dm-cv7-gnss-ins): Inertial Measurement Unit (IMU) and Inertial Navigation System (INS) combined with dual multiband (GNSS) receivers. + +PX4 can use these sensors to provide raw IMU data for EKF2 or to replace EKF2 as an external INS. +For more information, including user manuals and datasheets, please refer to the sensors product page. + +## 购买渠道 + +MicroStrain sensors can be purchased through HBK's official [MicroStrain product page](https://www.hbkworld.com/en/products/transducers/inertial-sensors) or through authorized distributors globally. +For large orders, custom requirements, or technical inquiries, reach out directly to [sales](https://www.hbkworld.com/en/contact-us/contact-sales-microstrain) + +## 硬件安装 + +### 布线 + +Connect the main UART port of the MicroStrain sensor to any unused serial port on the flight controller. +This port needs to be specified while starting the device. + +### Mounting + +The MicroStrain sensor can be mounted in any orientation. +The default coordinate system uses X for the front, Y for the right, and Z for down, with directions marked on the device. + +## Firmware Configuration + +### PX4 配置 + +To use the MicroStrain driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_MICROSTRAIN` or `CONFIG_COMMON_INS`. + +2. Configure the driver mode by setting [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) + + - To use the MicroStrain sensor to provide raw IMU data to EKF2 + + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 0 + 2. Update the [EKF2_MULTI_IMU](../advanced_config/parameter_reference.md#EKF2_MULTI_IMU) parameter to account for the added MicroStrain sensor. + 3. Enable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 1 + 4. To prioritize MicroStrain sensor output, adjust the priority level of individual sensors from 0-100 using the following parameters: + + - [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO) + - [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO) + - [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO) + - [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO) + + where `n` corresponds to the index of the corresponding sensor. + + ::: tip + Sensors can be identified by their device id, which can be found by checking the parameters: + + - [CAL_ACCn_ID](../advanced_config/parameter_reference.md#CAL_ACC0_ID) + - [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) + - [CAL_MAGn_ID](../advanced_config/parameter_reference.md#CAL_MAG0_ID) + - [CAL_BAROn_ID](../advanced_config/parameter_reference.md#CAL_BARO0_ID) + + +::: + + - To use the MicroStrain sensor as an external INS + 1. Set [MS_MODE](../advanced_config/parameter_reference.md#MS_MODE) to 1 + 2. Disable EKF2 by setting [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN) to 0 + +3. Reboot and start the driver + - `microstrain start -d ` + - To start the driver automatically when the flight controller powers on, set [SENS_MS_CFG](../advanced_config/parameter_reference.md#SENS_MS_CFG) to the sensor’s connected port. + +## MicroStrain Configuration + +1. Rates: + + - By default, accel and gyro data are published at 500 Hz, magnetometer at 50 Hz, and barometric pressure at 50 Hz. + This can be changed by adjusting the following parameters: + + - [MS_IMU_RATE_HZ](../advanced_config/parameter_reference.md#MS_IMU_RATE_HZ) + - [MS_MAG_RATE_HZ](../advanced_config/parameter_reference.md#MS_MAG_RATE_HZ) + - [MS_BARO_RATE_HZ](../advanced_config/parameter_reference.md#MS_BARO_RATE_HZ) + + - Global position, local position, attitude and odometry will be published at 250 Hz by default. + This can be configured via: + + - [MS_FILT_RATE_HZ](../advanced_config/parameter_reference.md#MS_FILT_RATE_HZ) + + - For the CV7-GNSS/INS, the GNSS receiver 1 and 2 will publish data at 5Hz by default. + This can be changed using: + + - [MS_GNSS_RATE_HZ](../advanced_config/parameter_reference.md#MS_GNSS_RATE_HZ) + + - The driver will automatically configure data outputs based on the specific sensor model and available data streams. + + - The driver is scheduled to run at twice the fastest configured data rate. + +2. Aiding measurements: + + - If supported, GNSS position and velocity aiding are always enabled. + + - Internal/external magnetometer and heading aiding, as well as optical flow aiding, are disabled by default. They can be enabled using the following parameters: + + - [MS_INT_MAG_EN](../advanced_config/parameter_reference.md#MS_INT_MAG_EN) + - [MS_INT_HEAD_EN](../advanced_config/parameter_reference.md#MS_INT_HEAD_EN) + - [MS_EXT_HEAD_EN](../advanced_config/parameter_reference.md#MS_EXT_HEAD_EN) + - [MS_EXT_MAG_EN](../advanced_config/parameter_reference.md#MS_EXT_MAG_EN) + - [MS_OPT_FLOW_EN](../advanced_config/parameter_reference.md#MS_OPT_FLOW_EN) + + - The aiding frames for external sources can be configured using the following parameters: + + - [MS_EHEAD_YAW](../advanced_config/parameter_reference.md#MS_EHEAD_YAW) + - [MS_EMAG_ROLL](../advanced_config/parameter_reference.md#MS_EMAG_ROLL) + - [MS_EMAG_PTCH](../advanced_config/parameter_reference.md#MS_EMAG_PTCH) + - [MS_EMAG_YAW](../advanced_config/parameter_reference.md#MS_EMAG_YAW) + - [MS_OFLW_OFF_X](../advanced_config/parameter_reference.md#MS_OFLW_OFF_X) + - [MS_OFLW_OFF_Y](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Y) + - [MS_OFLW_OFF_Z](../advanced_config/parameter_reference.md#MS_OFLW_OFF_Z) + - [SENS_FLOW_ROT](../advanced_config/parameter_reference.md#SENS_FLOW_ROT) + + - The uncertainty for optical flow and external magnetometer aiding must be specified using the following parameters: + + - [MS_EMAG_UNCERT](../advanced_config/parameter_reference.md#MS_EMAG_UNCERT) + - [MS_OFLW_UNCERT](../advanced_config/parameter_reference.md#MS_OFLW_UNCERT) + + ::: tip + + 1. When optical flow aiding is enabled, the sensor uses the `vehicle_optical_flow_vel` output from the flight controller as a body-frame velocity aiding measurement. + 2. If the MicroStrain sensor does not support these aiding sources but they are enabled, sensor initialization will fail. + + +::: + +3. Initial heading alignment: + + - Initial heading alignment is set to kinematic by default. This can be changed by adjusting + + - [MS_ALIGNMENT](../advanced_config/parameter_reference.md#MS_ALIGNMENT) + +4. GNSS Aiding Source Control (GNSS/INS only) + + - The Source of the GNSS aiding data can be configured using: + + - [MS_GNSS_AID_SRC](../advanced_config/parameter_reference.md#MS_GNSS_AID_SRC) + +5. Sensor to vehicle transform: + + - If the sensor is mounted in an orientation different from the vehicle frame. A sensor to vehicle transform can be enabled using + + - [MS_SVT_EN](../advanced_config/parameter_reference.md#MS_SVT_EN) + + - The transform is defined using the following parameters + + - [MS_SENSOR_ROLL](../advanced_config/parameter_reference.md#MS_SENSOR_ROLL) + - [MS_SENSOR_PTCH](../advanced_config/parameter_reference.md#MS_SENSOR_PTCH) + - [MS_SENSOR_YAW](../advanced_config/parameter_reference.md#MS_SENSOR_YAW) + +6. IMU ranges: + + - The accelerometer and gyroscope ranges on the device are configurable using: + + - [MS_ACCEL_RANGE](../advanced_config/parameter_reference.md#MS_ACCEL_RANGE) + - [MS_GYRO_RANGE](../advanced_config/parameter_reference.md#MS_GYRO_RANGE) + + ::: tip + Available range settings depend on the specific [sensor](https://www.hbkworld.com/en/products/transducers/inertial-sensors) and can be found in the corresponding user manual. + By default, the ranges are not changed. + + +::: + +7. GNSS Lever arm offsets: + + - The lever arm offset for the external GNSS receiver can be configured using: + + - [MS_GNSS_OFF1_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_X) + - [MS_GNSS_OFF1_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Y) + - [MS_GNSS_OFF1_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF1_Z) + + - For dual-antenna configurations, the second GNSS receiver’s offset is configured using: + + - [MS_GNSS_OFF2_X](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_X) + - [MS_GNSS_OFF2_Y](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Y) + - [MS_GNSS_OFF2_Z](../advanced_config/parameter_reference.md#MS_GNSS_OFF2_Z) + +## Published Data + +The MicroStrain driver continuously publishes sensor data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) +- [sensor_baro](../msg_docs/SensorBaro.md) + +For GNSS/INS devices, GPS data is also published to: + +- [sensor_gps](../msg_docs/SensorGps.md) + +If used as an external INS replacing EKF2, it publishes: + +- [vehicle_global_position](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) +- [vehicle_odometry](../msg_docs/VehicleOdometry.md) + +otherwise the same data is published to the following topics + +- `external_ins_global_position` +- `external_ins_attitude` +- `external_ins_local_position` + +:::tip +Published topics can be viewed using the `listener` command. +::: diff --git a/docs/zh/sensor/rangefinders.md b/docs/zh/sensor/rangefinders.md index f5d645cb40..4e11fb19ac 100644 --- a/docs/zh/sensor/rangefinders.md +++ b/docs/zh/sensor/rangefinders.md @@ -15,11 +15,69 @@ This is a subset of the rangefinders that can be used with PX4. There may also be other DroneCAN rangefinders than those listed here. ::: -### ARK Flow & AKR Flow MR +| Rangefinder | Technology | Range (min – max) | Connections | NDAA | 备注 | +| ------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------- | ------------------------------------------------------ | +| [Ainstein US-D1 Standard Radar Altimeter] | Microwave radar | ~50 m | UART | ✔️ | | +| [ARK DIST SR] | ToF (850 nm IR) | 8 cm to ~30 m | DroneCAN, UART | ✔️ | | +| [ARK DIST MR] | ToF (IR) | 8 cm to ~50 m | DroneCAN, UART | ✔️ | | +| [Benewake TFmini] | ToF (IR laser) | ~12 m | UART | ~ | | +| [Holybro ST VL53L1X Lidar] | ToF (IR) | up to ~4 m | I2C | ~ | | +| [LeddarOne] | ToF (IR) | 1 cm – 40 m | UART | ~ | | +| [Lidar-Lite] | ToF (IR laser) | 5 cm – 40 m | I2C, PWM | ~ | | +| [LightWare SF11/C] | ToF (IR laser) | up to ~120 m | UART, I2C | ~ | | +| [LightWare LW20/C] | ToF (IR laser) | up to ~100 m | I2C | ~ | Waterproof (IP67) + servo | +| [LightWare SF45/B] | ToF (IR laser) | ~50 m | UART | ~ | Rotary lidar (collision prevention) | +| [MaxBotix I2CXL-MaxSonar-EZ] | Ultrasonic | | I2C | ~ | | +| [RaccoonLab Cyphal & DroneCAN µRANGEFINDER] | ToF (IR) | ~0.1 m – ~8 m | DroneCAN, Cyphal | ~ | | +| [TeraRanger Evo 60 m] | ToF (IR) | 0.5 m – 60 m | I2C | ~ | | +| [TeraRanger Evo 600Hz] | ToF (IR) | 0.75 m – 8 m | I2C | ~ | High update rate (600 Hz) | +| [LightWare SF02] _(disc.)_ | ToF (IR laser) | ~50 m | UART | ~ | Discontinued | +| [LightWare SF10/A] _(disc.)_ | ToF (IR laser) | ~25 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/B] _(disc.)_ | ToF (IR laser) | ~50 m | UART, I2C | ~ | Discontinued | +| [LightWare SF10/C] _(disc.)_ | ToF (IR laser) | ~100 m | UART, I2C | ~ | Discontinued | +| [Lanbao PSK-CM8JL65-CC5] _(disc.)_ | ToF (IR) | 0.17 m – 8 m | UART | ✖️ | Discontinued | +| [TeraRanger One] _(disc.)_ | ToF (IR) | ~0.2 m – ~14 m (typical) | I2C (adapter required) | ~ | Discontinued | -[ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md) are open-source Time-of-Flight (ToF) and optical flow sensor modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. -它可以通过CAN1接口连接至飞控,允许通过CAN2接口添加传感器。 -It supports [DroneCAN](../dronecan/index.md), runs [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and is packed into a tiny form factor. +[Ainstein US-D1 Standard Radar Altimeter]: ../sensor/ulanding_radar.md +[ARK DIST SR]: ../dronecan/ark_dist.md +[ARK DIST MR]: ../dronecan/ark_dist_mr.md +[Benewake TFmini]: ../sensor/tfmini.md +[Holybro ST VL53L1X Lidar]: #holybro-st-vl53l1x-lidar +[Lanbao PSK-CM8JL65-CC5]: ../sensor/cm8jl65_ir_distance_sensor.md +[LeddarOne]: ../sensor/leddar_one.md +[Lidar-Lite]: ../sensor/lidar_lite.md +[LightWare Lidar]: ../sensor/sfxx_lidar.md +[LightWare SF11/C]: ../sensor/sfxx_lidar.md +[LightWare LW20/C]: ../sensor/sfxx_lidar.md +[LightWare SF45/B]: ../sensor/sfxx_lidar.md +[LightWare SF02]: ../sensor/sfxx_lidar.md +[LightWare SF10/A]: ../sensor/sfxx_lidar.md +[LightWare SF10/B]: ../sensor/sfxx_lidar.md +[LightWare SF10/C]: ../sensor/sfxx_lidar.md +[MaxBotix I2CXL-MaxSonar-EZ]: #maxbotix-i2cxl-maxsonar-ez +[TeraRanger Evo 60 m]: ../sensor/teraranger.md +[TeraRanger Evo 600Hz]: ../sensor/teraranger.md +[TeraRanger One]: ../sensor/teraranger.md + +These adaptors allows you to connect a non-CAN rangefinder via the CAN interface. +Note that the range depends on the connected rangefinder + +| Adaptor | Connections | NDAA | +| ------------------------------------------------------- | ---------------- | ----------------- | +| **Avionics Anonymous UAVCAN Laser Altimeter Interface** | DroneCAN | ~ | +| [RaccoonLab Cyphal & DroneCAN Rangefinder Adapter] | DroneCAN, Cyphal | ~ | + +[RaccoonLab Cyphal & DroneCAN µRANGEFINDER]: #raccoonlab-cyphal-and-dronecan-μrangefinder +[RaccoonLab Cyphal & DroneCAN Rangefinder Adapter]: #raccoonlab-cyphal-and-dronecan-rangefinder-adapter + +Note that some [Optical Flow](../sensor/optical_flow.md) sensors also include a rangefinder, such as [ARK Flow](../dronecan/ark_flow.md) and [ARK Flow MR](../dronecan/ark_flow_mr.md). + +### ARK DIST SR & ARK DIST MR + +[ARK DIST SR](../dronecan/ark_dist.md) and [ARK DIST MR](../dronecan/ark_dist_mr.md) are open-source Time-of-Flight (ToF) rangefinder modules, which are capable of measuring distances from 8cm to 30m and from 8cm to 50m, respectively. + +The sensors support [DroneCAN](../dronecan/index.md), run [PX4 DroneCAN Firmware](../dronecan/px4_cannode_fw.md), and are packed into a tiny form factor. +They can be connected to a flight controller via its `CAN1` port, allowing additional sensors to connected through the `CAN2` port. ### Holybro ST VL53L1X 激光雷达 @@ -146,11 +204,11 @@ To view the rangefinder output: 1. Open the menu **Q > Select Tool > Analyze Tools**: - ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) + ![Menu for QGC Analyze Tool](../../assets/qgc/analyze/menu_analyze_tool.png) 2. Select the message `DISTANCE_SENSOR`, and then check the plot checkbox against `current_distance`. - The tool will then plot the result: - ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) + The tool will then plot the result: + ![QGC Analyze DISTANCE_SENSOR value](../../assets/qgc/analyze/qgc_analyze_tool_distance_sensor.png) ### QGroundControl MAVLink Console diff --git a/docs/zh/sensor/sbgecom.md b/docs/zh/sensor/sbgecom.md new file mode 100644 index 0000000000..b8dd1f5141 --- /dev/null +++ b/docs/zh/sensor/sbgecom.md @@ -0,0 +1,157 @@ +# SBG Systems INS/AHRS (Pulse, Ellipse, etc.) + +[SBG-Systems](https://www.sbg-systems.com/) designs, manufactures, and support an extensive range of state-of-the-art inertial sensors such as Inertial Measurement Units (IMU), Attitude and Heading Reference Systems (AHRS), Inertial Navigation Systems with embedded GNSS (INS/GNSS), and so on. + +PX4 supports [all SBG Systems products](https://www.sbg-systems.com/products/) and can use these as an [external INS](../sensor/inertial_navigation_systems.md) (bypassing/replacing the EKF2 estimator), or as a source of raw sensor data provided to the navigation estimator. + +![Ellipse](../../assets/hardware/sensors/inertial/ellipse-inertial-navigation-system.png) + +## 综述 + +SBG Systems products provide a range of benefits to PX4 users and can be integrated for: + +- Higher accuracy heading, pitch, and roll estimates +- More robust and reliable GNSS positioning +- Improved positioning and attitude performance in GNSS-contested environments +- Performance under challenging dynamic conditions (e.g. catapult launches, VTOL operations, high-g or high angular rate operations) + +The sbgECom PX4 driver is streamlined to provide a simple plug-and-play architecture, removing engineering obstacles and allowing the acceleration of the design, development, and launch of platforms to keep pace with the rapid rate of innovation. + +The driver supports [all SBG Systems products](https://www.sbg-systems.com/products/). +In particular the following systems are recommended: + +- **Pulse:** Recommended for fixed-wing systems without hovering, where static heading is not necessary. +- **Ellipse:** Recommended for multicopter systems where hovering and low dynamics requires the use of static heading. + +## 购买渠道 + +SBG Systems solutions are available directly from [MySBG](https://my.sbg-systems.com) (FR) or through their Global Sales Representatives. For more information on their solutions or for international orders, please contact contact@sbg-systems.com. + +## 硬件安装 + +### 布线 + +Connect any unused flight controller serial interface, such as a spare `GPS` or `TELEM` port, to the SBG Systems product MAIN port (required by PX4). + +### Mounting + +The SBG Systems product sensor can be mounted in any orientation, in any position on the vehicle, without regard to center of gravity. +All SBG Systems product sensors default to a coordinate system of x-forward, y-right, and z-down, making the default mounting as connector-back, base down. +This can be changed to any rigid rotation using the sbgECom Reference Frame Rotation register. + +If using a GNSS-enabled product, the GNSS antenna must be mounted rigidly with respect to the inertial sensor and with an unobstructed sky view. If using a dual-GNSS-enabled product (Ellipse-D), the secondary antenna must be mounted rigidly with respect to the primary antenna and the inertial sensor with an unobstructed sky view. + +For more mounting and configuration requirements and recommendations, see the relevant [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +## Firmware Configuration + +### PX4 配置 + +To use the sbgECom driver: + +1. Include the module in firmware in the [kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) by setting the kconfig variables: `CONFIG_DRIVERS_INS_SBGECOM` or `CONFIG_COMMON_INS`. + +2. [Set the parameter](../advanced_config/parameters.md) [SENS_SBG_CFG](../advanced_config/parameter_reference.md#SENS_SBG_CFG) to the hardware port connected to the SBG Systems product (for more information see [Serial Port Configuration](../peripherals/serial_configuration.md)). + + ::: warning + Disable or change port of other sensors that are using the same one, for example [GPS_1_CONFIG](../advanced_config/parameter_reference.md#GPS_1_CONFIG) if using GPS1 port. + +::: + +3. Set [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) to the desired default baudrate value. + +4. Allow the sbgECom driver to initialize by restarting PX4. + +5. Configure driver to provide IMU data, GNSS data and INS : + + 1. Set [SBG_MODE](../advanced_config/parameter_reference.md#SBG_MODE) to the desired mode. + 2. Make sensor module select sensors by enabling [SENS_IMU_MODE](../advanced_config/parameter_reference.md#SENS_IMU_MODE). + 3. Prioritize SBG Systems sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + + ::: tip + In most cases the external IMU (SBG) is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + + Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. + The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. + +::: + + ::: warning + When configuring both SBG Systems and Pixhawk sensors to have non-zero priority, if the selected sensor is errored (timeout), it can change during operation without being notified. + In this case, MAVLink messages will be updated with the newly selected sensor. + + If you don't want to have this fallback mechanism, you must disable unwanted sensors. + +::: + 4. If using the sbgECom as an INS, disable EKF2 using [EKF2_EN](../advanced_config/parameter_reference.md#EKF2_EN). + +6. Restart PX4. + +Once enabled, the module will be detected on boot. +IMU data should be published at 200Hz. + +## SBG Systems Configuration + +All High Performance and Ellipse 3.0 and higher SBG Systems INS can be configured directly from PX4 firmware: + +1. Enable [SBG_CONFIGURE_EN](../advanced_config/parameter_reference.md#SBG_CONFIGURE_EN). + +2. Provide a JSON file `sbg_settings.json` containing SBG Systems INS settings to be applied in your PX4 board `extras` directory (ex: `boards/px4/fmu-v5/extras`). The settings JSON file will be installed in `/etc/extras/sbg_settings.json` on the board. + + ::: tip + The settings can be retrieved using [sbgEComAPI](https://github.com/SBG-Systems/sbgECom/tree/main/tools/sbgEComApi) or [sbgInsRestApi](https://developer.sbg-systems.com/sbgInsRestApi/1.3/#tag/Settings) and then modified as a JSON file. + +::: + + ::: tip + The settings file can be provided in the SD card in q`/fs/microsd/etc/extras/sbg_settings.json` to avoid rebuilding a new firmware to change JSON settings file. + +::: + +3. For testing purpose, it's also possible to modify SBG Systems INS settings on the fly: + - By passing a JSON file path as argument when starting sbgecom driver (ex: `sbgecom start -f /fs/microsd/new_sbg_settings.json`) + - By passing a JSON string as argument when starting sbgecom driver: (ex: `sbgecom start -s {"output":{"comA":{"messages":{"airData":"onChange"}}}}`) + +For older Ellipse SBG Systems INS or to configure any SBG Systems INS directly, all commands and registers can be found in the [SBG SUPPORT CENTER](https://support.sbg-systems.com/sc). + +:::warning +If the baudrate of the serial port on the INS product (used to communicate with PX4) is changed, the parameter [SBG_BAUDRATE](../advanced_config/parameter_reference.md#SBG_BAUDRATE) must be changed to match. +::: + +## Published Data + +Upon initialization, the driver should print the following information to console (printed using `PX4_INFO`) + +- Unit model number +- Unit hardware version +- Unit serial number +- Unit firmware number + +This should be accessible using the [`dmesg`](../modules/modules_system.md#dmesg) command. + +The sbgECom driver always publishes the unit's data to the following uORB topics: + +- [sensor_accel](../msg_docs/SensorAccel.md) +- [sensor_gyro](../msg_docs/SensorGyro.md) +- [sensor_mag](../msg_docs/SensorMag.md) + +if configured as a GNSS, publishes: + +- [sensor_gps](../msg_docs/SensorGps.md) + +and, if configured as an INS, publishes: + +- [estimator_status](../msg_docs/EstimatorStatus.md) +- [vehicle_local_position](../msg_docs/VehicleLocalPosition.md) +- [vehicle_global_positon](../msg_docs/VehicleGlobalPosition.md) +- [vehicle_attitude](../msg_docs/VehicleAttitude.md) + +:::tip +Published topics can be viewed using the `listener` command. +::: + +## Hardware Specifications + +- [Product Briefs](https://www.sbg-systems.com/products/) +- [Datasheets](https://www.sbg-systems.com/contact/#products) diff --git a/docs/zh/sensor/sfxx_lidar.md b/docs/zh/sensor/sfxx_lidar.md index 390e52128a..561d08a26b 100644 --- a/docs/zh/sensor/sfxx_lidar.md +++ b/docs/zh/sensor/sfxx_lidar.md @@ -9,11 +9,14 @@ These are useful for applications including terrain following, precision hoverin The following models are supported by PX4, and can be connected to either the I2C or Serial bus (the tables below indicates what bus can be used for each model). -| Model | Range (m) | Bus | 描述 | -| ---------------------------------------------------------- | ---------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------- | -| [SF11/C](https://lightwarelidar.com/products/sf11-c-100-m) | 100 | Serial or I2C bus | | -| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C bus | Waterproofed (IP67) with servo for sense-and-avoid applications | -| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Serial | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| Model | Range (m) | Bus | 描述 | +| ------------------------------------------------------- | ---------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------- | +| [SF11/C](https://lightwarelidar.com/shop/sf11-c-100-m/) | 100 | Serial or I2C bus | | +| [LW20/C](https://lightware.co.za/products/lw20-c-100-m) | 100 | I2C bus | Waterproofed (IP67) with servo for sense-and-avoid applications | +| [SF30/D](https://lightwarelidar.com/shop/sf30-d-200-m/) | 200 | I2C bus | Waterproofed (IP67) | +| [SF45/B](../sensor/sf45_rotating_lidar.md) | 50 | Serial | Rotary Lidar (Used for [Collision Prevention](../computer_vision/collision_prevention.md)) | +| [GRF250](https://lightwarelidar.com/shop/grf-250/) | 250 | I2C | Gimbal Range Finder | +| [GRF500](https://lightwarelidar.com/shop/grf-500/) | 500 | I2C | Gimbal Range Finder | :::details Discontinued diff --git a/docs/zh/sensor/vectornav.md b/docs/zh/sensor/vectornav.md index 1ec42b5668..84003cf023 100644 --- a/docs/zh/sensor/vectornav.md +++ b/docs/zh/sensor/vectornav.md @@ -61,18 +61,18 @@ To use the VectorNav driver: 5. Configure driver as either an external INS or to provide raw data: - If using the VectorNav as an external INS, set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `INS`. - This disables EKF2. + This disables EKF2. - If using the VectorNav as external inertial sensors: - 1. Set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `Sensors Only` - 2. If internal sensors are enabled, prioritize VectorNav sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). + 1. Set [VN_MODE](../advanced_config/parameter_reference.md#VN_MODE) to `Sensors Only` + 2. If internal sensors are enabled, prioritize VectorNav sensors using [CAL_GYROn_PRIO](../advanced_config/parameter_reference.md#CAL_GYRO0_PRIO), [CAL_ACCn_PRIO](../advanced_config/parameter_reference.md#CAL_ACC0_PRIO), [CAL_BAROn_PRIO](../advanced_config/parameter_reference.md#CAL_BARO0_PRIO), [CAL_MAGn_PRIO](../advanced_config/parameter_reference.md#CAL_MAG0_PRIO), where _n_ is the instance number of the IMU component (0, 1, etc.). - ::: tip - In most cases the external IMU (VN) is the highest-numbered. - You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. + ::: tip + In most cases the external IMU (VN) is the highest-numbered. + You can get a list of the IMU components available using [`uorb top -1`](../middleware/uorb.md#uorb-top-command), you can differentiate between them using the [`listener`](../modules/modules_command.md#listener) command and looking through the data, or just the rates. - Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. - The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. + Alternatively, you can check [CAL_GYROn_ID](../advanced_config/parameter_reference.md#CAL_GYRO0_ID) to see the device id. + The priority is 0-255, where 0 is entirely disabled and 255 is highest priority. ::: diff --git a/docs/zh/sim_flightgear/index.md b/docs/zh/sim_flightgear/index.md index 9e5e0c2179..d528471c34 100644 --- a/docs/zh/sim_flightgear/index.md +++ b/docs/zh/sim_flightgear/index.md @@ -40,33 +40,33 @@ These instructions were tested on Ubuntu 18.04 2. Install FlightGear: - ```sh - sudo add-apt-repository ppa:saiarcot895/flightgear - sudo apt update - sudo apt install flightgear - ``` + ```sh + sudo add-apt-repository ppa:saiarcot895/flightgear + sudo apt update + sudo apt install flightgear + ``` - This installs the latest stable FlightGear version from the PAA repository along with the FGdata package. + This installs the latest stable FlightGear version from the PAA repository along with the FGdata package. - :::tip - For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. - Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). + :::tip + For some models (e.g. those with electric engines) the daily build with the newest features may be necessary. + Install this using the [daily build PPA](https://launchpad.net/~saiarcot895/+archive/ubuntu/flightgear-edge). ::: 3. Check that you are able to run FlightGear: - ```sh - fgfs --launcher - ``` + ```sh + fgfs --launcher + ``` 4. Set write permissions to the **Protocols** folder in the FlightGear installation directory: - ```sh - sudo chmod a+w /usr/share/games/flightgear/Protocol - ``` + ```sh + sudo chmod a+w /usr/share/games/flightgear/Protocol + ``` - Setting the permissions is required because the PX4-FlightGear-Bridge puts the communication definition file here. + Setting the permissions is required because the PX4-FlightGear-Bridge puts the communication definition file here. Additional installation instructions can be found on [FlightGear wiki](https://wiki.flightgear.org/Howto:Install_Flightgear_from_a_PPA). diff --git a/docs/zh/sim_gazebo_classic/index.md b/docs/zh/sim_gazebo_classic/index.md index 73f6f7444f..d3245db579 100644 --- a/docs/zh/sim_gazebo_classic/index.md +++ b/docs/zh/sim_gazebo_classic/index.md @@ -249,14 +249,14 @@ It is enabled by default in many vehicle SDF files: **solo.sdf**, **iris.sdf**, To enable/disable GPS noise: 1. Build any gazebo target in order to generate SDF files (for all vehicles). - 例如: + 例如: - ```sh - make px4_sitl gazebo-classic_iris - ``` + ```sh + make px4_sitl gazebo-classic_iris + ``` - :::tip - The SDF files are not overwritten on subsequent builds. + :::tip + The SDF files are not overwritten on subsequent builds. ::: @@ -264,17 +264,17 @@ To enable/disable GPS noise: 3. Search for the `gpsNoise` element: - ```xml - - - true - - ``` + ```xml + + + true + + ``` - - If it is present, GPS is enabled. - You can disable it by deleting the line: `true` - - If it is not present, GPS is disabled. - You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). + - If it is present, GPS is enabled. + You can disable it by deleting the line: `true` + - If it is not present, GPS is disabled. + You can enable it by adding the `gpsNoise` element to the `gps_plugin` section (as shown above). The next time you build/restart Gazebo Classic it will use the new GPS noise setting. diff --git a/docs/zh/sim_gazebo_classic/multi_vehicle_simulation.md b/docs/zh/sim_gazebo_classic/multi_vehicle_simulation.md index 722bfd7a30..381773e488 100644 --- a/docs/zh/sim_gazebo_classic/multi_vehicle_simulation.md +++ b/docs/zh/sim_gazebo_classic/multi_vehicle_simulation.md @@ -68,36 +68,36 @@ To build an example setup, follow the steps below: 1. Clone the PX4/Firmware code, then build the SITL code: - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl gazebo-classic + ``` 2. Build the `micro xrce-dds agent` and the interface package following the [instructions here](../ros2/user_guide.md). 3. Run `Tools/simulation/gazebo-classic/sitl_multiple_run.sh`. - For example, to spawn 4 vehicles, run: + For example, to spawn 4 vehicles, run: - ```sh - ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 - ``` + ```sh + ./Tools/simulation/gazebo-classic/sitl_multiple_run.sh -m iris -n 4 + ``` - ::: info - Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). - MAVLink system id 1 is skipped. + ::: info + Each vehicle instance is allocated a unique MAVLink system id (2, 3, 4, etc.). + MAVLink system id 1 is skipped. ::: 4. Run `MicroXRCEAgent`. - It will automatically connect to all four vehicles: + It will automatically connect to all four vehicles: - ```sh - MicroXRCEAgent udp4 -p 8888 - ``` + ```sh + MicroXRCEAgent udp4 -p 8888 + ``` - ::: info - The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. + ::: info + The simulator startup script automatically assigns a [unique namespace](../ros2/multi_vehicle.md) to each vehicle. ::: @@ -117,27 +117,27 @@ To build an example setup, follow the step below: 1. Clone the PX4/PX4-Autopilot code, then build the SITL code - ```sh - cd Firmware_clone - git submodule update --init --recursive - DONT_RUN=1 make px4_sitl_default gazebo-classic - ``` + ```sh + cd Firmware_clone + git submodule update --init --recursive + DONT_RUN=1 make px4_sitl_default gazebo-classic + ``` 2. Source your environment: - ```sh - source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default - export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo - ``` + ```sh + source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default + export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/simulation/gazebo-classic/sitl_gazebo + ``` 3. Run launch file: - ```sh - roslaunch px4 multi_uav_mavros_sitl.launch - ``` + ```sh + roslaunch px4 multi_uav_mavros_sitl.launch + ``` - ::: info - You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. + ::: info + You can specify `gui:=false` in the above _roslaunch_ to launch Gazebo Classic without its UI. ::: @@ -253,45 +253,45 @@ This section shows how developers can simulate multiple vehicles using vehicle m 1. Install _xmlstarlet_ from your Linux terminal: - ```sh - sudo apt install xmlstarlet - ``` + ```sh + sudo apt install xmlstarlet + ``` 2. Use _roslaunch_ with the **multi_uav_mavros_sitl_sdf.launch** launch file: - ````sh - roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= - ``` + ````sh + roslaunch multi_uav_mavros_sitl_sdf.launch vehicle:= + ``` - ::: info - Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. + ::: info + Note that the vehicle model file name argument is optional (`vehicle:=`); if omitted the [plane model](https://github.com/PX4/PX4-SITL_gazebo-classic/tree/master/models/plane) will be used by default. ::: - ```` + ```` This method is similar to using the xacro except that the SITL/Gazebo Classic port number is automatically inserted by _xmstarlet_ for each spawned vehicle, and does not need to be specified in the SDF file. To add a new vehicle, you need to make sure the model can be found (in order to spawn it in Gazebo Classic), and PX4 needs to have an appropriate corresponding startup script. 1. You can choose to do either of: - - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: + - modify the **single_vehicle_spawn_sdf.launch** file to point to the location of your model by changing the line below to point to your model: - ```sh - $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf - ``` + ```sh + $(find px4)/Tools/simulation/gazebo/sitl_gazebo-classic/models/$(arg vehicle)/$(arg vehicle).sdf + ``` - ::: info - Ensure you set the `vehicle` argument even if you hardcode the path to your model. + ::: info + Ensure you set the `vehicle` argument even if you hardcode the path to your model. ::: - - copy your model into the folder indicated above (following the same path convention). + - copy your model into the folder indicated above (following the same path convention). 2. The `vehicle` argument is used to set the `PX4_SIM_MODEL` environment variable, which is used by the default rcS (startup script) to find the corresponding startup settings file for the model. - Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. - For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). - For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). - For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. + Within PX4 these startup files can be found in the **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/** directory. + For example, here is the plane model's [startup script](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/1030_gazebo-classic_plane). + For this to work, the PX4 node in the launch file is passed arguments that specify the _rcS_ file (**etc/init.d/rcS**) and the location of the rootfs etc directory (`$(find px4)/build_px4_sitl_default/etc`). + For simplicity, it is suggested that the startup file for the model be placed alongside PX4's in **PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/**. ## Additional Resources diff --git a/docs/zh/sim_gazebo_classic/worlds.md b/docs/zh/sim_gazebo_classic/worlds.md index 804df72e9d..5baf68e163 100644 --- a/docs/zh/sim_gazebo_classic/worlds.md +++ b/docs/zh/sim_gazebo_classic/worlds.md @@ -1,6 +1,6 @@ -# Gazebo Classic Worlds +# Gazebo 经典世界 -This topic provides imagery/information about the [Gazebo Classic](../sim_gazebo_classic/index.md) worlds supported by PX4. +这个主题提供了 PX4 支持的 [Gazebo Classic](../sim_gazebo_classic/index.md) 世界的图像/信息。 The [empty.world](#empty_world) is spawned by default, though this may be overridden by a [model specific world](#model_specific_worlds). Developers can also manually specify the world to load: [Gazebo Classic > Loading a Specific World](../sim_gazebo_classic/index.md#loading-a-specific-world). @@ -69,4 +69,4 @@ The model specific worlds are: - [uuv_hippocampus.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/uuv_hippocampus.world): An empty world used to simulate an underwater environment for the [HippoCampus UUV](../sim_gazebo_classic/vehicles.md#hippocampus-tuhh-uuv). - [typhoon_h480.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/typhoon_h480.world): Used by [Typhoon H480 (Hexrotor)](../sim_gazebo_classic/vehicles.md#typhoon-h480-hexrotor) vehicle model and includes a video widget to enable / disable video streaming. The world includes a gazebo plugin for a simulated camera. -- [iris_irlock.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/iris_irlock.world): Includes a IR beacon for testing [precision landing](../advanced_features/precland.md). +- [iris_irlock.world](https://github.com/PX4/PX4-SITL_gazebo-classic/blob/main/worlds/iris_irlock.world): 包括用于测试[精确着陆]的IR 信标(../advanced_features/precland.md)。 diff --git a/docs/zh/sim_gazebo_gz/gazebo_models.md b/docs/zh/sim_gazebo_gz/gazebo_models.md index 915dd7a90d..5756fa3bda 100644 --- a/docs/zh/sim_gazebo_gz/gazebo_models.md +++ b/docs/zh/sim_gazebo_gz/gazebo_models.md @@ -101,15 +101,15 @@ This example explains how you can run standalone mode PX4 via two terminals on o 1. In one terminal run - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_WORLD=windy ./build/px4_sitl_default/bin/px4 + ``` 2. In a second terminal window run: - ```sh - python3 /path/to/simulation-gazebo --world windy - ``` + ```sh + python3 /path/to/simulation-gazebo --world windy + ``` No additional parameters have to be passed to the simulation-gazebo script in order for this example to work, as all Gazebo nodes run on the same host. See the example below for a more involved scenario with different hosts. diff --git a/docs/zh/sim_gazebo_gz/index.md b/docs/zh/sim_gazebo_gz/index.md index 34c383c3c9..f9dfc91f12 100644 --- a/docs/zh/sim_gazebo_gz/index.md +++ b/docs/zh/sim_gazebo_gz/index.md @@ -20,6 +20,8 @@ See [Simulation](../simulation/index.md) for general information about simulator Gazebo Harmonic is installed by default on Ubuntu 22.04 as part of the normal [development environment setup](../dev_setup/dev_env_linux_ubuntu.md#simulation-and-nuttx-pixhawk-targets). +Gazebo versions Harmonic, Ionic, and Jetty are supported on Ubuntu 24.04. The latest installed Gazebo release is used by default. + :::info The PX4 installation scripts are based on the instructions: [Binary Installation on Ubuntu](https://gazebosim.org/docs/harmonic/install_ubuntu/) (gazebosim.org). ::: @@ -48,22 +50,23 @@ This runs both the PX4 SITL instance and the Gazebo client. The supported vehicles and `make` commands are listed below. Note that all gazebo make targets have the prefix `gz_`. -| Vehicle | 通信 | `PX4_SYS_AUTOSTART` | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------- | -| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4011 | -| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | -| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | -| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | -| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | -| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | -| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | -| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | -| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | -| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | -| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_r1_rover` | 4009 | -| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 4012 | -| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | -| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| Vehicle | 通信 | `PX4_SYS_AUTOSTART` | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------------------- | +| [Quadrotor (x500)](../sim_gazebo_gz/vehicles.md#x500-quadrotor) | `make px4_sitl gz_x500` | 4011 | +| [X500 Quadrotor with Depth Camera (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-depth-camera-front-facing) | `make px4_sitl gz_x500_depth` | 4002 | +| [Quadrotor(x500) with Vision Odometry](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-visual-odometry) | `make px4_sitl gz_x500_vision` | 4005 | +| [Quadrotor(x500) with 1D LIDAR (Down-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-down-facing) | `make px4_sitl gz_x500_lidar_down` | 4016 | +| [Quadrotor(x500) with 2D LIDAR](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-2d-lidar) | `make px4_sitl gz_x500_lidar_2d` | 4013 | +| [Quadrotor(x500) with 1D LIDAR (Front-facing)](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-1d-lidar-front-facing) | `make px4_sitl gz_x500_lidar_front` | 4017 | +| [Quadrotor(x500) with gimbal (Front-facing) in Gazebo](../sim_gazebo_gz/vehicles.md#x500-quadrotor-with-gimbal-front-facing) | `make px4_sitl gz_x500_gimbal` | 4019 | +| [VTOL](../sim_gazebo_gz/vehicles.md#standard-vtol) | `make px4_sitl gz_standard_vtol` | 4004 | +| [Plane](../sim_gazebo_gz/vehicles.md#standard-plane) | `make px4_sitl gz_rc_cessna` | 4003 | +| [Advanced Plane](../sim_gazebo_gz/vehicles.md#advanced-plane) | `make px4_sitl gz_advanced_plane` | 4008 | +| [Quad Tailsitter VTOL](../sim_gazebo_gz/vehicles.md#quad-tailsitter-vtol) | `make px4_sitl gz_quadtailsitter` | 4018 | +| [Tiltrotor VTOL](../sim_gazebo_gz/vehicles.md#tiltrotor-vtol) | `make px4_sitl gz_tiltrotor` | 4020 | +| [Differential Rover](../sim_gazebo_gz/vehicles.md#differential-rover) | `make px4_sitl gz_rover_differential` | 50000 | +| [Ackermann Rover](../sim_gazebo_gz/vehicles.md#ackermann-rover) | `make px4_sitl gz_rover_ackermann` | 51000 | +| [Mecanum Rover](../sim_gazebo_gz/vehicles.md#mecanum-rover) | `make px4_sitl gz_rover_mecanum` | 52000 | All [vehicle models](../sim_gazebo_gz/vehicles.md) (and [worlds](#specify-world)) are included as a submodule from the [Gazebo Models Repository](../sim_gazebo_gz/gazebo_models.md) repository. @@ -316,33 +319,33 @@ Here are some examples of the different scenarios covered above. 1. **Start simulator + default world + spawn vehicle at default pose** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 2. **Start simulator + default world + spawn vehicle at custom pose (y=2m)** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,2" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` 3. **Start simulator + default world + link to existing vehicle** - ```sh - PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_NAME=x500 ./build/px4_sitl_default/bin/px4 + ``` 4. **Start simulator in standalone mode + connect to Gazebo instance running default world** - ```sh - PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 + ``` - In a separate terminal run: + In a separate terminal run: - ```sh - python /path/to/simulation-gazebo - ``` + ```sh + python /path/to/simulation-gazebo + ``` ## Adding New Worlds and Models @@ -358,38 +361,38 @@ To add a new model: 2. Define the default parameters for Gazebo in the airframe configuration file (this example is from [x500 quadcopter](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/4001_gz_x500)): - ```ini - PX4_SIMULATOR=${PX4_SIMULATOR:=gz} - PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} - PX4_SIM_MODEL=${PX4_SIM_MODEL:=} - ``` + ```ini + PX4_SIMULATOR=${PX4_SIMULATOR:=gz} + PX4_GZ_WORLD=${PX4_GZ_WORLD:=default} + PX4_SIM_MODEL=${PX4_SIM_MODEL:=} + ``` - - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. + - `PX4_SIMULATOR=${PX4_SIMULATOR:=gz}` sets the default simulator (Gz) for that specific airframe. - - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. + - `PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}` sets the [default world](https://github.com/PX4/PX4-gazebo-models/blob/main/worlds/default.sdf) for that specific airframe. - - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: + - Setting the default value of `PX4_SIM_MODEL` lets you start the simulation with just: - ```sh - PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 - ``` + ```sh + PX4_SYS_AUTOSTART= ./build/px4_sitl_default/bin/px4 + ``` 3. Add CMake Target for the [airframe](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt). - - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. - - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` + - If you plan to use "regular" mode, add your model SDF to `Tools/simulation/gz/models/`. + - If you plan to use _standalone_ mode, add your model SDF to `~/.simulation-gazebo/models/` - You can of course also use both. + You can of course also use both. ### Adding a World To add a new world: 1. Add your world to the list of worlds found in the [`CMakeLists.txt` here](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/CMakeLists.txt). - This is required in order to allow `CMake` to generate correct targets. + This is required in order to allow `CMake` to generate correct targets. - - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. - - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` + - If you plan to use "normal" mode, add your world sdf to `Tools/simulation/gz/worlds/`. + - If you plan to use _standalone_ mode, add your world SDF to `~/.simulation-gazebo/worlds/` :::info As long as the world file and the model file are in the Gazebo search path (`GZ_SIM_RESOURCE_PATH`) it is not necessary to add them to the PX4 world and model directories. diff --git a/docs/zh/sim_gazebo_gz/plugins.md b/docs/zh/sim_gazebo_gz/plugins.md index 9723f44177..0f48c53db8 100644 --- a/docs/zh/sim_gazebo_gz/plugins.md +++ b/docs/zh/sim_gazebo_gz/plugins.md @@ -43,8 +43,8 @@ When developing new plugins: 1. **Follow the plugin architecture** - Implement desired interfaces. - You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. - The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). + You can start by copying the [Template plugin](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/simulation/gz_plugins/template_plugin) which is a simple example that only implements `ISystemPreUpdate` and `ISystemPostUpdate`. + The interfaces are specified in the official [Gazebo documentation](https://gazebosim.org/api/sim/9/createsystemplugins.html). 2. **Register your plugin** - Add it to [server.config](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/simulation/gz_bridge/server.config) for discovery. diff --git a/docs/zh/sim_gazebo_gz/tools_avl_automation.md b/docs/zh/sim_gazebo_gz/tools_avl_automation.md index 049c37b623..fd57223dce 100644 --- a/docs/zh/sim_gazebo_gz/tools_avl_automation.md +++ b/docs/zh/sim_gazebo_gz/tools_avl_automation.md @@ -11,26 +11,26 @@ The results will then automatically be written into a provided plugin template t To setup the tool: 1. Download AVL 3.36 from . - The file for AVL version 3.36 can be found about halfway down the page. + The file for AVL version 3.36 can be found about halfway down the page. 2. After downloading, extract AVL and move it to the home directory using: - ```sh - sudo tar -xf avl3.36.tgz - mv ./Avl /home/ - ``` + ```sh + sudo tar -xf avl3.36.tgz + mv ./Avl /home/ + ``` 3. Follow the **index.md** found in `./Avl` to finish the setup process for AVL (this requires that you set up `plotlib` and `eispack` libraries). - We recommend using the `gfortran` compile option, which might further require that you to install `gfortran`. - On Ubuntu can be done by running: + We recommend using the `gfortran` compile option, which might further require that you to install `gfortran`. + On Ubuntu can be done by running: - ```sh - sudo apt update - sudo apt install gfortran - ``` + ```sh + sudo apt update + sudo apt install gfortran + ``` - When running the Makefile for AVL, you might encounter an `Error 1` message stating that there is a directory missing. - This does not prevent AVL from working for our purposes. + When running the Makefile for AVL, you might encounter an `Error 1` message stating that there is a directory missing. + This does not prevent AVL from working for our purposes. Once the process described in the AVL README is completed, AVL is ready to be used. No further set up is required on the side of the AVL or the tool. @@ -49,16 +49,16 @@ To run the tool for your plane: 2. Run the tool on your yml file: - ```sh - python input_avl.py .yml - ``` + ```sh + python input_avl.py .yml + ``` - Note that the `yaml` and `argparse` packages must be present in your Python environment. + Note that the `yaml` and `argparse` packages must be present in your Python environment. 3. The tool prompts for a range of vehicle specific parameters that are needed in order to specify the geometry and physical properties of the plane. - You can either: - - select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and just modify some physical properties, or - - define a completely custom model + You can either: + - select a predefined model template (such as a Cessna or a VTOL), which has a known number of control surfaces, and just modify some physical properties, or + - define a completely custom model Once the script has been executed, the generated `.avl`, `.sdf` and a plot of the proposed control surfaces can be found in `` directory. The sdf file is the generated Advanced Lift Drag Plugin that can be copied and pasted into a model.sdf file, which can then be run in Gazebo. diff --git a/docs/zh/sim_gazebo_gz/vehicles.md b/docs/zh/sim_gazebo_gz/vehicles.md index a449199159..ba9b16be4a 100644 --- a/docs/zh/sim_gazebo_gz/vehicles.md +++ b/docs/zh/sim_gazebo_gz/vehicles.md @@ -185,7 +185,7 @@ make px4_sitl gz_tiltrotor [Differential Rover](../frames_rover/index.md#differential) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. ```sh -make px4_sitl gz_r1_rover +make px4_sitl gz_rover_differential ``` ![Differential Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_differential.png) @@ -199,3 +199,13 @@ make px4_sitl gz_rover_ackermann ``` ![Ackermann Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_ackermann.png) + +### Mecanum Rover + +[Mecanum Rover](../frames_rover/index.md#mecanum) uses the [rover world](../sim_gazebo_gz/worlds.md#rover) by default. + +```sh +make px4_sitl gz_rover_mecanum +``` + +![Mecanum Rover in Gazebo](../../assets/simulation/gazebo/vehicles/rover_mecanum.png) diff --git a/docs/zh/sim_jmavsim/index.md b/docs/zh/sim_jmavsim/index.md index 8208f0b7a6..d63db8d443 100644 --- a/docs/zh/sim_jmavsim/index.md +++ b/docs/zh/sim_jmavsim/index.md @@ -30,23 +30,23 @@ Follow the instructions below to install jMAVSim on macOS. To setup the environment for [jMAVSim](../sim_jmavsim/index.md) simulation: 1. Install a recent version of Java (e.g. Java 15). - You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): + You can download [Java 15 (or later) from Oracle](https://www.oracle.com/java/technologies/downloads/?er=221886) or use [Eclipse Temurin](https://adoptium.net): - ```sh - brew install --cask temurin - ``` + ```sh + brew install --cask temurin + ``` 2. Install jMAVSim: - ```sh - brew install px4-sim-jmavsim - ``` + ```sh + brew install px4-sim-jmavsim + ``` - :::warning - PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. + :::warning + PX4 v1.11 and beyond require at least JDK 15 for jMAVSim simulation. - For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. - You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). + For earlier versions, macOS users might see the error `Exception in thread "main" java.lang.UnsupportedClassVersionError:`. + You can find the fix in the [jMAVSim with SITL > Troubleshooting](../sim_jmavsim/index.md#troubleshooting)). ::: diff --git a/docs/zh/sim_sih/index.md b/docs/zh/sim_sih/index.md index 7b09b1442f..383c700b8c 100644 --- a/docs/zh/sim_sih/index.md +++ b/docs/zh/sim_sih/index.md @@ -27,8 +27,8 @@ The Desktop computer is only used to display the virtual vehicle. - SIH for FW (airplane) and VTOL tailsitter are supported from PX4 v1.13. - SIH as SITL (without hardware) from PX4 v1.14. - SIH for Standard VTOL from PX4 v1.16. -- SIH for MC Hexacopter X from `main` (expected to be PX4 v1.17). -- SIH for Ackermann Rover from `main`. +- SIH for MC Hexacopter X from PX4 v1.17. +- SIH for Ackermann Rover from PX4 v1.17. ### Benefits @@ -65,30 +65,30 @@ These include: [`pwm_out_sim`](../modules/modules_driver.md#pwm-out-sim), [`sens To check that these are present on your flight controller: -1. Start QGroundControl. +1. 启动QGroundControl。 2. Open **Analyze Tools > Mavlink Console**. 3. Enter the following commands in the console: - ```sh - pwm_out_sim status - ``` + ```sh + pwm_out_sim status + ``` - ```sh - sensor_baro_sim status - ``` + ```sh + sensor_baro_sim status + ``` - ```sh - sensor_gps_sim status - ``` + ```sh + sensor_gps_sim status + ``` - ```sh - sensor_mag_sim status - ``` + ```sh + sensor_mag_sim status + ``` - ::: tip - Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). + ::: tip + Note that when using SIH on real hardware you do not need to additionally enable the modules using their corresponding parameters ([SENS_EN_GPSSIM](../advanced_config/parameter_reference.md#SENS_EN_GPSSIM), [SENS_EN_BAROSIM](../advanced_config/parameter_reference.md#SENS_EN_BAROSIM), [SENS_EN_MAGSIM](../advanced_config/parameter_reference.md#SENS_EN_MAGSIM)). ::: @@ -141,12 +141,12 @@ To set up/start SIH: 1. Connect the flight controller to the desktop computer with a USB cable. 2. Open QGroundControl and wait for the flight controller too boot and connect. 3. Open [Vehicle Setup > Airframe](../config/airframe.md) then select the desired frame: - - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) - - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). - - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) - - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) - - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) - - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) + - [SIH Quadcopter X](../airframes/airframe_reference.md#copter_simulation_sih_quadcopter_x) + - **SIH Hexacopter X** (currently only has an airframe for SITL to safe flash so on flight control hardware it has to be manually configured equivalently). + - [SIH plane AERT](../airframes/airframe_reference.md#plane_simulation_sih_plane_aert) + - [SIH Tailsitter Duo](../airframes/airframe_reference.md#vtol_simulation_sih_tailsitter_duo) + - [SIH Standard VTOL QuadPlane](../airframes/airframe_reference.md#vtol_simulation_sih_standard_vtol_quadplane) + - [SIH Ackermann Rover](../airframes/airframe_reference.md#rover_rover_sih_rover_ackermann) The autopilot will then reboot. The `sih` module is started on reboot, and the vehicle should be displayed on the ground control station map. @@ -172,19 +172,19 @@ To display the simulated vehicle: 3. Start jMAVSim by calling the script **jmavsim_run.sh** from a terminal: - ```sh - ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o - ``` + ```sh + ./Tools/simulation/jmavsim/jmavsim_run.sh -q -d /dev/ttyACM0 -b 2000000 -o + ``` - where the flags are: + where the flags are: - - `-q` to allow the communication to _QGroundControl_ (optional). - - `-d` to start the serial device `/dev/ttyACM0` on Linux. - On macOS this would be `/dev/tty.usbmodem1`. - - `-b` to set the serial baud rate to `2000000`. - - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). - - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. - If this flag is not present a quadrotor will be displayed by default. + - `-q` to allow the communication to _QGroundControl_ (optional). + - `-d` to start the serial device `/dev/ttyACM0` on Linux. + On macOS this would be `/dev/tty.usbmodem1`. + - `-b` to set the serial baud rate to `2000000`. + - `-o` to start jMAVSim in _display Only_ mode (i.e. the physical engine is turned off and jMAVSim only displays the trajectory given by the SIH in real-time). + - add a flag `-a` to display an aircraft or `-t` to display a tailsitter. + If this flag is not present a quadrotor will be displayed by default. 4. After few seconds, _QGroundControl_ can be opened again. @@ -201,41 +201,41 @@ To run SIH as SITL: 1. Install the [PX4 Development toolchain](../dev_setup/dev_env.md). 2. Run the appropriate make command for each vehicle type (at the root of the PX4-Autopilot repository): - - Quadcopter + - Quadcopter - ```sh - make px4_sitl sihsim_quadx - ``` + ```sh + make px4_sitl sihsim_quadx + ``` - - Hexacopter + - Hexacopter - ```sh - make px4_sitl sihsim_hex - ``` + ```sh + make px4_sitl sihsim_hex + ``` - - Fixed-wing (plane) + - Fixed-wing (plane) - ```sh - make px4_sitl sihsim_airplane - ``` + ```sh + make px4_sitl sihsim_airplane + ``` - - XVert VTOL tailsitter + - XVert VTOL tailsitter - ```sh - make px4_sitl sihsim_xvert - ``` + ```sh + make px4_sitl sihsim_xvert + ``` - - 标准垂起固定翼 + - 标准垂起固定翼 - ```sh - make px4_sitl sihsim_standard_vtol - ``` + ```sh + make px4_sitl sihsim_standard_vtol + ``` - - Ackermann Rover + - Ackermann Rover - ```sh - make px4_sitl sihsim_rover_ackermann - ``` + ```sh + make px4_sitl sihsim_rover_ackermann + ``` ### Change Simulation Speed @@ -328,6 +328,44 @@ For SIH as SITL (no FC): For specific examples see the `_sihsim_` airframes in [ROMFS/px4fmu_common/init.d-posix/airframes](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/airframes/) (SIH as SITL) and [ROMFS/px4fmu_common/init.d/airframes](https://github.com/PX4/PX4-Autopilot/tree/main/ROMFS/px4fmu_common/init.d/airframes) (SIH on FC). +## Controlling Actuators in SIH + +:::warning +If you want to control throttling actuators in SIH, make sure to remove propellers for safety. +::: + +In some scenarios, it may be useful to control an actuator while running SIH. For example, you might want to verify that winches or grippers are functioning correctly by checking the servo responses. + +To enable actuator control in SIH: + +1. Configure PWM parameters in the airframe file: + +Ensure your airframe file includes the necessary parameters to map PWM outputs to the correct channels. + +For example, if a servo is connected to MAIN 3 and you want to map it to AUX1 on your RC, use the following command: + +`param set-default PWM_MAIN_FUNC3 407` + +You can find a full list of available values for `PWM_MAIN_FUNCn` [here](../advanced_config/parameter_reference.md#PWM_MAIN_FUNC1). In this case, `407` maps the MAIN 3 output to AUX1 on the RC. + +Alternatively, you can use the [`PWM_AUX_FUNCn`](../advanced_config/parameter_reference.md#PWM_AUX_FUNC1) parameters. + +You may also configure the output as desired: + +- Disarmed PWM: ([`PWM_MAIN_DISn`](../advanced_config/parameter_reference.md#PWM_MAIN_DIS1) / [`PWM_AUX_DIS1`](../advanced_config/parameter_reference.md#PWM_AUX_DIS1)) +- Minimum PWM ([`PWM_MAIN_MINn`](../advanced_config/parameter_reference.md#PWM_MAIN_MIN1) / [`PWM_AUX_MINn`](../advanced_config/parameter_reference.md#PWM_AUX_MIN1)) +- Maximum PWM ([`PWM_MAIN_MAXn`](../advanced_config/parameter_reference.md#PWM_MAIN_MAX1) / [`PWM_AUX_MAXn`](../advanced_config/parameter_reference.md#PWM_AUX_MAX1)) + +2. Manually start the PWM output driver + +For safety, the PWM driver is not started automatically in SIH. To enable it, run the following command in the MAVLink shell: + +`pwm_out start` + +And to disable it again: + +`pwm_out stop` + ## Dynamic Models The dynamic models for the various vehicles are: diff --git a/docs/zh/simulation/index.md b/docs/zh/simulation/index.md index db8211d3cd..e5d3f03025 100644 --- a/docs/zh/simulation/index.md +++ b/docs/zh/simulation/index.md @@ -217,20 +217,20 @@ The simulated camera is a gazebo classic plugin that implements the [MAVLink Cam PX4 connects/integrates with this camera in _exactly the same way_ as it would with any other MAVLink camera: 1. [TRIG_INTERFACE](../advanced_config/parameter_reference.md#TRIG_INTERFACE) must be set to `3` to configure the camera trigger driver for use with a MAVLink camera - :::tip - In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. - For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). + :::tip + In this mode the driver just sends a [CAMERA_TRIGGER](https://mavlink.io/en/messages/common.html#CAMERA_TRIGGER) message whenever an image capture is requested. + For more information see [Cameras Connected to Flight Controller Outputs](../camera/fc_connected_camera.md). ::: 2. PX4 必须在 GCS 和(模拟器)MAVLink Camera 之间转发所有摄像机命令。 - You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. + You can do this by starting [MAVLink](../modules/modules_communication.md#mavlink) with the `-f` flag as shown, specifying the UDP ports for the new connection. - ```sh - mavlink start -u 14558 -o 14530 -r 4000 -f -m camera - ``` + ```sh + mavlink start -u 14558 -o 14530 -r 4000 -f -m camera + ``` - ::: info - More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. + ::: info + More than just the camera MAVLink messages will be forwarded, but the camera will ignore those that it doesn't consider relevant. ::: diff --git a/docs/zh/smart_batteries/rotoye_batmon.md b/docs/zh/smart_batteries/rotoye_batmon.md index ead3d454db..e12979457b 100644 --- a/docs/zh/smart_batteries/rotoye_batmon.md +++ b/docs/zh/smart_batteries/rotoye_batmon.md @@ -3,11 +3,6 @@ [Rotoye 电池监测器](https://rotoye.com/batmon/) 是一款套件,用于为现成的锂离子和锂聚合物电池增添智能电池功能。 It can be purchased as a standalone unit or as part of a factory-assembled smart-battery. -:::info -At time of writing you can only use Batmon by [building a custom branch of PX4](#build-px4-firmware). -Support in the codeline is pending [PR approval](https://github.com/PX4/PX4-Autopilot/pull/16723). -::: - ![Rotoye 电池监控板](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye.jpg) ![组装的罗托耶智能电池](../../assets/hardware/smart_batteries/rotoye_batmon/smart-battery-rotoye-pack.jpg) diff --git a/docs/zh/telemetry/crsf_telemetry.md b/docs/zh/telemetry/crsf_telemetry.md index 322d3ebbe9..cbb8abf219 100644 --- a/docs/zh/telemetry/crsf_telemetry.md +++ b/docs/zh/telemetry/crsf_telemetry.md @@ -77,36 +77,36 @@ To use this feature you must build and upload custom firmware that includes [crs 1. [Setup a development environment](../dev_setup/dev_env.md) for building PX4. - As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. + As part of this process you will have used `git` to fetch source code into the **PX4-Autopilot** directory. 2. Open a terminal and `cd` into the `PX4-Autopilot` directory. - ```sh - cd PX4-Autopilot - ``` + ```sh + cd PX4-Autopilot + ``` 3. Launch the [PX4 board config tool (`menuconfig`)](../hardware/porting_guide_config.md#px4-menuconfig-setup) for your `make` target using the `boardconfig` option (here the target is the [ARK Electronics ARKV6X](../flight_controller/ark_v6x.md) flight controller): - ```sh - make ark_fmu-v6x_default boardconfig - ``` + ```sh + make ark_fmu-v6x_default boardconfig + ``` 4. In the PX4 board config tool: - - Disable the default `rc_input` module - 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. - 2. Use the enter key to remove the `*` from `rc_input` checkbox. - - Enable the `crsf_rc` module - 1. Scroll to highlight the `RC` submenu, then press enter to open it. - 2. Scroll to highlight `crsf_rc` and press enter to enable it. + - Disable the default `rc_input` module + 1. Navigate to the `drivers` submenu, then scroll down to highlight `rc_input`. + 2. Use the enter key to remove the `*` from `rc_input` checkbox. + - Enable the `crsf_rc` module + 1. Scroll to highlight the `RC` submenu, then press enter to open it. + 2. Scroll to highlight `crsf_rc` and press enter to enable it. - Save and exit the PX4 board config tool. + Save and exit the PX4 board config tool. 5. [Build the PX4 source code](../dev_setup/building_px4.md) with your changes (again assuming you are using ARKV6X): - ```sh - make ark_fmu-v6x_default - ``` + ```sh + make ark_fmu-v6x_default + ``` This will build your custom firmware, which must now be uploaded to your flight controller. @@ -128,11 +128,11 @@ Alternatively you can use QGroundControl to install the firmware, as described i 1. [RC_CRSF_PRT_CFG](../advanced_config/parameter_reference.md#RC_CRSF_PRT_CFG) — Set to the port that is connected to the CRSF receiver (such as `TELEM1`). - This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. - Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. - For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. + This [configures the serial port](../peripherals/serial_configuration.md) to use the CRSF protocol. + Note that some serial ports may already have a [default serial port mapping](../peripherals/serial_configuration.md#default-serial-port-configuration) or [default MAVLink serial port mapping](../peripherals/mavlink_peripherals.md#default-mavlink-ports) that you will have to un-map before you can assign the port to CRSF. + For example, if you want to use `TELEM1` or `TELEM2` you first need to modify [MAV_0_CONFIG](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to stop setting those ports. - There is no need to set the baud rate for the port, as this is configured by the driver. + There is no need to set the baud rate for the port, as this is configured by the driver. 2. [RC_CRSF_TEL_EN](../advanced_config/parameter_reference.md#RC_CRSF_TEL_EN) — Enable to activate Crossfire telemetry. @@ -213,7 +213,7 @@ The supported telemetry messages and their source are listed below (this table i | FM | Flight mode | FC | | VSPD | Barometer | FC | -## See Also +## 另见 - [TBS Crossfire Manual](https://www.team-blacksheep.com/media/files/tbs-crossfire-manual.pdf) - [ExpressLRS Documentation](https://www.expresslrs.org/quick-start/getting-started/) diff --git a/docs/zh/telemetry/jfi_telemetry.md b/docs/zh/telemetry/jfi_telemetry.md index e7fc2526c3..b9387b536b 100644 --- a/docs/zh/telemetry/jfi_telemetry.md +++ b/docs/zh/telemetry/jfi_telemetry.md @@ -111,9 +111,9 @@ However if you change the baud rate from 57600 you will need to create and use a 1. Disable SiK Radio in QGC (**Application Settings → General → AutoConnect**). 2. Create a new link configuration: - - Go to **Application Settings → Comms Links**. - - Click **Add**. - - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. + - Go to **Application Settings → Comms Links**. + - Click **Add**. + - Set **Type** to **Serial**, configure the **Serial Port** and **Baud Rate** to match the J.Fi device. 3. Select **Connect** to connect with the new configuration. ## J.Fi Configuration diff --git a/docs/zh/telemetry/telemetry_wifi.md b/docs/zh/telemetry/telemetry_wifi.md index b1f435c36d..84d13ddd32 100644 --- a/docs/zh/telemetry/telemetry_wifi.md +++ b/docs/zh/telemetry/telemetry_wifi.md @@ -1,6 +1,6 @@ # WiFi 数传电台 -WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS.\ +WiFi telemetry enables MAVLink communication between a WiFi radio on a vehicle and a GCS. WiFi typically offers shorter range than a normal telemetry radio, but supports higher data rates, and makes it easier to support FPV/video feeds. Usually only a single radio unit for the vehicle is needed (assuming the ground station already has WiFi). diff --git a/docs/zh/test_and_ci/fuzz_tests.md b/docs/zh/test_and_ci/fuzz_tests.md index b087f5b21e..202d7e383d 100644 --- a/docs/zh/test_and_ci/fuzz_tests.md +++ b/docs/zh/test_and_ci/fuzz_tests.md @@ -15,14 +15,14 @@ To write a fuzz test: 1. Start by writing a "normal" [functional test](../test_and_ci/unit_tests.md#functional-test). 2. Make sure the file name contains `fuzz` (lower case). - For example `my_driver_fuzz_tests.cpp`. + For example `my_driver_fuzz_tests.cpp`. 3. Add one or more fuzz tests to the file. - 例如: + 例如: ```cpp #include #include - + void myDriverNeverCrashes(const std::string& s) { MyDriver driver; driver.handleInput(s); diff --git a/docs/zh/test_and_ci/index.md b/docs/zh/test_and_ci/index.md index 91ceadea53..6e7c94f8e3 100644 --- a/docs/zh/test_and_ci/index.md +++ b/docs/zh/test_and_ci/index.md @@ -9,8 +9,8 @@ Test topics include: - [Unit Tests](../test_and_ci/unit_tests.md) - [Continuous Integration (CI)](../test_and_ci/continous_integration.md) - [Integration Testing](../test_and_ci/integration_testing.md) - - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) - - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) - - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) + - [MAVSDK Integration Testing](../test_and_ci/integration_testing_mavsdk.md) + - [PX4 ROS2 Interface Library Integration Testing](../test_and_ci/integration_testing_px4_ros2_interface.md) + - [ROS 1 Integration Testing](../test_and_ci/integration_testing_ros1_mavros.md) (Deprecated) - [Docker](../test_and_ci/docker.md) - [Maintenance](../test_and_ci/maintenance.md) diff --git a/docs/zh/test_and_ci/integration_testing_px4_ros2_interface.md b/docs/zh/test_and_ci/integration_testing_px4_ros2_interface.md index 1c967e89f6..17d80ec588 100644 --- a/docs/zh/test_and_ci/integration_testing_px4_ros2_interface.md +++ b/docs/zh/test_and_ci/integration_testing_px4_ros2_interface.md @@ -2,11 +2,11 @@ This topic outlines the integration tests for the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). -These test that mode registration, failsafes, and mode replacement, work as expected. +这些测试用于验证模式注册、故障保护(failsafes)和模式替换功能是否按预期工作。 ## CI Testing -When opening a pull request to PX4, CI runs the library integration tests. +向 PX4 提交拉取请求(pull request)时,持续集成(CI)会运行该库的集成测试 ## Running Tests Locally diff --git a/docs/zh/test_and_ci/integration_testing_ros1_mavros.md b/docs/zh/test_and_ci/integration_testing_ros1_mavros.md index e2a21e6795..083deb2310 100644 --- a/docs/zh/test_and_ci/integration_testing_ros1_mavros.md +++ b/docs/zh/test_and_ci/integration_testing_ros1_mavros.md @@ -65,73 +65,73 @@ To write a new test: 1. Create a new test script by copying the empty test skeleton below: - ```python - #!/usr/bin/env python - # [... LICENSE ...] - - # - # @author Example Author - # - PKG = 'px4' - - import unittest - import rospy - import rosbag - - from sensor_msgs.msg import NavSatFix - - class MavrosNewTest(unittest.TestCase): - """ - Test description - """ - - def setUp(self): - rospy.init_node('test_node', anonymous=True) - rospy.wait_for_service('mavros/cmd/arming', 30) - - rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) - self.rate = rospy.Rate(10) # 10hz - self.has_global_pos = False - - def tearDown(self): - pass - - # - # General callback functions used in tests - # - def global_position_callback(self, data): - self.has_global_pos = True - - def test_method(self): - """Test method description""" - - # FIXME: hack to wait for simulation to be ready - while not self.has_global_pos: - self.rate.sleep() - - # TODO: execute test - - if __name__ == '__main__': - import rostest - rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) - ``` + ```python + #!/usr/bin/env python + # [... LICENSE ...] + + # + # @author Example Author + # + PKG = 'px4' + + import unittest + import rospy + import rosbag + + from sensor_msgs.msg import NavSatFix + + class MavrosNewTest(unittest.TestCase): + """ + Test description + """ + + def setUp(self): + rospy.init_node('test_node', anonymous=True) + rospy.wait_for_service('mavros/cmd/arming', 30) + + rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback) + self.rate = rospy.Rate(10) # 10hz + self.has_global_pos = False + + def tearDown(self): + pass + + # + # General callback functions used in tests + # + def global_position_callback(self, data): + self.has_global_pos = True + + def test_method(self): + """Test method description""" + + # FIXME: hack to wait for simulation to be ready + while not self.has_global_pos: + self.rate.sleep() + + # TODO: execute test + + if __name__ == '__main__': + import rostest + rostest.rosrun(PKG, 'mavros_new_test', MavrosNewTest) + ``` 2. Run the new test only - Start the simulator: - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - roslaunch launch/mavros_posix_sitl.launch - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + roslaunch launch/mavros_posix_sitl.launch + ``` - Run test (in a new shell): - ```sh - cd - source Tools/simulation/gazebo/setup_gazebo.bash - rosrun px4 mavros_new_test.py - ``` + ```sh + cd + source Tools/simulation/gazebo/setup_gazebo.bash + rosrun px4 mavros_new_test.py + ``` 3. Add new test node to a launch file - In `test/` create a new `.test` ROS launch file. @@ -145,9 +145,9 @@ To write a new test: 例如: - ```sh - tests_: rostest - @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test - ``` + ```sh + tests_: rostest + @"$(SRC_DIR)"/test/rostest_px4_run.sh mavros_posix_tests_.test + ``` Run the tests as described above. diff --git a/docs/zh/test_and_ci/test_flights.md b/docs/zh/test_and_ci/test_flights.md index abe1d95d7c..654ab39b1e 100644 --- a/docs/zh/test_and_ci/test_flights.md +++ b/docs/zh/test_and_ci/test_flights.md @@ -28,3 +28,7 @@ These are run by the test team as part of release testing, and for more signific - [MC_04 - Failsafe Testing](../test_cards/mc_04_failsafe_testing.md) - [MC_05 - Indoor Flight (Manual Modes)](../test_cards/mc_05_indoor_flight_manual_modes.md) - [MC_06 - Indoor Flight (Optical Flow)](../test_cards/mc_06_optical_flow.md) +- [MC_07 - Optical Flow Low Mount](../test_cards/mc_07_optical_flow_low_mount.md) +- [MC_08 - DSHOT ESC](../test_cards/mc_08_dshot.md) +- [MC_09 - VIO (Visual-Inertial Odometry)](../test_cards/mc_09_vio.md) +- [MC_10 - Optical Flow / GPS Mixed](../test_cards/mc_10_optical_flow_gps_mixed.md) diff --git a/docs/zh/test_and_ci/unit_tests.md b/docs/zh/test_and_ci/unit_tests.md index f8cbf9747c..0a3039a8f9 100644 --- a/docs/zh/test_and_ci/unit_tests.md +++ b/docs/zh/test_and_ci/unit_tests.md @@ -126,34 +126,34 @@ It can be run directly in a debugger, however be careful to only run one test pe 10. Within [tests_main.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.h) define the new test: - ```cpp - extern int test_[description](int argc, char *argv[]); - ``` + ```cpp + extern int test_[description](int argc, char *argv[]); + ``` 11. Within [tests_main.c](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/tests_main.c) add description name, test function and option: - ```cpp - ... - } tests[] = { - {... - {"[description]", test_[description], OPTION}, - ... - } - ``` + ```cpp + ... + } tests[] = { + {... + {"[description]", test_[description], OPTION}, + ... + } + ``` - `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: + `OPTION` can be `OPT_NOALLTEST`,`OPT_NOJIGTEST` or `0` and is considered if within px4 shell one of the two commands are called: - ```sh - pxh> tests all - ``` + ```sh + pxh> tests all + ``` - 或 + 或 - ```sh - pxh> tests jig - ``` + ```sh + pxh> tests jig + ``` - If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. + If a test has option `OPT_NOALLTEST`, then that test will be excluded when calling `tests all`. The same is true for `OPT_NOJITEST` when command `test jig` is called. Option `0` means that the test is never excluded, which is what most developer want to use. 12. Add the test `test_[description].cpp` to the [CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/systemcmds/tests/CMakeLists.txt). diff --git a/docs/zh/test_cards/mc_04_failsafe_testing.md b/docs/zh/test_cards/mc_04_failsafe_testing.md index bca8c73323..630b537e83 100644 --- a/docs/zh/test_cards/mc_04_failsafe_testing.md +++ b/docs/zh/test_cards/mc_04_failsafe_testing.md @@ -9,10 +9,10 @@ Test RC loss, data link loss, and low battery failsafes. - Verify RC Loss action is Return to Land - Verify Data Link Loss action is Return to Land and the timeout is 10 seconds - Verify Battery failsafe - - Action is Return to Land - - Battery Warn Level is 25% - - Battery Failsafe Level is 20% - - Battery Emergency Level is 15% + - Action is Return to Land + - Battery Warn Level is 25% + - Battery Failsafe Level is 20% + - Battery Emergency Level is 15% ## Flight Tests diff --git a/docs/zh/test_cards/mc_06_optical_flow.md b/docs/zh/test_cards/mc_06_optical_flow.md index 037881f4b0..a5c415366c 100644 --- a/docs/zh/test_cards/mc_06_optical_flow.md +++ b/docs/zh/test_cards/mc_06_optical_flow.md @@ -2,17 +2,23 @@ ## Objective -To test that optical flow / external vision work as expected +Test that optical flow works as expected ## Preflight -Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation ([setup information here](../sensor/optical_flow.md)) -Ensure that the drone can go into Altitude / Position flight mode while still on the ground +Ensure there are no other sources of positioning besides optical flow: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into Altitude / Position mode while still on the ground ## Flight Tests -❏ Altitude flight mode +❏ [Altitude mode](../flight_modes_mc/altitude.md)     ❏ Vertical position should hold current value with stick centered @@ -20,7 +26,7 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Throttle response set to climb/descent rate -❏ Position flight mode +❏ [Position mode](../flight_modes_mc/position.md)     ❏ Horizontal position should hold current value with stick centered @@ -30,6 +36,16 @@ Ensure that the drone can go into Altitude / Position flight mode while still on     ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates +❏ Varying height terrain + +    ❏ Put boxes on the ground to create varying heights in terrain + +    ❏ Take off in position mode and fly over the boxes such that the downward facing rangefinder varies in value + +    ❏ Do a few passes with varying amounts of time over the boxes (1-30 seconds if possible) + +    ❏ Drone should not raise in height when flying over boxes + ## 降落 ❏ Land in either Position or Altitude mode with the throttle below 40% @@ -39,5 +55,8 @@ Ensure that the drone can go into Altitude / Position flight mode while still on ## 预期成果 - 当油门升高时,起飞应该是平稳的 +- Drone should hold altitude in Altitude mode without wandering (over surface with many features) +- Drone should hold position within 1 meter in Position mode without pilot moving sticks - 在上述任何飞行模式中都不应出现振荡 +- Drone should not raise in height when flying over boxes - 着陆时,直升机不应在地面上反弹 diff --git a/docs/zh/test_cards/mc_07_optical_flow_low_mount.md b/docs/zh/test_cards/mc_07_optical_flow_low_mount.md new file mode 100644 index 0000000000..d6458d7adc --- /dev/null +++ b/docs/zh/test_cards/mc_07_optical_flow_low_mount.md @@ -0,0 +1,45 @@ +# Test MC_07 - Optical Flow Low Sensor + +## Objective + +Test that optical flow works as expected with a low mounted optical flow sensor + +## Preflight + +Ensure that the drone's optical flow sensor is mounted more than an inch off of the ground + +Ensure that [MPC_THR_MIN](../advanced_config/parameter_reference.md#MPC_THR_MIN) is tuned correctly for landing + +Disconnect all GPS / compasses and ensure vehicle is using optical flow for navigation +([Setup Information here](../sensor/optical_flow.md)) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` + +Ensure that the drone can go into [Position mode](../flight_modes_mc/position.md) while still on the ground + +## Flight Tests + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 降落 + +❏ Land in Position mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 预期成果 + +- 当油门升高时,起飞应该是平稳的 +- Drone should stay in Position mode, NOT fall into [altitude](../flight_modes_mc/altitude.md) mode diff --git a/docs/en/test_cards/mc_07_vio.md b/docs/zh/test_cards/mc_07_vio.md similarity index 89% rename from docs/en/test_cards/mc_07_vio.md rename to docs/zh/test_cards/mc_07_vio.md index 24743eaf7e..0972a15540 100644 --- a/docs/en/test_cards/mc_07_vio.md +++ b/docs/zh/test_cards/mc_07_vio.md @@ -37,16 +37,16 @@ Ensure there are no other sources of positioning besides VIO:     ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates -## Landing +## 降落 ❏ Land in either Position or Altitude mode with the throttle below 40% ❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) -## Expected Results +## 预期成果 -- Take-off should be smooth as throttle is raised +- 当油门升高时,起飞应该是平稳的 - Drone should hold altitude in Altitude Flight mode without wandering - Drone should hold position within 1 meter in Position Flight mode without pilot moving sticks -- No oscillations should present in any of the above flight modes -- Upon landing, copter should not bounce on the ground +- 在上述任何飞行模式中都不应出现振荡 +- 着陆时,直升机不应在地面上反弹 diff --git a/docs/zh/test_cards/mc_08_dshot.md b/docs/zh/test_cards/mc_08_dshot.md new file mode 100644 index 0000000000..ca740ca877 --- /dev/null +++ b/docs/zh/test_cards/mc_08_dshot.md @@ -0,0 +1,46 @@ +# Test MC_08 - DSHOT ESC + +## Objective + +Regression test for DSHOT working with PX4 + +## Preflight + +- Ensure vehicle is using a DSHOT ESC +- Parameter [DSHOT_BIDIR_EN](../advanced_config/parameter_reference.md#DSHOT_BIDIR_EN) is enabled +- Parameter [DSHOT_TEL_CFG](../advanced_config/parameter_reference.md#DSHOT_TEL_CFG) is configured (if ESC supports telemetry) +- Parameter [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) has Debug (`5`) checked + +## Flight Tests + +❏ [Stabilized mode](../flight_modes_mc/manual_stabilized.md) + +    ❏ Takeoff in stabilized mode to ensure correct motor spin + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response 1:1 + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 降落 + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 预期成果 + +- Download flight logs +- Load into Data Plot Juggler +- Ensure data is logged for `esc_status`/`esc.0x`/`esc_rpm` + + ![Reference frames](../../assets/test_cards/dshot_log_output.png) diff --git a/docs/zh/test_cards/mc_09_vio.md b/docs/zh/test_cards/mc_09_vio.md new file mode 100644 index 0000000000..a1438f8967 --- /dev/null +++ b/docs/zh/test_cards/mc_09_vio.md @@ -0,0 +1,52 @@ +# Test MC_09 - VIO (Visual-Inertial Odometry) + +## Objective + +Test that external vision (VIO) works as expected + +## Preflight + +Disconnect all GPS / compasses and ensure vehicle is using VIO for navigation + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +Ensure there are no other sources of positioning besides VIO: + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `0` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `0` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `15` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `0` + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +## 降落 + +❏ Land in either Position or Altitude mode with the throttle below 40% + +❏ Upon touching ground, copter should disarm automatically within 2 seconds (default: see [COM_DISARM_LAND](../advanced_config/parameter_reference.md#COM_DISARM_LAND)) + +## 预期成果 + +- 当油门升高时,起飞应该是平稳的 +- Drone should hold altitude in Altitude mode without wandering +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- 在上述任何飞行模式中都不应出现振荡 +- 着陆时,直升机不应在地面上反弹 diff --git a/docs/zh/test_cards/mc_10_optical_flow_gps_mixed.md b/docs/zh/test_cards/mc_10_optical_flow_gps_mixed.md new file mode 100644 index 0000000000..61097c8568 --- /dev/null +++ b/docs/zh/test_cards/mc_10_optical_flow_gps_mixed.md @@ -0,0 +1,74 @@ +# Test MC_10 - Optical Flow / GPS Mixed + +## Objective + +Test that optical flow mixed with GPS works as expected + +## Preflight + +[Setup optical flow and GPS](../sensor/optical_flow.md) + +Ensure there are no other sources of positioning besides optical flow + +- [EKF2_OF_CTRL](../advanced_config/parameter_reference.md#EKF2_OF_CTRL): `1` +- [EKF2_GPS_CTRL](../advanced_config/parameter_reference.md#EKF2_GPS_CTRL): `7` +- [EKF2_EV_CTRL](../advanced_config/parameter_reference.md#EKF2_EV_CTRL): `0` +- [SYS_HAS_MAG](../advanced_config/parameter_reference.md#SYS_HAS_MAG): `1` +- [EKF2_HGT_REF](../advanced_config/parameter_reference.md#EKF2_HGT_REF): `1` (GPS) + +Ensure that the drone can go into [Altitude](../flight_modes_mc/altitude.md) / [Position](../flight_modes_mc/position.md) mode while still on the ground + +## Flight Tests + +❏ [Altitude mode](../flight_modes_mc/altitude.md) + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Pitch/Roll/Yaw response 1:1 + +    ❏ Throttle response set to climb/descent rate + +❏ [Position mode](../flight_modes_mc/position.md) + +    ❏ Horizontal position should hold current value with stick centered + +    ❏ Vertical position should hold current value with stick centered + +    ❏ Throttle response set to climb/descent rate + +    ❏ Pitch/Roll/Yaw response set to pitch/roll/yaw rates + +❏ GPS Cutout + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Open QGC and navigate to MAVLink Console + +    ❏ Type `gps off` to disable GPS + +    ❏ Drone should maintain position hold via optical flow + +❏ GPS Degredation + +    ❏ Takeoff in position mode in GPS rich environment (outdoors) + +    ❏ Fly under a metal surface (or other GPS blocking structure) + +    ❏ Ensure drone does not lose position hold or start drifting + +    ❏ Fly out of metal structure to regain GPS + +❏ GPS Acquisition + +    ❏ Takeoff in position mode in non-GPS environment + +    ❏ Fly into a GPS rich environment (outdoors) + +    ❏ Ensure drone acquires GPS position + +## 预期成果 + +- 当油门升高时,起飞应该是平稳的 +- Drone should hold position within 1 meter in Position mode without pilot moving sticks +- Drone should hold position in GPS rich environment as well as non-GPS environment +- 在上述任何飞行模式中都不应出现振荡 diff --git a/docs/zh/uart/user_configurable_serial_driver.md b/docs/zh/uart/user_configurable_serial_driver.md index 08ff1d6363..948fee14c5 100644 --- a/docs/zh/uart/user_configurable_serial_driver.md +++ b/docs/zh/uart/user_configurable_serial_driver.md @@ -26,33 +26,33 @@ 1. Create a YAML module configuration file: - - Add a new file in the driver's source directory named **module.yaml** - - Insert the following text and adjust as needed: + - Add a new file in the driver's source directory named **module.yaml** + - Insert the following text and adjust as needed: - ```cmake - module_name: uLanding Radar - serial_config: - - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} - port_config_param: - name: SENS_ULAND_CFG - group: Sensors - ``` + ```cmake + module_name: uLanding Radar + serial_config: + - command: ulanding_radar start -d ${SERIAL_DEV} -b p:${BAUD_PARAM} + port_config_param: + name: SENS_ULAND_CFG + group: Sensors + ``` - ::: info - The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. - This is also used to validate all configuration files in CI. + ::: info + The full documentation of the module configuration file can be found in the [validation/module_schema.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/validation/module_schema.yaml) file. + This is also used to validate all configuration files in CI. ::: 2. Add the module configuration to the **CMakeLists.txt** file for the driver module: - ```cmake - px4_add_module( - MODULE drivers__ulanding - MAIN ulanding_radar - SRCS - ulanding.cpp - MODULE_CONFIG - module.yaml - ) - ``` + ```cmake + px4_add_module( + MODULE drivers__ulanding + MAIN ulanding_radar + SRCS + ulanding.cpp + MODULE_CONFIG + module.yaml + ) + ``` diff --git a/docs/zh/uorb/uorb_documentation.md b/docs/zh/uorb/uorb_documentation.md new file mode 100644 index 0000000000..300c195449 --- /dev/null +++ b/docs/zh/uorb/uorb_documentation.md @@ -0,0 +1,170 @@ +# uORB Documentation Standard + +This topic demonstrates and explains how to document uORB messages. + +:::info +At time of writing many topics have not been updated. +::: + +## 综述 + +The [AirspeedValidated](../msg_docs/AirspeedValidated.md) message shown below is a good example of a uORB topic that has been documented to the current standard. + +```py +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + +uint32 MESSAGE_VERSION = 1 + +uint64 timestamp # [us] Time since system start + +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) + +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed + +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch +``` + +The main things to note are: + +- Documentation is added using formatted uORB comments. + Any text on a line after the `#` character is a comment, except for lines that start with the text `# TOPIC` (which indicates a multi-topic message). +- The message starts with a comment block consisting of short description (mandatory), followed by a longer description and then a space. +- Field and constants almost all have comments. + The comments are added on the same line as the field/constant, separated by one space. +- Fields: + - Comments are all on the same line as the field (extra lines become internal comments). + - Comments start with metadata, such as the units (`[m/s]`, `[rad/s]`) or allowed values (`[@enum SOURCE]`), and can also list invalid values (`[@invalid NaN]`) and allowed ranges (`[@range min, max]`). + - Units are required except for boolean fields or for fields with an enum value. + `[-]` is used to indicate unitless fields. + - Comments follow the metadata after a space. + The line should not be terminated in a full stop. +- Constants: + - Don't have metadata: the description follows the comment marker after one space. + - Some constants, such as `MESSAGE_VERSION`, don't need documentation because they are standardized. + - Constants with the same name prefix are grouped together as enums after the associated field. + +The following sections expand on the allowed formats. + +## Message Description + +Every message should start with a comment block that describes the message: + +```py +# Short description (mandatory) +# +# Longer description for the message if needed. +# Can be multiline, and should have punctuation. +# Should be followed by an empty line. +``` + +This consists of a mandatory short description, optionally followed by an empty comment line, and then a longer description. + +Short description (mandatory): + +- A succinct explanation for the purpose of the message. +- Usually just one line without a terminating full stop. +- Minimally it may just mirror the message name. +- For example, [`AirspeedValidated`](../msg_docs/AirspeedValidated.md) above has the short description `Validated airspeed`. + +Long description (Optional): + +- Additional context required to understand how the message is used. +- In particular this should be anything that can't be inferred from the name, fields or constants, such as the publishers and expected consumers. + It might also cover whether the message is only used for a particular frame type or mode. +- The message is often multiline and contains punctuation. +- May include comment lines that are empty, in order to indicate paragraphs. + +Both short and long descriptions may be multi-line. +Single line descriptions should not include a terminating full stop, but multiline comments should do so. + +The message description block ends at the first non-comment line, which should be an empty line, but might be a field or constant. +Any subsequent comment lines are considered "internal comments". + +### Fields + +A typical field comment looks like this: + +```py +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +``` + +Field comments must all be on the same line as the field, and consist of optional metadata followed by a description: + +- `metadata` (Optional) + - Information about the field units and allowed values: + - `[]` + - The unit of measurement inside square brackets (note, no `@` delineator indicates a unit), such as `[m]` for metres. + - Allowed units include: `m`, `m/s`, `m/s^2`, `rad`, `rad/s`, `rpm`, `V`, `A`, `mA`, `mAh`, `W`, `dBm`, `s`, `ms`, `us`, `Ohm`, `MB`, `Kb/s`, `degC`, `Pa`. + - Units are required unless clearly invalid, such as when the field is a boolean, or is an enum value. + - Unitless values should be specified as `[-]`. + Note though that units are not required for boolean fields or enum fields. + - `[@enum ]` + - The `enum_name` gives the prefix of constant values in the message that can be assigned to the field. + Note that enums in uORB are just a naming convention: they are not explicitly declared. + Multiple enum names allowed for a field indicates a possible error in the field design. + - `[@range , ]` + - The allowed range of the field, specified as a `lower_value` and/or an `upper_value`. + Either value can be omitted to indicate an unbounded upper or lower value. + For example `[@range 0, 3]`, `[@range 5.3, ]`, `[@range , 3]`. + - `[@invalid ]` + - The `value` to set the field to indicate that the field doesn't contain valid data, such as `[@invalid NaN]`. + The `description` is optional, and might be used to indicate the conditions under which data is invalid. + - `[@frame ]` + - The `frame` in which the field is set, such as `[@frame NED]` or `[@frame Body]`. +- `description` + - A concise description of the purpose of the field, and including any important information that can't be inferred from the name! + Use a capital first letter, and omit the full stop if the description is a single sentence. + Multiple sentences may also omit the final full stop. + +### Constants + +Constants follow the documentation conventions as fields except they only have a description (no metadata). +Documentation for a constant might look like this: + +```py +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +``` + +Constants are often grouped together following a field as enum values. +Note below how the prefix `SOURCE` for the values is specified as an enum against the _field_. + +```py +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +... +``` + +A small number of constants have a standardised meaning and do not require documentation. +These are: + +- `ORB_QUEUE_LENGTH` +- `MESSAGE_VERSION` + +### `# TOPICS` + +The prefix `# TOPICS` is used to indicate topic names for multi-topic messages. +For example, the [VehicleGlobalPosition.msg](../msg_docs/VehicleGlobalPosition.md) message definition is used to define the topic ids as shown: + +```text +# TOPICS vehicle_global_position vehicle_global_position_groundtruth external_ins_global_position +# TOPICS estimator_global_position +# TOPICS aux_global_position +``` + +At time of writing there is no format for documenting these. diff --git a/docs/zh/vtx/index.md b/docs/zh/vtx/index.md new file mode 100644 index 0000000000..b39ad4c57b --- /dev/null +++ b/docs/zh/vtx/index.md @@ -0,0 +1,287 @@ +# Analog Video Transmitters + +Analog Video Transmitters (VTX) can be controlled by PX4 via a half-duplex UART connection implementing the SmartAudio v1, v2, and v2.1 and Tramp protocols. + +The protocols allow writing and reading: + +- device status. +- transmission frequency in MHz or via band and channel index. +- transmission power in dBm or mW. +- operation modes. + +VTX settings are controlled by parameters and optionally via RC AUX channels or CRSF MSP commands. +The driver stores frequency and power tables that map band/channel indices to actual transmission values. +Configuration is device-specific and set up using the command line interface. + +## 入门指南 + +Connect the SmartAudio or Tramp pin of the VTX to the TX pin of a free serial port on the flight controller. +Then set the following parameters: + +- `VTX_SER_CFG`: Select the serial port used for VTX communication. +- `VTX_DEVICE`: Selects the VTX device (generic SmartAudio/Tramp or a specific device). + +Note that since the VTX communication is half-duplex, you can, for example, use the single-pin Radio Controller port for the VTX and use a full duplex TELEM port for CRSF communication. + +You should now be able to see the VTX device in the driver status: + +``` +nsh> vtx status +INFO [vtx] UART device: /dev/ttyS4 +INFO [vtx] VTX table "UNINITIALIZED": +INFO [vtx] Power levels: +INFO [vtx] RC mapping: Disabled +INFO [vtx] Parameters: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 0 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 = 0 mW +INFO [vtx] pit mode: off +INFO [vtx] SmartAudio v2: +INFO [vtx] band: 1 +INFO [vtx] channel: 1 +INFO [vtx] frequency: 6110 MHz +INFO [vtx] power level: 1 +INFO [vtx] power: 0 mW +INFO [vtx] pit mode: on +INFO [vtx] lock: unlocked +``` + +:::warning +Without a configured power table, power mappings are unknown and default to 0 mW. +Some VTX devices enter pit mode when power is set to 0, regardless of the `VTX_PIT_MODE` parameter. +::: + +## VTX Table Configuration + +The VTX table stores frequency and power mappings for your specific device. + +The manufacturer usually provides this information in the form of a JSON file that can be translated into a [Betaflight CLI command set](https://www.betaflight.com/docs/development/VTX#vtx-table) that this driver implements for compatibility. + +### Power Level Configuration + +``` +# Set table name ≤16 characters +vtxtable name "Peak THOR T67" + +# Set the power values that are sent to the VTX for each power level index +# Note: SmartAudio v1 and v2 use index values! +vtxtable powervalues 0 1 2 3 4 +# Note: SmartAudio v2.1 uses dBm values instead! +# vtxtable powervalues 14 23 27 30 35 +# Note: Tramp uses mW values instead! +# vtxtable powervalues 25 200 500 1000 3000 + +# Set the corresponding power labels for each power level index ≤4 characters. +# These are used for status reporting. +vtxtable powerlabels 25 200 500 1W 3W + +# Set number of power levels +vtxtable powerlevels 5 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 5 power levels. + +```nsh> vtxtable status +INFO [vtxtable] VTX table "Peak THOR T67": +INFO [vtxtable] Power levels: +INFO [vtxtable] 1: 0 = 25 +INFO [vtxtable] 2: 1 = 200 +INFO [vtxtable] 3: 2 = 500 +INFO [vtxtable] 4: 3 = 1W +INFO [vtxtable] 5: 4 = 3W +``` + +### Frequency Table Configuration + +``` +# Set the name of each band and the frequencies of each channel +vtxtable band 1 BAND_A A FACTORY 6110 6130 6150 6170 6190 6210 6230 6250 +vtxtable band 2 BAND_B B FACTORY 6270 6290 6310 6330 6350 6370 6390 6410 +vtxtable band 3 BAND_E E FACTORY 6430 6450 6470 6490 6510 6530 6550 6570 +vtxtable band 4 BAND_F F FACTORY 6590 6610 6630 6650 6670 6690 6710 6730 +vtxtable band 5 BAND_R R FACTORY 6750 6770 6790 6810 6830 6850 6870 6890 +vtxtable band 6 BAND_P P FACTORY 6910 6930 6950 6970 6990 7010 7030 7050 +vtxtable band 7 BAND_H H FACTORY 7070 7090 7110 7130 7150 7170 7190 7210 +vtxtable band 8 BAND_U U FACTORY 6115 6265 6425 6585 6745 6905 7065 7185 + +# Set number of bands and channels +vtxtable bands 8 +vtxtable channels 8 + +# Save configuration +vtxtable save +``` + +This will create a VTX table with 8 bands and 8 channels. +Note that FACTORY sends the band and channel indexes to the VTX device and they use their internal frequency mapping. In this mode the frequency is just for indication purposes. +In contrast, CUSTOM would send the actual frequency values to the VTX device, but not all devices support this mode. +Setting a frequency to zero will skip setting it. + +``` +nsh> vtxtable status +INFO [vtxtable] VTX table 8x8: Peak THOR T67 +INFO [vtxtable] A: BAND_A = 6110 6130 6150 6170 6190 6210 6230 6250 +INFO [vtxtable] B: BAND_B = 6270 6290 6310 6330 6350 6370 6390 6410 +INFO [vtxtable] E: BAND_E = 6430 6450 6470 6490 6510 6530 6550 6570 +INFO [vtxtable] F: BAND_F = 6590 6610 6630 6650 6670 6690 6710 6730 +INFO [vtxtable] R: BAND_R = 6750 6770 6790 6810 6830 6850 6870 6890 +INFO [vtxtable] P: BAND_P = 6910 6930 6950 6970 6990 7010 7030 7050 +INFO [vtxtable] H: BAND_H = 7070 7090 7110 7130 7150 7170 7190 7210 +INFO [vtxtable] U: BAND_U = 6115 6265 6425 6585 6745 6905 7065 7185 +``` + +### Table Constraints + +Maximum table dimensions: + +- ≤24 bands each with ≤16 channels and ≤32GHz frequency values. +- ≤16 power levels. +- ≤16 characters table name. +- ≤12 characters band name and 1 character band letter. +- ≤4 characters power label length (to support "2.5W"). + +## AUX Channel Mapping + +The AUX mapping feature allows you to control VTX settings using RC AUX channels. +Each mapping entry defines an AUX channel range that triggers a specific VTX configuration. + +To enable AUX mapping, set `VTX_MAP_CONFIG` to one of the following values: + +- `0`: Disabled +- `1`: Disabled (reserved for CRSF MSP integration) +- `2`: Map AUX channels to power level control only +- `3`: Map AUX channels to band and channel control only +- `4`: Map AUX channels to all settings (power, band, and channel) + +### Configuring AUX Map Entries + +Use the following command format to add mapping entries: + +``` +vtxtable +``` + +Parameters: + +- `index`: Map entry index (0-159) +- `aux_channel`: AUX channel number (3-19, where AUX1=3) +- `band`: Target band (1-24, or 0 to leave unchanged) +- `channel`: Target channel (1-16, or 0 to leave unchanged) +- `power`: Power level (1-16, 0 to leave unchanged, or -1 for pit mode) +- `start_pwm`: Start of PWM range in microseconds (typically 900-2100) +- `end_pwm`: End of PWM range in microseconds (typically 900-2100) + +:::info +AUX channel numbering starts from 3 (AUX1=channel 3) to account for the first four RC channels 0-3 used for flight control. +::: + +Example configuration for a 6-position dial controlling band/channel on AUX4 (channel 7): + +``` +vtx 0 7 7 1 0 900 1025 +vtx 1 7 7 2 0 1025 1100 +vtx 2 7 7 4 0 1100 1175 +vtx 3 7 7 6 0 1175 1225 +vtx 4 7 7 8 0 1225 1300 +vtx 5 7 3 8 0 1300 2100 +``` + +Example configuration for power control on AUX3 (channel 6): + +``` +vtxtable 16 6 0 0 -1 900 1250 +vtxtable 17 6 0 0 1 1250 1525 +vtxtable 18 6 0 0 2 1525 1650 +vtxtable 19 6 0 0 3 1650 1875 +vtxtable 20 6 0 0 4 1875 2010 +``` + +Save the configuration with: + +``` +vtxtable save +``` + +The map status can be verified with `vtxtable status`. + +## CRSF MSP Integration + +When using a CRSF receiver with MSP support, you can control VTX settings directly from your transmitter using MSP commands sent over the CRSF link. +This feature must be enabled at compile time with the `VTX_CRSF_MSP_SUPPORT` Kconfig option. + +To enable CRSF MSP control, set `VTX_MAP_CONFIG` to one of: + +- `1`: MSP controls both frequency (band/channel) and power +- `2`: MSP controls frequency (band/channel) only, AUX controls power +- `3`: MSP controls power only, AUX controls band/channel + +When MSP integration is active, the driver responds to `MSP_SET_VTX_CONFIG` (0x59) commands. +The transmitter can send band, channel, frequency, power level, and pit mode settings via MSP, which are automatically mapped to the corresponding PX4 parameters. + +:::tip +The MSP integration allows seamless VTX control from transmitters that support VTX configuration via Lua scripts or built-in VTX menus without requiring additional hardware switches. +::: + +## Build Configuration + +Both the VTX driver and VTX table support are configured via Kconfig options. + +Key configuration options: + +- `VTX_CRSF_MSP_SUPPORT`: Enables CRSF MSP command support (default: disabled) +- `VTXTABLE_CONFIG_FILE`: File path for persistent configuration (default: `/fs/microsd/vtx_config`) +- `VTXTABLE_AUX_MAP`: Enables AUX channel mapping (default: disabled) + +## Parameter Reference + +### VTX Settings Parameters + +- `VTX_BAND` (0-23): Frequency band selection (Band 1-24 in UI) +- `VTX_CHANNEL` (0-15): Channel within band (Channel 1-16 in UI) +- `VTX_FREQUENCY` (0-32000): Direct frequency in MHz (overrides band/channel when non-zero) +- `VTX_POWER` (0-15): Power level (Level 1-16 in UI, as configured in table) +- `VTX_PIT_MODE` (boolean): Pit mode for reduced power (default: disabled) + +### Configuration Parameters + +- `VTX_SER_CFG`: Serial port assignment for VTX communication +- `VTX_MAP_CONFIG`: Controls how VTX settings are mapped: + - Without `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: Disabled + - `2`: AUX controls power only + - `3`: AUX controls band/channel only + - `4`: AUX controls both power and band/channel + - With `VTX_CRSF_MSP_SUPPORT`: + - `0`: Disabled + - `1`: MSP controls both frequency and power + - `2`: MSP controls frequency, AUX controls power + - `3`: MSP controls power, AUX controls band/channel + - `4`: Not used with MSP support +- `VTX_DEVICE`: Device-specific configuration (see below) + +## Device-Specific Configuration + +The `VTX_DEVICE` parameter allows device-specific workarounds. +It encodes both the protocol type and device variant: + +- Low byte (bits 0-7): Protocol selection + - `0`: SmartAudio (default) + - `1`: Tramp +- High byte (bits 8-15): Device-specific variant + - `0`: Generic device + - `20`: Peak THOR T67 + - `40`: Rush Max Solo + +### Known Device Workarounds + +**Peak THOR T67** (`VTX_DEVICE` = 5120): +This device incorrectly reports pit mode status but otherwise functions normally. +The driver applies a workaround to override the reported status with the actual configured state. + +For generic devices, use `VTX_DEVICE` = 0 (SmartAudio) or `VTX_DEVICE` = 1 (Tramp). diff --git a/msg/AdcReport.msg b/msg/AdcReport.msg index 1ae72b6d6c..4a56bc2875 100644 --- a/msg/AdcReport.msg +++ b/msg/AdcReport.msg @@ -1,6 +1,10 @@ -uint64 timestamp # time since system start (microseconds) -uint32 device_id # unique device ID for the sensor that does not change between power cycles -int16[12] channel_id # ADC channel IDs, negative for non-existent, TODO: should be kept same as array index -int32[12] raw_data # ADC channel raw value, accept negative value, valid if channel ID is positive -uint32 resolution # ADC channel resolution -float32 v_ref # ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) +# ADC raw data. +# +# Communicates raw data from an analog-to-digital converter (ADC) to other modules, such as battery status. + +uint64 timestamp # [us] Time since system start +uint32 device_id # [-] unique device ID for the sensor that does not change between power cycles +int16[16] channel_id # [-] ADC channel IDs, negative for non-existent, TODO: should be kept same as array index +int32[16] raw_data # [-] ADC channel raw value, accept negative value, valid if channel ID is positive +uint32 resolution # [-] ADC channel resolution +float32 v_ref # [V] ADC channel voltage reference, use to calculate LSB voltage(lsb=scale/resolution) diff --git a/msg/AutotuneAttitudeControlStatus.msg b/msg/AutotuneAttitudeControlStatus.msg index 021a8c345b..63cc07d576 100644 --- a/msg/AutotuneAttitudeControlStatus.msg +++ b/msg/AutotuneAttitudeControlStatus.msg @@ -1,35 +1,45 @@ -uint64 timestamp # time since system start (microseconds) +# Autotune attitude control status +# +# This message is published by the fw_autotune_attitude_control and mc_autotune_attitude_control modules when the user engages autotune, +# and is subscribed to by the respective attitude controllers to command rate setpoints. +# +# The rate_sp field is consumed by the controllers, while the remaining fields (model coefficients, gains, filters, and autotune state) are used for logging and debugging. -float32[5] coeff # coefficients of the identified discrete-time model -float32[5] coeff_var # coefficients' variance of the identified discrete-time model -float32 fitness # fitness of the parameter estimate -float32 innov -float32 dt_model +uint64 timestamp # [us] Time since system start -float32 kc -float32 ki -float32 kd -float32 kff -float32 att_p +float32[5] coeff # [-] Coefficients of the identified discrete-time model +float32[5] coeff_var # [-] Coefficients' variance of the identified discrete-time model +float32 fitness # [-] Fitness of the parameter estimate +float32 innov # [rad/s] Innovation (residual error between model and measured output) +float32 dt_model # [s] Model sample time used for identification -float32[3] rate_sp -float32 u_filt -float32 y_filt +float32 kc # [-] Proportional rate-loop gain (ideal form) +float32 ki # [-] Integral rate-loop gain (ideal form) +float32 kd # [-] Derivative rate-loop gain (ideal form) +float32 kff # [-] Feedforward rate-loop gain +float32 att_p # [-] Proportional attitude gain -uint8 STATE_IDLE = 0 -uint8 STATE_INIT = 1 -uint8 STATE_ROLL = 2 -uint8 STATE_ROLL_PAUSE = 3 -uint8 STATE_PITCH = 4 -uint8 STATE_PITCH_PAUSE = 5 -uint8 STATE_YAW = 6 -uint8 STATE_YAW_PAUSE = 7 -uint8 STATE_VERIFICATION = 8 -uint8 STATE_APPLY = 9 -uint8 STATE_TEST = 10 -uint8 STATE_COMPLETE = 11 -uint8 STATE_FAIL = 12 -uint8 STATE_WAIT_FOR_DISARM = 13 +float32[3] rate_sp # [rad/s] Rate setpoint commanded to the attitude controller. -uint8 state +float32 u_filt # [-] Filtered input signal (normalized torque setpoint) used in system identification. +float32 y_filt # [rad/s] Filtered output signal (angular velocity) used in system identification. + +uint8 state # [@enum STATE] Current state of the autotune procedure. +uint8 STATE_IDLE = 0 # Idle (not running) +uint8 STATE_INIT = 1 # Initialize filters and setup +uint8 STATE_ROLL_AMPLITUDE_DETECTION = 2 # FW only: determine required excitation amplitude (roll) +uint8 STATE_ROLL = 3 # Roll-axis excitation and model identification +uint8 STATE_ROLL_PAUSE = 4 # Pause to return to level flight +uint8 STATE_PITCH_AMPLITUDE_DETECTION = 5 # FW only: determine required excitation amplitude (pitch) +uint8 STATE_PITCH = 6 # Pitch-axis excitation and model identification +uint8 STATE_PITCH_PAUSE = 7 # Pause to return to level flight +uint8 STATE_YAW_AMPLITUDE_DETECTION = 8 # FW only: determine required excitation amplitude (yaw) +uint8 STATE_YAW = 9 # Yaw-axis excitation and model identification +uint8 STATE_YAW_PAUSE = 10 # Pause to return to level flight +uint8 STATE_VERIFICATION = 11 # Verify model and candidate gains +uint8 STATE_APPLY = 12 # Apply gains +uint8 STATE_TEST = 13 # Test gains in closed-loop +uint8 STATE_COMPLETE = 14 # Tuning completed successfully +uint8 STATE_FAIL = 15 # Tuning failed (model invalid or controller unstable) +uint8 STATE_WAIT_FOR_DISARM = 16 # Waiting for disarm before finalizing diff --git a/msg/CMakeLists.txt b/msg/CMakeLists.txt index 0cdbc63683..0b066fddf1 100644 --- a/msg/CMakeLists.txt +++ b/msg/CMakeLists.txt @@ -63,6 +63,7 @@ set(msg_files DebugKeyValue.msg DebugValue.msg DebugVect.msg + DeviceInformation.msg DifferentialPressure.msg DistanceSensor.msg DistanceSensorModeChangeRequest.msg @@ -99,6 +100,7 @@ set(msg_files GeneratorStatus.msg GeofenceResult.msg GeofenceStatus.msg + GainCompression.msg GimbalControls.msg GimbalDeviceAttitudeStatus.msg GimbalDeviceInformation.msg @@ -196,6 +198,7 @@ set(msg_files SensorCombined.msg SensorCorrection.msg SensorGnssRelative.msg + SensorGnssStatus.msg SensorGps.msg SensorGyro.msg SensorGyroFft.msg @@ -207,6 +210,7 @@ set(msg_files SensorSelection.msg SensorsStatus.msg SensorsStatusImu.msg + SensorTemp.msg SensorUwb.msg SensorAirflow.msg SystemPower.msg @@ -237,6 +241,7 @@ set(msg_files VehicleThrustSetpoint.msg VehicleTorqueSetpoint.msg VelocityLimits.msg + Vtx.msg WheelEncoders.msg YawEstimatorStatus.msg versioned/ActuatorMotors.msg @@ -254,6 +259,8 @@ set(msg_files versioned/LongitudinalControlConfiguration.msg versioned/ManualControlSetpoint.msg versioned/ModeCompleted.msg + versioned/RaptorInput.msg + versioned/RaptorStatus.msg versioned/RegisterExtComponentReply.msg versioned/RegisterExtComponentRequest.msg versioned/TrajectorySetpoint.msg diff --git a/msg/ControlAllocatorStatus.msg b/msg/ControlAllocatorStatus.msg index 2d7b088322..3eed13b27d 100644 --- a/msg/ControlAllocatorStatus.msg +++ b/msg/ControlAllocatorStatus.msg @@ -19,3 +19,4 @@ int8[16] actuator_saturation # Indicates actuator saturation status. # Note 2: an actuator with limited dynamics can be indicated as upper-saturated even if it as not reached its maximum value. uint16 handled_motor_failure_mask # Bitmask of failed motors that were removed from the allocation / effectiveness matrix. Not necessarily identical to the report from FailureDetector +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection diff --git a/msg/DeviceInformation.msg b/msg/DeviceInformation.msg new file mode 100644 index 0000000000..c47804b6ed --- /dev/null +++ b/msg/DeviceInformation.msg @@ -0,0 +1,33 @@ +# Device information +# +# Can be used to uniquely associate a device_id from a sensor topic with a physical device using serial number. +# as well as tracking of the used firmware versions on the devices. + +uint64 timestamp # time since system start (microseconds) + +uint8 device_type # [@enum DEVICE_TYPE] Type of the device. Matches MAVLink DEVICE_TYPE enum + +uint8 DEVICE_TYPE_GENERIC = 0 # Generic/unknown sensor +uint8 DEVICE_TYPE_AIRSPEED = 1 # Airspeed sensor +uint8 DEVICE_TYPE_ESC = 2 # ESC +uint8 DEVICE_TYPE_SERVO = 3 # Servo +uint8 DEVICE_TYPE_GPS = 4 # GPS +uint8 DEVICE_TYPE_MAGNETOMETER = 5 # Magnetometer +uint8 DEVICE_TYPE_PARACHUTE = 6 # Parachute +uint8 DEVICE_TYPE_RANGEFINDER = 7 # Rangefinder +uint8 DEVICE_TYPE_WINCH = 8 # Winch +uint8 DEVICE_TYPE_BAROMETER = 9 # Barometer +uint8 DEVICE_TYPE_OPTICAL_FLOW = 10 # Optical flow +uint8 DEVICE_TYPE_ACCELEROMETER = 11 # Accelerometer +uint8 DEVICE_TYPE_GYROSCOPE = 12 # Gyroscope +uint8 DEVICE_TYPE_DIFFERENTIAL_PRESSURE = 13 # Differential pressure +uint8 DEVICE_TYPE_BATTERY = 14 # Battery +uint8 DEVICE_TYPE_HYGROMETER = 15 # Hygrometer + +char[32] vendor_name # Name of the device vendor +char[32] model_name # Name of the device model + +uint32 device_id # [-] [@invalid 0 if not available] Unique device ID for the sensor. Does not change between power cycles. +char[24] firmware_version # [-] [@invalid empty if not available] Firmware version. +char[24] hardware_version # [-] [@invalid empty if not available] Hardware version. +char[33] serial_number # [-] [@invalid empty if not available] Device serial number or unique identifier. diff --git a/msg/DifferentialPressure.msg b/msg/DifferentialPressure.msg index 0cdf1e4cce..44de2e9fc7 100644 --- a/msg/DifferentialPressure.msg +++ b/msg/DifferentialPressure.msg @@ -1,10 +1,12 @@ -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Differential-pressure (airspeed) sensor +# +# This is populated by airspeed sensor drivers and used by the sensor module to calculate airspeed. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `SensorBaro` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 differential_pressure_pa # differential pressure reading in Pascals (may be negative) - -float32 temperature # Temperature provided by sensor in degrees Celsius, NAN if unknown - -uint32 error_count # Number of errors detected by driver +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 differential_pressure_pa # [Pa] Differential pressure reading (may be negative) +float32 temperature # [degC] [@invalid NaN if unknown] Temperature +uint32 error_count # [-] Number of errors detected by driver diff --git a/msg/EscReport.msg b/msg/EscReport.msg index 9a75c3d7cc..ca80753f14 100644 --- a/msg/EscReport.msg +++ b/msg/EscReport.msg @@ -11,6 +11,19 @@ uint8 esc_state # State of ESC - depend on Vendor uint8 actuator_function # actuator output function (one of Motor1...MotorN) +uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 +uint8 ACTUATOR_FUNCTION_MOTOR2 = 102 +uint8 ACTUATOR_FUNCTION_MOTOR3 = 103 +uint8 ACTUATOR_FUNCTION_MOTOR4 = 104 +uint8 ACTUATOR_FUNCTION_MOTOR5 = 105 +uint8 ACTUATOR_FUNCTION_MOTOR6 = 106 +uint8 ACTUATOR_FUNCTION_MOTOR7 = 107 +uint8 ACTUATOR_FUNCTION_MOTOR8 = 108 +uint8 ACTUATOR_FUNCTION_MOTOR9 = 109 +uint8 ACTUATOR_FUNCTION_MOTOR10 = 110 +uint8 ACTUATOR_FUNCTION_MOTOR11 = 111 +uint8 ACTUATOR_FUNCTION_MOTOR12 = 112 + uint16 failures # Bitmask to indicate the internal ESC faults int8 esc_power # Applied power 0-100 in % (negative values reserved) diff --git a/msg/EstimatorStatus.msg b/msg/EstimatorStatus.msg index 3de2bfd722..a60f346770 100644 --- a/msg/EstimatorStatus.msg +++ b/msg/EstimatorStatus.msg @@ -16,6 +16,7 @@ uint8 GPS_CHECK_FAIL_MAX_VERT_DRIFT = 7 # 7 : maximum allowed vertical position uint8 GPS_CHECK_FAIL_MAX_HORZ_SPD_ERR = 8 # 8 : maximum allowed horizontal speed fail - requires stationary vehicle uint8 GPS_CHECK_FAIL_MAX_VERT_SPD_ERR = 9 # 9 : maximum allowed vertical velocity discrepancy fail uint8 GPS_CHECK_FAIL_SPOOFED = 10 # 10 : GPS signal is spoofed +uint8 GPS_CHECK_FAIL_JAMMED = 11 # 11 : GPS signal is jammed uint64 control_mode_flags # Bitmask to indicate EKF logic state uint8 CS_TILT_ALIGN = 0 # 0 - true if the filter tilt alignment is complete @@ -47,7 +48,9 @@ uint8 CS_SYNTHETIC_MAG_Z = 25 # 25 - true when we are using a synthesized measur uint8 CS_VEHICLE_AT_REST = 26 # 26 - true when the vehicle is at rest uint8 CS_GPS_YAW_FAULT = 27 # 27 - true when the GNSS heading has been declared faulty and is no longer being used uint8 CS_RNG_FAULT = 28 # 28 - true when the range finder has been declared faulty and is no longer being used -uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurements are being fused +uint8 CS_GNSS_VEL = 44 # 44 - true if GNSS velocity measurement fusion is intended +uint8 CS_GNSS_FAULT = 45 # 45 - true if GNSS measurements have been declared faulty and are no longer used +uint8 CS_YAW_MANUAL = 46 # 46 - true if yaw has been set manually uint32 filter_fault_flags # Bitmask to indicate EKF internal faults # 0 - true if the fusion of the magnetometer X-axis has encountered a numerical error diff --git a/msg/EstimatorStatusFlags.msg b/msg/EstimatorStatusFlags.msg index 8ab5b3d3e4..6de62f2c06 100644 --- a/msg/EstimatorStatusFlags.msg +++ b/msg/EstimatorStatusFlags.msg @@ -49,6 +49,9 @@ bool cs_valid_fake_pos # 41 - true if a valid constant position is bein bool cs_constant_pos # 42 - true if the vehicle is at a constant position bool cs_baro_fault # 43 - true when the current baro has been declared faulty and is no longer being used bool cs_gnss_vel # 44 - true if GNSS velocity measurement fusion is intended +bool cs_gnss_fault # 45 - true if GNSS true if GNSS measurements (lat, lon, vel) have been declared faulty +bool cs_yaw_manual # 46 - true if yaw has been set manually +bool cs_gnss_hgt_fault # 47 - true if GNSS true if GNSS measurements (alt) have been declared faulty # fault status uint32 fault_status_changes # number of filter fault status (fs) changes @@ -63,17 +66,3 @@ bool fs_bad_optflow_x # 7 - true if fusion of the optical flow X axis h bool fs_bad_optflow_y # 8 - true if fusion of the optical flow Y axis has encountered a numerical error bool fs_bad_acc_vertical # 10 - true if bad vertical accelerometer data has been detected bool fs_bad_acc_clipping # 11 - true if delta velocity data contains clipping (asymmetric railing) - - -# innovation test failures -uint32 innovation_fault_status_changes # number of innovation fault status (reject) changes -bool reject_hor_vel # 0 - true if horizontal velocity observations have been rejected -bool reject_ver_vel # 1 - true if vertical velocity observations have been rejected -bool reject_hor_pos # 2 - true if horizontal position observations have been rejected -bool reject_ver_pos # 3 - true if vertical position observations have been rejected -bool reject_yaw # 7 - true if the yaw observation has been rejected -bool reject_airspeed # 8 - true if the airspeed observation has been rejected -bool reject_sideslip # 9 - true if the synthetic sideslip observation has been rejected -bool reject_hagl # 10 - true if the height above ground observation has been rejected -bool reject_optflow_x # 11 - true if the X optical flow observation has been rejected -bool reject_optflow_y # 12 - true if the Y optical flow observation has been rejected diff --git a/msg/FailureDetectorStatus.msg b/msg/FailureDetectorStatus.msg index 923ceb36da..092848932e 100644 --- a/msg/FailureDetectorStatus.msg +++ b/msg/FailureDetectorStatus.msg @@ -12,3 +12,4 @@ bool fd_motor float32 imbalanced_prop_metric # Metric of the imbalanced propeller check (low-passed) uint16 motor_failure_mask # Bit-mask with motor indices, indicating critical motor failures +uint16 motor_stop_mask # Bitmaks of motors stopped by failure injection diff --git a/msg/FixedWingRunwayControl.msg b/msg/FixedWingRunwayControl.msg index 62d09a5ebf..f83e109547 100644 --- a/msg/FixedWingRunwayControl.msg +++ b/msg/FixedWingRunwayControl.msg @@ -1,8 +1,15 @@ # Auxiliary control fields for fixed-wing runway takeoff/landing -# Passes information from the FixedWingModeManager to the FixedWingAttitudeController +# Passes information from the FixedWingModeManager to the FixedWingAttitudeController (wheel control) and FixedWingLandDetector (takeoff state) uint64 timestamp # [us] time since system start +uint8 STATE_THROTTLE_RAMP = 0 # ramping up throttle +uint8 STATE_CLAMPED_TO_RUNWAY = 1 # clamped to runway, controlling yaw directly (wheel or rudder) +uint8 STATE_CLIMBOUT = 2 # climbout to safe height before navigation +uint8 STATE_FLYING = 3 # navigate freely + +uint8 runway_takeoff_state # Current state of runway takeoff state machine + bool wheel_steering_enabled # Flag that enables the wheel steering. float32 wheel_steering_nudging_rate # [norm] [@range -1, 1] [FRD] Manual wheel nudging, added to controller output. NAN is interpreted as 0. diff --git a/msg/GainCompression.msg b/msg/GainCompression.msg new file mode 100644 index 0000000000..b7d6735007 --- /dev/null +++ b/msg/GainCompression.msg @@ -0,0 +1,5 @@ +uint64 timestamp # Time since system start (microseconds) + +float32[3] compression_gains # [-] [@frame FRD] [@range 0, 1] Multiplicative gain to modify the output of the controller per axis +float32[3] spectral_damper_hpf # [-] [@frame FRD] Squared output of spectral damper high-pass filter +float32[3] spectral_damper_out # [-] [@frame FRD] Spectral damper output squared diff --git a/msg/GimbalControls.msg b/msg/GimbalControls.msg index 3e1c5a9dda..3546a4a0af 100644 --- a/msg/GimbalControls.msg +++ b/msg/GimbalControls.msg @@ -4,4 +4,4 @@ uint8 INDEX_PITCH = 1 uint8 INDEX_YAW = 2 uint64 timestamp_sample # the timestamp the data this control response is based on was sampled -float32[3] control +float32[3] control # Normalized output. 1 means maximum positive position. -1 maximum negative position. 0 means no deflection. NaN maps to disarmed. diff --git a/msg/GimbalDeviceAttitudeStatus.msg b/msg/GimbalDeviceAttitudeStatus.msg index 0007a1c03d..72eca870f3 100644 --- a/msg/GimbalDeviceAttitudeStatus.msg +++ b/msg/GimbalDeviceAttitudeStatus.msg @@ -9,6 +9,9 @@ uint16 DEVICE_FLAGS_NEUTRAL = 2 uint16 DEVICE_FLAGS_ROLL_LOCK = 4 uint16 DEVICE_FLAGS_PITCH_LOCK = 8 uint16 DEVICE_FLAGS_YAW_LOCK = 16 +uint16 DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32 +uint16 DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64 + float32[4] q float32 angular_velocity_x diff --git a/msg/GpioIn.msg b/msg/GpioIn.msg index 0482a2188e..2dc6e3cff2 100644 --- a/msg/GpioIn.msg +++ b/msg/GpioIn.msg @@ -1,4 +1,5 @@ # GPIO mask and state +uint8 MAX_INSTANCES = 8 uint64 timestamp # time since system start (microseconds) uint32 device_id # Device id diff --git a/msg/GpsDump.msg b/msg/GpsDump.msg index 2477bcfa3a..bbd16339f9 100644 --- a/msg/GpsDump.msg +++ b/msg/GpsDump.msg @@ -2,9 +2,13 @@ uint64 timestamp # time since system start (microseconds) +uint8 INSTANCE_MAIN = 0 +uint8 INSTANCE_SECONDARY = 1 + uint8 instance # Instance of GNSS receiver +uint32 device_id uint8 len # length of data, MSB bit set = message to the gps device, # clear = message from the device uint8[79] data # data to write to the log -uint8 ORB_QUEUE_LENGTH = 8 +uint8 ORB_QUEUE_LENGTH = 16 diff --git a/msg/InputRc.msg b/msg/InputRc.msg index 782477407e..2f72125ab8 100644 --- a/msg/InputRc.msg +++ b/msg/InputRc.msg @@ -32,9 +32,11 @@ bool rc_lost # RC receiver connection status: True,if no frame has arrived in uint16 rc_lost_frame_count # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_total_frame_count # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike functionality. uint16 rc_ppm_frame_length # Length of a single PPM frame. Zero for non-PPM systems +uint16 rc_frame_rate # RC frame rate in msg/second. 0 = invalid uint8 input_source # Input source uint16[18] values # measured pulse widths for each of the supported channels int8 link_quality # link quality. Percentage 0-100%. -1 = invalid float32 rssi_dbm # Actual rssi in units of dBm. NaN = invalid +int8 link_snr # link signal to noise ratio in units of dB. -1 = invalid diff --git a/msg/LaunchDetectionStatus.msg b/msg/LaunchDetectionStatus.msg index 6917f4bc24..5693e5a822 100644 --- a/msg/LaunchDetectionStatus.msg +++ b/msg/LaunchDetectionStatus.msg @@ -7,3 +7,5 @@ uint8 STATE_LAUNCH_DETECTED_DISABLED_MOTOR = 1 # launch detected, but keep moto uint8 STATE_FLYING = 2 # launch detected, use normal takeoff/flying configuration uint8 launch_detection_state + +bool selected_control_surface_disarmed # [-] flag indicating whether selected actuators should kept disarmed (have to be configured in control allocation) diff --git a/msg/MavlinkTunnel.msg b/msg/MavlinkTunnel.msg index 140bca5a1b..bc9949f139 100644 --- a/msg/MavlinkTunnel.msg +++ b/msg/MavlinkTunnel.msg @@ -20,4 +20,4 @@ uint8 payload_length # Length of the data transported in payload uint8[128] payload # Data itself # Topic aliases for known payload types -# TOPICS mavlink_tunnel esc_serial_passthru +# TOPICS mavlink_tunnel esc_serial_passthru io_serial_passthru diff --git a/msg/PurePursuitStatus.msg b/msg/PurePursuitStatus.msg index ef17246be5..bf1bb88b24 100644 --- a/msg/PurePursuitStatus.msg +++ b/msg/PurePursuitStatus.msg @@ -1,8 +1,8 @@ # Pure pursuit status -uint64 timestamp # [us] Time since system start -float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller -float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller -float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path -float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint -float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint +uint64 timestamp # [us] Time since system start +float32 lookahead_distance # [m] [@range 0, inf] Lookahead distance of pure the pursuit controller +float32 target_bearing # [rad] [@range -pi, pi] [@frame NED] Target bearing calculated by the pure pursuit controller +float32 crosstrack_error # [m] [@range -inf (Left of the path), inf (Right of the path)] Shortest distance from the vehicle to the path +float32 distance_to_waypoint # [m] [@range -inf, inf]Distance from the vehicle to the current waypoint +float32 bearing_to_waypoint # [rad] [@range -pi, pi] [@frame NED]Bearing towards current waypoint diff --git a/msg/RoverAttitudeSetpoint.msg b/msg/RoverAttitudeSetpoint.msg index 05b5d15086..2b8315016c 100644 --- a/msg/RoverAttitudeSetpoint.msg +++ b/msg/RoverAttitudeSetpoint.msg @@ -1,4 +1,4 @@ # Rover Attitude Setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_setpoint # [rad] [@range -inf, inf] [@frame NED] Yaw setpoint diff --git a/msg/RoverAttitudeStatus.msg b/msg/RoverAttitudeStatus.msg index 6b8afc192a..9d4bd2a949 100644 --- a/msg/RoverAttitudeStatus.msg +++ b/msg/RoverAttitudeStatus.msg @@ -1,5 +1,5 @@ # Rover Attitude Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw -float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) +uint64 timestamp # [us] Time since system start +float32 measured_yaw # [rad] [@range -pi, pi] [@frame NED]Measured yaw +float32 adjusted_yaw_setpoint # [rad] [@range -pi, pi] [@frame NED] Yaw setpoint that is being tracked (Applied slew rates) diff --git a/msg/RoverPositionSetpoint.msg b/msg/RoverPositionSetpoint.msg index bc711d2d29..e55dcd4737 100644 --- a/msg/RoverPositionSetpoint.msg +++ b/msg/RoverPositionSetpoint.msg @@ -1,8 +1,8 @@ # Rover Position Setpoint -uint64 timestamp # [us] Time since system start -float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position -float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track -float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed -float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with -float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel +uint64 timestamp # [us] Time since system start +float32[2] position_ned # [m] [@range -inf, inf] [@frame NED] Target position +float32[2] start_ned # [m] [@range -inf, inf] [@frame NED] [@invalid NaN Defaults to vehicle position] Start position which specifies a line for the rover to track +float32 cruising_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to maximum speed] Cruising speed +float32 arrival_speed # [m/s] [@range 0, inf] [@invalid NaN Defaults to 0] Speed the rover should arrive at the target with +float32 yaw # [rad] [@range -pi,pi] [@frame NED] [@invalid NaN Defaults to vehicle yaw] Mecanum only: Specify vehicle yaw during travel diff --git a/msg/RoverRateSetpoint.msg b/msg/RoverRateSetpoint.msg index 1a3c3b89f1..06752f285d 100644 --- a/msg/RoverRateSetpoint.msg +++ b/msg/RoverRateSetpoint.msg @@ -1,4 +1,4 @@ # Rover Rate setpoint -uint64 timestamp # [us] Time since system start -float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint +uint64 timestamp # [us] Time since system start +float32 yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint diff --git a/msg/RoverRateStatus.msg b/msg/RoverRateStatus.msg index fd6c0b7f3c..cde9200ea7 100644 --- a/msg/RoverRateStatus.msg +++ b/msg/RoverRateStatus.msg @@ -1,6 +1,6 @@ # Rover Rate Status -uint64 timestamp # [us] Time since system start -float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate -float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) -float32 pid_yaw_rate_integral # [] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller +uint64 timestamp # [us] Time since system start +float32 measured_yaw_rate # [rad/s] [@range -inf, inf] [@frame NED] Measured yaw rate +float32 adjusted_yaw_rate_setpoint # [rad/s] [@range -inf, inf] [@frame NED] Yaw rate setpoint that is being tracked (Applied slew rates) +float32 pid_yaw_rate_integral # [-] [@range -1, 1] Integral of the PID for the closed loop yaw rate controller diff --git a/msg/RoverSpeedSetpoint.msg b/msg/RoverSpeedSetpoint.msg index ac7787f6c9..9933c1157d 100644 --- a/msg/RoverSpeedSetpoint.msg +++ b/msg/RoverSpeedSetpoint.msg @@ -1,5 +1,5 @@ # Rover Speed Setpoint -uint64 timestamp # [us] Time since system start -float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction -float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction +uint64 timestamp # [us] Time since system start +float32 speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction +float32 speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction diff --git a/msg/RoverSpeedStatus.msg b/msg/RoverSpeedStatus.msg index 71cacd0e77..a005bb64c8 100644 --- a/msg/RoverSpeedStatus.msg +++ b/msg/RoverSpeedStatus.msg @@ -1,9 +1,9 @@ # Rover Velocity Status -uint64 timestamp # [us] Time since system start -float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction -float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_x_integral # [] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction -float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction -float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) -float32 pid_throttle_body_y_integral # [] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction +uint64 timestamp # [us] Time since system start +float32 measured_speed_body_x # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Measured speed in body x direction +float32 adjusted_speed_body_x_setpoint # [m/s] [@range -inf (Backwards), inf (Forwards)] [@frame Body] Speed setpoint in body x direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_x_integral # [-] [@range -1, 1] Integral of the PID for the closed loop controller of the speed in body x direction +float32 measured_speed_body_y # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Measured speed in body y direction +float32 adjusted_speed_body_y_setpoint # [m/s] [@range -inf (Left), inf (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Speed setpoint in body y direction that is being tracked (Applied slew rates) +float32 pid_throttle_body_y_integral # [-] [@range -1, 1] [@invalid NaN If not mecanum] Mecanum only: Integral of the PID for the closed loop controller of the speed in body y direction diff --git a/msg/RoverSteeringSetpoint.msg b/msg/RoverSteeringSetpoint.msg index f2daa967f9..eb6c2787f6 100644 --- a/msg/RoverSteeringSetpoint.msg +++ b/msg/RoverSteeringSetpoint.msg @@ -1,4 +1,4 @@ # Rover Steering setpoint -uint64 timestamp # [us] Time since system start -float32 normalized_steering_setpoint # [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels +uint64 timestamp # [us] Time since system start +float32 normalized_steering_setpoint # [-] [@range -1 (Left), 1 (Right)] [@frame Body] Ackermann: Normalized steering angle, Differential/Mecanum: Normalized speed difference between the left and right wheels diff --git a/msg/RoverThrottleSetpoint.msg b/msg/RoverThrottleSetpoint.msg index 333ebee5c3..104e228d15 100644 --- a/msg/RoverThrottleSetpoint.msg +++ b/msg/RoverThrottleSetpoint.msg @@ -1,5 +1,5 @@ # Rover Throttle setpoint -uint64 timestamp # [us] Time since system start -float32 throttle_body_x # [] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis -float32 throttle_body_y # [] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis +uint64 timestamp # [us] Time since system start +float32 throttle_body_x # [-] [@range -1 (Backwards), 1 (Forwards)] [@frame Body] Throttle setpoint along body X axis +float32 throttle_body_y # [-] [@range -1 (Left), 1 (Right)] [@frame Body] [@invalid NaN If not mecanum] Mecanum only: Throttle setpoint along body Y axis diff --git a/msg/SensorBaro.msg b/msg/SensorBaro.msg index 7c4154e159..f13096d9aa 100644 --- a/msg/SensorBaro.msg +++ b/msg/SensorBaro.msg @@ -1,12 +1,14 @@ -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +# Barometer sensor +# +# This is populated by barometer drivers and used by the EKF2 estimator. +# The information is published in the `SCALED_PRESSURE_n` MAVLink messages (along with information from a corresponding `DifferentialPressure` instance). -uint32 device_id # unique device ID for the sensor that does not change between power cycles +uint64 timestamp # [us] Time of publication (since system start) +uint64 timestamp_sample # [us] Time of raw data capture -float32 pressure # static pressure measurement in Pascals - -float32 temperature # temperature in degrees Celsius - -uint32 error_count +uint32 device_id # [-] Unique device ID for the sensor that does not change between power cycles +float32 pressure # [Pa] Static pressure measurement +float32 temperature # [degC] Temperature. +uint32 error_count # [-] Number of errors detected by driver. uint8 ORB_QUEUE_LENGTH = 4 diff --git a/msg/SensorGnssStatus.msg b/msg/SensorGnssStatus.msg new file mode 100644 index 0000000000..1562d47ce7 --- /dev/null +++ b/msg/SensorGnssStatus.msg @@ -0,0 +1,10 @@ +# Gnss quality indicators + +uint64 timestamp # time since system start (microseconds) +uint32 device_id # unique device ID for the sensor that does not change between power cycles + +bool quality_available # Set to true if quality indicators are available +uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available +uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available +uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available +uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available diff --git a/msg/SensorGps.msg b/msg/SensorGps.msg index ce2bfad4fd..2e94d174f3 100644 --- a/msg/SensorGps.msg +++ b/msg/SensorGps.msg @@ -30,18 +30,26 @@ float32 vdop # Vertical dilution of precision int32 noise_per_ms # GPS noise per millisecond uint16 automatic_gain_control # Automatic gain control monitor -uint8 JAMMING_STATE_UNKNOWN = 0 -uint8 JAMMING_STATE_OK = 1 -uint8 JAMMING_STATE_WARNING = 2 -uint8 JAMMING_STATE_CRITICAL = 3 -uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical -int32 jamming_indicator # indicates jamming is occurring +uint8 JAMMING_STATE_UNKNOWN = 0 #default +uint8 JAMMING_STATE_OK = 1 +uint8 JAMMING_STATE_MITIGATED = 2 +uint8 JAMMING_STATE_DETECTED = 3 +uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected +int32 jamming_indicator # indicates jamming is occurring -uint8 SPOOFING_STATE_UNKNOWN = 0 -uint8 SPOOFING_STATE_NONE = 1 -uint8 SPOOFING_STATE_INDICATED = 2 -uint8 SPOOFING_STATE_MULTIPLE = 3 -uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical +uint8 SPOOFING_STATE_UNKNOWN = 0 #default +uint8 SPOOFING_STATE_OK = 1 +uint8 SPOOFING_STATE_MITIGATED = 2 +uint8 SPOOFING_STATE_DETECTED = 3 +uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected + +# Combined authentication state (e.g. Galileo OSNMA) +uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default +uint8 AUTHENTICATION_STATE_INITIALIZING = 1 +uint8 AUTHENTICATION_STATE_ERROR = 2 +uint8 AUTHENTICATION_STATE_OK = 3 +uint8 AUTHENTICATION_STATE_DISABLED = 4 +uint8 authentication_state # GPS signal authentication state float32 vel_m_s # GPS ground speed, (metres/sec) float32 vel_n_m_s # GPS North velocity, (metres/sec) @@ -55,6 +63,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi uint8 satellites_used # Number of satellites used +uint32 SYSTEM_ERROR_OK = 0 #default +uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1 +uint32 SYSTEM_ERROR_CONFIGURATION = 2 +uint32 SYSTEM_ERROR_SOFTWARE = 4 +uint32 SYSTEM_ERROR_ANTENNA = 8 +uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16 +uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32 +uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64 +uint32 system_error # General errors with the connected GPS receiver + float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI]) float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI]) float32 heading_accuracy # heading accuracy (rad, [0, 2PI]) diff --git a/msg/SensorTemp.msg b/msg/SensorTemp.msg new file mode 100644 index 0000000000..2837857ef1 --- /dev/null +++ b/msg/SensorTemp.msg @@ -0,0 +1,4 @@ +uint64 timestamp # time since system start (microseconds) + +uint32 device_id # unique device ID for the sensor that does not change between power cycles +float32 temperature # Temperature provided by sensor (Celsius) diff --git a/msg/Vtx.msg b/msg/Vtx.msg new file mode 100644 index 0000000000..b62a490636 --- /dev/null +++ b/msg/Vtx.msg @@ -0,0 +1,32 @@ +uint64 timestamp # time since system start (microseconds) + +uint8 BAND_NAME_LENGTH = 12 +uint8 POWER_LABEL_LENGTH = 4 + +uint8 PROTOCOL_NONE = 0 # No protocol is detected, usually an error +uint8 PROTOCOL_SMART_AUDIO_V1 = 10 +uint8 PROTOCOL_SMART_AUDIO_V2 = 20 +uint8 PROTOCOL_SMART_AUDIO_V2_1 = 21 +uint8 PROTOCOL_TRAMP = 100 +uint8 protocol + +uint8 DEVICE_UNKNOWN = 0 +uint8 DEVICE_PEAK_THOR_T67 = 20 +uint8 DEVICE_RUSH_MAX_SOLO = 40 +uint8 device + +uint8 MODE_NORMAL = 0 +uint8 MODE_PIT = 1 +uint8 mode + +# Band and Channel are 0-indexed! But the user expects a 1-indexed display! +int8 band # Band number (0-23), negative values indicate frequency mode +int8 channel # Channel number (0-15), negative values indicate frequency mode +uint16 frequency # Frequency in MHz, zero indicates unknown + +uint8 band_letter # Band letter as ASCII +uint8[12] band_name # Band name in ASCII without null termination + +# Also 0-indexed, but the user expects a 1-indexed display! +int8 power_level # Current power level (0-15), negative values indicate unknown +uint8[4] power_label # Current power label in ASCII without null termination diff --git a/msg/px4_msgs_old/msg/BatteryStatusV0.msg b/msg/px4_msgs_old/msg/BatteryStatusV0.msg index f8f9e3f12d..7e36e38f3f 100644 --- a/msg/px4_msgs_old/msg/BatteryStatusV0.msg +++ b/msg/px4_msgs_old/msg/BatteryStatusV0.msg @@ -21,9 +21,9 @@ uint8 cell_count # [@invalid 0] Number of cells uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 uint16 capacity # [mAh] Capacity of the battery when fully charged diff --git a/msg/px4_msgs_old/msg/ConfigOverridesV0.msg b/msg/px4_msgs_old/msg/ConfigOverridesV0.msg new file mode 100644 index 0000000000..b274adfbec --- /dev/null +++ b/msg/px4_msgs_old/msg/ConfigOverridesV0.msg @@ -0,0 +1,21 @@ +# Configurable overrides by (external) modes or mode executors + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +bool disable_auto_disarm # Prevent the drone from automatically disarming after landing (if configured) + +bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) +int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout + + +int8 SOURCE_TYPE_MODE = 0 +int8 SOURCE_TYPE_MODE_EXECUTOR = 1 +int8 source_type + +uint8 source_id # ID depending on source_type + +uint8 ORB_QUEUE_LENGTH = 4 + +# TOPICS config_overrides config_overrides_request diff --git a/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg b/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg new file mode 100644 index 0000000000..4495bcdb90 --- /dev/null +++ b/msg/px4_msgs_old/msg/RegisterExtComponentReplyV0.msg @@ -0,0 +1,15 @@ +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID from the request +char[25] name # name from the request + +uint16 px4_ros2_api_version + +bool success +int8 arming_check_id # arming check registration ID (-1 if invalid) +int8 mode_id # assigned mode ID (-1 if invalid) +int8 mode_executor_id # assigned mode executor ID (-1 if invalid) + +uint8 ORB_QUEUE_LENGTH = 2 diff --git a/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg b/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg new file mode 100644 index 0000000000..b0798705ca --- /dev/null +++ b/msg/px4_msgs_old/msg/RegisterExtComponentRequestV0.msg @@ -0,0 +1,24 @@ +# Request to register an external component + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # time since system start (microseconds) + +uint64 request_id # ID, set this to a random value +char[25] name # either the requested mode name, or component name + +uint16 LATEST_PX4_ROS2_API_VERSION = 1 # API version compatibility. Increase this on a breaking semantic change. Changes to any message field are detected separately and do not require an API version change. + +uint16 px4_ros2_api_version # Set to LATEST_PX4_ROS2_API_VERSION + +# Components to be registered +bool register_arming_check +bool register_mode # registering a mode also requires arming_check to be set +bool register_mode_executor # registering an executor also requires a mode to be registered (which is the owned mode by the executor) + +bool enable_replace_internal_mode # set to true if an internal mode should be replaced +uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* +bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) + + +uint8 ORB_QUEUE_LENGTH = 2 diff --git a/msg/translation_node/translations/all_translations.h b/msg/translation_node/translations/all_translations.h index 1322253715..12a8763ec6 100644 --- a/msg/translation_node/translations/all_translations.h +++ b/msg/translation_node/translations/all_translations.h @@ -10,8 +10,11 @@ #include "translation_arming_check_reply_v1.h" #include "translation_arming_check_request_v1.h" #include "translation_battery_status_v1.h" +#include "translation_config_overrides_v1.h" #include "translation_event_v1.h" #include "translation_home_position_v1.h" +#include "translation_register_ext_component_reply_v1.h" +#include "translation_register_ext_component_request_v1.h" #include "translation_vehicle_attitude_setpoint_v1.h" #include "translation_vehicle_status_v1.h" #include "translation_vehicle_local_position_v1.h" diff --git a/msg/translation_node/translations/translation_config_overrides_v1.h b/msg/translation_node/translations/translation_config_overrides_v1.h new file mode 100644 index 0000000000..1f7e813951 --- /dev/null +++ b/msg/translation_node/translations/translation_config_overrides_v1.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * Copyright (c) 2025 PX4 Development Team. + * SPDX-License-Identifier: BSD-3-Clause + ****************************************************************************/ +#pragma once + +// Translate ConfigOverrides v0 <--> v1 +#include +#include + +class ConfigOverridesV1Translation { +public: + using MessageOlder = px4_msgs_old::msg::ConfigOverridesV0; + static_assert(MessageOlder::MESSAGE_VERSION == 0); + + using MessageNewer = px4_msgs::msg::ConfigOverrides; + static_assert(MessageNewer::MESSAGE_VERSION == 1); + + static constexpr const char* kTopic = "fmu/in/config_overrides_request"; + + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.disable_auto_disarm = msg_older.disable_auto_disarm; + msg_newer.defer_failsafes = msg_older.defer_failsafes; + msg_newer.defer_failsafes_timeout_s = msg_older.defer_failsafes_timeout_s; + msg_newer.disable_auto_set_home = false; + msg_newer.source_type = msg_older.source_type; + msg_newer.source_id = msg_older.source_id; + } + + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.disable_auto_disarm = msg_newer.disable_auto_disarm; + msg_older.defer_failsafes = msg_newer.defer_failsafes; + msg_older.defer_failsafes_timeout_s = msg_newer.defer_failsafes_timeout_s; + msg_older.source_type = msg_newer.source_type; + msg_older.source_id = msg_newer.source_id; + } +}; + +REGISTER_TOPIC_TRANSLATION_DIRECT(ConfigOverridesV1Translation); diff --git a/msg/translation_node/translations/translation_register_ext_component_reply_v1.h b/msg/translation_node/translations/translation_register_ext_component_reply_v1.h new file mode 100644 index 0000000000..7ff61d7d97 --- /dev/null +++ b/msg/translation_node/translations/translation_register_ext_component_reply_v1.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * Copyright (c) 2025 PX4 Development Team. + * SPDX-License-Identifier: BSD-3-Clause + ****************************************************************************/ +#pragma once + +// Translate RegisterExtComponentReply v0 <--> v1 +#include +#include + +class RegisterExtComponentReplyV1Translation { +public: + using MessageOlder = px4_msgs_old::msg::RegisterExtComponentReplyV0; + static_assert(MessageOlder::MESSAGE_VERSION == 0); + + using MessageNewer = px4_msgs::msg::RegisterExtComponentReply; + static_assert(MessageNewer::MESSAGE_VERSION == 1); + + static constexpr const char* kTopic = "fmu/out/register_ext_component_reply"; + + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.request_id = msg_older.request_id; + msg_newer.name = msg_older.name; + msg_newer.px4_ros2_api_version = msg_older.px4_ros2_api_version; + msg_newer.success = msg_older.success; + msg_newer.arming_check_id = msg_older.arming_check_id; + msg_newer.mode_id = msg_older.mode_id; + msg_newer.mode_executor_id = msg_older.mode_executor_id; + msg_newer.not_user_selectable = false; + } + + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.request_id = msg_newer.request_id; + msg_older.name = msg_newer.name; + msg_older.px4_ros2_api_version = msg_newer.px4_ros2_api_version; + msg_older.success = msg_newer.success; + msg_older.arming_check_id = msg_newer.arming_check_id; + msg_older.mode_id = msg_newer.mode_id; + msg_older.mode_executor_id = msg_newer.mode_executor_id; + } +}; + +REGISTER_TOPIC_TRANSLATION_DIRECT(RegisterExtComponentReplyV1Translation); diff --git a/msg/translation_node/translations/translation_register_ext_component_request_v1.h b/msg/translation_node/translations/translation_register_ext_component_request_v1.h new file mode 100644 index 0000000000..9f90b90784 --- /dev/null +++ b/msg/translation_node/translations/translation_register_ext_component_request_v1.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * Copyright (c) 2025 PX4 Development Team. + * SPDX-License-Identifier: BSD-3-Clause + ****************************************************************************/ +#pragma once + +// Translate RegisterExtComponentRequest v0 <--> v1 +#include +#include + +class RegisterExtComponentRequestV1Translation { +public: + using MessageOlder = px4_msgs_old::msg::RegisterExtComponentRequestV0; + static_assert(MessageOlder::MESSAGE_VERSION == 0); + + using MessageNewer = px4_msgs::msg::RegisterExtComponentRequest; + static_assert(MessageNewer::MESSAGE_VERSION == 1); + + static constexpr const char* kTopic = "fmu/in/register_ext_component_request"; + + static void fromOlder(const MessageOlder &msg_older, MessageNewer &msg_newer) { + msg_newer.timestamp = msg_older.timestamp; + msg_newer.request_id = msg_older.request_id; + msg_newer.name = msg_older.name; + msg_newer.px4_ros2_api_version = msg_older.px4_ros2_api_version; + msg_newer.register_arming_check = msg_older.register_arming_check; + msg_newer.register_mode = msg_older.register_mode; + msg_newer.register_mode_executor = msg_older.register_mode_executor; + msg_newer.enable_replace_internal_mode = msg_older.enable_replace_internal_mode; + msg_newer.replace_internal_mode = msg_older.replace_internal_mode; + msg_newer.activate_mode_immediately = msg_older.activate_mode_immediately; + msg_newer.not_user_selectable = false; + } + + static void toOlder(const MessageNewer &msg_newer, MessageOlder &msg_older) { + msg_older.timestamp = msg_newer.timestamp; + msg_older.request_id = msg_newer.request_id; + msg_older.name = msg_newer.name; + msg_older.px4_ros2_api_version = msg_newer.px4_ros2_api_version; + msg_older.register_arming_check = msg_newer.register_arming_check; + msg_older.register_mode = msg_newer.register_mode; + msg_older.register_mode_executor = msg_newer.register_mode_executor; + msg_older.enable_replace_internal_mode = msg_newer.enable_replace_internal_mode; + msg_older.replace_internal_mode = msg_newer.replace_internal_mode; + msg_older.activate_mode_immediately = msg_newer.activate_mode_immediately; + } +}; + +REGISTER_TOPIC_TRANSLATION_DIRECT(RegisterExtComponentRequestV1Translation); diff --git a/msg/versioned/ActuatorMotors.msg b/msg/versioned/ActuatorMotors.msg index 04b8ebbb4e..d165c5c1cb 100644 --- a/msg/versioned/ActuatorMotors.msg +++ b/msg/versioned/ActuatorMotors.msg @@ -8,9 +8,9 @@ uint32 MESSAGE_VERSION = 0 uint64 timestamp # [us] Time since system start uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on -uint16 reversible_flags # Bitset indicating which motors are configured to be reversible +uint16 reversible_flags # [-] Bitset indicating which motors are configured to be reversible uint8 ACTUATOR_FUNCTION_MOTOR1 = 101 # uint8 NUM_CONTROLS = 12 # -float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) +float32[12] control # [@range -1, 1] Normalized thrust. where 1 means maximum positive thrust, -1 maximum negative (if not supported by the output, <0 maps to NaN). NaN maps to disarmed (stop the motors) diff --git a/msg/versioned/ActuatorServos.msg b/msg/versioned/ActuatorServos.msg index 30b1b359b9..c547998d1c 100644 --- a/msg/versioned/ActuatorServos.msg +++ b/msg/versioned/ActuatorServos.msg @@ -9,4 +9,4 @@ uint64 timestamp # [us] Time since system start uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on uint8 NUM_CONTROLS = 8 # -float32[8] control # [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. +float32[8] control # [-] [@range -1, 1] Normalized output. 1 means maximum positive position. -1 maximum negative position (if not supported by the output, <0 maps to NaN). NaN maps to disarmed. diff --git a/msg/versioned/AirspeedValidated.msg b/msg/versioned/AirspeedValidated.msg index a54e1510b6..c9d9eb2a61 100644 --- a/msg/versioned/AirspeedValidated.msg +++ b/msg/versioned/AirspeedValidated.msg @@ -1,22 +1,27 @@ +# Validated airspeed +# +# Provides information about airspeed (indicated, true, calibrated) and the source of the data. +# Used by controllers, estimators and for airspeed reporting to operator. + + uint32 MESSAGE_VERSION = 1 -uint64 timestamp # time since system start (microseconds) +uint64 timestamp # [us] Time since system start -float32 indicated_airspeed_m_s # [m/s] Indicated airspeed (IAS), set to NAN if invalid -float32 calibrated_airspeed_m_s # [m/s] Calibrated airspeed (CAS), set to NAN if invalid -float32 true_airspeed_m_s # [m/s] True airspeed (TAS), set to NAN if invalid +float32 indicated_airspeed_m_s # [m/s] [@invalid NaN] Indicated airspeed (IAS) +float32 calibrated_airspeed_m_s # [m/s] [@invalid NaN] Calibrated airspeed (CAS) +float32 true_airspeed_m_s # [m/s] [@invalid NaN] True airspeed (TAS) -int8 airspeed_source # Source of currently published airspeed values -int8 DISABLED = -1 -int8 GROUND_MINUS_WIND = 0 -int8 SENSOR_1 = 1 -int8 SENSOR_2 = 2 -int8 SENSOR_3 = 3 -int8 SYNTHETIC = 4 +int8 airspeed_source # [@enum SOURCE] Source of currently published airspeed values +int8 SOURCE_DISABLED = -1 # Disabled +int8 SOURCE_GROUND_MINUS_WIND = 0 # Ground speed minus wind +int8 SOURCE_SENSOR_1 = 1 # Sensor 1 +int8 SOURCE_SENSOR_2 = 2 # Sensor 2 +int8 SOURCE_SENSOR_3 = 3 # Sensor 3 +int8 SOURCE_SYNTHETIC = 4 # Synthetic airspeed -# debug states -float32 calibrated_ground_minus_wind_m_s # CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption, set to NAN if invalid -float32 calibraded_airspeed_synth_m_s # synthetic airspeed in m/s, set to NAN if invalid -float32 airspeed_derivative_filtered # filtered indicated airspeed derivative [m/s/s] -float32 throttle_filtered # filtered fixed-wing throttle [-] -float32 pitch_filtered # filtered pitch [rad] +float32 calibrated_ground_minus_wind_m_s # [m/s] [@invalid NaN] CAS calculated from groundspeed - windspeed, where windspeed is estimated based on a zero-sideslip assumption +float32 calibraded_airspeed_synth_m_s # [m/s] [@invalid NaN] Synthetic airspeed +float32 airspeed_derivative_filtered # [m/s^2] Filtered indicated airspeed derivative +float32 throttle_filtered # [-] Filtered fixed-wing throttle +float32 pitch_filtered # [rad] Filtered pitch diff --git a/msg/versioned/ArmingCheckReply.msg b/msg/versioned/ArmingCheckReply.msg index 7ba4ad7bf3..b39649641f 100644 --- a/msg/versioned/ArmingCheckReply.msg +++ b/msg/versioned/ArmingCheckReply.msg @@ -1,4 +1,4 @@ -# Arming check reply. +# Arming check reply # # This is a response to an ArmingCheckRequest message sent by the FMU to an external component, such as a ROS 2 navigation mode. # The response contains the current set of external mode requirements, and a queue of events indicating recent failures to set the mode (which the FMU may then forward to a ground station). @@ -11,33 +11,33 @@ uint32 MESSAGE_VERSION = 1 uint64 timestamp # [us] Time since system start. -uint8 request_id # Id of ArmingCheckRequest for which this is a response. -uint8 registration_id # Id of external component emitting this response. +uint8 request_id # [-] Id of ArmingCheckRequest for which this is a response +uint8 registration_id # [-] Id of external component emitting this response -uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies. +uint8 HEALTH_COMPONENT_INDEX_NONE = 0 # Index of health component for which this response applies uint8 health_component_index # [@enum HEALTH_COMPONENT_INDEX] -bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json). -bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json). +bool health_component_is_present # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_warning # Unused. Intended for use with health events interface (health_component_t in events.json) +bool health_component_error # Unused. Intended for use with health events interface (health_component_t in events.json) -bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed. +bool can_arm_and_run # True if the component can arm. For navigation mode components, true if the component can arm in the mode or switch to the mode when already armed -uint8 num_events # Number of queued failure messages (Event) in the events field. +uint8 num_events # Number of queued failure messages (Event) in the events field -Event[5] events # Arming failure reasons (Queue of events to report to GCS). +Event[5] events # Arming failure reasons (Queue of events to report to GCS) # Mode requirements -bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope). -bool mode_req_attitude # Requires an attitude estimate. -bool mode_req_local_alt # Requires a local altitude estimate. -bool mode_req_local_position # Requires a local position estimate. -bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate. -bool mode_req_global_position # Requires a global position estimate. -bool mode_req_global_position_relaxed # Requires a relaxed global position estimate. -bool mode_req_mission # Requires an uploaded mission. -bool mode_req_home_position # Requires a home position (such as RTL/Return mode). -bool mode_req_prevent_arming # Prevent arming (such as in Land mode). +bool mode_req_angular_velocity # Requires angular velocity estimate (e.g. from gyroscope) +bool mode_req_attitude # Requires an attitude estimate +bool mode_req_local_alt # Requires a local altitude estimate +bool mode_req_local_position # Requires a local position estimate +bool mode_req_local_position_relaxed # Requires a more relaxed global position estimate +bool mode_req_global_position # Requires a global position estimate +bool mode_req_global_position_relaxed # Requires a relaxed global position estimate +bool mode_req_mission # Requires an uploaded mission +bool mode_req_home_position # Requires a home position (such as RTL/Return mode) +bool mode_req_prevent_arming # Prevent arming (such as in Land mode) bool mode_req_manual_control # Requires a manual controller uint8 ORB_QUEUE_LENGTH = 4 diff --git a/msg/versioned/ArmingCheckRequest.msg b/msg/versioned/ArmingCheckRequest.msg index 42d56bdf51..df12a79d35 100644 --- a/msg/versioned/ArmingCheckRequest.msg +++ b/msg/versioned/ArmingCheckRequest.msg @@ -1,4 +1,4 @@ -# Arming check request. +# Arming check request # # Broadcast message to request arming checks be reported by all registered components, such as external ROS 2 navigation modes. # All registered components should respond with an ArmingCheckReply message that indicates their current mode requirements, and any arming failure information. @@ -9,8 +9,8 @@ uint32 MESSAGE_VERSION = 1 -uint64 timestamp # [us] Time since system start. +uint64 timestamp # [us] Time since system start -uint8 request_id # Id of this request. Allows correlation with associated ArmingCheckReply messages. +uint8 request_id # [-] Id of this request. Allows correlation with associated ArmingCheckReply messages. -uint32 valid_registrations_mask # Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) +uint32 valid_registrations_mask # [-] Bitmask of valid registration ID's (the bit is also cleared if flagged as unresponsive) diff --git a/msg/versioned/BatteryStatus.msg b/msg/versioned/BatteryStatus.msg index 39f75ed611..567f6633fc 100644 --- a/msg/versioned/BatteryStatus.msg +++ b/msg/versioned/BatteryStatus.msg @@ -1,78 +1,79 @@ # Battery status # -# Battery status information for up to 4 battery instances. +# Battery status information for up to 3 battery instances. # These are populated from power module and smart battery device drivers, and one battery updated from MAVLink. # Battery instance information is also logged and streamed in MAVLink telemetry. uint32 MESSAGE_VERSION = 1 -uint8 MAX_INSTANCES = 4 +uint8 MAX_INSTANCES = 3 -uint64 timestamp # [us] Time since system start -bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. -float32 voltage_v # [V] [@invalid 0] Battery voltage -float32 current_a # [A] [@invalid -1] Battery current -float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) -float32 discharged_mah # [mAh] [@invalid -1] Discharged amount -float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity -float32 scale # [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag -float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load -float32 temperature # [°C] [@invalid NaN] Temperature of the battery -uint8 cell_count # [@invalid 0] Number of cells +uint64 timestamp # [us] Time since system start + +bool connected # Whether or not a battery is connected. For power modules this is based on a voltage threshold. +float32 voltage_v # [V] [@invalid 0] Battery voltage +float32 current_a # [A] [@invalid -1] Battery current +float32 current_average_a # [A] [@invalid -1] Battery current average (for FW average in level flight) +float32 discharged_mah # [mAh] [@invalid -1] Discharged amount +float32 remaining # [@range 0,1] [@invalid -1] Remaining capacity +float32 scale # [-] [@range 1,] [@invalid -1] Scaling factor to compensate for lower actuation power caused by voltage sag +float32 time_remaining_s # [s] [@invalid NaN] Predicted time remaining until battery is empty under previous averaged load +float32 temperature # [°C] [@invalid NaN] Temperature of the battery +uint8 cell_count # [-] [@invalid 0] Number of cells -uint8 source # [@enum SOURCE] Battery source -uint8 SOURCE_POWER_MODULE = 0 # Power module -uint8 SOURCE_EXTERNAL = 1 # External -uint8 SOURCE_ESCS = 2 # ESCs +uint8 source # [@enum SOURCE] Battery source +uint8 SOURCE_POWER_MODULE = 0 # Power module (analog ADC or I2C power monitor) +uint8 SOURCE_EXTERNAL = 1 # External (MAVLink, CAN, or external driver) +uint8 SOURCE_ESCS = 2 # ESCs (via ESC telemetry) -uint8 priority # Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 -uint16 capacity # [mAh] Capacity of the battery when fully charged -uint16 cycle_count # Number of discharge cycles the battery has experienced -uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge -uint16 manufacture_date # Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 -uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity -uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation -uint8 id # ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed -uint16 interface_error # Interface error counter +uint8 priority # [-] Zero based priority is the connection on the Power Controller V1..Vn AKA BrickN-1 +uint16 capacity # [mAh] Capacity of the battery when fully charged +uint16 cycle_count # [-] Number of discharge cycles the battery has experienced +uint16 average_time_to_empty # [minutes] Predicted remaining battery capacity based on the average rate of discharge +uint16 manufacture_date # [-] Manufacture date, part of serial number of the battery pack. Formatted as: Day + Month×32 + (Year–1980)×512 +uint16 state_of_health # [%] [@range 0, 100] State of health. FullChargeCapacity/DesignCapacity +uint16 max_error # [%] [@range 1, 100] Max error, expected margin of error in the state-of-charge calculation +uint8 id # [-] ID number of a battery. Should be unique and consistent for the lifetime of a vehicle. 1-indexed +uint16 interface_error # [-] Interface error counter -float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages -float32 max_cell_voltage_delta # Max difference between individual cell voltages +float32[14] voltage_cell_v # [V] [@invalid 0] Battery individual cell voltages +float32 max_cell_voltage_delta # [V] Max difference between individual cell voltages -bool is_powering_off # Power off event imminent indication, false if unknown -bool is_required # Set if the battery is explicitly required before arming +bool is_powering_off # Power off event imminent indication, false if unknown +bool is_required # Set if the battery is explicitly required before arming -uint8 warning # [@enum WARNING STATE] Current battery warning -uint8 WARNING_NONE = 0 # No battery low voltage warning active -uint8 WARNING_LOW = 1 # Low voltage warning -uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately -uint8 WARNING_EMERGENCY = 3 # Immediate landing required -uint8 WARNING_FAILED = 4 # Battery has failed completely -uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field -uint8 STATE_CHARGING = 7 # Battery is charging +uint8 warning # [@enum WARNING STATE] Current battery warning +uint8 WARNING_NONE = 0 # No battery low voltage warning active +uint8 WARNING_LOW = 1 # Low voltage warning +uint8 WARNING_CRITICAL = 2 # Critical voltage, return / abort immediately +uint8 WARNING_EMERGENCY = 3 # Immediate landing required +uint8 WARNING_FAILED = 4 # Battery has failed completely +uint8 STATE_UNHEALTHY = 6 # Battery is diagnosed to be defective or an error occurred, usage is discouraged / prohibited. Possible causes (faults) are listed in faults field +uint8 STATE_CHARGING = 7 # Battery is charging -uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication -uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged -uint8 FAULT_SPIKES = 1 # Voltage spikes -uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed -uint8 FAULT_OVER_CURRENT = 3 # Over-current -uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature -uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault -uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) -uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware -uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system -uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem -uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming -uint8 FAULT_COUNT = 11 # Counter. Keep this as last element +uint16 faults # [@enum FAULT] Smart battery supply status/fault flags (bitmask) for health indication +uint8 FAULT_DEEP_DISCHARGE = 0 # Battery has deep discharged +uint8 FAULT_SPIKES = 1 # Voltage spikes +uint8 FAULT_CELL_FAIL= 2 # One or more cells have failed +uint8 FAULT_OVER_CURRENT = 3 # Over-current +uint8 FAULT_OVER_TEMPERATURE = 4 # Over-temperature +uint8 FAULT_UNDER_TEMPERATURE = 5 # Under-temperature fault +uint8 FAULT_INCOMPATIBLE_VOLTAGE = 6 # Vehicle voltage is not compatible with this battery (batteries on same power rail should have similar voltage) +uint8 FAULT_INCOMPATIBLE_FIRMWARE = 7 # Battery firmware is not compatible with current autopilot firmware +uint8 FAULT_INCOMPATIBLE_MODEL = 8 # Battery model is not supported by the system +uint8 FAULT_HARDWARE_FAILURE = 9 # Hardware problem +uint8 FAULT_FAILED_TO_ARM = 10 # Battery had a problem while arming +uint8 FAULT_COUNT = 11 # Counter. Keep this as last element -float32 full_charge_capacity_wh # [Wh] Compensated battery capacity -float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining -uint16 over_discharge_count # Number of battery overdischarge -float32 nominal_voltage # [V] Nominal voltage of the battery pack +float32 full_charge_capacity_wh # [Wh] Compensated battery capacity +float32 remaining_capacity_wh # [Wh] Compensated battery capacity remaining +uint16 over_discharge_count # [-] Number of battery overdischarge +float32 nominal_voltage # [V] Nominal voltage of the battery pack -float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate -float32 ocv_estimate # [V] Open circuit voltage estimate -float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate -float32 volt_based_soc_estimate # [@range 0, 1] Normalized volt based state of charge estimate -float32 voltage_prediction # [V] Predicted voltage -float32 prediction_error # [V] Prediction error -float32 estimation_covariance_norm # Norm of the covariance matrix +float32 internal_resistance_estimate # [Ohm] Internal resistance per cell estimate +float32 ocv_estimate # [V] Open circuit voltage estimate +float32 ocv_estimate_filtered # [V] Filtered open circuit voltage estimate +float32 volt_based_soc_estimate # [-] [@range 0, 1] Normalized volt based state of charge estimate +float32 voltage_prediction # [V] Predicted voltage +float32 prediction_error # [V] Prediction error +float32 estimation_covariance_norm # [-] Norm of the covariance matrix diff --git a/msg/versioned/ConfigOverrides.msg b/msg/versioned/ConfigOverrides.msg index b274adfbec..51fd86b037 100644 --- a/msg/versioned/ConfigOverrides.msg +++ b/msg/versioned/ConfigOverrides.msg @@ -1,6 +1,6 @@ # Configurable overrides by (external) modes or mode executors -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -8,7 +8,7 @@ bool disable_auto_disarm # Prevent the drone from automatically disarmin bool defer_failsafes # Defer all failsafes that can be deferred (until the flag is cleared) int16 defer_failsafes_timeout_s # Maximum time a failsafe can be deferred. 0 = system default, -1 = no timeout - +bool disable_auto_set_home # Prevent the drone from automatically setting the home position on arm or takeoff int8 SOURCE_TYPE_MODE = 0 int8 SOURCE_TYPE_MODE_EXECUTOR = 1 diff --git a/msg/versioned/RaptorInput.msg b/msg/versioned/RaptorInput.msg new file mode 100644 index 0000000000..4193397137 --- /dev/null +++ b/msg/versioned/RaptorInput.msg @@ -0,0 +1,18 @@ +# Raptor Input + +# The exact inputs to the Raptor foundation policy. +# Having access to the exact inputs helps with debugging and post-hoc analysis. + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +bool active # Signals if the policy is active (aka publishing actuator_motors) +float32[3] position # [m] [@frame FLU] Position of the vehicle_local_position frame +float32[4] orientation # [-] Orientation in the vehicle_attitude frame but using the FLU convention as a unit quaternion (w, x, y, z) +float32[3] linear_velocity # [m/s] [@frame FLU] Linear velocity in the vehicle_local_position frame +float32[3] angular_velocity # [rad/s] [@frame FLU] Angular velocity in the body frame +uint8 ACTION_DIM = 4 # Policy output dimensionality (for quadrotors) +float32[4] previous_action # [@range -1, 1] Previous action. Motor commands normalized to [-1, 1] + +# TOPICS raptor_input diff --git a/msg/versioned/RaptorStatus.msg b/msg/versioned/RaptorStatus.msg new file mode 100644 index 0000000000..25801a0020 --- /dev/null +++ b/msg/versioned/RaptorStatus.msg @@ -0,0 +1,46 @@ +# Raptor Status + +# Diagnostic messages for the Raptor foundation policy. +# This diagnostic data is useful for debugging (e.g. identifying missing input information). + +uint32 MESSAGE_VERSION = 0 + +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Sampling timestamp of the data this control response is based on +bool subscription_update_angular_velocity # [bool] Flag signalling if the vehicle_angular_velocity was updated +bool subscription_update_local_position # [bool] Flag signalling if the vehicle_local_position was updated +bool subscription_update_attitude # [bool] Flag signalling if the vehicle_attitude was updated +bool subscription_update_trajectory_setpoint # [bool] Flag signalling if the trajectory_setpoint was updated +bool subscription_update_vehicle_status # [bool] Flag signalling if the vehicle_status was updated + +uint8 exit_reason # [enum] Exit reason identifier. Representing conditions that lead to the Raptor policy not being executed +uint8 EXIT_REASON_NONE = 0 # No exit reason => Raptor control step was executed (actuator_motors should have been published) +uint8 EXIT_REASON_NO_ANGULAR_VELOCITY_UPDATE = 1 # We synchronize the control onto the input observation with the highest update frequency, which is vehicle_angular_velocity. If there was no update, we do not need to execute the policy again +uint8 EXIT_REASON_NOT_ALL_OBSERVATIONS_SET = 2 # We can not execute the policy if not all observations are available +uint8 EXIT_REASON_ANGULAR_VELOCITY_STALE = 3 # If OBSERVATION_TIMEOUT_ANGULAR_VELOCITY is exceeded, we treat the vehicle_angular_velocity as stale and can not run the policy +uint8 EXIT_REASON_LOCAL_POSITION_STALE = 4 # If OBSERVATION_TIMEOUT_LOCAL_POSITION is exceeded, we treat the vehicle_local_position as stale and can not run the policy +uint8 EXIT_REASON_ATTITUDE_STALE = 5 # If OBSERVATION_TIMEOUT_ATTITUDE is exceeded, we treat the vehicle_attitude as stale and can not run the policy +uint8 EXIT_REASON_EXECUTOR_STATUS_SOURCE_NOT_CONTROL = 6 # The executor that runs the policy can run in oversampling mode, where it decides if the policy should be ran based on the timestamp and not based on fixed synchronization onto the vehicle_angular_velocity. In this case the executor can decide to skip running the policy if the interval is too small, in which case this flag is set. + +uint32 timestamp_last_vehicle_angular_velocity # [us] Timestamp of the last received vehicle_angular_velocity message +uint32 timestamp_last_vehicle_local_position # [us] Timestamp of the last received vehicle_local_position message +uint32 timestamp_last_vehicle_attitude # [us] Timestamp of the last received vehicle_attitude message +uint32 timestamp_last_trajectory_setpoint # [us] Timestamp of the last received trajectory_setpoint message + +bool vehicle_angular_velocity_stale # [bool] True if vehicle_angular_velocity data is considered stale (exceeded timeout) +bool vehicle_local_position_stale # [bool] True if vehicle_local_position data is considered stale (exceeded timeout) +bool vehicle_attitude_stale # [bool] True if vehicle_attitude data is considered stale (exceeded timeout) +bool trajectory_setpoint_stale # [bool] True if trajectory_setpoint data is considered stale (exceeded timeout) + +bool active # [bool] True if the Raptor policy is currently active (publishing actuator_motors) +uint8 substep # [-] The policy is trained at a fixed frequency (e.g. 100 Hz) but we might want to use it for control at higher frequencies (e.g. 400 Hz), which leads to a number of intermediate steps before the actual policy state is advanced (in this case 4 = 400 Hz / 100 Hz). This field provides the current substep (e.g. 0-3). +float32 control_interval # [s] Time interval between control updates + +float32 trajectory_setpoint_dt_mean # [us] The average trajectory setpoint arrival time interval (since Raptor mode activation within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) +float32 trajectory_setpoint_dt_max # [us] The max trajectory setpoint arrival time interval (since Raptor mode activation and within NUM_TRAJECTORY_SETPOINT_DTS received trajectory_setpoint messages) +float32 trajectory_setpoint_dt_max_since_activation # [us] The max trajectory setpoint arrival time interval (since Raptor mode activation) + +float32[3] internal_reference_position # [m] [@frame FLU] Internal reference position +float32[3] internal_reference_linear_velocity # [m/s] [@frame FLU] Internal reference linear velocity + +# TOPICS raptor_status diff --git a/msg/versioned/RegisterExtComponentReply.msg b/msg/versioned/RegisterExtComponentReply.msg index 4495bcdb90..17ff6765c9 100644 --- a/msg/versioned/RegisterExtComponentReply.msg +++ b/msg/versioned/RegisterExtComponentReply.msg @@ -1,4 +1,4 @@ -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -12,4 +12,6 @@ int8 arming_check_id # arming check registration ID (-1 if invalid) int8 mode_id # assigned mode ID (-1 if invalid) int8 mode_executor_id # assigned mode executor ID (-1 if invalid) +bool not_user_selectable # mode cannot be selected by the user + uint8 ORB_QUEUE_LENGTH = 2 diff --git a/msg/versioned/RegisterExtComponentRequest.msg b/msg/versioned/RegisterExtComponentRequest.msg index b0798705ca..3b76aef15e 100644 --- a/msg/versioned/RegisterExtComponentRequest.msg +++ b/msg/versioned/RegisterExtComponentRequest.msg @@ -1,6 +1,6 @@ # Request to register an external component -uint32 MESSAGE_VERSION = 0 +uint32 MESSAGE_VERSION = 1 uint64 timestamp # time since system start (microseconds) @@ -19,6 +19,6 @@ bool register_mode_executor # registering an executor also requires a mod bool enable_replace_internal_mode # set to true if an internal mode should be replaced uint8 replace_internal_mode # vehicle_status::NAVIGATION_STATE_* bool activate_mode_immediately # switch to the registered mode (can only be set in combination with an executor) - +bool not_user_selectable # mode cannot be selected by the user uint8 ORB_QUEUE_LENGTH = 2 diff --git a/msg/versioned/VehicleCommand.msg b/msg/versioned/VehicleCommand.msg index 80cb791b89..9a123a8e5c 100644 --- a/msg/versioned/VehicleCommand.msg +++ b/msg/versioned/VehicleCommand.msg @@ -20,7 +20,7 @@ uint16 VEHICLE_CMD_DO_ORBIT = 34 # Start orbiting on the circumference of a circ uint16 VEHICLE_CMD_DO_FIGUREEIGHT = 35 # Start flying on the outline of a figure eight defined by the parameters. |[m] Major radius|[m] Minor radius|[m/s] Velocity|Orientation|Latitude/X|Longitude/Y|Altitude/Z| uint16 VEHICLE_CMD_NAV_ROI = 80 # Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras. |[@enum VEHICLE_ROI] Region of interest mode.|MISSION index/ target ID.|ROI index (allows a vehicle to manage multiple ROI's)|Unused|x the location of the fixed ROI (see MAV_FRAME)|y|z| uint16 VEHICLE_CMD_NAV_PATHPLANNING = 81 # Control autonomous path planning on the MAV. |0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning|0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid|Unused|[deg] [@range 0, 360] Yaw angle at goal, in compass degrees|Latitude/X of goal|Longitude/Y of goal|Altitude/Z of goal| -uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Unused|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| +uint16 VEHICLE_CMD_NAV_VTOL_TAKEOFF = 84 # Takeoff from ground / hand and transition to fixed wing. |Minimum pitch (if airspeed sensor present), desired pitch without sensor|Transition heading, 0: Default, 3: Use specified transition heading|Unused|Yaw angle (if magnetometer present), ignored without magnetometer|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_VTOL_LAND = 85 # Transition to MC and land at location. |Unused|Unused|Unused|Desired yaw angle.|Latitude|Longitude|Altitude| uint16 VEHICLE_CMD_NAV_GUIDED_LIMITS = 90 # Set limits for external control. |[s] Timeout - maximum time that external controller will be allowed to control vehicle. 0 means no timeout|[m] Absolute altitude min AMSL - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit|[m] Absolute altitude max - if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit|[m] Horizontal move limit (AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit|Unused|Unused|Unused| uint16 VEHICLE_CMD_NAV_GUIDED_MASTER = 91 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -61,6 +61,7 @@ uint16 VEHICLE_CMD_DO_PARACHUTE=208 # Mission command to trigger a parachute. |a uint16 VEHICLE_CMD_DO_MOTOR_TEST=209 # Motor test command. |Instance (@range 1, )|throttle type|throttle|timeout [s]|Motor count|Test order|Unused| uint16 VEHICLE_CMD_DO_INVERTED_FLIGHT=210 # Change to/from inverted flight. |inverted (0=normal, 1=inverted)|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GRIPPER = 211 # Command to operate a gripper. +uint16 VEHICLE_CMD_DO_AUTOTUNE_ENABLE = 212 # Enable autotune module. |1 to enable|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_SET_CAM_TRIGG_INTERVAL=214 # Mission command to set TRIG_INTERVAL for this flight. |[m] Camera trigger distance|Shutter integration time (ms)|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_MOUNT_CONTROL_QUAT=220 # Mission command to control a camera or antenna mount, using a quaternion as reference. |q1 - quaternion param #1, w (1 in null-rotation)|q2 - quaternion param #2, x (0 in null-rotation)|q3 - quaternion param #3, y (0 in null-rotation)|q4 - quaternion param #4, z (0 in null-rotation)|Unused|Unused|Unused| uint16 VEHICLE_CMD_DO_GUIDED_MASTER=221 # Set id of master controller. |System ID|Component ID|Unused|Unused|Unused|Unused|Unused| @@ -88,6 +89,7 @@ uint16 VEHICLE_CMD_REQUEST_CAMERA_INFORMATION = 521 # Request camera information uint16 VEHICLE_CMD_SET_CAMERA_MODE = 530 # Set camera capture mode (photo, video, etc.). uint16 VEHICLE_CMD_SET_CAMERA_ZOOM = 531 # Set camera zoom. uint16 VEHICLE_CMD_SET_CAMERA_FOCUS = 532 +uint16 VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE = 620 # Set an external estimate of vehicle attitude in degrees. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW = 1000 # Setpoint to be sent to a gimbal manager to set a gimbal pitch and yaw. uint16 VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE = 1001 # Gimbal configuration to set which sysid/compid is in primary and secondary control. uint16 VEHICLE_CMD_IMAGE_START_CAPTURE = 2000 # Start image capture sequence. @@ -98,6 +100,7 @@ uint16 VEHICLE_CMD_LOGGING_START = 2510 # Start streaming ULog data. uint16 VEHICLE_CMD_LOGGING_STOP = 2511 # Stop streaming ULog data. uint16 VEHICLE_CMD_CONTROL_HIGH_LATENCY = 2600 # Control starting/stopping transmitting data over the high latency link. uint16 VEHICLE_CMD_DO_VTOL_TRANSITION = 3000 # Command VTOL transition. +uint16 VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE = 5300 # Command safety on/off. |1 to activate safety, 0 to deactivate safety and allow control surface movements|Unused|Unused|Unused|Unused|Unused|Unused| uint16 VEHICLE_CMD_ARM_AUTHORIZATION_REQUEST = 3001 # Request arm authorization. uint16 VEHICLE_CMD_PAYLOAD_PREPARE_DEPLOY = 30001 # Prepare a payload deployment in the flight plan. uint16 VEHICLE_CMD_PAYLOAD_CONTROL_DEPLOY = 30002 # Control a pre-programmed payload deployment. @@ -178,6 +181,10 @@ int8 ARMING_ACTION_ARM = 1 uint8 GRIPPER_ACTION_RELEASE = 0 uint8 GRIPPER_ACTION_GRAB = 1 +# Used as param1 in DO_SET_SAFETY_SWITCH_STATE command. +uint8 SAFETY_OFF = 0 +uint8 SAFETY_ON = 1 + uint8 ORB_QUEUE_LENGTH = 8 float32 param1 # Parameter 1, as defined by MAVLink uint16 VEHICLE_CMD enum. diff --git a/msg/versioned/VehicleCommandAck.msg b/msg/versioned/VehicleCommandAck.msg index c11a5f8c5d..c3f679bfbc 100644 --- a/msg/versioned/VehicleCommandAck.msg +++ b/msg/versioned/VehicleCommandAck.msg @@ -23,7 +23,7 @@ uint16 ARM_AUTH_DENIED_REASON_TIMEOUT = 3 uint16 ARM_AUTH_DENIED_REASON_AIRSPACE_IN_USE = 4 uint16 ARM_AUTH_DENIED_REASON_BAD_WEATHER = 5 -uint8 ORB_QUEUE_LENGTH = 4 +uint8 ORB_QUEUE_LENGTH = 8 uint32 command # Command that is being acknowledged uint8 result # Command result diff --git a/msg/versioned/VehicleOdometry.msg b/msg/versioned/VehicleOdometry.msg index f4d600d2b8..cf117ff82c 100644 --- a/msg/versioned/VehicleOdometry.msg +++ b/msg/versioned/VehicleOdometry.msg @@ -1,34 +1,35 @@ -# Vehicle odometry data. Fits ROS REP 147 for aerial vehicles +# Vehicle odometry data +# +# Fits ROS REP 147 for aerial vehicles uint32 MESSAGE_VERSION = 0 -uint64 timestamp # time since system start (microseconds) -uint64 timestamp_sample +uint64 timestamp # [us] Time since system start +uint64 timestamp_sample # [us] Timestamp sample -uint8 POSE_FRAME_UNKNOWN = 0 -uint8 POSE_FRAME_NED = 1 # NED earth-fixed frame -uint8 POSE_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 pose_frame # Position and orientation frame of reference +uint8 pose_frame # [@enum POSE_FRAME] Position and orientation frame of reference +uint8 POSE_FRAME_UNKNOWN = 0 # Unknown frame +uint8 POSE_FRAME_NED = 1 # North-East-Down (NED) navigation frame. Aligned with True North. +uint8 POSE_FRAME_FRD = 2 # Forward-Right-Down (FRD) frame. Constant arbitrary heading offset from True North. Z is down. -float32[3] position # Position in meters. Frame of reference defined by local_frame. NaN if invalid/unknown -float32[4] q # Quaternion rotation from FRD body frame to reference frame. First value NaN if invalid/unknown +float32[3] position # [m] [@frame local frame] [@invalid NaN If invalid/unknown] Position. Origin is position of GC at startup. +float32[4] q # [-] [@invalid NaN First value if invalid/unknown] Attitude (expressed as a quaternion) relative to pose reference frame at current location. Follows the Hamiltonian convention (w, x, y, z, right-handed, passive rotations from body to world) -uint8 VELOCITY_FRAME_UNKNOWN = 0 -uint8 VELOCITY_FRAME_NED = 1 # NED earth-fixed frame -uint8 VELOCITY_FRAME_FRD = 2 # FRD world-fixed frame, arbitrary heading reference -uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -uint8 velocity_frame # Reference frame of the velocity data +uint8 velocity_frame # [@enum VELOCITY_FRAME] Reference frame of the velocity data +uint8 VELOCITY_FRAME_UNKNOWN = 0 # Unknown frame +uint8 VELOCITY_FRAME_NED = 1 # NED navigation frame at current position. +uint8 VELOCITY_FRAME_FRD = 2 # FRD navigation frame at current position. Constant arbitrary heading offset from True North. Z is down. +uint8 VELOCITY_FRAME_BODY_FRD = 3 # FRD body-fixed frame -float32[3] velocity # Velocity in meters/sec. Frame of reference defined by velocity_frame variable. NaN if invalid/unknown +float32[3] velocity # [m/s] [@frame @velocity_frame] [@invalid NaN If invalid/unknown] Velocity. +float32[3] angular_velocity # [rad/s] [@frame @VELOCITY_FRAME_BODY_FRD] [@invalid NaN If invalid/unknown] Angular velocity in body-fixed frame -float32[3] angular_velocity # Angular velocity in body-fixed frame (rad/s). NaN if invalid/unknown +float32[3] position_variance # [m^2] Variance of position error +float32[3] orientation_variance # [rad^2] Variance of orientation/attitude error (expressed in body frame) +float32[3] velocity_variance # [m^2/s^2] Variance of velocity error -float32[3] position_variance -float32[3] orientation_variance -float32[3] velocity_variance - -uint8 reset_counter -int8 quality +uint8 reset_counter # [-] Reset counter. Counts reset events on attitude, velocity and position. +int8 quality # [-] [@invalid 0] Quality. Unused. # TOPICS vehicle_odometry vehicle_mocap_odometry vehicle_visual_odometry # TOPICS estimator_odometry diff --git a/msg/versioned/VehicleStatus.msg b/msg/versioned/VehicleStatus.msg index f433d564e9..185076a5d6 100644 --- a/msg/versioned/VehicleStatus.msg +++ b/msg/versioned/VehicleStatus.msg @@ -13,20 +13,16 @@ uint8 ARMING_STATE_ARMED = 2 uint8 latest_arming_reason uint8 latest_disarming_reason -uint8 ARM_DISARM_REASON_TRANSITION_TO_STANDBY = 0 uint8 ARM_DISARM_REASON_STICK_GESTURE = 1 uint8 ARM_DISARM_REASON_RC_SWITCH = 2 uint8 ARM_DISARM_REASON_COMMAND_INTERNAL = 3 uint8 ARM_DISARM_REASON_COMMAND_EXTERNAL = 4 uint8 ARM_DISARM_REASON_MISSION_START = 5 -uint8 ARM_DISARM_REASON_SAFETY_BUTTON = 6 -uint8 ARM_DISARM_REASON_AUTO_DISARM_LAND = 7 -uint8 ARM_DISARM_REASON_AUTO_DISARM_PREFLIGHT = 8 -uint8 ARM_DISARM_REASON_KILL_SWITCH = 9 -uint8 ARM_DISARM_REASON_LOCKDOWN = 10 -uint8 ARM_DISARM_REASON_FAILURE_DETECTOR = 11 -uint8 ARM_DISARM_REASON_SHUTDOWN = 12 -uint8 ARM_DISARM_REASON_UNIT_TEST = 13 +uint8 ARM_DISARM_REASON_LANDING = 6 +uint8 ARM_DISARM_REASON_PREFLIGHT_INACTION = 7 +uint8 ARM_DISARM_REASON_KILL_SWITCH = 8 +uint8 ARM_DISARM_REASON_RC_BUTTON = 13 +uint8 ARM_DISARM_REASON_FAILSAFE = 14 uint64 nav_state_timestamp # time when current nav_state activated @@ -41,7 +37,7 @@ uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode uint8 NAVIGATION_STATE_POSITION_SLOW = 6 uint8 NAVIGATION_STATE_FREE5 = 7 -uint8 NAVIGATION_STATE_FREE4 = 8 +uint8 NAVIGATION_STATE_ALTITUDE_CRUISE = 8 # Altitude with Cruise mode uint8 NAVIGATION_STATE_FREE3 = 9 uint8 NAVIGATION_STATE_ACRO = 10 # Acro mode uint8 NAVIGATION_STATE_FREE2 = 11 diff --git a/platforms/common/Serial.cpp b/platforms/common/Serial.cpp index 88a29667c8..a129fe2492 100644 --- a/platforms/common/Serial.cpp +++ b/platforms/common/Serial.cpp @@ -74,6 +74,11 @@ ssize_t Serial::bytesAvailable() return _impl.bytesAvailable(); } +ssize_t Serial::txSpaceAvailable() +{ + return _impl.txSpaceAvailable(); +} + ssize_t Serial::read(uint8_t *buffer, size_t buffer_size) { return _impl.read(buffer, buffer_size); @@ -89,6 +94,11 @@ ssize_t Serial::write(const void *buffer, size_t buffer_size) return _impl.write(buffer, buffer_size); } +ssize_t Serial::writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_ms) +{ + return _impl.writeBlocking(buffer, buffer_size, timeout_ms); +} + void Serial::flush() { return _impl.flush(); diff --git a/platforms/common/apps.cpp.in b/platforms/common/apps.cpp.in index 11d1c50d9f..36c3ce6bdb 100644 --- a/platforms/common/apps.cpp.in +++ b/platforms/common/apps.cpp.in @@ -2,6 +2,7 @@ #include #include #include +#include #include "apps.h" @@ -43,6 +44,7 @@ void list_builtins(apps_map_type &apps) int shutdown_main(int argc, char *argv[]) { printf("Exiting NOW.\n"); + uorb_shutdown(); system_exit(0); } diff --git a/platforms/common/include/px4_platform_common/Serial.hpp b/platforms/common/include/px4_platform_common/Serial.hpp index cad568d134..bf14035a5e 100644 --- a/platforms/common/include/px4_platform_common/Serial.hpp +++ b/platforms/common/include/px4_platform_common/Serial.hpp @@ -62,10 +62,12 @@ public: bool close(); ssize_t bytesAvailable(); + ssize_t txSpaceAvailable(); ssize_t read(uint8_t *buffer, size_t buffer_size); ssize_t readAtLeast(uint8_t *buffer, size_t buffer_size, size_t character_count = 1, uint32_t timeout_ms = 0); ssize_t write(const void *buffer, size_t buffer_size); + ssize_t writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_ms = 0); void flush(); diff --git a/platforms/common/include/px4_platform_common/board_common.h b/platforms/common/include/px4_platform_common/board_common.h index 4b9678afd6..1056d721b9 100644 --- a/platforms/common/include/px4_platform_common/board_common.h +++ b/platforms/common/include/px4_platform_common/board_common.h @@ -157,8 +157,13 @@ #if BOARD_NUMBER_BRICKS == 0 /* allow SITL to disable all bricks */ #elif BOARD_NUMBER_BRICKS == 1 -# define BOARD_BATT_V_LIST {ADC_BATTERY_VOLTAGE_CHANNEL} -# define BOARD_BATT_I_LIST {ADC_BATTERY_CURRENT_CHANNEL} +# if defined(BOARD_NUMBER_DIGITAL_BRICKS) +# define BOARD_BATT_V_LIST {-1} +# define BOARD_BATT_I_LIST {-1} +# else +# define BOARD_BATT_V_LIST {ADC_BATTERY_VOLTAGE_CHANNEL} +# define BOARD_BATT_I_LIST {ADC_BATTERY_CURRENT_CHANNEL} +# endif # define BOARD_BRICK_VALID_LIST {BOARD_ADC_BRICK_VALID} #elif BOARD_NUMBER_BRICKS == 2 # if defined(BOARD_NUMBER_DIGITAL_BRICKS) @@ -173,10 +178,6 @@ # define BOARD_BATT_V_LIST {ADC_BATTERY1_VOLTAGE_CHANNEL, ADC_BATTERY2_VOLTAGE_CHANNEL, ADC_BATTERY3_VOLTAGE_CHANNEL} # define BOARD_BATT_I_LIST {ADC_BATTERY1_CURRENT_CHANNEL, ADC_BATTERY2_CURRENT_CHANNEL, ADC_BATTERY3_CURRENT_CHANNEL} # define BOARD_BRICK_VALID_LIST {BOARD_ADC_BRICK1_VALID, BOARD_ADC_BRICK2_VALID, BOARD_ADC_BRICK3_VALID} -#elif BOARD_NUMBER_BRICKS == 4 -# define BOARD_BATT_V_LIST {ADC_BATTERY1_VOLTAGE_CHANNEL, ADC_BATTERY2_VOLTAGE_CHANNEL, ADC_BATTERY3_VOLTAGE_CHANNEL, ADC_BATTERY4_VOLTAGE_CHANNEL} -# define BOARD_BATT_I_LIST {ADC_BATTERY1_CURRENT_CHANNEL, ADC_BATTERY2_CURRENT_CHANNEL, ADC_BATTERY3_CURRENT_CHANNEL, ADC_BATTERY4_CURRENT_CHANNEL} -# define BOARD_BRICK_VALID_LIST {BOARD_ADC_BRICK1_VALID, BOARD_ADC_BRICK2_VALID, BOARD_ADC_BRICK3_VALID, BOARD_ADC_BRICK4_VALID} #else # error Unsuported BOARD_NUMBER_BRICKS number. #endif diff --git a/platforms/common/pab_manifest.c b/platforms/common/pab_manifest.c index 5e0cee9a30..c6560d6803 100644 --- a/platforms/common/pab_manifest.c +++ b/platforms/common/pab_manifest.c @@ -402,6 +402,52 @@ static const px4_hw_mft_item_t base_configuration_18[] = { }, }; +// BASE ID 19 Auterion Skynode N +static const px4_hw_mft_item_t base_configuration_19[] = { + { + .id = PX4_MFT_PX4IO, + .present = 0, + .mandatory = 0, + .connection = px4_hw_con_unknown, + }, + { + .id = PX4_MFT_USB, + .present = 0, + .mandatory = 0, + .connection = px4_hw_con_unknown, + }, + { + .id = PX4_MFT_CAN2, + .present = 1, + .mandatory = 1, + .connection = px4_hw_con_onboard, + }, + { + .id = PX4_MFT_CAN3, + .present = 0, + .mandatory = 0, + .connection = px4_hw_con_unknown, + }, + { + .id = PX4_MFT_PM2, + .present = 0, + .mandatory = 0, + .connection = px4_hw_con_unknown, + }, + { + .id = PX4_MFT_ETHERNET, + .present = 1, + .mandatory = 1, + .connection = px4_hw_con_onboard, + }, + { + .id = PX4_MFT_T100_ETH, + .present = 1, + .mandatory = 1, + .connection = px4_hw_con_onboard, + }, +}; + // BASE ID 0x100 Holybro Pixhawk Jetson Baseboard Alaised to ID 0 // BASE ID 0x150 ZeroOne Pixhawk Baseboard Alaised to ID 0 // BASE ID 0x200 AmovLab Pixhawk Baseboard Alaised to ID 0 @@ -419,6 +465,7 @@ static px4_hw_mft_list_entry_t mft_lists[] = { {HW_BASE_ID(16), base_configuration_0, arraySize(base_configuration_0)}, // Auterion Skynode ver 16 {HW_BASE_ID(17), base_configuration_17, arraySize(base_configuration_17)}, // Auterion Skynode ver 17 {HW_BASE_ID(18), base_configuration_18, arraySize(base_configuration_18)}, // Auterion Skynode S ver 18 + {HW_BASE_ID(19), base_configuration_19, arraySize(base_configuration_19)}, // Auterion Skynode N {HW_BASE_ID(0x100), base_configuration_0, arraySize(base_configuration_0)}, // Holybro Pixhawk Jetson Baseboard ver 0x100 Alaised to ID 0 {HW_BASE_ID(0x150), base_configuration_0, arraySize(base_configuration_0)}, // ZeroOne Pixhawk Baseboard ver 0x150 {HW_BASE_ID(0x200), base_configuration_0, arraySize(base_configuration_0)}, // AmovLab Pixhawk Baseboard ver 0x150 diff --git a/platforms/common/shutdown.cpp b/platforms/common/shutdown.cpp index 878d99c62e..d1be7ff5a1 100644 --- a/platforms/common/shutdown.cpp +++ b/platforms/common/shutdown.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -173,6 +174,8 @@ static void shutdown_worker(void *arg) const bool delay_elapsed = (now > shutdown_time_us); if (delay_elapsed && ((done && shutdown_lock_counter == 0) || (now > (shutdown_time_us + shutdown_timeout_us)))) { + uorb_shutdown(); + if (shutdown_args & SHUTDOWN_ARG_REBOOT) { #if defined(CONFIG_BOARDCTL_RESET) PX4_INFO_RAW("Reboot NOW."); diff --git a/platforms/common/uORB/uORB.cpp b/platforms/common/uORB/uORB.cpp index a68f3c5dc8..dd08a8e067 100644 --- a/platforms/common/uORB/uORB.cpp +++ b/platforms/common/uORB/uORB.cpp @@ -51,6 +51,7 @@ #include #endif + static uORB::DeviceMaster *g_dev = nullptr; int uorb_start(void) @@ -113,6 +114,18 @@ int uorb_top(char **topic_filter, int num_filters) return OK; } +void uorb_shutdown(void) +{ +#ifdef CONFIG_ORB_COMMUNICATOR + uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + + if (ch) { + ch->shutdown(); + } + +#endif /* CONFIG_ORB_COMMUNICATOR */ +} + orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data) { return uORB::Manager::get_instance()->orb_advertise(meta, data); diff --git a/platforms/common/uORB/uORB.h b/platforms/common/uORB/uORB.h index ee11923b59..bfdf46fab8 100644 --- a/platforms/common/uORB/uORB.h +++ b/platforms/common/uORB/uORB.h @@ -121,6 +121,7 @@ __BEGIN_DECLS int uorb_start(void); int uorb_status(void); int uorb_top(char **topic_filter, int num_filters); +void uorb_shutdown(void); /** * ORB topic advertiser handle. diff --git a/platforms/common/uORB/uORBCommunicator.hpp b/platforms/common/uORB/uORBCommunicator.hpp index 8122b34780..64706f29bf 100644 --- a/platforms/common/uORB/uORBCommunicator.hpp +++ b/platforms/common/uORB/uORBCommunicator.hpp @@ -129,6 +129,22 @@ public: virtual int16_t send_message(const char *messageName, int32_t length, uint8_t *data) = 0; + + //========================================================================= + // INTERFACES FOR Lifecycle messages + //========================================================================= + + /** + * @brief Interface to notify the remote entity of a shutdown. + * + * @return + * 0 = success; This means the shutdown is successfully sent to the receiver + * Note: This does not mean that the receiver has received it. + * otherwise = failure. + */ + + virtual int16_t shutdown() { return 0; } + }; /** diff --git a/platforms/nuttx/CMakeLists.txt b/platforms/nuttx/CMakeLists.txt index 4bee8ed581..304273d05f 100644 --- a/platforms/nuttx/CMakeLists.txt +++ b/platforms/nuttx/CMakeLists.txt @@ -507,6 +507,9 @@ if(NOT NUTTX_DIR MATCHES "external") if(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) set(DEBUG_DEVICE "MIMXRT1062XXX6A") set(DEBUG_SVD_FILE "MIMXRT1062.xml") + elseif(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A) + set(DEBUG_DEVICE "MIMXRT1064XXX6A") + set(DEBUG_SVD_FILE "MIMXRT1064.xml") elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) set(DEBUG_DEVICE "MIMXRT1176DVMAA") set(DEBUG_SVD_FILE "MIMXRT1176_cm7.xml") @@ -595,6 +598,7 @@ if(NOT NUTTX_DIR MATCHES "external") add_custom_target(jlink-nuttx ALL DEPENDS ${NUTTX_DIR}/tools/jlink-nuttx.so ) + add_dependencies(jlink-nuttx nuttx_context) # JLINK_RTOS_PATH used by launch.json.in set(JLINK_RTOS_PATH ${NUTTX_DIR}/tools/jlink-nuttx.so) diff --git a/platforms/nuttx/NuttX/nuttx b/platforms/nuttx/NuttX/nuttx index b0b49a2106..f34ff89edf 160000 --- a/platforms/nuttx/NuttX/nuttx +++ b/platforms/nuttx/NuttX/nuttx @@ -1 +1 @@ -Subproject commit b0b49a210696dd0074dff9531fd1603afb0cc2e4 +Subproject commit f34ff89edf9764fdd177f3faa616d85ebf2778f2 diff --git a/platforms/nuttx/cmake/px4_impl_os.cmake b/platforms/nuttx/cmake/px4_impl_os.cmake index cefa37a6c2..98be37ff3f 100644 --- a/platforms/nuttx/cmake/px4_impl_os.cmake +++ b/platforms/nuttx/cmake/px4_impl_os.cmake @@ -158,6 +158,9 @@ function(px4_os_determine_build_chip) elseif(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) set(CHIP_MANUFACTURER "nxp") set(CHIP "rt106x") + elseif(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A) + set(CHIP_MANUFACTURER "nxp") + set(CHIP "rt106x") elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA) set(CHIP_MANUFACTURER "nxp") set(CHIP "rt117x") diff --git a/platforms/nuttx/cmake/upload.cmake b/platforms/nuttx/cmake/upload.cmake index 83f623c090..3bffd08535 100644 --- a/platforms/nuttx/cmake/upload.cmake +++ b/platforms/nuttx/cmake/upload.cmake @@ -31,69 +31,32 @@ # ############################################################################ -# NuttX CDCACM vendor and product strings -set(vendorstr_underscore) -set(productstr_underscore) -string(REPLACE " " "_" vendorstr_underscore ${CONFIG_CDCACM_VENDORSTR}) -string(REPLACE "," "_" vendorstr_underscore "${vendorstr_underscore}") -string(REPLACE " " "_" productstr_underscore ${CONFIG_CDCACM_PRODUCTSTR}) - -set(serial_ports) -if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") - - set(px4_usb_path "${vendorstr_underscore}_${productstr_underscore}") - set(px4_bl_usb_path "${vendorstr_underscore}_BL") - - list(APPEND serial_ports - # NuttX vendor + product string - /dev/serial/by-id/*-${px4_usb_path}* - - # Bootloader - /dev/serial/by-id/*_${px4_bl_usb_path}* - /dev/serial/by-id/*PX4_BL* # typical bootloader USB device string - /dev/serial/by-id/*BL_FMU* - - # TODO: handle these per board - /dev/serial/by-id/usb-The_Autopilot* - /dev/serial/by-id/usb-Bitcraze* - /dev/serial/by-id/pci-Bitcraze* - /dev/serial/by-id/usb-Gumstix* - /dev/serial/by-id/usb-Hex_ProfiCNC* - /dev/serial/by-id/usb-UVify* - /dev/serial/by-id/usb-ArduPilot* - ) - -elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") - list(APPEND serial_ports - /dev/tty.usbmodemPX*,/dev/tty.usbmodem* - ) -elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "CYGWIN") - list(APPEND serial_ports - /dev/ttyS* - ) -elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") - foreach(port RANGE 32 0) - list(APPEND serial_ports - "COM${port}") - endforeach() -endif() - -string(REPLACE ";" "," serial_ports "${serial_ports}") +# Uploader script auto-detects PX4 devices by USB VID/PID +set(PX4_UPLOADER_SCRIPT "${PX4_SOURCE_DIR}/Tools/px4_uploader.py") add_custom_target(upload - COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_uploader.py --port ${serial_ports} ${fw_package} + COMMAND ${PYTHON_EXECUTABLE} ${PX4_UPLOADER_SCRIPT} ${fw_package} DEPENDS ${fw_package} COMMENT "uploading px4" VERBATIM USES_TERMINAL WORKING_DIRECTORY ${PX4_BINARY_DIR} - ) +) add_custom_target(force-upload - COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_uploader.py --force --port ${serial_ports} ${fw_package} + COMMAND ${PYTHON_EXECUTABLE} ${PX4_UPLOADER_SCRIPT} --force ${fw_package} DEPENDS ${fw_package} COMMENT "uploading px4 with --force" VERBATIM USES_TERMINAL WORKING_DIRECTORY ${PX4_BINARY_DIR} - ) +) + +add_custom_target(upload-verbose + COMMAND ${PYTHON_EXECUTABLE} ${PX4_UPLOADER_SCRIPT} --verbose ${fw_package} + DEPENDS ${fw_package} + COMMENT "uploading px4 with verbose output" + VERBATIM + USES_TERMINAL + WORKING_DIRECTORY ${PX4_BINARY_DIR} +) diff --git a/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c b/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c index dcdc50a911..a137c8477b 100644 --- a/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c +++ b/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c @@ -9,9 +9,19 @@ #include "hw_config.h" #include #include -#include -#include -#include +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x +# include +# include +# include +#else +# include +# include +# include +# include +# include "hardware/imxrt_ccm.h" +# include "imxrt_periphclks.h" +# define SNVS_LPCR_GPR_Z_DIS (1 << 24) /* Bit 24: General Purpose Registers Zeroization Disable */ +#endif #include #include "imxrt_clockconfig.h" @@ -30,14 +40,31 @@ #define APP_SIZE_MAX (BOARD_FLASH_SIZE - (BOOTLOADER_RESERVATION_SIZE + APP_RESERVATION_SIZE)) +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x #define CHIP_TAG "i.MX RT11?0,r??" -#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1 - #define SI_REV(n) ((n & 0x7000000) >> 24) #define DIFPROG_TYPE(n) ((n & 0xF000) >> 12) #define DIFPROG_REV_MAJOR(n) ((n & 0xF0) >> 4) #define DIFPROG_REV_MINOR(n) ((n & 0xF)) +#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x) +#define CHIP_TAG "i.MX RT10?? r?.?" +#define DIGPROG_MINOR_SHIFT 0 +#define DIGPROG_MINOR_MASK (0xff << DIGPROG_MINOR_SHIFT) +#define DIGPROG_MINOR(info) (((info) & DIGPROG_MINOR_MASK) >> DIGPROG_MINOR_SHIFT) +#define DIGPROG_MAJOR_LOWER_SHIFT 8 +#define DIGPROG_MAJOR_LOWER_MASK (0xff << DIGPROG_MAJOR_LOWER_SHIFT) +#define DIGPROG_MAJOR_LOWER(info) (((info) & DIGPROG_MAJOR_LOWER_MASK) >> DIGPROG_MAJOR_LOWER_SHIFT) +#define DIGPROG_MAJOR_UPPER_SHIFT 16 +#define DIGPROG_MAJOR_UPPER_MASK (0xff << DIGPROG_MAJOR_UPPER_SHIFT) +#define DIGPROG_MAJOR_UPPER(info) (((info) & DIGPROG_MAJOR_UPPER_MASK) >> DIGPROG_MAJOR_UPPER_SHIFT) +#endif +#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1 +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x +#define FLASH_BASE IMXRT_FLEXSPI1_CIPHER_BASE +#elif defined(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A) +#define FLASH_BASE IMXRT_FLEX2CIPHER_BASE +#endif /* context passed to cinit */ #if INTERFACE_USART @@ -287,6 +314,27 @@ board_deinit(void) px4_arch_configgpio(MK_GPIO_INPUT(BOARD_PIN_LED_BOOTLOADER)); #endif +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x + + // Restore CCM registers to ROM state + putreg32(0x00000001, IMXRT_CCM_CACRR); + putreg32(0x000A8200, IMXRT_CCM_CBCDR); + putreg32(0x06490B03, IMXRT_CCM_CSCDR1); + putreg32(0x75AE8104, IMXRT_CCM_CBCMR); + putreg32(0x67930001, IMXRT_CCM_CSCMR1); + + imxrt_clockoff_lpuart3(); + imxrt_clockoff_usboh3(); + imxrt_clockoff_timer3(); + imxrt_clockoff_xbar1(); + imxrt_clockoff_xbar3(); + + up_disable_icache(); + up_disable_dcache(); + +#endif + +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x const uint32_t dnfw[] = { CCM_CR_M7, CCM_CR_BUS, @@ -309,6 +357,8 @@ board_deinit(void) putreg32(CCM_CR_CTRL_OFF, IMXRT_CCM_CR_CTRL(i)); } } + +#endif } inline void arch_systic_init(void) @@ -365,7 +415,7 @@ ssize_t arch_flash_write(uintptr_t address, const void *buffer, size_t buflen) j++; } - uintptr_t offset = ((uintptr_t) address) - IMXRT_FLEXSPI1_CIPHER_BASE; + uintptr_t offset = ((uintptr_t) address) - FLASH_BASE; volatile uint32_t status = ROM_FLEXSPI_NorFlash_ProgramPage(1, pConfig, offset, (const uint32_t *)buffer); up_invalidate_dcache((uintptr_t)address, @@ -400,7 +450,7 @@ flash_func_sector_size(unsigned sector) ssize_t up_progmem_ispageerased(unsigned sector) { const uint32_t bytes_per_sector = flash_func_sector_size(sector); - uint32_t *address = (uint32_t *)(IMXRT_FLEXSPI1_CIPHER_BASE + (sector * bytes_per_sector)); + uint32_t *address = (uint32_t *)(FLASH_BASE + (sector * bytes_per_sector)); const uint32_t uint32_per_sector = bytes_per_sector / sizeof(*address); int blank = 0; /* Assume it is Bank */ @@ -437,9 +487,9 @@ flash_func_erase_sector(unsigned sector, bool force) struct flexspi_nor_config_s *pConfig = &g_bootConfig; const uint32_t bytes_per_sector = flash_func_sector_size(sector); - uint32_t *address = (uint32_t *)(IMXRT_FLEXSPI1_CIPHER_BASE + (sector * bytes_per_sector)); + uint32_t *address = (uint32_t *)(FLASH_BASE + (sector * bytes_per_sector)); - uintptr_t offset = ((uintptr_t) address) - IMXRT_FLEXSPI1_CIPHER_BASE; + uintptr_t offset = ((uintptr_t) address) - FLASH_BASE; irqstate_t flags; flags = enter_critical_section(); volatile uint32_t status = ROM_FLEXSPI_NorFlash_Erase(1, pConfig, (uintptr_t) offset, bytes_per_sector); @@ -473,6 +523,8 @@ flash_func_read_otp(uintptr_t address) return 0; } +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x + uint32_t get_mcu_id(void) { // ??? is DEBUGMCU get able @@ -499,6 +551,36 @@ int get_mcu_desc(int max, uint8_t *revstr) return strp - revstr; } +#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x) + +uint32_t get_mcu_id(void) +{ + return getreg32(IMXRT_OCOTP_UNIQUE_ID_LSB); +} + +int get_mcu_desc(int max, uint8_t *revstr) +{ + uint32_t info = getreg32(IMXRT_USB_ANALOG_DIGPROG); + // CHIP_TAG "i.MX RT10?? r?.?" + static uint8_t chip[sizeof(CHIP_TAG) + 1] = CHIP_TAG; + chip[CHIP_TAG_LEN - 1] = '0' + DIGPROG_MINOR(info); + chip[CHIP_TAG_LEN - 3] = '1' + DIGPROG_MAJOR_LOWER(info); + chip[CHIP_TAG_LEN - 6] = getreg32(0x401F867C) == 0x10 ? '4' : '2'; + chip[CHIP_TAG_LEN - 7] = DIGPROG_MAJOR_UPPER(info) == 0x6a ? '5' : '6'; + + uint8_t *endp = &revstr[max - 1]; + uint8_t *strp = revstr; + uint8_t *des = chip; + + while (strp < endp && *des) { + *strp++ = *des++; + } + + return strp - revstr; +} + +#endif + int check_silicon(void) { @@ -717,6 +799,7 @@ bootloader_main(void) * Returns - 0 if connected. * ************************************************************************************/ +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x #undef IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT #define USB1_VBUS_DET_STAT_OFFSET 0xd0 #define IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT (IMXRT_USBPHY1_BASE + USB1_VBUS_DET_STAT_OFFSET) @@ -727,6 +810,17 @@ bootloader_main(void) try_boot = false; } +#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x) +#undef IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT +#define IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT (IMXRT_ANATOP_BASE + IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT_OFFSET) + + if ((getreg32(IMXRT_USB_ANALOG_USB1_VBUS_DETECT_STAT) & USB_ANALOG_USB_VBUS_DETECT_STAT_VBUS_VALID) != 0) { + usb_connected = true; + /* don't try booting before we set up the bootloader */ + try_boot = false; + } + +#endif #endif #if INTERFACE_USART diff --git a/platforms/nuttx/src/bootloader/nxp/rt106x/CMakeLists.txt b/platforms/nuttx/src/bootloader/nxp/rt106x/CMakeLists.txt new file mode 100644 index 0000000000..a1c9b593c9 --- /dev/null +++ b/platforms/nuttx/src/bootloader/nxp/rt106x/CMakeLists.txt @@ -0,0 +1,34 @@ +############################################################################ +# +# Copyright (c) 2023 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_subdirectory(../imxrt_common arch_bootloader) diff --git a/platforms/nuttx/src/canbootloader/uavcan/main.c b/platforms/nuttx/src/canbootloader/uavcan/main.c index db1f6691f9..015943f0e9 100644 --- a/platforms/nuttx/src/canbootloader/uavcan/main.c +++ b/platforms/nuttx/src/canbootloader/uavcan/main.c @@ -847,6 +847,8 @@ static flash_error_t file_read_and_program(const uavcan_Path_t *fw_path, uint8_t request.offset += length; bootloader.percentage_done = (request.offset / a_percent); + watchdog_pet(); + } while (request.offset < fw_image_size && length == sizeof(response.data) && flash_status == FLASH_OK); diff --git a/platforms/nuttx/src/px4/common/SerialImpl.cpp b/platforms/nuttx/src/px4/common/SerialImpl.cpp index cd9caa4982..9bee2ddf23 100644 --- a/platforms/nuttx/src/px4/common/SerialImpl.cpp +++ b/platforms/nuttx/src/px4/common/SerialImpl.cpp @@ -180,8 +180,34 @@ bool SerialImpl::configure() // uart_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); - /* no parity, one stop bit, disable flow control */ - uart_config.c_cflag &= ~(CSTOPB | PARENB | CRTSCTS); + // Control modes + uart_config.c_cflag = 0; + + switch (_bytesize) { + case ByteSize::FiveBits: uart_config.c_cflag |= CS5; break; + + case ByteSize::SixBits: uart_config.c_cflag |= CS6; break; + + case ByteSize::SevenBits: uart_config.c_cflag |= CS7; break; + + case ByteSize::EightBits: uart_config.c_cflag |= CS8; break; + } + + if (_flowcontrol == FlowControl::Enabled) { + uart_config.c_cflag |= CRTSCTS; + } + + if (_parity != Parity::None) { + uart_config.c_cflag |= PARENB; + } + + if (_parity == Parity::Odd) { + uart_config.c_cflag |= PARODD; + } + + if (_stopbits == StopBits::Two) { + uart_config.c_cflag |= CSTOPB; + } /* set baud rate */ if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) { @@ -267,12 +293,36 @@ ssize_t SerialImpl::bytesAvailable() { if (!_open) { PX4_ERR("Device not open!"); + errno = EBADF; return -1; } ssize_t bytes_available = 0; int ret = ioctl(_serial_fd, FIONREAD, &bytes_available); - return ret >= 0 ? bytes_available : 0; + + if (ret < 0) { + return -1; + } + + return bytes_available; +} + +ssize_t SerialImpl::txSpaceAvailable() +{ + if (!_open) { + PX4_ERR("Device not open!"); + errno = EBADF; + return -1; + } + + ssize_t space_available = 0; + int ret = ioctl(_serial_fd, FIONSPACE, &space_available); + + if (ret < 0) { + return -1; + } + + return space_available; } ssize_t SerialImpl::read(uint8_t *buffer, size_t buffer_size) @@ -355,15 +405,75 @@ ssize_t SerialImpl::write(const void *buffer, size_t buffer_size) } int written = ::write(_serial_fd, buffer, buffer_size); - tcdrain(_serial_fd); // Wait until all output is transmitted if (written < 0) { - PX4_ERR("%s write error %d", _port, written); + if (errno != EAGAIN) { + PX4_ERR("%s write error %d", _port, written); + } } return written; } +ssize_t SerialImpl::writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_ms) +{ + if (!_open) { + PX4_ERR("Cannot writeBlocking to serial device until it has been opened"); + return -1; + } + + const uint8_t *data = static_cast(buffer); + size_t total_written = 0; + const hrt_abstime start_time_us = hrt_absolute_time(); + const hrt_abstime timeout_us = timeout_ms * 1000; + + while (total_written < buffer_size) { + if (hrt_elapsed_time(&start_time_us) > timeout_us) { + PX4_WARN("Write timeout, sent %zu", total_written); + break; + } + + pollfd fds[1]; + fds[0].fd = _serial_fd; + fds[0].events = POLLOUT; + + hrt_abstime elapsed_us = hrt_elapsed_time(&start_time_us); + int remaining_timeout_ms = (timeout_us - elapsed_us) / 1000; + + if (remaining_timeout_ms <= 0) { + break; + } + + int result = ::poll(fds, 1, remaining_timeout_ms); + + if (result < 0) { + PX4_ERR("poll error %d", errno); + return -1; + } + + if (fds[0].revents & POLLOUT) { + // Write as much as we can + ssize_t written = ::write(_serial_fd, data + total_written, buffer_size - total_written); + + if (written < 0) { + if (errno == EAGAIN) { + // Buffer full, wait a bit and try again + px4_usleep(1000); + continue; + } + + PX4_ERR("Write error: %d", errno); + return -1; + + } else if (written > 0) { + total_written += written; + } + } + } + + return total_written; +} + void SerialImpl::flush() { if (_open) { @@ -426,7 +536,19 @@ ByteSize SerialImpl::getBytesize() const bool SerialImpl::setBytesize(ByteSize bytesize) { - return bytesize == ByteSize::EightBits; + // check if already configured + if ((bytesize == _bytesize) && _open) { + return true; + } + + _bytesize = bytesize; + + // process bytesize change now if port is already open + if (_open) { + return configure(); + } + + return true; } Parity SerialImpl::getParity() const @@ -436,7 +558,19 @@ Parity SerialImpl::getParity() const bool SerialImpl::setParity(Parity parity) { - return parity == Parity::None; + // check if already configured + if ((parity == _parity) && _open) { + return true; + } + + _parity = parity; + + // process parity change now if port is already open + if (_open) { + return configure(); + } + + return true; } StopBits SerialImpl::getStopbits() const @@ -446,7 +580,19 @@ StopBits SerialImpl::getStopbits() const bool SerialImpl::setStopbits(StopBits stopbits) { - return stopbits == StopBits::One; + // check if already configured + if ((stopbits == _stopbits) && _open) { + return true; + } + + _stopbits = stopbits; + + // process stopbits change now if port is already open + if (_open) { + return configure(); + } + + return true; } FlowControl SerialImpl::getFlowcontrol() const @@ -456,7 +602,19 @@ FlowControl SerialImpl::getFlowcontrol() const bool SerialImpl::setFlowcontrol(FlowControl flowcontrol) { - return flowcontrol == FlowControl::Disabled; + // check if already configured + if ((flowcontrol == _flowcontrol) && _open) { + return true; + } + + _flowcontrol = flowcontrol; + + // process flowcontrol change now if port is already open + if (_open) { + return configure(); + } + + return true; } bool SerialImpl::getSingleWireMode() const diff --git a/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt b/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt index 208cc5c828..d3a45a4e62 100644 --- a/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt +++ b/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt @@ -31,5 +31,4 @@ # ############################################################################ - -add_subdirectory(mcp23009) +add_subdirectory(mcp) diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt b/platforms/nuttx/src/px4/common/gpio/mcp/CMakeLists.txt similarity index 92% rename from platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt rename to platforms/nuttx/src/px4/common/gpio/mcp/CMakeLists.txt index da6dac979f..b8ba517d98 100644 --- a/platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt +++ b/platforms/nuttx/src/px4/common/gpio/mcp/CMakeLists.txt @@ -30,7 +30,7 @@ # POSSIBILITY OF SUCH DAMAGE. # ############################################################################ -px4_add_library(platform_gpio_mcp23009 - mcp23009.cpp +px4_add_library(platform_gpio_mcp + mcp.cpp ) -target_link_libraries(platform_gpio_mcp23009 PRIVATE drivers__device) # device::I2C +target_link_libraries(platform_gpio_mcp PRIVATE drivers__device) # device::I2C diff --git a/platforms/nuttx/src/px4/common/gpio/mcp/mcp.cpp b/platforms/nuttx/src/px4/common/gpio/mcp/mcp.cpp new file mode 100644 index 0000000000..2b69a7cbf3 --- /dev/null +++ b/platforms/nuttx/src/px4/common/gpio/mcp/mcp.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +static int mcp230XX_read(struct gpio_dev_s *dev, bool *value) +{ + mcp_gpio_dev_s *gpio = (struct mcp_gpio_dev_s *)dev; + *value = gpio->callback_handler->input & gpio->mask; + return OK; +} + +static uORB::PublicationMulti toGpioOut{ORB_ID(gpio_out)}; +static int mcp230XX_write(struct gpio_dev_s *dev, bool value) +{ + mcp_gpio_dev_s *gpio = (struct mcp_gpio_dev_s *)dev; + gpio_out_s msg{ + hrt_absolute_time(), + gpio->callback_handler->dev_id, + gpio->mask, // clear mask + value ? gpio->mask : 0u, // set mask + }; + return toGpioOut.publish(msg) ? OK : -ETIMEDOUT; +} + +static uORB::PublicationMulti toGpioConfig{ORB_ID(gpio_config)}; +static int mcp230XX_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype) +{ + mcp_gpio_dev_s *gpio = (struct mcp_gpio_dev_s *)dev; + gpio_config_s msg{ + hrt_absolute_time(), + gpio->callback_handler->dev_id, + gpio->mask, + }; + + switch (pintype) { + case GPIO_INPUT_PIN: + msg.config = gpio_config_s::INPUT; + break; + + case GPIO_INPUT_PIN_PULLUP: + msg.config = gpio_config_s::INPUT_PULLUP; + break; + + case GPIO_OUTPUT_PIN: + msg.config = gpio_config_s::OUTPUT; + break; + + default: + return -ENOTSUP; + } + + return toGpioConfig.publish(msg) ? OK : -ETIMEDOUT; +} + +static const struct gpio_operations_s mcp_gpio_ops { + mcp230XX_read, + mcp230XX_write, + nullptr, + nullptr, + mcp230XX_setpintype, +}; + +int mcp230XX_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor, uint16_t dir_mask, int num_pins, uint8_t device_type, + mcp_gpio_dev_s *_gpio) +{ + bool all_registered = true; + + for (int i = 0; i < num_pins; i++) { + uint16_t mask = 1u << i; + + if (!_gpio[i].registered) { + if (dir_mask & mask) { + _gpio[i] = { {GPIO_INPUT_PIN, {}, &mcp_gpio_ops}, mask, false, nullptr}; + + } else { + _gpio[i] = { {GPIO_OUTPUT_PIN, {}, &mcp_gpio_ops}, mask, false, nullptr}; + } + + int ret = gpio_pin_register(&_gpio[i].gpio, first_minor + i); + + if (ret != OK) { + all_registered = false; + + } else { + _gpio[i].registered = true; + } + } + } + + const auto device_id = device::Device::DeviceId{device::Device::DeviceBusType_I2C, i2c_bus, i2c_addr, device_type}; + CallbackHandler *callback_handler = new CallbackHandler(ORB_ID(gpio_in)); + callback_handler->dev_id = device_id.devid; + bool callback_registered = callback_handler->registerCallback(); + + if (!all_registered || !callback_registered) { + for (int i = 0; i < num_pins; i++) { + if (_gpio[i].registered) { + gpio_pin_unregister(&_gpio[i].gpio, first_minor + i); + _gpio[i].registered = false; + } + } + + callback_handler->unregisterCallback(); + delete callback_handler; + return ERROR; + } + + for (int i = 0; i < num_pins; i++) { + _gpio[i].callback_handler = callback_handler; + } + + return OK; +} + +int mcp230XX_unregister_gpios(int first_minor, int num_pins, mcp_gpio_dev_s *_gpio) +{ + if (_gpio[0].callback_handler) { + CallbackHandler *callback_handler = _gpio[0].callback_handler; + callback_handler->unregisterCallback(); + delete callback_handler; + } + + for (int i = 0; i < num_pins; ++i) { + if (_gpio[i].registered) { + mcp230XX_setpintype(&_gpio[i].gpio, GPIO_INPUT_PIN); + gpio_pin_unregister(&_gpio[i].gpio, first_minor + i); + _gpio[i].registered = false; + _gpio[i].callback_handler = nullptr; + } + } + + return OK; +} diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp deleted file mode 100644 index 63a60e5484..0000000000 --- a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2023 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint32_t DEVID{0}; -struct mcp23009_gpio_dev_s { - struct gpio_dev_s gpio; - uint8_t mask; -}; - -/* Copy the read input data */ -class ReadCallback : public uORB::SubscriptionCallback -{ -public: - using SubscriptionCallback::SubscriptionCallback; - - void call() override - { - px4::msg::GpioIn new_input; - - if (update(&new_input) && new_input.device_id == DEVID) { - input = new_input.state; - } - - } - - uint8_t input; -}; - -static uORB::Publication toGpioRequest{ORB_ID(gpio_request)}; -static ReadCallback fromGpioIn{ORB_ID(gpio_in)}; -static int mcp23009_read(struct gpio_dev_s *dev, bool *value) -{ - mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; - *value = fromGpioIn.input & gpio->mask; - return OK; -} - -static uORB::Publication toGpioOut{ORB_ID(gpio_out)}; -static int mcp23009_write(struct gpio_dev_s *dev, bool value) -{ - mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; - gpio_out_s msg{ - hrt_absolute_time(), - DEVID, - gpio->mask, // clear mask - value ? gpio->mask : 0u, // set mask - }; - return toGpioOut.publish(msg) ? OK : -ETIMEDOUT; -} - -static uORB::Publication toGpioConfig{ORB_ID(gpio_config)}; -static int mcp23009_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype) -{ - mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; - gpio_config_s msg{ - hrt_absolute_time(), - DEVID, - gpio->mask, - }; - - switch (pintype) { - case GPIO_INPUT_PIN: - msg.config = gpio_config_s::INPUT; - break; - - case GPIO_INPUT_PIN_PULLUP: - msg.config = gpio_config_s::INPUT_PULLUP; - break; - - case GPIO_OUTPUT_PIN: - msg.config = gpio_config_s::OUTPUT; - break; - - default: - return -ENOTSUP; - } - - return toGpioConfig.publish(msg) ? OK : -ETIMEDOUT; -} - - - -// ---------------------------------------------------------------------------- -static const struct gpio_operations_s mcp23009_gpio_ops { - mcp23009_read, - mcp23009_write, - nullptr, - nullptr, - mcp23009_setpintype, -}; - -static constexpr uint8_t NUM_GPIOS = 8; -static mcp23009_gpio_dev_s _gpio[NUM_GPIOS] { - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 0) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 1) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 2) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 3) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 4) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 5) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 6) }, - { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 7) } -}; - -// ---------------------------------------------------------------------------- -int mcp23009_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor) -{ - const auto device_id = device::Device::DeviceId{ - device::Device::DeviceBusType_I2C, i2c_bus, i2c_addr, DRV_GPIO_DEVTYPE_MCP23009}; - DEVID = device_id.devid; - - for (int i = 0; i < NUM_GPIOS; ++i) { - int ret = gpio_pin_register(&_gpio[i].gpio, first_minor + i); - - if (ret != OK) { - return ret; - } - } - - fromGpioIn.registerCallback(); - return OK; -} - -int mcp23009_unregister_gpios(int first_minor) -{ - for (int i = 0; i < NUM_GPIOS; ++i) { - mcp23009_setpintype(&_gpio[i].gpio, GPIO_INPUT_PIN); - gpio_pin_unregister(&_gpio[i].gpio, first_minor + i); - } - - fromGpioIn.unregisterCallback(); - return OK; -} diff --git a/platforms/nuttx/src/px4/common/include/SerialImpl.hpp b/platforms/nuttx/src/px4/common/include/SerialImpl.hpp index c7fb1ede81..32c549ad6e 100644 --- a/platforms/nuttx/src/px4/common/include/SerialImpl.hpp +++ b/platforms/nuttx/src/px4/common/include/SerialImpl.hpp @@ -60,10 +60,12 @@ public: bool close(); ssize_t bytesAvailable(); + ssize_t txSpaceAvailable(); ssize_t read(uint8_t *buffer, size_t buffer_size); ssize_t readAtLeast(uint8_t *buffer, size_t buffer_size, size_t character_count = 1, uint32_t timeout_us = 0); ssize_t write(const void *buffer, size_t buffer_size); + ssize_t writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_us = 0); void flush(); diff --git a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp.hpp b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp.hpp new file mode 100644 index 0000000000..e9dfcf14e3 --- /dev/null +++ b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp.hpp @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + +#include +#include +#include +#include + +#ifndef CONFIG_DEV_GPIO +# error "CONFIG_DEV_GPIO is required to use MCP GPIO expander, enable it in your NuttX config" +#endif + +struct mcp_gpio_dev_s { + struct gpio_dev_s gpio; + uint16_t mask; + bool registered = false; + CallbackHandler *callback_handler; +}; + +int mcp230XX_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor = 0, uint16_t dir_mask = 0x0000, int num_pins = 8, + uint8_t device_type = 0, mcp_gpio_dev_s *_gpio = nullptr); +int mcp230XX_unregister_gpios(int first_minor = 0, int num_pins = 0, mcp_gpio_dev_s *_gpio = nullptr); diff --git a/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c b/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c index da2b7e932a..f171621aee 100644 --- a/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c +++ b/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c @@ -78,7 +78,6 @@ #define LEDC_LSCH0_DUTY_REG (DR_REG_LEDC_BASE + 0x00A8) #define LEDC_CONF_REG (DR_REG_LEDC_BASE + 0x0190) - #define LEDC_SIG_OUT_EN_LSCH0 1 << 2 #define LEDC_PARA_UP_LSCH0 1 << 4 #define DPORT_LEDC_CLK_EN 1 << 11 @@ -129,7 +128,8 @@ void get_optimal_timer_setup(uint32_t desired_freq) uint32_t shifted = 1; timer_rate = desired_freq; - reload = (20480000000 / desired_freq + LEDC_CLKDIV_MAX) / LEDC_CLKDIV_MAX; + uint64_t pwm_clk = 80000000; + reload = (pwm_clk * 256 / desired_freq + LEDC_CLKDIV_MAX) / LEDC_CLKDIV_MAX; if (reload == 0) { reload = 1; @@ -148,7 +148,7 @@ void get_optimal_timer_setup(uint32_t desired_freq) } shift = shifted; - prescaler = (20480000000 / reload) / desired_freq; + prescaler = (pwm_clk * 256 / reload) / desired_freq; } int up_pwm_servo_set(unsigned channel, uint16_t value) @@ -157,10 +157,23 @@ int up_pwm_servo_set(unsigned channel, uint16_t value) uint32_t regval = b16toi(duty * reload + b16HALF); irqstate_t flags; - flags = px4_enter_critical_section(); + SET_CHAN_REG(channel, LEDC_LSCH0_CONF0_REG, 0); + SET_CHAN_REG(channel, LEDC_LSCH0_CONF1_REG, 0); + + /* Set pulse phase 0 */ + SET_CHAN_REG(channel, LEDC_LSCH0_HPOINT_REG, 0); SET_CHAN_REG(channel, LEDC_LSCH0_DUTY_REG, regval << 4); + + SET_CHAN_BITS(channel, LEDC_LSCH0_CONF0_REG, LEDC_SIG_OUT_EN_LSCH0); + + /* Start Duty counter */ + SET_CHAN_BITS(channel, LEDC_LSCH0_CONF1_REG, LEDC_DUTY_START_LSCH0); + + /* Update duty and phase to hardware */ SET_CHAN_BITS(channel, LEDC_LSCH0_CONF0_REG, LEDC_PARA_UP_LSCH0); + + px4_leave_critical_section(flags); return OK; diff --git a/platforms/nuttx/src/px4/nxp/imxrt/board_reset/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/imxrt/board_reset/CMakeLists.txt index deff20f14c..cba22cb320 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/board_reset/CMakeLists.txt +++ b/platforms/nuttx/src/px4/nxp/imxrt/board_reset/CMakeLists.txt @@ -35,9 +35,7 @@ px4_add_library(arch_board_reset board_reset.cpp ) -if (CONFIG_ARCH_FAMILY_IMXRT117x) target_link_libraries(arch_board_reset PRIVATE arch_board_romapi) -endif() # up_systemreset if (NOT DEFINED CONFIG_BUILD_FLAT) diff --git a/platforms/nuttx/src/px4/nxp/imxrt/board_reset/board_reset.cpp b/platforms/nuttx/src/px4/nxp/imxrt/board_reset/board_reset.cpp index 1d29a64dfb..632180f412 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/board_reset/board_reset.cpp +++ b/platforms/nuttx/src/px4/nxp/imxrt/board_reset/board_reset.cpp @@ -45,6 +45,12 @@ #ifdef CONFIG_ARCH_FAMILY_IMXRT117x #include +#elif defined CONFIG_ARCH_FAMILY_IMXRT106x +# include +# define SNVS_LPCR_GPR_Z_DIS (1 << 24) /* Bit 24: General Purpose Registers Zeroization Disable */ +#endif + +#ifdef BOARD_HAS_ISP_BOOTLOADER #include #include #endif @@ -59,12 +65,12 @@ static int board_reset_enter_bootloader() { -#ifdef CONFIG_ARCH_FAMILY_IMXRT117x +#ifdef BOARD_HAS_TEENSY_BOOTLOADER + asm("BKPT #251"); /* Enter Teensy MKL02 bootloader */ +#else uint32_t regvalue = BOOT_RTC_SIGNATURE; modifyreg32(IMXRT_SNVS_LPCR, 0, SNVS_LPCR_GPR_Z_DIS); putreg32(regvalue, PX4_IMXRT_RTC_REBOOT_REG_ADDRESS); -#elif defined(BOARD_HAS_TEENSY_BOOTLOADER) - asm("BKPT #251"); /* Enter Teensy MKL02 bootloader */ #endif return OK; } @@ -75,15 +81,14 @@ int board_reset(int status) board_reset_enter_bootloader(); } -#if defined(BOARD_HAS_ISP_BOOTLOADER) - else if (status == REBOOT_TO_ISP) { +#ifdef BOARD_HAS_ISP_BOOTLOADER uint32_t arg = 0xeb100000; ROM_API_Init(); ROM_RunBootloader(&arg); +#endif } -#endif #if defined(BOARD_HAS_ON_RESET) board_on_reset(status); diff --git a/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c b/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c index 233d4fc288..7bd2508ddf 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c @@ -74,26 +74,40 @@ typedef enum { BDSHOT_RECEIVE_COMPLETE, } dshot_state; -typedef struct dshot_handler_t { +typedef struct dshot_channel_t { bool init; uint32_t data_seg1; uint32_t irq_data; dshot_state state; - bool bdshot; uint32_t raw_response; uint16_t erpm; uint32_t crc_error_cnt; uint32_t frame_error_cnt; uint32_t no_response_cnt; uint32_t last_no_response_cnt; -} dshot_handler_t; + bool bdshot; + uint32_t bdshot_tcmp; + uint32_t bdshot_training_mask; + uint8_t bdshot_training_count; + uint8_t bdshot_training_success; + bool bdshot_training_done; + int8_t bdshot_tcmp_offset; +} dshot_channel_t; #define BDSHOT_OFFLINE_COUNT 400 // If there are no responses for 400 setpoints ESC is offline -static dshot_handler_t dshot_inst[DSHOT_TIMERS] = {}; +#define BDSHOT_TCMP_MIN_OFFSET -16 +#define BDSHOT_TCMP_MAX_OFFSET 15 +#define BDSHOT_TCMP_TO_MASK(x) ((x) - BDSHOT_TCMP_MIN_OFFSET) +#define BDSHOT_TRAINING_TRIES 200 +#define BDSHOT_TRAINING_SUCCESS 198 + +#define BDSHOT_ZERO_RESPONSE 0x52951 + +static dshot_channel_t dshot_inst[DSHOT_TIMERS] = {}; static uint32_t dshot_tcmp; -static uint32_t bdshot_tcmp; +static unsigned dshot_speed; static uint32_t dshot_mask; static uint32_t bdshot_recv_mask; static uint32_t bdshot_parsed_recv_mask; @@ -155,6 +169,12 @@ static inline void clear_timer_status_flags(uint32_t mask) flexio_putreg32(mask, IMXRT_FLEXIO_TIMSTAT_OFFSET); } +static inline void flexio_dshot_set_tcmp(uint32_t channel) +{ + dshot_inst[channel].bdshot_tcmp = 0x2900 | (((BOARD_FLEXIO_PREQ / (dshot_speed * 5 / 4) / 2) + + dshot_inst[channel].bdshot_tcmp_offset) & 0xFF); +} + static void flexio_dshot_output(uint32_t channel, uint32_t pin, uint32_t timcmp, bool inverted) { /* Disable Shifter */ @@ -278,7 +298,7 @@ static int flexio_irq_handler(int irq, void *context, void *arg) IMXRT_FLEXIO_TIMCFG0_OFFSET + channel * 0x4); /* Enable on pin transition, resychronize through reset on rising edge */ - flexio_putreg32(bdshot_tcmp, IMXRT_FLEXIO_TIMCMP0_OFFSET + channel * 0x4); + flexio_putreg32(dshot_inst[channel].bdshot_tcmp, IMXRT_FLEXIO_TIMCMP0_OFFSET + channel * 0x4); /* Trigger on FXIO pin transition, Baud mode */ flexio_putreg32(FLEXIO_TIMCTL_TRGSEL(2 * timer_io_channels[channel].dshot.flexio_pin) | @@ -305,7 +325,7 @@ int up_dshot_init(uint32_t channel_mask, unsigned dshot_pwm_freq, bool enable_bi { /* Calculate dshot timings based on dshot_pwm_freq */ dshot_tcmp = 0x2F00 | (((BOARD_FLEXIO_PREQ / (dshot_pwm_freq * 3) / 2) - 1) & 0xFF); - bdshot_tcmp = 0x2900 | (((BOARD_FLEXIO_PREQ / (dshot_pwm_freq * 5 / 4) / 2) - 3) & 0xFF); + dshot_speed = dshot_pwm_freq; /* Clock FlexIO peripheral */ imxrt_clockall_flexio1(); @@ -340,7 +360,16 @@ int up_dshot_init(uint32_t channel_mask, unsigned dshot_pwm_freq, bool enable_bi imxrt_config_gpio(timer_io_channels[channel].dshot.pinmux | IOMUX_PULL_UP); - dshot_inst[channel].bdshot = enable_bidirectional_dshot; + if (enable_bidirectional_dshot) { + dshot_inst[channel].bdshot = true; + dshot_inst[channel].bdshot_training_mask = 0; + dshot_inst[channel].bdshot_tcmp_offset = BDSHOT_TCMP_MIN_OFFSET; + dshot_inst[channel].bdshot_training_done = false; + flexio_dshot_set_tcmp(channel); + + } else { + dshot_inst[channel].bdshot = false; + } flexio_dshot_output(channel, timer_io_channels[channel].dshot.flexio_pin, dshot_tcmp, dshot_inst[channel].bdshot); @@ -357,6 +386,52 @@ int up_dshot_init(uint32_t channel_mask, unsigned dshot_pwm_freq, bool enable_bi return channel_mask; } +void up_bdshot_training(uint32_t channel, uint32_t value) +{ + dshot_channel_t *ch = &dshot_inst[channel]; + + if (value == BDSHOT_ZERO_RESPONSE) { + // Count successful responses + ch->bdshot_training_success++; + + } else if ((value & 0x1) == 0) { + // Invalidate frame error immediately + ch->bdshot_training_count = BDSHOT_TRAINING_TRIES - 1; + } + + // Keep count and check if a training round finished + ch->bdshot_training_count++; + + if (ch->bdshot_training_count == BDSHOT_TRAINING_TRIES) { + if (ch->bdshot_training_success >= BDSHOT_TRAINING_SUCCESS) { + ch->bdshot_training_mask |= + (1 << BDSHOT_TCMP_TO_MASK(ch->bdshot_tcmp_offset)); + } + + ch->bdshot_training_count = 0; + ch->bdshot_training_success = 0; + ch->bdshot_tcmp_offset++; + + if (ch->bdshot_tcmp_offset == BDSHOT_TCMP_MAX_OFFSET) { + + if (ch->bdshot_training_mask == 0) { + // No candidates retry + ch->bdshot_tcmp_offset = BDSHOT_TCMP_MIN_OFFSET; + + } else { + // Training done, use mask to find best offset + int low = __builtin_ctz(ch->bdshot_training_mask); + int high = 31 - __builtin_clz(ch->bdshot_training_mask); + ch->bdshot_tcmp_offset = ((low + high) / 2) + BDSHOT_TCMP_MIN_OFFSET; + ch->bdshot_training_done = true; + } + } + + // Update TCMP + flexio_dshot_set_tcmp(channel); + } +} + void up_bdshot_erpm(void) { uint32_t value; @@ -373,8 +448,12 @@ void up_bdshot_erpm(void) if (bdshot_recv_mask & (1 << channel)) { value = ~dshot_inst[channel].raw_response & 0xFFFFF; - /* if lowest significant isn't 1 we've got a framing error */ - if (value & 0x1) { + // BDSHOT ESC hardware varies and timings differ between units. + // Run training to estimate the correct baudrate to lock onto. + if (!dshot_inst[channel].bdshot_training_done) { + up_bdshot_training(channel, value); + + } else if (value & 0x1) { /* if lowest significant isn't 1 we've got a framing error */ /* Decode RLL */ value = (value ^ (value >> 1)); @@ -425,7 +504,7 @@ int up_bdshot_num_erpm_ready(void) for (unsigned i = 0; i < DSHOT_TIMERS; ++i) { // We only check that data has been received, rather than if it's valid. // This ensures data is published even if one channel has bit errors. - if (bdshot_recv_mask & (1 << i)) { + if (bdshot_parsed_recv_mask & (1 << i)) { ++num_ready; } } @@ -461,6 +540,8 @@ void up_bdshot_status(void) if (dshot_inst[channel].init) { PX4_INFO("Channel %i %s Last erpm %i value", channel, up_bdshot_channel_status(channel) ? "online" : "offline", dshot_inst[channel].erpm); + PX4_INFO("BDSHOT Training done: %s TCMP offset: %d", dshot_inst[channel].bdshot_training_done ? "YES" : "NO", + dshot_inst[channel].bdshot_tcmp_offset); PX4_INFO("CRC errors Frame error No response"); PX4_INFO("%10lu %11lu %11lu", dshot_inst[channel].crc_error_cnt, dshot_inst[channel].frame_error_cnt, dshot_inst[channel].no_response_cnt); diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_flexspi_nor_flash.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_flexspi_nor_flash.h index 727744b974..e58554aa5b 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_flexspi_nor_flash.h +++ b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_flexspi_nor_flash.h @@ -138,18 +138,33 @@ (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq { + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; +#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x) //!@brief Definitions for FlexSPI Serial Clock Frequency typedef enum _FlexSpiSerialClockFreq { kFlexSpiSerialClk_30MHz = 1, kFlexSpiSerialClk_50MHz = 2, kFlexSpiSerialClk_60MHz = 3, kFlexSpiSerialClk_80MHz = 4, - kFlexSpiSerialClk_100MHz = 5, + kFlexSpiSerialClk_100MHz = 5, kFlexSpiSerialClk_120MHz = 6, kFlexSpiSerialClk_133MHz = 7, kFlexSpiSerialClk_166MHz = 8, kFlexSpiSerialClk_200MHz = 9, } flexspi_serial_clk_freq_t; +#endif //!@brief FlexSPI clock configuration type enum { diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_romapi.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_romapi.h index f51775e2bd..fa944e0c1b 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_romapi.h +++ b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/imxrt_romapi.h @@ -239,7 +239,9 @@ status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *con * @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout. * @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout */ +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t start); +#endif /*! * @brief Erase one block specified by address @@ -259,7 +261,9 @@ status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_ * @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout. * @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout */ +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x status_t ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t start); +#endif /*! * @brief Erase all the Serial NOR devices connected on FLEXSPI. @@ -342,10 +346,12 @@ status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance, * @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided. * @retval kStatus_ROM_FLEXSPI_DeviceTimeout Device timeout. */ +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x status_t ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance, flexspi_nor_config_t *config, bool isParallelMode, uint32_t address); +#endif /*@}*/ /*! diff --git a/platforms/nuttx/src/px4/nxp/imxrt/romapi/imxrt_romapi.c b/platforms/nuttx/src/px4/nxp/imxrt/romapi/imxrt_romapi.c index 68443e3353..e6b657d326 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/romapi/imxrt_romapi.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/romapi/imxrt_romapi.c @@ -52,8 +52,29 @@ typedef union _standard_version { #endif } standard_version_t; + +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x + /*! - * @brief Interface for the ROM FLEXSPI NOR flash driver. + * @brief Interface for the IMXRT106X ROM FLEXSPI NOR flash driver. + */ +typedef struct { + uint32_t version; + status_t (*init)(uint32_t instance, flexspi_nor_config_t *config); + status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src); + status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config); + status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length); + status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes); + void (*clear_cache)(uint32_t instance); + status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer); + status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq); + status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option); +} flexspi_nor_driver_interface_t; + +#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x) + +/*! + * @brief Interface for the IMXRT117X ROM FLEXSPI NOR flash driver. */ typedef struct { uint32_t version; @@ -73,6 +94,33 @@ typedef struct { const uint32_t reserved1[2]; /*!< Reserved */ } flexspi_nor_driver_interface_t; +#endif + + +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x + +/*! +* @brief Root of the bootloader api tree. +* +* An instance of this struct resides in read-only memory in the bootloader. It +* provides a user application access to APIs exported by the bootloader. +* +* @note The order of existing fields must not be changed. +*/ +typedef struct { + const uint32_t version; //!< Bootloader version number + const char *copyright; //!< Bootloader Copyright + void (*runBootloader)(void *arg); //!< Function to start the bootloader executing + const uint32_t *reserved0; //!< Reserved + const flexspi_nor_driver_interface_t *flexSpiNorDriver; //!< FlexSPI NOR Flash API + const uint32_t *reserved1; //!< Reserved + const uint32_t *unused_rtwdogDriver; + const uint32_t *unused_wdogDriver; + const uint32_t *reserved2; +} bootloader_api_entry_t; + +#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x) + /*! * @brief Root of the bootloader api tree. * @@ -89,6 +137,8 @@ typedef struct { const uint32_t reserved[8]; /*!< Reserved */ } bootloader_api_entry_t; +#endif + /******************************************************************************* * Variables ******************************************************************************/ @@ -104,13 +154,18 @@ static bootloader_api_entry_t *g_bootloaderTree = NULL; locate_code(".ramfunc") void ROM_API_Init(void) { +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x + g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0020001cU); +#else - if ((getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) & ANADIG_MISC_MISC_DIFPROG_CHIPID(0x10U)) != 0U) { - g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0021001cU); + if (getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) == 0x001170A0U) { + g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0020001cU); } else { - g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0020001cU); + g_bootloaderTree = ((bootloader_api_entry_t *) * (uint32_t *)0x0021001cU); } + +#endif } /*! @@ -193,6 +248,8 @@ status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *con return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length); } +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x + /*! * @brief Erase one sector specified by address. * @@ -219,6 +276,8 @@ status_t ROM_FLEXSPI_NorFlash_EraseBlock(uint32_t instance, flexspi_nor_config_t return g_bootloaderTree->flexSpiNorDriver->erase_block(instance, config, start); } +#endif + /*! @brief Erase all the Serial NOR devices connected on FLEXSPI. */ locate_code(".ramfunc") status_t ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance, flexspi_nor_config_t *config) @@ -242,23 +301,42 @@ status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance, return g_bootloaderTree->flexSpiNorDriver->update_lut(instance, seqIndex, lutBase, seqNumber); } + +#ifdef CONFIG_ARCH_FAMILY_IMXRT106x + +/*! @brief Software reset for the FLEXSPI logic. */ +locate_code(".ramfunc") +void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance) +{ + g_bootloaderTree->flexSpiNorDriver->clear_cache(instance); +} + + +#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x) + /*! @brief Software reset for the FLEXSPI logic. */ locate_code(".ramfunc") void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance) { uint32_t clearCacheFunctionAddress; - if ((getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) & ANADIG_MISC_MISC_DIFPROG_CHIPID(0x10U)) != 0U) { + if (getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) == 0x001170a0U) { + clearCacheFunctionAddress = 0x0020426bU; + + } else if (getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG) == 0x001170b0U) { clearCacheFunctionAddress = 0x0021a3b7U; } else { - clearCacheFunctionAddress = 0x0020426bU; + clearCacheFunctionAddress = 0x0021a3bfU; } clearCacheCommand_t clearCacheCommand; MISRA_CAST(clearCacheCommand_t, clearCacheCommand, uint32_t, clearCacheFunctionAddress); (void)clearCacheCommand(instance); } +#endif + +#ifdef CONFIG_ARCH_FAMILY_IMXRT117x /*! @brief Wait until device is idle*/ locate_code(".ramfunc") @@ -269,3 +347,5 @@ status_t ROM_FLEXSPI_NorFlash_WaitBusy(uint32_t instance, { return g_bootloaderTree->flexSpiNorDriver->wait_busy(instance, config, isParallelMode, address); } + +#endif diff --git a/platforms/nuttx/src/px4/nxp/imxrt/version/board_mcu_version.c b/platforms/nuttx/src/px4/nxp/imxrt/version/board_mcu_version.c index ae8594bd4f..94c75844d8 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/version/board_mcu_version.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/version/board_mcu_version.c @@ -90,7 +90,7 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata) #define DIGPROG_MAJOR_UPPER_MASK (0xff << DIGPROG_MAJOR_UPPER_SHIFT) #define DIGPROG_MAJOR_UPPER(info) (((info) & DIGPROG_MAJOR_UPPER_MASK) >> DIGPROG_MAJOR_UPPER_SHIFT) // 876543210 -#define CHIP_TAG "i.MX RT10?2 r?.?" +#define CHIP_TAG "i.MX RT10?? r?.?" #define CHIP_TAG_LEN sizeof(CHIP_TAG)-1 int board_mcu_version(char *rev, const char **revstr, const char **errata) @@ -100,6 +100,7 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata) chip[CHIP_TAG_LEN - 1] = '0' + DIGPROG_MINOR(info); chip[CHIP_TAG_LEN - 3] = '1' + DIGPROG_MAJOR_LOWER(info); + chip[CHIP_TAG_LEN - 6] = getreg32(0x401F867C) == 0x10 ? '4' : '2'; chip[CHIP_TAG_LEN - 7] = DIGPROG_MAJOR_UPPER(info) == 0x6a ? '5' : '6'; *revstr = chip; *rev = '0' + DIGPROG_MINOR(info); diff --git a/platforms/nuttx/src/px4/nxp/rt106x/CMakeLists.txt b/platforms/nuttx/src/px4/nxp/rt106x/CMakeLists.txt index f487b031c7..57bd94ee6e 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/CMakeLists.txt +++ b/platforms/nuttx/src/px4/nxp/rt106x/CMakeLists.txt @@ -36,11 +36,13 @@ add_subdirectory(../imxrt/adc adc) add_subdirectory(../imxrt/board_critmon board_critmon) add_subdirectory(../imxrt/board_hw_info board_hw_info) add_subdirectory(../imxrt/board_reset board_reset) +add_subdirectory(../imxrt/romapi romapi) add_subdirectory(../imxrt/dshot dshot) add_subdirectory(../imxrt/hrt hrt) add_subdirectory(../imxrt/led_pwm led_pwm) add_subdirectory(../imxrt/io_pins io_pins) add_subdirectory(../imxrt/tone_alarm tone_alarm) add_subdirectory(../imxrt/version version) +add_subdirectory(../imxrt/spi spi) add_subdirectory(px4io_serial) diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h index d4aada2ffe..27da505127 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/hw_description.h @@ -41,8 +41,8 @@ #include #include -#ifndef CONFIG_ARCH_CHIP_MIMXRT1062DVL6A -# error "This code has only been validated with IMXRT1062. Make sure it is correct before using it on another board." +#if !defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) && !defined(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A) +# error "This code has only been validated with IMXRT1062 and IMXRT1064. Make sure it is correct before using it on another board." #endif /* diff --git a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_flexspi_nor_flash.h similarity index 88% rename from platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp rename to platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_flexspi_nor_flash.h index 481f5b51d7..3925012e86 100644 --- a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_flexspi_nor_flash.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2023 PX4 Development Team. All rights reserved. + * Copyright (c) 2024 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,10 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ - #pragma once -#include -int mcp23009_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor = 0); -int mcp23009_unregister_gpios(int first_minor = 0); +#include "../../../imxrt/include/px4_arch/imxrt_flexspi_nor_flash.h" diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_romapi.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_romapi.h new file mode 100644 index 0000000000..aeab841162 --- /dev/null +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/imxrt_romapi.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + + +#include "../../../imxrt/include/px4_arch/imxrt_romapi.h" diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h index 5cbc33fdc3..a5ec76ea25 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/io_timer_hw_description.h @@ -47,8 +47,8 @@ #include #include -#ifndef CONFIG_ARCH_CHIP_MIMXRT1062DVL6A -# error "This code has only been validated with IMXRT1062. Make sure it is correct before using it on another board." +#if !defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) && !defined(CONFIG_ARCH_CHIP_MIMXRT1064DVL6A) +# error "This code has only been validated with IMXRT1062 and IMXRT1064. Make sure it is correct before using it on another board." #endif diff --git a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h index de0c30247d..0e1a46b8e3 100644 --- a/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/rt106x/include/px4_arch/spi_hw_description.h @@ -46,6 +46,58 @@ #define GENERAL_OUTPUT_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP | IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST) +constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS]) +{ + const bool nuttx_enabled_spi_buses[] = { +#ifdef CONFIG_IMXRT_LPSPI1 + true, +#else + false, +#endif +#ifdef CONFIG_IMXRT_LPSPI2 + true, +#else + false, +#endif +#ifdef CONFIG_IMXRT_LPSPI3 + true, +#else + false, +#endif +#ifdef CONFIG_IMXRT_LPSPI4 + true, +#else + false, +#endif +#ifdef CONFIG_IMXRT_LPSPI5 + true, +#else + false, +#endif +#ifdef CONFIG_IMXRT_LPSPI6 + true, +#else + false, +#endif + }; + + for (unsigned i = 0; i < sizeof(nuttx_enabled_spi_buses) / sizeof(nuttx_enabled_spi_buses[0]); ++i) { + bool found_bus = false; + + for (int j = 0; j < SPI_BUS_MAX_BUS_ITEMS; ++j) { + if (spi_busses_conf[j].bus == (int)i + 1) { + found_bus = true; + } + } + + // Either the bus is enabled in NuttX and configured in spi_busses_conf, or disabled and not configured + constexpr_assert(found_bus == nuttx_enabled_spi_buses[i], "SPI bus config mismatch (CONFIG_STM32H7_SPIx)"); + } + + return false; +} + + static inline constexpr px4_spi_bus_device_t initSPIDevice(uint32_t devid, SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) { px4_spi_bus_device_t ret{}; @@ -138,8 +190,57 @@ static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI return ret; } -constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS]) + +struct px4_spi_bus_array_t { + px4_spi_bus_t item[SPI_BUS_MAX_BUS_ITEMS]; +}; +#if defined(BOARD_HAS_HW_SPLIT_VERSIONING) +static inline constexpr px4_spi_bus_all_hw_t initSPIFmumID(hw_fmun_id_t hw_fmun_id, + const px4_spi_bus_array_t &bus_items) { - return true; + px4_spi_bus_all_hw_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + ret.buses[i] = bus_items.item[i]; + } + + ret.board_hw_fmun_id = hw_fmun_id; + return ret; } +#else +static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version_revision, + const px4_spi_bus_array_t &bus_items) +{ + px4_spi_bus_all_hw_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + ret.buses[i] = bus_items.item[i]; + } + + ret.board_hw_version_revision = hw_version_revision; + return ret; +} +#endif +constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]); + +constexpr bool validateSPIConfig(const px4_spi_bus_all_hw_t spi_buses_conf[BOARD_NUM_SPI_CFG_HW_VERSIONS]) +{ + for (int ver = 0; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) { + validateSPIConfig(spi_buses_conf[ver].buses); + } + + for (int ver = 1; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) { + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + const bool equal_power_enable_gpio = spi_buses_conf[ver].buses[i].power_enable_gpio == spi_buses_conf[ver - + 1].buses[i].power_enable_gpio; + // currently board_control_spi_sensors_power_configgpio() depends on that - this restriction can be removed + // by ensuring board_control_spi_sensors_power_configgpio() is called after the hw version is determined + // and SPI config is initialized. + constexpr_assert(equal_power_enable_gpio, "All HW versions must define the same power enable GPIO"); + } + } + + return false; +} + #endif // CONFIG_SPI diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/hw_description.h index e6d854bef3..09559f950b 100644 --- a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/hw_description.h +++ b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/hw_description.h @@ -46,10 +46,34 @@ namespace Timer { + + +// Just to keep def extract_timer(line): happy enum Timer { - EMIOS0 = 0, - EMIOS1, - EMIOS2, + EMIOS0_Channel0, + EMIOS0_Channel1, + EMIOS0_Channel2, + EMIOS0_Channel3, + EMIOS0_Channel4, + EMIOS0_Channel5, + EMIOS0_Channel6, + EMIOS0_Channel7, + EMIOS1_Channel0, + EMIOS1_Channel1, + EMIOS1_Channel2, + EMIOS1_Channel3, + EMIOS1_Channel4, + EMIOS1_Channel5, + EMIOS1_Channel6, + EMIOS1_Channel7, + EMIOS2_Channel0, + EMIOS2_Channel1, + EMIOS2_Channel2, + EMIOS2_Channel3, + EMIOS2_Channel4, + EMIOS2_Channel5, + EMIOS2_Channel6, + EMIOS2_Channel7, }; enum Channel { Channel0 = 0, @@ -70,11 +94,37 @@ struct TimerChannel { static inline constexpr uint32_t timerBaseRegister(Timer::Timer timer) { switch (timer) { - case Timer::EMIOS0: return S32K3XX_EMIOS0_BASE; + case Timer::EMIOS0_Channel0: + case Timer::EMIOS0_Channel1: + case Timer::EMIOS0_Channel2: + case Timer::EMIOS0_Channel3: + case Timer::EMIOS0_Channel4: + case Timer::EMIOS0_Channel5: + case Timer::EMIOS0_Channel6: + case Timer::EMIOS0_Channel7: + return S32K3XX_EMIOS0_BASE; - case Timer::EMIOS1: return S32K3XX_EMIOS1_BASE; - case Timer::EMIOS2: return S32K3XX_EMIOS2_BASE; + + case Timer::EMIOS1_Channel0: + case Timer::EMIOS1_Channel1: + case Timer::EMIOS1_Channel2: + case Timer::EMIOS1_Channel3: + case Timer::EMIOS1_Channel4: + case Timer::EMIOS1_Channel5: + case Timer::EMIOS1_Channel6: + case Timer::EMIOS1_Channel7: + return S32K3XX_EMIOS1_BASE; + + case Timer::EMIOS2_Channel0: + case Timer::EMIOS2_Channel1: + case Timer::EMIOS2_Channel2: + case Timer::EMIOS2_Channel3: + case Timer::EMIOS2_Channel4: + case Timer::EMIOS2_Channel5: + case Timer::EMIOS2_Channel6: + case Timer::EMIOS2_Channel7: + return S32K3XX_EMIOS2_BASE; } return 0; diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer.h index d6e0ad6eb5..e569349dd5 100644 --- a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer.h +++ b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer.h @@ -45,7 +45,7 @@ #pragma once __BEGIN_DECLS /* configuration limits */ -#define MAX_IO_TIMERS 1 +#define MAX_IO_TIMERS 8 #define MAX_TIMER_IO_CHANNELS 8 #define MAX_LED_TIMERS 2 @@ -88,6 +88,7 @@ typedef struct io_timers_t { uint32_t vectorno_12_15; /* IRQ number */ uint32_t vectorno_16_19; /* IRQ number */ uint32_t vectorno_20_23; /* IRQ number */ + uint32_t channel; } io_timers_t; typedef struct io_timers_channel_mapping_element_t { diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer_hw_description.h index b689593a53..724d944792 100644 --- a/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/s32k3xx/include/px4_arch/io_timer_hw_description.h @@ -55,15 +55,7 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t ret.timer_channel = (int)timer.channel + 1; // find timer index - ret.timer_index = 0xff; - const uint32_t timer_base = timerBaseRegister(timer.timer); - - for (int i = 0; i < MAX_IO_TIMERS; ++i) { - if (io_timers_conf[i].base == timer_base) { - ret.timer_index = i; - break; - } - } + ret.timer_index = timer.channel; constexpr_assert(ret.timer_index != 0xff, "Timer not found"); @@ -80,13 +72,20 @@ static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t * Ch20 - Ch23 = vectorno - 5 */ -static inline constexpr io_timers_t initIOTimer(Timer::Timer timer) +static inline constexpr io_timers_t initIOTimer(Timer::Timer timer, Timer::Channel channel) { bool nuttx_config_timer_enabled = false; io_timers_t ret{}; switch (timer) { - case Timer::EMIOS0: + case Timer::EMIOS0_Channel0: + case Timer::EMIOS0_Channel1: + case Timer::EMIOS0_Channel2: + case Timer::EMIOS0_Channel3: + case Timer::EMIOS0_Channel4: + case Timer::EMIOS0_Channel5: + case Timer::EMIOS0_Channel6: + case Timer::EMIOS0_Channel7: ret.base = S32K3XX_EMIOS0_BASE; ret.clock_register = 0; ret.clock_bit = 0; @@ -96,12 +95,20 @@ static inline constexpr io_timers_t initIOTimer(Timer::Timer timer) ret.vectorno_12_15 = S32K3XX_IRQ_EMIOS0_12_15; ret.vectorno_16_19 = S32K3XX_IRQ_EMIOS0_16_19; ret.vectorno_20_23 = S32K3XX_IRQ_EMIOS0_20_23; + ret.channel = channel; #ifdef CONFIG_S32K3XX_EMIOS0 nuttx_config_timer_enabled = true; #endif break; - case Timer::EMIOS1: + case Timer::EMIOS1_Channel0: + case Timer::EMIOS1_Channel1: + case Timer::EMIOS1_Channel2: + case Timer::EMIOS1_Channel3: + case Timer::EMIOS1_Channel4: + case Timer::EMIOS1_Channel5: + case Timer::EMIOS1_Channel6: + case Timer::EMIOS1_Channel7: ret.base = S32K3XX_EMIOS1_BASE; ret.clock_register = 0; ret.clock_bit = 0; @@ -116,7 +123,15 @@ static inline constexpr io_timers_t initIOTimer(Timer::Timer timer) #endif break; - case Timer::EMIOS2: + + case Timer::EMIOS2_Channel0: + case Timer::EMIOS2_Channel1: + case Timer::EMIOS2_Channel2: + case Timer::EMIOS2_Channel3: + case Timer::EMIOS2_Channel4: + case Timer::EMIOS2_Channel5: + case Timer::EMIOS2_Channel6: + case Timer::EMIOS2_Channel7: ret.base = S32K3XX_EMIOS2_BASE; ret.clock_register = 0; ret.clock_bit = 0; diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/io_timer.c b/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/io_timer.c index 2a3a0afce5..1a56a5338a 100644 --- a/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/io_timer.c @@ -868,6 +868,11 @@ int io_timer_set_ccr(unsigned channel, uint16_t value) } else { //FIXME why multiple by 2 + + if ((rC(channels_timer(channel), channel) & EMIOS_C_UCPRE_MASK) == 0) { + value = value * 4; + } + /* configure the channel */ irqstate_t flags = px4_enter_critical_section(); rA(channels_timer(channel), timer_io_channels[channel].timer_channel - 1) = EMIOS_A(value * 2); diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/pwm_servo.c b/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/pwm_servo.c index 6f613b2149..6178c86c64 100644 --- a/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/pwm_servo.c +++ b/platforms/nuttx/src/px4/nxp/s32k3xx/io_pins/pwm_servo.c @@ -128,13 +128,13 @@ int up_pwm_servo_set_rate_group_update(unsigned channel, unsigned rate) if (rate != 0) { - /* limit update rate to 1..10000Hz; somewhat arbitrary but safe */ + /* limit update rate to 1..20000Hz; somewhat arbitrary but safe */ if (rate < 1) { return -ERANGE; } - if (rate > 10000) { + if (rate > 20000) { return -ERANGE; } } diff --git a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c index 7e8a19726d..44a82c1652 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c @@ -888,9 +888,13 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode, #if !defined(BOARD_HAS_NO_CAPTURE) case IOTimerChanMode_Capture: + setbits = CCMR_C1_CAPTURE_INIT; + gpio = timer_io_channels[channel].gpio_in | GPIO_PULLUP; + break; + case IOTimerChanMode_CaptureDMA: setbits = CCMR_C1_CAPTURE_INIT; - gpio = timer_io_channels[channel].gpio_in; + gpio = timer_io_channels[channel].gpio_in | GPIO_PULLUP; break; #endif @@ -980,7 +984,6 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode, int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_channel_allocation_t masks) { - struct action_cache_t { uint32_t ccer_clearbits; uint32_t ccer_setbits; @@ -1065,7 +1068,6 @@ int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, io_timer_chann irqstate_t flags = px4_enter_critical_section(); - for (unsigned actions = 0; actions < arraySize(action_cache); actions++) { if (action_cache[actions].base != 0) { uint32_t rvalue = _REG32(action_cache[actions].base, STM32_GTIM_CCER_OFFSET); diff --git a/platforms/posix/CMakeLists.txt b/platforms/posix/CMakeLists.txt index 71c546b9ec..5b94634f57 100644 --- a/platforms/posix/CMakeLists.txt +++ b/platforms/posix/CMakeLists.txt @@ -87,7 +87,7 @@ install( DIRECTORY ${PROJECT_SOURCE_DIR}/posix-configs ${PROJECT_SOURCE_DIR}/test - ${CMAKE_BINARY_DIR}/etc + ${PX4_BINARY_DIR}/etc ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} DESTINATION ${PROJECT_NAME} @@ -201,6 +201,14 @@ elseif("${PX4_BOARD}" MATCHES "sitl") ${PROJECT_NAME}/build/px4_sitl_default ) + # gazebo files + install( + FILES + ${PROJECT_SOURCE_DIR}/Tools/simulation/gz/server.config + DESTINATION + ${PROJECT_NAME}/Tools/simulation/gz + ) + # gazebo dirs install( DIRECTORY diff --git a/platforms/posix/include/SerialImpl.hpp b/platforms/posix/include/SerialImpl.hpp index c7fb1ede81..32c549ad6e 100644 --- a/platforms/posix/include/SerialImpl.hpp +++ b/platforms/posix/include/SerialImpl.hpp @@ -60,10 +60,12 @@ public: bool close(); ssize_t bytesAvailable(); + ssize_t txSpaceAvailable(); ssize_t read(uint8_t *buffer, size_t buffer_size); ssize_t readAtLeast(uint8_t *buffer, size_t buffer_size, size_t character_count = 1, uint32_t timeout_us = 0); ssize_t write(const void *buffer, size_t buffer_size); + ssize_t writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_us = 0); void flush(); diff --git a/platforms/posix/src/px4/common/SerialImpl.cpp b/platforms/posix/src/px4/common/SerialImpl.cpp index 6d9b64a828..4859832829 100644 --- a/platforms/posix/src/px4/common/SerialImpl.cpp +++ b/platforms/posix/src/px4/common/SerialImpl.cpp @@ -169,8 +169,34 @@ bool SerialImpl::configure() // uart_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); - /* no parity, one stop bit, disable flow control */ - uart_config.c_cflag &= ~(CSTOPB | PARENB | CRTSCTS); + // Control modes + uart_config.c_cflag = 0; + + switch (_bytesize) { + case ByteSize::FiveBits: uart_config.c_cflag |= CS5; break; + + case ByteSize::SixBits: uart_config.c_cflag |= CS6; break; + + case ByteSize::SevenBits: uart_config.c_cflag |= CS7; break; + + case ByteSize::EightBits: uart_config.c_cflag |= CS8; break; + } + + if (_flowcontrol == FlowControl::Enabled) { + uart_config.c_cflag |= CRTSCTS; + } + + if (_parity != Parity::None) { + uart_config.c_cflag |= PARENB; + } + + if (_parity == Parity::Odd) { + uart_config.c_cflag |= PARODD; + } + + if (_stopbits == StopBits::Two) { + uart_config.c_cflag |= CSTOPB; + } /* set baud rate */ if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) { @@ -255,12 +281,31 @@ ssize_t SerialImpl::bytesAvailable() { if (!_open) { PX4_ERR("Device not open!"); + errno = EBADF; return -1; } ssize_t bytes_available = 0; int ret = ioctl(_serial_fd, FIONREAD, &bytes_available); - return ret >= 0 ? bytes_available : 0; + + if (ret < 0) { + return -1; + } + + return bytes_available; +} + +ssize_t SerialImpl::txSpaceAvailable() +{ + if (!_open) { + PX4_ERR("Device not open!"); + errno = EBADF; + return -1; + } + + // POSIX/Linux doesn't have a direct equivalent to NuttX's FIONSPACE + errno = ENOSYS; + return -1; } ssize_t SerialImpl::read(uint8_t *buffer, size_t buffer_size) @@ -274,7 +319,6 @@ ssize_t SerialImpl::read(uint8_t *buffer, size_t buffer_size) if (ret < 0) { PX4_DEBUG("%s read error %d", _port, ret); - } return ret; @@ -337,16 +381,75 @@ ssize_t SerialImpl::write(const void *buffer, size_t buffer_size) } int written = ::write(_serial_fd, buffer, buffer_size); - ::fsync(_serial_fd); if (written < 0) { - PX4_ERR("%s write error %d", _port, written); - + if (errno != EAGAIN) { + PX4_ERR("%s write error %d", _port, written); + } } return written; } +ssize_t SerialImpl::writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_ms) +{ + if (!_open) { + PX4_ERR("Cannot writeBlocking to serial device until it has been opened"); + return -1; + } + + const uint8_t *data = static_cast(buffer); + size_t total_written = 0; + const hrt_abstime start_time_us = hrt_absolute_time(); + const hrt_abstime timeout_us = timeout_ms * 1000; + + while (total_written < buffer_size) { + if (hrt_elapsed_time(&start_time_us) > timeout_us) { + PX4_WARN("Write timeout, sent %zu", total_written); + break; + } + + pollfd fds[1]; + fds[0].fd = _serial_fd; + fds[0].events = POLLOUT; + + hrt_abstime elapsed_us = hrt_elapsed_time(&start_time_us); + int remaining_timeout_ms = (timeout_us - elapsed_us) / 1000; + + if (remaining_timeout_ms <= 0) { + break; + } + + int result = ::poll(fds, 1, remaining_timeout_ms); + + if (result < 0) { + PX4_ERR("poll error %d", errno); + return -1; + } + + if (fds[0].revents & POLLOUT) { + // Write as much as we can + ssize_t written = ::write(_serial_fd, data + total_written, buffer_size - total_written); + + if (written < 0) { + if (errno == EAGAIN) { + // Buffer full, wait a bit and try again + px4_usleep(1000); + continue; + } + + PX4_ERR("Write error: %d", errno); + return -1; + + } else if (written > 0) { + total_written += written; + } + } + } + + return total_written; +} + void SerialImpl::flush() { if (_open) { @@ -387,7 +490,6 @@ uint32_t SerialImpl::getBaudrate() const bool SerialImpl::setBaudrate(uint32_t baudrate) { - // check if already configured if ((baudrate == _baudrate) && _open) { return true; } @@ -409,7 +511,17 @@ ByteSize SerialImpl::getBytesize() const bool SerialImpl::setBytesize(ByteSize bytesize) { - return bytesize == ByteSize::EightBits; + if ((bytesize == _bytesize) && _open) { + return true; + } + + _bytesize = bytesize; + + if (_open) { + return configure(); + } + + return true; } Parity SerialImpl::getParity() const @@ -419,7 +531,17 @@ Parity SerialImpl::getParity() const bool SerialImpl::setParity(Parity parity) { - return parity == Parity::None; + if ((parity == _parity) && _open) { + return true; + } + + _parity = parity; + + if (_open) { + return configure(); + } + + return true; } StopBits SerialImpl::getStopbits() const @@ -429,7 +551,17 @@ StopBits SerialImpl::getStopbits() const bool SerialImpl::setStopbits(StopBits stopbits) { - return stopbits == StopBits::One; + if ((stopbits == _stopbits) && _open) { + return true; + } + + _stopbits = stopbits; + + if (_open) { + return configure(); + } + + return true; } FlowControl SerialImpl::getFlowcontrol() const @@ -439,7 +571,17 @@ FlowControl SerialImpl::getFlowcontrol() const bool SerialImpl::setFlowcontrol(FlowControl flowcontrol) { - return flowcontrol == FlowControl::Disabled; + if ((flowcontrol == _flowcontrol) && _open) { + return true; + } + + _flowcontrol = flowcontrol; + + if (_open) { + return configure(); + } + + return true; } bool SerialImpl::getSingleWireMode() const diff --git a/platforms/posix/src/px4/common/drv_hrt.cpp b/platforms/posix/src/px4/common/drv_hrt.cpp index b510229bc0..1163f3fd8e 100644 --- a/platforms/posix/src/px4/common/drv_hrt.cpp +++ b/platforms/posix/src/px4/common/drv_hrt.cpp @@ -51,7 +51,7 @@ #include #include "hrt_work.h" -// Voxl2 board specific API definitions to get time offset +// Voxl board specific API definitions to get time #if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) #include "fc_sensor.h" #endif @@ -112,29 +112,6 @@ hrt_abstime hrt_absolute_time() #else // defined(ENABLE_LOCKSTEP_SCHEDULER) struct timespec ts; px4_clock_gettime(CLOCK_MONOTONIC, &ts); - -# if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) - hrt_abstime temp_abstime = ts_to_abstime(&ts); - int apps_time_offset = fc_sensor_get_time_offset(); - - if (apps_time_offset < 0) { - hrt_abstime temp_offset = -apps_time_offset; - - if (temp_offset >= temp_abstime) { - temp_abstime = 0; - - } else { - temp_abstime -= temp_offset; - } - - } else { - temp_abstime += (hrt_abstime) apps_time_offset; - } - - ts.tv_sec = temp_abstime / 1000000; - ts.tv_nsec = (temp_abstime % 1000000) * 1000; -# endif // defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) - return ts_to_abstime(&ts); #endif // defined(ENABLE_LOCKSTEP_SCHEDULER) } @@ -476,8 +453,21 @@ int px4_clock_gettime(clockid_t clk_id, struct timespec *tp) } #endif // defined(ENABLE_LOCKSTEP_SCHEDULER) - return system_clock_gettime(clk_id, tp); + int rv = system_clock_gettime(clk_id, tp); + +# if defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) + + // On VOXL use DSP clock as reference for MONOTONIC + if (clk_id == CLOCK_MONOTONIC) { + hrt_abstime temp_abstime = fc_sensor_get_dsp_timestamp_us(); + tp->tv_sec = temp_abstime / 1000000; + tp->tv_nsec = (temp_abstime % 1000000) * 1000; + } + +# endif // defined(CONFIG_MUORB_APPS_SYNC_TIMESTAMP) + + return rv; } #if defined(ENABLE_LOCKSTEP_SCHEDULER) diff --git a/platforms/posix/src/px4/common/main.cpp b/platforms/posix/src/px4/common/main.cpp index db6bfe850b..87af3b7344 100644 --- a/platforms/posix/src/px4/common/main.cpp +++ b/platforms/posix/src/px4/common/main.cpp @@ -73,6 +73,7 @@ #include #include #include +#include #include "apps.h" #include "px4_daemon/client.h" @@ -505,6 +506,7 @@ void sig_int_handler(int sig_num) fflush(stdout); printf("\nPX4 Exiting...\n"); fflush(stdout); + uorb_shutdown(); px4_daemon::Pxh::stop(); _exit_requested = true; } diff --git a/platforms/qurt/include/SerialImpl.hpp b/platforms/qurt/include/SerialImpl.hpp index 469bd6db97..09797a33f7 100644 --- a/platforms/qurt/include/SerialImpl.hpp +++ b/platforms/qurt/include/SerialImpl.hpp @@ -59,10 +59,12 @@ public: bool close(); ssize_t bytesAvailable(); + ssize_t txSpaceAvailable(); ssize_t read(uint8_t *buffer, size_t buffer_size); ssize_t readAtLeast(uint8_t *buffer, size_t buffer_size, size_t character_count = 1, uint32_t timeout_us = 0); ssize_t write(const void *buffer, size_t buffer_size); + ssize_t writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_us = 0); void flush(); diff --git a/platforms/qurt/src/px4/SerialImpl.cpp b/platforms/qurt/src/px4/SerialImpl.cpp index e176f528c9..ad93529f9b 100644 --- a/platforms/qurt/src/px4/SerialImpl.cpp +++ b/platforms/qurt/src/px4/SerialImpl.cpp @@ -103,25 +103,14 @@ bool SerialImpl::open() return false; } - if (_bytesize != ByteSize::EightBits) { - PX4_ERR("Qurt platform only supports ByteSize::EightBits"); - return false; - } + // Check all non-supported configurations without duplicating the error strings + if (!setBytesize(_bytesize)) { return false; } - if (_parity != Parity::None) { - PX4_ERR("Qurt platform only supports Parity::None"); - return false; - } + if (!setParity(_parity)) { return false; } - if (_stopbits != StopBits::One) { - PX4_ERR("Qurt platform only supports StopBits::One"); - return false; - } + if (!setStopbits(_stopbits)) { return false; } - if (_flowcontrol != FlowControl::Disabled) { - PX4_ERR("Qurt platform only supports FlowControl::Disabled"); - return false; - } + if (!setFlowcontrol(_flowcontrol)) { return false; } if (!validatePort(_port)) { PX4_ERR("Invalid port %s", _port); @@ -167,14 +156,33 @@ ssize_t SerialImpl::bytesAvailable() { if (!_open) { PX4_ERR("Device not open!"); + errno = EBADF; return -1; } uint32_t rx_bytes = 0; - (void) fc_uart_rx_available(_serial_fd, &rx_bytes); + int ret = fc_uart_rx_available(_serial_fd, &rx_bytes); + + if (ret < 0) { + return -1; + } + return (ssize_t) rx_bytes; } +ssize_t SerialImpl::txSpaceAvailable() +{ + if (!_open) { + PX4_ERR("Device not open!"); + errno = EBADF; + return -1; + } + + // QURT doesn't have a direct equivalent to NuttX's FIONSPACE + errno = ENOSYS; + return -1; +} + ssize_t SerialImpl::read(uint8_t *buffer, size_t buffer_size) { if (!_open) { @@ -259,6 +267,12 @@ ssize_t SerialImpl::readAtLeast(uint8_t *buffer, size_t buffer_size, size_t char } ssize_t SerialImpl::write(const void *buffer, size_t buffer_size) +{ + // TODO: Implement a non-blocking write in Qurt + return writeBlocking(buffer, buffer_size, 0); +} + +ssize_t SerialImpl::writeBlocking(const void *buffer, size_t buffer_size, uint32_t timeout_ms) { if (!_open) { PX4_ERR("Cannot write to serial device until it has been opened"); @@ -342,7 +356,12 @@ ByteSize SerialImpl::getBytesize() const bool SerialImpl::setBytesize(ByteSize bytesize) { - return bytesize == ByteSize::EightBits; + if (bytesize != ByteSize::EightBits) { + PX4_ERR("Qurt platform only supports ByteSize::EightBits"); + return false; + } + + return true; } Parity SerialImpl::getParity() const @@ -352,7 +371,12 @@ Parity SerialImpl::getParity() const bool SerialImpl::setParity(Parity parity) { - return parity == Parity::None; + if (parity != Parity::None) { + PX4_ERR("Qurt platform only supports Parity::None"); + return false; + } + + return true; } StopBits SerialImpl::getStopbits() const @@ -362,7 +386,12 @@ StopBits SerialImpl::getStopbits() const bool SerialImpl::setStopbits(StopBits stopbits) { - return stopbits == StopBits::One; + if (stopbits != StopBits::One) { + PX4_ERR("Qurt platform only supports StopBits::One"); + return false; + } + + return true; } FlowControl SerialImpl::getFlowcontrol() const @@ -372,7 +401,12 @@ FlowControl SerialImpl::getFlowcontrol() const bool SerialImpl::setFlowcontrol(FlowControl flowcontrol) { - return flowcontrol == FlowControl::Disabled; + if (flowcontrol != FlowControl::Disabled) { + PX4_ERR("Qurt platform only supports FlowControl::Disabled"); + return false; + } + + return true; } bool SerialImpl::getSingleWireMode() const @@ -382,7 +416,7 @@ bool SerialImpl::getSingleWireMode() const bool SerialImpl::setSingleWireMode() { - // Qurt platform does not support single wire mode + PX4_ERR("Qurt platform does not support single wire mode"); return false; } @@ -393,14 +427,18 @@ bool SerialImpl::getSwapRxTxMode() const bool SerialImpl::setSwapRxTxMode() { - // Qurt platform does not support swap rx tx mode + PX4_ERR("Qurt platform does not support swap rx tx mode"); return false; } bool SerialImpl::setInvertedMode(bool enable) { - // Qurt platform does not support inverted mode - return false == enable; + if (enable) { + PX4_ERR("Qurt platform does not support inverted mode"); + return false; + } + + return true; } bool SerialImpl::getInvertedMode() const { diff --git a/src/drivers/actuators/voxl_esc/module.yaml b/src/drivers/actuators/voxl_esc/module.yaml index c3bb1f4e6e..1a7e3fa319 100644 --- a/src/drivers/actuators/voxl_esc/module.yaml +++ b/src/drivers/actuators/voxl_esc/module.yaml @@ -19,6 +19,10 @@ actuator_output: label: 'ESC 3 Spin Direction' - param: 'VOXL_ESC_SDIR4' label: 'ESC 4 Spin Direction' + - param: 'VOXL_ESC_CMD' + label: 'ESC Command Type' + - param: 'VOXL_ESC_PWR_MIN' + label: 'ESC Minimum Power With PWM Command Type' output_groups: - param_prefix: VOXL_ESC group_label: 'ESCs' diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.cpp b/src/drivers/actuators/voxl_esc/voxl_esc.cpp index ec4db9e2d4..3414851b4b 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.cpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.cpp @@ -300,6 +300,7 @@ int VoxlEsc::load_params(voxl_esc_params_t *params, ch_assign_t *map) param_get(param_find("VOXL_ESC_SDIR3"), ¶ms->direction_map[2]); param_get(param_find("VOXL_ESC_SDIR4"), ¶ms->direction_map[3]); + param_get(param_find("VOXL_ESC_PWR_MIN"), ¶ms->pwr_min); param_get(param_find("VOXL_ESC_RPM_MIN"), ¶ms->rpm_min); param_get(param_find("VOXL_ESC_RPM_MAX"), ¶ms->rpm_max); @@ -311,10 +312,23 @@ int VoxlEsc::load_params(voxl_esc_params_t *params, ch_assign_t *map) param_get(param_find("VOXL_ESC_GPIO_CH"), ¶ms->gpio_ctl_channel); - if (params->rpm_min >= params->rpm_max) { - PX4_ERR("Invalid parameter VOXL_ESC_RPM_MIN. Please verify parameters."); - params->rpm_min = 0; - ret = PX4_ERROR; + param_get(param_find("VOXL_ESC_CMD"), ¶ms->cmd_type); + + if (params->cmd_type > VOXL_ESC_PWM_CMDS) { + PX4_WARN("Warning, VOXL_ESC_CMD set to invalid value %d. Using 1 instead", (int) params->cmd_type); + params->cmd_type = VOXL_ESC_PWM_CMDS; + + } else if (params->cmd_type < VOXL_ESC_RPM_CMDS) { + PX4_WARN("Warning, VOXL_ESC_CMD set to invalid value %d. Using 0 instead", (int) params->cmd_type); + params->cmd_type = VOXL_ESC_RPM_CMDS; + } + + if (params->cmd_type == VOXL_ESC_RPM_CMDS) { + if (params->rpm_min >= params->rpm_max) { + PX4_ERR("Invalid parameter VOXL_ESC_RPM_MIN. Please verify parameters."); + params->rpm_min = 0; + ret = PX4_ERROR; + } } if (params->turtle_motor_percent < 0 || params->turtle_motor_percent > 100) { @@ -392,19 +406,24 @@ int VoxlEsc::task_spawn(int argc, char *argv[]) int ch; const char *myoptarg = nullptr; - while ((ch = px4_getopt(argc, argv, "dv", &myoptind, &myoptarg)) != EOF) { - switch (ch) { - case 'd': - _device = argv[myoptind]; - break; + VoxlEsc *instance = new VoxlEsc(); - default: - break; + // Parse any passed in options + if ((argc > 1) && (argv[1] != nullptr)) { + while ((ch = px4_getopt(argc - 1, &argv[1], "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + _device = argv[myoptind]; + PX4_INFO("Configuring device as %s", _device); + break; + + default: + PX4_ERR("Unknown option: %c", ch); + break; + } } } - VoxlEsc *instance = new VoxlEsc(); - if (instance) { _object.store(instance); _task_id = task_id_is_work_queue; @@ -571,6 +590,8 @@ int VoxlEsc::parse_response(uint8_t *buf, uint8_t len, bool print_feedback) QC_ESC_FB_POWER_STATUS packet; memcpy(&packet, _fb_packet.buffer, packet_size); + _rx_power_status_count++; + float voltage = packet.voltage * 0.001f; // Voltage is reported at 1 mV resolution float current = packet.current * 0.008f; // Total current is reported at 8mA resolution @@ -907,8 +928,19 @@ int VoxlEsc::update_params() if (ret == PX4_OK) { _mixing_output.setAllDisarmedValues(0); _mixing_output.setAllFailsafeValues(0); - _mixing_output.setAllMinValues(_parameters.rpm_min); - _mixing_output.setAllMaxValues(_parameters.rpm_max); + + if (_parameters.cmd_type == VOXL_ESC_RPM_CMDS) { + _mixing_output.setAllMinValues(_parameters.rpm_min); + _mixing_output.setAllMaxValues(_parameters.rpm_max); + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + // we use a minimum value of 1, since 0 is for disarmed + _min_active_pwm = math::constrain(static_cast((_parameters.pwr_min * + static_cast(VOXL_ESC_PWM_MAX))), + VOXL_ESC_PWM_MIN, VOXL_ESC_PWM_MAX); + _mixing_output.setAllMinValues(_min_active_pwm); + _mixing_output.setAllMaxValues(VOXL_ESC_PWM_MAX); + } _rpm_fullscale = _parameters.rpm_max - _parameters.rpm_min; } @@ -1216,11 +1248,18 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], _esc_chans[i].rate_req = 0; } else { - if (_extended_rpm) { - if (outputs[i] > VOXL_ESC_RPM_MAX_EXT) { outputs[i] = VOXL_ESC_RPM_MAX_EXT; } + if ((_turtle_mode_en) || (_parameters.cmd_type == VOXL_ESC_RPM_CMDS)) { + if (_extended_rpm) { + if (outputs[i] > VOXL_ESC_RPM_MAX_EXT) { outputs[i] = VOXL_ESC_RPM_MAX_EXT; } - } else { - if (outputs[i] > VOXL_ESC_RPM_MAX) { outputs[i] = VOXL_ESC_RPM_MAX; } + } else { + if (outputs[i] > VOXL_ESC_RPM_MAX) { outputs[i] = VOXL_ESC_RPM_MAX; } + } + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + if (outputs[i] > VOXL_ESC_PWM_MAX) { outputs[i] = VOXL_ESC_PWM_MAX; } + + else if (outputs[i] < _min_active_pwm) { outputs[i] = _min_active_pwm; } } if (!_turtle_mode_en) { @@ -1235,18 +1274,34 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], Command cmd; - cmd.len = qc_esc_create_rpm_packet4_fb(_esc_chans[0].rate_req, - _esc_chans[1].rate_req, - _esc_chans[2].rate_req, - _esc_chans[3].rate_req, - _esc_chans[0].led, - _esc_chans[1].led, - _esc_chans[2].led, - _esc_chans[3].led, - _fb_idx, - cmd.buf, - sizeof(cmd.buf), - _extended_rpm); + + if (_parameters.cmd_type == VOXL_ESC_RPM_CMDS) { + cmd.len = qc_esc_create_rpm_packet4_fb(_esc_chans[0].rate_req, + _esc_chans[1].rate_req, + _esc_chans[2].rate_req, + _esc_chans[3].rate_req, + _esc_chans[0].led, + _esc_chans[1].led, + _esc_chans[2].led, + _esc_chans[3].led, + _fb_idx, + cmd.buf, + sizeof(cmd.buf), + _extended_rpm); + + } else if (_parameters.cmd_type == VOXL_ESC_PWM_CMDS) { + cmd.len = qc_esc_create_pwm_packet4_fb(_esc_chans[0].rate_req, + _esc_chans[1].rate_req, + _esc_chans[2].rate_req, + _esc_chans[3].rate_req, + _esc_chans[0].led, + _esc_chans[1].led, + _esc_chans[2].led, + _esc_chans[3].led, + _fb_idx, + cmd.buf, + sizeof(cmd.buf)); + } if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { PX4_ERR("Failed to send packet"); @@ -1336,16 +1391,22 @@ bool VoxlEsc::updateOutputs(uint16_t outputs[MAX_ACTUATORS], uint8_t num_writes = 0; - while (_esc_serial_passthru_sub.updated() && (num_writes < 4)) { - mavlink_tunnel_s uart_passthru{}; - _esc_serial_passthru_sub.copy(&uart_passthru); + // Don't do these faster than 20Hz + if (hrt_elapsed_time(&_last_uart_passthru) > 50_ms) { + _last_uart_passthru = hrt_absolute_time(); - if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { - PX4_ERR("Failed to send mavlink tunnel data to esc"); - return false; + // Don't do more than a few writes each check + while (_esc_serial_passthru_sub.updated() && (num_writes < 4)) { + mavlink_tunnel_s uart_passthru{}; + _esc_serial_passthru_sub.copy(&uart_passthru); + + if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { + PX4_ERR("Failed to send mavlink tunnel data to esc"); + return false; + } + + num_writes++; } - - num_writes++; } perf_count(_output_update_perf); @@ -1625,6 +1686,8 @@ void VoxlEsc::print_params() PX4_INFO("Params: VOXL_ESC_SDIR3: %" PRId32, _parameters.direction_map[2]); PX4_INFO("Params: VOXL_ESC_SDIR4: %" PRId32, _parameters.direction_map[3]); + PX4_INFO("Params: VOXL_ESC_PWR_MIN: %f", (double) _parameters.pwr_min); + PX4_INFO("Params: VOXL_ESC_RPM_MIN: %" PRId32, _parameters.rpm_min); PX4_INFO("Params: VOXL_ESC_RPM_MAX: %" PRId32, _parameters.rpm_max); @@ -1641,6 +1704,8 @@ void VoxlEsc::print_params() PX4_INFO("Params: VOXL_ESC_T_OVER: %" PRId32, _parameters.esc_over_temp_threshold); PX4_INFO("Params: VOXL_ESC_GPIO_CH: %" PRId32, _parameters.gpio_ctl_channel); + + PX4_INFO("Params: VOXL_ESC_CMD: %" PRId32, _parameters.cmd_type); } int VoxlEsc::print_status() @@ -1650,6 +1715,10 @@ int VoxlEsc::print_status() PX4_INFO("UART port: %s", _device); PX4_INFO("UART open: %s", _uart_port.isOpen() ? "yes" : "no"); + PX4_INFO("CRC error count: %lu", (long unsigned int) _rx_crc_error_count); + PX4_INFO("Packet RX count: %lu", (long unsigned int) _rx_packet_count); + PX4_INFO("Power status count: %lu", (long unsigned int) _rx_power_status_count); + PX4_INFO(""); print_params(); PX4_INFO(""); @@ -1689,6 +1758,7 @@ const char * VoxlEsc::board_id_to_name(int board_id) case 40: return "ModalAi 4-in-1 ESC (M0129-3)"; case 41: return "ModalAi 4-in-1 ESC (M0134-6)"; case 42: return "ModalAi 4-in-1 ESC (M0138-1)"; + case 44: return "ModalAi 4-in-1 ESC (M0129-6)"; default: return "Unknown Board"; } } diff --git a/src/drivers/actuators/voxl_esc/voxl_esc.hpp b/src/drivers/actuators/voxl_esc/voxl_esc.hpp index c5885b20d7..d103f902d0 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc.hpp +++ b/src/drivers/actuators/voxl_esc/voxl_esc.hpp @@ -117,8 +117,8 @@ private: static constexpr uint16_t DISARMED_VALUE = 0; - static constexpr uint16_t VOXL_ESC_PWM_MIN = 0; - static constexpr uint16_t VOXL_ESC_PWM_MAX = 800; + static constexpr int VOXL_ESC_PWM_MIN = 1; + static constexpr int VOXL_ESC_PWM_MAX = 800; static constexpr uint16_t VOXL_ESC_DEFAULT_RPM_MIN = 5000; static constexpr uint16_t VOXL_ESC_DEFAULT_RPM_MAX = 17000; @@ -148,6 +148,9 @@ private: static constexpr uint32_t VOXL_ESC_GPIO_CTL_AUX5 = 5; static constexpr uint32_t VOXL_ESC_GPIO_CTL_AUX6 = 6; + static constexpr int32_t VOXL_ESC_RPM_CMDS = 0; + static constexpr int32_t VOXL_ESC_PWM_CMDS = 1; + Serial _uart_port{}; typedef struct { @@ -159,6 +162,7 @@ private: float turtle_stick_minf{0.15f}; float turtle_cosphi{0.99f}; int32_t baud_rate{VOXL_ESC_DEFAULT_BAUD}; + float pwr_min{0.05f}; int32_t rpm_min{VOXL_ESC_DEFAULT_RPM_MIN}; int32_t rpm_max{VOXL_ESC_DEFAULT_RPM_MAX}; int32_t function_map[VOXL_ESC_OUTPUT_CHANNELS] {0, 0, 0, 0}; @@ -169,6 +173,7 @@ private: int32_t esc_warn_temp_threshold{0}; int32_t esc_over_temp_threshold{0}; int32_t gpio_ctl_channel{0}; + int32_t cmd_type{0}; } voxl_esc_params_t; struct EscChan { @@ -222,6 +227,8 @@ private: bool _need_version_info{true}; QC_ESC_EXTENDED_VERSION_INFO _version_info[VOXL_ESC_OUTPUT_CHANNELS]; + int _min_active_pwm{1}; + voxl_esc_params_t _parameters; int update_params(); int load_params(voxl_esc_params_t *params, ch_assign_t *map); @@ -250,13 +257,15 @@ private: int _fb_idx; uint32_t _rx_crc_error_count{0}; uint32_t _rx_packet_count{0}; + uint32_t _rx_power_status_count{0}; static const uint8_t READ_BUF_SIZE = 128; uint8_t _read_buf[READ_BUF_SIZE]; Battery _battery; - static constexpr unsigned _battery_report_interval{100_ms}; + static constexpr unsigned _battery_report_interval{20_ms}; hrt_abstime _last_battery_report_time; + hrt_abstime _last_uart_passthru{0}; bool _device_initialized{false}; diff --git a/src/drivers/actuators/voxl_esc/voxl_esc_params.c b/src/drivers/actuators/voxl_esc/voxl_esc_params.c index b0526ecf1f..6ccfeb60ba 100644 --- a/src/drivers/actuators/voxl_esc/voxl_esc_params.c +++ b/src/drivers/actuators/voxl_esc/voxl_esc_params.c @@ -276,3 +276,31 @@ PARAM_DEFINE_INT32(VOXL_ESC_T_OVER, 0); * @max 6 */ PARAM_DEFINE_INT32(VOXL_ESC_GPIO_CH, 0); + +/** + * UART ESC command type + * + * Selects between RPM or PWM commands + * + * @reboot_required true + * + * @group VOXL ESC + * @value 0 - RPM + * @value 1 - PWM + * @min 0 + * @max 1 + */ +PARAM_DEFINE_INT32(VOXL_ESC_CMD, 0); + +/** + * UART ESC Minimum motor power + * + * Minimum motor power for ESC when VOXL_ESC_CMD is set for PWM. + * Make sure to set this high enough so that the motors are always spinning + * while armed. + * + * @group VOXL ESC + * @min 0.0 + * @max 1.0 + */ +PARAM_DEFINE_FLOAT(VOXL_ESC_PWR_MIN, 0.05); diff --git a/src/drivers/adc/ads1115/ads1115_main.cpp b/src/drivers/adc/ads1115/ads1115_main.cpp index 1967b58263..140b8dfd0e 100644 --- a/src/drivers/adc/ads1115/ads1115_main.cpp +++ b/src/drivers/adc/ads1115/ads1115_main.cpp @@ -154,6 +154,7 @@ If enabled, internal ADCs are not used. )DESCR_STR"); PRINT_MODULE_USAGE_NAME("ads1115", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("adc"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x48); diff --git a/src/drivers/adc/ads7953/ADS7953.cpp b/src/drivers/adc/ads7953/ADS7953.cpp new file mode 100644 index 0000000000..8a25b56c5b --- /dev/null +++ b/src/drivers/adc/ads7953/ADS7953.cpp @@ -0,0 +1,135 @@ + +#include "ADS7953.h" +#include +#include +#include +#include + +ADS7953::ADS7953(const I2CSPIDriverConfig &config) : + SPI(config), + I2CSPIDriver(config), + ModuleParams(nullptr), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) +{ + static_assert(arraySize(adc_report_s::channel_id) >= NUM_CHANNELS, "ADS7953 reports 16 channels"); +} + +ADS7953::~ADS7953() +{ + ScheduleClear(); + perf_free(_cycle_perf); + perf_free(_comms_errors); +} + +int ADS7953::init() +{ + int ret = SPI::init(); + + if (ret != PX4_OK) { + PX4_DEBUG("SPI::init failed (%i)", ret); + return ret; + } + + _adc_report.device_id = this->get_device_id(); + _adc_report.v_ref = _adc_ads7953_refv.get(); + _adc_report.resolution = 4096; + + for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) { + _adc_report.channel_id[i] = -1; + } + + ScheduleOnInterval(SAMPLE_INTERVAL, SAMPLE_INTERVAL); + return PX4_OK; +} + +int ADS7953::probe() +{ + // The ADS7953 has no ID register which we can check, so we verify the device via the returned channel ID. + // We set the mode to "manual mode" and the channel to measure to 1. + // If the returned channel ID on the third message is 1, we assume the ADS7953 is connected. + uint8_t recv_data[2]; + + int ret = rw_msg(&recv_data[0], 1, true); + + if (ret != PX4_OK) { + PX4_DEBUG("ADS7953 probing failed (%i)", ret); + return ret; + } + + ret |= rw_msg(&recv_data[0], 0, false); + ret |= rw_msg(&recv_data[0], 0, true); + + if (ret != PX4_OK || (recv_data[0] >> 4) != 1U) { + PX4_DEBUG("ADS7953 probing failed (%i)", ret); + return PX4_ERROR; + } + + return PX4_OK; +} + +int ADS7953::rw_msg(uint8_t *recv_data, uint8_t ch, bool change_channel) +{ + uint8_t send_data[2]; + + if (change_channel) { + send_data[0] = 0x10 | (ch >> 1); + send_data[1] = 0x00 | (ch << 7); + + } else { + send_data[0] = 0x00; + send_data[1] = 0x00; + } + + return transfer(&send_data[0], &recv_data[0], 2); +} + +int ADS7953::get_measurements() +{ + uint8_t recv_data[2]; + int count = 0; + uint16_t mask = 0x00; + uint8_t idx = 0; + + while (count < NUM_CHANNELS) { + if (rw_msg(&recv_data[0], idx, true) == PX4_OK) { + uint8_t ch_id = (recv_data[0] >> 4); + + //check if we already have a measurement for the returned channel + if (!(mask & (1U << ch_id))) { + mask |= (1U << ch_id); + count++; + _adc_report.channel_id[ch_id] = ch_id; + _adc_report.raw_data[ch_id] = ((((uint16_t) recv_data[0]) & 0x0F) << 8) | recv_data[1]; + } + + } else { + perf_count(_comms_errors); + } + + // Find index to measure next + for (int i = 1; i <= NUM_CHANNELS; i++) { + uint8_t candidate_id = (idx + i) % NUM_CHANNELS; + + if (!(mask & (1U << candidate_id))) { + idx = candidate_id; + break; + } + } + } + + return 0; +} + +void ADS7953::RunImpl() +{ + perf_begin(_cycle_perf); + get_measurements(); + _adc_report.timestamp = hrt_absolute_time(); + _adc_report_pub.publish(_adc_report); + perf_end(_cycle_perf); + + for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) { + _adc_report.channel_id[i] = -1; + } +} diff --git a/src/drivers/adc/ads7953/ADS7953.h b/src/drivers/adc/ads7953/ADS7953.h new file mode 100644 index 0000000000..7d955a274f --- /dev/null +++ b/src/drivers/adc/ads7953/ADS7953.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace time_literals; + + +class ADS7953 : public device::SPI, public I2CSPIDriver, public ModuleParams +{ +public: + ADS7953(const I2CSPIDriverConfig &config); + ~ADS7953() override; + static void print_usage(); + + int init() override; + void RunImpl(); + int probe() override; + + +private: + static constexpr int NUM_CHANNELS = 16; + uORB::PublicationMulti _adc_report_pub{ORB_ID(adc_report)}; + + static const hrt_abstime SAMPLE_INTERVAL{10_ms}; + perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; + + DEFINE_PARAMETERS( + (ParamFloat) _adc_ads7953_refv + ) + adc_report_s _adc_report{}; + + int get_measurements(); + int rw_msg(uint8_t *recv_data, uint8_t ch, bool change_channel); +}; diff --git a/src/drivers/adc/ads7953/CMakeLists.txt b/src/drivers/adc/ads7953/CMakeLists.txt new file mode 100644 index 0000000000..fbb25e5f5d --- /dev/null +++ b/src/drivers/adc/ads7953/CMakeLists.txt @@ -0,0 +1,46 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__adc__ads7953 + MAIN ads7953 + COMPILE_FLAGS + SRCS + ADS7953.cpp + ADS7953.h + ads7953_main.cpp + MODULE_CONFIG + module.yaml + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/adc/ads7953/Kconfig b/src/drivers/adc/ads7953/Kconfig new file mode 100644 index 0000000000..a50f4c8b26 --- /dev/null +++ b/src/drivers/adc/ads7953/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_ADC_ADS7953 + bool "ADS7953 driver" + default n + ---help--- + Enable support for ADS7953 diff --git a/src/drivers/adc/ads7953/ads7953_main.cpp b/src/drivers/adc/ads7953/ads7953_main.cpp new file mode 100644 index 0000000000..9c9de10faf --- /dev/null +++ b/src/drivers/adc/ads7953/ads7953_main.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include "ADS7953.h" + +void ADS7953::print_usage() +{ + PRINT_MODULE_USAGE_NAME("ads7953", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("adc"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +extern "C" int ads7953_main(int argc, char *argv[]) +{ + using ThisDriver = ADS7953; + BusCLIArguments cli{false, true}; + cli.spi_mode = SPIDEV_MODE0; + cli.default_spi_frequency = 10 * 1000 * 1000; + const char *name = MODULE_NAME; + const char *verb = cli.parseDefaultArguments(argc, argv); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(name, cli, DRV_ADC_DEVTYPE_ADS7953); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} diff --git a/src/drivers/adc/ads7953/module.yaml b/src/drivers/adc/ads7953/module.yaml new file mode 100644 index 0000000000..9097daeb08 --- /dev/null +++ b/src/drivers/adc/ads7953/module.yaml @@ -0,0 +1,29 @@ +__max_num_config_instances: &max_num_config_instances 1 + +module_name: ADS7953 + +parameters: + - group: ADC + definitions: + ADC_ADS7953_EN: + description: + short: Enable ADS7953 + long: | + Enable the driver for the ADS7953 board + type: boolean + reboot_required: true + default: 0 + + ADC_ADS7953_REFV: + description: + short: Applied reference Voltage. + long: | + The voltage applied to the ADS7953 board as reference + type: float + unit: V + min: 2.0 + max: 3.0 + decimal: 2 + increment: 0.01 + reboot_required: true + default: 2.5 diff --git a/src/drivers/adc/board_adc/ADC.cpp b/src/drivers/adc/board_adc/ADC.cpp index 7bf553f9b4..936f0971ac 100644 --- a/src/drivers/adc/board_adc/ADC.cpp +++ b/src/drivers/adc/board_adc/ADC.cpp @@ -410,6 +410,7 @@ ADC driver. )DESCR_STR"); PRINT_MODULE_USAGE_NAME("adc", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("adc"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_COMMAND("test"); PRINT_MODULE_USAGE_PARAM_FLAG('n', "Do not publish ADC report, only system power", true); diff --git a/src/drivers/adc/board_adc/ADC.hpp b/src/drivers/adc/board_adc/ADC.hpp index 47f9538814..c765d596b4 100644 --- a/src/drivers/adc/board_adc/ADC.hpp +++ b/src/drivers/adc/board_adc/ADC.hpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -110,7 +111,7 @@ private: const uint32_t _base_address; px4_adc_msg_t *_samples{nullptr}; /**< sample buffer */ - uORB::Publication _to_adc_report{ORB_ID(adc_report)}; + uORB::PublicationMulti _to_adc_report{ORB_ID(adc_report)}; uORB::Publication _to_system_power{ORB_ID(system_power)}; #ifdef BOARD_GPIO_VDD_5V_COMP_VALID diff --git a/src/drivers/adc/tla2528/CMakeLists.txt b/src/drivers/adc/tla2528/CMakeLists.txt new file mode 100644 index 0000000000..1d77bfe65a --- /dev/null +++ b/src/drivers/adc/tla2528/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__adc__tla2528 + MAIN tla2528 + COMPILE_FLAGS + SRCS + tla2528.cpp + tla2528_main.cpp + MODULE_CONFIG + module.yaml + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/adc/tla2528/Kconfig b/src/drivers/adc/tla2528/Kconfig new file mode 100644 index 0000000000..ea3ae7e317 --- /dev/null +++ b/src/drivers/adc/tla2528/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_ADC_TLA2528 + bool "TLA2528 driver" + default n + ---help--- + Enable support for TLA2528 diff --git a/src/drivers/adc/tla2528/module.yaml b/src/drivers/adc/tla2528/module.yaml new file mode 100644 index 0000000000..b9059ddf04 --- /dev/null +++ b/src/drivers/adc/tla2528/module.yaml @@ -0,0 +1,30 @@ +__max_num_config_instances: &max_num_config_instances 1 + +module_name: TLA2528 + +parameters: + - group: ADC + definitions: + ADC_TLA2528_EN: + description: + short: Enable TLA2528 + long: | + Enable the driver for the TLA2528 + type: boolean + reboot_required: true + default: 0 + + + ADC_TLA2528_REFV: + description: + short: Applied reference Voltage. + long: | + The voltage applied to the TLA2528 board as reference + type: float + unit: V + min: 2.0 + max: 3.0 + decimal: 2 + increment: 0.01 + reboot_required: true + default: 2.5 diff --git a/src/drivers/adc/tla2528/tla2528.cpp b/src/drivers/adc/tla2528/tla2528.cpp new file mode 100644 index 0000000000..e537a3ca61 --- /dev/null +++ b/src/drivers/adc/tla2528/tla2528.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "tla2528.h" +#include + +#define READ 0x10 +#define WRITE 0x08 +#define SET_BIT 0x18 +#define CLEAR_BIT 0x20 + +#define SYSTEM_STATUS 0x00 +#define GENERAL_CFG 0x01 +#define DATA_CFG 0x02 +#define OSR_CFG 0x03 +#define OPMODE_CFG 0x04 +#define PIN_CFG 0x05 +#define GPIO_CFG 0x07 +#define GPO_DRIVE_CFG 0x09 +#define GPO_VALUE 0x0B +#define GPI_VALUE 0x0D +#define SEQUENCE_CFG 0x10 +#define CHANNEL_SEL 0x11 +#define AUTO_SEQ_CH_SEL 0x12 + +TLA2528::TLA2528(const I2CSPIDriverConfig &config) : + I2C(config), + I2CSPIDriver(config), + ModuleParams(nullptr), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) +{ + static_assert(arraySize(adc_report_s::channel_id) >= NUM_CHANNELS, "TLA2528 reports 8 channels"); +} + +TLA2528::~TLA2528() +{ + ScheduleClear(); + perf_free(_cycle_perf); + perf_free(_comms_errors); +} + +int TLA2528::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + PX4_DEBUG("I2C::init failed (%i)", ret); + return ret; + } + + _adc_report.device_id = this->get_device_id(); + _adc_report.v_ref = _adc_tla2528_refv.get(); + _adc_report.resolution = 4096; + + ScheduleClear(); + ScheduleOnInterval(SAMPLE_INTERVAL, SAMPLE_INTERVAL); + return PX4_OK; +} + +int TLA2528::init_calibrate() +{ + uint8_t send_data[3]; + send_data[0] = SET_BIT; + send_data[1] = GENERAL_CFG; + send_data[2] = 0x02; + int ret = transfer(&send_data[0], 3, nullptr, 0); + + if (ret != PX4_OK) { + PX4_DEBUG("TLA2528::Initializing Calibration failed (%i)", ret); + perf_count(_comms_errors); + } + + return ret; +} + +int TLA2528::poll_calibrate() +{ + uint8_t send_data[2]; + uint8_t recv_data; + send_data[0] = READ; + send_data[1] = GENERAL_CFG; + int ret = transfer(&send_data[0], 2, nullptr, 0); + ret |= transfer(nullptr, 0, &recv_data, 1); + + if (recv_data & 2u) { + PX4_DEBUG("TLA2528::Calibration not yet finished"); + perf_count(_comms_errors); + return PX4_ERROR; + } + + return ret; +} + +int TLA2528::init_reset() +{ + uint8_t send_data[3]; + send_data[0] = SET_BIT; + send_data[1] = GENERAL_CFG; + send_data[2] = 0x01; + int ret = transfer(&send_data[0], 3, nullptr, 0); + + if (ret != PX4_OK) { + PX4_DEBUG("TLA2528::Initializing Reset failed (%i)", ret); + perf_count(_comms_errors); + } + + return ret; +} + +int TLA2528::poll_reset() +{ + uint8_t send_data[2]; + uint8_t recv_data; + send_data[0] = READ; + send_data[1] = GENERAL_CFG; + int ret = transfer(&send_data[0], 2, nullptr, 0); + ret |= transfer(nullptr, 0, &recv_data, 1); + + if (ret != PX4_OK) { + perf_count(_comms_errors); + return ret; + } + + if (recv_data & 1u) { + PX4_DEBUG("TLA2528::Reset not finished"); + return PX4_ERROR; + } + + return ret; +} + +void TLA2528::adc_get() +{ + // Start sequential read + uint8_t send_data[3] = {SET_BIT, SEQUENCE_CFG, 0x10}; + uint8_t recv_data[2]; + int ret = transfer(&send_data[0], 3, nullptr, 0); + + if (ret != PX4_OK) { + perf_count(_comms_errors); + return; + } + + // Read data + for (int i = 0; i < NUM_CHANNELS; i++) { + ret = transfer(nullptr, 0, &recv_data[0], 2); + + if (ret == PX4_OK) { + uint16_t tmp = ((uint16_t)recv_data[0]) << 8; + uint16_t measurement = (tmp | recv_data[1]) >> 4; + uint8_t ch_id = recv_data[1] & 0x0F; + + _adc_report.channel_id[i] = ch_id; + _adc_report.raw_data[i] = measurement; + + } else { + perf_count(_comms_errors); + } + } + + // Stop sequential read + send_data[0] = CLEAR_BIT; + send_data[1] = SEQUENCE_CFG; + send_data[2] = 0x10; + transfer(&send_data[0], 3, nullptr, 0); + return; +} + +int TLA2528::probe() +{ + for (int i = 0; i < 3; i++) { + // Select channel 0 + uint8_t send_data[3]; + send_data[0] = WRITE; + send_data[1] = CHANNEL_SEL; + send_data[2] = 0x00; // Channel 0 + int ret = transfer(&send_data[0], 3, nullptr, 0); + + // Put device in in manual mode + send_data[0] = WRITE; + send_data[1] = OPMODE_CFG; + send_data[2] = 0x00; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + // Set device in debug mode (should respond with 0xA5AX to all reads) + send_data[0] = SET_BIT; + send_data[1] = DATA_CFG; + send_data[2] = 0x80; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + // Read + uint8_t recv_data[2]; + ret |= transfer(nullptr, 0, &recv_data[0], 2); + + // Turn debug mode off + send_data[0] = CLEAR_BIT; + send_data[1] = DATA_CFG; + send_data[2] = 0x80; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + if (recv_data[0] == 165 && recv_data[1] >= 160 && ret == PX4_OK) { + return PX4_OK; + } + + px4_sleep(1); + } + + return PX4_ERROR; +} + +int TLA2528::configure() +{ + uint8_t send_data[3]; + // Configure pins as analog + send_data[0] = SET_BIT; + send_data[1] = PIN_CFG; + send_data[2] = 0x00; + int ret = transfer(&send_data[0], 3, nullptr, 0); + + // Append channel-id to measurements + send_data[0] = SET_BIT; + send_data[1] = DATA_CFG; + send_data[2] = 0x10; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + // Activate all pins + send_data[0] = SET_BIT; + send_data[1] = AUTO_SEQ_CH_SEL; + send_data[2] = 0xFF; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + // Set seq-mode + send_data[0] = SET_BIT; + send_data[1] = SEQUENCE_CFG; + send_data[2] = 0x01; + ret |= transfer(&send_data[0], 3, nullptr, 0); + + if (ret != PX4_OK) { + perf_count(_comms_errors); + PX4_DEBUG("TLA2528::Configuring failed (%i)", ret); + } + + return ret; +} + +void TLA2528::exit_and_cleanup() +{ + I2CSPIDriverBase::exit_and_cleanup(); // nothing to do +} + +void TLA2528::RunImpl() +{ + if (should_exit()) { + PX4_INFO("stopping"); + return; // stop and return immediately to avoid unexpected schedule from stopping procedure + } + + int ret; + + switch (_state) { + case STATE::RESET: + ret = init_reset(); + + if (ret == PX4_OK) { + _state = STATE::CONFIGURE; + } + + break; + + case STATE::CONFIGURE: + ret = poll_reset(); + ret |= configure(); + ret |= init_calibrate(); + + if (ret == PX4_OK) { + _state = STATE::CALIBRATE; + + } else { + _state = STATE::RESET; + } + + break; + + case STATE::CALIBRATE: + ret = poll_calibrate(); + + if (ret == PX4_OK) { + _state = STATE::WORK; + + } else { + _state = STATE::RESET; + } + + break; + + case STATE::WORK: + perf_begin(_cycle_perf); + adc_get(); + _adc_report.timestamp = hrt_absolute_time(); + _adc_report_pub.publish(_adc_report); + perf_end(_cycle_perf); + break; + } + + for (unsigned i = 0; i < arraySize(adc_report_s::channel_id); ++i) { + _adc_report.channel_id[i] = -1; + } +} diff --git a/src/drivers/adc/tla2528/tla2528.h b/src/drivers/adc/tla2528/tla2528.h new file mode 100644 index 0000000000..b95aaf364e --- /dev/null +++ b/src/drivers/adc/tla2528/tla2528.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +using namespace time_literals; + +class TLA2528 : public device::I2C, public I2CSPIDriver, public ModuleParams +{ +public: + TLA2528(const I2CSPIDriverConfig &config); + ~TLA2528() override; + + static void print_usage(); + int init() override; + void RunImpl(); + int probe() override; + void print_status() override; + +private: + static const hrt_abstime SAMPLE_INTERVAL{10_ms}; + static constexpr int NUM_CHANNELS = 8; + + perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; + + uORB::PublicationMulti _adc_report_pub{ORB_ID(adc_report)}; + adc_report_s _adc_report{}; + + DEFINE_PARAMETERS( + (ParamFloat) _adc_tla2528_refv + ) + + int init_reset(); + int poll_reset(); + int configure(); + int init_calibrate(); + int poll_calibrate(); + void adc_get(); + void exit_and_cleanup() override; + + enum class STATE : uint8_t { + RESET, + CONFIGURE, + CALIBRATE, + WORK + }; + STATE _state{STATE::RESET}; +}; diff --git a/src/drivers/adc/tla2528/tla2528_main.cpp b/src/drivers/adc/tla2528/tla2528_main.cpp new file mode 100644 index 0000000000..652ac150d4 --- /dev/null +++ b/src/drivers/adc/tla2528/tla2528_main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include +#include +#include "tla2528.h" + +void TLA2528::print_usage() +{ + PRINT_MODULE_USAGE_NAME("TLA2528", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("adc"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +void TLA2528::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); + perf_print_counter(_comms_errors); +} + +extern "C" int tla2528_main(int argc, char *argv[]) +{ + using ThisDriver = TLA2528; + BusCLIArguments cli{true, false}; + + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x10; + const char *name = MODULE_NAME; + const char *verb = cli.parseDefaultArguments(argc, argv); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(name, cli, DRV_ADC_DEVTYPE_TLA2528); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} diff --git a/src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.cpp b/src/drivers/auterion_autostarter/AuterionAutostarter.cpp similarity index 61% rename from src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.cpp rename to src/drivers/auterion_autostarter/AuterionAutostarter.cpp index 294d3ba7b6..28bd1b9a84 100644 --- a/src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.cpp +++ b/src/drivers/auterion_autostarter/AuterionAutostarter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2026 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,26 +35,26 @@ * Automatic handling power monitors */ -#include "PowerMonitorSelectorAuterion.h" -#include "../ina226/ina226.h" +#include "AuterionAutostarter.h" +#include "../power_monitor/ina226/ina226.h" #include #include -PowerMonitorSelectorAuterion::PowerMonitorSelectorAuterion() : +AuterionAutostarter::AuterionAutostarter() : ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default) { } -PowerMonitorSelectorAuterion::~PowerMonitorSelectorAuterion() = default; +AuterionAutostarter::~AuterionAutostarter() = default; -bool PowerMonitorSelectorAuterion::init() +bool AuterionAutostarter::init() { ScheduleNow(); return true; } -void PowerMonitorSelectorAuterion::Run() +void AuterionAutostarter::Run() { if (should_exit()) { exit_and_cleanup(); @@ -83,33 +83,48 @@ void PowerMonitorSelectorAuterion::Run() ScheduleDelayed(RUN_INTERVAL); } -void PowerMonitorSelectorAuterion::try_eeprom_start() +void AuterionAutostarter::try_eeprom_start() { static_assert(sizeof(_buses) / sizeof(Buses) == BUSES_NUMBERS, "Unexpected number of buses"); - static_assert(sizeof(_eeprom_blocks_pm) / sizeof(EepromBlockPm) == EEPROM_MAX_BLOCKS, + static_assert(sizeof(_eeprom_decoded_blocks) / sizeof(DecodedBlock) == EEPROM_MAX_BLOCKS, "Unexpected number of EEPROM PM blocks"); for (uint32_t i = 0U; i < BUSES_NUMBERS; i++) { if (!_buses[i].started) { if (eeprom_read(i) == PX4_OK) { - for (int ii = 0U; ii < _eeprom_valid_blocks_pm && ii < EEPROM_MAX_BLOCKS; ii++) { - EepromBlockPm eeprom_block_pm = _eeprom_blocks_pm[ii]; + int ret_val = PX4_OK; - uint16_t dev_type = eeprom_block_pm.dev_type; - set_max_current(dev_type, eeprom_block_pm.max_current); - set_shunt_value(dev_type, eeprom_block_pm.shunt_value); - int ret_val = start_pm(_buses[i].bus_number, dev_type, eeprom_block_pm.i2c_addr, _buses[i].id); + for (uint32_t ii = 0U; ii < _eeprom_num_decoded_blocks && ii < EEPROM_MAX_BLOCKS; ii++) { + DecodedBlock decoded_block = _eeprom_decoded_blocks[ii]; - if (ret_val == PX4_OK) { - _buses[i].started = true; + switch (decoded_block.block_type) { + case TYPE_PM: { + EepromBlockPm block_pm = decoded_block.block_pm; + uint16_t dev_type = block_pm.dev_type; + set_max_current(dev_type, block_pm.max_current); + set_shunt_value(dev_type, block_pm.shunt_value); + ret_val |= start_pm(_buses[i].bus_number, dev_type, block_pm.i2c_addr, _buses[i].id); + break; + } + + case TYPE_PWM_EXPANDER: { + EepromBlockPwmExpander block_pwm_expader = decoded_block.block_pwm_expander; + uint16_t dev_type = block_pwm_expader.dev_type; + ret_val |= start_i2c_driver(_buses[i].bus_number, dev_type, block_pwm_expader.i2c_addr); + break; + } } } + + if (ret_val == PX4_OK) { + _buses[i].started = true; + } } } } } -void PowerMonitorSelectorAuterion::try_probe_start() +void AuterionAutostarter::try_probe_start() { static_assert(sizeof(_sensors) / sizeof(Sensor) == SENSORS_NUMBER, "Unexpected number of sensors"); @@ -133,7 +148,7 @@ void PowerMonitorSelectorAuterion::try_probe_start() } } -int PowerMonitorSelectorAuterion::ina226_probe(const uint32_t instance) const +int AuterionAutostarter::ina226_probe(const uint32_t instance) const { I2CWrapper i2c{_sensors[instance].bus_number}; int ret = PX4_ERROR; @@ -177,10 +192,10 @@ int PowerMonitorSelectorAuterion::ina226_probe(const uint32_t instance) const return ret; } -int PowerMonitorSelectorAuterion::eeprom_read(const uint32_t instance) +int AuterionAutostarter::eeprom_read(const uint32_t instance) { I2CWrapper i2c{_buses[instance].bus_number}; - _eeprom_valid_blocks_pm = 0; + _eeprom_num_decoded_blocks = 0; EepromHeader eeprom_header; if (i2c.is_valid()) { @@ -228,7 +243,7 @@ int PowerMonitorSelectorAuterion::eeprom_read(const uint32_t instance) return PX4_ERROR; } - _eeprom_valid_blocks_pm = transferred_blocks; + _eeprom_num_decoded_blocks = transferred_blocks; return PX4_OK; } else { @@ -236,7 +251,7 @@ int PowerMonitorSelectorAuterion::eeprom_read(const uint32_t instance) } } -bool PowerMonitorSelectorAuterion::is_eeprom_header_valid(EepromHeader *eeprom_header) const +bool AuterionAutostarter::is_eeprom_header_valid(EepromHeader *eeprom_header) const { if (eeprom_header->magic != EEPROM_MAGIC || eeprom_header->version != EEPROM_VERSION @@ -247,8 +262,8 @@ bool PowerMonitorSelectorAuterion::is_eeprom_header_valid(EepromHeader *eeprom_h return true; } -int PowerMonitorSelectorAuterion::eeprom_read_block(struct i2c_master_s *i2c, const uint32_t instance, - const uint16_t transferred_blocks, uint16_t &crc) +int AuterionAutostarter::eeprom_read_block(struct i2c_master_s *i2c, const uint32_t instance, const uint16_t transferred_blocks, + uint16_t &crc) { int ret = PX4_ERROR; EepromBlockHeader eeprom_block_header; @@ -263,44 +278,76 @@ int PowerMonitorSelectorAuterion::eeprom_read_block(struct i2c_master_s *i2c, co ret = I2C_TRANSFER(i2c, &msg, 1); - if (ret == PX4_OK && is_eeprom_block_header_valid(&eeprom_block_header)) { - EepromBlockPm &eeprom_block_pm = _eeprom_blocks_pm[transferred_blocks]; - eeprom_block_pm.block_header = eeprom_block_header; + if (ret == PX4_OK) { + DecodedBlock &block = _eeprom_decoded_blocks[transferred_blocks]; - /* Already read the header, so just need to read the block itself now */ - uint8_t *data_ptr = reinterpret_cast(&eeprom_block_pm) + offsetof(EepromBlockPm, dev_type); - size_t data_size = sizeof(EepromBlockPm) - offsetof(EepromBlockPm, dev_type); + switch (eeprom_block_header.block_type) { + case TYPE_PM: { + if (!is_eeprom_block_header_valid(&eeprom_block_header)) { return PX4_ERROR; } - /* Read the actual block data from the EEPROM */ - msg.buffer = data_ptr; - msg.length = data_size; + EepromBlockPm *block_pm = &block.block_pm; + block.block_type = TYPE_PM; + block_pm->block_header = eeprom_block_header; + ret |= eeprom_read_block_data(i2c, instance, crc, block_pm); + break; + } - ret = I2C_TRANSFER(i2c, &msg, 1); + case TYPE_PWM_EXPANDER: { + if (!is_eeprom_block_header_valid(&eeprom_block_header)) { return PX4_ERROR; } - if (ret == PX4_OK) { - crc = crc16_update(crc, reinterpret_cast(&eeprom_block_pm), sizeof(EepromBlockPm)); + EepromBlockPwmExpander *block_pwm_expander = &block.block_pwm_expander; + block.block_type = TYPE_PWM_EXPANDER; + block_pwm_expander->block_header = eeprom_block_header; + ret |= eeprom_read_block_data(i2c, instance, crc, block_pwm_expander); + break; + } + + default: + return PX4_ERROR; } - - } else { - ret = PX4_ERROR; } return ret; } -bool PowerMonitorSelectorAuterion::is_eeprom_block_header_valid(EepromBlockHeader *eeprom_block_header) const +template +int AuterionAutostarter::eeprom_read_block_data(struct i2c_master_s *i2c, const uint32_t instance, uint16_t &crc, T *block) { - if (eeprom_block_header->block_type != BlockType::TYPE_PM + /* Already read the header, so just need to read the block itself now */ + uint8_t *data_ptr = reinterpret_cast(block) + offsetof(T, dev_type); + size_t data_size = sizeof(T) - offsetof(T, dev_type); + + /* Read the actual block data from the EEPROM */ + struct i2c_msg_s msg; + msg.frequency = I2C_SPEED_STANDARD; + msg.addr = _buses[instance].eeprom_i2c_addr; + msg.flags = I2C_M_READ; + msg.buffer = data_ptr; + msg.length = data_size; + + int ret = I2C_TRANSFER(i2c, &msg, 1); + + if (ret == PX4_OK) { + crc = crc16_update(crc, reinterpret_cast(block), sizeof(T)); + } + + return ret; +} + +template +bool AuterionAutostarter::is_eeprom_block_header_valid(EepromBlockHeader *eeprom_block_header) const +{ + if (eeprom_block_header->block_type != ExpectedBlockType || eeprom_block_header->block_type_version != EEPROM_BLOCK_TYPE_VERSION - || eeprom_block_header->block_length != sizeof(EepromBlockPm)) { + || eeprom_block_header->block_length != sizeof(T)) { return false; } return true; } -int PowerMonitorSelectorAuterion::start_pm(const uint8_t bus_number, const uint16_t dev_type, - const uint16_t i2c_addr, const uint16_t id) const +int AuterionAutostarter::start_pm(const uint8_t bus_number, const uint16_t dev_type, + const uint16_t i2c_addr, const uint16_t id) const { char bus_number_str[BUS_MAX_LEN]; snprintf(bus_number_str, sizeof(bus_number_str), "%u", bus_number); @@ -312,33 +359,51 @@ int PowerMonitorSelectorAuterion::start_pm(const uint8_t bus_number, const uint1 snprintf(id_str, sizeof(id_str), "%u", id); const char *start_command = get_start_command(dev_type); - - if (start_command == nullptr) { - return PX4_ERROR; - } - const char *start_argv[] { start_command, "-X", "-b", bus_number_str, "-a", i2c_addr_str, "-t", id_str, "-q", "start", NULL }; - int status = PX4_ERROR; - int pid = exec_builtin(start_command, (char **)start_argv, NULL, 0); + return start(start_command, start_argv); +} - if (pid != -1) { - waitpid(pid, &status, WUNTRACED); +int AuterionAutostarter::start_i2c_driver(const uint8_t bus_number, const uint16_t dev_type, const uint16_t i2c_addr) const +{ + char bus_number_str[BUS_MAX_LEN]; + snprintf(bus_number_str, sizeof(bus_number_str), "%u", bus_number); + + char i2c_addr_str[I2C_ADDR_MAX_LEN]; + snprintf(i2c_addr_str, sizeof(i2c_addr_str), "%u", i2c_addr); + + const char *start_command = get_start_command(dev_type); + const char *start_argv[] { + start_command, + "-X", "-b", bus_number_str, "-a", i2c_addr_str, + "-q", "start", NULL + }; + + return start(start_command, start_argv); +} + +int AuterionAutostarter::start(const char *start_command, const char **start_argv) const +{ + int status = PX4_ERROR; + + if (start_command != nullptr) { + int pid = exec_builtin(start_command, (char **)start_argv, NULL, 0); + + if (pid != -1) { + waitpid(pid, &status, WUNTRACED); + } } return status; } -const char *PowerMonitorSelectorAuterion::get_start_command(const uint16_t dev_type) const +const char *AuterionAutostarter::get_start_command(const uint16_t dev_type) const { switch (dev_type) { - case DRV_POWER_DEVTYPE_INA220: - return "ina220"; - case DRV_POWER_DEVTYPE_INA226: return "ina226"; @@ -348,12 +413,15 @@ const char *PowerMonitorSelectorAuterion::get_start_command(const uint16_t dev_t case DRV_POWER_DEVTYPE_INA238: return "ina238"; + case DRV_PWM_DEVTYPE_PCA9685: + return "pca9685_pwm_out"; + default: return nullptr; } } -bool PowerMonitorSelectorAuterion::is_user_configured(const uint16_t dev_type) const +bool AuterionAutostarter::is_user_configured(const uint16_t dev_type) const { const char *ina_type = get_ina_type(dev_type); @@ -369,7 +437,7 @@ bool PowerMonitorSelectorAuterion::is_user_configured(const uint16_t dev_type) c return sens_en != 0; } -void PowerMonitorSelectorAuterion::set_max_current(const uint16_t dev_type, const float max_current) const +void AuterionAutostarter::set_max_current(const uint16_t dev_type, const float max_current) const { const char *ina_type = get_ina_type(dev_type); @@ -382,7 +450,7 @@ void PowerMonitorSelectorAuterion::set_max_current(const uint16_t dev_type, cons set_float_param(param_name, max_current); } -void PowerMonitorSelectorAuterion::set_shunt_value(const uint16_t dev_type, const float shunt_value) const +void AuterionAutostarter::set_shunt_value(const uint16_t dev_type, const float shunt_value) const { const char *ina_type = get_ina_type(dev_type); @@ -395,7 +463,7 @@ void PowerMonitorSelectorAuterion::set_shunt_value(const uint16_t dev_type, cons set_float_param(param_name, shunt_value); } -void PowerMonitorSelectorAuterion::set_float_param(const char *param_name, const float param_val) const +void AuterionAutostarter::set_float_param(const char *param_name, const float param_val) const { float current_param_value = 0; param_get(param_find(param_name), ¤t_param_value); @@ -405,12 +473,9 @@ void PowerMonitorSelectorAuterion::set_float_param(const char *param_name, const } } -const char *PowerMonitorSelectorAuterion::get_ina_type(const uint16_t dev_type) const +const char *AuterionAutostarter::get_ina_type(const uint16_t dev_type) const { switch (dev_type) { - case DRV_POWER_DEVTYPE_INA220: - return "220"; - case DRV_POWER_DEVTYPE_INA226: return "226"; @@ -425,7 +490,7 @@ const char *PowerMonitorSelectorAuterion::get_ina_type(const uint16_t dev_type) } } -uint16_t PowerMonitorSelectorAuterion::crc16_update(const uint16_t current_crc, const uint8_t *data_p, +uint16_t AuterionAutostarter::crc16_update(const uint16_t current_crc, const uint8_t *data_p, size_t length) const { uint8_t x; @@ -440,9 +505,9 @@ uint16_t PowerMonitorSelectorAuterion::crc16_update(const uint16_t current_crc, return crc; } -int PowerMonitorSelectorAuterion::task_spawn(int argc, char *argv[]) +int AuterionAutostarter::task_spawn(int argc, char *argv[]) { - PowerMonitorSelectorAuterion *instance = new PowerMonitorSelectorAuterion(); + AuterionAutostarter *instance = new AuterionAutostarter(); if (instance) { _object.store(instance); @@ -463,12 +528,12 @@ int PowerMonitorSelectorAuterion::task_spawn(int argc, char *argv[]) return PX4_ERROR; } -int PowerMonitorSelectorAuterion::custom_command(int argc, char *argv[]) +int AuterionAutostarter::custom_command(int argc, char *argv[]) { return print_usage("unknown command"); } -int PowerMonitorSelectorAuterion::print_usage(const char *reason) +int AuterionAutostarter::print_usage(const char *reason) { if (reason) { PX4_WARN("%s\n", reason); @@ -481,14 +546,14 @@ Driver for starting and auto-detecting different power monitors. )DESCR_STR"); - PRINT_MODULE_USAGE_NAME("pm_selector_auterion", "driver"); + PRINT_MODULE_USAGE_NAME("auterion_autostarter", "driver"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); return 0; } -extern "C" __EXPORT int pm_selector_auterion_main(int argc, char *argv[]) +extern "C" __EXPORT int auterion_autostarter_main(int argc, char *argv[]) { - return PowerMonitorSelectorAuterion::main(argc, argv); + return AuterionAutostarter::main(argc, argv); } diff --git a/src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.h b/src/drivers/auterion_autostarter/AuterionAutostarter.h similarity index 78% rename from src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.h rename to src/drivers/auterion_autostarter/AuterionAutostarter.h index 23910cf39a..f83107db3b 100644 --- a/src/drivers/power_monitor/pm_selector_auterion/PowerMonitorSelectorAuterion.h +++ b/src/drivers/auterion_autostarter/AuterionAutostarter.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * Copyright (C) 2026 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -71,12 +71,12 @@ private: struct i2c_master_s *_i2c {nullptr}; }; -class PowerMonitorSelectorAuterion : public ModuleBase, public px4::ScheduledWorkItem +class AuterionAutostarter : public ModuleBase, public px4::ScheduledWorkItem { public: - PowerMonitorSelectorAuterion(); - virtual ~PowerMonitorSelectorAuterion(); + AuterionAutostarter(); + virtual ~AuterionAutostarter(); /** @see ModuleBase */ static int task_spawn(int argc, char *argv[]); @@ -89,7 +89,14 @@ public: private: enum BlockType : uint8_t { - TYPE_PM = 0 + TYPE_PM = 0, + TYPE_PWM_EXPANDER = 1, + }; + + enum ClockType : uint8_t { + CLOCK_NONE = 0, + CLOCK_INTERNAL = 1, + CLOCK_EXTERNAL_GENERIC = 2, }; struct Buses { @@ -117,7 +124,7 @@ private: uint16_t flags; /**< offset 6 */ uint16_t num_blocks; /**< offset 8 */ uint8_t _reserved1[2]; /**< offset 10 */ - }; + } __attribute__((aligned(4))); #pragma pack(pop) #pragma pack(push, 1) @@ -125,11 +132,11 @@ private: uint8_t block_type; /**< offset 0 */ uint8_t block_type_version; /**< offset 1 */ uint16_t block_length; /**< offset 2 */ - }; + } __attribute__((aligned(4))); #pragma pack(pop) #pragma pack(push, 1) - /* Block n starts at 12 + (n * 20) */ + /* Block n starts at 12 + (n * 20), each block needs to contain a block_header and dev_type! */ struct EepromBlockPm { EepromBlockHeader block_header; /**< offset 0 */ uint16_t dev_type; /**< offset 4 */ @@ -138,9 +145,33 @@ private: uint8_t _padding1[2]; /**< offset 10 */ float max_current; /**< offset 12 */ float shunt_value; /**< offset 16 */ - }; + } __attribute__((aligned(4))); #pragma pack(pop) +#pragma pack(push, 1) + /* Block n starts at 12 + (n * 20), each block needs to contain a block_header and dev_type! */ + struct EepromBlockPwmExpander { + EepromBlockHeader block_header; /**< offset 0 */ + uint16_t dev_type; /**< offset 4 */ + uint16_t sensor_type; /**< offset 6 */ + uint16_t i2c_addr; /**< offset 8 */ + uint16_t num_channels; /**< offset 10 */ + uint16_t offset_channels; /**< offset 12 */ + ClockType clock_type; /**< offset 14 */ + uint8_t _padding1; /**< offset 15 */ + float signal_level; /**< offset 16 */ + } __attribute__((aligned(4))); +#pragma pack(pop) + + struct DecodedBlock { + BlockType block_type; + + union { + EepromBlockPm block_pm; + EepromBlockPwmExpander block_pwm_expander; + }; + }; + void Run() override; bool init(); @@ -152,12 +183,16 @@ private: int eeprom_read(const uint32_t instance); bool is_eeprom_header_valid(EepromHeader *eeprom_header) const; - int eeprom_read_block(struct i2c_master_s *i2c, const uint32_t instance, const uint16_t transferred_blocks, - uint16_t &crc); + int eeprom_read_block(struct i2c_master_s *i2c, const uint32_t instance, const uint16_t transferred_blocks, uint16_t &crc); + template + int eeprom_read_block_data(struct i2c_master_s *i2c, const uint32_t instance, uint16_t &crc, T *block); + template bool is_eeprom_block_header_valid(EepromBlockHeader *eeprom_block_header) const; int start_pm(const uint8_t bus_number, const uint16_t dev_type, const uint16_t i2c_addr, const uint16_t id) const; + int start_i2c_driver(const uint8_t bus_number, const uint16_t dev_type, const uint16_t i2c_addr) const; const char *get_start_command(const uint16_t dev_type) const; + int start(const char *start_command, const char **start_argv) const; bool is_user_configured(const uint16_t dev_type) const; void set_max_current(const uint16_t dev_type, const float max_current) const; @@ -234,6 +269,6 @@ private: } }; - EepromBlockPm _eeprom_blocks_pm[EEPROM_MAX_BLOCKS] = { 0 }; - uint16_t _eeprom_valid_blocks_pm = 0; + DecodedBlock _eeprom_decoded_blocks[EEPROM_MAX_BLOCKS]; + uint16_t _eeprom_num_decoded_blocks = 0; }; diff --git a/src/drivers/power_monitor/pm_selector_auterion/CMakeLists.txt b/src/drivers/auterion_autostarter/CMakeLists.txt similarity index 93% rename from src/drivers/power_monitor/pm_selector_auterion/CMakeLists.txt rename to src/drivers/auterion_autostarter/CMakeLists.txt index b715c5cec5..d6b3f208a5 100644 --- a/src/drivers/power_monitor/pm_selector_auterion/CMakeLists.txt +++ b/src/drivers/auterion_autostarter/CMakeLists.txt @@ -31,10 +31,10 @@ # ############################################################################ px4_add_module( - MODULE drivers__power_monitor_pm_selector_auterion - MAIN pm_selector_auterion + MODULE drivers__auterion_autostarter + MAIN auterion_autostarter SRCS - PowerMonitorSelectorAuterion.cpp + AuterionAutostarter.cpp DEPENDS px4_work_queue ) diff --git a/src/drivers/auterion_autostarter/Kconfig b/src/drivers/auterion_autostarter/Kconfig new file mode 100644 index 0000000000..36c633da1c --- /dev/null +++ b/src/drivers/auterion_autostarter/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_AUTERION_AUTOSTARTER + bool "auterion_autostarter" + default n + ---help--- + Enable support for auterion_autostarter diff --git a/src/drivers/barometer/ms5837/MS5837.cpp b/src/drivers/barometer/ms5837/MS5837.cpp index 933d3a1a32..4bd4d11c9a 100644 --- a/src/drivers/barometer/ms5837/MS5837.cpp +++ b/src/drivers/barometer/ms5837/MS5837.cpp @@ -332,14 +332,13 @@ int MS5837::_collect() } else { /* pressure calculation, result in Pa */ - int32_t P = (((raw * _SENS) >> 21) - _OFF) >> 13; - + int32_t pressure_pascal = ((((raw * _SENS) >> 21) - _OFF) >> 13) * 10; // publish sensor_baro_s sensor_baro{}; sensor_baro.timestamp_sample = timestamp_sample; sensor_baro.device_id = get_device_id(); - sensor_baro.pressure = P; + sensor_baro.pressure = pressure_pascal; sensor_baro.temperature = _last_temperature; sensor_baro.error_count = perf_event_count(_comms_errors); sensor_baro.timestamp = hrt_absolute_time(); diff --git a/src/drivers/bootloaders/CMakeLists.txt b/src/drivers/bootloaders/CMakeLists.txt index 0972160fdf..3123ea9d54 100644 --- a/src/drivers/bootloaders/CMakeLists.txt +++ b/src/drivers/bootloaders/CMakeLists.txt @@ -43,6 +43,17 @@ target_link_libraries(drivers_bootloaders PRIVATE crc) # generate bootloader_app_shared_t if(NOT "${PX4_BOARD_LABEL}" MATCHES "canbootloader") + # Check if UAVCAN board identity variables are defined + # These are only set for UAVCAN node boards (CAN peripherals like can-gps, cannode, etc.) + if(NOT DEFINED uavcanblid_hw_version_major OR NOT DEFINED uavcanblid_hw_version_minor OR + NOT DEFINED uavcanblid_sw_version_major OR NOT DEFINED uavcanblid_sw_version_minor) + message(FATAL_ERROR + "CONFIG_DRIVERS_BOOTLOADERS is only supported on UAVCAN node boards.\n" + "This board (${PX4_BOARD}) does not have UAVCAN board identity defined.\n" + "Please disable CONFIG_DRIVERS_BOOTLOADERS in boardconfig (make ${PX4_CONFIG} boardconfig).\n" + "Note: This option is only needed for CAN peripheral boards (e.g., can-gps, cannode, can-flow).") + endif() + set(HW_MAJOR ${uavcanblid_hw_version_major}) set(HW_MINOR ${uavcanblid_hw_version_minor}) set(SW_MAJOR ${uavcanblid_sw_version_major}) diff --git a/src/drivers/bootloaders/Kconfig b/src/drivers/bootloaders/Kconfig index a630d51277..4d75c553e4 100644 --- a/src/drivers/bootloaders/Kconfig +++ b/src/drivers/bootloaders/Kconfig @@ -1,5 +1,7 @@ menuconfig DRIVERS_BOOTLOADERS bool "bootloaders" default n + depends on BOARD_ROMFSROOT = "cannode" || BOARD_ROMFSROOT = "" ---help--- Enable support for bootloaders + Note: This is only supported on UAVCAN node boards (CAN peripherals) diff --git a/src/drivers/differential_pressure/auav/AUAV.cpp b/src/drivers/differential_pressure/auav/AUAV.cpp index 2533399a35..fb89148133 100644 --- a/src/drivers/differential_pressure/auav/AUAV.cpp +++ b/src/drivers/differential_pressure/auav/AUAV.cpp @@ -65,6 +65,7 @@ AUAV::AUAV(const I2CSPIDriverConfig &config) : _sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": read")), _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) { + I2C::_retries = 5; } AUAV::~AUAV() @@ -76,6 +77,10 @@ AUAV::~AUAV() void AUAV::RunImpl() { switch (_state) { + case STATE::READ_FACTORY_DATA: + handle_state_read_factory_data(); + break; + case STATE::READ_CALIBDATA: handle_state_read_calibdata(); break; @@ -106,23 +111,6 @@ int AUAV::init() return ret; } - int32_t hw_model = 0; - param_get(param_find("SENS_EN_AUAVX"), &hw_model); - - switch (hw_model) { - case 1: /* AUAV L05D (+- 5 inH20) */ - _cal_range = 10.0f; - break; - - case 2: /* AUAV L10D (+- 10 inH20) */ - _cal_range = 20.0f; - break; - - case 3: /* AUAV L30D (+- 30 inH20) */ - _cal_range = 60.0f; - break; - } - ScheduleClear(); ScheduleNow(); return PX4_OK; @@ -130,15 +118,35 @@ int AUAV::init() int AUAV::probe() { - uint8_t res_data = 0; - int status = transfer(nullptr, 0, &res_data, sizeof(res_data)); + uint8_t res_data; - /* Check that the sensor is active. Reported in bit 6 of the status byte */ - if ((res_data & 0x40) == 0) { - status = PX4_ERROR; + for (unsigned i = 0; i < 10; i++) { + res_data = 0; + int status = transfer(nullptr, 0, &res_data, 1); + + /* Check that the sensor is active. Reported in bit 6 of the status byte */ + if (status == PX4_OK && (res_data & 0x40)) { + return PX4_OK; + } + + px4_usleep(10'000); } - return status; + return PX4_ERROR; +} + +void AUAV::handle_state_read_factory_data() +{ + int status = read_factory_data(); + + if (status == PX4_OK) { + /* Factory data read or sensor does not have any, move to next state */ + _state = STATE::READ_CALIBDATA; + ScheduleNow(); + + } else { + ScheduleDelayed(100_ms); + } } void AUAV::handle_state_read_calibdata() diff --git a/src/drivers/differential_pressure/auav/AUAV.hpp b/src/drivers/differential_pressure/auav/AUAV.hpp index b6d952d813..7011e8b748 100644 --- a/src/drivers/differential_pressure/auav/AUAV.hpp +++ b/src/drivers/differential_pressure/auav/AUAV.hpp @@ -61,6 +61,7 @@ public: protected: enum class STATE : uint8_t { + READ_FACTORY_DATA, READ_CALIBDATA, REQUEST_MEASUREMENT, GATHER_MEASUREMENT @@ -107,7 +108,9 @@ protected: virtual int64_t get_conversion_interval() const = 0; virtual calib_eeprom_addr_t get_calib_eeprom_addr() const = 0; virtual float process_pressure_dig(const float pressure_dig) const = 0; + virtual int read_factory_data() = 0; + void handle_state_read_factory_data(); void handle_state_read_calibdata(); void handle_state_request_measurement(); void handle_state_gather_measurement(); @@ -117,8 +120,7 @@ protected: float correct_pressure(const uint32_t pressure_raw, const uint32_t temperature_raw) const; float process_temperature_raw(const float temperature_raw) const; - float _cal_range{10.0f}; - STATE _state{STATE::READ_CALIBDATA}; + STATE _state{STATE::READ_FACTORY_DATA}; calib_data_t _calib_data {}; perf_counter_t _sample_perf; diff --git a/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp b/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp index bded1d626d..69e01d50fc 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp +++ b/src/drivers/differential_pressure/auav/AUAV_Absolute.cpp @@ -77,3 +77,9 @@ float AUAV_Absolute::process_pressure_dig(const float pressure_dig) const const float pressure_mbar = 250.f + 1.25f * ((pressure_dig - (0.1f * (1 << 24))) / (1 << 24)) * 1000.f; return pressure_mbar * MBAR_TO_PA; } + +int AUAV_Absolute::read_factory_data() +{ + /* Absolute sensor doesn't need to read factory data */ + return PX4_OK; +} diff --git a/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp b/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp index 624ef27079..5ab105f5a5 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp +++ b/src/drivers/differential_pressure/auav/AUAV_Absolute.hpp @@ -51,6 +51,8 @@ static constexpr uint8_t EEPROM_ABS_ES = 0x38; /* Measurement rate is 50Hz */ static constexpr unsigned ABS_MEAS_RATE = 50; static constexpr int64_t ABS_CONVERSION_INTERVAL = (1000000 / ABS_MEAS_RATE); /* microseconds */ +/* reading too fast can yield all zero data -> incorrect sensor reading */ +static_assert(ABS_CONVERSION_INTERVAL >= 7000, "Conversion interval is too fast"); /* Conversions */ static constexpr float MBAR_TO_PA = 100.0f; @@ -66,6 +68,7 @@ private: int64_t get_conversion_interval() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override; float process_pressure_dig(const float pressure_dig) const override; + int read_factory_data() override; uORB::PublicationMulti _sensor_baro_pub{ORB_ID(sensor_baro)}; }; diff --git a/src/drivers/differential_pressure/auav/AUAV_Differential.cpp b/src/drivers/differential_pressure/auav/AUAV_Differential.cpp index 3a4243b366..b2d2b1fa21 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Differential.cpp +++ b/src/drivers/differential_pressure/auav/AUAV_Differential.cpp @@ -33,10 +33,38 @@ #include "AUAV_Differential.hpp" #include +#include AUAV_Differential::AUAV_Differential(const I2CSPIDriverConfig &config) : AUAV(config) { + /* Initialize cal_range from parameter as fallback value */ + int32_t hw_model = 0; + param_get(param_find("SENS_EN_AUAVX"), &hw_model); + + switch (hw_model) { + case 1: /* AUAV L05D (+- 5 inH20) */ + _cal_range = 10; + break; + + case 2: /* AUAV L10D (+- 10 inH20) */ + _cal_range = 20; + break; + + case 3: /* AUAV L30D (+- 30 inH20) */ + _cal_range = 60; + break; + + default: + _cal_range = 10; /* Default fallback */ + break; + } +} + +void AUAV_Differential::print_status() +{ + AUAV::print_status(); + PX4_INFO("cal range: %" PRId32, _cal_range); } void AUAV_Differential::publish_pressure(const float pressure_p, const float temperature_c, @@ -83,6 +111,52 @@ AUAV::calib_eeprom_addr_t AUAV_Differential::get_calib_eeprom_addr() const float AUAV_Differential::process_pressure_dig(const float pressure_dig) const { - const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * _cal_range; + const float pressure_in_h = 1.25f * ((pressure_dig - (1 << 23)) / (1 << 24)) * static_cast(_cal_range); return pressure_in_h * INH_TO_PA; } + +int AUAV_Differential::read_factory_data() +{ + /* The differential sensor needs the cal_range from the absolute sensor's EEPROM. + * Temporarily switch to the absolute sensor's I2C address to read it, then switch back. */ + + uint8_t original_address = get_device_address(); + set_device_address(I2C_ADDRESS_ABSOLUTE); + + /* Read the calibration range from the absolute sensor's EEPROM */ + uint16_t factory_data = 0; + int status = read_calibration_eeprom(EEPROM_ABS_CAL_RNG, factory_data); + + set_device_address(original_address); + + if (status != PX4_OK) { + return status; + } + + /* If EEPROM data is 0, stop trying (sensor does not have factory data) */ + if (factory_data == 0) { + PX4_INFO("Differential: cal range data is 0, using fallback value"); + return PX4_OK; + } + + /* Decode the two bytes as ASCII characters */ + uint8_t char_high = (factory_data >> 8) & 0xFF; + uint8_t char_low = factory_data & 0xFF; + + /* Validate that both characters are ASCII digits (0-9) */ + if (!isdigit(char_high) || !isdigit(char_low)) { + return PX4_ERROR; + } + + int32_t sensor_type = ((char_high - '0') * 10) + (char_low - '0'); + + /* Check if the detected sensor type is valid */ + if (sensor_type != AUAV_LD_05 && sensor_type != AUAV_LD_10 && sensor_type != AUAV_LD_30) { + return PX4_ERROR; + } + + _cal_range = sensor_type * 2; + PX4_INFO("Differential: read cal range %" PRId32 " from absolute sensor EEPROM", _cal_range); + + return PX4_OK; +} diff --git a/src/drivers/differential_pressure/auav/AUAV_Differential.hpp b/src/drivers/differential_pressure/auav/AUAV_Differential.hpp index 412066a6ac..1b3ce238ce 100644 --- a/src/drivers/differential_pressure/auav/AUAV_Differential.hpp +++ b/src/drivers/differential_pressure/auav/AUAV_Differential.hpp @@ -37,6 +37,7 @@ #include /* AUAV EEPROM addresses for differential channel */ +static constexpr uint8_t EEPROM_ABS_CAL_RNG = 0x25; static constexpr uint8_t EEPROM_DIFF_AHW = 0x2B; static constexpr uint8_t EEPROM_DIFF_ALW = 0x2C; static constexpr uint8_t EEPROM_DIFF_BHW = 0x2D; @@ -51,21 +52,32 @@ static constexpr uint8_t EEPROM_DIFF_ES = 0x34; /* Measurement rate is 100Hz */ static constexpr unsigned DIFF_MEAS_RATE = 100; static constexpr int64_t DIFF_CONVERSION_INTERVAL = (1000000 / DIFF_MEAS_RATE); /* microseconds */ +/* reading too fast can yield all zero data -> incorrect sensor reading */ +static_assert(DIFF_CONVERSION_INTERVAL >= 7000, "Conversion interval is too fast"); /* Conversions */ static constexpr float INH_TO_PA = 249.08f; +/* Valid AUAV types */ +static constexpr int32_t AUAV_LD_05 = 5; +static constexpr int32_t AUAV_LD_10 = 10; +static constexpr int32_t AUAV_LD_30 = 30; + class AUAV_Differential : public AUAV { public: explicit AUAV_Differential(const I2CSPIDriverConfig &config); ~AUAV_Differential() = default; + void print_status() override; + private: void publish_pressure(const float pressure_p, const float temperature_c, const hrt_abstime timestamp_sample) override; int64_t get_conversion_interval() const override; calib_eeprom_addr_t get_calib_eeprom_addr() const override; float process_pressure_dig(const float pressure_dig) const override; + int read_factory_data() override; uORB::PublicationMulti _differential_pressure_pub{ORB_ID(differential_pressure)}; + int32_t _cal_range{10}; }; diff --git a/src/drivers/distance_sensor/Kconfig b/src/drivers/distance_sensor/Kconfig index 25adedcd89..65af4614df 100644 --- a/src/drivers/distance_sensor/Kconfig +++ b/src/drivers/distance_sensor/Kconfig @@ -2,11 +2,9 @@ menu "Distance sensors" menuconfig COMMON_DISTANCE_SENSOR bool "Common distance sensor's" default n - select DRIVERS_DISTANCE_SENSOR_CM8JL65 select DRIVERS_DISTANCE_SENSOR_LIGHTWARE_LASER_I2C select DRIVERS_DISTANCE_SENSOR_LIGHTWARE_LASER_SERIAL select DRIVERS_DISTANCE_SENSOR_LL40LS - select DRIVERS_DISTANCE_SENSOR_TERARANGER select DRIVERS_DISTANCE_SENSOR_TF02PRO select DRIVERS_DISTANCE_SENSOR_TFMINI select DRIVERS_DISTANCE_SENSOR_ULANDING_RADAR diff --git a/src/drivers/distance_sensor/lightware_grf_serial/CMakeLists.txt b/src/drivers/distance_sensor/lightware_grf_serial/CMakeLists.txt new file mode 100755 index 0000000000..9a3c045be7 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/CMakeLists.txt @@ -0,0 +1,46 @@ +############################################################################ +# +# Copyright (c) 2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__distance_sensor__lightware_grf_serial + MAIN lightware_grf_serial + COMPILE_FLAGS + SRCS + lightware_grf_serial.cpp + lightware_grf_serial.hpp + lightware_grf_serial_main.cpp + DEPENDS + drivers_rangefinder + px4_work_queue + MODULE_CONFIG + module.yaml + ) diff --git a/src/drivers/distance_sensor/lightware_grf_serial/Kconfig b/src/drivers/distance_sensor/lightware_grf_serial/Kconfig new file mode 100755 index 0000000000..3c89bf0974 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_DISTANCE_SENSOR_LIGHTWARE_GRF_SERIAL + bool "lightware_grf_serial" + default n + ---help--- + Enable support for lightware_grf_serial diff --git a/src/drivers/distance_sensor/lightware_grf_serial/grf_commands.h b/src/drivers/distance_sensor/lightware_grf_serial/grf_commands.h new file mode 100755 index 0000000000..c278a166c6 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/grf_commands.h @@ -0,0 +1,91 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file grf_commands.h + * @author Aaron Porter + * + * Declarations of grf serial commands for the Lightware grf series + */ + +#pragma once +#define GRF_MAX_PAYLOAD 256 +#define GRF_CRC_FIELDS 2 + +enum GRF_SERIAL_CMD { + GRF_PRODUCT_NAME = 0, + GRF_HARDWARE_VERSION = 1, + GRF_FIRMWARE_VERSION = 2, + GRF_SERIAL_NUMBER = 3, + GRF_TEXT_MESSAGE = 7, + GRF_USER_DATA = 9, + GRF_TOKEN = 10, + GRF_SAVE_PARAMETERS = 12, + GRF_RESET = 14, + GRF_STAGE_FIRMWARE = 16, + GRF_COMMIT_FIRMWARE = 17, + GRF_DISTANCE_OUTPUT = 27, + GRF_STREAM = 30, + GRF_DISTANCE_DATA_CM = 44, + GRF_DISTANCE_DATA_MM = 45, + GRF_LASER_FIRING = 50, + GRF_TEMPERATURE = 55, + GRF_AUTO_EXPOSURE = 70, + GRF_UPDATE_RATE = 74, + GRF_LOST_SIGNAL_COUNT = 78, + GRF_GPIO_MODE = 83, + GRF_GPIO_ALARM = 84, + GRF_MEDIAN_FILTER_EN = 86, + GRF_MEDIAN_FILETER_S = 87, + GRF_SMOOTH_FILTER_EN = 88, + GRF_SMOOTH_FACTOR = 89, + GRF_BAUD_RATE = 91, + GRF_I2C_ADDRESS = 92, + GRF_ROLL_AVG_EN = 93, + GRF_ROLL_AVG_SIZE = 94, + GRF_SLEEP_COMMAND = 98, + GRF_ZERO_OFFSET = 114 +}; + +// Store contents of rx'd frame +struct { + const uint8_t data_fields = 2; // useful for breaking crc's into byte separated fields + uint16_t data_len{0}; // last message payload length (1+ bytes in payload) + uint8_t data[GRF_MAX_PAYLOAD]; // payload size limited by posix serial + uint8_t msg_id{0}; // latest message's message id + uint8_t flags_lo{0}; // flags low byte + uint8_t flags_hi{0}; // flags high byte + uint16_t crc[GRF_CRC_FIELDS] = {0, 0}; + uint8_t crc_lo{0}; // crc low byte + uint8_t crc_hi{0}; // crc high byte +} rx_field; diff --git a/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.cpp b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.cpp new file mode 100755 index 0000000000..403c61f562 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.cpp @@ -0,0 +1,633 @@ +/************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "lightware_grf_serial.hpp" + +#include +#include +#include +#include + +#include + +using namespace time_literals; + +GRFLaserSerial::GRFLaserSerial(const char *port, uint8_t rotation) : + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(port)), + _px4_rangefinder(0, rotation), + _sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": read")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": com_err")) +{ + /* store port name */ + strncpy(_port, port, sizeof(_port) - 1); + + /* enforce null termination */ + _port[sizeof(_port) - 1] = '\0'; + + device::Device::DeviceId device_id; + device_id.devid_s.bus_type = device::Device::DeviceBusType_SERIAL; + + uint8_t bus_num = atoi(&_port[strlen(_port) - 1]); // Assuming '/dev/ttySx' + + if (bus_num < 10) { + device_id.devid_s.bus = bus_num; + } + + _px4_rangefinder.set_device_id(device_id.devid); + _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_LIGHTWARE_LASER); + +} + +GRFLaserSerial::~GRFLaserSerial() +{ + stop(); + + perf_free(_sample_perf); + perf_free(_comms_errors); +} + +int GRFLaserSerial::init() +{ + param_get(param_find("GRF_RATE_CFG"), &_update_rate); + param_get(param_find("GRF_SENS_MODEL"), &_model_type); + + start(); + return PX4_OK; +} + +int GRFLaserSerial::measure() +{ + int32_t rate = (int32_t)_update_rate; + _data_output = 0x01; // raw distance (last return) + _stream_data = 5; // enable constant streaming + + // send packets to the sensor depending on the state + switch (_sensor_state) { + + case STATE_UNINIT: + // Used to probe if the sensor is alive + grf_send(GRF_PRODUCT_NAME, false, &_product_name[0], 0); + break; + + case STATE_ACK_PRODUCT_NAME: + // Update rate default to 5 readings/s + grf_send(GRF_UPDATE_RATE, true, &rate, sizeof(uint8_t)); + ScheduleDelayed(100_ms); + break; + + case STATE_ACK_UPDATE_RATE: + // Configure the data that the sensor shall output + grf_send(GRF_DISTANCE_OUTPUT, true, &_data_output, sizeof(_data_output)); + break; + + case STATE_ACK_DISTANCE_OUTPUT: + // Configure the sensor to automatically output data at the configured update rate + grf_send(GRF_STREAM, true, &_stream_data, sizeof(_stream_data)); + _sensor_state = STATE_SEND_STREAM; + break; + + default: + break; + } + + return PX4_OK; +} + +int GRFLaserSerial::collect() +{ + if (_sensor_state == STATE_UNINIT) { + + perf_begin(_sample_perf); + const int payload_length = 22; + + _crc_valid = false; + grf_get_and_handle_request(payload_length, GRF_PRODUCT_NAME); + + if (_crc_valid) { + _sensor_state = STATE_ACK_PRODUCT_NAME; + perf_end(_sample_perf); + return PX4_OK; + } + + perf_end(_sample_perf); + return -EAGAIN; + + } else if (_sensor_state == STATE_ACK_PRODUCT_NAME) { + + perf_begin(_sample_perf); + const int payload_length = 7; + + _crc_valid = false; + grf_get_and_handle_request(payload_length, GRF_UPDATE_RATE); + + if (_crc_valid) { + _sensor_state = STATE_ACK_UPDATE_RATE; + perf_end(_sample_perf); + return PX4_OK; + } + + perf_end(_sample_perf); + return -EAGAIN; + + } else if (_sensor_state == STATE_ACK_UPDATE_RATE) { + + perf_begin(_sample_perf); + const int payload_length = 10; + + _crc_valid = false; + grf_get_and_handle_request(payload_length, GRF_DISTANCE_OUTPUT); + + if (_crc_valid) { + _sensor_state = STATE_ACK_DISTANCE_OUTPUT; + perf_end(_sample_perf); + return PX4_OK; + } + + perf_end(_sample_perf); + return -EAGAIN; + + } else { + + // Stream data from sensor + perf_begin(_sample_perf); + const int payload_length = 10; + + _crc_valid = false; + grf_get_and_handle_request(payload_length, GRF_DISTANCE_DATA_CM); + + if (_crc_valid) { + grf_process_replies(); + perf_end(_sample_perf); + return PX4_OK; + } + + perf_end(_sample_perf); + return -EAGAIN; + } +} + +void GRFLaserSerial::start() +{ + /* reset the sensor state */ + _sensor_state = STATE_UNINIT; + + /* reset the report ring */ + _collect_phase = false; + + /* reset the UART receive buffer size */ + _linebuf_size = 0; + + /* reset the fail counter */ + _last_received_time = hrt_absolute_time(); + + /*Set Lidar Min/Max based on model*/ + switch (_model_type) { + case GRF250: { + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(250.0f); + break; + } + + case GRF500: { + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(500.0f); + break; + } + } + + /* schedule a cycle to start things */ + ScheduleNow(); +} + +void GRFLaserSerial::stop() +{ + ScheduleClear(); +} + +void GRFLaserSerial::Run() +{ + /* fds initialized? */ + if (_fd < 0) { + /* open fd: non-blocking read mode*/ + _fd = ::open(_port, O_RDWR | O_NOCTTY | O_NONBLOCK); + + if (_fd < 0) { + PX4_ERR("serial open failed (%i)", errno); + return; + } + + struct termios uart_config; + + int termios_state; + + /* fill the struct for the new configuration */ + tcgetattr(_fd, &uart_config); + + /* clear ONLCR flag (which appends a CR for every LF) */ + uart_config.c_oflag &= ~ONLCR; + + /* no parity, one stop bit */ + uart_config.c_cflag &= ~(CSTOPB | PARENB); + + unsigned speed = B115200; + + /* set baud rate */ + if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) { + PX4_ERR("CFG: %d ISPD", termios_state); + } + + if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) { + PX4_ERR("CFG: %d OSPD", termios_state); + } + + if ((termios_state = tcsetattr(_fd, TCSANOW, &uart_config)) < 0) { + PX4_ERR("baud %d ATTR", termios_state); + } + } + + if (_collect_phase) { + if (hrt_absolute_time() - _last_received_time >= 1_s) { + start(); + return; + } + + /* perform collection */ + if (collect() != PX4_OK && errno != EAGAIN) { + PX4_DEBUG("collect error"); + } + + if (_sensor_state != STATE_SEND_STREAM) { + /* next phase is measurement */ + _collect_phase = false; + } + + } else { + /* measurement phase */ + + if (measure() != PX4_OK) { + PX4_DEBUG("measure error"); + } + + /* next phase is collection */ + _collect_phase = true; + } + + /* schedule a fresh cycle call when the measurement is done */ + ScheduleDelayed(_interval); +} + +void GRFLaserSerial::print_info() +{ + perf_print_counter(_sample_perf); + perf_print_counter(_comms_errors); +} + +void GRFLaserSerial::grf_get_and_handle_request(const int payload_length, const GRF_SERIAL_CMD msg_id) +{ + // GRF protocol + // Start byte is 0xAA and is the start of packet + // Payload length sanity check (0-1023) bytes + // and represented by 16-bit integer (payload + + // read/write status) + // ID byte precedes the data in the payload + // CRC comprised of 16-bit checksum (not included in checksum calc.) + + int ret; + size_t max_read = sizeof(_linebuf) - _linebuf_size; + ret = ::read(_fd, &_linebuf[_linebuf_size], max_read); + + if (ret < 0 && errno != EAGAIN) { + PX4_ERR("ERROR (ack from streaming distance data): %d", ret); + _linebuf_size = 0; + perf_count(_comms_errors); + perf_end(_sample_perf); + return; + } + + if (ret > 0) { + _last_received_time = hrt_absolute_time(); + _linebuf_size += ret; + } + + // Not enough data to parse a complete packet. Gather more data in the next cycle. + if (_linebuf_size < payload_length) { + return; + } + + int index = 0; + + while (index <= _linebuf_size - payload_length && _crc_valid == false) { + bool restart_flag = false; + + while (restart_flag != true) { + switch (_parsed_state) { + case GRF_PARSED_STATE::START: { + if (_linebuf[index] == 0xAA) { + // start of frame is valid, continue + _calc_crc = grf_format_crc(_calc_crc, _start_of_frame); + _parsed_state = GRF_PARSED_STATE::FLG_LOW; + break; + + } else { + _crc_valid = false; + _parsed_state = GRF_PARSED_STATE::START; + restart_flag = true; + _calc_crc = 0; + PX4_DEBUG("Start of packet not valid: %d", _sensor_state); + break; + } + } + + case GRF_PARSED_STATE::FLG_LOW: { + rx_field.flags_lo = _linebuf[index + 1]; + _calc_crc = grf_format_crc(_calc_crc, rx_field.flags_lo); + _parsed_state = GRF_PARSED_STATE::FLG_HIGH; + break; + } + + case GRF_PARSED_STATE::FLG_HIGH: { + rx_field.flags_hi = _linebuf[index + 2]; + rx_field.data_len = (rx_field.flags_hi << 2) | (rx_field.flags_lo >> 6); + _calc_crc = grf_format_crc(_calc_crc, rx_field.flags_hi); + + // Check payload length against known max value + if (rx_field.data_len > 17) { + _parsed_state = GRF_PARSED_STATE::START; + restart_flag = true; + _calc_crc = 0; + PX4_DEBUG("Payload length error: %d", _sensor_state); + break; + + } else { + _parsed_state = GRF_PARSED_STATE::ID; + break; + } + } + + case GRF_PARSED_STATE::ID: { + rx_field.msg_id = _linebuf[index + 3]; + + if (rx_field.msg_id == msg_id) { + _calc_crc = grf_format_crc(_calc_crc, rx_field.msg_id); + _parsed_state = GRF_PARSED_STATE::DATA; + break; + } + + // Ignore message ID's that aren't searched + else { + _parsed_state = GRF_PARSED_STATE::START; + _calc_crc = 0; + restart_flag = true; + PX4_DEBUG("Non needed message ID: %d", _sensor_state); + break; + } + } + + case GRF_PARSED_STATE::DATA: { + // Process commands with & w/out data bytes + if (rx_field.data_len > 1) { + for (uint8_t i = 4; i < 3 + rx_field.data_len; ++i) { + + rx_field.data[_data_bytes_recv] = _linebuf[index + i]; + _calc_crc = grf_format_crc(_calc_crc, rx_field.data[_data_bytes_recv]); + _data_bytes_recv = _data_bytes_recv + 1; + + } + } + + else { + + _parsed_state = GRF_PARSED_STATE::CRC_LOW; + _data_bytes_recv = 0; + _calc_crc = grf_format_crc(_calc_crc, _data_bytes_recv); + } + + _parsed_state = GRF_PARSED_STATE::CRC_LOW; + _data_bytes_recv = 0; + break; + } + + case GRF_PARSED_STATE::CRC_LOW: { + rx_field.crc[0] = _linebuf[index + 3 + rx_field.data_len]; + _parsed_state = GRF_PARSED_STATE::CRC_HIGH; + break; + } + + case GRF_PARSED_STATE::CRC_HIGH: { + rx_field.crc[1] = _linebuf[index + 4 + rx_field.data_len]; + uint16_t recv_crc = (rx_field.crc[1] << 8) | rx_field.crc[0]; + + // Check the received crc bytes from the grf against our own CRC calcuation + // If it matches, we can check if sensor ready + // Only if crc match is valid and sensor ready (transmitting distance data) do we flag _init_complete + if (recv_crc == _calc_crc) { + _crc_valid = true; + _parsed_state = GRF_PARSED_STATE::START; + _calc_crc = 0; + restart_flag = true; + break; + + } else { + + _crc_valid = false; + _parsed_state = GRF_PARSED_STATE::START; + _calc_crc = 0; + restart_flag = true; + perf_count(_comms_errors); + PX4_DEBUG("CRC mismatch: %d", _sensor_state); + break; + } + } + } + } + + index++; + } + + // If we parsed successfully, remove the parsed part from the buffer if it is still large enough + if (_crc_valid && index + payload_length < _linebuf_size) { + unsigned next_after_index = index + payload_length; + memmove(&_linebuf[0], &_linebuf[next_after_index], _linebuf_size - next_after_index); + _linebuf_size -= next_after_index; + } + + // The buffer is filled. Either we can't keep up with the stream and/or it contains only invalid data. Reset to try again. + if ((unsigned)_linebuf_size >= sizeof(_linebuf)) { + _linebuf_size = 0; + perf_count(_comms_errors); + } +} + +void GRFLaserSerial::grf_send(uint8_t msg_id, bool write, int32_t *data, uint8_t data_len) +{ + uint16_t crc_val = 0; + uint8_t packet_buff[GRF_MAX_PAYLOAD]; + uint8_t data_inc = 4; + int ret = 0; + uint8_t packet_len = 0; + // Include payload ID byte in payload len + uint16_t flags = (data_len + 1) << 6; + + // If writing to the device, lsb is 1 + if (write) { + flags |= 0x01; + } + + else { + flags |= 0x0; + } + + uint8_t flags_lo = flags & 0xFF; + uint8_t flags_hi = (flags >> 8) & 0xFF; + + // Add packet bytes to format into crc based on CRC-16-CCITT 0x1021/XMODEM + crc_val = grf_format_crc(crc_val, _start_of_frame); + crc_val = grf_format_crc(crc_val, flags_lo); + crc_val = grf_format_crc(crc_val, flags_hi); + crc_val = grf_format_crc(crc_val, msg_id); + + // Write the packet header contents + payload msg ID to the output buffer + packet_buff[0] = _start_of_frame; + packet_buff[1] = flags_lo; + packet_buff[2] = flags_hi; + packet_buff[3] = msg_id; + + if (msg_id == GRF_DISTANCE_OUTPUT) { + uint8_t data_convert = data[0] & 0x00FF; + // write data bytes to the output buffer + packet_buff[data_inc] = data_convert; + // Add data bytes to crc add function + crc_val = grf_format_crc(crc_val, data_convert); + data_inc = data_inc + 1; + data_convert = data[0] >> 8; + packet_buff[data_inc] = data_convert; + crc_val = grf_format_crc(crc_val, data_convert); + data_inc = data_inc + 1; + packet_buff[data_inc] = 0; + crc_val = grf_format_crc(crc_val, packet_buff[data_inc]); + data_inc = data_inc + 1; + packet_buff[data_inc] = 0; + crc_val = grf_format_crc(crc_val, packet_buff[data_inc]); + data_inc = data_inc + 1; + } + + else if (msg_id == GRF_STREAM) { + packet_buff[data_inc] = data[0]; + //pad zeroes + crc_val = grf_format_crc(crc_val, data[0]); + data_inc = data_inc + 1; + packet_buff[data_inc] = 0; + crc_val = grf_format_crc(crc_val, packet_buff[data_inc]); + data_inc = data_inc + 1; + packet_buff[data_inc] = 0; + crc_val = grf_format_crc(crc_val, packet_buff[data_inc]); + data_inc = data_inc + 1; + packet_buff[data_inc] = 0; + crc_val = grf_format_crc(crc_val, packet_buff[data_inc]); + data_inc = data_inc + 1; + } + + else if (msg_id == GRF_UPDATE_RATE) { + // Update Rate + packet_buff[data_inc] = (uint8_t)data[0]; + // Add data bytes to crc add function + crc_val = grf_format_crc(crc_val, data[0]); + data_inc = data_inc + 1; + } + + else { + // Product Name + PX4_DEBUG("DEBUG: Product name"); + } + + uint8_t crc_lo = crc_val & 0xFF; + uint8_t crc_hi = (crc_val >> 8) & 0xFF; + + packet_buff[data_inc] = crc_lo; + data_inc = data_inc + 1; + packet_buff[data_inc] = crc_hi; + + size_t len = sizeof(packet_buff[0]) * (data_inc + 1); + packet_len = (uint8_t)len; + + // DEBUG + for (uint8_t i = 0; i < packet_len; ++i) { + PX4_DEBUG("DEBUG: Send byte: %d", packet_buff[i]); + } + + ret = ::write(_fd, packet_buff, packet_len); + + if (ret != packet_len) { + perf_count(_comms_errors); + PX4_ERR("serial write fail %d", ret); + // Flush data written, not transmitted + tcflush(_fd, TCOFLUSH); + } +} + +void GRFLaserSerial::grf_process_replies() +{ + float distance_m = -1.0f; + hrt_abstime now = hrt_absolute_time(); + + switch (rx_field.msg_id) { + case GRF_DISTANCE_DATA_CM: { + const float raw_distance = (rx_field.data[0] << 0) | (rx_field.data[1] << 8) | (rx_field.data[2] << 16); + distance_m = raw_distance * GRF_SCALE_FACTOR; + _px4_rangefinder.update(now, distance_m); + break; + } + + default: + // add case for future use + break; + } +} + +uint16_t GRFLaserSerial::grf_format_crc(uint16_t crc, uint8_t data_val) +{ + uint32_t i; + const uint16_t poly = 0x1021u; + crc ^= (uint16_t)((uint16_t) data_val << 8u); + + for (i = 0; i < 8; i++) { + if (crc & (1u << 15u)) { + crc = (uint16_t)((crc << 1u) ^ poly); + + } else { + crc = (uint16_t)(crc << 1u); + } + } + + return crc; +} diff --git a/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.hpp b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.hpp new file mode 100755 index 0000000000..17c73c4d54 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial.hpp @@ -0,0 +1,134 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file lightware_grf_serial.hpp + * @author Aaron Porter + * + * Serial Protocol driver for the Lightware GRF rangefinder series + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "grf_commands.h" + +enum GRF_SERIAL_STATE { + STATE_UNINIT = 0, + STATE_ACK_PRODUCT_NAME = 1, + STATE_ACK_UPDATE_RATE = 2, + STATE_ACK_DISTANCE_OUTPUT = 3, + STATE_SEND_STREAM = 4, +}; + +enum GRF_PARSED_STATE { + START = 0, + FLG_LOW, + FLG_HIGH, + ID, + DATA, + CRC_LOW, + CRC_HIGH +}; + +enum MODEL { + Disable = 0, + GRF250 = 1, + GRF500 = 2 +}; + +using namespace time_literals; +class GRFLaserSerial : public px4::ScheduledWorkItem +{ +public: + GRFLaserSerial(const char *port, uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING); + ~GRFLaserSerial() override; + + int init(); + void print_info(); + void grf_get_and_handle_request(const int payload_length, const GRF_SERIAL_CMD msg_id); + void grf_send(uint8_t msg_id, bool r_w, int32_t *data, uint8_t data_len); + uint16_t grf_format_crc(uint16_t crc, uint8_t data_value); + void grf_process_replies(); + +private: + + distance_sensor_s _distance{}; + static constexpr uint64_t GRF_MEAS_TIMEOUT{100_ms}; + static constexpr float GRF_SCALE_FACTOR = 0.1f; + + void start(); + void stop(); + void Run() override; + int measure(); + int collect(); + bool _crc_valid{false}; + + PX4Rangefinder _px4_rangefinder; + char _port[20] {}; + int _interval{200000}; + bool _collect_phase{false}; + int _fd{-1}; + uint8_t _linebuf[GRF_MAX_PAYLOAD] {}; + int _linebuf_size{0}; + + // GRF uses a binary protocol to include header,flags + // message ID, payload, and checksum + GRF_SERIAL_STATE _sensor_state{STATE_UNINIT}; + int _baud_rate{0}; + int32_t _product_name[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int32_t _stream_data{0}; + int32_t _update_rate{0}; + int32_t _model_type{0}; + int32_t _data_output{0}; + const uint8_t _start_of_frame{0xAA}; + uint16_t _data_bytes_recv{0}; + uint8_t _parsed_state{0}; + uint16_t _calc_crc{0}; + + // end of GRF data members + + hrt_abstime _last_received_time{0}; + perf_counter_t _sample_perf; + perf_counter_t _comms_errors; +}; diff --git a/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial_main.cpp b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial_main.cpp new file mode 100755 index 0000000000..08e912e2c8 --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/lightware_grf_serial_main.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "lightware_grf_serial.hpp" + +#include +#include + +namespace lightware_grf +{ + +GRFLaserSerial *g_dev{nullptr}; + +static int start(const char *port) +{ + if (g_dev != nullptr) { + PX4_WARN("already started"); + return -1; + } + + if (port == nullptr) { + PX4_ERR("no device specified"); + return -1; + } + + /* create the driver */ + g_dev = new GRFLaserSerial(port); + + if (g_dev == nullptr) { + return -1; + } + + if (g_dev->init() != PX4_OK) { + delete g_dev; + g_dev = nullptr; + return -1; + } + + return 0; +} + +static int stop() +{ + if (g_dev != nullptr) { + delete g_dev; + g_dev = nullptr; + + } else { + return -1; + } + + return 0; +} + +static int status() +{ + if (g_dev == nullptr) { + PX4_ERR("driver not running"); + return -1; + } + + g_dev->print_info(); + + return 0; +} + +static int usage() +{ + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description + +Serial bus driver for the Lightware GRF Laser rangefinder. + +### Configuration +https://docs.px4.io/main/en/sensor/grf_lidar + +### Parameters +https://docs.px4.io/main/en/advanced_config/parameter_reference#GRF_SENS_MODEL +https://docs.px4.io/main/en/advanced_config/parameter_reference#GRF_RATE_CFG +https://docs.px4.io/main/en/advanced_config/parameter_reference#SENS_EN_GRF_CFG + +### Examples + +Attempt to start driver on a specified serial device. +$ lightware_grf_serial start -d /dev/ttyS1 +Stop driver +$ lightware_grf_serial stop +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("lightware_grf_serial", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("distance_sensor"); + PRINT_MODULE_USAGE_COMMAND_DESCR("start", "Start driver"); + PRINT_MODULE_USAGE_PARAM_STRING('d', nullptr, nullptr, "Serial device", false); + PRINT_MODULE_USAGE_COMMAND_DESCR("stop", "Stop driver"); + return PX4_OK; +} + +} // namespace + +extern "C" __EXPORT int lightware_grf_serial_main(int argc, char *argv[]) +{ + const char *device_path = nullptr; + int ch; + int myoptind = 1; + const char *myoptarg = nullptr; + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_path = myoptarg; + break; + + default: + lightware_grf::usage(); + return -1; + } + } + + if (myoptind >= argc) { + lightware_grf::usage(); + return -1; + } + + if (!strcmp(argv[myoptind], "start")) { + return lightware_grf::start(device_path); + + } else if (!strcmp(argv[myoptind], "stop")) { + return lightware_grf::stop(); + + } else if (!strcmp(argv[myoptind], "status")) { + return lightware_grf::status(); + } + + lightware_grf::usage(); + return -1; +} diff --git a/src/drivers/distance_sensor/lightware_grf_serial/module.yaml b/src/drivers/distance_sensor/lightware_grf_serial/module.yaml new file mode 100755 index 0000000000..7765f9802c --- /dev/null +++ b/src/drivers/distance_sensor/lightware_grf_serial/module.yaml @@ -0,0 +1,44 @@ +module_name: Lightware GRF Rangefinder (serial) +serial_config: + - command: lightware_grf_serial start -d ${SERIAL_DEV} + port_config_param: + name: SENS_EN_GRF_CFG + group: Sensors + num_instances: 1 + supports_networking: false + +parameters: + - group: Sensors + definitions: + GRF_RATE_CFG: + description: + short: Lightware GRF lidar update rate. + long: | + The Lightware GRF distance sensor can increase the update rate to enable greater resolution. + type: enum + values: + 1: 1 Hz + 2: 2 Hz + 3: 4 Hz + 4: 5 Hz + 5: 10 Hz + 6: 20 Hz + 7: 30 Hz + 8: 40 Hz + 9: 50 Hz + reboot_required: true + num_instances: 1 + default: 4 + GRF_SENS_MODEL: + description: + short: GRF Sensor model + long: | + GRF Sensor Model used to distinush between the GRF250 and GRF500 since both have different max distance range. + type: enum + values: + 0: disable + 1: GRF250 + 2: GRF500 + reboot_required: true + num_instances: 1 + default: 0 diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp index 825cbdf97f..93c4b94b82 100644 --- a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp +++ b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp @@ -83,19 +83,39 @@ private: static constexpr uint8_t I2C_LEGACY_CMD_WRITE_LASER_CONTROL = 5; enum class Register : uint8_t { - // see http://support.lightware.co.za/sf20/#/commands + // Common registers ProductName = 0, - DistanceOutput = 27, DistanceData = 44, LaserFiring = 50, + Protocol = 120, + }; + + enum class RegisterSF20 : uint8_t { + // See http://support.lightware.co.za/sf20/#/commands + DistanceOutput = 27, MeasurementMode = 93, ZeroOffset = 94, LostSignalCounter = 95, - Protocol = 120, ServoConnected = 121, }; - static constexpr uint16_t output_data_config = 0b11010110100; + enum class RegisterSF30 : uint8_t { + // See https://lightwarelidar.com/wp-content/uploads/2025/06/SF30D-Product-Guide-v3.pdf + DistanceOutput = 29, + UpdateRate = 76, + LostSignalCounter = 115, + ZeroOffset = 116, + }; + + enum class RegisterGRF : uint8_t { + DistanceOutput = 27, + UpdateRate = 74, + }; + + + static constexpr uint16_t output_data_config_sf20 = 0b110'1011'0100; + static constexpr uint8_t output_data_config_sf30 = 0b0111'1110; + struct OutputData { int16_t first_return_median; int16_t first_return_strength; @@ -107,7 +127,9 @@ private: enum class Type { Generic = 0, - LW20c + LW20c, + SF30d, + GRF, }; enum class State { Configuring, @@ -118,10 +140,11 @@ private: void start(); - int readRegister(Register reg, uint8_t *data, int len); + template + int readRegister(RegisterType reg, uint8_t *data, int len); int configure(); - int enableI2CBinaryProtocol(); + int enableI2CBinaryProtocol(const char *product_name1, const char *product_name2); int collect(); int updateRestriction(); @@ -139,7 +162,8 @@ private: DEFINE_PARAMETERS( (ParamInt) _param_sens_en_sf1xx, - (ParamInt) _param_sf1xx_mode + (ParamInt) _param_sf1xx_mode, + (ParamInt) _param_sf1xx_rot ) uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; @@ -155,7 +179,7 @@ LightwareLaser::LightwareLaser(const I2CSPIDriverConfig &config) : I2C(config), I2CSPIDriver(config), ModuleParams(nullptr), - _px4_rangefinder(get_device_id(), config.rotation) + _px4_rangefinder(get_device_id()) { _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_LIGHTWARE_LASER); } @@ -171,6 +195,9 @@ int LightwareLaser::init() { int ret = PX4_ERROR; updateParams(); + + _px4_rangefinder.set_orientation(_param_sf1xx_rot.get()); + const int32_t hw_model = _param_sens_en_sf1xx.get(); switch (hw_model) { @@ -219,10 +246,25 @@ int LightwareLaser::init() break; case 7: - /* SF/LW30/d (200m 49-20'000Hz) */ + /* SF/SF30/d (200m 39-20'000Hz) */ _px4_rangefinder.set_min_distance(0.2f); _px4_rangefinder.set_max_distance(200.0f); - _conversion_interval = 20409; + _conversion_interval = 25641; + _type = Type::SF30d; + break; + + case 8: /* GRF250 (250m 5Hz) */ + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(250.0f); + _conversion_interval = 200000; + _type = Type::GRF; + break; + + case 9: /* GRF500 (500m 5Hz) */ + _px4_rangefinder.set_min_distance(0.1f); + _px4_rangefinder.set_max_distance(500.0f); + _conversion_interval = 200000; + _type = Type::GRF; break; default: @@ -240,7 +282,8 @@ int LightwareLaser::init() return ret; } -int LightwareLaser::readRegister(Register reg, uint8_t *data, int len) +template +int LightwareLaser::readRegister(RegisterType reg, uint8_t *data, int len) { const uint8_t cmd = (uint8_t)reg; return transfer(&cmd, 1, data, len); @@ -256,12 +299,24 @@ int LightwareLaser::probe() } case Type::LW20c: - // try to enable I2C binary protocol - int ret = enableI2CBinaryProtocol(); + return enableI2CBinaryProtocol("SF20", "LW20"); - if (ret != 0) { - return ret; - } + case Type::SF30d: + return enableI2CBinaryProtocol("SF30", "LW30"); + + case Type::GRF: + return enableI2CBinaryProtocol("GRF250", "GRF500"); + } + + return -1; +} + +int LightwareLaser::enableI2CBinaryProtocol(const char *product_name1, const char *product_name2) +{ + for (int i = 0; i < 3; ++i) { + // try to enable I2C binary protocol (this command is undocumented) + const uint8_t cmd[] = {(uint8_t)Register::Protocol, 0xaa, 0xaa}; + int ret = transfer(cmd, sizeof(cmd), nullptr, 0); // read the product name uint8_t product_name[16]; @@ -269,43 +324,10 @@ int LightwareLaser::probe() product_name[sizeof(product_name) - 1] = '\0'; PX4_DEBUG("product: %s", product_name); - if (ret == 0 && (strncmp((const char *)product_name, "SF20", sizeof(product_name)) == 0 || - strncmp((const char *)product_name, "LW20", sizeof(product_name)) == 0)) { + if (ret == 0 && (strncmp((const char *)product_name, product_name1, sizeof(product_name)) == 0 || + strncmp((const char *)product_name, product_name2, sizeof(product_name)) == 0)) { return 0; } - - return -1; - } - - return -1; -} - -int LightwareLaser::enableI2CBinaryProtocol() -{ - const uint8_t cmd[] = {(uint8_t)Register::Protocol, 0xaa, 0xaa}; - int ret = transfer(cmd, sizeof(cmd), nullptr, 0); - - if (ret != 0) { - return ret; - } - - // Now read and check against the expected values - for (int i = 0; i < 2; ++i) { - uint8_t value[2]; - ret = transfer(cmd, 1, value, sizeof(value)); - - if (ret != 0) { - return ret; - } - - PX4_DEBUG("protocol values: 0x%" PRIx8 " 0x%" PRIx8, value[0], value[1]); - - if (value[0] == 0xcc && value[1] == 0x00) { - return 0; - } - - // Occasionally the previous transfer returns ret == value[0] == value[1] == 0. If so, wait a bit and retry - px4_usleep(1000); } return -1; @@ -330,23 +352,53 @@ int LightwareLaser::configure() } break; - case Type::LW20c: + case Type::LW20c: { + // There are commonly 2 hardware variants (SF + LW) with the same specifications + int ret = enableI2CBinaryProtocol("SF20", "LW20"); + const uint8_t cmd1[] = {(uint8_t)RegisterSF20::ServoConnected, 0}; + ret |= transfer(cmd1, sizeof(cmd1), nullptr, 0); + const uint8_t cmd2[] = {(uint8_t)RegisterSF20::ZeroOffset, 0, 0, 0, 0}; + ret |= transfer(cmd2, sizeof(cmd2), nullptr, 0); + const uint8_t cmd3[] = {(uint8_t)RegisterSF20::MeasurementMode, 1}; // 48Hz + ret |= transfer(cmd3, sizeof(cmd3), nullptr, 0); + const uint8_t cmd4[] = {(uint8_t)RegisterSF20::DistanceOutput, output_data_config_sf20 & 0xff, (output_data_config_sf20 >> 8) & 0xff, 0, 0}; + ret |= transfer(cmd4, sizeof(cmd4), nullptr, 0); + const uint8_t cmd5[] = {(uint8_t)RegisterSF20::LostSignalCounter, 0, 0, 0, 0}; // immediately report lost signal + ret |= transfer(cmd5, sizeof(cmd5), nullptr, 0); + const uint8_t cmd6[] = {(uint8_t)Register::LaserFiring, (uint8_t)(_restriction ? 0 : 1)}; + ret |= transfer(cmd6, sizeof(cmd6), nullptr, 0); - int ret = enableI2CBinaryProtocol(); - const uint8_t cmd1[] = {(uint8_t)Register::ServoConnected, 0}; - ret |= transfer(cmd1, sizeof(cmd1), nullptr, 0); - const uint8_t cmd2[] = {(uint8_t)Register::ZeroOffset, 0, 0, 0, 0}; - ret |= transfer(cmd2, sizeof(cmd2), nullptr, 0); - const uint8_t cmd3[] = {(uint8_t)Register::MeasurementMode, 1}; // 48Hz - ret |= transfer(cmd3, sizeof(cmd3), nullptr, 0); - const uint8_t cmd4[] = {(uint8_t)Register::DistanceOutput, output_data_config & 0xff, (output_data_config >> 8) & 0xff, 0, 0}; - ret |= transfer(cmd4, sizeof(cmd4), nullptr, 0); - const uint8_t cmd5[] = {(uint8_t)Register::LostSignalCounter, 0, 0, 0, 0}; // immediately report lost signal - ret |= transfer(cmd5, sizeof(cmd5), nullptr, 0); - const uint8_t cmd6[] = {(uint8_t)Register::LaserFiring, (uint8_t)(_restriction ? 0 : 1)}; - ret |= transfer(cmd6, sizeof(cmd6), nullptr, 0); + return ret; + } + break; - return ret; + case Type::SF30d: { + // There are commonly 2 hardware variants (SF + LW) with the same specifications + int ret = enableI2CBinaryProtocol("SF30", "LW30"); + const uint8_t cmd2[] = {(uint8_t)RegisterSF30::ZeroOffset, 0, 0, 0, 0}; + ret |= transfer(cmd2, sizeof(cmd2), nullptr, 0); + const uint8_t cmd3[] = {(uint8_t)RegisterSF30::UpdateRate, 9}; // 39Hz + ret |= transfer(cmd3, sizeof(cmd3), nullptr, 0); + const uint8_t cmd4[] = {(uint8_t)RegisterSF30::DistanceOutput, output_data_config_sf30, 0, 0, 0}; + ret |= transfer(cmd4, sizeof(cmd4), nullptr, 0); + const uint8_t cmd5[] = {(uint8_t)RegisterSF30::LostSignalCounter, 0, 0, 0, 0}; // immediately report lost signal + ret |= transfer(cmd5, sizeof(cmd5), nullptr, 0); + const uint8_t cmd6[] = {(uint8_t)Register::LaserFiring, (uint8_t)(_restriction ? 0 : 1)}; + ret |= transfer(cmd6, sizeof(cmd6), nullptr, 0); + + return ret; + } + break; + + case Type::GRF: { + int ret = enableI2CBinaryProtocol("GRF250", "GRF500"); + const uint8_t cmd1[] = {(uint8_t) RegisterGRF::UpdateRate, 0, 0, 0, 50}; + ret |= transfer(cmd1, sizeof(cmd1), nullptr, 0); + uint8_t cmd2[] = {(uint8_t)RegisterGRF::DistanceOutput, 0, 0, 1}; + ret |= transfer(cmd2, sizeof(cmd2), nullptr, 0); + + return ret; + } break; } @@ -377,7 +429,31 @@ int LightwareLaser::collect() break; } + case Type::GRF: { + + /* read from the sensor */ + perf_begin(_sample_perf); + uint8_t val[4] {}; + const hrt_abstime timestamp_sample = hrt_absolute_time(); + + if (readRegister((uint8_t)Register::DistanceData, &val[0], 4) < 0) { + perf_count(_comms_errors); + perf_end(_sample_perf); + PX4_INFO("Register Read Error"); + return PX4_ERROR; + } + + perf_end(_sample_perf); + + uint16_t distance_cm = val[2] << 16 | val[1] << 8 | val[0]; + float distance_m = float(distance_cm) * 1e-1f; + + _px4_rangefinder.update(timestamp_sample, distance_m); + break; + } + case Type::LW20c: + case Type::SF30d: /* read from the sensor */ perf_begin(_sample_perf); @@ -402,6 +478,8 @@ int LightwareLaser::collect() _px4_rangefinder.update(timestamp_sample, distance_m, quality); break; + + } return PX4_OK; @@ -479,10 +557,15 @@ int LightwareLaser::updateRestriction() return transfer(cmd, sizeof(cmd), nullptr, 0); } - case Type::LW20c: { + case Type::LW20c: + case Type::SF30d: { const uint8_t cmd[] = {(uint8_t)Register::LaserFiring, (uint8_t)(_restriction ? 0 : 1)}; return transfer(cmd, sizeof(cmd), nullptr, 0); } + + case Type::GRF: { + return 0; + } } } @@ -551,7 +634,7 @@ void LightwareLaser::print_usage() R"DESCR_STR( ### Description -I2C bus driver for Lightware SFxx series LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20. +I2C bus driver for Lightware LIDAR rangefinders: SF10/a, SF10/b, SF10/c, SF11/c, SF/LW20, SF/LW30/d, GRF250, GRF500. Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html )DESCR_STR"); @@ -561,28 +644,17 @@ Setup/usage information: https://docs.px4.io/main/en/sensor/sfxx_lidar.html PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x66); - PRINT_MODULE_USAGE_PARAM_INT('R', 25, 0, 25, "Sensor rotation - downward facing by default", true); PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); } extern "C" __EXPORT int lightware_laser_i2c_main(int argc, char *argv[]) { - int ch; using ThisDriver = LightwareLaser; BusCLIArguments cli{true, false}; - cli.rotation = (Rotation)distance_sensor_s::ROTATION_DOWNWARD_FACING; cli.default_i2c_frequency = 400000; cli.i2c_address = LIGHTWARE_LASER_BASEADDR; - while ((ch = cli.getOpt(argc, argv, "R:")) != EOF) { - switch (ch) { - case 'R': - cli.rotation = (Rotation)atoi(cli.optArg()); - break; - } - } - - const char *verb = cli.optArg(); + const char *verb = cli.parseDefaultArguments(argc, argv); if (!verb) { ThisDriver::print_usage(); diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c index 161e9d3cab..d549144f9d 100644 --- a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c +++ b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c @@ -32,11 +32,11 @@ ****************************************************************************/ /** - * Lightware SF1xx/SF20/LW20 laser rangefinder (i2c) + * Lightware laser rangefinder (i2c) * * @reboot_required true * @min 0 - * @max 6 + * @max 9 * @group Sensors * @value 0 Disabled * @value 1 SF10/a @@ -46,11 +46,13 @@ * @value 5 SF/LW20/b * @value 6 SF/LW20/c * @value 7 SF/LW30/d + * @value 8 GRF250 + * @value 9 GRF500 */ PARAM_DEFINE_INT32(SENS_EN_SF1XX, 0); /** - * Lightware SF1xx/SF20/LW20 Operation Mode + * Lightware laser rangefinder Operation Mode * * @value 0 Disabled * @value 1 Enabled @@ -60,3 +62,22 @@ PARAM_DEFINE_INT32(SENS_EN_SF1XX, 0); * @max 2 */ PARAM_DEFINE_INT32(SF1XX_MODE, 1); + +/** + * Lightware laser rangefinder Rotation + * + * Distance sensor orientation as MAV_SENSOR_ORIENTATION enum. + * Applies to all models supported by SENS_EN_SF1XX. + * + * @reboot_required true + * @min 0 + * @max 25 + * @group Sensors + * @value 0 Forward + * @value 2 Right + * @value 4 Backward + * @value 6 Left + * @value 24 Upward + * @value 25 Downward + */ +PARAM_DEFINE_INT32(SF1XX_ROT, 25); diff --git a/src/drivers/distance_sensor/mb12xx/mb12xx.cpp b/src/drivers/distance_sensor/mb12xx/mb12xx.cpp index da8d5321b0..402b2a32e9 100644 --- a/src/drivers/distance_sensor/mb12xx/mb12xx.cpp +++ b/src/drivers/distance_sensor/mb12xx/mb12xx.cpp @@ -371,7 +371,9 @@ MB12XX::set_address(const uint8_t address) address == 80 || address == 164 || address == 170 || - address > 224) { + address > 224 || + (address % 2) != 0 || + address < MB12XX_MIN_ADDR) { PX4_ERR("incompatible address requested"); return PX4_ERROR; } @@ -386,6 +388,8 @@ MB12XX::set_address(const uint8_t address) } set_device_address(address); + _sensor_addresses[0] = address; + PX4_INFO("device address: %u", get_device_address()); return PX4_OK; } @@ -423,6 +427,7 @@ extern "C" __EXPORT int mb12xx_main(int argc, char *argv[]) using ThisDriver = MB12XX; BusCLIArguments cli{true, false}; cli.default_i2c_frequency = MB12XX_BUS_SPEED; + cli.i2c_address = MB12XX_BASE_ADDR; const char *verb = cli.parseDefaultArguments(argc, argv); @@ -431,8 +436,6 @@ extern "C" __EXPORT int mb12xx_main(int argc, char *argv[]) return -1; } - cli.i2c_address = MB12XX_BASE_ADDR; - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_DIST_DEVTYPE_MB12XX); if (!strcmp(verb, "start")) { diff --git a/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp b/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp index fb95686381..2c3b22d57b 100644 --- a/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp +++ b/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp @@ -39,27 +39,15 @@ #define VL53L1X_DELAY 50000 // delay to reduce CPU usage (us) #define VL53L1X_SAMPLE_RATE 200 // ms, default -#define VL53L1X_INTER_MEAS_MS 200 // ms +#define VL53L1X_INTER_MEAS_MS 250 // ms #define VL53L1X_SHORT_RANGE 1 // sub-2 meter distance mode #define VL53L1X_LONG_RANGE 2 // sub-4 meter distance mode #define VL53L1X_RANGE_STATUS_OUT_OF_BOUNDS 13 // region of interest out of bounds error #define VL53L1X_RANGE_STATUS_OK 0 // range status ok -#define VL53L1X_ROI_FAR_RIGHT 247 // ROI far right of optical center -#define VL53L1X_ROI_MID_RIGHT 215 // ROI middle right of optical center -#define VL53L1X_ROI_CENTER_LEFT 183 // ROI optical center left +#define VL53L1X_ROI_MID_RIGHT 231 // ROI middle right of optical center #define VL53L1X_ROI_MID_LEFT 167 // ROI middle left of optical center -#define VL53L1X_ROI_FAR_LEFT 151 // ROI far left of optical center -#define VL53L1X_ROI_FAR_RIGHT_LO 10 // ROI far right lo -#define VL53L1X_ROI_MID_RIGHT_LO 42 // ROI middle right of optical center -#define VL53L1X_ROI_CENTER_LEFT_LO 74 // ROI optical center left lo -#define VL53L1X_ROI_MID_LEFT_LO 90 // ROI middle left of optical center -#define VL53L1X_ROI_FAR_LEFT_LO 106 // ROI far left lo -#define VL53L1X_ROI_FAR_RIGHT_HI 243 // ROI far right hi -#define VL53L1X_ROI_MID_RIGHT_HI 211 // ROI middle right of optical center -#define VL53L1X_ROI_CENTER_LEFT_HI 179 // ROI optical center left hi -#define VL53L1X_ROI_MID_LEFT_HI 163 // ROI middle left of optical center -#define VL53L1X_ROI_FAR_LEFT_HI 147 // ROI far left hi +using namespace matrix; /* ST */ const uint8_t VL51L1X_DEFAULT_CONFIGURATION[] = { 0x00, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), else don't touch */ @@ -164,7 +152,7 @@ static const uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0, // ROI array assignment -uint8_t roi_center[] = {VL53L1X_ROI_FAR_RIGHT, VL53L1X_ROI_MID_RIGHT, VL53L1X_ROI_CENTER_LEFT, VL53L1X_ROI_MID_LEFT, VL53L1X_ROI_FAR_LEFT, VL53L1X_ROI_FAR_RIGHT_LO, VL53L1X_ROI_MID_RIGHT_LO, VL53L1X_ROI_CENTER_LEFT_LO, VL53L1X_ROI_MID_LEFT_LO, VL53L1X_ROI_FAR_LEFT_LO, VL53L1X_ROI_FAR_RIGHT_HI, VL53L1X_ROI_MID_RIGHT_HI, VL53L1X_ROI_CENTER_LEFT_HI, VL53L1X_ROI_MID_LEFT_HI, VL53L1X_ROI_FAR_LEFT_HI}; +uint8_t roi_center[] = { VL53L1X_ROI_MID_RIGHT, VL53L1X_ROI_MID_LEFT}; VL53L1X::VL53L1X(const I2CSPIDriverConfig &config) : I2C(config), @@ -173,6 +161,8 @@ VL53L1X::VL53L1X(const I2CSPIDriverConfig &config) : { // Set distance mode (1 for ~2m ranging, 2 for ~4m ranging _distance_mode = VL53L1X_LONG_RANGE; + + _sensor_orientation = config.rotation; // VL53L1X typical range 0-4 meters with 27 degree field of view _px4_rangefinder.set_min_distance(0.f); @@ -190,6 +180,7 @@ VL53L1X::VL53L1X(const I2CSPIDriverConfig &config) : // Zone index _zone_index = 0; + // Allow 3 retries as the device typically misses the first measure attempts. I2C::_retries = 3; @@ -208,12 +199,13 @@ int VL53L1X::collect() uint8_t ret = 0; uint8_t rangeStatus = VL53L1X_RANGE_STATUS_OK; uint16_t distance_mm = 0; - + static constexpr float DOWNWARD_FACING_THETA = -1.57f; + static constexpr float RIGHT_PSI = 0.117809725; + static constexpr float LEFT_PSI = -0.117809725; perf_begin(_sample_perf); - const hrt_abstime timestamp_sample = hrt_absolute_time(); - ret = VL53L1X_GetRangeStatus(&rangeStatus); + const int8_t quality = VL53L1X_GetRangeStatus(&rangeStatus); if ((ret != PX4_OK) | (rangeStatus == VL53L1X_RANGE_STATUS_OUT_OF_BOUNDS)) { perf_count(_comms_errors); @@ -221,9 +213,18 @@ int VL53L1X::collect() return PX4_ERROR; } + const hrt_abstime timestamp_sample = hrt_absolute_time(); + ret = VL53L1X_GetDistance(&distance_mm); + ret |= VL53L1X_ClearInterrupt(); + // zone modulus increment + _zone_index = (_zone_index + 1) % _zone_limit; + + // Set the ROI center based on zone incrementation + ret |= VL53L1X_SetROICenter(roi_center[_zone_index]); + if (ret != PX4_OK) { perf_count(_comms_errors); perf_end(_sample_perf); @@ -233,8 +234,34 @@ int VL53L1X::collect() perf_end(_sample_perf); float distance_m = distance_mm / 1000.f; + float psi = 0.f; + float theta = 0.f; - _px4_rangefinder.update(timestamp_sample, distance_m); + if (_sensor_orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING) { + theta = DOWNWARD_FACING_THETA; + } + + float phi = 0.f; + + switch (roi_center[_zone_index]) { + + case VL53L1X_ROI_MID_RIGHT: + psi = RIGHT_PSI; // Approximately 7 degrees; + break; + + case VL53L1X_ROI_MID_LEFT: + psi = LEFT_PSI; + break; + + default: + break; + } + + Quaternionf quat_e = Eulerf(phi, theta, psi); + + float dist_q[] {quat_e(0), quat_e(1), quat_e(2), quat_e(3)}; + + _px4_rangefinder.update(timestamp_sample, distance_m, quality, dist_q); return PX4_OK; } @@ -264,7 +291,6 @@ void VL53L1X::RunImpl() { uint8_t dataReady = 0; - VL53L1X_CheckForDataReady(&dataReady); if (dataReady == 1) { @@ -273,10 +299,7 @@ void VL53L1X::RunImpl() // Reduce CPU usage ScheduleDelayed(VL53L1X_DELAY); - // zone modulus increment - _zone_index = (_zone_index + 1) % _zone_limit; - // Set the ROI center based on zone incrementation - VL53L1X_SetROICenter(roi_center[_zone_index]); + } int VL53L1X::init() @@ -290,10 +313,8 @@ int VL53L1X::init() } // Spad width (x) & height (y) - - uint8_t x = 4; - uint8_t y = 4; - + uint8_t x = 8; + uint8_t y = 16; ret |= VL53L1X_SensorInit(); ret |= VL53L1X_ConfigBig(_distance_mode, VL53L1X_SAMPLE_RATE); diff --git a/src/drivers/distance_sensor/vl53l1x/vl53l1x.hpp b/src/drivers/distance_sensor/vl53l1x/vl53l1x.hpp index a086db3a47..2161bcf5b3 100644 --- a/src/drivers/distance_sensor/vl53l1x/vl53l1x.hpp +++ b/src/drivers/distance_sensor/vl53l1x/vl53l1x.hpp @@ -48,7 +48,7 @@ #include #include #include - +#include /* ST */ #define SOFT_RESET 0x0000 #define VL53L1_I2C_SLAVE__DEVICE_ADDRESS 0x0001 @@ -157,7 +157,7 @@ private: int8_t VL53L1X_SetROICenter(uint8_t data); int8_t VL53L1X_SetROI(uint16_t x, uint16_t y); PX4Rangefinder _px4_rangefinder; - + Rotation _sensor_orientation{ROTATION_PITCH_270}; perf_counter_t _comms_errors{perf_alloc(PC_COUNT, MODULE_NAME": com_err")}; perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")}; }; diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index 2d943397ea..bcd663dd05 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -184,6 +184,7 @@ #define DRV_IMU_DEVTYPE_UAVCAN 0x87 #define DRV_MAG_DEVTYPE_UAVCAN 0x88 #define DRV_DIST_DEVTYPE_UAVCAN 0x89 +#define DRV_HYGRO_DEVTYPE_UAVCAN 0x8A #define DRV_ADC_DEVTYPE_ADS1115 0x90 @@ -201,6 +202,7 @@ #define DRV_DIST_DEVTYPE_GY_US42 0x9C #define DRV_BAT_DEVTYPE_BATMON_SMBUS 0x9d +#define DRV_GPIO_DEVTYPE_MCP23017 0x9E #define DRV_GPIO_DEVTYPE_MCP23009 0x9F #define DRV_GPS_DEVTYPE_ASHTECH 0xA0 @@ -214,6 +216,8 @@ #define DRV_GPS_DEVTYPE_UBX_8 0xA8 #define DRV_GPS_DEVTYPE_UBX_9 0xA9 #define DRV_GPS_DEVTYPE_UBX_F9P 0xAA +#define DRV_GPS_DEVTYPE_UBX_10 0xAC +#define DRV_GPS_DEVTYPE_UBX_20 0xAD #define DRV_GPS_DEVTYPE_NMEA 0xAB #define DRV_GPS_DEVTYPE_SIM 0xAF @@ -254,6 +258,16 @@ #define DRV_INS_DEVTYPE_ILABS 0xE9 #define DRV_INS_DEVTYPE_MICROSTRAIN 0xEA +#define DRV_INS_DEVTYPE_BAHRS 0xEB + +#define DRV_INS_DEVTYPE_SBG 0xEC + +#define DRV_ADC_DEVTYPE_ADS7953 0xED +#define DRV_ADC_DEVTYPE_TLA2528 0xEF + + +#define DRV_TEMP_DEVTYPE_MCP9808 0xEE +#define DRV_TEMP_DEVTYPE_TMP102 0xF0 #define DRV_DEVTYPE_UNUSED 0xff diff --git a/src/drivers/gnss/septentrio/CMakeLists.txt b/src/drivers/gnss/septentrio/CMakeLists.txt index 6971f57e28..3b3cd47ecc 100644 --- a/src/drivers/gnss/septentrio/CMakeLists.txt +++ b/src/drivers/gnss/septentrio/CMakeLists.txt @@ -37,7 +37,7 @@ px4_add_module( COMPILE_FLAGS # -DDEBUG_BUILD # Enable during development of the module -DSEP_LOG_ERROR # Enable module-level error logs - # -DSEP_LOG_WARN # Enable module-level warning logs + -DSEP_LOG_WARN # Enable module-level warning logs # -DSEP_LOG_INFO # Enable module-level info logs # -DSEP_LOG_TRACE_PARSING # Tracing of parsing steps SRCS diff --git a/src/drivers/gnss/septentrio/sbf/decoder.cpp b/src/drivers/gnss/septentrio/sbf/decoder.cpp index 308d26ef9b..3c66555449 100644 --- a/src/drivers/gnss/septentrio/sbf/decoder.cpp +++ b/src/drivers/gnss/septentrio/sbf/decoder.cpp @@ -163,7 +163,7 @@ int Decoder::parse(QualityInd *message) const int Decoder::parse(RFStatus *message) const { - if (can_parse() && id() == BlockID::PVTGeodetic) { + if (can_parse() && id() == BlockID::RFStatus) { static_assert(sizeof(*message) <= sizeof(_message.payload), "Buffer too small"); memcpy(message, _message.payload, sizeof(RFStatus) - sizeof(RFStatus::rf_band)); diff --git a/src/drivers/gnss/septentrio/sbf/messages.h b/src/drivers/gnss/septentrio/sbf/messages.h index 8b7ca0c95e..704f4c3b6e 100644 --- a/src/drivers/gnss/septentrio/sbf/messages.h +++ b/src/drivers/gnss/septentrio/sbf/messages.h @@ -243,9 +243,14 @@ struct QualityInd { }; struct RFBand { + enum class InfoMode : uint8_t { + Suppressed = 1, + Mitigated = 2, + Interference = 8 + }; uint32_t frequency; uint16_t bandwidth; - uint8_t info_mode: 4; + uint8_t info_mode: 4; uint8_t info_reserved: 2; uint8_t info_antenna_id: 2; }; @@ -261,6 +266,15 @@ struct RFStatus { }; struct GALAuthStatus { + enum class OSNMAStatus : uint16_t { + Disabled = 0, + Initializing = 1, + AwaitingTrustedTimeInfo = 2, + InitFailedInconsistentTime = 3, + InitFailedKROOTInvalid = 4, + InitFailedInvalidParam = 5, + Authenticating = 6, + }; uint16_t osnma_status_status: 3; uint16_t osnma_status_initialization_progress: 8; uint16_t osnma_status_trusted_time_source: 3; @@ -271,6 +285,8 @@ struct GALAuthStatus { uint64_t gal_authentic_mask; uint64_t gps_active_mask; uint64_t gps_authentic_mask; + + OSNMAStatus osnmaStatus() const { return static_cast(osnma_status_status); } }; struct VelCovGeodetic { diff --git a/src/drivers/gnss/septentrio/septentrio.cpp b/src/drivers/gnss/septentrio/septentrio.cpp index d05e0b61e5..a20b0b9365 100644 --- a/src/drivers/gnss/septentrio/septentrio.cpp +++ b/src/drivers/gnss/septentrio/septentrio.cpp @@ -92,7 +92,7 @@ constexpr size_t k_min_receiver_read_bytes = 32; */ constexpr uint32_t k_septentrio_receiver_default_baud_rate = 115200; -constexpr uint8_t k_max_command_size = 120; +constexpr uint8_t k_max_command_size = 140; constexpr uint16_t k_timeout_5hz = 500; constexpr uint32_t k_read_buffer_size = 150; constexpr time_t k_gps_epoch_secs = 1234567890ULL; // TODO: This seems wrong @@ -112,7 +112,7 @@ constexpr const char *k_command_reset_hot = "erst,soft,none\n"; constexpr const char *k_command_reset_warm = "erst,soft,PVTData\n"; constexpr const char *k_command_reset_cold = "erst,hard,SatData\n"; constexpr const char *k_command_sbf_output_pvt = - "sso,Stream%" PRIu32 ",%s,PVTGeodetic+VelCovGeodetic+DOP+AttEuler+AttCovEuler+EndOfPVT+ReceiverStatus,%s\n"; + "sso,Stream%lu,%s,PVTGeodetic+VelCovGeodetic+DOP+AttEuler+AttCovEuler+EndOfPVT+ReceiverStatus+GALAuthStatus+RFStatus+QualityInd,%s\n"; constexpr const char *k_command_set_sbf_output = "sso,Stream%" PRIu32 ",%s,%s%s,%s\n"; constexpr const char *k_command_clear_sbf = "sso,Stream%" PRIu32 ",%s,none,off\n"; @@ -967,7 +967,7 @@ SeptentrioDriver::ConfigureResult SeptentrioDriver::configure() } // Output a set of SBF blocks on a given connection at a regular interval. - snprintf(msg, sizeof(msg), k_command_sbf_output_pvt, _receiver_stream_main, com_port, sbf_frequency); + snprintf(msg, sizeof(msg), k_command_sbf_output_pvt, (long unsigned int) _receiver_stream_main, com_port, sbf_frequency); if (!send_message_and_wait_for_ack(msg, k_receiver_ack_timeout_fast)) { SEP_WARN("CONFIG: Failed to configure SBF"); return ConfigureResult::FailedCompletely; @@ -1191,20 +1191,138 @@ int SeptentrioDriver::process_message() if (_sbf_decoder.parse(&receiver_status) == PX4_OK) { _sensor_gps.rtcm_msg_used = receiver_status.rx_state_diff_corr_in ? sensor_gps_s::RTCM_MSG_USED_USED : sensor_gps_s::RTCM_MSG_USED_NOT_USED; _time_synced = receiver_status.rx_state_wn_set && receiver_status.rx_state_tow_set; + + _sensor_gps.system_error = sensor_gps_s::SYSTEM_ERROR_OK; + + if (receiver_status.rx_error_cpu_overload) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_CPU_OVERLOAD; + } + if (receiver_status.rx_error_antenna) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_ANTENNA; + } + if (receiver_status.ext_error_diff_corr_error) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_INCOMING_CORRECTIONS; + } + if (receiver_status.ext_error_setup_error) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_CONFIGURATION; + } + if (receiver_status.rx_error_software) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_SOFTWARE; + } + if (receiver_status.rx_error_congestion) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_OUTPUT_CONGESTION; + } + if (receiver_status.rx_error_missed_event) { + _sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_EVENT_CONGESTION; + } } break; } case BlockID::QualityInd: { + using Type = QualityIndicator::Type; + SEP_TRACE_PARSING("Processing QualityInd SBF message"); + + QualityInd quality_ind; + + if (_sbf_decoder.parse(&quality_ind) == PX4_OK) { + _message_sensor_gnss_status.quality_available = true; + _message_sensor_gnss_status.device_id = get_device_id(); + + _message_sensor_gnss_status.quality_corrections = 255; + _message_sensor_gnss_status.quality_receiver = 255; + _message_sensor_gnss_status.quality_post_processing = 255; + _message_sensor_gnss_status.quality_gnss_signals = 255; + + for (int i = 0; i < math::min(quality_ind.n, static_cast(sizeof(quality_ind.indicators) / sizeof(quality_ind.indicators[0]))); i++) { + int quality = quality_ind.indicators[i].value; + + switch (quality_ind.indicators[i].type) { + case Type::BaseStationMeasurements: + _message_sensor_gnss_status.quality_corrections = quality; + break; + case Type::Overall: + _message_sensor_gnss_status.quality_receiver = quality; + break; + case Type::RTKPostProcessing: + _message_sensor_gnss_status.quality_post_processing = quality; + break; + case Type::GNSSSignalsMainAntenna: + _message_sensor_gnss_status.quality_gnss_signals = quality; + break; + default: + break; + } + } + + + _message_sensor_gnss_status.timestamp = hrt_absolute_time(); + _time_last_qualityind_received = hrt_absolute_time(); + _sensor_gnss_status_pub.publish(_message_sensor_gnss_status); + } + break; } case BlockID::RFStatus: { + using InfoMode = RFBand::InfoMode; + SEP_TRACE_PARSING("Processing RFStatus SBF message"); + + RFStatus rf_status; + + if (_sbf_decoder.parse(&rf_status) == PX4_OK) { + _sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_OK; + _sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_OK; + + for (int i = 0; i < math::min(rf_status.n, static_cast(sizeof(rf_status.rf_band) / sizeof(rf_status.rf_band[0]))); i++) { + InfoMode status = static_cast(rf_status.rf_band[i].info_mode); + + if(status == InfoMode::Interference){ + _sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_DETECTED; + break; // Worst case, we don't need to check the other bands + } + + if(status == InfoMode::Suppressed || status == InfoMode::Mitigated){ + _sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_MITIGATED; + } + } + + if (rf_status.flags_inauthentic_gnss_signals || rf_status.flags_inauthentic_navigation_message) { + _sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_DETECTED; + } + _time_last_resilience_received = hrt_absolute_time(); + } + break; } case BlockID::GALAuthStatus: { + using OSNMAStatus = GALAuthStatus::OSNMAStatus; + SEP_TRACE_PARSING("Processing GALAuthStatus SBF message"); + + GALAuthStatus gal_auth_status; + + if (_sbf_decoder.parse(&gal_auth_status) == PX4_OK) { + switch (gal_auth_status.osnmaStatus()) { + case OSNMAStatus::Disabled: + _sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_DISABLED; + break; + case OSNMAStatus::AwaitingTrustedTimeInfo: + case OSNMAStatus::Initializing: + _sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_INITIALIZING; + break; + case OSNMAStatus::InitFailedInconsistentTime: + case OSNMAStatus::InitFailedKROOTInvalid: + case OSNMAStatus::InitFailedInvalidParam: + _sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_ERROR; + break; + case OSNMAStatus::Authenticating: + _sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_OK; + break; + } + } + break; } case BlockID::EndOfPVT: { @@ -1277,6 +1395,31 @@ int SeptentrioDriver::process_message() } } + //Check for how recent the resilience data for reciever is, if outdated set to unknown + if ((_time_last_resilience_received != 0) && (hrt_elapsed_time(&_time_last_resilience_received) > 5_s)) { + _sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_UNKNOWN; + _sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_UNKNOWN; + + _time_last_resilience_received = 0; // Reset + } + + // Check for how recent the status data for receiver is, if outdated set to unknown + if ((_time_last_qualityind_received != 0) && (hrt_elapsed_time(&_time_last_qualityind_received) > 5_s)) { + _message_sensor_gnss_status.quality_available = false; + _message_sensor_gnss_status.device_id = get_device_id(); + _message_sensor_gnss_status.timestamp = hrt_absolute_time(); + + _message_sensor_gnss_status.quality_corrections = 255; + _message_sensor_gnss_status.quality_receiver = 255; + _message_sensor_gnss_status.quality_post_processing = 255; + _message_sensor_gnss_status.quality_gnss_signals = 255; + + + _sensor_gnss_status_pub.publish(_message_sensor_gnss_status); + + _time_last_qualityind_received = 0; // Reset + } + break; } case DecodingStatus::RTCMv3: { @@ -1532,6 +1675,7 @@ void SeptentrioDriver::publish() _sensor_gps.device_id = get_device_id(); _sensor_gps.selected_rtcm_instance = _selected_rtcm_instance; _sensor_gps.rtcm_injection_rate = rtcm_injection_frequency(); + _sensor_gps.timestamp = hrt_absolute_time(); _sensor_gps_pub.publish(_sensor_gps); } @@ -1584,7 +1728,8 @@ void SeptentrioDriver::publish_rtcm_corrections(uint8_t *data, size_t len) void SeptentrioDriver::dump_gps_data(const uint8_t *data, size_t len, DataDirection data_direction) { gps_dump_s *dump_data = data_direction == DataDirection::FromReceiver ? _message_data_from_receiver : _message_data_to_receiver; - dump_data->instance = _instance == Instance::Main ? 0 : 1; + dump_data->instance = _instance == Instance::Main ? gps_dump_s::INSTANCE_MAIN : gps_dump_s::INSTANCE_SECONDARY; + dump_data->device_id = get_device_id(); while (len > 0) { size_t write_len = len; diff --git a/src/drivers/gnss/septentrio/septentrio.h b/src/drivers/gnss/septentrio/septentrio.h index 052d6ac1cd..cdc21fd092 100644 --- a/src/drivers/gnss/septentrio/septentrio.h +++ b/src/drivers/gnss/septentrio/septentrio.h @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -710,12 +711,16 @@ private: char _port[20] {}; ///< The path of the used serial device hrt_abstime _last_rtcm_injection_time {0}; ///< Time of last RTCM injection uint8_t _selected_rtcm_instance {0}; ///< uORB instance that is being used for RTCM corrections + uint8_t _spoofing_state {0}; ///< Receiver spoofing state + uint8_t _jamming_state {0}; ///< Receiver jamming state bool _time_synced {false}; ///< Receiver time in sync with GPS time const Instance _instance {Instance::Main}; ///< The receiver that this instance of the driver controls uint32_t _chosen_baud_rate {0}; ///< The baud rate requested by the user static px4::atomic _secondary_instance; hrt_abstime _sleep_end {0}; ///< End time for sleeping State _resume_state {State::OpeningSerialPort}; ///< Resume state after sleep + hrt_abstime _time_last_qualityind_received{0}; ///< Time of last quality message reception + hrt_abstime _time_last_resilience_received{0}; ///< Time of last resilience message reception // Module configuration float _heading_offset {0.0f}; ///< The heading offset given by the `SEP_YAW_OFFS` parameter @@ -737,14 +742,16 @@ private: rtcm::Decoder *_rtcm_decoder {nullptr}; ///< RTCM message decoder // uORB topics and subscriptions - sensor_gps_s _sensor_gps{}; ///< uORB topic for position - gps_dump_s *_message_data_to_receiver {nullptr}; ///< uORB topic for dumping data to the receiver - gps_dump_s *_message_data_from_receiver {nullptr}; ///< uORB topic for dumping data from the receiver - satellite_info_s *_message_satellite_info {nullptr}; ///< uORB topic for satellite info - uORB::PublicationMulti _sensor_gps_pub {ORB_ID(sensor_gps)}; ///< uORB publication for gps position - uORB::Publication _gps_dump_pub {ORB_ID(gps_dump)}; ///< uORB publication for dump GPS data - uORB::Publication _gps_inject_data_pub {ORB_ID(gps_inject_data)}; ///< uORB publication for injected data to the receiver - uORB::PublicationMulti _satellite_info_pub {ORB_ID(satellite_info)}; ///< uORB publication for satellite info + sensor_gps_s _sensor_gps {}; ///< uORB topic for position + sensor_gnss_status_s _message_sensor_gnss_status {}; ///< uORB topic for gps status + gps_dump_s *_message_data_to_receiver {nullptr}; ///< uORB topic for dumping data to the receiver + gps_dump_s *_message_data_from_receiver {nullptr}; ///< uORB topic for dumping data from the receiver + satellite_info_s *_message_satellite_info {nullptr}; ///< uORB topic for satellite info + uORB::PublicationMulti _sensor_gps_pub {ORB_ID(sensor_gps)}; ///< uORB publication for gps position + uORB::PublicationMulti _sensor_gnss_status_pub {ORB_ID(sensor_gnss_status)}; ///< uORB publication for gnss status + uORB::Publication _gps_dump_pub {ORB_ID(gps_dump)}; ///< uORB publication for dump GPS data + uORB::Publication _gps_inject_data_pub {ORB_ID(gps_inject_data)}; ///< uORB publication for injected data to the receiver + uORB::PublicationMulti _satellite_info_pub {ORB_ID(satellite_info)}; ///< uORB publication for satellite info uORB::SubscriptionMultiArray _gps_inject_data_sub {ORB_ID::gps_inject_data}; ///< uORB subscription about data to inject to the receiver // Data about update frequencies of various bits of information like RTCM message injection frequency, received data rate... diff --git a/src/drivers/gpio/Kconfig b/src/drivers/gpio/Kconfig index 902613ebbf..131cd4431b 100644 --- a/src/drivers/gpio/Kconfig +++ b/src/drivers/gpio/Kconfig @@ -1,9 +1,3 @@ menu "GPIO" - menuconfig COMMON_GPIO - bool "Common GPIOs" - default n - select DRIVERS_GPIO_MCP23009 - ---help--- - Enable default set of GPIO drivers rsource "*/Kconfig" endmenu diff --git a/src/drivers/gpio/mcp23009/CMakeLists.txt b/src/drivers/gpio/mcp23009/CMakeLists.txt index c7897fea8e..60ff7868cf 100644 --- a/src/drivers/gpio/mcp23009/CMakeLists.txt +++ b/src/drivers/gpio/mcp23009/CMakeLists.txt @@ -30,12 +30,13 @@ # POSSIBILITY OF SUCH DAMAGE. # ############################################################################ + px4_add_module( - MODULE drivers__mcp23009 + MODULE drivers__gpio__mcp23009 MAIN mcp23009 - COMPILE_FLAGS SRCS - mcp23009_main.cpp - mcp23009.cpp + MCP23009_main.cpp + MCP23009.cpp DEPENDS + mcp_common ) diff --git a/src/drivers/gpio/mcp23009/Kconfig b/src/drivers/gpio/mcp23009/Kconfig index 73078bf8eb..52d9b05775 100644 --- a/src/drivers/gpio/mcp23009/Kconfig +++ b/src/drivers/gpio/mcp23009/Kconfig @@ -1,5 +1,5 @@ menuconfig DRIVERS_GPIO_MCP23009 - bool "mcp23009" + bool "MCP23009" default n ---help--- - Enable support for mcp23009 + Enable support for MCP23009 8-bit GPIO expander diff --git a/src/drivers/gpio/mcp23009/MCP23009.cpp b/src/drivers/gpio/mcp23009/MCP23009.cpp new file mode 100644 index 0000000000..1f258efb41 --- /dev/null +++ b/src/drivers/gpio/mcp23009/MCP23009.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "MCP23009.hpp" + +MCP23009::MCP23009(const I2CSPIDriverConfig &config) : + MCP230XX(config) +{ +} + +int MCP23009::get_olat(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::OLAT; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23009::get_gppu(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::GPPU; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23009::get_iodir(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::IODIR; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23009::get_gpio(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::GPIO; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23009::get_probe_reg(uint8_t *addr) +{ + *addr = (uint8_t) Register::IOCON; + return PX4_OK; +} diff --git a/src/drivers/gpio/mcp23009/MCP23009.hpp b/src/drivers/gpio/mcp23009/MCP23009.hpp new file mode 100644 index 0000000000..263c27182b --- /dev/null +++ b/src/drivers/gpio/mcp23009/MCP23009.hpp @@ -0,0 +1,64 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once +#include + +using namespace time_literals; + +class MCP23009 : public MCP230XX +{ +public: + MCP23009(const I2CSPIDriverConfig &config); + +private: + enum class + Register : uint8_t { + IODIR = 0x00, + IPOL = 0x01, + GPINTEN = 0x02, + DEFVAL = 0x03, + INTCON = 0x04, + IOCON = 0x05, + GPPU = 0x06, + INTF = 0x07, + INTCAP = 0x08, + GPIO = 0x09, + OLAT = 0x0a + }; + + int get_olat(int bank, uint8_t *addr) override; + int get_gppu(int bank, uint8_t *addr) override; + int get_iodir(int bank, uint8_t *addr) override; + int get_gpio(int bank, uint8_t *addr) override; + int get_probe_reg(uint8_t *addr) override; +}; diff --git a/src/drivers/gpio/mcp23009/MCP23009_main.cpp b/src/drivers/gpio/mcp23009/MCP23009_main.cpp new file mode 100644 index 0000000000..106a9be055 --- /dev/null +++ b/src/drivers/gpio/mcp23009/MCP23009_main.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "MCP23009.hpp" + +constexpr MCP230XX_config_t def_mcp_config{ + .device_type = DRV_GPIO_DEVTYPE_MCP23009, + .i2c_addr = I2C_ADDRESS_MCP23009, + .num_pins = 8, + .num_banks = 1, +}; + +extern "C" int mcp23009_main(int argc, char *argv[]) +{ + using ThisDriver = MCP23009; + BusCLIArguments cli{true, false}; + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x25; + MCP230XX_config_t mcp_config = def_mcp_config; + + int ch; + + while ((ch = cli.getOpt(argc, argv, "D:O:P:U:R:M:")) != EOF) { + switch (ch) { + + case 'D': + mcp_config.direction = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'O': + mcp_config.state = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'P': + mcp_config.pullup = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'U': + mcp_config.interval = (uint16_t)atoi(cli.optArg()); + break; + + case 'M': + mcp_config.first_minor = (uint8_t)atoi(cli.optArg()); + break; + } + } + + const char *verb = cli.optArg(); + + if (!verb) { + MCP230XX::print_usage(); + return -1; + } + + cli.custom_data = &mcp_config; + + BusInstanceIterator iterator("MCP23009", cli, mcp_config.device_type); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + MCP230XX::print_usage(); + return -1; +} diff --git a/src/drivers/gpio/mcp23009/mcp23009.cpp b/src/drivers/gpio/mcp23009/mcp23009.cpp deleted file mode 100644 index 8d8eb92885..0000000000 --- a/src/drivers/gpio/mcp23009/mcp23009.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2023 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include "mcp23009.h" - -int MCP23009::read_reg(Register address, uint8_t &data) -{ - return transfer((uint8_t *)&address, 1, &data, 1); -} - -int MCP23009::write_reg(Register address, uint8_t value) -{ - uint8_t data[2] = {(uint8_t)address, value}; - return transfer(data, sizeof(data), nullptr, 0); -} - -int MCP23009::init(uint8_t direction, uint8_t state, uint8_t pull_up) -{ - // do I2C init (and probe) first - int ret = I2C::init(); - - if (ret != PX4_OK) { - PX4_ERR("I2C init failed"); - return ret; - } - - // buffer the new initial states - _iodir = direction; - _olat = state; - _gppu = pull_up; - - // Write the initial state to the device - ret = write_reg(Register::OLAT, _olat); - ret |= write_reg(Register::IODIR, _iodir); - ret |= write_reg(Register::GPPU, _gppu); - - if (ret != PX4_OK) { - PX4_ERR("Device init failed (%i)", ret); - return ret; - } - - return init_uorb(); -} - -int MCP23009::probe() -{ - // no whoami, try to read IOCON - uint8_t data; - return read_reg(Register::IOCON, data); -} - -int MCP23009::read(uint8_t *mask) -{ - return read_reg(Register::GPIO, *mask); -} - -int MCP23009::write(uint8_t mask_set, uint8_t mask_clear) -{ - // no need to read, we can use the buffered register value - _olat = (_olat & ~mask_clear) | mask_set; - return write_reg(Register::OLAT, _olat); -} - -int MCP23009::configure(uint8_t mask, PinType type) -{ - // no need to read, we can use the buffered register values - switch (type) { - case PinType::Input: - _iodir |= mask; - _gppu &= ~mask; - break; - - case PinType::InputPullUp: - _iodir |= mask; - _gppu |= mask; - break; - - case PinType::Output: - _iodir &= ~mask; - break; - - default: - return -EINVAL; - } - - int ret = write_reg(Register::GPPU, _gppu); - - if (ret != 0) { - return ret; - } - - return write_reg(Register::IODIR, _iodir); -} diff --git a/src/drivers/gpio/mcp23009/mcp23009_main.cpp b/src/drivers/gpio/mcp23009/mcp23009_main.cpp deleted file mode 100644 index f5f9a2cfc4..0000000000 --- a/src/drivers/gpio/mcp23009/mcp23009_main.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** - * - * Copyright (C) 2023 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * Driver for the MCP23009 connected via I2C. - */ - -#include "mcp23009.h" -#include - -MCP23009::MCP23009(const I2CSPIDriverConfig &config) : - I2C(config), - I2CSPIDriver(config), - _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")) -{ -} - -MCP23009::~MCP23009() -{ - ScheduleClear(); - perf_free(_cycle_perf); -} - -int MCP23009::init_uorb() -{ - if (!_gpio_config_sub.registerCallback() || - !_gpio_request_sub.registerCallback() || - !_gpio_out_sub.registerCallback()) { - PX4_ERR("callback registration failed"); - return -1; - } - - return PX4_OK; -} - -void MCP23009::exit_and_cleanup() -{ - _gpio_config_sub.unregisterCallback(); - _gpio_request_sub.unregisterCallback(); - _gpio_out_sub.unregisterCallback(); -} - -void MCP23009::RunImpl() -{ - perf_begin(_cycle_perf); - - gpio_config_s config; - - if (_gpio_config_sub.update(&config) && config.device_id == get_device_id()) { - PinType type = PinType::Input; - - switch (config.config) { - case config.INPUT_PULLUP: type = PinType::InputPullUp; break; - - case config.OUTPUT: type = PinType::Output; break; - } - - write(config.state, config.mask); - configure(config.mask, type); - } - - gpio_out_s output; - - if (_gpio_out_sub.update(&output) && output.device_id == get_device_id()) { - write(output.state, output.mask); - } - - // read every time we run, either when requested or when scheduled on interval - { - gpio_in_s _gpio_in; - _gpio_in.timestamp = hrt_absolute_time(); - _gpio_in.device_id = get_device_id(); - uint8_t input; - read(&input); - _gpio_in.state = input; - _to_gpio_in.publish(_gpio_in); - } - - perf_end(_cycle_perf); -} - -void MCP23009::print_usage() -{ - PRINT_MODULE_USAGE_NAME("MCP23009", "driver"); - PRINT_MODULE_USAGE_COMMAND("start"); - PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); - PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x25); - PRINT_MODULE_USAGE_PARAM_INT('D', 0, 0, 255, "Direction", true); - PRINT_MODULE_USAGE_PARAM_INT('O', 0, 0, 255, "Output", true); - PRINT_MODULE_USAGE_PARAM_INT('P', 0, 0, 255, "Pullups", true); - PRINT_MODULE_USAGE_PARAM_INT('U', 0, 0, 1000, "Update Interval [ms]", true); - PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); -} - -void MCP23009::print_status() -{ - I2CSPIDriverBase::print_status(); - perf_print_counter(_cycle_perf); -} - -struct init_config_t { - uint16_t interval; - uint8_t direction; - uint8_t state; - uint8_t pullup; -}; - -I2CSPIDriverBase *MCP23009::instantiate(const I2CSPIDriverConfig &config, int runtime_instance) -{ - auto *init = (const init_config_t *)config.custom_data; - auto *instance = new MCP23009(config); - - if (!instance) { - PX4_ERR("alloc failed"); - return nullptr; - } - - if (OK != instance->init(init->direction, init->state, init->pullup)) { - delete instance; - return nullptr; - } - - if (init->interval) { - instance->ScheduleOnInterval(init->interval * 1000); - } - - return instance; -} - -extern "C" int mcp23009_main(int argc, char *argv[]) -{ - using ThisDriver = MCP23009; - BusCLIArguments cli{true, false}; - cli.default_i2c_frequency = 400000; - cli.i2c_address = 0x25; - init_config_t config_data{}; - - int ch; - - while ((ch = cli.getOpt(argc, argv, "D:O:P:U:")) != EOF) { - switch (ch) { - case 'D': - config_data.direction = (int)strtol(cli.optArg(), nullptr, 0); - break; - - case 'O': - config_data.state = (int)strtol(cli.optArg(), nullptr, 0); - break; - - case 'P': - config_data.pullup = (int)strtol(cli.optArg(), nullptr, 0); - break; - - case 'U': - config_data.interval = atoi(cli.optArg()); - break; - } - } - - cli.custom_data = &config_data; - - const char *verb = cli.optArg(); - - if (!verb) { - ThisDriver::print_usage(); - return -1; - } - - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_GPIO_DEVTYPE_MCP23009); - - if (!strcmp(verb, "start")) { - return ThisDriver::module_start(cli, iterator); - } - - if (!strcmp(verb, "stop")) { - return ThisDriver::module_stop(iterator); - } - - if (!strcmp(verb, "status")) { - return ThisDriver::module_status(iterator); - } - - ThisDriver::print_usage(); - return -1; -} diff --git a/src/drivers/gpio/mcp23017/CMakeLists.txt b/src/drivers/gpio/mcp23017/CMakeLists.txt new file mode 100644 index 0000000000..62107d59ad --- /dev/null +++ b/src/drivers/gpio/mcp23017/CMakeLists.txt @@ -0,0 +1,42 @@ +############################################################################ +# +# Copyright (c) 2023 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__gpio__mcp23017 + MAIN mcp23017 + SRCS + MCP23017_main.cpp + MCP23017.cpp + DEPENDS + mcp_common + ) diff --git a/src/drivers/gpio/mcp23017/Kconfig b/src/drivers/gpio/mcp23017/Kconfig new file mode 100644 index 0000000000..8d0e44b071 --- /dev/null +++ b/src/drivers/gpio/mcp23017/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_GPIO_MCP23017 + bool "MCP23017" + default n + ---help--- + Enable support for MCP23017 16-bit GPIO expander diff --git a/src/drivers/gpio/mcp23017/MCP23017.cpp b/src/drivers/gpio/mcp23017/MCP23017.cpp new file mode 100644 index 0000000000..98be95ed06 --- /dev/null +++ b/src/drivers/gpio/mcp23017/MCP23017.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "MCP23017.hpp" + +MCP23017::MCP23017(const I2CSPIDriverConfig &config) : + MCP230XX(config) +{ +} + +int MCP23017::get_olat(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::OLATA; + return PX4_OK; + + case 1: + *addr = (uint8_t) Register::OLATB; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23017::get_gppu(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::GPPUA; + return PX4_OK; + + case 1: + *addr = (uint8_t) Register::GPPUB; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23017::get_iodir(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::IODIRA; + return PX4_OK; + + case 1: + *addr = (uint8_t) Register::IODIRB; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23017::get_gpio(int bank, uint8_t *addr) +{ + switch (bank) { + case 0: + *addr = (uint8_t) Register::GPIOA; + return PX4_OK; + + case 1: + *addr = (uint8_t) Register::GPIOB; + return PX4_OK; + + default: + return PX4_ERROR; + } +} + +int MCP23017::get_probe_reg(uint8_t *addr) +{ + *addr = (uint8_t) Register::IOCONA; + return PX4_OK; +} diff --git a/src/drivers/gpio/mcp23017/MCP23017.hpp b/src/drivers/gpio/mcp23017/MCP23017.hpp new file mode 100644 index 0000000000..afa1f52872 --- /dev/null +++ b/src/drivers/gpio/mcp23017/MCP23017.hpp @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once +#include + +using namespace time_literals; + +class MCP23017 : public MCP230XX +{ +public: + MCP23017(const I2CSPIDriverConfig &config); + +private: + enum class + Register : uint8_t { + IODIRA = 0x00, + IODIRB = 0x01, + IPOLA = 0x02, + IPOLB = 0x03, + GPINTENA = 0x04, + GPINTENB = 0x05, + DEFVALA = 0x06, + DEFVALB = 0x07, + INTCONA = 0x08, + INTCONB = 0x09, + IOCONA = 0x0a, + IOCONB = 0x0b, + GPPUA = 0x0c, + GPPUB = 0x0d, + INTFA = 0x0e, + INTFB = 0x0f, + INTCAPA = 0x10, + INTCAPB = 0x11, + GPIOA = 0x12, + GPIOB = 0x13, + OLATA = 0x14, + OLATB = 0x15 + }; + + int get_olat(int bank, uint8_t *addr) override; + int get_gppu(int bank, uint8_t *addr) override; + int get_iodir(int bank, uint8_t *addr) override; + int get_gpio(int bank, uint8_t *addr) override; + int get_probe_reg(uint8_t *addr) override; +}; diff --git a/src/drivers/gpio/mcp23017/MCP23017_main.cpp b/src/drivers/gpio/mcp23017/MCP23017_main.cpp new file mode 100644 index 0000000000..5905786d6c --- /dev/null +++ b/src/drivers/gpio/mcp23017/MCP23017_main.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "MCP23017.hpp" + +constexpr MCP230XX_config_t def_mcp_config{ + .device_type = DRV_GPIO_DEVTYPE_MCP23017, + .i2c_addr = I2C_ADDRESS_MCP23017, + .num_pins = 16, + .num_banks = 2, +}; + +extern "C" int mcp23017_main(int argc, char *argv[]) +{ + using ThisDriver = MCP23017; + BusCLIArguments cli{true, false}; + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x27; + MCP230XX_config_t mcp_config = def_mcp_config; + + int ch; + + while ((ch = cli.getOpt(argc, argv, "D:O:P:U:R:M:")) != EOF) { + switch (ch) { + + case 'D': + mcp_config.direction = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'O': + mcp_config.state = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'P': + mcp_config.pullup = (int)strtol(cli.optArg(), nullptr, 0); + break; + + case 'U': + mcp_config.interval = (uint16_t)atoi(cli.optArg()); + break; + + case 'M': + mcp_config.first_minor = (uint8_t)atoi(cli.optArg()); + break; + } + } + + const char *verb = cli.optArg(); + + if (!verb) { + MCP230XX::print_usage(); + return -1; + } + + cli.custom_data = &mcp_config; + + BusInstanceIterator iterator("MCP23017", cli, mcp_config.device_type); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + MCP230XX::print_usage(); + return -1; +} diff --git a/src/drivers/gps/CMakeLists.txt b/src/drivers/gps/CMakeLists.txt index 4719e0e34e..3c3c0cc3e0 100644 --- a/src/drivers/gps/CMakeLists.txt +++ b/src/drivers/gps/CMakeLists.txt @@ -55,4 +55,5 @@ px4_add_module( module.yaml DEPENDS git_gps_devices + gnss ) diff --git a/src/drivers/gps/devices b/src/drivers/gps/devices index ce0afaeca2..5ed844c374 160000 --- a/src/drivers/gps/devices +++ b/src/drivers/gps/devices @@ -1 +1 @@ -Subproject commit ce0afaeca23a3b88efcf52d47c82277839980f9d +Subproject commit 5ed844c374646bfa2b41461c909a3b4df1a17233 diff --git a/src/drivers/gps/gps.cpp b/src/drivers/gps/gps.cpp index eae1732f0a..464eb892e9 100644 --- a/src/drivers/gps/gps.cpp +++ b/src/drivers/gps/gps.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ #include #include +#include + #ifndef CONSTRAINED_FLASH # include "devices/src/ashtech.h" # include "devices/src/emlid_reach.h" @@ -84,9 +87,11 @@ using namespace device; using namespace time_literals; -#define TIMEOUT_1HZ 1300 //!< Timeout time in mS, 1000 mS (1Hz) + 300 mS delta for error -#define TIMEOUT_5HZ 500 //!< Timeout time in mS, 200 mS (5Hz) + 300 mS delta for error -#define TIMEOUT_DUMP_ADD 450 //!< Additional time in mS to account for RTCM3 parsing and dumping +#define TIMEOUT_1HZ 1300 //!< Timeout time in mS, 1000 mS (1Hz) + 300 mS delta for error +#define TIMEOUT_5HZ 500 //!< Timeout time in mS, 200 mS (5Hz) + 300 mS delta for error +#define TIMEOUT_INIT_1HZ (3 * TIMEOUT_1HZ) //!< Timeout time in mS, used until GPS is healthy +#define TIMEOUT_INIT_5HZ (3 * TIMEOUT_5HZ) //!< Timeout time in mS, used until GPS is healthy +#define TIMEOUT_DUMP_ADD 450 //!< Additional time in mS to account for RTCM3 parsing and dumping enum class gps_driver_mode_t { None = 0, @@ -178,6 +183,7 @@ private: char _port[20] {}; ///< device / serial port path bool _healthy{false}; ///< flag to signal if the GPS is ok + bool _cfg_wiped{false}; ///< flag to signal if the config was already wiped bool _mode_auto; ///< if true, auto-detect which GPS is attached gps_driver_mode_t _mode; ///< current mode @@ -212,6 +218,11 @@ private: gps_dump_s *_dump_from_device{nullptr}; gps_dump_comm_mode_t _dump_communication_mode{gps_dump_comm_mode_t::Disabled}; + gnss::Rtcm3Parser _rtcm_parser{}; + + perf_counter_t _uart_tx_buffer_full_perf{perf_alloc(PC_COUNT, MODULE_NAME": tx buf full")}; + perf_counter_t _rtcm_buffer_full_perf{perf_alloc(PC_COUNT, MODULE_NAME": rtcm buf full")}; + static px4::atomic_bool _is_gps_main_advertised; ///< for the second gps we want to make sure that it gets instance 1 /// and thus we wait until the first one publishes at least one message. @@ -261,7 +272,7 @@ private: * @param data * @param len */ - inline bool injectData(uint8_t *data, size_t len); + inline bool injectData(const uint8_t *data, size_t len); /** * set the Baudrate @@ -282,7 +293,7 @@ private: * @param mode calling source * @param msg_to_gps_device if true, this is a message sent to the gps device, otherwise it's from the device */ - void dumpGpsData(uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device); + void dumpGpsData(const uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device); void initializeCommunicationDump(); @@ -307,9 +318,13 @@ GPS::GPS(const char *path, gps_driver_mode_t mode, GPSHelper::Interface interfac _instance(instance) { /* store port name */ - strncpy(_port, path, sizeof(_port) - 1); - /* enforce null termination */ - _port[sizeof(_port) - 1] = '\0'; + if (path != nullptr) { + strncpy(_port, path, sizeof(_port) - 1); + _port[sizeof(_port) - 1] = '\0'; + + } else { + _port[0] = '\0'; + } _sensor_gps.heading = NAN; _sensor_gps.heading_offset = NAN; @@ -380,6 +395,9 @@ GPS::~GPS() } while (_secondary_instance.load() && i < 100); } + perf_free(_uart_tx_buffer_full_perf); + perf_free(_rtcm_buffer_full_perf); + delete _sat_info; delete _dump_to_device; delete _dump_from_device; @@ -572,6 +590,7 @@ void GPS::handleInjectDataTopic() // Looking at 8 packets thus guarantees, that at least a full injection // data set is evaluated. // Moving Base reuires a higher rate, so we allow up to 8 packets. + // Drain uORB messages into RTCM parser and inject full messages after draining the queue. const size_t max_num_injections = gps_inject_data_s::ORB_QUEUE_LENGTH; size_t num_injections = 0; @@ -581,23 +600,54 @@ void GPS::handleInjectDataTopic() // Prevent injection of data from self if (msg.device_id != get_device_id()) { - /* Write the message to the gps device. Note that the message could be fragmented. - * But as we don't write anywhere else to the device during operation, we don't - * need to assemble the message first. - */ - injectData(msg.data, msg.len); + // Add data to the RTCM parser buffer for frame reassembly + size_t added = _rtcm_parser.addData(msg.data, msg.len); + + if (added < msg.len) { + perf_count(_rtcm_buffer_full_perf); + } - ++_rtcm_injection_rate_message_count; _last_rtcm_injection_time = hrt_absolute_time(); } } - updated = _orb_inject_data_sub[_selected_rtcm_instance].update(&msg); + auto &gps_inject_data_sub = _orb_inject_data_sub[_selected_rtcm_instance]; + + const unsigned last_generation = gps_inject_data_sub.get_last_generation(); + + updated = gps_inject_data_sub.update(&msg); + + if (updated) { + if (gps_inject_data_sub.get_last_generation() != last_generation + 1) { + PX4_WARN("gps_inject_data lost, generation %u -> %u", last_generation, gps_inject_data_sub.get_last_generation()); + } + } } while (updated && num_injections < max_num_injections); + + // Now inject all complete RTCM frames from the parser buffer + size_t frame_len = {}; + const uint8_t *frame_ptr = {}; + + while ((frame_ptr = _rtcm_parser.getNextMessage(&frame_len)) != nullptr) { + // Check TX buffer space before writing + if (_interface == GPSHelper::Interface::UART) { + ssize_t tx_available = _uart.txSpaceAvailable(); + + if ((ssize_t)frame_len > tx_available) { + // TX buffer full, stop and let it drain - frames stay in parser buffer + perf_count(_uart_tx_buffer_full_perf); + break; + } + } + + injectData(frame_ptr, frame_len); + _rtcm_parser.consumeMessage(frame_len); + _rtcm_injection_rate_message_count++; + } } -bool GPS::injectData(uint8_t *data, size_t len) +bool GPS::injectData(const uint8_t *data, size_t len) { dumpGpsData(data, len, gps_dump_comm_mode_t::Full, true); @@ -666,7 +716,7 @@ void GPS::initializeCommunicationDump() _dump_communication_mode = (gps_dump_comm_mode_t)param_dump_comm; } -void GPS::dumpGpsData(uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device) +void GPS::dumpGpsData(const uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device) { gps_dump_s *dump_data = msg_to_gps_device ? _dump_to_device : _dump_from_device; @@ -675,6 +725,7 @@ void GPS::dumpGpsData(uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool } dump_data->instance = (uint8_t)_instance; + dump_data->device_id = get_device_id(); while (len > 0) { size_t write_len = len; @@ -718,6 +769,34 @@ GPS::run() param_get(handle, &gps_ubx_dynmodel); } + int32_t gps_ubx_dgnss_to = 0; + handle = param_find("GPS_UBX_DGNSS_TO"); + + if (handle != PARAM_INVALID) { + param_get(handle, &gps_ubx_dgnss_to); + } + + int32_t gps_ubx_min_cno = 0; + handle = param_find("GPS_UBX_MIN_CNO"); + + if (handle != PARAM_INVALID) { + param_get(handle, &gps_ubx_min_cno); + } + + int32_t gps_ubx_min_elev = 0; + handle = param_find("GPS_UBX_MIN_ELEV"); + + if (handle != PARAM_INVALID) { + param_get(handle, &gps_ubx_min_elev); + } + + int32_t gps_ubx_rate = 0; + handle = param_find("GPS_UBX_RATE"); + + if (handle != PARAM_INVALID) { + param_get(handle, &gps_ubx_rate); + } + handle = param_find("GPS_UBX_MODE"); GPSDriverUBX::UBXMode ubx_mode{GPSDriverUBX::UBXMode::Normal}; @@ -776,6 +855,20 @@ GPS::run() param_get(handle, &f9p_uart2_baudrate); } + handle = param_find("GPS_UBX_PPK"); + int32_t ppk_output = 0; + + if (handle != PARAM_INVALID) { + param_get(handle, &ppk_output); + } + + handle = param_find("GPS_UBX_JAM_DET"); + int32_t jam_det_sensitivity_hi = 1; + + if (handle != PARAM_INVALID) { + param_get(handle, &jam_det_sensitivity_hi); + } + int32_t gnssSystemsParam = static_cast(GPSHelper::GNSSSystemsMask::RECEIVER_DEFAULTS); if (_instance == Instance::Main) { @@ -857,11 +950,26 @@ GPS::run() _mode = gps_driver_mode_t::UBX; /* FALLTHROUGH */ - case gps_driver_mode_t::UBX: - _helper = new GPSDriverUBX(_interface, &GPS::callback, this, &_sensor_gps, _p_report_sat_info, - gps_ubx_dynmodel, heading_offset, f9p_uart2_baudrate, ubx_mode); - set_device_type(DRV_GPS_DEVTYPE_UBX); - break; + case gps_driver_mode_t::UBX: { + GPSDriverUBX::Settings settings = { + .dynamic_model = (uint8_t)gps_ubx_dynmodel, + .dgnss_timeout = (uint8_t)gps_ubx_dgnss_to, + .min_cno = (uint8_t)gps_ubx_min_cno, + .min_elev = (int8_t)gps_ubx_min_elev, + .output_rate = (uint8_t)gps_ubx_rate, + .heading_offset = heading_offset, + .uart2_baudrate = f9p_uart2_baudrate, + .ppk_output = ppk_output > 0, + .jam_det_sensitivity_hi = jam_det_sensitivity_hi > 0, + .mode = ubx_mode, + }; + + _helper = new GPSDriverUBX(_interface, &GPS::callback, this, &_sensor_gps, _p_report_sat_info, settings); + + set_device_type(DRV_GPS_DEVTYPE_UBX); + break; + } + #ifndef CONSTRAINED_FLASH case gps_driver_mode_t::MTK: @@ -921,7 +1029,7 @@ GPS::run() param_get(handle, &gps_cfg_wipe); } - gpsConfig.cfg_wipe = static_cast(gps_cfg_wipe); + gpsConfig.cfg_wipe = static_cast(gps_cfg_wipe) && !_cfg_wiped; if (_helper && _helper->configure(_baudrate, gpsConfig) == 0) { @@ -961,6 +1069,14 @@ GPS::run() set_device_type(DRV_GPS_DEVTYPE_UBX_F9P); break; + case GPSDriverUBX::Board::u_blox10_L1L5: + set_device_type(DRV_GPS_DEVTYPE_UBX_10); + break; + + case GPSDriverUBX::Board::u_blox_X20: + set_device_type(DRV_GPS_DEVTYPE_UBX_20); + break; + default: set_device_type(DRV_GPS_DEVTYPE_UBX); break; @@ -969,21 +1085,30 @@ GPS::run() } int helper_ret; - unsigned receive_timeout = TIMEOUT_5HZ; + + /* After being configured (especially in combination with FLASH wipes) the GPS may require + * additional time before outputting the first navigation data. To account for this, there is + * an init timeout. As soon as the GPS is healthy, the timeout is decreased. This allows for + * a quick reaction to a connection loss. */ + unsigned receive_timeout = TIMEOUT_INIT_5HZ; + unsigned healthy_timeout = TIMEOUT_5HZ; if ((ubx_mode == GPSDriverUBX::UBXMode::RoverWithMovingBase) || (ubx_mode == GPSDriverUBX::UBXMode::RoverWithMovingBaseUART1)) { /* The MB rover will wait as long as possible to compute a navigation solution, * possibly lowering the navigation rate all the way to 1 Hz while doing so. */ - receive_timeout = TIMEOUT_1HZ; + receive_timeout = TIMEOUT_INIT_1HZ; + healthy_timeout = TIMEOUT_1HZ; } if (_dump_communication_mode != gps_dump_comm_mode_t::Disabled) { /* Dumping the RTCM3/UBX data requires additional parsing and storing of data via uORB. * Without additional time this can lead to timeouts. */ - receive_timeout += TIMEOUT_DUMP_ADD; + healthy_timeout += TIMEOUT_DUMP_ADD; } + PX4_INFO("GPS device configured @ %u baud", _baudrate); + while ((helper_ret = _helper->receive(receive_timeout)) > 0 && !should_exit()) { if (helper_ret & 1) { @@ -1041,6 +1166,12 @@ GPS::run() // // PX4_WARN("module found: %s", mode_str); _healthy = true; + receive_timeout = healthy_timeout; + } + + /* Do not wipe the FLASH config multiple times. */ + if (!_cfg_wiped) { + _cfg_wiped = true; } } @@ -1165,6 +1296,9 @@ GPS::print_status() print_message(ORB_ID(sensor_gps), _sensor_gps); } + perf_print_counter(_uart_tx_buffer_full_perf); + perf_print_counter(_rtcm_buffer_full_perf); + if (_instance == Instance::Main && _secondary_instance.load()) { GPS *secondary_instance = _secondary_instance.load(); secondary_instance->print_status(); diff --git a/src/drivers/gps/params.c b/src/drivers/gps/params.c index 92fb83323d..4eb8142128 100644 --- a/src/drivers/gps/params.c +++ b/src/drivers/gps/params.c @@ -69,6 +69,70 @@ PARAM_DEFINE_INT32(GPS_DUMP_COMM, 0); */ PARAM_DEFINE_INT32(GPS_UBX_DYNMODEL, 7); +/** + * u-blox GPS DGNSS timeout + * + * When set to 0 (default), default DGNSS timeout set by u-blox will be used. + * + * @min 0 + * @max 255 + * @unit s + * + * @reboot_required true + * + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_DGNSS_TO, 0); + +/** + * u-blox GPS minimum satellite signal level for navigation + * + * When set to 0 (default), default minimum satellite signal level set by u-blox wll be used. + * + * @min 0 + * @max 255 + * @unit dBHz + * + * @reboot_required true + * + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_MIN_CNO, 0); + +/** + * u-blox GPS minimum elevation for a GNSS satellite to be used in navigation + * + * When set to 0 (default), default minimum elevation set by u-blox will be used. + * + * @min 0 + * @max 127 + * @unit deg + * + * @reboot_required true + * + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_MIN_ELEV, 0); + +/** + * u-blox GPS output rate + * + * Configure the output rate of u-blox GPS receivers (protocol v27+). + * When set to 0, automatic rate selection is used based on the receiver model. + * Default rates: M9N=8Hz, F9P L1L2=5Hz, F9P L1L5=5Hz, Others=10Hz. + * + * Note: Higher rates reduce satellite count (e.g., >8Hz limits to 16 SVs on M9N). + * Max rates vary by model and RTK mode: F9P L1L2=5-7Hz, F9P L1L5=7-8Hz, X20=25Hz. + * High rates at 115200 baud may cause dropouts. + * + * @min 0 + * @max 25 + * @unit Hz + * @reboot_required true + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_RATE, 0); + /** * Enable sat info (if available) * @@ -144,6 +208,29 @@ PARAM_DEFINE_INT32(GPS_UBX_BAUD2, 230400); */ PARAM_DEFINE_INT32(GPS_UBX_CFG_INTF, 0); +/** + * Enable MSM7 message output for PPK workflow. + * + * @boolean + * @reboot_required true + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_PPK, 0); + +/** + * u-blox GPS jamming detection high sensitivity mode + * + * Enables or disables the high sensitivity mode for the u-blox jamming detection + * (CFG-SEC-JAMDET_SENSITIVITY_HI). When enabled, the receiver uses a + * more sensitive algorithm to detect jamming. Disabling this may reduce false + * positives in electrically noisy environments. + * + * @boolean + * @reboot_required true + * @group GPS + */ +PARAM_DEFINE_INT32(GPS_UBX_JAM_DET, 1); + /** * Wipes the flash config of UBX modules. * diff --git a/src/drivers/hygrometer/sht3x/sht3x.h b/src/drivers/hygrometer/sht3x/sht3x.h index 2750b8d9ff..a01a0a4335 100644 --- a/src/drivers/hygrometer/sht3x/sht3x.h +++ b/src/drivers/hygrometer/sht3x/sht3x.h @@ -110,7 +110,7 @@ private: float measured_temperature = 0; float measured_humidity = 0; - uint32_t measurement_time = 0; + uint64_t measurement_time = 0; uint16_t measurement_index = 0; sht_info _sht_info; diff --git a/src/drivers/ins/Kconfig b/src/drivers/ins/Kconfig index e5f5f6324a..8b99c3a215 100644 --- a/src/drivers/ins/Kconfig +++ b/src/drivers/ins/Kconfig @@ -5,6 +5,8 @@ menu "Inertial Navigation Systems (INS)" select DRIVERS_INS_VECTORNAV select DRIVERS_INS_ILABS select DRIVERS_INS_MICROSTRAIN + select DRIVERS_INS_EULERNAV_BAHRS + select DRIVERS_INS_SBGECOM ---help--- Enable default set of INS sensors rsource "*/Kconfig" diff --git a/src/drivers/ins/eulernav_bahrs/CMakeLists.txt b/src/drivers/ins/eulernav_bahrs/CMakeLists.txt new file mode 100644 index 0000000000..8d40252de1 --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__ins__eulerav_bahrs + MAIN eulernav_bahrs + INCLUDES + bahrs + SRCS + eulernav_bahrs_main.cpp + eulernav_driver.cpp + eulernav_driver.h + DEPENDS + ringbuffer + ) diff --git a/src/drivers/ins/eulernav_bahrs/Kconfig b/src/drivers/ins/eulernav_bahrs/Kconfig new file mode 100644 index 0000000000..80c32787dd --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_INS_EULERNAV_BAHRS + bool "eulernav_bahrs" + default n + ---help--- + Enable support for EULER-NAV Baro-Inertial AHRS diff --git a/src/drivers/ins/eulernav_bahrs/bahrs/CSerialProtocol.h b/src/drivers/ins/eulernav_bahrs/bahrs/CSerialProtocol.h new file mode 100644 index 0000000000..8814f2a5fc --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/bahrs/CSerialProtocol.h @@ -0,0 +1,371 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * The header is a modified version of a header from this repo: + * https://github.com/euler-nav/bahrs-oss + * + * Copyright 2023 AMS Advanced Air Mobility Sensors UG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +#define PROTOCOL_WORD_LEN (4) +#define PADDING_SIZE(SPayloadType) (PROTOCOL_WORD_LEN - ((sizeof(SMessageHeader) + sizeof(SPayloadType)) % PROTOCOL_WORD_LEN)) + +#define BIT_VALID_HEIGHT (0x01) +#define BIT_VALID_VELOCITY_DOWN (0x02) +#define BIT_VALID_ROLL (0x04) +#define BIT_VALID_PITCH (0x08) +#define BIT_VALID_MAGNETIC_HEADING (0x10) +#define BIT_VALID_SPECIFIC_FORCE_X (0x01) +#define BIT_VALID_SPECIFIC_FORCE_Y (0x02) +#define BIT_VALID_SPECIFIC_FORCE_Z (0x04) +#define BIT_VALID_ANGULAR_RATE_X (0x08) +#define BIT_VALID_ANGULAR_RATE_Y (0x10) +#define BIT_VALID_ANGULAR_RATE_Z (0x20) + +/** + * @brief The class that describes and implements the BAHRS serial protocol. +*/ +class CSerialProtocol +{ +public: + static constexpr uint8_t uMarker1_ { 0x4E }; ///< Sync byte 1, symbol 'N' + static constexpr uint8_t uMarker2_ { 0x45 }; ///< Sync char 2, symbol 'E' + static constexpr uint16_t uVersion_ { 2U }; ///< Protocol version + + static constexpr float skfSpecificForceScale_ { 1.495384e-3F }; ///< Integer to float, +-5g range + static constexpr float skfAngularRateScale_ { 1.597921e-4F }; ///< Integer to float, +-300 deg/s range + static constexpr float skfHeightScale_ { 0.16784924F }; ///< Integer to float, -1000 to 10000 m range + static constexpr float skfHeighOffset_ { 1000.0F }; ///< An offset to convert unsigned integer to float + static constexpr float skfVelocityDownScale_ { 9.155413e-3F }; ///< Integer to float, -300 to 300 m/s range + static constexpr float skfAngleScale_ { 9.587526e-5F }; ///< Integer to float, -pi to pi or 0 to 2 pi range + + // Signal ranges + static constexpr float skfMaxHeight_ { 10000.0F }; + static constexpr float skfMinHeight_ { -1000.0F }; + static constexpr float skfMaxVelocityDown_ { 300.0F }; + static constexpr float skfMinVelocityDown_ { -300.0F }; + + enum class EMessageIds : uint8_t { + eInvalid = 0x00, ///< Invalid + eInertialData = 0x01, ///< Inertial data message + eNavigationData = 0x02, ///< Navigation data message + eAccuracy = 0x03, ///< Attitude accuracy information + eTimeOfNavigationData = 0x04, ///< "Time of navigation data" message + eTimeOfInertialData = 0x05, ///< "Time of inertial data" message + eTimeOfSyncPulse = 0x06, ///< "Time of the latest sync pulse" message + eSoftwareVersion = 0x0F, ///< "Software version" message + + eDebugEventWriteToPort = 0xC0, ///< Debug information: SWC port data + eDebugEventRunnableCall = 0xC1, ///< Debug information: SWC API call + + eTypeOpenDiagnostic = 0xF0, ///< Request to enter diagnostics mode + eTypeCloseDiagnostic = 0xF1, ///< Request to exit diagnostics mode + eTypeReadNVMPage = 0xF2, ///< Request to read NVM page + eTypeNVMPageData = 0xF3, ///< A message with NVM page data + eTypeAccept = 0xFF ///< Acknowledgment of diagnostics message reception + }; + + typedef uint32_t CrcType_t; + +#pragma pack(push, 1) + + /** + * @brief Message header struct. + */ + struct SMessageHeader { + uint8_t uMarker1_ { 0x4E }; + uint8_t uMarker2_ { 0x45 }; + uint16_t uVersion_ { CSerialProtocol::uVersion_ }; + uint8_t uMsgType_ { 0U }; + }; + + /** + * @brief Inertial data message payload. + */ + struct SInertialData { + uint8_t uSequenceCounter_ { 0U }; + int16_t iSpecificForceX_ { 0 }; + int16_t iSpecificForceY_ { 0 }; + int16_t iSpecificForceZ_ { 0 }; + int16_t iAngularRateX_ { 0 }; + int16_t iAngularRateY_ { 0 }; + int16_t iAngularRateZ_ { 0 }; + uint8_t uValidity_ { 0U }; + }; + + /** + * @brief Payload of the time of inertial data message. + */ + struct STimeOfInertialData { + uint8_t uSequenceCounter_ { 0U }; + uint8_t uInertialDataSequenceCounter_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + }; + + /** + * @brief Navigation data message payload. + */ + struct SNavigationData { + uint8_t uSequenceCounter_ { 0U }; + uint16_t uPressureHeight_ { 0 }; + int16_t iVelocityDown_ { 0 }; + int16_t iRoll_ { 0 }; + int16_t iPitch_ { 0 }; + uint16_t uMagneticHeading_ { 0U }; + uint8_t uValidity_ { 0 }; + }; + + /** + * @brief Payload of the "time of navigation data" message. + */ + struct STimeOfNavigationData { + uint8_t uSequenceCounter_ { 0U }; + uint8_t uNavigationDataSequenceCounter_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + }; + + /** + * @brief Accuracy message payload. + */ + struct SAccuracyData { + uint8_t uSequenceCounter_ { 0U }; + uint16_t uAttitudeStdN_ { 0U }; + uint16_t uAttitudeStdE_ { 0U }; + uint16_t uMagneticHeadingStd_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + }; + + /** + * @brief Payload of the "time of the latest pulse" message. + */ + struct STimeOfLatestSyncPulse { + uint8_t uSequenceCounter_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + }; + + /** + * @brief Payload of the "software version" message. + */ + struct SSoftwareVersionData { + char acProjectCode_[3] { '\0', '\0', '\0' }; + uint16_t uMajor_ { 0U }; + uint16_t uMinor_ { 0U }; + }; + + /** + * @brief Partial data of the "write to port event". + * The struct does not include a variable size array of data written to a port. + */ + struct SWriteToPortEventPartialData { + uint8_t uPortId_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + uint16_t uDataLen_ { 0U }; + }; + + /** + * @brief Debug information on runnable call. + */ + struct SRunnableCallEventData { + uint8_t uRunnableId_ { 0U }; + uint64_t uTimestampUs_ { 0U }; + }; + + /** + * @brief Inertial data message. + */ + struct SInertialDataMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eInertialData) }; + + SInertialData oInertialData_; + uint8_t auPadding_[PADDING_SIZE(SInertialData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Time of inertial data message. + */ + struct STimeOfInertialDataMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eTimeOfInertialData) }; + + STimeOfInertialData oTimeOfInertialData_; + uint8_t auPadding_[PADDING_SIZE(STimeOfInertialData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Navigation data message. + */ + struct SNavigationDataMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eNavigationData) }; + + SNavigationData oNavigationData_; + uint8_t auPadding_[PADDING_SIZE(SNavigationData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Navigation data accuracy message. + */ + struct SAccuracyDataMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eAccuracy) }; + + SAccuracyData oAccuracy_; + uint8_t auPadding_[PADDING_SIZE(SAccuracyData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Time of navigation data message. + */ + struct STimeOfNavigationDataMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eTimeOfNavigationData) }; + + STimeOfNavigationData oTimeOfNavigationData_; + uint8_t auPadding_[PADDING_SIZE(STimeOfNavigationData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Time of the latest sync pulse message. + */ + struct STimeOfLatestSyncPulseMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eTimeOfSyncPulse) }; + + STimeOfLatestSyncPulse oTimeOfLatestSyncPulse_; + uint8_t auPadding_[PADDING_SIZE(STimeOfLatestSyncPulse)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief Software version message. + */ + struct SSoftwareVersionMessage { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eSoftwareVersion) }; + + SSoftwareVersionData oSoftwareVersion_; + uint8_t auPadding_[PADDING_SIZE(SSoftwareVersionData)]; + CrcType_t uCrc_ { 0U }; + }; + + /** + * @brief A debug message with runnable call data. + */ + struct SRunnableCallEventDebugMessage { + SMessageHeader oHeader_{ CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eDebugEventRunnableCall) }; + + SRunnableCallEventData oRunnableCallData_; + uint8_t auPadding_[PADDING_SIZE(oRunnableCallData_)]; + CrcType_t uCrc_{ 0U }; + }; + + /** + * @brief Diagnostic Mode Messages + ****************************************************************************/ + + /** + * @brief Diagnostic message: Page request from NVM. + */ + struct SPacketReadNVMPage { + SMessageHeader oHeader_; + uint8_t uPageNumber { 0U }; + CrcType_t uCrc32 { 0U }; + }; + + /** + * @brief Diagnostic message: confirmation of request processing by the device. + */ + struct SPacketReceiveConfirmation { + SMessageHeader oHeader_ { CSerialProtocol::uMarker1_, + CSerialProtocol::uMarker2_, + CSerialProtocol::uVersion_, + static_cast(EMessageIds::eTypeAccept) }; + EMessageIds eMessageType; // message type to confirm. + uint8_t uStatus { 0U }; // 0 - OK, other values - error codes + CrcType_t uCrc32 { 0U }; + }; + +#pragma pack(pop) + +}; diff --git a/src/drivers/ins/eulernav_bahrs/eulernav_bahrs_main.cpp b/src/drivers/ins/eulernav_bahrs/eulernav_bahrs_main.cpp new file mode 100644 index 0000000000..674db6dbf1 --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/eulernav_bahrs_main.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file eulernav_bahrs_main.cpp + * A driver module for EULER-NAV Baro-Inertial AHRS. + * + * @author Fedor Baklanov + */ + +#include +#include "eulernav_driver.h" + +extern "C" __EXPORT int eulernav_bahrs_main(int argc, char *argv[]) +{ + EulerNavDriver::main(argc, argv); + return OK; +} diff --git a/src/drivers/ins/eulernav_bahrs/eulernav_driver.cpp b/src/drivers/ins/eulernav_bahrs/eulernav_driver.cpp new file mode 100644 index 0000000000..1592308d76 --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/eulernav_driver.cpp @@ -0,0 +1,514 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "eulernav_driver.h" +#include +#include +#include +#include +#include + +EulerNavDriver::EulerNavDriver(const char *device_name) + : ModuleParams{nullptr} + , _serial_port{device_name, 115200, ByteSize::EightBits, Parity::None, StopBits::One, FlowControl::Disabled} + , _data_buffer{} + , _px4_accel{DRV_INS_DEVTYPE_BAHRS} + , _px4_gyro{DRV_INS_DEVTYPE_BAHRS} +{ +} + +EulerNavDriver::~EulerNavDriver() +{ + deinitialize(); +} + +int EulerNavDriver::task_spawn(int argc, char *argv[]) +{ + int task_id = px4_task_spawn_cmd("bahrs", SCHED_DEFAULT, SCHED_PRIORITY_FAST_DRIVER, + Config::TASK_STACK_SIZE, (px4_main_t)&run_trampoline, argv); + + if (task_id < 0) { + _task_id = -1; + PX4_ERR("Failed to spawn task."); + + } else { + _task_id = task_id; + } + + return (_task_id < 0) ? 1 : 0; +} + +EulerNavDriver *EulerNavDriver::instantiate(int argc, char *argv[]) +{ + int option_index = 1; + const char *option_arg{nullptr}; + const char *device_name{nullptr}; + + while (true) { + int option{px4_getopt(argc, argv, "d:", &option_index, &option_arg)}; + + if (EOF == option) { + break; + } + + switch (option) { + case 'd': + device_name = option_arg; + break; + + default: + break; + } + } + + auto *instance = new EulerNavDriver(device_name); + + if (nullptr != instance) { + instance->initialize(); + + } else { + PX4_ERR("Failed to initialize EULER-NAV driver."); + } + + return instance; +} + +int EulerNavDriver::custom_command(int argc, char *argv[]) +{ + return print_usage("unrecognized command"); +} + +int EulerNavDriver::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description + +Serial bus driver for the EULER-NAV Baro-Inertial AHRS. + +### Examples + +Attempt to start driver on a specified serial device. +$ eulernav_bahrs start -d /dev/ttyS1 +Stop driver +$ eulernav_bahrs stop +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("eulernav_bahrs", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("ins"); + PRINT_MODULE_USAGE_COMMAND_DESCR("start", "Start driver"); + PRINT_MODULE_USAGE_PARAM_STRING('d', nullptr, nullptr, "Serial device", false); + PRINT_MODULE_USAGE_COMMAND_DESCR("status", "Print driver status"); + PRINT_MODULE_USAGE_COMMAND_DESCR("stop", "Stop driver"); + + return PX4_OK; +} + +int EulerNavDriver::print_status() +{ + if (_is_initialized) + { + PX4_INFO("Elapsed time: %llu [us].\n", hrt_elapsed_time(&_statistics.start_time)); + PX4_INFO("Total bytes received: %lu.\n", _statistics.total_bytes_received); + PX4_INFO("Inertial messages received: %lu. Navigation messages received: %lu.\n", + _statistics.inertial_message_counter, _statistics.navigation_message_counter); + PX4_INFO("Failed CRC count: %lu.\n", _statistics.crc_failures); + + } + else + { + PX4_INFO("Initialization failed. The driver is not running.\n"); + } + + return PX4_OK; +} + +void EulerNavDriver::run() +{ + _statistics.start_time = hrt_absolute_time(); + + while(!should_exit()) + { + if (_is_initialized) + { + const auto bytes_read{_serial_port.readAtLeast(_serial_read_buffer, sizeof(_serial_read_buffer), + Config::MIN_BYTES_TO_READ, Config::SERIAL_READ_TIMEOUT_MS)}; + + _statistics.total_bytes_received += bytes_read; + + if (bytes_read > 0) + { + if (!_data_buffer.push_back(_serial_read_buffer, bytes_read)) + { + PX4_ERR("No space in data buffer"); + } + } + + processDataBuffer(); + } + else + { + // The driver failed to initialize in the instantiate() method, so we exit the loop. + request_stop(); + } + } +} + +void EulerNavDriver::initialize() +{ + if (!_is_initialized) + { + if (_serial_port.open()) + { + PX4_INFO("Serial port opened successfully."); + _is_initialized = true; + } + else + { + PX4_ERR("Failed to open serial port"); + } + + if (_is_initialized) + { + if (!_data_buffer.allocate(Config::DATA_BUFFER_SIZE)) + { + PX4_ERR("Failed to allocate data buffer"); + _is_initialized = false; + } + } + + if (_is_initialized) + { + _attitude_pub.advertise(); + _barometer_pub.advertise(); + } + } +} + +void EulerNavDriver::deinitialize() +{ + if (_serial_port.isOpen()) + { + _serial_port.close(); + } + + _data_buffer.deallocate(); + _attitude_pub.unadvertise(); + _barometer_pub.unadvertise(); + _is_initialized = false; +} + +void EulerNavDriver::processDataBuffer() +{ + static_assert(Config::MIN_MESSAGE_LENGTH >= (sizeof(CSerialProtocol::SMessageHeader) + sizeof(CSerialProtocol::CrcType_t))); + using EMessageIds = CSerialProtocol::EMessageIds; + + while (_data_buffer.space_used() >= Config::MIN_MESSAGE_LENGTH) + { + if (!_next_message_info.is_detected) + { + _next_message_info.is_detected = findNextMessageHeader(_data_buffer); + + if (!_next_message_info.is_detected) + { + // No message header found, wait for more bytes to arrive. + break; + } + + if (!retrieveProtocolVersionAndMessageType(_data_buffer, _next_message_info.protocol_version, _next_message_info.message_code)) + { + _next_message_info.is_detected = false; + } + } + + if (_next_message_info.is_detected) + { + static_assert(sizeof(CSerialProtocol::SMessageHeader) < Config::MIN_MESSAGE_LENGTH); + + const EMessageIds message_id{static_cast(_next_message_info.message_code)}; + const int32_t message_length{getMessageLength(message_id)}; + + if ((message_length < 0) || (message_length < Config::MIN_MESSAGE_LENGTH) || + (message_length > static_cast(sizeof(_message_storage))) || ((message_length % sizeof(uint32_t)) != 0U)) + { + // The message is unknown, not supported, or does not fit into the temporary storage. + _next_message_info.is_detected = false; + continue; + } + + const int32_t bytes_to_retrieve{message_length - static_cast(sizeof(CSerialProtocol::SMessageHeader))}; + + if (static_cast(_data_buffer.space_used()) < bytes_to_retrieve) + { + // Do nothing and wait for more bytes to arrive. + break; + } + + // Get message from the data buffer + uint8_t* bytes{reinterpret_cast(_message_storage)}; + + bytes[0] = CSerialProtocol::uMarker1_; + bytes[1] = CSerialProtocol::uMarker2_; + bytes[2] = reinterpret_cast(&_next_message_info.protocol_version)[0]; + bytes[3] = reinterpret_cast(&_next_message_info.protocol_version)[1]; + bytes[4] = _next_message_info.message_code; + + if (static_cast(bytes_to_retrieve) == _data_buffer.pop_front(bytes + sizeof(CSerialProtocol::SMessageHeader), bytes_to_retrieve)) + { + const uint32_t message_length_in_words{message_length / sizeof(uint32_t)}; + const uint32_t actual_crc{crc32(_message_storage, message_length_in_words - 1)}; + const uint32_t expected_crc = _message_storage[message_length_in_words - 1]; + + if (expected_crc != actual_crc) + { + ++_statistics.crc_failures; + } + else + { + decodeMessageAndPublishData(bytes, message_id); + } + } + + _next_message_info.is_detected = false; + } + } +} + +bool EulerNavDriver::findNextMessageHeader(Ringbuffer& buffer) +{ + bool result{false}; + + while (buffer.space_used() >= sizeof(CSerialProtocol::SMessageHeader)) + { + uint8_t sync_byte{0U}; + + if ((1 == buffer.pop_front(&sync_byte, 1)) && (CSerialProtocol::uMarker1_ == sync_byte)) + { + sync_byte = 0U; + + if ((1 == buffer.pop_front(&sync_byte, 1)) && (CSerialProtocol::uMarker2_ == sync_byte)) + { + result = true; + break; + } + } + } + + return result; +} + +bool EulerNavDriver::retrieveProtocolVersionAndMessageType(Ringbuffer& buffer, uint16_t& protocol_ver, uint8_t& message_code) +{ + bool status{true}; + auto bytes_to_pop{sizeof(protocol_ver)}; + + // Note: BAHRS uses little endian + if (bytes_to_pop != buffer.pop_front(reinterpret_cast(&protocol_ver), bytes_to_pop)) + { + status = false; + } + + if (status) + { + bytes_to_pop = 1; + + if (bytes_to_pop != buffer.pop_front(&message_code, bytes_to_pop)) + { + status = false; + } + } + + return status; +} + +void EulerNavDriver::decodeMessageAndPublishData(const uint8_t* data, CSerialProtocol::EMessageIds messsage_id) +{ + switch (messsage_id) + { + case CSerialProtocol::EMessageIds::eInertialData: + handleInertialDataMessage(data); + break; + case CSerialProtocol::EMessageIds::eNavigationData: + handleNavigationDataMessage(data); + break; + default: + break; + } +} + +void EulerNavDriver::handleInertialDataMessage(const uint8_t* data) +{ + const CSerialProtocol::SInertialDataMessage* imu_msg{reinterpret_cast(data)}; + + if (nullptr != imu_msg) + { + const auto& imu_data{imu_msg->oInertialData_}; + const bool accel_valid{((imu_data.uValidity_ & BIT_VALID_SPECIFIC_FORCE_X) > 0) && + ((imu_data.uValidity_ & BIT_VALID_SPECIFIC_FORCE_Y) > 0) && + ((imu_data.uValidity_ & BIT_VALID_SPECIFIC_FORCE_Z) > 0)}; + + const bool gyro_valid{((imu_data.uValidity_ & BIT_VALID_ANGULAR_RATE_X) > 0) && + ((imu_data.uValidity_ & BIT_VALID_ANGULAR_RATE_Y) > 0) && + ((imu_data.uValidity_ & BIT_VALID_ANGULAR_RATE_Z) > 0)}; + + const auto time = hrt_absolute_time(); + + if (accel_valid) + { + const float accel_x{CSerialProtocol::skfSpecificForceScale_ * static_cast(imu_data.iSpecificForceX_)}; + const float accel_y{CSerialProtocol::skfSpecificForceScale_ * static_cast(imu_data.iSpecificForceY_)}; + const float accel_z{CSerialProtocol::skfSpecificForceScale_ * static_cast(imu_data.iSpecificForceZ_)}; + + _px4_accel.update(time, accel_x, accel_y, accel_z); + } + + if (gyro_valid) + { + const float gyro_x{CSerialProtocol::skfAngularRateScale_ * static_cast(imu_data.iAngularRateX_)}; + const float gyro_y{CSerialProtocol::skfAngularRateScale_ * static_cast(imu_data.iAngularRateY_)}; + const float gyro_z{CSerialProtocol::skfAngularRateScale_ * static_cast(imu_data.iAngularRateZ_)}; + + _px4_gyro.update(time, gyro_x, gyro_y, gyro_z); + } + + ++_statistics.inertial_message_counter; + } +} + +void EulerNavDriver::handleNavigationDataMessage(const uint8_t* data) +{ + const CSerialProtocol::SNavigationDataMessage* nav_msg{reinterpret_cast(data)}; + + if (nullptr != nav_msg) + { + const auto& nav_data{nav_msg->oNavigationData_}; + const bool roll_valid{(nav_data.uValidity_ & BIT_VALID_ROLL) > 0}; + const bool pitch_valid{(nav_data.uValidity_ & BIT_VALID_PITCH) > 0}; + const bool yaw_valid{(nav_data.uValidity_ & BIT_VALID_MAGNETIC_HEADING) > 0}; + const auto time{hrt_absolute_time()}; + + if (roll_valid && pitch_valid && yaw_valid) + { + const float roll{CSerialProtocol::skfAngleScale_ * static_cast(nav_data.iRoll_)}; + const float pitch{CSerialProtocol::skfAngleScale_ * static_cast(nav_data.iPitch_)}; + const float yaw{CSerialProtocol::skfAngleScale_ * static_cast(nav_data.uMagneticHeading_)}; + + const matrix::Quaternionf quat{matrix::Eulerf{roll, pitch, yaw}}; + px4::msg::VehicleAttitude attitude{}; + + attitude.q[0] = quat(0); + attitude.q[1] = quat(1); + attitude.q[2] = quat(2); + attitude.q[3] = quat(3); + + attitude.timestamp = time; + attitude.timestamp_sample = time; + + _attitude_pub.publish(attitude); + } + + const bool height_valid{(nav_data.uValidity_ & BIT_VALID_HEIGHT) > 0}; + + if (height_valid) + { + const float height{(CSerialProtocol::skfHeightScale_ * static_cast(nav_data.uPressureHeight_)) - CSerialProtocol::skfHeighOffset_}; + px4::msg::SensorBaro pressure{}; + + pressure.pressure = atmosphere::getPressureFromAltitude(height); + + // EULER-NAV Baro-Inertial AHRS provides height estimate from a Kalman filter. It has got low noise and resolution + // of about 17 cm. It causes PX4 autopilot to mistakenly report that pressure signal is stale. In order to prevent + // the false alarms we add a small noise to the received height data. + if (_statistics.navigation_message_counter % 2U == 0) + { + pressure.pressure += 0.01F; + } + + pressure.timestamp = time; + pressure.timestamp_sample = time; + pressure.device_id = DRV_INS_DEVTYPE_BAHRS; + pressure.temperature = NAN; + + _barometer_pub.publish(pressure); + } + + ++_statistics.navigation_message_counter; + } +} + +int32_t EulerNavDriver::getMessageLength(CSerialProtocol::EMessageIds messsage_id) +{ + int message_length{-1}; + + switch (messsage_id) + { + case CSerialProtocol::EMessageIds::eInertialData: + message_length = sizeof(CSerialProtocol::SInertialDataMessage); + break; + case CSerialProtocol::EMessageIds::eNavigationData: + message_length = sizeof(CSerialProtocol::SNavigationDataMessage); + break; + default: + break; + } + + return message_length; +} + +uint32_t EulerNavDriver::crc32(const uint32_t* buffer, size_t length) +{ + uint32_t crc = 0xFFFFFFFF; + + for (size_t i = 0; i < length; ++i) + { + crc = crc ^ buffer[i]; + + for (uint8_t j = 0; j < 32; j++) + { + if (crc & 0x80000000) + { + crc = (crc << 1) ^ 0x04C11DB7; + } + else + { + crc = (crc << 1); + } + } + } + + return crc; +} diff --git a/src/drivers/ins/eulernav_bahrs/eulernav_driver.h b/src/drivers/ins/eulernav_bahrs/eulernav_driver.h new file mode 100644 index 0000000000..851b8d63b1 --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/eulernav_driver.h @@ -0,0 +1,174 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CSerialProtocol.h" + +class EulerNavDriver : public ModuleBase, public ModuleParams +{ +public: + /// @brief Class constructor + /// @param device_name Serial port to open + EulerNavDriver(const char *device_name); + + ~EulerNavDriver(); + + /// @brief Required by ModuleBase + static int task_spawn(int argc, char *argv[]); + + /// @brief Required by ModuleBase + static EulerNavDriver *instantiate(int argc, char *argv[]); + + /// @brief Required by ModuleBase + static int custom_command(int argc, char *argv[]); + + /// @brief Required by ModuleBase + static int print_usage(const char *reason = nullptr); + + /// @brief Overload of the method from the ModuleBase + int print_status() final; + + /// @brief The main loop of the task. + void run() final; + +private: + /// @brief Driver performance indicators + class Statistics + { + public: + uint32_t total_bytes_received{0U}; ///< Total number of received bytes + uint32_t inertial_message_counter{0U}; ///< Total number of received inertial data messages + uint32_t navigation_message_counter{0U}; ///< Total number of received navigation messages + uint32_t crc_failures{0U}; ///< CRC failure counter + hrt_abstime start_time{0U}; ///< Driver start time, [us] + }; + + /// @brief Configuration constants + class Config + { + public: + static constexpr uint32_t TASK_STACK_SIZE{2048}; ///< Driver task stack size + static constexpr uint32_t SERIAL_READ_BUFFER_SIZE{128}; ///< Buffer size for serial port read operations + static constexpr uint32_t MIN_BYTES_TO_READ{16}; ///< Minimum number of bytes to wait for when reading from a serial port + static constexpr uint32_t SERIAL_READ_TIMEOUT_MS{5}; ///< A timeout for serial port read operation + static constexpr uint32_t DATA_BUFFER_SIZE{512}; ///< Size of a ring buffer for storing RX data stream + static constexpr int32_t MIN_MESSAGE_LENGTH{12}; ///< Min length of a valid message. 5 bytes header + 4 bytes CRC + padding to 12 (multiple of 32 bit words) + }; + + /// @brief An object for grouping message-related attributes + class NextMessageInfo + { + public: + bool is_detected{false}; ///< A flag to indicate that the next message header was detected + uint16_t protocol_version{0U}; ///< Protocol version retrieved from the next message header + uint8_t message_code{0U}; ///< Message code retrieved from the next message header + }; + + /// @brief Perform initialization + /// If the driver is not initialized, the function does the following: + /// 1. Opens serial port + /// 2. Allocates a ring buffer for RX data stream + /// 3. Cleans up if any of the previous operations fails + /// 4. Sets the "is initialized" flag to true on success + void initialize(); + + /// @brief De-initialize + /// The function does the following: + /// 1. Close the serial port, if it is opened + /// 2. Deallocates the ring buffer + /// 3. Resets the "is initialized" flag to false + void deinitialize(); + + /// @brief Process data in the ring buffer. + /// Extracts and parses protocol messages. + void processDataBuffer(); + + /// @brief Searches the ring buffer for sync bytes. + /// @param buffer Ring buffer to search + /// @return True if sync bytes found, false if the number of bytes remaining in the buffer is less then message header length. + static bool findNextMessageHeader(Ringbuffer &buffer); + + /// @brief Get protocol version and message code from the ring buffer. + /// @param buffer The buffer to process + /// @param protocol_ver Output protocol version + /// @param message_code Output message code + /// @return True on success, false on failure + static bool retrieveProtocolVersionAndMessageType(Ringbuffer &buffer, uint16_t &protocol_ver, uint8_t &message_code); + + /// @brief Decode a message from BAHRS and publish its content. + /// @param data An array of message bytes + /// @param messsage_id Message ID + void decodeMessageAndPublishData(const uint8_t *data, CSerialProtocol::EMessageIds messsage_id); + + /// @brief Decode and publish IMU data. + /// @param data Inertial message data bytes + void handleInertialDataMessage(const uint8_t *data); + + /// @brief Decode and publish vehicle attitude and pressure height. + /// @param data Navigation message data bytes + void handleNavigationDataMessage(const uint8_t *data); + + /// @brief Get message length by message ID + /// @param messsage_id Query message ID + /// @return Message length, or -1 if the message ID is unknown or not supported. + static int32_t getMessageLength(CSerialProtocol::EMessageIds messsage_id); + + /// @brief Perform CRC + /// @param buf Data buffer pointer + /// @param len Number of words to include in the CRC. + /// @return CRC value + static uint32_t crc32(const uint32_t *buf, size_t len); + + device::Serial _serial_port; ///< Serial port object to read data from + Ringbuffer _data_buffer; ///< A buffer for RX data stream + uint8_t _serial_read_buffer[Config::SERIAL_READ_BUFFER_SIZE]; ///< A buffer for serial port read operation + uint32_t _message_storage[8]; ///< A temporary storage for BAHRS messages being extracted + NextMessageInfo _next_message_info{}; ///< Attributes of the next message detected in the data buffer + Statistics _statistics{}; ///< Driver performance indicators + bool _is_initialized{false}; ///< Initialization flag + PX4Accelerometer _px4_accel; ///< Accelerometer sensor object for publishing acceleration data + PX4Gyroscope _px4_gyro; ///< Gyroscope sensor object for publishing angular rate data + uORB::PublicationMulti _attitude_pub{ORB_ID(vehicle_attitude)}; ///< Vehicle attitude publisher + uORB::PublicationMulti _barometer_pub{ORB_ID(sensor_baro)}; ///< Pressure data publisher +}; diff --git a/src/drivers/ins/eulernav_bahrs/module.yaml b/src/drivers/ins/eulernav_bahrs/module.yaml new file mode 100644 index 0000000000..38ff4a5f1b --- /dev/null +++ b/src/drivers/ins/eulernav_bahrs/module.yaml @@ -0,0 +1,7 @@ +module_name: EULER-NAV BAHRS + +serial_config: + - command: eulernav_bahrs start -d ${SERIAL_DEV} + port_config_param: + name: SENS_BAHRS_CFG + group: Sensors diff --git a/src/drivers/ins/ilabs/ILabs.cpp b/src/drivers/ins/ilabs/ILabs.cpp index 98f169357d..1c81a818ab 100644 --- a/src/drivers/ins/ilabs/ILabs.cpp +++ b/src/drivers/ins/ilabs/ILabs.cpp @@ -236,34 +236,42 @@ void ILabs::Run() { if (!result) { PX4_ERR("Sensor initializing error"); - ScheduleDelayed(1_s); + _sensor.deinit(); + _time_initialized.store(0); + _time_last_valid_imu_data.store(0); + ScheduleDelayed(3_s); return; } _time_initialized.store(hrt_absolute_time()); } - // check for timeout const hrt_abstime time_initialized = _time_initialized.load(); const hrt_abstime time_last_valid_imu_data = _time_last_valid_imu_data.load(); - if (_param_ilabs_mode.get() == ILabsMode::FULL_INS && time_last_valid_imu_data != 0 && - hrt_elapsed_time(&time_last_valid_imu_data) < 3_s) { - // update sensor_selection if configured in INS mode + // Update sensor_selection for FULL_INS mode + if (_param_ilabs_mode.get() == ILabsMode::FULL_INS && time_initialized != 0 && time_last_valid_imu_data != 0 && + hrt_elapsed_time(&time_last_valid_imu_data) < 3_s) { + if ((_px4_accel.get_device_id() != 0) && (_px4_gyro.get_device_id() != 0)) { sensor_selection_s sensor_selection{}; sensor_selection.accel_device_id = _px4_accel.get_device_id(); sensor_selection.gyro_device_id = _px4_gyro.get_device_id(); - sensor_selection.timestamp = _time_initialized.load(); + sensor_selection.timestamp = time_initialized; _sensor_selection_pub.publish(sensor_selection); } else { PX4_ERR("Sensor not initialized"); } } - if (time_initialized != 0 && hrt_elapsed_time(&time_last_valid_imu_data) > 5_s && - time_last_valid_imu_data != 0 && hrt_elapsed_time(&time_last_valid_imu_data) > 1_s) { - PX4_ERR("Timeout, reinitializing"); + // Missing data handling + if (time_initialized != 0 && time_last_valid_imu_data != 0 && + hrt_elapsed_time(&time_last_valid_imu_data) > 3_s) { + PX4_ERR("Timeout: no new data from sensor. Reinitializing"); _sensor.deinit(); + _time_initialized.store(0); + _time_last_valid_imu_data.store(0); + ScheduleDelayed(3_s); + return; } ScheduleDelayed(100_ms); diff --git a/src/drivers/ins/ilabs/ILabs.h b/src/drivers/ins/ilabs/ILabs.h index 82b94541db..3754dce982 100644 --- a/src/drivers/ins/ilabs/ILabs.h +++ b/src/drivers/ins/ilabs/ILabs.h @@ -80,6 +80,10 @@ private: void Run() override; void processData(InertialLabs::SensorsData *sensordata); static void processDataProxy(void *context, InertialLabs::SensorsData *data) { + if (!context || !data) { + return; + } + ILabs *self = static_cast(context); self->processData(data); } diff --git a/src/drivers/ins/ilabs/libilabs/include/sensor.h b/src/drivers/ins/ilabs/libilabs/include/sensor.h index f8c29bef0a..504cabbc53 100644 --- a/src/drivers/ins/ilabs/libilabs/include/sensor.h +++ b/src/drivers/ins/ilabs/libilabs/include/sensor.h @@ -35,6 +35,7 @@ #include +#include #include #include "data.h" @@ -61,12 +62,15 @@ public: private: static void *updateDataThreadHelper(void *context) { + if (!context) { + return nullptr; + } Sensor *sensor = reinterpret_cast(context); sensor->updateData(); return nullptr; } - void resetSerial(); + bool initSerialPort(const char *serialDeviceName); bool moveToBufferStart(const uint8_t *pos); bool skipPackageInBufferStart(); bool movePackageHeaderToBufferStart(); @@ -74,15 +78,16 @@ private: bool parseUDDPayload(); - device::Serial *_serial{nullptr}; - pthread_t _threadId; - bool _processInThread{false}; + device::Serial *_serial{nullptr}; + pthread_t _threadId{0}; + px4::atomic_bool _processInThread{false}; // callback. C-style class method pointer void *_context{nullptr}; DataHandler _dataHandler{nullptr}; - bool _isInitialized{false}; + px4::atomic_bool _isInitialized{false}; + px4::atomic_bool _isDeinitInProcess{false}; uint8_t _buf[BUFFER_SIZE]{}; uint16_t _bufOffset{0}; diff --git a/src/drivers/ins/ilabs/libilabs/src/sensor.cpp b/src/drivers/ins/ilabs/libilabs/src/sensor.cpp index fa79551188..ba6427536c 100644 --- a/src/drivers/ins/ilabs/libilabs/src/sensor.cpp +++ b/src/drivers/ins/ilabs/libilabs/src/sensor.cpp @@ -86,72 +86,72 @@ Sensor::~Sensor() { } bool Sensor::init(const char *serialDeviceName, void *context, DataHandler dataHandler) { - if (_isInitialized) { - PX4_ERR("Serial device already initialized. Deinitialize first."); + if (_isInitialized.load()) { + PX4_WARN("Serial device already initialized. Deinitialize first"); + return false; + } + if (_isDeinitInProcess.load()) { + PX4_WARN("Deinitialization is in progress. Please wait until it completes before re-initializing"); return false; } - if (serialDeviceName[0] == '\0') { PX4_ERR("Empty serial device name"); return false; } - if (!context || !dataHandler) { PX4_ERR("Empty data handler callback"); return false; } - _serial = new device::Serial(serialDeviceName, BAUDRATE); - if (_serial == nullptr) { - PX4_ERR("Error creating serial device: %s", serialDeviceName); - px4_sleep(1); // NOLINT(concurrency-mt-unsafe) + if (!initSerialPort(serialDeviceName)) { return false; } - if (!_serial->isOpen() && !_serial->open()) { - // Open the UART. If this is successful then the UART is ready to use. - if (!_serial->open()) { - PX4_ERR("Error opening serial device: %s", serialDeviceName); - px4_sleep(1); // NOLINT(concurrency-mt-unsafe) - resetSerial(); - return false; - } - - PX4_INFO("Serial device opened sucessfully: %s", serialDeviceName); - - _serial->flush(); - } _context = context; _dataHandler = dataHandler; - _processInThread = true; + _processInThread.store(true); const int result = pthread_create(&_threadId, nullptr, &Sensor::updateDataThreadHelper, this); if (result) { PX4_ERR("Cant create working thread"); - _processInThread = false; - px4_sleep(1); // NOLINT(concurrency-mt-unsafe) - resetSerial(); + deinit(); return false; } - pthread_detach(_threadId); - _isInitialized = true; + _isInitialized.store(true); return true; } void Sensor::deinit() { - _processInThread = false; - _isInitialized = false; - resetSerial(); + if (_isDeinitInProcess.load()) { + PX4_WARN("Deinitialization already in process"); + return; + } + + _isDeinitInProcess.store(true); + _isInitialized.store(false); + _processInThread.store(false); + // Wait to be shure, that operations with UART are finished + px4_sleep(1); // NOLINT(concurrency-mt-unsafe) + if (_serial) { + (void)_serial->close(); + delete _serial; + _serial = nullptr; + } + + _context = nullptr; + _dataHandler = nullptr; + _bufOffset = 0; + _isDeinitInProcess.store(false); } bool Sensor::isInitialized() const { - return _isInitialized; + return _isInitialized.load(); } void Sensor::updateData() { - while (_processInThread) { + while (_processInThread.load()) { bool result = moveValidPackageToBufferStart(); if (!result) { continue; @@ -162,18 +162,40 @@ void Sensor::updateData() { continue; } - _dataHandler(_context, &_sensorData); + if (_dataHandler) { + _dataHandler(_context, &_sensorData); + } skipPackageInBufferStart(); } } -void Sensor::resetSerial() { +bool Sensor::initSerialPort(const char *serialDeviceName) { if (_serial) { - (void)_serial->close(); - delete _serial; - _serial = nullptr; + PX4_WARN("Serial port already initialized. Deinitialize first"); + return false; } + + _serial = new device::Serial(serialDeviceName, BAUDRATE); + if (_serial == nullptr) { + PX4_ERR("Error creating serial device: %s", serialDeviceName); + px4_sleep(1); // NOLINT(concurrency-mt-unsafe) + return false; + } + + if (!_serial->isOpen()) { + _serial->open(); + if (!_serial->isOpen()) { + PX4_ERR("Error opening serial device: %s", serialDeviceName); + deinit(); + return false; + } + PX4_INFO("Serial device opened sucessfully: %s", serialDeviceName); + } else { + PX4_INFO("Serial device already opened: %s", serialDeviceName); + } + _serial->flush(); + return true; } bool Sensor::moveToBufferStart(const uint8_t *pos) { @@ -201,7 +223,7 @@ bool Sensor::moveToBufferStart(const uint8_t *pos) { bool Sensor::skipPackageInBufferStart() { const MessageHeader *packageHeader = reinterpret_cast(_buf); if (!isMessageHeaderCorrect(packageHeader)) { - PX4_ERR("Incorrect message header in buffer start. Can't skip the package correctly."); + PX4_ERR("Incorrect message header in buffer start. Can't skip the package correctly"); return false; } @@ -239,7 +261,7 @@ bool Sensor::moveValidPackageToBufferStart() { return false; } - const ssize_t nRead = _serial->readAtLeast(&_buf[_bufOffset], freeBufByteCount, freeBufByteCount, 1000); + const ssize_t nRead = _serial->readAtLeast(&_buf[_bufOffset], freeBufByteCount, freeBufByteCount, 500); if (nRead != freeBufByteCount) { PX4_ERR("Can't read requested data from the serial device. Bytes requested: %d. Bytes read: %d", freeBufByteCount, static_cast(nRead)); @@ -546,8 +568,8 @@ bool Sensor::parseUDDPayload() { break; } default: { - PX4_ERR("Unknown message type: %d. Further package parsing result will be incorrect!", - messageType); + PX4_ERR("Unknown message type: %d. Further package parsing result will be incorrect", + messageType); messageLength = 0; break; } diff --git a/src/drivers/ins/microstrain/MicroStrain.cpp b/src/drivers/ins/microstrain/MicroStrain.cpp index 428e404b36..a46639e4ff 100755 --- a/src/drivers/ins/microstrain/MicroStrain.cpp +++ b/src/drivers/ins/microstrain/MicroStrain.cpp @@ -91,13 +91,35 @@ MicroStrain::MicroStrain(const char *uart_port) : (double)_param_ms_gnss_offset2_y.get(), (double)_param_ms_gnss_offset2_z.get()); - rotation.euler[0] = _param_ms_sensor_roll.get(); - rotation.euler[1] = _param_ms_sensor_pitch.get(); - rotation.euler[2] = _param_ms_sensor_yaw.get(); + optical_flow_offset[0] = _param_ms_oflow_offset_x.get(); + optical_flow_offset[1] = _param_ms_oflow_offset_y.get(); + optical_flow_offset[2] = _param_ms_oflow_offset_z.get(); + PX4_DEBUG("Optical flow offset: %f/%f/%f", (double)_param_ms_oflow_offset_x.get(), + (double)_param_ms_oflow_offset_y.get(), + (double)_param_ms_oflow_offset_z.get()); + + rotation_sens.euler[0] = _param_ms_sensor_roll.get(); + rotation_sens.euler[1] = _param_ms_sensor_pitch.get(); + rotation_sens.euler[2] = _param_ms_sensor_yaw.get(); PX4_DEBUG("Device Roll/Pitch/Yaw: %f/%f/%f", (double)_param_ms_sensor_roll.get(), (double)_param_ms_sensor_pitch.get(), (double)_param_ms_sensor_yaw.get()); + rotation_ext_mag.euler[0] = _param_ms_emag_roll.get(); + rotation_ext_mag.euler[1] = _param_ms_emag_pitch.get(); + rotation_ext_mag.euler[2] = _param_ms_emag_yaw.get(); + PX4_DEBUG("External magnetometer Roll/Pitch/Yaw: %f/%f/%f", (double)_param_ms_emag_roll.get(), + (double)_param_ms_emag_pitch.get(), + (double)_param_ms_emag_yaw.get()); + + rotation_ext_heading.euler[2] = _param_ms_ehead_yaw.get(); + PX4_DEBUG("External heading yaw: %f", (double)_param_ms_ehead_yaw.get()); + + ext_mag_uncert = _param_ms_emag_uncert.get(); + opt_flow_uncert = _param_ms_oflow_uncert.get(); + PX4_DEBUG("External Mag Uncertainty: %f", (double)_param_ms_emag_uncert.get()); + PX4_DEBUG("Optical Flow Uncertainty: %f", (double)_param_ms_oflow_uncert.get()); + _sensor_baro_pub.advertise(); _sensor_selection_pub.advertise(); _vehicle_local_position_pub.advertise(); @@ -106,9 +128,6 @@ MicroStrain::MicroStrain(const char *uart_port) : _vehicle_global_position_pub.advertise(); _vehicle_odometry_pub.advertise(); _estimator_status_pub.advertise(); - _sensor_gps_pub[0].advertise(); - _sensor_gps_pub[1].advertise(); - } MicroStrain::~MicroStrain() @@ -156,9 +175,9 @@ bool mipInterfaceUserRecvFromDevice(mip_interface *device, uint8_t *buffer, size bool mipInterfaceUserSendToDevice(mip_interface *device, const uint8_t *data, size_t length) { - int res = device_uart.write(const_cast(data), length); + size_t res = device_uart.write(const_cast(data), length); - if (res >= 0) { + if (res == length) { return true; } @@ -239,7 +258,7 @@ mip_cmd_result MicroStrain::getSupportedDescriptors() return res; } - if (mip_cmd_result_is_ack(res_extended)) { + if (!mip_cmd_result_is_ack(res_extended)) { PX4_DEBUG("Device does not support the extended descriptors command."); } @@ -531,7 +550,6 @@ mip_cmd_result MicroStrain::configureImuMessageFormat() imu_descriptors); return res; - } mip_cmd_result MicroStrain::configureFilterMessageFormat() @@ -635,6 +653,11 @@ mip_cmd_result MicroStrain::configureFilterMessageFormat() mip_cmd_result MicroStrain::configureGnssMessageFormat(uint8_t descriptor_set) { + if (_param_ms_gnss_aid_src_ctrl.get() == MIP_FILTER_GNSS_SOURCE_COMMAND_SOURCE_EXT) { + PX4_DEBUG("External GNSS aiding source detected, skipping GNSS message format config"); + return MIP_ACK_OK; + } + PX4_DEBUG("Configuring GNSS Message Format"); uint8_t num_gnss_descriptors = 0; @@ -700,34 +723,174 @@ mip_cmd_result MicroStrain::configureGnssMessageFormat(uint8_t descriptor_set) gnss_descriptors); return res; - } mip_cmd_result MicroStrain::configureAidingMeasurement(uint16_t aiding_source, bool enable) { - mip_cmd_result res; - - // Configures the aiding measurement if the device support it - if (supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_AIDING_MEASUREMENT_ENABLE)) { - res = mip_filter_write_aiding_measurement_enable(&_device, aiding_source, enable); - - // If the device doesnt support the aiding source but the command is to disable it, we consider it a success - if (res == MIP_NACK_INVALID_PARAM && !enable) { - res = MIP_ACK_OK; - } - - } else { + // If the device doesn’t support aiding measurements + if (!supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_AIDING_MEASUREMENT_ENABLE)) { PX4_WARN("Aiding measurements are not supported"); - // If the command was to disable, we consider it a success - if (!enable) { - res = MIP_ACK_OK; + // disabling is always OK + return enable ? MIP_PX4_ERROR : MIP_ACK_OK; + } + + // Try to configure aiding measurement + mip_cmd_result res = mip_filter_write_aiding_measurement_enable(&_device, aiding_source, enable); + + // If the device doesnt support the aiding source but the command is to disable it, we consider it a success + if (res == MIP_NACK_INVALID_PARAM && !enable) { + return MIP_ACK_OK; + } + + return res; +} + +mip_cmd_result MicroStrain::enableAidingSource(uint16_t source, + bool enabled, + uint8_t frame_id, + uint8_t frame_format, + const float offset[3], + mip_aiding_frame_config_command_rotation rotation, + uint16_t aiding_cmd_desc, + bool &aiding_flag, + const char *name) +{ + mip_cmd_result res = configureAidingMeasurement(source, enabled); + + if (!mip_cmd_result_is_ack(res)) { + PX4_ERR("Could not configure %s aiding", name); + return res; + } + + // Frame 0 is used to handle the internal aiding scenario + if (frame_id == 0) { + return res; + } + + // True if the aiding message supported & requested + aiding_flag = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, aiding_cmd_desc) && enabled; + + // Error if requested but unsupported. + if (enabled && !aiding_flag) { + PX4_ERR("Sending %s aiding messages not supported", name); + return MIP_PX4_ERROR; + } + + // Write the frame config if enabled + if (aiding_flag) { + res = mip_aiding_write_frame_config(&_device, frame_id, frame_format, false, offset, &rotation); + + if (!mip_cmd_result_is_ack(res)) { + PX4_ERR("Could not write %s frame config", name); + return res; + } + } + + return res; +} + +mip_cmd_result MicroStrain::configureGnssAiding() +{ + // Enables GNSS Position & Velocity as an aiding measurement + mip_cmd_result res = configureAidingMeasurement(MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_GNSS_POS_VEL, + true); + + if (!mip_cmd_result_is_ack(res)) { + if (res != MIP_NACK_INVALID_PARAM && res != MIP_PX4_ERROR) { + PX4_ERR("Error enabling GNSS Position & Velocity aiding"); + return res; } else { - res = MIP_PX4_ERROR; + // AR and AHRS edge case + PX4_WARN("Could not enable GNSS Position & Velocity aiding"); + return MIP_ACK_OK; } } + else { + // Check to see if sending GNSS position and velocity as an aiding measurement is supported + bool pos_aiding = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_POS_LLH); + bool vel_aiding = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_VEL_NED); + _ext_pos_vel_aiding = pos_aiding && vel_aiding; + + if (!_ext_pos_vel_aiding) { + PX4_ERR("Sending GNSS pos/vel aiding messages is not supported"); + return MIP_PX4_ERROR; + } + } + + // Prioritizing setting up multi antenna offsets if it is supported + if (supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_MULTI_ANTENNA_OFFSET)) { + + // Sets up the GNSS aiding source + if (supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_GNSS_SOURCE_CONTROL)) { + if (!mip_cmd_result_is_ack(res = mip_filter_write_gnss_source(&_device, (uint8_t)_param_ms_gnss_aid_src_ctrl.get()))) { + PX4_ERR("Could not write the gnss aiding source"); + return res; + } + + // Checks if the gnss aiding source is external + if (_param_ms_gnss_aid_src_ctrl.get() == MIP_FILTER_GNSS_SOURCE_COMMAND_SOURCE_EXT) { + _ext_pos_vel_aiding = true; + + // Sets up the aiding frame for the external source + if (supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_FRAME_CONFIG)) { + if (!mip_cmd_result_is_ack(res = mip_aiding_write_frame_config(&_device, 1, + MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, false, + gnss_antenna_offset1, &rotation_gnss))) { + PX4_ERR("Could not write aiding frame config"); + return res; + } + } + } + + else { + // Sets up the antenna offsets if the source is internal + mip_cmd_result res1 = mip_filter_write_multi_antenna_offset(&_device, 1, gnss_antenna_offset1); + mip_cmd_result res2 = mip_filter_write_multi_antenna_offset(&_device, 2, gnss_antenna_offset2); + + if (!mip_cmd_result_is_ack(res1)) { + PX4_ERR("Could not write multi antenna (1) offsets"); + return res1; + } + + else if (!mip_cmd_result_is_ack(res2)) { + PX4_ERR("Could not write multi antenna (2) offsets"); + return res2; + } + } + } + + else { + PX4_ERR("Does not support GNSS source control"); + return MIP_PX4_ERROR; + } + + // Selectively enables dual antenna heading as an aiding measurement + if (!mip_cmd_result_is_ack(res = enableAidingSource( + MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_GNSS_HEADING, + _param_ms_int_heading_en.get(), + 0, 0, nullptr, mip_aiding_frame_config_command_rotation{0}, + 0, _int_aiding, "dual antenna heading"))) { + return res; + } + } + + // Otherwise sets up the aiding frame + else if (supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_FRAME_CONFIG)) { + if (!mip_cmd_result_is_ack(res = mip_aiding_write_frame_config(&_device, 1, + MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, false, + gnss_antenna_offset1, &rotation_gnss))) { + PX4_ERR("Could not write aiding frame config"); + return res; + } + } + + else { + PX4_WARN("Aiding frames are not supported"); + } + return res; } @@ -736,116 +899,53 @@ mip_cmd_result MicroStrain::configureAidingSources() PX4_DEBUG("Configuring aiding sources"); mip_cmd_result res; - // Selectively turn on the magnetometer aiding source - if (!mip_cmd_result_is_ack(res = configureAidingMeasurement( + // Selectively turn on internal magnetometer as an aiding source + if (!mip_cmd_result_is_ack(res = enableAidingSource( MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_MAGNETOMETER, - _param_ms_int_mag_en.get()))) { - PX4_ERR("Could not configure magnetometer aiding"); + _param_ms_int_mag_en.get(), + 0, 0, nullptr, mip_aiding_frame_config_command_rotation{0}, + 0, _int_aiding, "internal magnetometer"))) { return res; } - // Enables GNSS Position & Velocity as an aiding measurement - res = configureAidingMeasurement(MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_GNSS_POS_VEL, - true); - - if (!mip_cmd_result_is_ack(res)) { - if (res != MIP_NACK_INVALID_PARAM && res != MIP_PX4_ERROR) { - PX4_ERR("Error enabling GNSS Position & Velocity aiding"); - return res; - - } else { - PX4_WARN("Could not enable GNSS Position & Velocity aiding"); - } - - } else { - // Check to see if sending GNSS position and velocity as an aiding measurement is supported - bool pos_aiding = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_POS_LLH); - bool vel_aiding = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_VEL_NED); - _ext_pos_vel_aiding = pos_aiding && vel_aiding; - - if (!_ext_pos_vel_aiding) { - PX4_ERR("Sending GNSS pos/vel aiding messages is not supported"); - return MIP_PX4_ERROR; - } - - } - - // Selectively turn on external heading as an aiding measurement - if (!mip_cmd_result_is_ack(res = configureAidingMeasurement( - MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_GNSS_HEADING, - _param_ms_ext_heading_en.get()))) { - PX4_ERR("Could not configure external heading aiding"); + // Selectively turn on external magnetometer as an aiding source + if (!mip_cmd_result_is_ack(res = enableAidingSource( + MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_EXTERNAL_MAGNETOMETER, + _param_ms_ext_mag_en.get(), + 2, MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, + ext_mag_offset, rotation_ext_mag, + MIP_CMD_DESC_AIDING_MAGNETIC_FIELD, + _ext_mag_aiding, + "external magnetometer"))) { return res; - - } else { - // Check to see if sending external heading as an aiding measurement is supported - _ext_heading_aiding = supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_HEADING_TRUE) - && _param_ms_ext_heading_en.get(); - - if (!_ext_heading_aiding && _param_ms_ext_heading_en.get()) { - PX4_ERR("Sending external heading aiding messages is not supported"); - return MIP_PX4_ERROR; - } - } - // Prioritizing setting up multi antenna offsets if it is supported - if (supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_MULTI_ANTENNA_OFFSET)) { - mip_cmd_result res1 = mip_filter_write_multi_antenna_offset(&_device, 1, gnss_antenna_offset1); - mip_cmd_result res2 = mip_filter_write_multi_antenna_offset(&_device, 2, gnss_antenna_offset2); - - if (!mip_cmd_result_is_ack(res1)) { - PX4_ERR("Could not write multi antenna offsets"); - return res1; - - } - - else if (!mip_cmd_result_is_ack(res2)) { - PX4_ERR("Could not write multi antenna offsets"); - return res2; - - } - - if (supportsDescriptor(MIP_FILTER_CMD_DESC_SET, MIP_CMD_DESC_FILTER_GNSS_SOURCE_CONTROL)) { - if (!mip_cmd_result_is_ack(res = mip_filter_write_gnss_source(&_device, (uint8_t)_param_ms_gnss_aid_src_ctrl.get()))) { - PX4_ERR("Could not write the gnss aiding source"); - return res; - - } - - _ext_pos_vel_aiding = (_param_ms_gnss_aid_src_ctrl.get() == MIP_FILTER_GNSS_SOURCE_COMMAND_SOURCE_EXT); - - - } else { - PX4_ERR("Does not support GNSS source control"); - return MIP_PX4_ERROR; - } - - // Selectively enables dual antenna heading as an aiding measurement - if (!mip_cmd_result_is_ack(res = configureAidingMeasurement( - MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_GNSS_HEADING, - _param_ms_int_heading_en.get()))) { - PX4_ERR("Could not configure dual antenna heading aiding"); - return res; - } - + // Selectively turn on body frame velocity as an aiding source + if (!mip_cmd_result_is_ack(res = enableAidingSource( + MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_VEHICLE_FRAME_VEL, + _param_ms_ext_opt_flow_en.get(), + 3, MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, + optical_flow_offset, rotation_oflow, + MIP_CMD_DESC_AIDING_VEL_ODOM, + _ext_optical_flow_aiding, + "optical flow"))) { + return res; } - // Otherwise sets up the aiding frame - else if (supportsDescriptor(MIP_AIDING_CMD_DESC_SET, MIP_CMD_DESC_AIDING_FRAME_CONFIG)) { - if (!mip_cmd_result_is_ack(res = mip_aiding_write_frame_config(&_device, 1, - MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, false, - gnss_antenna_offset1, &rotation))) { - PX4_ERR("Could not write aiding frame config"); - return res; - } + // Selectively turn on external heading as an aiding source + if (!mip_cmd_result_is_ack(res = enableAidingSource( + MIP_FILTER_AIDING_MEASUREMENT_ENABLE_COMMAND_AIDING_SOURCE_EXTERNAL_HEADING, + _param_ms_ext_heading_en.get(), + 4, MIP_AIDING_FRAME_CONFIG_COMMAND_FORMAT_EULER, + ext_heading_offset, rotation_ext_heading, + MIP_CMD_DESC_AIDING_HEADING_TRUE, + _ext_heading_aiding, + "external heading"))) { + return res; } - else { - PX4_WARN("Aiding frames are not supported"); - } - - _ext_aiding = (_ext_pos_vel_aiding || _ext_heading_aiding); + // Configures GNSS Aiding + res = configureGnssAiding(); return res; } @@ -985,8 +1085,8 @@ bool MicroStrain::initializeIns() PX4_DEBUG("Writing SVT"); if (!mip_cmd_result_is_ack(res = mip_3dm_write_sensor_2_vehicle_transform_euler(&_device, - math::radians(rotation.euler[0]), - math::radians(rotation.euler[1]), math::radians(rotation.euler[2])))) { + math::radians(rotation_sens.euler[0]), + math::radians(rotation_sens.euler[1]), math::radians(rotation_sens.euler[2])))) { MS_PX4_ERROR(res, "Could not set sensor-to-vehicle transformation!"); return false; } @@ -1047,29 +1147,23 @@ void MicroStrain::sensorCallback(void *user, const mip_packet *packet, mip::Time accel.updated = true; break; - case MIP_DATA_DESC_SENSOR_GYRO_SCALED: extract_mip_sensor_scaled_gyro_data_from_field(&field, &gyro.sample); gyro.updated = true; break; - case MIP_DATA_DESC_SENSOR_MAG_SCALED: extract_mip_sensor_scaled_mag_data_from_field(&field, &mag.sample); mag.updated = true; break; - case MIP_DATA_DESC_SENSOR_PRESSURE_SCALED: extract_mip_sensor_scaled_pressure_data_from_field(&field, &baro.sample); baro.updated = true; break; - default: break; - - } } @@ -1078,7 +1172,6 @@ void MicroStrain::sensorCallback(void *user, const mip_packet *packet, mip::Time ref->_px4_accel.update(t, accel.sample.scaled_accel[0]*CONSTANTS_ONE_G, accel.sample.scaled_accel[1]*CONSTANTS_ONE_G, accel.sample.scaled_accel[2]*CONSTANTS_ONE_G); - } if (gyro.updated) { @@ -1201,8 +1294,8 @@ void MicroStrain::filterCallback(void *user, const mip_packet *packet, mip::Time gp.alt_valid = is_fullnav && pos_llh.sample.valid_flags; - gp.eph = sqrtf(sq(llh_uncert.sample.north) + sq(llh_uncert.sample.east) + sq(ref->_gps_origin_ep[0])); - gp.epv = sqrtf(sq(llh_uncert.sample.down) + sq(ref->_gps_origin_ep[1])); + gp.eph = sqrtf(sq(llh_uncert.sample.north) + sq(llh_uncert.sample.east)); + gp.epv = llh_uncert.sample.down; // ------- Fields we cannot obtain ------- gp.delta_alt = 0; @@ -1625,9 +1718,6 @@ void MicroStrain::initializeRefPos() _pos_ref.initReference(gps.latitude_deg, gps.longitude_deg, t); _ref_alt = gps.altitude_msl_m; - _gps_origin_ep[0] = gps.eph; - _gps_origin_ep[1] = gps.epv; - PX4_DEBUG("Reference position initialized"); } @@ -1646,7 +1736,7 @@ void MicroStrain::updateGeoidHeight(float geoid_height, float t) } } -void MicroStrain::sendAidingMeasurements() +void MicroStrain::sendGPSAiding() { sensor_gps_s gps{0}; @@ -1667,13 +1757,13 @@ void MicroStrain::sendAidingMeasurements() mip_time t; t.timebase = MIP_TIME_TIMEBASE_TIME_OF_ARRIVAL; - t.reserved = 0x01; + t.reserved = 0x00; t.nanoseconds = 0; // Sends GNSS position and velocity aiding data if they are both supported if (_ext_pos_vel_aiding) { float llh_uncertainty[3] = {gps.eph, gps.eph, gps.epv}; - mip_aiding_llh_pos(&_device, &t, MIP_FILTER_REFERENCE_FRAME_LLH, gps.latitude_deg, + mip_aiding_llh_pos(&_device, &t, 1, gps.latitude_deg, gps.longitude_deg, gps.altitude_ellipsoid_m, llh_uncertainty, MIP_AIDING_LLH_POS_COMMAND_VALID_FLAGS_ALL); @@ -1684,7 +1774,7 @@ void MicroStrain::sendAidingMeasurements() if (gps.vel_ned_valid) { float ned_v[3] = {gps.vel_n_m_s, gps.vel_e_m_s, gps.vel_d_m_s}; float ned_velocity_uncertainty[3] = {sqrtf(gps.s_variance_m_s), sqrtf(gps.s_variance_m_s), sqrtf(gps.s_variance_m_s)}; - mip_aiding_ned_vel(&_device, &t, MIP_FILTER_REFERENCE_FRAME_LLH, ned_v, ned_velocity_uncertainty, + mip_aiding_ned_vel(&_device, &t, 1, ned_v, ned_velocity_uncertainty, MIP_AIDING_NED_VEL_COMMAND_VALID_FLAGS_ALL); } } @@ -1692,7 +1782,60 @@ void MicroStrain::sendAidingMeasurements() // Sends external heading aiding data if they are both supported if (_ext_heading_aiding && PX4_ISFINITE(gps.heading)) { float heading = gps.heading + gps.heading_offset; - mip_aiding_true_heading(&_device, &t, MIP_FILTER_REFERENCE_FRAME_LLH, heading, gps.heading_accuracy, 0xff); + mip_aiding_true_heading(&_device, &t, 4, heading, gps.heading_accuracy, 0xff); + } +} + +void MicroStrain::sendMagAiding() +{ + vehicle_magnetometer_s mag{0}; + + if (!_vehicle_magnetometer_sub.update(&mag)) { + return; + } + + mip_time t; + t.timebase = MIP_TIME_TIMEBASE_TIME_OF_ARRIVAL; + t.reserved = 0x00; + t.nanoseconds = 0; + + float uncert[3] = {ext_mag_uncert, ext_mag_uncert, ext_mag_uncert}; + + mip_aiding_magnetic_field(&_device, &t, 2, mag.magnetometer_ga, uncert, + MIP_AIDING_MAGNETIC_FIELD_COMMAND_VALID_FLAGS_ALL); +} + +void MicroStrain::sendOpticalFlowAiding() +{ + vehicle_optical_flow_vel_s ofv{0}; + + if (!_vehicle_optical_flow_vel_sub.update(&ofv)) { + return; + } + + mip_time t; + t.timebase = MIP_TIME_TIMEBASE_TIME_OF_ARRIVAL; + t.reserved = 0x00; + t.nanoseconds = 0; + + float vel[3] = {ofv.vel_body[0], ofv.vel_body[1], 0}; + float uncert[3] = {opt_flow_uncert, opt_flow_uncert, 0.0}; + + mip_aiding_vehicle_fixed_frame_velocity(&_device, &t, 3, vel, uncert, 0x0003); +} + +void MicroStrain::sendAidingMeasurements() +{ + if (_ext_pos_vel_aiding || _ext_heading_aiding) { + sendGPSAiding(); + } + + if (_ext_mag_aiding) { + sendMagAiding(); + } + + if (_ext_optical_flow_aiding) { + sendOpticalFlowAiding(); } } @@ -1706,7 +1849,6 @@ bool MicroStrain::init() void MicroStrain::Run() { - if (should_exit()) { ScheduleClear(); exit_and_cleanup(); @@ -1742,8 +1884,7 @@ void MicroStrain::Run() //Initializes reference position if there is gps data if (_vehicle_gps_position_sub.updated() && !_pos_ref.isInitialized()) {initializeRefPos();} - // Sends aiding data only if external aiding was set up - if (_ext_aiding) {sendAidingMeasurements();} + sendAidingMeasurements(); perf_end(_loop_perf); } diff --git a/src/drivers/ins/microstrain/MicroStrain.hpp b/src/drivers/ins/microstrain/MicroStrain.hpp index af4c707d82..3cba872793 100755 --- a/src/drivers/ins/microstrain/MicroStrain.hpp +++ b/src/drivers/ins/microstrain/MicroStrain.hpp @@ -62,6 +62,8 @@ #include #include #include +#include +#include #include #include @@ -145,6 +147,18 @@ private: mip_cmd_result configureAidingMeasurement(uint16_t aiding_source, bool enable); + mip_cmd_result enableAidingSource(uint16_t source, + bool enabled, + uint8_t frame_id, + uint8_t frame_format, + const float offset[3], + mip_aiding_frame_config_command_rotation rotation, + uint16_t aiding_cmd_desc, + bool &aiding_flag, + const char *name); + + mip_cmd_result configureGnssAiding(); + mip_cmd_result configureAidingSources(); mip_cmd_result writeFilterInitConfig(); @@ -153,6 +167,12 @@ private: void updateGeoidHeight(float geoid_height, float t); + void sendGPSAiding(); + + void sendMagAiding(); + + void sendOpticalFlowAiding(); + void sendAidingMeasurements(); bool init(); @@ -170,11 +190,23 @@ private: bool _ext_pos_vel_aiding{false}; bool _ext_heading_aiding{false}; - bool _ext_aiding{false}; + bool _ext_mag_aiding{false}; + bool _ext_optical_flow_aiding{false}; + bool _int_aiding{false}; float gnss_antenna_offset1[3] = {0}; float gnss_antenna_offset2[3] = {0}; - mip_aiding_frame_config_command_rotation rotation = {0}; + float ext_mag_offset[3] = {0}; + float optical_flow_offset[3] = {0}; + float ext_heading_offset[3] = {0}; + mip_aiding_frame_config_command_rotation rotation_sens = {0}; + mip_aiding_frame_config_command_rotation rotation_gnss = {0}; + mip_aiding_frame_config_command_rotation rotation_ext_mag = {0}; + mip_aiding_frame_config_command_rotation rotation_oflow = {0}; + mip_aiding_frame_config_command_rotation rotation_ext_heading = {0}; + + float ext_mag_uncert = 0.0; + float opt_flow_uncert = 0.0; AlphaFilter _geoid_height_lpf; uint64_t _last_geoid_height_update_us{0}; @@ -182,7 +214,6 @@ private: MapProjection _pos_ref{}; double _ref_alt = 0; - float _gps_origin_ep[2] = {0}; template struct SensorSample { @@ -217,8 +248,10 @@ private: (ParamInt) _param_ms_alignment, (ParamInt) _param_ms_gnss_aid_src_ctrl, (ParamInt) _param_ms_int_mag_en, + (ParamInt) _param_ms_ext_mag_en, (ParamInt) _param_ms_int_heading_en, (ParamInt) _param_ms_ext_heading_en, + (ParamInt) _param_ms_ext_opt_flow_en, (ParamInt) _param_ms_svt_en, (ParamInt) _param_ms_accel_range_setting, (ParamInt) _param_ms_gyro_range_setting, @@ -230,7 +263,16 @@ private: (ParamFloat) _param_ms_gnss_offset2_z, (ParamFloat) _param_ms_sensor_roll, (ParamFloat) _param_ms_sensor_pitch, - (ParamFloat) _param_ms_sensor_yaw + (ParamFloat) _param_ms_sensor_yaw, + (ParamFloat) _param_ms_emag_roll, + (ParamFloat) _param_ms_emag_pitch, + (ParamFloat) _param_ms_emag_yaw, + (ParamFloat) _param_ms_oflow_offset_x, + (ParamFloat) _param_ms_oflow_offset_y, + (ParamFloat) _param_ms_oflow_offset_z, + (ParamFloat) _param_ms_ehead_yaw, + (ParamFloat) _param_ms_emag_uncert, + (ParamFloat) _param_ms_oflow_uncert ) // Sensor types needed for message creation / updating / publishing @@ -256,4 +298,6 @@ private: // Subscriptions uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; // subscription limited to 1 Hz updates uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; + uORB::Subscription _vehicle_magnetometer_sub{ORB_ID(vehicle_magnetometer)}; + uORB::Subscription _vehicle_optical_flow_vel_sub{ORB_ID(vehicle_optical_flow_vel)}; }; diff --git a/src/drivers/ins/microstrain/module.yaml b/src/drivers/ins/microstrain/module.yaml index 6c91ee0d40..786db17094 100644 --- a/src/drivers/ins/microstrain/module.yaml +++ b/src/drivers/ins/microstrain/module.yaml @@ -1,310 +1,391 @@ module_name: MICROSTRAIN +serial_config: + - command: sleep 1; microstrain start -d ${SERIAL_DEV} + port_config_param: + name: SENS_MS_CFG + group: Sensors + parameters: - group: Sensors definitions: MS_MODE: description: - short: Toggles using the device as the primary EKF + short: MicroStrain device mode long: | - Setting to 1 will publish data from the device to the vehicle topics (global_position, attitude, local_position, odometry), estimator_status and sensor_selection - Setting to 0 will publish data from the device to the external_ins topics (global position, attitude, local position) - Restart Required - - This parameter is specific to the MicroStrain driver. - type: int32 - default: 1 + Sensor mode publishes raw IMU data to be used by EKF2. INS data from the device is published to the external INS topics. + INS mode publishes the INS data to the vehicle topics to be used for navigation. + type: enum + values: + 0: Sensor Mode + 1: INS Mode + reboot_required: true + default: 0 MS_IMU_RATE_HZ: description: - short: IMU Data Rate + short: MicroStrain IMU data rate long: | - IMU (Accelerometer and Gyroscope) data rate - The INS driver will be scheduled at a rate 2*MS_IMU_RATE_HZ - Max Limit: 1000 - 0 - Disable IMU datastream - The max limit should be divisible by the rate - eg: 1000 % MS_IMU_RATE_HZ = 0 - Restart required - - This parameter is specific to the MicroStrain driver. + Accelerometer and Gyroscope data rate (Hz). + Valid rates: 0 or any factor of 1000. type: int32 + max: 1000 + min: 0 + reboot_required: true default: 500 MS_MAG_RATE_HZ: description: - short: Magnetometer Data Rate + short: MicroStrain magnetometer data rate long: | - Magnetometer data rate - Max Limit: 1000 - 0 - Disable magnetometer datastream - The max limit should be divisible by the rate - eg: 1000 % MS_MAG_RATE_HZ = 0 - Restart required - - This parameter is specific to the MicroStrain driver. + Magnetometer data rate (Hz). + Valid rates: 0 or any factor of 1000. type: int32 + max: 1000 + min: 0 + reboot_required: true default: 50 MS_BARO_RATE_HZ: description: - short: Barometer data rate + short: MicroStrain barometer data rate long: | - Barometer data rate - Max Limit: 1000 - 0 - Disable barometer datastream - The max limit should be divisible by the rate - eg: 1000 % MS_BARO_RATE_HZ = 0 - Restart required - - This parameter is specific to the MicroStrain driver. + Barometer data rate (Hz). + Valid rates: 0 or any factor of 1000. type: int32 + max: 1000 + min: 0 + reboot_required: true default: 50 MS_FILT_RATE_HZ: description: - short: EKF data Rate + short: MicroStrain EKF data rate long: | - EKF data rate - Max Limit: 1000 - 0 - Disable EKF datastream - The max limit should be divisible by the rate - eg: 1000 % MS_FILT_RATE_HZ = 0 - Restart required - - This parameter is specific to the MicroStrain driver. + The rate at which the INS data is published (Hz). + Valid rates: 0 or any factor of 1000. type: int32 + max: 1000 + min: 0 + reboot_required: true default: 250 MS_GNSS_RATE_HZ: description: - short: GNSS data Rate + short: MicroStrain GNSS data rate long: | - GNSS receiver 1 and 2 data rate - Max Limit: 5 - The max limit should be divisible by the rate - 0 - Disable GNSS datastream - eg: 5 % MS_GNSS_RATE_HZ = 0 - Restart required - - This parameter is specific to the MicroStrain driver. + GNSS receiver 1 and 2 data rate (Hz). + Valid rates: 0, 1 or 5. type: int32 + max: 5 + min: 0 + reboot_required: true default: 5 MS_ALIGNMENT: description: - short: Alignment type + short: MicroStrain heading alignment type long: | - Select the source of heading alignment - This is a bitfield, you can use more than 1 source - Bit 0 - Dual-antenna GNSS - Bit 1 - GNSS kinematic (requires motion, e.g. a GNSS velocity) - Bit 2 - Magnetometer - Bit 3 - External Heading (first valid external heading will be used to initialize the filter) - Restart required - - This parameter is specific to the MicroStrain driver. - type: int32 + Select the source of heading alignment. + type: bitmask + bit: + 0: Dual-antenna GNSS + 1: GNSS kinematic (requires motion, e.g. a GNSS velocity) + 2: Magnetometer + 3: External Heading (first valid external heading will be used to initialize the filter) + max: 15 + min: 1 + reboot_required: true default: 2 MS_GNSS_AID_SRC: description: - short: GNSS aiding source control + short: MicroStrain GNSS aiding source control long: | - Select the source of gnss aiding (GNSS/INS) - 1 = All internal receivers, - 2 = External GNSS messages, - 3 = GNSS receiver 1 only - 4 = GNSS receiver 2 only - Restart required - - This parameter is specific to the MicroStrain driver. - type: int32 + Select the source of gnss aiding (GNSS/INS). + type: enum + values: + 1: All internal receivers + 2: External GNSS messages + 3: GNSS receiver 1 only + 4: GNSS receiver 2 only + reboot_required: true default: 1 MS_INT_MAG_EN: description: - short: Toggles internal magnetometer aiding in the device filter + short: Enable MicroStrain internal magnetometer long: | - 0 = Disabled, - 1 = Enabled - Restart required + Toggles internal magnetometer aiding in the device filter. + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true + default: 0 - This parameter is specific to the MicroStrain driver. - type: int32 + MS_EXT_MAG_EN: + description: + short: Enable MicroStrain external magnetometer aiding + long: | + Toggles external magnetometer aiding in the device filter. + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true default: 0 MS_INT_HEAD_EN: description: - short: Toggles internal heading as an aiding measurement + short: Enable MicroStrain internal heading aiding long: | - 0 = Disabled, - 1 = Enabled + Toggles internal heading as an aiding measurement. If dual antennas are supported (CV7-GNSS/INS). The filter will be configured to use dual antenna heading as an aiding measurement. - Restart required - - This parameter is specific to the MicroStrain driver. - type: int32 + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true default: 0 MS_EXT_HEAD_EN: description: - short: Toggles external heading as an aiding measurement + short: Enable MicroStrain external heading aiding long: | - 0 = Disabled, - 1 = Enabled + Toggles external heading as an aiding measurement. If enabled, the filter will be configured to accept external heading as an aiding meaurement. - Restart required + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true + default: 0 - This parameter is specific to the MicroStrain driver. - type: int32 + MS_OPT_FLOW_EN: + description: + short: Enable MicroStrain optical flow aiding + long: | + Toggles body frame velocity as an aiding measurement. + The driver uses the body frame velocity from the optical flow sensor as the aiding measurements. + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true default: 0 MS_SVT_EN: description: - short: Enables sensor to vehicle transform + short: Enables Microstrain sensor to vehicle transform long: | - 0 = Disabled, - 1 = Enabled If the sensor has a different orientation with respect to the vehicle. This will enable a transform to correct itself. - The transform is described by MS_SENSOR_ROLL, MS_SENSOR_PITCH, MS_SENSOR_YAW - Restart required - - This parameter is specific to the MicroStrain driver. - type: int32 + The transform is described by MS_SENSOR_ROLL, MS_SENSOR_PITCH, MS_SENSOR_YAW. + type: enum + values: + 0: Disabled + 1: Enabled + reboot_required: true default: 0 MS_ACCEL_RANGE: description: - short: Sets the range of the accelerometer + short: MicroStrain accelerometer range long: | - -1 = Will not be configured, and will use the device default range, - Each adjustable range has a corresponding integer setting. Refer to the device's User Manual to check the available adjustment ranges. - https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com - Restart required - - This parameter is specific to the MicroStrain driver. + -1 = Will not be configured, and will use the device default range. + Ranges vary by device and map to integer codes. Check the device's [User Manual](https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com) for supported ranges and set the corresponding integer. type: int32 + reboot_required: true default: -1 MS_GYRO_RANGE: description: - short: Sets the range of the gyro + short: MicroStrain gyroscope range long: | - -1 = Will not be configured, and will use the device default range, - Each adjustable range has a corresponding integer setting. Refer to the device's User Manual to check the available adjustment ranges. - https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com - Restart required - - This parameter is specific to the MicroStrain driver. + -1 = Will not be configured, and will use the device default range. + Ranges vary by device and map to integer codes. Check the device's [User Manual](https://www.hbkworld.com/en/products/transducers/inertial-sensors#!ref_microstrain.com) for supported ranges and set the corresponding integer. type: int32 + reboot_required: true default: -1 MS_GNSS_OFF1_X: description: - short: GNSS lever arm offset 1 (X) + short: MicroStrain GNSS lever arm offset 1 (X) long: | - Lever arm offset (m) in the X direction for the external GNSS receiver - In the case of a dual antenna setup, this is antenna 1 - Restart required - - This parameter is specific to the MicroStrain driver. + Lever arm offset (m) in the X direction for the external GNSS receiver. + In the case of a dual antenna setup, this is antenna 1. type: float + reboot_required: true default: 0.0 MS_GNSS_OFF1_Y: description: - short: GNSS lever arm offset 1 (Y) + short: MicroStrain GNSS lever arm offset 1 (Y) long: | - Lever arm offset (m) in the Y direction for the external GNSS receiver - In the case of a dual antenna setup, this is antenna 1 - Restart required - - This parameter is specific to the MicroStrain driver. + Lever arm offset (m) in the Y direction for the external GNSS receiver. + In the case of a dual antenna setup, this is antenna 1. type: float + reboot_required: true default: 0.0 MS_GNSS_OFF1_Z: description: - short: GNSS lever arm offset 1 (Z) + short: MicroStrain GNSS lever arm offset 1 (Z) long: | - Lever arm offset (m) in the Z direction for the external GNSS receiver - In the case of a dual antenna setup, this is antenna 1 - Restart required - - This parameter is specific to the MicroStrain driver. + Lever arm offset (m) in the Z direction for the external GNSS receiver. + In the case of a dual antenna setup, this is antenna 1. type: float + reboot_required: true default: 0.0 MS_GNSS_OFF2_X: description: - short: GNSS lever arm offset 2 (X) + short: MicroStrain GNSS lever arm offset 2 (X) long: | Lever arm offset (m) in the X direction for antenna 2 - This will only be used if the device supports a dual antenna setup - Restart required - - This parameter is specific to the MicroStrain driver. + This will only be used if the device supports a dual antenna setup. type: float + reboot_required: true default: 0.0 MS_GNSS_OFF2_Y: description: - short: GNSS lever arm offset 2 (Y) + short: MicroStrain GNSS lever arm offset 2 (Y) long: | - Lever arm offset (m) in the Y direction for antenna 2 - This will only be used if the device supports a dual antenna setup - Restart required - - This parameter is specific to the MicroStrain driver. + Lever arm offset (m) in the Y direction for antenna 2. + This will only be used if the device supports a dual antenna setup. type: float + reboot_required: true default: 0.0 MS_GNSS_OFF2_Z: description: - short: GNSS lever arm offset 2 (Z) + short: MicroStrain GNSS lever arm offset 2 (Z) long: | - Lever arm offset (m) in the X direction for antenna 2 - This will only be used if the device supports a dual antenna setup - Restart required - - This parameter is specific to the MicroStrain driver. + Lever arm offset (m) in the X direction for antenna 2. + This will only be used if the device supports a dual antenna setup. type: float + reboot_required: true default: 0.0 MS_SENSOR_ROLL: description: - short: Sensor to Vehicle Transform (Roll) + short: MicroStrain Sensor to vehicle transform (Roll) long: | - The orientation of the device (Radians) with respect to the vehicle frame around the x axis - Requires MS_SVT_EN to be enabled to be used - Restart required - - This parameter is specific to the MicroStrain driver. + The orientation of the device (Radians) with respect to the vehicle frame around the x axis. + Requires MS_SVT_EN to be enabled to be used. type: float + reboot_required: true default: 0.0 MS_SENSOR_PTCH: description: - short: Sensor to Vehicle Transform (Pitch) + short: MicroStrain Sensor to Vehicle Transform (Pitch) long: | - The orientation of the device (Radians) with respect to the vehicle frame around the y axis - Requires MS_SVT_EN to be enabled to be used - Restart required - - This parameter is specific to the MicroStrain driver. + The orientation of the device (Radians) with respect to the vehicle frame around the y axis. + Requires MS_SVT_EN to be enabled to be used. type: float + reboot_required: true default: 0.0 MS_SENSOR_YAW: description: - short: Sensor to Vehicle Transform (Yaw) + short: MicroStrain Sensor to Vehicle Transform (Yaw) long: | - The orientation of the device (Radians) with respect to the vehicle frame around the z axis - Requires MS_SVT_EN to be enabled to be used - Restart required - - This parameter is specific to the MicroStrain driver. + The orientation of the device (Radians) with respect to the vehicle frame around the z axis. + Requires MS_SVT_EN to be enabled to be used. type: float + reboot_required: true default: 0.0 + + MS_EMAG_ROLL: + description: + short: MicroStrain External Magnetometer Orientation (Roll) + long: | + The orientation of the device (Radians) with respect to the vehicle frame around the x axis. + Requires MS_EXT_MAG_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_EMAG_PTCH: + description: + short: MicroStrain External Magnetometer Orientation (Pitch) + long: | + The orientation of the device (Radians) with respect to the vehicle frame around the y axis. + Requires MS_EXT_MAG_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_EMAG_YAW: + description: + short: MicroStrain External Magnetometer Orientation (Yaw) + long: | + The orientation of the device (Radians) with respect to the vehicle frame around the z axis. + Requires MS_EXT_MAG_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_OFLW_OFF_X: + description: + short: MicroStrain optical flow offset (X) + long: | + Offset (m) in the X direction if an Optical Flow sensor is connected. + Requires MS_OPT_FLOW_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_OFLW_OFF_Y: + description: + short: MicroStrain optical flow offset (Y) + long: | + Offset (m) in the Y direction if an Optical Flow sensor is connected. + Requires MS_OPT_FLOW_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_OFLW_OFF_Z: + description: + short: MicroStrain optical flow offset (Z) + long: | + Offset (m) in the Z direction if an Optical Flow sensor is connected. + Requires MS_OPT_FLOW_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_EHEAD_YAW: + description: + short: MicroStrain External Heading Orientation (Yaw) + long: | + The orientation of the device (Radians) with respect to the vehicle frame around the z axis. + Requires MS_EXT_HEAD_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.0 + + MS_EMAG_UNCERT: + description: + short: MicroStrain external magnetometer uncertainty + long: | + The 1-sigma uncertainty (in Gauss) for all axes, which will remain constant across all aiding measurements. + Requires MS_EXT_MAG_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.1 + + MS_OFLW_UNCERT: + description: + short: MicroStrain optical flow uncertainty + long: | + The 1-sigma uncertainty (in m/s) for the X and Y axes, which will remain constant across all aiding measurements. + The Z axis is not used for aiding. + Requires MS_OPT_FLOW_EN to be enabled to be used. + type: float + reboot_required: true + default: 0.1 diff --git a/src/drivers/ins/sbgecom/CMakeLists.txt b/src/drivers/ins/sbgecom/CMakeLists.txt new file mode 100644 index 0000000000..e4c8362da3 --- /dev/null +++ b/src/drivers/ins/sbgecom/CMakeLists.txt @@ -0,0 +1,73 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_compile_definitions(SBG_CONFIG_LOG_MAX_SIZE=128) + +set(SBGECOM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sbgECom) +px4_add_git_submodule(TARGET git_sbgECom PATH ${SBGECOM_DIR}) + +add_subdirectory(sbgECom) + +add_dependencies(sbgECom prebuild_targets) + +target_compile_options(sbgECom + PRIVATE + -Wno-format + -Wno-format-security + -Wno-bad-function-cast + -Wno-double-promotion + -Wno-type-limits + -Wno-maybe-uninitialized + -Wno-float-equal +) + +if("${PX4_PLATFORM}" MATCHES "nuttx") + target_compile_definitions(sbgECom PUBLIC __NUTTX__) +endif() + + +px4_add_module( + MODULE drivers__ins__sbgecom + MAIN sbgecom + INCLUDES + sbgECom/common + sbgECom/src + COMPILE_FLAGS + SRCS + sbgecom.cpp + sbgecom.hpp + MODULE_CONFIG + module.yaml + DEPENDS + sbgECom + ) diff --git a/src/drivers/ins/sbgecom/Kconfig b/src/drivers/ins/sbgecom/Kconfig new file mode 100644 index 0000000000..2569367c7a --- /dev/null +++ b/src/drivers/ins/sbgecom/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_INS_SBGECOM + bool "sbgecom" + default n + ---help--- + Enable support for sbgecom diff --git a/src/drivers/ins/sbgecom/module.yaml b/src/drivers/ins/sbgecom/module.yaml new file mode 100644 index 0000000000..c32971e183 --- /dev/null +++ b/src/drivers/ins/sbgecom/module.yaml @@ -0,0 +1,50 @@ +module_name: sbgECom + +serial_config: + - command: sbgecom start -d ${SERIAL_DEV} + port_config_param: + name: SENS_SBG_CFG + group: Sensors + +parameters: + - group: Sensors + definitions: + SBG_MODE: + description: + short: sbgECom driver mode + long: | + Modes available for sbgECom driver. + In Sensors Only mode, use external IMU and magnetometer. + In GNSS mode, use external GNSS in addition to sensors only mode. + In INS mode, use external Kalman Filter in addition to GNSS mode. + + In INS mode, requires EKF2_EN 0. Keeping both enabled + can lead to an unexpected behavior and vehicle instability. + category: System + type: enum + values: + 0: Sensors Only + 1: GNSS + 2: INS (default) + default: 2 + SBG_BAUDRATE: + description: + short: sbgECom driver baudrate + long: | + Baudrate used by default for serial communication between PX4 + and SBG Systems INS through sbgECom driver. + category: System + type: int32 + min: 9600 + max: 921600 + default: 921600 + reboot_required: true + SBG_CONFIGURE_EN: + description: + short: sbgECom driver INS configuration enable + long: | + Enable SBG Systems INS configuration through sbgECom driver + on start. + category: System + type: boolean + default: 0 diff --git a/src/drivers/ins/sbgecom/sbgECom b/src/drivers/ins/sbgecom/sbgECom new file mode 160000 index 0000000000..80b121c771 --- /dev/null +++ b/src/drivers/ins/sbgecom/sbgECom @@ -0,0 +1 @@ +Subproject commit 80b121c7714083cc4868c0fdb8c41623c7ef9c93 diff --git a/src/drivers/ins/sbgecom/sbgecom.cpp b/src/drivers/ins/sbgecom/sbgecom.cpp new file mode 100644 index 0000000000..17c422839d --- /dev/null +++ b/src/drivers/ins/sbgecom/sbgecom.cpp @@ -0,0 +1,1125 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file sbgecom.cpp + * Driver for the SBG Systems products + * + * @author SBG Systems + */ + +#include "sbgecom.hpp" + +#include +#include + +#include +#include +#include + +#define DEFAULT_DEVNAME "/dev/ttyS0" + +#define SBG_MODE_SENSOR 0 +#define SBG_MODE_GNSS 1 +#define SBG_MODE_INS 2 + +#define SBG_ESTIMATOR_ATTITUDE (1 << 0) ///< 0 - attitude estimate is good +#define SBG_ESTIMATOR_VELOCITY_HORIZ (1 << 1) ///< 1 - horizontal velocity estimate is good +#define SBG_ESTIMATOR_VELOCITY_VERT (1 << 2) ///< 2 - vertical velocity estimate is good +#define SBG_ESTIMATOR_POS_HORIZ_REL (1 << 3) ///< 3 - horizontal position (relative) estimate is good +#define SBG_ESTIMATOR_POS_HORIZ_ABS (1 << 4) ///< 4 - horizontal position (absolute) estimate is good +#define SBG_ESTIMATOR_POS_VERT_ABS (1 << 5) ///< 5 - vertical position (absolute) estimate is good +#define SBG_ESTIMATOR_POS_VERT_AGL (1 << 6) ///< 6 - vertical position (above ground) estimate is good +#define SBG_ESTIMATOR_CONST_POS_MODE (1 << 7) ///< 7 - EKF is in a constant position mode and is not using external measurements (eg GPS or optical flow) +#define SBG_ESTIMATOR_PRED_POS_HORIZ_REL (1 << 8) ///< 8 - EKF has sufficient data to enter a mode that will provide a (relative) position estimate +#define SBG_ESTIMATOR_PRED_POS_HORIZ_ABS (1 << 9) ///< 9 - EKF has sufficient data to enter a mode that will provide a (absolute) position estimate +#define SBG_ESTIMATOR_GPS_GLITCH (1 << 10) ///< 10 - EKF has detected a GPS glitch +#define SBG_ESTIMATOR_ACCEL_ERROR (1 << 11) ///< 11 - EKF has detected bad accelerometer data + +#define DEFAULT_CONFIG_PATH "/etc/extras/sbg_settings.json" +#define OVERRIDE_CONFIG_PATH CONFIG_BOARD_ROOT_PATH DEFAULT_CONFIG_PATH +#define NEED_REBOOT_STR "\"needReboot\":true" + +using matrix::Vector2f; + +SbgEcom::SbgEcom(const char *device_name, uint32_t baudrate, const char *config_file, const char *config_string): + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device_name)), + _baudrate(baudrate), + _config_file(config_file), + _config_string(config_string) +{ + if (device_name) { + strncpy(_device_name, device_name, sizeof(_device_name) - 1); + _device_name[sizeof(_device_name) - 1] = '\0'; + } + + device::Device::DeviceId device_id{}; + device_id.devid_s.bus_type = device::Device::DeviceBusType_SERIAL; + device_id.devid_s.devtype = DRV_INS_DEVTYPE_SBG; + + set_device_id(device_id.devid); + _px4_accel.set_device_id(device_id.devid); + _px4_gyro.set_device_id(device_id.devid); + _px4_mag.set_device_id(device_id.devid); +} + +SbgEcom::~SbgEcom() +{ + sbgEComClose(&_com_handle); + sbgInterfaceDestroy(&_sbg_interface); + + perf_free(_accel_pub_interval_perf); + perf_free(_gyro_pub_interval_perf); + perf_free(_mag_pub_interval_perf); + perf_free(_gnss_pub_interval_perf); + + perf_free(_attitude_pub_interval_perf); + perf_free(_local_position_pub_interval_perf); + perf_free(_global_position_pub_interval_perf); +} + +void SbgEcom::set_device_id(uint32_t device_id) +{ + _device_id = device_id; +} + +uint32_t SbgEcom::get_device_id() +{ + return _device_id; +} + +SbgErrorCode SbgEcom::getAndPrintProductInfo(SbgEComHandle *handle) +{ + SbgErrorCode error_code; + SbgEComDeviceInfo device_info; + + assert(handle); + + error_code = sbgEComCmdGetInfo(handle, &device_info); + + if (error_code == SBG_NO_ERROR) { + char calib_version_str[32]; + char hw_revision_str[32]; + char fmw_version_str[32]; + + sbgVersionToStringEncoded(device_info.calibationRev, calib_version_str, sizeof(calib_version_str)); + sbgVersionToStringEncoded(device_info.hardwareRev, hw_revision_str, sizeof(hw_revision_str)); + sbgVersionToStringEncoded(device_info.firmwareRev, fmw_version_str, sizeof(fmw_version_str)); + + PX4_INFO(" Serial Number: %09" PRIu32, device_info.serialNumber); + PX4_INFO(" Product Code: %s", device_info.productCode); + PX4_INFO(" Hardware Revision: %s", hw_revision_str); + PX4_INFO(" Firmware Version: %s", fmw_version_str); + PX4_INFO(" Calib. Version: %s", calib_version_str); + + } else { + SBG_LOG_WARNING(error_code, "Unable to retrieve device information"); + } + + return error_code; +} + +void SbgEcom::printLogCallBack(const char *file_name, const char *function_name, uint32_t line, const char *category, + SbgDebugLogType log_type, SbgErrorCode error_code, const char *message) +{ + const char *base_name; + + assert(file_name); + assert(function_name); + assert(category); + assert(message); + + base_name = strrchr(file_name, '/'); + + if (!base_name) { + base_name = file_name; + + } else { + base_name++; + } + + switch (log_type) { + case SBG_DEBUG_LOG_TYPE_DEBUG: + PX4_DEBUG("%s:%" PRIu32 ": %s: %s", base_name, line, function_name, message); + break; + + case SBG_DEBUG_LOG_TYPE_INFO: + PX4_INFO("%s:%" PRIu32 ": %s: %s", base_name, line, function_name, message); + break; + + case SBG_DEBUG_LOG_TYPE_WARNING: + PX4_WARN("%s:%" PRIu32 ": %s: err:%s: %s", base_name, line, function_name, sbgErrorCodeToString(error_code), message); + break; + + case SBG_DEBUG_LOG_TYPE_ERROR: + PX4_ERR("%s:%" PRIu32 ": %s: err:%s: %s", base_name, line, function_name, sbgErrorCodeToString(error_code), message); + break; + } +} + +void SbgEcom::handleLogImuShort(const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + + const float temperature = sbgEComLogImuShortGetTemperature(&ref_sbg_data->imuShort); + + // publish sensor_accel + instance->_px4_accel.update(hrt_absolute_time(), + sbgEComLogImuShortGetDeltaVelocity(&ref_sbg_data->imuShort, 0), + sbgEComLogImuShortGetDeltaVelocity(&ref_sbg_data->imuShort, 1), + sbgEComLogImuShortGetDeltaVelocity(&ref_sbg_data->imuShort, 2)); + instance->_px4_accel.set_error_count(perf_event_count(instance->_comms_errors)); + instance->_px4_accel.set_temperature(temperature); + perf_count(instance->_accel_pub_interval_perf); + + // publish sensor_gyro + instance->_px4_gyro.update(hrt_absolute_time(), + sbgEComLogImuShortGetDeltaAngle(&ref_sbg_data->imuShort, 0), + sbgEComLogImuShortGetDeltaAngle(&ref_sbg_data->imuShort, 1), + sbgEComLogImuShortGetDeltaAngle(&ref_sbg_data->imuShort, 2)); + instance->_px4_gyro.set_error_count(perf_event_count(instance->_comms_errors)); + instance->_px4_gyro.set_temperature(temperature); + perf_count(instance->_gyro_pub_interval_perf); +} + +void SbgEcom::handleLogMag(const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + + // publish sensor_mag + instance->_px4_mag.update(ref_sbg_data->magData.timeStamp, + (ref_sbg_data->magData.magnetometers[0]), + (ref_sbg_data->magData.magnetometers[1]), + (ref_sbg_data->magData.magnetometers[2])); + instance->_px4_mag.set_error_count(perf_event_count(instance->_comms_errors)); + perf_count(instance->_mag_pub_interval_perf); +} + +void SbgEcom::updateEstimatorStatus(uint32_t ekf_status, estimator_status_s *estimator_status) +{ + SbgEComSolutionMode ekf_nav_status = sbgEComLogEkfGetSolutionMode(ekf_status); + + estimator_status->solution_status_flags |= ((ekf_status & SBG_ECOM_SOL_ATTITUDE_VALID) + && (ekf_status & SBG_ECOM_SOL_HEADING_VALID)) ? SBG_ESTIMATOR_ATTITUDE : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_VELOCITY_VALID) ? SBG_ESTIMATOR_VELOCITY_HORIZ : + 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_VELOCITY_VALID) ? SBG_ESTIMATOR_VELOCITY_VERT : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_POSITION_VALID) ? SBG_ESTIMATOR_POS_HORIZ_REL : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_POSITION_VALID) ? SBG_ESTIMATOR_POS_HORIZ_ABS : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_POSITION_VALID) ? SBG_ESTIMATOR_POS_VERT_ABS : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_POSITION_VALID) ? SBG_ESTIMATOR_POS_VERT_AGL : 0; + estimator_status->solution_status_flags |= (ekf_status & SBG_ECOM_SOL_ZUPT_USED) ? SBG_ESTIMATOR_CONST_POS_MODE : 0; + + estimator_status->solution_status_flags |= (ekf_nav_status == SBG_ECOM_SOL_MODE_NAV_POSITION) ? + SBG_ESTIMATOR_PRED_POS_HORIZ_REL : 0; + estimator_status->solution_status_flags |= (ekf_nav_status == SBG_ECOM_SOL_MODE_NAV_POSITION) ? + SBG_ESTIMATOR_PRED_POS_HORIZ_ABS : 0; +} + +void SbgEcom::handleLogEkfQuat(const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + const hrt_abstime time_now_us = hrt_absolute_time(); + + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + + // publish estimator_status + estimator_status_s estimator_status{}; + estimator_status.timestamp = time_now_us; + estimator_status.timestamp_sample = ref_sbg_data->ekfQuatData.timeStamp; + estimator_status.accel_device_id = instance->get_device_id(); + estimator_status.gyro_device_id = instance->get_device_id(); + estimator_status.mag_device_id = instance->get_device_id(); + + instance->updateEstimatorStatus(ref_sbg_data->ekfQuatData.status, &estimator_status); + + instance->_estimator_status_pub.publish(estimator_status); + + // publish attitude + vehicle_attitude_s attitude{}; + + attitude.timestamp = time_now_us; + attitude.timestamp_sample = ref_sbg_data->ekfQuatData.timeStamp; + + attitude.q[0] = ref_sbg_data->ekfQuatData.quaternion[0]; + attitude.q[1] = ref_sbg_data->ekfQuatData.quaternion[1]; + attitude.q[2] = ref_sbg_data->ekfQuatData.quaternion[2]; + attitude.q[3] = ref_sbg_data->ekfQuatData.quaternion[3]; + + instance->_attitude_pub.publish(attitude); + perf_count(instance->_attitude_pub_interval_perf); + + matrix::Quatf q{attitude.q}; + instance->_heading = matrix::Eulerf{q}.psi(); +} + +void SbgEcom::handleLogEkfNav(const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + const hrt_abstime time_now_us = hrt_absolute_time(); + + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + + // publish estimator_status + estimator_status_s estimator_status{}; + estimator_status.timestamp = time_now_us; + estimator_status.timestamp_sample = ref_sbg_data->ekfNavData.timeStamp; + + instance->updateEstimatorStatus(ref_sbg_data->ekfNavData.status, &estimator_status); + + instance->_estimator_status_pub.publish(estimator_status); + + SbgEComSolutionMode ekf_nav_status = sbgEComLogEkfGetSolutionMode(ref_sbg_data->ekfNavData.status); + + // don't publish local and global positions if not reliable + if (ekf_nav_status != SBG_ECOM_SOL_MODE_NAV_POSITION) { + return; + } + + const double latitude = ref_sbg_data->ekfNavData.position[0]; + const double longitude = ref_sbg_data->ekfNavData.position[1]; + const double altitude = ref_sbg_data->ekfNavData.position[2]; + + const double north_velocity = ref_sbg_data->ekfNavData.velocity[0]; + const double east_velocity = ref_sbg_data->ekfNavData.velocity[1]; + const double down_velocity = ref_sbg_data->ekfNavData.velocity[2]; + + if (!instance->_pos_ref.isInitialized()) { + instance->_pos_ref.initReference(latitude, longitude, time_now_us); + instance->_gps_alt_ref = altitude; + } + + const Vector2f pos_ned = instance->_pos_ref.project(latitude, longitude); + + // publish local_position + vehicle_local_position_s local_position{}; + + local_position.timestamp = time_now_us; + local_position.timestamp_sample = ref_sbg_data->ekfNavData.timeStamp; + + local_position.xy_valid = math::isFinite(latitude) && math::isFinite(longitude); + local_position.z_valid = math::isFinite(altitude); + local_position.v_xy_valid = math::isFinite(north_velocity) && math::isFinite(east_velocity); + local_position.v_z_valid = math::isFinite(down_velocity); + + local_position.x = pos_ned(0); + local_position.y = pos_ned(1); + local_position.z = -(altitude - instance->_gps_alt_ref); + + local_position.vx = north_velocity; + local_position.vy = east_velocity; + local_position.vz = down_velocity; + + local_position.heading = instance->_heading; + local_position.heading_good_for_control = true;; + + if (instance->_pos_ref.isInitialized()) { + local_position.xy_global = true; + local_position.z_global = true; + local_position.ref_timestamp = instance->_pos_ref.getProjectionReferenceTimestamp(); + local_position.ref_lat = instance->_pos_ref.getProjectionReferenceLat(); + local_position.ref_lon = instance->_pos_ref.getProjectionReferenceLon(); + local_position.ref_alt = instance->_gps_alt_ref; + } + + local_position.dist_bottom_valid = false; + + local_position.eph = sqrt(pow(ref_sbg_data->ekfNavData.positionStdDev[0], 2) + + pow(ref_sbg_data->ekfNavData.positionStdDev[1], 2)); + local_position.epv = ref_sbg_data->ekfNavData.positionStdDev[2]; + local_position.evh = sqrt(pow(ref_sbg_data->ekfNavData.velocityStdDev[0], 2) + + pow(ref_sbg_data->ekfNavData.velocityStdDev[1], 2)); + local_position.evv = ref_sbg_data->ekfNavData.velocityStdDev[2]; + + + local_position.dead_reckoning = false; + + local_position.vxy_max = INFINITY; + local_position.vz_max = INFINITY; + local_position.hagl_min = INFINITY; + local_position.hagl_max_xy = INFINITY; + local_position.hagl_max_z = INFINITY; + + instance->_local_position_pub.publish(local_position); + perf_count(instance->_local_position_pub_interval_perf); + + // publish global_position + vehicle_global_position_s global_position{}; + + global_position.timestamp = time_now_us; + global_position.timestamp_sample = ref_sbg_data->ekfNavData.timeStamp; + + global_position.lat = latitude; + global_position.lon = longitude; + global_position.alt = altitude; + global_position.alt_ellipsoid = ref_sbg_data->ekfNavData.undulation; + + global_position.lat_lon_valid = math::isFinite(latitude) && math::isFinite(longitude); + global_position.alt_valid = math::isFinite(altitude); + + global_position.eph = sqrt(pow(ref_sbg_data->ekfNavData.positionStdDev[0], 2) + + pow(ref_sbg_data->ekfNavData.positionStdDev[1], 2)); + global_position.epv = ref_sbg_data->ekfNavData.positionStdDev[2]; + + global_position.dead_reckoning = false; + + instance->_global_position_pub.publish(global_position); + perf_count(instance->_global_position_pub_interval_perf); +} + +void SbgEcom::handleLogGnssPosVelHdt(SbgEComMsgId msg, const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + const hrt_abstime time_now_us = hrt_absolute_time(); + uint8_t type; + uint8_t state; + uint8_t spoofing; + + assert(msg); + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + GnssData *gnss_data = &instance->gnss_data; + + // Store the data based on its type + switch (msg) { + case SBG_ECOM_LOG_GPS1_POS: + gnss_data->gps_pos = ref_sbg_data->gpsPosData; + gnss_data->pos_received = true; + gnss_data->pos_timestamp = time_now_us; + break; + + case SBG_ECOM_LOG_GPS1_VEL: + gnss_data->gps_vel = ref_sbg_data->gpsVelData; + gnss_data->vel_received = true; + gnss_data->vel_timestamp = time_now_us; + break; + + case SBG_ECOM_LOG_GPS1_HDT: + gnss_data->gps_hdt = ref_sbg_data->gpsHdtData; + gnss_data->hdt_received = true; + gnss_data->hdt_timestamp = time_now_us; + break; + } + + if (gnss_data->pos_received && gnss_data->vel_received && gnss_data->hdt_received) { + // publish sensor_gps + sensor_gps_s sensor_gps{}; + + sensor_gps.timestamp = time_now_us; + sensor_gps.timestamp_sample = gnss_data->gps_pos.timeStamp; + + sensor_gps.device_id = instance->get_device_id(); + + sensor_gps.latitude_deg = gnss_data->gps_pos.latitude; + sensor_gps.longitude_deg = gnss_data->gps_pos.longitude; + sensor_gps.altitude_msl_m = gnss_data->gps_pos.altitude; + sensor_gps.altitude_ellipsoid_m = gnss_data->gps_pos.undulation; + + sensor_gps.s_variance_m_s = sqrt(pow(gnss_data->gps_vel.velocityAcc[0], 2) + + pow(gnss_data->gps_vel.velocityAcc[1], 2) + + pow(gnss_data->gps_vel.velocityAcc[2], 2)); + sensor_gps.c_variance_rad = math::radians(gnss_data->gps_vel.courseAcc); + + type = sbgEComLogGnssPosGetType(&gnss_data->gps_pos); + + switch (type) { + case SBG_ECOM_GNSS_POS_TYPE_NO_SOLUTION: + sensor_gps.fix_type = 0; + break; + + case SBG_ECOM_GNSS_POS_TYPE_PSRDIFF: + case SBG_ECOM_GNSS_POS_TYPE_SBAS: + sensor_gps.fix_type = 4; + break; + + case SBG_ECOM_GNSS_POS_TYPE_RTK_FLOAT: + sensor_gps.fix_type = 5; + break; + + case SBG_ECOM_GNSS_POS_TYPE_RTK_INT: + sensor_gps.fix_type = 6; + break; + + case SBG_ECOM_GNSS_POS_TYPE_FIXED: + sensor_gps.fix_type = 7; + break; + + case SBG_ECOM_GNSS_POS_TYPE_PPP_FLOAT: + case SBG_ECOM_GNSS_POS_TYPE_PPP_INT: + sensor_gps.fix_type = 8; + break; + + default: + sensor_gps.fix_type = 3; + break; + } + + sensor_gps.eph = sqrt(pow(gnss_data->gps_pos.longitudeAccuracy, 2) + + pow(gnss_data->gps_pos.latitudeAccuracy, 2)); + sensor_gps.epv = gnss_data->gps_pos.altitudeAccuracy; + + state = sbgEComLogGnssPosGetIfmStatus(&gnss_data->gps_pos); + + switch (state) { + case SBG_ECOM_GNSS_IFM_STATUS_UNKNOWN: + sensor_gps.jamming_state = 0; + break; + + case SBG_ECOM_GNSS_IFM_STATUS_CLEAN: + sensor_gps.jamming_state = 1; + break; + + case SBG_ECOM_GNSS_IFM_STATUS_MITIGATED: + sensor_gps.jamming_state = 2; + break; + + case SBG_ECOM_GNSS_IFM_STATUS_CRITICAL: + sensor_gps.jamming_state = 3; + break; + } + + spoofing = sbgEComLogGnssPosGetSpoofingStatus(&gnss_data->gps_pos); + + switch (spoofing) { + case SBG_ECOM_GNSS_SPOOFING_STATUS_UNKNOWN: + sensor_gps.spoofing_state = 0; + break; + + case SBG_ECOM_GNSS_SPOOFING_STATUS_CLEAN: + sensor_gps.spoofing_state = 1; + break; + + case SBG_ECOM_GNSS_SPOOFING_STATUS_SINGLE: + sensor_gps.spoofing_state = 2; + break; + + case SBG_ECOM_GNSS_SPOOFING_STATUS_MULTIPLE: + sensor_gps.spoofing_state = 3; + break; + } + + sensor_gps.vel_m_s = sqrt(pow(gnss_data->gps_vel.velocity[0], 2) + + pow(gnss_data->gps_vel.velocity[1], 2) + + pow(gnss_data->gps_vel.velocity[2], 2)); + sensor_gps.vel_n_m_s = gnss_data->gps_vel.velocity[0]; + sensor_gps.vel_e_m_s = gnss_data->gps_vel.velocity[1]; + sensor_gps.vel_d_m_s = gnss_data->gps_vel.velocity[2]; + sensor_gps.vel_ned_valid = true; + + sensor_gps.cog_rad = math::radians(gnss_data->gps_vel.course); + + sensor_gps.timestamp_time_relative = sensor_gps.timestamp_sample - time_now_us; + sensor_gps.time_utc_usec = 0; + + sensor_gps.satellites_used = gnss_data->gps_pos.numSvUsed; + + sensor_gps.heading = math::radians(gnss_data->gps_hdt.heading); + sensor_gps.heading_offset = math::radians(gnss_data->gps_hdt.pitch); + sensor_gps.heading_accuracy = math::radians(gnss_data->gps_hdt.headingAccuracy); + + // Check timestamp synchronization + const hrt_abstime max_time_diff = 1000000; // Maximum allowed time difference in microseconds (e.g., 1 second) + hrt_abstime pos_time = gnss_data->pos_timestamp; + hrt_abstime vel_time = gnss_data->vel_timestamp; + hrt_abstime hdt_time = gnss_data->hdt_timestamp; + + if (((time_now_us - pos_time) < max_time_diff) && + ((time_now_us - vel_time) < max_time_diff) && + ((time_now_us - hdt_time) < max_time_diff) && + ((pos_time - vel_time) < max_time_diff) && + ((pos_time - hdt_time) < max_time_diff) && + ((vel_time - hdt_time) < max_time_diff)) { + instance->_sensor_gps_pub.publish(sensor_gps); + perf_count(instance->_gnss_pub_interval_perf); + } + + // Reset the flags and timestamps + gnss_data->pos_received = false; + gnss_data->vel_received = false; + gnss_data->hdt_received = false; + + gnss_data->pos_timestamp = 0; + gnss_data->vel_timestamp = 0; + gnss_data->hdt_timestamp = 0; + } +} + +SbgErrorCode SbgEcom::onLogReceived(SbgEComHandle *handle, SbgEComClass msg_class, SbgEComMsgId msg, + const SbgEComLogUnion *ref_sbg_data, void *user_arg) +{ + SBG_UNUSED_PARAMETER(handle); + + assert(msg_class); + assert(msg); + assert(ref_sbg_data); + assert(user_arg); + + SbgEcom *instance = static_cast(user_arg); + + if (msg_class == SBG_ECOM_CLASS_LOG_ECOM_0) { + int32_t mode; + int32_t ekf2_en; + param_get(param_find("SBG_MODE"), &mode); + param_get(param_find("EKF2_EN"), &ekf2_en); + + bool ekf_failure = (ekf2_en && mode == SBG_MODE_INS); + + if (!instance->_ekf_failure && ekf_failure) { + PX4_WARN("Both SBG EKF and EKF2 are configured, this can lead to an unexpected behaviour"); + instance->_ekf_failure = true; + + } else if (instance->_ekf_failure && !ekf_failure) { + PX4_INFO("EKF management is back to good"); + instance->_ekf_failure = false; + } + + switch (msg) { + case SBG_ECOM_LOG_IMU_SHORT: + instance->handleLogImuShort(ref_sbg_data, user_arg); + break; + + case SBG_ECOM_LOG_MAG: + instance->handleLogMag(ref_sbg_data, user_arg); + break; + + case SBG_ECOM_LOG_GPS1_POS: + case SBG_ECOM_LOG_GPS1_VEL: + case SBG_ECOM_LOG_GPS1_HDT: + if (mode == SBG_MODE_GNSS || mode == SBG_MODE_INS) { + instance->handleLogGnssPosVelHdt(msg, ref_sbg_data, user_arg); + } + + break; + + case SBG_ECOM_LOG_EKF_QUAT: + if (mode == SBG_MODE_INS) { + instance->handleLogEkfQuat(ref_sbg_data, user_arg); + } + + break; + + case SBG_ECOM_LOG_EKF_NAV: + if (mode == SBG_MODE_INS) { + instance->handleLogEkfNav(ref_sbg_data, user_arg); + } + + break; + + default: + PX4_DEBUG("Received unknown SBG message (class %u, id %u)", msg_class, msg); + break; + } + + } else { + PX4_INFO("Received message from unsupported SBGEcom class %u", msg_class); + } + + return SBG_NO_ERROR; +} + +SbgErrorCode SbgEcom::handleOneLog(SbgEComHandle *handle) +{ + SbgErrorCode error_code; + SbgEComProtocolPayload payload; + uint8_t received_msg; + uint8_t received_msg_class; + + assert(handle); + + sbgEComProtocolPayloadConstruct(&payload); + + perf_begin(_sample_perf); + + error_code = sbgEComProtocolReceive2(&handle->protocolHandle, &received_msg_class, &received_msg, &payload); + + if (error_code == SBG_NO_ERROR) { + if (sbgEComMsgClassIsALog((SbgEComClass)received_msg_class)) { + error_code = sbgEComLogParse((SbgEComClass)received_msg_class, (SbgEComMsgId)received_msg, + sbgEComProtocolPayloadGetBuffer(&payload), sbgEComProtocolPayloadGetSize(&payload), &_log_data); + + if (error_code == SBG_NO_ERROR) { + if (handle->pReceiveLogCallback) { + error_code = handle->pReceiveLogCallback(handle, (SbgEComClass)received_msg_class, (SbgEComMsgId)received_msg, + &_log_data, handle->pUserArg); + } + + sbgEComLogCleanup(&_log_data, (SbgEComClass)received_msg_class, (SbgEComMsgId)received_msg); + + perf_end(_sample_perf); + + } else { + perf_count(_comms_errors); + } + + } else { + PX4_ERR("command received %d", error_code); + } + + } else if (error_code != SBG_NOT_READY) { + PX4_WARN("Invalid frame received %d", error_code); + perf_count(_comms_errors); + } + + sbgEComProtocolPayloadDestroy(&payload); + + return error_code; +} + +SbgErrorCode SbgEcom::sendAirDataLog(SbgEComHandle *handle, SbgEcom *instance) +{ + SbgErrorCode error_code = SBG_NO_ERROR; + SbgEComLogAirData air_data_log; + uint8_t output_buffer[64]; + SbgStreamBuffer output_stream; + + assert(handle); + assert(instance); + + vehicle_air_data_s air_data{}; + + if (instance->_air_data_sub.update(&air_data)) { + memset(&air_data_log, 0x00, sizeof(air_data_log)); + + air_data_log.timeStamp = hrt_absolute_time() - air_data.timestamp; + air_data_log.status |= SBG_ECOM_AIR_DATA_TIME_IS_DELAY; + + air_data_log.pressureAbs = air_data.baro_pressure_pa; + air_data_log.status |= SBG_ECOM_AIR_DATA_PRESSURE_ABS_VALID; + + air_data_log.altitude = air_data.baro_alt_meter; + air_data_log.status |= SBG_ECOM_AIR_DATA_ALTITUDE_VALID; + + air_data_log.airTemperature = air_data.ambient_temperature; + air_data_log.status |= SBG_ECOM_AIR_DATA_TEMPERATURE_VALID; + + differential_pressure_s differential_pressure{}; + + if (instance->_diff_pressure_sub.update(&differential_pressure)) { + air_data_log.pressureDiff = differential_pressure.differential_pressure_pa; + air_data_log.status |= SBG_ECOM_AIR_DATA_PRESSURE_DIFF_VALID; + } + + airspeed_s airspeed{}; + + if (instance->_airspeed_sub.update(&airspeed)) { + air_data_log.trueAirspeed = airspeed.true_airspeed_m_s; + air_data_log.status |= SBG_ECOM_AIR_DATA_AIRPSEED_VALID; + } + + sbgStreamBufferInitForWrite(&output_stream, output_buffer, sizeof(output_buffer)); + + perf_begin(_write_perf); + + error_code = sbgEComLogAirDataWriteToStream(&air_data_log, &output_stream); + + if (error_code == SBG_NO_ERROR) { + error_code = sbgEComProtocolSend(&handle->protocolHandle, SBG_ECOM_CLASS_LOG_ECOM_0, SBG_ECOM_LOG_AIR_DATA, + sbgStreamBufferGetLinkedBuffer(&output_stream), sbgStreamBufferGetLength(&output_stream)); + + if (error_code != SBG_NO_ERROR) { + PX4_ERR("Unable to send the AirData log %d", error_code); + + } else { + perf_end(_write_perf); + } + + } else { + PX4_ERR("Unable to write the AirData payload. %d", error_code); + } + } + + return error_code; +} + +SbgErrorCode SbgEcom::sendMagLog(SbgEComHandle *handle, SbgEcom *instance) +{ + SbgErrorCode error_code = SBG_NO_ERROR; + SbgEComLogMag mag_log; + uint8_t output_buffer[64]; + SbgStreamBuffer output_stream; + + assert(handle); + assert(instance); + + vehicle_magnetometer_s mag{}; + + if (instance->_mag_sub.update(&mag)) { + memset(&mag_log, 0x00, sizeof(mag_log)); + + mag_log.timeStamp = mag.timestamp_sample; + // mag_log.status = 0; // STO: don't know how to set it + + mag_log.magnetometers[0] = mag.magnetometer_ga[0]; + mag_log.magnetometers[1] = mag.magnetometer_ga[1]; + mag_log.magnetometers[2] = mag.magnetometer_ga[2]; + + sbgStreamBufferInitForWrite(&output_stream, output_buffer, sizeof(output_buffer)); + + perf_begin(_write_perf); + + error_code = sbgEComLogMagWriteToStream(&mag_log, &output_stream); + + if (error_code == SBG_NO_ERROR) { + error_code = sbgEComProtocolSend(&handle->protocolHandle, SBG_ECOM_CLASS_LOG_ECOM_0, SBG_ECOM_LOG_MAG, + sbgStreamBufferGetLinkedBuffer(&output_stream), sbgStreamBufferGetLength(&output_stream)); + + if (error_code != SBG_NO_ERROR) { + PX4_ERR("Unable to send the Mag log %d", error_code); + + } else { + perf_end(_write_perf); + } + + } else { + PX4_ERR("Unable to write the Mag payload. %d", error_code); + } + } + + return error_code; +} + +void SbgEcom::send_config(SbgEComHandle *pHandle, const char *config) +{ + SbgEComCmdApiReply reply; + + assert(pHandle); + assert(config); + + sbgEComCmdApiReplyConstruct(&reply); + + sbgEComCmdApiPost(pHandle, "/api/v1/settings", NULL, config, &reply); + + if (!sbgEComCmdApiReplySuccessful(&reply)) { + PX4_ERR("Fail to apply SBG configuration: %s", reply.pContent); + + } else { + bool need_reboot = (strstr(reply.pContent, NEED_REBOOT_STR) != NULL); + sbgEComCmdApiPost(pHandle, "/api/v1/settings/save", NULL, NULL, &reply); + + if (need_reboot) { + PX4_INFO("Reboot SBG device"); + sbgEComCmdApiPost(pHandle, "/api/v1/system/reboot", NULL, NULL, &reply); + } + } + + sbgEComCmdApiReplyDestroy(&reply); +} + +void SbgEcom::send_config_file(SbgEComHandle *pHandle, const char *file_path) +{ + int fd; + char *body = NULL; + struct stat s; + + assert(pHandle); + assert(file_path); + + fd = open(file_path, O_RDONLY); + + if (fd == -1) { + PX4_ERR("Failed to open config"); + return; + } + + fstat(fd, &s); + body = (char *)malloc(s.st_size + 1); + + if (!body) { + PX4_ERR("Failed to allocate memory (%ld) - %s", s.st_size + 1, strerror(get_errno())); + close(fd); + return; + } + + read(fd, body, s.st_size); + body[s.st_size] = '\0'; + + send_config(pHandle, body); + + free(body); + + if (close(fd) == -1) { + perror("Error closing the file"); + return; + } +} + +int SbgEcom::init() +{ + SbgErrorCode error_code; + struct termios options; + int *pSerialHandle; + + error_code = sbgInterfaceSerialCreate(&_sbg_interface, _device_name, _baudrate); + + if (error_code == SBG_NO_ERROR) { + PX4_INFO("Serial interface created successfully on port: %s, baudrate: %ld", _device_name, _baudrate); + } + + pSerialHandle = (int *)_sbg_interface.handle; + + if (tcgetattr((*pSerialHandle), &options) != -1) { + // add custom options + options.c_cflag &= CSIZE; + options.c_iflag &= ~(IXON | IXOFF | IXANY); + options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | ICRNL | INPCK); + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | ECHONL | IEXTEN); + + if (tcsetattr((*pSerialHandle), TCSANOW, &options) != -1) { + error_code = sbgInterfaceFlush(&_sbg_interface, SBG_IF_FLUSH_ALL); + + } else { + error_code = SBG_ERROR; + } + + } else { + error_code = SBG_ERROR; + } + + error_code = sbgEComInit(&_com_handle, &_sbg_interface); + // Increase sbgECom timeout for the initialization + sbgEComSetCmdTrialsAndTimeOut(&_com_handle, 3, 5000); + + if (error_code == SBG_NO_ERROR) { + int32_t ins_config_enable; + param_get(param_find("SBG_CONFIGURE_EN"), &ins_config_enable); + + getAndPrintProductInfo(&_com_handle); + + if (ins_config_enable) { + if (_config_string != nullptr) { + PX4_INFO("Apply config string instead of config file"); + send_config(&_com_handle, _config_string); + + } else { + send_config_file(&_com_handle, _config_file); + } + } + + // Reset sbgECom timeout to its defaut value + sbgEComSetCmdTrialsAndTimeOut(&_com_handle, 3, SBG_ECOM_DEFAULT_CMD_TIME_OUT); + sbgEComSetReceiveLogCallback(&_com_handle, onLogReceived, this); + return PX4_OK; + + } else { + PX4_ERR("sbgECom initialization failed (%d)", error_code); + return PX4_ERROR; + } +} + +void SbgEcom::Run() +{ + if (should_exit()) { + ScheduleClear(); + exit_and_cleanup(); + return; + } + + if (!_initialized) { + init_result = init(); + _initialized = true; + } + + if (init_result == PX4_OK) { + SbgErrorCode error_code; + + error_code = handleOneLog(&_com_handle); + + if (error_code == SBG_NO_ERROR) { + ScheduleDelayed(time_literals::operator ""_ms(0)); + + if (failure) { + assert(iteration_count >= 0); + iteration_count--; + failure = false; + } + + } else if (error_code != SBG_NOT_READY) { + PX4_ERR("Unable to process incoming sbgECom logs %d", error_code); + } + + if (error_code != SBG_NO_ERROR) { + ScheduleDelayed(time_literals::operator ""_ms(1)); + failure = true; + } + + error_code = sendAirDataLog(&_com_handle, this); + + if (error_code != SBG_NO_ERROR) { + PX4_WARN("Unable to send AirData log %d", error_code); + } + + error_code = sendMagLog(&_com_handle, this); + + if (error_code != SBG_NO_ERROR) { + PX4_WARN("Unable to send Mag log %d", error_code); + } + } +} + +int SbgEcom::task_spawn(int argc, char **argv) +{ + sbgCommonLibSetLogCallback(printLogCallBack); + + bool error_flag = false; + + const char *myoptarg = nullptr; + int myoptind = 1; + int ch; + + int32_t baudrate; + param_get(param_find("SBG_BAUDRATE"), &baudrate); + const char *dev_name = DEFAULT_DEVNAME; + const char *config_file = DEFAULT_CONFIG_PATH; + + /* INS settings can be overwritten from the SD card */ + if (access(OVERRIDE_CONFIG_PATH, F_OK) == 0) { + config_file = OVERRIDE_CONFIG_PATH; + + } else { + config_file = DEFAULT_CONFIG_PATH; + } + + const char *config_string = nullptr; + + while ((ch = px4_getopt(argc, argv, "b:d:f:s:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'b': + baudrate = atoi(myoptarg); + break; + + case 'd': + dev_name = myoptarg; + break; + + case 'f': + config_file = myoptarg; + break; + + case 's': + config_string = myoptarg; + break; + + case '?': + PX4_WARN("unrecognized flag ?"); + error_flag = true; + break; + + default: + PX4_WARN("unrecognized flag"); + error_flag = true; + break; + } + } + + if (error_flag) { + return -1; + } + + if (dev_name && (access(dev_name, R_OK | W_OK) == 0)) { + SbgEcom *instance = new SbgEcom(dev_name, baudrate, config_file, config_string); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _task_id = task_id_is_work_queue; + _object.store(instance); + instance->ScheduleNow(); + return PX4_OK; + + } else { + if (dev_name) { + PX4_ERR("invalid device (-d) %s", dev_name); + + } else { + PX4_ERR("valid device required"); + } + } + + return PX4_ERROR; +} + +int SbgEcom::custom_command(int argc, char **argv) +{ + return print_usage("unrecognized command"); +} + +int SbgEcom::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION("Description du module"); + + PRINT_MODULE_USAGE_NAME("sbgecom", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("ins"); + PRINT_MODULE_USAGE_COMMAND_DESCR("start", "Start driver"); + PRINT_MODULE_USAGE_PARAM_STRING('d', DEFAULT_DEVNAME, nullptr, "Serial device", true); + PRINT_MODULE_USAGE_PARAM_INT('b', 921600, 9600, 921600, "Baudrate device", true); + PRINT_MODULE_USAGE_PARAM_STRING('f', DEFAULT_CONFIG_PATH, nullptr, "Config JSON file path", true); + PRINT_MODULE_USAGE_PARAM_STRING('s', nullptr, nullptr, "Config JSON string", true); + PRINT_MODULE_USAGE_COMMAND_DESCR("status", "Driver status"); + PRINT_MODULE_USAGE_COMMAND_DESCR("stop", "Stop driver"); + + return PX4_OK; +} + +int SbgEcom::print_status() +{ + printf("Using port '%s'\n", _device_name); + + perf_print_counter(_sample_perf); + perf_print_counter(_write_perf); + perf_print_counter(_comms_errors); + + return 0; +} + +extern "C" __EXPORT int sbgecom_main(int argc, char **argv) +{ + return SbgEcom::main(argc, argv); +} diff --git a/src/drivers/ins/sbgecom/sbgecom.hpp b/src/drivers/ins/sbgecom/sbgecom.hpp new file mode 100644 index 0000000000..332f8def2c --- /dev/null +++ b/src/drivers/ins/sbgecom/sbgecom.hpp @@ -0,0 +1,294 @@ +/**************************************************************************** + * + * Copyright (c) 2012-2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file sbgecom.hpp + * Driver for the SBG Systems products + * + * @author SBG Systems + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SbgEcom : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + + SbgEcom(const char *port, uint32_t baudrate, const char *config_file, const char *config_string); + ~SbgEcom() override; + + /** @see ModuleBase */ + static int task_spawn(int argc, char **argv); + + /** @see ModuleBase */ + static int custom_command(int argc, char **argv); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase */ + int print_status() override; + + /** @see ModuleBase::run() */ + void Run() override; + + int init(); + +private: + + /** + * @brief Type for logging functions. + * + * @param file_name File name where the error occurred. + * @param function_name Function name where the error occurred. + * @param line Line number where the error occurred. + * @param category Category for this log or "None" if no category has been specified. + * @param log_type Define if we have an error, a warning, an info or a debug log. + * @param error_code The error code associated with the message. + * @param message The message to log. + */ + static void printLogCallBack(const char *file_name, const char *function_name, uint32_t line, const char *category, + SbgDebugLogType log_type, SbgErrorCode error_code, const char *message); + + /** + * @brief Parse IMU (Inertial Measurement Unit) measurement logs. + * + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + */ + static void handleLogImuShort(const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief Parse magnetic field measurements logs. + * + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + */ + static void handleLogMag(const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief Parse EKF quaternion measurement logs. + * + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + */ + static void handleLogEkfQuat(const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief Parse EKF navigation measurement logs. + * + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + */ + static void handleLogEkfNav(const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief GNSS position, velocity and heading related logs. + * + * @param msg Message ID of the log received. + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + */ + static void handleLogGnssPosVelHdt(SbgEComMsgId msg, const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief Update estimator status message from EKF status flags. + * + * @param ekf_status EKF status flags. + * @param estimator_status Estimator status message. + */ + static void updateEstimatorStatus(uint32_t ekf_status, estimator_status_s *estimator_status); + + /** + * @brief Callback definition called each time a new log is received. + * + * @param handle Valid handle on the sbgECom instance that has called this callback. + * @param msg_class Class of the message we have received + * @param msg Message ID of the log received. + * @param ref_sbg_data Contains the received log data as an union. + * @param user_arg Optional user supplied argument. + * @return SBG_NO_ERROR if the received log has been used successfully. + */ + static SbgErrorCode onLogReceived(SbgEComHandle *handle, SbgEComClass msg_class, SbgEComMsgId msg, + const SbgEComLogUnion *ref_sbg_data, void *user_arg); + + /** + * @brief Send a config to the INS + * + * @param pHandle SbgECom instance. + * @param config Config json string. + */ + static void send_config(SbgEComHandle *pHandle, const char *config); + + /** + * @brief Send a config file to the INS + * + * @param pHandle SbgECom instance. + * @param file_path Config file path. + */ + static void send_config_file(SbgEComHandle *pHandle, const char *file_path); + + /** + * @brief Get and print product info. + * + * @param handle SbgECom instance. + * @return SBG_NO_ERROR if successful. + */ + SbgErrorCode getAndPrintProductInfo(SbgEComHandle *handle); + + /** + * @brief Try to parse one log from the input interface and then return. + * + * @param handle A valid sbgECom handle. + * @return SBG_NO_ERROR if no error occurs during incoming log parsing. + */ + SbgErrorCode handleOneLog(SbgEComHandle *handle); + + /** + * @brief Get air data and send it. + * + * @param handle A valid sbgECom handle. + * @param instance An SbgEcom object. + * @return SBG_NO_ERROR if no error occurs during incoming log parsing. + */ + SbgErrorCode sendAirDataLog(SbgEComHandle *handle, SbgEcom *instance); + + /** + * @brief Get magnetometer data and send it. + * + * @param handle A valid sbgECom handle. + * @param instance An SbgEcom object. + * @return SBG_NO_ERROR if no error occurs during incoming log parsing. + */ + SbgErrorCode sendMagLog(SbgEComHandle *handle, SbgEcom *instance); + + void set_device_id(uint32_t device_id); + uint32_t get_device_id(void); + + // SBG interface and state variables + SbgInterface _sbg_interface; + SbgEComHandle _com_handle; + SbgEComLogUnion _log_data; + + uint32_t _baudrate; + const char *_config_file; + const char *_config_string; + char _device_name[25]; + uint32_t _device_id{0}; + + const int log_interval = 10; + int iteration_count = log_interval; + + bool failure = false; + bool _ekf_failure = false; + + bool _initialized = false; + int init_result; + + MapProjection _pos_ref{}; + double _gps_alt_ref{NAN}; + + struct GnssData { + bool pos_received = false; + bool vel_received = false; + bool hdt_received = false; + + SbgEComLogGnssPos gps_pos; + SbgEComLogGnssVel gps_vel; + SbgEComLogGnssHdt gps_hdt; + + hrt_abstime pos_timestamp = 0; + hrt_abstime vel_timestamp = 0; + hrt_abstime hdt_timestamp = 0; + }; + + GnssData gnss_data; + float _heading; + + px4::atomic _time_last_valid_imu_us{false}; + + // Sensors topics + PX4Accelerometer _px4_accel{0}; + PX4Gyroscope _px4_gyro{0}; + PX4Magnetometer _px4_mag{0}; + + // Publications with topic dependent on multi-mode + uORB::PublicationMulti _sensor_gps_pub{ORB_ID(sensor_gps)}; + uORB::PublicationMulti _attitude_pub{ORB_ID(vehicle_attitude)}; + uORB::PublicationMulti _local_position_pub{ORB_ID(vehicle_local_position)}; + uORB::PublicationMulti _global_position_pub{ORB_ID(vehicle_global_position)}; + uORB::Publication _estimator_status_pub{ORB_ID(estimator_status)}; + + // Subscription for INS EKF aiding + uORB::Subscription _air_data_sub{ORB_ID(vehicle_air_data)}; + uORB::Subscription _airspeed_sub{ORB_ID(airspeed)}; + uORB::Subscription _diff_pressure_sub{ORB_ID(differential_pressure)}; + uORB::Subscription _mag_sub{ORB_ID(vehicle_magnetometer)}; + + // Performance mounters for monitoring and debugging + perf_counter_t _comms_errors{perf_alloc(PC_COUNT, MODULE_NAME": errors")}; + perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": sample")}; + perf_counter_t _write_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": write")}; + + perf_counter_t _accel_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": accel publish interval")}; + perf_counter_t _gyro_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": gyro publish interval")}; + perf_counter_t _mag_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": mag publish interval")}; + perf_counter_t _gnss_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": GNSS publish interval")}; + + perf_counter_t _attitude_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": attitude publish interval")}; + perf_counter_t _local_position_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": local position publish interval")}; + perf_counter_t _global_position_pub_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": global position publish interval")}; +}; diff --git a/src/drivers/ins/vectornav/VectorNav.cpp b/src/drivers/ins/vectornav/VectorNav.cpp index e4e9821d47..0e6877a555 100644 --- a/src/drivers/ins/vectornav/VectorNav.cpp +++ b/src/drivers/ins/vectornav/VectorNav.cpp @@ -273,11 +273,11 @@ void VectorNav::sensorCallback(VnUartPacket *packet) const double lat = positionEstimatedLla.c[0]; const double lon = positionEstimatedLla.c[1]; - const float alt = positionEstimatedLla.c[2]; + const float alt_ellipsoid = positionEstimatedLla.c[2]; if (!_pos_ref.isInitialized()) { _pos_ref.initReference(lat, lon, time_now_us); - _gps_alt_ref = alt; + _gps_alt_ref = alt_ellipsoid; } const Vector2f pos_ned = _pos_ref.project(lat, lon); @@ -292,7 +292,7 @@ void VectorNav::sensorCallback(VnUartPacket *packet) local_position.x = pos_ned(0); local_position.y = pos_ned(1); - local_position.z = -(alt - _gps_alt_ref); + local_position.z = -(alt_ellipsoid - _gps_alt_ref); local_position.vx = velocityEstimatedNed.c[0]; local_position.vy = velocityEstimatedNed.c[1]; @@ -342,8 +342,10 @@ void VectorNav::sensorCallback(VnUartPacket *packet) global_position.timestamp_sample = time_now_us; global_position.lat = lat; global_position.lon = lon; - global_position.alt = alt; - global_position.alt = alt; + global_position.lat_lon_valid = true; + global_position.alt = alt_ellipsoid; // AMSL altitude is not available + global_position.alt_ellipsoid = alt_ellipsoid; + global_position.alt_valid = true; global_position.eph = positionUncertaintyEstimated; global_position.epv = positionUncertaintyEstimated; diff --git a/src/drivers/magnetometer/bosch/bmm350/BMM350.cpp b/src/drivers/magnetometer/bosch/bmm350/BMM350.cpp index 83f43a962b..65b2299268 100755 --- a/src/drivers/magnetometer/bosch/bmm350/BMM350.cpp +++ b/src/drivers/magnetometer/bosch/bmm350/BMM350.cpp @@ -590,13 +590,13 @@ int BMM350::ReadOutRawData(float *out_data) return -1; } - float temp = 0.0; struct BMM350::raw_mag_data raw_data = {0}; // --- Start read_uncomp_mag_temp_data uint8_t mag_data[14] = {0}; uint32_t raw_mag_x, raw_mag_y, raw_mag_z, raw_temp; + uint8_t cmd = static_cast(Register::DATAX_XLSB); uint8_t res = transfer(&cmd, 1, (uint8_t *)&mag_data, sizeof(mag_data)); @@ -623,17 +623,7 @@ int BMM350::ReadOutRawData(float *out_data) out_data[3] = (float)raw_data.raw_t * lsb_to_utc_degc[3]; // Adjust temperature - if (out_data[3] > 0.0f) { - temp = (float)(out_data[3] - (1 * 25.49f)); - - } else if (out_data[3] < 0.0f) { - temp = (float)(out_data[3] - (-1 * 25.49f)); - - } else { - temp = (float)(out_data[3]); - } - - out_data[3] = temp; + out_data[3] = (float)(out_data[3] - (1 * 25.49f)); return res; } diff --git a/src/drivers/magnetometer/isentek/ist8310/IST8310.cpp b/src/drivers/magnetometer/isentek/ist8310/IST8310.cpp index a0cc3fabe1..3edf4e27b7 100644 --- a/src/drivers/magnetometer/isentek/ist8310/IST8310.cpp +++ b/src/drivers/magnetometer/isentek/ist8310/IST8310.cpp @@ -94,9 +94,11 @@ int IST8310::probe() while (hrt_elapsed_time(&start_time) < 50_ms) { set_device_address(start_addr); - const int WAI = RegisterRead(Register::WAI); - if (WAI == Device_ID) { + const uint8_t wai = RegisterRead(Register::WAI); + + if ((wai == IST8310_Device_ID) || (wai == IST8310J_Device_ID)) { + // Device has the right I2C address and register content return PX4_OK; } @@ -128,30 +130,31 @@ void IST8310::RunImpl() ScheduleDelayed(50_ms); // Power On Reset: max 50ms break; - case STATE::WAIT_FOR_RESET: + case STATE::WAIT_FOR_RESET: { + // SRST: This bit is automatically reset to zero after POR routine + const uint8_t wai = RegisterRead(Register::WAI); - // SRST: This bit is automatically reset to zero after POR routine - if ((RegisterRead(Register::WAI) == Device_ID) - && ((RegisterRead(Register::CNTL2) & CNTL2_BIT::SRST) == 0)) { - - // if reset succeeded then configure - _state = STATE::CONFIGURE; - ScheduleDelayed(10_ms); - - } else { - // RESET not complete - if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { - PX4_DEBUG("Reset failed, retrying"); - _state = STATE::RESET; - ScheduleDelayed(100_ms); + if (((wai == IST8310_Device_ID) || (wai == IST8310J_Device_ID)) + && ((RegisterRead(Register::CNTL2) & CNTL2_BIT::SRST) == 0)) { + // if reset succeeded then configure + _state = STATE::CONFIGURE; + ScheduleDelayed(10_ms); } else { - PX4_DEBUG("Reset not complete, check again in 10 ms"); - ScheduleDelayed(10_ms); - } - } + // RESET not complete + if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { + PX4_DEBUG("Reset failed, retrying"); + _state = STATE::RESET; + ScheduleDelayed(100_ms); - break; + } else { + PX4_DEBUG("Reset not complete, check again in 10 ms"); + ScheduleDelayed(10_ms); + } + } + + break; + } case STATE::CONFIGURE: if (Configure()) { diff --git a/src/drivers/magnetometer/isentek/ist8310/iSentek_IST8310_registers.hpp b/src/drivers/magnetometer/isentek/ist8310/iSentek_IST8310_registers.hpp index 2a49ee03e9..d2b7563752 100644 --- a/src/drivers/magnetometer/isentek/ist8310/iSentek_IST8310_registers.hpp +++ b/src/drivers/magnetometer/isentek/ist8310/iSentek_IST8310_registers.hpp @@ -57,7 +57,8 @@ namespace iSentek_IST8310 static constexpr uint32_t I2C_SPEED = 400 * 1000; // 400 kHz I2C serial interface static constexpr uint8_t I2C_ADDRESS_DEFAULT = 0x0E; -static constexpr uint8_t Device_ID = 0x10; +static constexpr uint8_t IST8310_Device_ID = 0x10; +static constexpr uint8_t IST8310J_Device_ID = 0xA3; enum class Register : uint8_t { WAI = 0x00, // Who Am I Register diff --git a/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp b/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp index b0d9693b19..e508e8863e 100644 --- a/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp +++ b/src/drivers/magnetometer/qmc5883p/QMC5883P.cpp @@ -244,6 +244,8 @@ void QMC5883P::RunImpl() bool QMC5883P::Configure() { + RegisterWrite(Register::REG_29, 0x06); + // first set and clear all configured register bits for (const auto ®_cfg : _register_cfg) { RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); diff --git a/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp b/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp index 3ad532d0fb..1663fd88f4 100644 --- a/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp +++ b/src/drivers/magnetometer/qmc5883p/QMC5883P.hpp @@ -107,7 +107,7 @@ private: static constexpr uint8_t size_register_cfg{2}; register_config_t _register_cfg[size_register_cfg] { // Register | Set bits, Clear bits - { Register::CNTL1, CNTL1_BIT::MODE_CONTINUOUS | CNTL1_BIT::OSR1_8 | CNTL1_BIT::ODR_50HZ, CNTL1_BIT::OSR2_8}, + { Register::CNTL1, CNTL1_BIT::MODE_CONTINUOUS | CNTL1_BIT::OSR2_4 | CNTL1_BIT::ODR_200HZ, CNTL1_BIT::OSR1_8}, { Register::CNTL2, CNTL2_BIT::RNG_2G, CNTL2_BIT::SOFT_RST | CNTL2_BIT::SELF_TEST}, }; }; diff --git a/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp b/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp index 57fffa6579..ff9428d48d 100644 --- a/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp +++ b/src/drivers/magnetometer/qmc5883p/QST_QMC5883P_registers.hpp @@ -79,6 +79,8 @@ enum class Register : uint8_t { CNTL2 = 0x0B, // Control Register 2 CHIP_ID = 0x00, + + REG_29 = 0x29, }; // STATUS @@ -90,11 +92,11 @@ enum STATUS_BIT : uint8_t { // CNTL1 enum CNTL1_BIT : uint8_t { // OSR2[7:6] - OSR2_8 = Bit7 | Bit6, // 00 + OSR2_4 = Bit7, // 10 // OSR1[5:4] OSR1_8 = Bit5 | Bit4, // 11 // ODR[3:2] - ODR_50HZ = Bit2, // 01 + ODR_200HZ = Bit3 | Bit2, // 11 // MODE[1:0] MODE_CONTINUOUS = Bit1 | Bit0, // 11 }; diff --git a/src/drivers/magnetometer/rm3100/rm3100.h b/src/drivers/magnetometer/rm3100/rm3100.h index 7e4737d48b..3057d98c27 100644 --- a/src/drivers/magnetometer/rm3100/rm3100.h +++ b/src/drivers/magnetometer/rm3100/rm3100.h @@ -91,8 +91,12 @@ #define RM3100_REVID 0x22 /* interface factories */ +#if defined(CONFIG_SPI) extern device::Device *RM3100_SPI_interface(int bus, uint32_t devid, int bus_frequency, spi_mode_e spi_mode); +#endif // CONFIG_SPI +#if defined(CONFIG_I2C) extern device::Device *RM3100_I2C_interface(int bus, int bus_frequency); +#endif // CONFIG_I2C #define RM3100_ADDRESS 0x20 diff --git a/src/drivers/magnetometer/rm3100/rm3100_i2c.cpp b/src/drivers/magnetometer/rm3100/rm3100_i2c.cpp index 3aeba5d57e..9a7826c314 100644 --- a/src/drivers/magnetometer/rm3100/rm3100_i2c.cpp +++ b/src/drivers/magnetometer/rm3100/rm3100_i2c.cpp @@ -39,6 +39,8 @@ #include +#if defined(CONFIG_I2C) + #include #include #include @@ -129,3 +131,5 @@ int RM3100_I2C::write(unsigned address, void *data, unsigned count) return transfer(&buf[0], count + 1, nullptr, 0); } + +#endif // CONFIG_I2C diff --git a/src/drivers/magnetometer/rm3100/rm3100_main.cpp b/src/drivers/magnetometer/rm3100/rm3100_main.cpp index be8571cced..3c3b51060f 100644 --- a/src/drivers/magnetometer/rm3100/rm3100_main.cpp +++ b/src/drivers/magnetometer/rm3100/rm3100_main.cpp @@ -45,12 +45,16 @@ I2CSPIDriverBase *RM3100::instantiate(const I2CSPIDriverConfig &config, int runt { device::Device *interface = nullptr; +#if defined(CONFIG_I2C) + if (config.bus_type == BOARD_I2C_BUS) { interface = RM3100_I2C_interface(config.bus, config.bus_frequency); - } else if (config.bus_type == BOARD_SPI_BUS) { - interface = RM3100_SPI_interface(config.bus, config.spi_devid, config.bus_frequency, config.spi_mode); - } + } else +#endif // CONFIG_I2C + if (config.bus_type == BOARD_SPI_BUS) { + interface = RM3100_SPI_interface(config.bus, config.spi_devid, config.bus_frequency, config.spi_mode); + } if (interface == nullptr) { PX4_ERR("alloc failed"); @@ -93,8 +97,12 @@ extern "C" int rm3100_main(int argc, char *argv[]) using ThisDriver = RM3100; int ch; BusCLIArguments cli{true, true}; +#if defined(CONFIG_I2C) cli.default_i2c_frequency = 400000; +#endif // CONFIG_I2C +#if defined(CONFIG_SPI) cli.default_spi_frequency = 1 * 1000 * 1000; +#endif // CONFIG_SPI while ((ch = cli.getOpt(argc, argv, "R:")) != EOF) { switch (ch) { @@ -111,7 +119,9 @@ extern "C" int rm3100_main(int argc, char *argv[]) return -1; } +#if defined(CONFIG_I2C) cli.i2c_address = RM3100_ADDRESS; +#endif // CONFIG_I2C BusInstanceIterator iterator(MODULE_NAME, cli, DRV_MAG_DEVTYPE_RM3100); diff --git a/src/drivers/magnetometer/rm3100/rm3100_spi.cpp b/src/drivers/magnetometer/rm3100/rm3100_spi.cpp index 3d8f84498a..b9da9f5493 100644 --- a/src/drivers/magnetometer/rm3100/rm3100_spi.cpp +++ b/src/drivers/magnetometer/rm3100/rm3100_spi.cpp @@ -39,6 +39,8 @@ #include +#if defined(CONFIG_SPI) + #include #include #include @@ -135,3 +137,5 @@ int RM3100_SPI::write(unsigned address, void *data, unsigned count) return transfer(&buf[0], &buf[0], count + 1); } + +#endif // CONFIG_SPI diff --git a/src/drivers/osd/atxxxx/atxxxx.cpp b/src/drivers/osd/atxxxx/atxxxx.cpp index a5acabd391..6f85fcd383 100644 --- a/src/drivers/osd/atxxxx/atxxxx.cpp +++ b/src/drivers/osd/atxxxx/atxxxx.cpp @@ -387,6 +387,10 @@ OSDatxxxx::get_flight_mode(uint8_t nav_state) flight_mode = "ALTITUDE"; break; + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: + flight_mode = "CRUISE"; + break; + case vehicle_status_s::NAVIGATION_STATE_POSCTL: flight_mode = "POSITION"; break; diff --git a/src/drivers/osd/msp_osd/uorb_to_msp.cpp b/src/drivers/osd/msp_osd/uorb_to_msp.cpp index 20caca3e38..bb2db04a16 100644 --- a/src/drivers/osd/msp_osd/uorb_to_msp.cpp +++ b/src/drivers/osd/msp_osd/uorb_to_msp.cpp @@ -319,7 +319,7 @@ msp_raw_gps_t construct_RAW_GPS(const sensor_gps_s &vehicle_gps_position, //raw_gps.hdop = vehicle_gps_position_struct.hdop raw_gps.numSat = vehicle_gps_position.satellites_used; - if (airspeed_validated.airspeed_source >= airspeed_validated_s::GROUND_MINUS_WIND + if (airspeed_validated.airspeed_source >= airspeed_validated_s::SOURCE_GROUND_MINUS_WIND && PX4_ISFINITE(airspeed_validated.indicated_airspeed_m_s) && airspeed_validated.indicated_airspeed_m_s > 0.f) { raw_gps.groundSpeed = airspeed_validated.indicated_airspeed_m_s * 100; diff --git a/src/drivers/pca9685_pwm_out/PCA9685.cpp b/src/drivers/pca9685_pwm_out/PCA9685.cpp index 7eccd6c04b..f2a151ef44 100644 --- a/src/drivers/pca9685_pwm_out/PCA9685.cpp +++ b/src/drivers/pca9685_pwm_out/PCA9685.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2019-2022 PX4 Development Team. All rights reserved. + * Copyright (c) 2019-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,61 +57,61 @@ PCA9685::PCA9685(int bus, int addr): int PCA9685::init() { - int ret = I2C::init(); - - if (ret != PX4_OK) { return ret; } + return I2C::init(); +} +int PCA9685::configure() +{ uint8_t buf[2] = {}; buf[0] = PCA9685_REG_MODE1; buf[1] = PCA9685_DEFAULT_MODE1_CFG | PCA9685_MODE1_SLEEP_MASK; // put into sleep mode - ret = transfer(buf, 2, nullptr, 0); - - if (OK != ret) { - PX4_ERR("init: i2c::transfer returned %d", ret); - return ret; - } + int ret = transfer(buf, 2, nullptr, 0); #ifdef CONFIG_PCA9685_USE_EXTERNAL_CRYSTAL + /* EXTCLK is sticky, so writing it once is enough. Its not a problem when its written to 0 later. */ buf[1] = PCA9685_DEFAULT_MODE1_CFG | PCA9685_MODE1_SLEEP_MASK | PCA9685_MODE1_EXTCLK_MASK; - ret = transfer(buf, 2, nullptr, 0); // enable EXTCLK if possible - - if (OK != ret) { - PX4_ERR("init: i2c::transfer returned %d", ret); - return ret; - } - + ret |= transfer(buf, 2, nullptr, 0); #endif buf[0] = PCA9685_REG_MODE2; buf[1] = PCA9685_DEFAULT_MODE2_CFG; - ret = transfer(buf, 2, nullptr, 0); + ret |= transfer(buf, 2, nullptr, 0); + return ret; +} - if (OK != ret) { - PX4_ERR("init: i2c::transfer returned %d", ret); - return ret; +int PCA9685::registers_check() +{ + /* Check MODE1 register */ + uint8_t send_buf = PCA9685_REG_MODE1; + uint8_t recv_buf; + + int ret = transfer(&send_buf, 1, &recv_buf, 1); + uint8_t ignore_extclk_mask = ~PCA9685_MODE1_EXTCLK_MASK; + + if (ret != PX4_OK) { + return -EIO; + } + + if ((recv_buf & ignore_extclk_mask) != (PCA9685_DEFAULT_MODE1_CFG & ignore_extclk_mask)) { + return -EFAULT; + } + + /* Check MODE2 register */ + send_buf = PCA9685_REG_MODE2; + ret = transfer(&send_buf, 1, &recv_buf, 1); + + if (ret != PX4_OK) { + return -EIO; + } + + if (recv_buf != PCA9685_DEFAULT_MODE2_CFG) { + return -EFAULT; } return PX4_OK; } -int PCA9685::updatePWM(const uint16_t *outputs, unsigned num_outputs) -{ - if (num_outputs > PCA9685_PWM_CHANNEL_COUNT) { - num_outputs = PCA9685_PWM_CHANNEL_COUNT; - PX4_DEBUG("PCA9685 can only drive up to 16 channels"); - } - - uint16_t out[PCA9685_PWM_CHANNEL_COUNT]; - memcpy(out, outputs, sizeof(uint16_t) * num_outputs); - - for (unsigned i = 0; i < num_outputs; ++i) { - out[i] = calcRawFromPulse(out[i]); - } - - return writePWM(0, out, num_outputs); -} - int PCA9685::updateFreq(float freq) { uint16_t divider = (uint16_t)round((float)PCA9685_CLOCK_REFERENCE / freq / PCA9685_PWM_RES) - 1; @@ -160,30 +160,47 @@ int PCA9685::sleep() int PCA9685::wake() { - uint8_t buf[2] = { - PCA9685_REG_MODE1, - PCA9685_DEFAULT_MODE1_CFG - }; - return transfer(buf, 2, nullptr, 0); -} + uint8_t send_buf[2]; + uint8_t recv_buf; -int PCA9685::doRestart() -{ - uint8_t buf[2] = { - PCA9685_REG_MODE1, - PCA9685_DEFAULT_MODE1_CFG | PCA9685_MODE1_RESTART_MASK - }; - return transfer(buf, 2, nullptr, 0); + send_buf[0] = PCA9685_REG_MODE1; + int ret = transfer(&send_buf[0], 1, &recv_buf, 1); + + if (ret != PX4_OK) { + return PX4_ERROR; + } + + send_buf[1] = recv_buf & ~PCA9685_MODE1_SLEEP_MASK; // Clear sleep bit + ret |= transfer(&send_buf[0], 2, nullptr, 0); + px4_usleep(500); // wait for oscillator to stabilize + + if (recv_buf & PCA9685_MODE1_RESTART_MASK) { // Check if reset bit is set + send_buf[1] |= PCA9685_MODE1_RESTART_MASK; // Set restart bit + ret |= transfer(&send_buf[0], 2, nullptr, 0); + } + + ret |= transfer(&send_buf[0], 1, &recv_buf, 1); + + if (ret != PX4_OK || recv_buf & (PCA9685_MODE1_RESTART_MASK | PCA9685_MODE1_SLEEP_MASK)) { + return PX4_ERROR; + } + + return ret; } int PCA9685::probe() { - int ret = I2C::probe(); + for (int i = 0; i < 10; i++) { + uint8_t send_buf = PCA9685_REG_MODE1; - if (ret != PX4_OK) { return ret; } + if (transfer(&send_buf, 1, nullptr, 0) == PX4_OK) { + return PX4_OK; + } - uint8_t buf[2] = {0x00}; - return transfer(buf, 2, buf, 1); + px4_usleep(10'000); + } + + return PX4_ERROR; } int PCA9685::writePWM(uint8_t idx, const uint16_t *value, uint8_t num) diff --git a/src/drivers/pca9685_pwm_out/PCA9685.h b/src/drivers/pca9685_pwm_out/PCA9685.h index e8bd5eb4d8..d22b4cec22 100644 --- a/src/drivers/pca9685_pwm_out/PCA9685.h +++ b/src/drivers/pca9685_pwm_out/PCA9685.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (c) 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -95,13 +95,6 @@ public: int init() override; - /* - * Write new PWM value to device - * - * *output: pulse width, us - */ - int updatePWM(const uint16_t *outputs, unsigned num_outputs); - /* * Set PWM frequency to new value. * @@ -150,11 +143,14 @@ public: int wake(); /* - * If PCA9685 is put into sleep without clearing all the outputs, - * then the restart command will be available, and it can bring back PWM output without the - * need of updatePWM() call. - */ - int doRestart(); + * Configure the PCA9685 device with necessary settings. e.g. MODE1 or MODE2 + */ + int configure(); + + /* + * Verfy whether the registers of PCA9685 are in a consistent state + */ + int registers_check(); protected: int probe() override; diff --git a/src/drivers/pca9685_pwm_out/main.cpp b/src/drivers/pca9685_pwm_out/main.cpp index 60d0cc6340..44464e9511 100644 --- a/src/drivers/pca9685_pwm_out/main.cpp +++ b/src/drivers/pca9685_pwm_out/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2012-2022 PX4 Development Team. All rights reserved. + * Copyright (c) 2012-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,6 +47,7 @@ #include #include #include +#include #include "PCA9685.h" @@ -80,12 +81,15 @@ protected: private: perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; + perf_counter_t _registers_invalid_reset; + perf_counter_t _registers_transfer_reset; enum class STATE : uint8_t { + CONFIGURE, INIT, - WAIT_FOR_OSC, RUNNING - } state{STATE::INIT}; + } _state{STATE::CONFIGURE}; PCA9685 *pca9685 = nullptr; uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; @@ -99,14 +103,22 @@ private: float param_pwm_freq, previous_pwm_freq; float param_schd_rate, previous_schd_rate; + bool param_update_failed = false; uint32_t param_duty_mode; + static constexpr uint8_t _transfer_fails_threshold = 10; + uint8_t _register_transfer_fails = 0; + void Run() override; + int registers_check(); }; PCA9685Wrapper::PCA9685Wrapper() : OutputModuleInterface(MODULE_NAME, px4::wq_configurations::hp_default), - _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")) + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")), + _registers_invalid_reset(perf_alloc(PC_COUNT, MODULE_NAME": registers invalid reset")), + _registers_transfer_reset(perf_alloc(PC_COUNT, MODULE_NAME": registers transfer reset")) { } @@ -119,6 +131,9 @@ PCA9685Wrapper::~PCA9685Wrapper() } perf_free(_cycle_perf); + perf_free(_comms_errors); + perf_free(_registers_invalid_reset); + perf_free(_registers_transfer_reset); } int PCA9685Wrapper::init() @@ -139,7 +154,7 @@ int PCA9685Wrapper::init() bool PCA9685Wrapper::updateOutputs(uint16_t *outputs, unsigned num_outputs, unsigned num_control_groups_updated) { - if (state != STATE::RUNNING) { return false; } + if (_state != STATE::RUNNING) { return false; } uint16_t low_level_outputs[PCA9685_PWM_CHANNEL_COUNT] = {}; num_outputs = num_outputs > PCA9685_PWM_CHANNEL_COUNT ? PCA9685_PWM_CHANNEL_COUNT : num_outputs; @@ -154,7 +169,7 @@ bool PCA9685Wrapper::updateOutputs(uint16_t *outputs, unsigned num_outputs, } if (pca9685->updateRAW(low_level_outputs, num_outputs) != PX4_OK) { - PX4_ERR("Failed to write PWM to PCA9685"); + perf_count(_comms_errors); return false; } @@ -176,69 +191,124 @@ void PCA9685Wrapper::Run() return; } - switch (state) { - case STATE::INIT: - updateParams(); - pca9685->updateFreq(param_pwm_freq); - previous_pwm_freq = param_pwm_freq; - previous_schd_rate = param_schd_rate; + switch (_state) { + case STATE::CONFIGURE: { + int ret = pca9685->configure(); - pca9685->wake(); - state = STATE::WAIT_FOR_OSC; - ScheduleDelayed(500); - break; + if (ret == PX4_OK) { + _state = STATE::INIT; + ScheduleNow(); - case STATE::WAIT_FOR_OSC: { - state = STATE::RUNNING; - ScheduleOnInterval(1000000 / param_schd_rate, 0); - } - break; - - case STATE::RUNNING: - perf_begin(_cycle_perf); - - _mixing_output.update(); - - // check for parameter updates - if (_parameter_update_sub.updated()) { - // clear update - parameter_update_s pupdate; - _parameter_update_sub.copy(&pupdate); - - // update parameters from storage - updateParams(); - - // apply param updates - if ((float)fabs(previous_pwm_freq - param_pwm_freq) > 0.01f) { - previous_pwm_freq = param_pwm_freq; - - ScheduleClear(); - - pca9685->sleep(); - pca9685->updateFreq(param_pwm_freq); - pca9685->wake(); - - // update of PWM freq will always trigger scheduling change - previous_schd_rate = param_schd_rate; - - state = STATE::WAIT_FOR_OSC; - ScheduleDelayed(500); - - } else if ((float)fabs(previous_schd_rate - param_schd_rate) > 0.01f) { - // case when PWM freq not changed but scheduling rate does - previous_schd_rate = param_schd_rate; - ScheduleClear(); - ScheduleOnInterval(1000000 / param_schd_rate, 1000000 / param_schd_rate); + } else { + perf_count(_comms_errors); + ScheduleDelayed(20_ms); } + + break; } - _mixing_output.updateSubscriptions(false); + case STATE::INIT: { + updateParams(); + int ret = pca9685->updateFreq(param_pwm_freq); + ret |= pca9685->wake(); - perf_end(_cycle_perf); - break; + if (ret == PX4_OK) { + previous_pwm_freq = param_pwm_freq; + previous_schd_rate = param_schd_rate; + _state = STATE::RUNNING; + ScheduleOnInterval(1000000 / param_schd_rate, 0); + + } else { + perf_count(_comms_errors); + _state = STATE::CONFIGURE; + ScheduleDelayed(20_ms); + } + + break; + } + + case STATE::RUNNING: { + perf_begin(_cycle_perf); + _mixing_output.update(); + + // check for parameter updates + if (_parameter_update_sub.updated() || param_update_failed) { + // clear update + parameter_update_s pupdate; + _parameter_update_sub.copy(&pupdate); + + // update parameters from storage + updateParams(); + + // apply param updates + if ((float)fabs(previous_pwm_freq - param_pwm_freq) > 0.01f) { + ScheduleClear(); + + int ret = pca9685->sleep(); + ret |= pca9685->updateFreq(param_pwm_freq); + ret |= pca9685->wake(); + + if (ret == PX4_OK) { + // update of PWM freq will always trigger scheduling change + param_update_failed = false; + previous_schd_rate = param_schd_rate; + previous_pwm_freq = param_pwm_freq; + ScheduleOnInterval(1000000 / param_schd_rate, 0); + + } else { + param_update_failed = true; + perf_count(_comms_errors); + ScheduleDelayed(20_ms); + break; + } + + } else if ((float)fabs(previous_schd_rate - param_schd_rate) > 0.01f) { + // case when PWM freq not changed but scheduling rate does + previous_schd_rate = param_schd_rate; + ScheduleClear(); + ScheduleOnInterval(1000000 / param_schd_rate, 1000000 / param_schd_rate); + } + } + + if (registers_check() != PX4_OK) { + _state = STATE::CONFIGURE; + ScheduleClear(); + ScheduleDelayed(20_ms); + } + + _mixing_output.updateSubscriptions(false); + + perf_end(_cycle_perf); + break; + } } } +int PCA9685Wrapper::registers_check() +{ + int reg_ret = pca9685->registers_check(); + + if (reg_ret == -EIO) { + _register_transfer_fails++; + + } else { + _register_transfer_fails = 0; + } + + if (reg_ret == -EFAULT) { + perf_count(_registers_invalid_reset); + return PX4_ERROR; + } + + if (_register_transfer_fails > _transfer_fails_threshold) { + perf_count(_registers_transfer_reset); + _register_transfer_fails = 0; + return PX4_ERROR; + } + + return PX4_OK; +} + int PCA9685Wrapper::print_usage(const char *reason) { if (reason) { @@ -287,8 +357,30 @@ int PCA9685Wrapper::custom_command(int argc, char **argv) { int PCA9685Wrapper::task_spawn(int argc, char **argv) { int ch; - int address=PCA9685_DEFAULT_ADDRESS; - int iicbus=PCA9685_DEFAULT_IICBUS; + int address = PCA9685_DEFAULT_ADDRESS; + int iicbus = PCA9685_DEFAULT_IICBUS; + + int32_t en_bus = 0; + param_t param_handle = param_find("PCA9685_EN_BUS"); + + if (param_handle != PARAM_INVALID) { + param_get(param_handle, &en_bus); + + if (en_bus > 0) { + iicbus = en_bus; + } + } + + int32_t i2c_addr = 0; + param_handle = param_find("PCA9685_I2C_ADDR"); + + if (param_handle != PARAM_INVALID) { + param_get(param_handle, &i2c_addr); + + if (i2c_addr > 0) { + address = i2c_addr; + } + } int myoptind = 1; const char *myoptarg = nullptr; diff --git a/src/drivers/pca9685_pwm_out/module.yaml b/src/drivers/pca9685_pwm_out/module.yaml index 57294c0c81..18d999830a 100644 --- a/src/drivers/pca9685_pwm_out/module.yaml +++ b/src/drivers/pca9685_pwm_out/module.yaml @@ -29,6 +29,16 @@ parameters: min: 0 max: 10 default: 0 + PCA9685_I2C_ADDR: + description: + short: I2C address of PCA9685 + long: | + I2C address of PCA9685. + The default address is 0x40 (64). + type: int32 + min: 1 + max: 127 + default: 64 PCA9685_SCHD_HZ: description: short: PWM update rate diff --git a/src/drivers/power_monitor/ina220/ina220.cpp b/src/drivers/power_monitor/ina220/ina220.cpp index c8f52bf71c..bde68ce875 100644 --- a/src/drivers/power_monitor/ina220/ina220.cpp +++ b/src/drivers/power_monitor/ina220/ina220.cpp @@ -329,8 +329,6 @@ INA220::RunImpl() if (_ch_type == PM_CH_TYPE_VBATT) { _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); } diff --git a/src/drivers/power_monitor/ina226/ina226.cpp b/src/drivers/power_monitor/ina226/ina226.cpp index f61a7c7b79..60fb333699 100644 --- a/src/drivers/power_monitor/ina226/ina226.cpp +++ b/src/drivers/power_monitor/ina226/ina226.cpp @@ -83,10 +83,10 @@ INA226::INA226(const I2CSPIDriverConfig &config, int battery_index) : _power_lsb = 25 * _current_lsb; // We need to publish immediately, to guarantee that the first instance of the driver publishes to uORB instance 0 - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); + + I2C::_retries = 5; } INA226::~INA226() @@ -226,14 +226,11 @@ INA226::collect() success = success && (read(INA226_REG_CURRENT, _current) == PX4_OK); // success = success && (read(INA226_REG_SHUNTVOLTAGE, _shunt) == PX4_OK); - if (!success) { - PX4_DEBUG("error reading from sensor"); - _bus_voltage = _power = _current = _shunt = 0; + if (setConnected(success)) { + _battery.updateVoltage(static_cast(_bus_voltage * INA226_VSCALE)); + _battery.updateCurrent(static_cast(_current * _current_lsb)); } - _battery.setConnected(success); - _battery.updateVoltage(static_cast(_bus_voltage * INA226_VSCALE)); - _battery.updateCurrent(static_cast(_current * _current_lsb)); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); perf_end(_sample_perf); @@ -246,6 +243,7 @@ INA226::collect() } } + void INA226::start() { @@ -297,9 +295,7 @@ INA226::RunImpl() ScheduleDelayed(INA226_CONVERSION_INTERVAL); } else { - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); if (init() != PX4_OK) { @@ -308,6 +304,28 @@ INA226::RunImpl() } } +bool INA226::setConnected(bool state) +{ + // Filter out brief I2C failures for 2s + if (state) { + _connected = INA226_SAMPLE_FREQUENCY_HZ * 2; + + } else if (_connected > 0) { + _connected--; + } + + if (_connected > 0) { + _battery.setConnected(true); + + } else { + _battery.setConnected(false); + _battery.updateVoltage(0); + _battery.updateCurrent(0); + } + + return state; +} + void INA226::print_status() { diff --git a/src/drivers/power_monitor/ina226/ina226.h b/src/drivers/power_monitor/ina226/ina226.h index a402a079ab..a69695a1cc 100644 --- a/src/drivers/power_monitor/ina226/ina226.h +++ b/src/drivers/power_monitor/ina226/ina226.h @@ -206,6 +206,10 @@ private: int read(uint8_t address, int16_t &data); int write(uint8_t address, uint16_t data); + uint8_t _connected{0}; + // returns state unchanged + bool setConnected(bool state); + /** * Initialise the automatic measurement state machine and start it. * diff --git a/src/drivers/power_monitor/ina228/ina228.cpp b/src/drivers/power_monitor/ina228/ina228.cpp index e586590470..fd7494d3f3 100644 --- a/src/drivers/power_monitor/ina228/ina228.cpp +++ b/src/drivers/power_monitor/ina228/ina228.cpp @@ -98,11 +98,10 @@ INA228::INA228(const I2CSPIDriverConfig &config, int battery_index) : _power_lsb = 3.2f * _current_lsb; // We need to publish immediately, to guarantee that the first instance of the driver publishes to uORB instance 0 - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); - _battery.updateTemperature(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); + + I2C::_retries = 5; } INA228::~INA228() @@ -322,15 +321,12 @@ INA228::collect() //success = success && (read(INA228_REG_VSHUNT, _shunt) == PX4_OK); success = success && (read(INA228_REG_DIETEMP, _temperature) == PX4_OK); - if (!success) { - PX4_DEBUG("error reading from sensor"); - _bus_voltage = _power = _current = _shunt = 0; + if (setConnected(success)) { + _battery.updateVoltage(static_cast(_bus_voltage * INA228_VSCALE)); + _battery.updateCurrent(static_cast(_current * _current_lsb)); + _battery.updateTemperature(static_cast(_temperature * INA228_TSCALE)); } - _battery.setConnected(success); - _battery.updateVoltage(static_cast(_bus_voltage * INA228_VSCALE)); - _battery.updateCurrent(static_cast(_current * _current_lsb)); - _battery.updateTemperature(static_cast(_temperature * INA228_TSCALE)); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); perf_end(_sample_perf); @@ -394,10 +390,7 @@ INA228::RunImpl() ScheduleDelayed(INA228_CONVERSION_INTERVAL); } else { - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); - _battery.updateTemperature(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); if (init() != PX4_OK) { @@ -406,6 +399,29 @@ INA228::RunImpl() } } +bool INA228::setConnected(bool state) +{ + // Filter out brief I2C failures for 2s + if (state) { + _connected = INA228_SAMPLE_FREQUENCY_HZ * 2; + + } else if (_connected > 0) { + _connected--; + } + + if (_connected > 0) { + _battery.setConnected(true); + + } else { + _battery.setConnected(false); + _battery.updateVoltage(0); + _battery.updateCurrent(0); + _battery.updateTemperature(0); + } + + return state; +} + void INA228::print_status() { diff --git a/src/drivers/power_monitor/ina228/ina228.h b/src/drivers/power_monitor/ina228/ina228.h index 46e152ff00..72a89e6dcb 100644 --- a/src/drivers/power_monitor/ina228/ina228.h +++ b/src/drivers/power_monitor/ina228/ina228.h @@ -356,6 +356,9 @@ private: Battery _battery; uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; + uint8_t _connected{0}; + // returns state unchanged + bool setConnected(bool state); int read(uint8_t address, int16_t &data); int write(uint8_t address, int16_t data); diff --git a/src/drivers/power_monitor/ina238/ina238.cpp b/src/drivers/power_monitor/ina238/ina238.cpp index a55f71b893..f42ae87764 100644 --- a/src/drivers/power_monitor/ina238/ina238.cpp +++ b/src/drivers/power_monitor/ina238/ina238.cpp @@ -90,11 +90,10 @@ INA238::INA238(const I2CSPIDriverConfig &config, int battery_index) : _register_cfg[2].clear_bits = ~_shunt_calibration; // We need to publish immediately, to guarantee that the first instance of the driver publishes to uORB instance 0 - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); - _battery.updateTemperature(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); + + I2C::_retries = 5; } INA238::~INA238() @@ -178,11 +177,8 @@ int INA238::probe() int INA238::Reset() { - int ret = PX4_ERROR; - _retries = 3; - if (RegisterWrite(Register::CONFIG, (uint16_t)(ADC_RESET_BIT)) != PX4_OK) { return ret; } @@ -254,13 +250,11 @@ int INA238::collect() success = success && (RegisterRead(Register::CURRENT, (uint16_t &)current) == PX4_OK); success = success && (RegisterRead(Register::DIETEMP, (uint16_t &)temperature) == PX4_OK); - if (success) { + if (setConnected(success)) { _battery.updateVoltage(static_cast(bus_voltage * INA238_VSCALE)); _battery.updateCurrent(static_cast(current * _current_lsb)); _battery.updateTemperature(static_cast(temperature * INA238_TSCALE)); - _battery.setConnected(success); - _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); } @@ -276,8 +270,7 @@ int INA238::collect() perf_count(_bad_register_perf); success = false; - _battery.setConnected(success); - + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); } } @@ -338,10 +331,7 @@ void INA238::RunImpl() ScheduleDelayed(INA238_CONVERSION_INTERVAL); } else { - _battery.setConnected(false); - _battery.updateVoltage(0.f); - _battery.updateCurrent(0.f); - _battery.updateTemperature(0.f); + setConnected(false); _battery.updateAndPublishBatteryStatus(hrt_absolute_time()); if (init() != PX4_OK) { @@ -354,6 +344,29 @@ void INA238::RunImpl() } } +bool INA238::setConnected(bool state) +{ + // Filter out brief I2C failures for 2s + if (state) { + _connected = INA238_SAMPLE_FREQUENCY_HZ * 2; + + } else if (_connected > 0) { + _connected--; + } + + if (_connected > 0) { + _battery.setConnected(true); + + } else { + _battery.setConnected(false); + _battery.updateVoltage(0); + _battery.updateCurrent(0); + _battery.updateTemperature(0); + } + + return state; +} + void INA238::print_status() { I2CSPIDriverBase::print_status(); diff --git a/src/drivers/power_monitor/ina238/ina238.h b/src/drivers/power_monitor/ina238/ina238.h index 7d888aef54..62750c44c4 100644 --- a/src/drivers/power_monitor/ina238/ina238.h +++ b/src/drivers/power_monitor/ina238/ina238.h @@ -154,6 +154,9 @@ private: Battery _battery; uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; + uint8_t _connected{0}; + // returns state unchanged + bool setConnected(bool state); int read(uint8_t address, uint16_t &data); int write(uint8_t address, uint16_t data); diff --git a/src/drivers/power_monitor/pm_selector_auterion/Kconfig b/src/drivers/power_monitor/pm_selector_auterion/Kconfig deleted file mode 100644 index e9d1c3f16f..0000000000 --- a/src/drivers/power_monitor/pm_selector_auterion/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -menuconfig DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION - bool "pm_selector_auterion" - default n - ---help--- - Enable support for pm_selector_auterion diff --git a/src/drivers/power_monitor/voxlpm/voxlpm.cpp b/src/drivers/power_monitor/voxlpm/voxlpm.cpp index 51a496bd6d..d25eec8374 100644 --- a/src/drivers/power_monitor/voxlpm/voxlpm.cpp +++ b/src/drivers/power_monitor/voxlpm/voxlpm.cpp @@ -254,11 +254,11 @@ VOXLPM::print_status() switch (_pm_type) { case VOXLPM_TYPE_V2_LTC: - printf("- V2 (LTC2964)\n"); + PX4_INFO("- V2 (LTC2964)"); break; case VOXLPM_TYPE_V3_INA: - printf("- V3 (INA231)\n"); + PX4_INFO("- V3 (INA231)"); break; default: @@ -267,27 +267,27 @@ VOXLPM::print_status() switch (_ch_type) { case VOXLPM_CH_TYPE_VBATT: - printf("- type: BATT\n"); + PX4_INFO("- type: BATT"); break; case VOXLPM_CH_TYPE_P5VDC: - printf("- type: P5VDC\n"); + PX4_INFO("- type: P5VDC"); break; case VOXLPM_CH_TYPE_P12VDC: - printf("- type: P12VDC\n"); + PX4_INFO("- type: P12VDC"); break; default: - printf("- type: UNKOWN\n"); + PX4_INFO("- type: UNKOWN"); break; } - printf(" - voltage: %9.4f VDC \n", (double)_voltage); - printf(" - current: %9.4f ADC \n", (double)_amperage); - printf(" - shunt: %9.4f mV, %9.4f mA\n", (double)_vshunt * 1000, (double)_vshuntamps * 1000); - printf(" - rsense: %9.6f ohm, cal: %i\n", (double)_rshunt, _cal); - printf(" - meas interval: %u us \n", _meas_interval_us); + PX4_INFO(" - voltage: %9.4f VDC ", (double)_voltage); + PX4_INFO(" - current: %9.4f ADC ", (double)_amperage); + PX4_INFO(" - shunt: %9.4f mV, %9.4f mA", (double)_vshunt * 1000, (double)_vshuntamps * 1000); + PX4_INFO(" - rsense: %9.6f ohm, cal: %i", (double)_rshunt, _cal); + PX4_INFO(" - meas interval: %u us ", _meas_interval_us); } void diff --git a/src/drivers/power_monitor/voxlpm/voxlpm.hpp b/src/drivers/power_monitor/voxlpm/voxlpm.hpp index e03326d622..4152bd0e54 100644 --- a/src/drivers/power_monitor/voxlpm/voxlpm.hpp +++ b/src/drivers/power_monitor/voxlpm/voxlpm.hpp @@ -246,7 +246,7 @@ private: int measure_ina231(); bool _initialized; - static constexpr unsigned _meas_interval_us{100_ms}; + static constexpr unsigned _meas_interval_us{20_ms}; perf_counter_t _sample_perf; perf_counter_t _comms_errors; diff --git a/src/drivers/pwm_out/module.yaml b/src/drivers/pwm_out/module.yaml index 8c2049cceb..2c5e54e83d 100644 --- a/src/drivers/pwm_out/module.yaml +++ b/src/drivers/pwm_out/module.yaml @@ -8,6 +8,7 @@ actuator_output: disarmed: { min: 800, max: 2200, default: 1000 } min: { min: 800, max: 1400, default: 1000 } max: { min: 1600, max: 2200, default: 2000 } + center: { min: 800, max: 2200} failsafe: { min: 800, max: 2200 } extra_function_groups: [ pwm_fmu ] pwm_timer_param: diff --git a/src/drivers/rc/crsf_rc/CrsfParser.cpp b/src/drivers/rc/crsf_rc/CrsfParser.cpp index a81fe930f5..1e8b8e0d0c 100644 --- a/src/drivers/rc/crsf_rc/CrsfParser.cpp +++ b/src/drivers/rc/crsf_rc/CrsfParser.cpp @@ -46,6 +46,9 @@ #include "QueueBuffer.hpp" #include "CrsfParser.hpp" #include "Crc8.hpp" +#ifdef CONFIG_VTX_CRSF_MSP_SUPPORT +#include +#endif #define CRSF_CHANNEL_VALUE_MIN 172 #define CRSF_CHANNEL_VALUE_MAX 1811 @@ -57,8 +60,11 @@ enum CRSF_PAYLOAD_SIZE { CRSF_PAYLOAD_SIZE_GPS = 15, CRSF_PAYLOAD_SIZE_BATTERY = 8, CRSF_PAYLOAD_SIZE_LINK_STATISTICS = 10, + CRSF_PAYLOAD_SIZE_LINK_STATISTICS_TX = -1, CRSF_PAYLOAD_SIZE_RC_CHANNELS = 22, CRSF_PAYLOAD_SIZE_ATTITUDE = 6, + CRSF_PAYLOAD_SIZE_MSP_WRITE = -1, // -1 means variable length + CRSF_PAYLOAD_SIZE_ELRS_STATUS = -1, // unclear how large this message is }; enum CRSF_PACKET_TYPE { @@ -68,6 +74,8 @@ enum CRSF_PACKET_TYPE { CRSF_PACKET_TYPE_OPENTX_SYNC = 0x10, CRSF_PACKET_TYPE_RADIO_ID = 0x3A, CRSF_PACKET_TYPE_RC_CHANNELS_PACKED = 0x16, + CRSF_PACKET_TYPE_LINK_STATISTICS_RX = 0x1C, + CRSF_PACKET_TYPE_LINK_STATISTICS_TX = 0x1D, CRSF_PACKET_TYPE_ATTITUDE = 0x1E, CRSF_PACKET_TYPE_FLIGHT_MODE = 0x21, // Extended Header Frames, range: 0x28 to 0x96 @@ -76,6 +84,7 @@ enum CRSF_PACKET_TYPE { CRSF_PACKET_TYPE_PARAMETER_SETTINGS_ENTRY = 0x2B, CRSF_PACKET_TYPE_PARAMETER_READ = 0x2C, CRSF_PACKET_TYPE_PARAMETER_WRITE = 0x2D, + CRSF_PACKET_TYPE_ELRS_STATUS = 0x2E, CRSF_PACKET_TYPE_COMMAND = 0x32, // MSP commands CRSF_PACKET_TYPE_MSP_REQ = 0x7A, // response request using msp sequence as command @@ -114,18 +123,28 @@ enum PARSER_STATE { typedef struct { uint8_t packet_type; - uint32_t packet_size; + int32_t packet_size; bool (*processor)(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); } CrsfPacketDescriptor_t; static bool ProcessChannelData(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); static bool ProcessLinkStatistics(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); +static bool ProcessLinkStatisticsTx(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); +static bool ProcessElrsStatus(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); +#ifdef CONFIG_VTX_CRSF_MSP_SUPPORT +static bool ProcessMspWrite(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet); +#endif -#define CRSF_PACKET_DESCRIPTOR_COUNT 2 -static const CrsfPacketDescriptor_t crsf_packet_descriptors[CRSF_PACKET_DESCRIPTOR_COUNT] = { +static const CrsfPacketDescriptor_t crsf_packet_descriptors[] = { {CRSF_PACKET_TYPE_RC_CHANNELS_PACKED, CRSF_PAYLOAD_SIZE_RC_CHANNELS, ProcessChannelData}, {CRSF_PACKET_TYPE_LINK_STATISTICS, CRSF_PAYLOAD_SIZE_LINK_STATISTICS, ProcessLinkStatistics}, + {CRSF_PACKET_TYPE_LINK_STATISTICS_TX, CRSF_PAYLOAD_SIZE_LINK_STATISTICS_TX, ProcessLinkStatisticsTx}, + {CRSF_PACKET_TYPE_ELRS_STATUS, CRSF_PAYLOAD_SIZE_ELRS_STATUS, ProcessElrsStatus}, +#ifdef CONFIG_VTX_CRSF_MSP_SUPPORT + {CRSF_PACKET_TYPE_MSP_WRITE, CRSF_PAYLOAD_SIZE_MSP_WRITE, ProcessMspWrite}, +#endif }; +#define CRSF_PACKET_DESCRIPTOR_COUNT (sizeof(crsf_packet_descriptors) / sizeof(CrsfPacketDescriptor_t)) static enum PARSER_STATE parser_state = PARSER_STATE_HEADER; static uint32_t working_index = 0; @@ -134,6 +153,11 @@ static uint32_t working_segment_size = HEADER_SIZE; #define RX_QUEUE_BUFFER_SIZE 200 static QueueBuffer_t rx_queue; static uint8_t rx_queue_buffer[RX_QUEUE_BUFFER_SIZE]; +#ifdef CONFIG_RC_CRSF_INJECT +static QueueBuffer_t inject_queue; +static uint8_t inject_queue_buffer[RX_QUEUE_BUFFER_SIZE]; +static uint8_t temp_queue_buffer[RX_QUEUE_BUFFER_SIZE]; +#endif static uint8_t process_buffer[CRSF_MAX_PACKET_LEN]; static CrsfPacketDescriptor_t *working_descriptor = NULL; @@ -142,6 +166,9 @@ static CrsfPacketDescriptor_t *FindCrsfDescriptor(const enum CRSF_PACKET_TYPE pa void CrsfParser_Init(void) { QueueBuffer_Init(&rx_queue, rx_queue_buffer, RX_QUEUE_BUFFER_SIZE); +#ifdef CONFIG_RC_CRSF_INJECT + QueueBuffer_Init(&inject_queue, inject_queue_buffer, RX_QUEUE_BUFFER_SIZE); +#endif } static float ConstrainF(const float x, const float min, const float max) @@ -201,7 +228,7 @@ static bool ProcessLinkStatistics(const uint8_t *data, const uint32_t size, Crsf new_packet->message_type = CRSF_MESSAGE_TYPE_LINK_STATISTICS; new_packet->link_statistics.uplink_rssi_1 = data[0]; - new_packet->link_statistics.uplink_rssi_2 = data[1]; + new_packet->link_statistics.uplink_rssi_2 = data[1]; new_packet->link_statistics.uplink_link_quality = data[2]; new_packet->link_statistics.uplink_snr = data[3]; new_packet->link_statistics.active_antenna = data[4]; @@ -214,6 +241,90 @@ static bool ProcessLinkStatistics(const uint8_t *data, const uint32_t size, Crsf return true; } +static bool ProcessLinkStatisticsTx(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet) +{ + new_packet->message_type = CRSF_MESSAGE_TYPE_LINK_STATISTICS_TX; + + new_packet->link_statistics_tx.uplink_rssi = data[0]; + new_packet->link_statistics_tx.uplink_rssi_pct = data[1]; + new_packet->link_statistics_tx.uplink_link_quality = data[2]; + new_packet->link_statistics_tx.uplink_snr = data[3]; + new_packet->link_statistics_tx.downlink_power = data[4]; + new_packet->link_statistics_tx.uplink_fps = data[5]; + + return true; +} + +static bool ProcessElrsStatus(const uint8_t *data, const uint32_t size, CrsfPacket_t *const new_packet) +{ + new_packet->message_type = CRSF_MESSAGE_TYPE_ELRS_STATUS; + + // Try: crsf_rc inject 0x2E 0x13 0x50 0xFB 0x53 0x31 0x63 0x63 0x63 0x63 + + new_packet->elrs_status.packets_bad = data[2]; + new_packet->elrs_status.packets_good = (data[3] << 8) | data[4]; + new_packet->elrs_status.flags = data[5]; + strncpy(new_packet->elrs_status.message, (const char *)&data[6], sizeof(new_packet->elrs_status.message) - 1); + new_packet->elrs_status.message[sizeof(new_packet->elrs_status.message) - 1] = '\0'; + + return true; +} + +#ifdef CONFIG_VTX_CRSF_MSP_SUPPORT +static bool ProcessMspWrite(const uint8_t *data, const uint32_t size, CrsfPacket_t *const) +{ + // Write the band/channel into the parameters, so it is thread-safe + // data contains the following: + // 0: CRSF v3: destination + // 1: CRSF v3: origin + // 2: CRSF v3: status + // 3: MSP: size + // 4: MSP: command + // 5: MSP: data[≤57] + // Try: crsf_rc inject 0x7C 0xC8 0xEA 0x30 0x4 0x59 0x22 0x0 0x1 0x0 + + int32_t map_config{}; + param_get(int(px4::params::VTX_MAP_CONFIG), &map_config); + + if (map_config == 0) { + // no mapping, just return + return false; + } + + if (data[2] == 0x30 && data[4] == 0x59) { + const uint8_t length = data[3]; + + if (map_config == 1 || map_config == 2) { + // Status = bit4=new frame, bit5,6=MSPv1 + // MSP command 0x59 is MSP_SET_VTX_CONFIG + uint32_t frequency = (data[6] << 8) | data[5]; + + if (frequency <= 0x3f) { + // first byte contains band and channel: 0b00bb'bccc + const int32_t band = (data[5] >> 3) & 0x07; + const int32_t channel = data[5] & 0x07; + + param_set_no_notification(int(px4::params::VTX_BAND), &band); + param_set_no_notification(int(px4::params::VTX_CHANNEL), &channel); + frequency = 0; // Disable the frequency override + } + + param_set_no_notification(int(px4::params::VTX_FREQUENCY), &frequency); + } + + if (length > 2 && (map_config == 1 || map_config == 3)) { + const int32_t pit_mode = (data[8] || (data[7] == 0)) ? 1 : 0; + param_set_no_notification(int(px4::params::VTX_PIT_MODE), &pit_mode); + const int32_t power{pit_mode ? 0 : data[7] - 1}; + param_set_no_notification(int(px4::params::VTX_POWER), &power); + } + } + + // nothing else is implemented yet + return false; +} +#endif + static CrsfPacketDescriptor_t *FindCrsfDescriptor(const enum CRSF_PACKET_TYPE packet_type) { uint32_t i; @@ -232,6 +343,13 @@ bool CrsfParser_LoadBuffer(const uint8_t *buffer, const uint32_t size) return QueueBuffer_AppendBuffer(&rx_queue, buffer, size); } +#ifdef CONFIG_RC_CRSF_INJECT +bool CrsfParser_InjectBuffer(const uint8_t *buffer, const uint32_t size) +{ + return QueueBuffer_AppendBuffer(&inject_queue, buffer, size); +} +#endif + uint32_t CrsfParser_FreeQueueSize(void) { return RX_QUEUE_BUFFER_SIZE - QueueBuffer_Count(&rx_queue); @@ -280,16 +398,21 @@ bool CrsfParser_TryParseCrsfPacket(CrsfPacket_t *const new_packet, CrsfParserSta // If we know what this packet is... if (working_descriptor != NULL) { // Validate length - if (packet_size != working_descriptor->packet_size + PACKET_SIZE_TYPE_SIZE) { - parser_statistics->invalid_known_packet_sizes++; - parser_state = PARSER_STATE_HEADER; - working_segment_size = HEADER_SIZE; - working_index = 0; - buffer_count = QueueBuffer_Count(&rx_queue); - continue; - } + if (working_descriptor->packet_size == -1) { + working_segment_size = packet_size - PACKET_SIZE_TYPE_SIZE; - working_segment_size = working_descriptor->packet_size; + } else { + if (packet_size != working_descriptor->packet_size + PACKET_SIZE_TYPE_SIZE) { + parser_statistics->invalid_known_packet_sizes++; + parser_state = PARSER_STATE_HEADER; + working_segment_size = HEADER_SIZE; + working_index = 0; + buffer_count = QueueBuffer_Count(&rx_queue); + continue; + } + + working_segment_size = working_descriptor->packet_size; + } } else { // We don't know what this packet is, so we'll let the parser continue @@ -349,7 +472,37 @@ bool CrsfParser_TryParseCrsfPacket(CrsfPacket_t *const new_packet, CrsfParserSta parser_state = PARSER_STATE_HEADER; if (valid_packet) { +#ifdef CONFIG_RC_CRSF_INJECT + + if (!QueueBuffer_IsEmpty(&inject_queue)) { + // copy the remaining bytes from the rx queue to the temp buffer + const uint32_t temp_size = QueueBuffer_Count(&rx_queue); + + if (temp_size) { + QueueBuffer_PeekBuffer(&rx_queue, 0, temp_queue_buffer, temp_size); + // clear the rx queue + QueueBuffer_Dequeue(&rx_queue, QueueBuffer_Count(&rx_queue)); + } + + // append the inject queue to the rx queue + uint8_t inject_byte; + + while (QueueBuffer_Get(&inject_queue, &inject_byte)) { + QueueBuffer_Append(&rx_queue, inject_byte); + } + + if (temp_size) { + // append the temp buffer back to the rx queue + QueueBuffer_AppendBuffer(&rx_queue, temp_queue_buffer, temp_size); + } + + } else { + return true; + } + +#else return true; +#endif } break; diff --git a/src/drivers/rc/crsf_rc/CrsfParser.hpp b/src/drivers/rc/crsf_rc/CrsfParser.hpp index c0bf0e8494..4c4b10217b 100644 --- a/src/drivers/rc/crsf_rc/CrsfParser.hpp +++ b/src/drivers/rc/crsf_rc/CrsfParser.hpp @@ -43,6 +43,7 @@ #include #include +#include #define CRSF_CHANNEL_COUNT 16 @@ -63,6 +64,22 @@ struct CrsfLinkStatistics_t { int8_t downlink_snr; }; +struct CrsfLinkStatisticsTx_t { + uint8_t uplink_rssi; + uint8_t uplink_rssi_pct; + uint8_t uplink_link_quality; + int8_t uplink_snr; + uint8_t downlink_power; + uint8_t uplink_fps; +}; + +struct CrsfElrsStatus_t { + uint8_t packets_bad; + uint16_t packets_good; + uint8_t flags; + char message[48]; +}; + struct CrsfParserStatistics_t { uint32_t disposed_bytes; uint32_t crcs_valid_known_packets; @@ -75,6 +92,8 @@ struct CrsfParserStatistics_t { enum CRSF_MESSAGE_TYPE { CRSF_MESSAGE_TYPE_RC_CHANNELS, CRSF_MESSAGE_TYPE_LINK_STATISTICS, + CRSF_MESSAGE_TYPE_LINK_STATISTICS_TX, + CRSF_MESSAGE_TYPE_ELRS_STATUS, }; typedef struct { @@ -83,10 +102,15 @@ typedef struct { union { CrsfChannelData_t channel_data; CrsfLinkStatistics_t link_statistics; + CrsfLinkStatisticsTx_t link_statistics_tx; + CrsfElrsStatus_t elrs_status; }; } CrsfPacket_t; void CrsfParser_Init(void); bool CrsfParser_LoadBuffer(const uint8_t *buffer, const uint32_t size); +#ifdef CONFIG_RC_CRSF_INJECT +bool CrsfParser_InjectBuffer(const uint8_t *buffer, const uint32_t size); +#endif uint32_t CrsfParser_FreeQueueSize(void); bool CrsfParser_TryParseCrsfPacket(CrsfPacket_t *const new_packet, CrsfParserStatistics_t *const parser_statistics); diff --git a/src/drivers/rc/crsf_rc/CrsfRc.cpp b/src/drivers/rc/crsf_rc/CrsfRc.cpp index 9db8911636..95aa9412ed 100644 --- a/src/drivers/rc/crsf_rc/CrsfRc.cpp +++ b/src/drivers/rc/crsf_rc/CrsfRc.cpp @@ -178,8 +178,11 @@ void CrsfRc::Run() Crc8Init(0xd5); + _input_rc.rssi = -1; _input_rc.rssi_dbm = NAN; _input_rc.link_quality = -1; + _input_rc.rc_frame_rate = 0; + _input_rc.link_snr = -1; CrsfParser_Init(); } @@ -213,8 +216,30 @@ void CrsfRc::Run() case CRSF_MESSAGE_TYPE_LINK_STATISTICS: _last_packet_seen = time_now_us; - _input_rc.rssi_dbm = -(float)new_crsf_packet.link_statistics.uplink_rssi_1; + _input_rc.rssi_dbm = -(float)(new_crsf_packet.link_statistics.active_antenna ? + new_crsf_packet.link_statistics.uplink_rssi_2 : + new_crsf_packet.link_statistics.uplink_rssi_1); + + if (time_now_us - _last_stats_tx_seen > 500_ms) { + // We haven't received link statistics tx in a while, use an approximation + _input_rc.rssi = (1.f - _input_rc.rssi_dbm / -130.f) * _input_rc.RSSI_MAX; + } + _input_rc.link_quality = new_crsf_packet.link_statistics.uplink_link_quality; + _input_rc.rc_frame_rate = new_crsf_packet.link_statistics.rf_mode; + _input_rc.link_snr = new_crsf_packet.link_statistics.uplink_snr; + break; + + case CRSF_MESSAGE_TYPE_LINK_STATISTICS_TX: + _last_packet_seen = time_now_us; + _last_stats_tx_seen = time_now_us; + _input_rc.rssi = new_crsf_packet.link_statistics_tx.uplink_rssi_pct; + break; + + case CRSF_MESSAGE_TYPE_ELRS_STATUS: + _last_packet_seen = time_now_us; + _input_rc.rc_lost_frame_count = new_crsf_packet.elrs_status.packets_bad; + _input_rc.rc_total_frame_count = new_crsf_packet.elrs_status.packets_good; break; default: @@ -281,6 +306,10 @@ void CrsfRc::Run() flight_mode = "Altitude"; break; + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: + flight_mode = "Altitude Cruise"; + break; + case vehicle_status_s::NAVIGATION_STATE_POSCTL: flight_mode = "Position"; break; @@ -338,14 +367,17 @@ void CrsfRc::Run() } // If no communication - if (time_now_us - _last_packet_seen > 100_ms) { + if (time_now_us - _last_packet_seen > 500_ms) { // Invalidate link statistics + _input_rc.rssi = -1; _input_rc.rssi_dbm = NAN; _input_rc.link_quality = -1; + _input_rc.rc_frame_rate = 0; + _input_rc.link_snr = -1; } // If we have not gotten RC updates specifically - if (time_now_us - _input_rc.timestamp_last_signal > 50_ms) { + if (time_now_us - _input_rc.timestamp_last_signal > 500_ms) { _input_rc.rc_lost = 1; _input_rc.rc_failsafe = 1; @@ -355,7 +387,6 @@ void CrsfRc::Run() } _input_rc.channel_count = CRSF_CHANNEL_COUNT; - _input_rc.rssi = -1; _input_rc.rc_ppm_frame_length = 0; _input_rc.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_CRSF; _input_rc.timestamp = hrt_absolute_time(); @@ -514,6 +545,43 @@ int CrsfRc::print_status() int CrsfRc::custom_command(int argc, char *argv[]) { +#ifdef CONFIG_RC_CRSF_INJECT + + if (!strcmp(argv[0], "start")) { + if (is_running()) { + return print_usage("already running"); + } + + int ret = CrsfRc::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + if (!is_running()) { + return print_usage("not running"); + } + + // crsf_rc inject 0x7C 0xC8 0xEA 0x30 0x02 0x59 0x31 0x00 0x6A + if (!strcmp(argv[0], "inject")) { + const uint8_t length = argc; + uint8_t buf[100]; + buf[0] = 0xC8; // sync byte + buf[1] = length; + uint8_t i = 0; + + for (; i < length - 1; i++) { + buf[i + 2] = (uint8_t) strtol(argv[i + 1], nullptr, 16); + } + + buf[i + 2] = Crc8Calc(buf + 2, length - 1); // CRC + CrsfParser_InjectBuffer(buf, length + 2); + return PX4_OK; + } + +#endif + return print_usage("unknown command"); } @@ -534,7 +602,9 @@ This module parses the CRSF RC uplink protocol and generates CRSF downlink telem PRINT_MODULE_USAGE_SUBCATEGORY("radio_control"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "", "RC device", true); - +#ifdef CONFIG_RC_CRSF_INJECT + PRINT_MODULE_USAGE_COMMAND_DESCR("inject", "Inject frame data bytes (for testing)"); +#endif PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); return 0; diff --git a/src/drivers/rc/crsf_rc/CrsfRc.hpp b/src/drivers/rc/crsf_rc/CrsfRc.hpp index c3b0a4ec54..a47b361903 100644 --- a/src/drivers/rc/crsf_rc/CrsfRc.hpp +++ b/src/drivers/rc/crsf_rc/CrsfRc.hpp @@ -100,6 +100,7 @@ private: uint32_t _bytes_rx{0}; hrt_abstime _last_packet_seen{0}; + hrt_abstime _last_stats_tx_seen{0}; CrsfParserStatistics_t _packet_parser_statistics{0}; diff --git a/src/drivers/rc/crsf_rc/Kconfig b/src/drivers/rc/crsf_rc/Kconfig index 21096275af..6c42bec5ff 100644 --- a/src/drivers/rc/crsf_rc/Kconfig +++ b/src/drivers/rc/crsf_rc/Kconfig @@ -3,3 +3,13 @@ menuconfig DRIVERS_RC_CRSF_RC default n ---help--- Enable support for crsf rc + +if DRIVERS_RC_CRSF_RC + +config RC_CRSF_INJECT + bool "Inject CRSF RC" + default n + ---help--- + Enable this to inject CRSF RC commands. + +endif # DRIVERS_RC_CRSF_RC diff --git a/src/drivers/rc_input/crsf_telemetry.cpp b/src/drivers/rc_input/crsf_telemetry.cpp index 60286e0f40..fb557f8497 100644 --- a/src/drivers/rc_input/crsf_telemetry.cpp +++ b/src/drivers/rc_input/crsf_telemetry.cpp @@ -141,6 +141,10 @@ bool CRSFTelemetry::send_flight_mode() flight_mode = "Altitude"; break; + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: + flight_mode = "Altitude Cruise"; + break; + case vehicle_status_s::NAVIGATION_STATE_POSCTL: flight_mode = "Position"; break; diff --git a/src/drivers/temperature_sensor/Kconfig b/src/drivers/temperature_sensor/Kconfig new file mode 100644 index 0000000000..af8c27e657 --- /dev/null +++ b/src/drivers/temperature_sensor/Kconfig @@ -0,0 +1,3 @@ +menu "TEMPERATURE_SENSOR" +rsource "*/Kconfig" +endmenu #TEMPERATURE_SENSOR diff --git a/src/drivers/temperature_sensor/mcp9808/CMakeLists.txt b/src/drivers/temperature_sensor/mcp9808/CMakeLists.txt new file mode 100644 index 0000000000..108858606b --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__temperature_sensor__mcp9808 + MAIN mcp9808 + COMPILE_FLAGS + SRCS + mcp9808_main.cpp + mcp9808.cpp + mcp9808.h + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/temperature_sensor/mcp9808/Kconfig b/src/drivers/temperature_sensor/mcp9808/Kconfig new file mode 100644 index 0000000000..f0f9f04145 --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_TEMPERATURE_SENSOR_MCP9808 + bool "MCP9808 temperature sensor" + default n + ---help--- + Enable support MCP9808 temperature sensor diff --git a/src/drivers/temperature_sensor/mcp9808/mcp9808.cpp b/src/drivers/temperature_sensor/mcp9808/mcp9808.cpp new file mode 100644 index 0000000000..a6a997e9a2 --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/mcp9808.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "mcp9808.h" + +MCP9808::MCP9808(const I2CSPIDriverConfig &config) : + I2C(config), + I2CSPIDriver(config), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) +{ + _sensor_temp.device_id = get_device_id(); +} + +MCP9808::~MCP9808() +{ + ScheduleClear(); + perf_free(_cycle_perf); + perf_free(_comms_errors); +} + +void MCP9808::RunImpl() +{ + perf_begin(_cycle_perf); + + float temperature = read_temperature(); + + if (std::isnan(temperature)) { + + perf_count(_comms_errors); + + } else { + _sensor_temp.timestamp = hrt_absolute_time(); + _sensor_temp.temperature = temperature; + + _sensor_temp_pub.publish(_sensor_temp); + } + + perf_end(_cycle_perf); +} + +int MCP9808::probe() +{ + uint16_t manuf_id, device_id; + int ret = read_reg(MCP9808_REG_MANUF_ID, manuf_id); + + if (ret != PX4_OK) { + return ret; + } + + ret = read_reg(MCP9808_REG_DEVICE_ID, device_id); + + if (ret != PX4_OK) { + return ret; + } + + // Verify manufacturer and device ID + if (manuf_id != 0x0054 || device_id != 0x0400) { + PX4_ERR("MCP9808 not found (manuf_id: 0x%04X, device_id: 0x%04X)", manuf_id, device_id); + return PX4_ERROR; + } + + PX4_INFO("MCP9808 found (manuf_id: 0x%04X, device_id: 0x%04X)", manuf_id, device_id); + return PX4_OK; +} + +int MCP9808::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + PX4_ERR("I2C init failed"); + return ret; + } + + PX4_DEBUG("I2C initialized successfully"); + + ret = write_reg(MCP9808_REG_CONFIG, 0x0000); // Ensure default configuration + + if (ret != PX4_OK) { + PX4_ERR("Configuration failed"); + return ret; + } + + _sensor_temp_pub.advertise(); + + ScheduleOnInterval(200_ms); // Sample at 5 Hz + return PX4_OK; +} + +float MCP9808::read_temperature() +{ + uint16_t temp_raw = 0; + + if (read_reg(MCP9808_REG_AMBIENT_TEMP, temp_raw) != PX4_OK) { + return NAN; + } + + float temp = (temp_raw & 0x0FFF) / 16.0f; + + if (temp_raw & 0x1000) { + temp -= 256.0f; + } + + return temp; +} + +int MCP9808::read_reg(uint8_t address, uint16_t &data) +{ + uint8_t addr = address; + uint8_t buffer[2] = {}; // Buffer to hold the raw data + + // Read 2 bytes from the register + int ret = transfer(&addr, 1, buffer, 2); + + if (ret != PX4_OK) { + return ret; + } + + // Combine bytes (big-endian) + data = (buffer[0] << 8) | buffer[1]; + + return PX4_OK; +} + +int MCP9808::write_reg(uint8_t address, uint16_t value) +{ + uint8_t buf[3] = {address, static_cast(value >> 8), static_cast(value & 0xFF)}; + return transfer(buf, sizeof(buf), nullptr, 0); +} diff --git a/src/drivers/temperature_sensor/mcp9808/mcp9808.h b/src/drivers/temperature_sensor/mcp9808/mcp9808.h new file mode 100644 index 0000000000..a13d5c46be --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/mcp9808.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +using namespace time_literals; + +#define MCP9808_REG_CONFIG 0x01 +#define MCP9808_REG_AMBIENT_TEMP 0x05 +#define MCP9808_REG_MANUF_ID 0x06 +#define MCP9808_REG_DEVICE_ID 0x07 +#define MCP9808_REG_RESOLUTION 0x08 + +class MCP9808 : public device::I2C, public I2CSPIDriver +{ +public: + MCP9808(const I2CSPIDriverConfig &config); + ~MCP9808() override; + + int init() override; + int probe() override; + void RunImpl(); + static void print_usage(); + +protected: + void print_status(); + +private: + uORB::PublicationMulti _sensor_temp_pub{ORB_ID(sensor_temp)}; + int read_reg(uint8_t address, uint16_t &data); + int write_reg(uint8_t address, uint16_t value); + float read_temperature(); + sensor_temp_s _sensor_temp{}; + perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; +}; diff --git a/src/drivers/temperature_sensor/mcp9808/mcp9808_main.cpp b/src/drivers/temperature_sensor/mcp9808/mcp9808_main.cpp new file mode 100644 index 0000000000..57cccaeaea --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/mcp9808_main.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file mcp9808_main.cpp + * @author TedObrien + * + * Driver for the Microchip MCP9080 Temperature Sensor connected via I2C. + */ + +#include "mcp9808.h" +#include + +void MCP9808::print_usage() +{ + PRINT_MODULE_USAGE_NAME("mcp9808", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); + PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x18); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +void MCP9808::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); + perf_print_counter(_comms_errors); +} + +extern "C" int mcp9808_main(int argc, char *argv[]) +{ + using ThisDriver = MCP9808; + BusCLIArguments cli{true, false}; + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x18; + + const char *verb = cli.parseDefaultArguments(argc, argv); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_TEMP_DEVTYPE_MCP9808); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} diff --git a/src/drivers/temperature_sensor/mcp9808/mcp9808_params.c b/src/drivers/temperature_sensor/mcp9808/mcp9808_params.c new file mode 100644 index 0000000000..8dc0b5241c --- /dev/null +++ b/src/drivers/temperature_sensor/mcp9808/mcp9808_params.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * Enable MCP9808 temperature sensor (external I2C) + * + * @reboot_required true + * @group Sensors + * @boolean + */ +PARAM_DEFINE_INT32(SENS_EN_MCP9808, 0); diff --git a/src/drivers/temperature_sensor/tmp102/CMakeLists.txt b/src/drivers/temperature_sensor/tmp102/CMakeLists.txt new file mode 100644 index 0000000000..39e23322ba --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/CMakeLists.txt @@ -0,0 +1,45 @@ +############################################################################ +# +# Copyright (c) 2026 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_module( + MODULE drivers__temperature_sensor__tmp102 + MAIN tmp102 + COMPILE_FLAGS + SRCS + tmp102_main.cpp + tmp102.cpp + MODULE_CONFIG + module.yaml + DEPENDS + px4_work_queue + ) diff --git a/src/drivers/temperature_sensor/tmp102/Kconfig b/src/drivers/temperature_sensor/tmp102/Kconfig new file mode 100644 index 0000000000..977a82929b --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_TEMPERATURE_SENSOR_TMP102 + bool "TMP102 temperature sensor" + default n + ---help--- + Enable support for the TMP102 temperature sensor diff --git a/src/drivers/temperature_sensor/tmp102/module.yaml b/src/drivers/temperature_sensor/tmp102/module.yaml new file mode 100644 index 0000000000..1d159deaa7 --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/module.yaml @@ -0,0 +1,15 @@ +__max_num_config_instances: &max_num_config_instances 1 + +module_name: TMP102 + +parameters: + - group: Sensors + definitions: + SENS_EN_TMP102: + description: + short: Enable TMP102 + long: | + Enable the driver for the TMP102 temperature sensor + type: boolean + reboot_required: true + default: 0 diff --git a/src/drivers/temperature_sensor/tmp102/tmp102.cpp b/src/drivers/temperature_sensor/tmp102/tmp102.cpp new file mode 100644 index 0000000000..5dc9df27e3 --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/tmp102.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "tmp102.h" + +TMP102::TMP102(const I2CSPIDriverConfig &config) : + I2C(config), + I2CSPIDriver(config), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")) +{ +} + +TMP102::~TMP102() +{ + ScheduleClear(); + perf_free(_cycle_perf); + perf_free(_comms_errors); +} + +void TMP102::RunImpl() +{ + if (should_exit()) { + exit_and_cleanup(); + return; + } + + perf_begin(_cycle_perf); + + float temperature = read_temperature(); + + if (std::isnan(temperature)) { + perf_count(_comms_errors); + + } else { + sensor_temp_s _sensor_temp{}; + _sensor_temp.timestamp = hrt_absolute_time(); + _sensor_temp.temperature = temperature; + _sensor_temp.device_id = get_device_id(); + _sensor_temp_pub.publish(_sensor_temp); + } + + perf_end(_cycle_perf); +} + +int TMP102::probe() +{ + uint16_t conf_reg; + + for (int i = 0; i < 3; i++) { + if (read_reg(TMP102_CONFIG_REG, conf_reg) == PX4_OK && (conf_reg | 0x0020) == DEFAULT_CONFIG_REG) { // Mask the AL bit + return PX4_OK; + } + + px4_sleep(1); + } + + return PX4_ERROR; +} + +int TMP102::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + PX4_ERR("TMP102, I2C init failed"); + return ret; + } + + _sensor_temp_pub.advertise(); + ScheduleOnInterval(250_ms); // DEFAULT SAMPLE RATE IS 4HZ => 250ms INTERVAL + return PX4_OK; +} + +float TMP102::read_temperature() +{ + uint16_t tmp_data; + + if (read_reg(TMP102_TEMP_REG, tmp_data) != PX4_OK) { + return NAN; + } + + float temperature = ((int16_t)(tmp_data) >> 4) * 0.0625f; + return temperature; +} + +int TMP102::read_reg(uint8_t reg, uint16_t &data) +{ + uint8_t tmp_data[2]; + tmp_data[0] = reg; + + if (transfer(tmp_data, 1, nullptr, 0) != PX4_OK) { // Set the PR to the desired register + return PX4_ERROR; + } + + int ret = transfer(nullptr, 0, tmp_data, 2); // Read the data from the desired register + data = (tmp_data[0] << 8) | tmp_data[1]; + return ret; +} diff --git a/src/drivers/temperature_sensor/tmp102/tmp102.h b/src/drivers/temperature_sensor/tmp102/tmp102.h new file mode 100644 index 0000000000..e0265867a6 --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/tmp102.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +using namespace time_literals; + +#define TMP102_TEMP_REG 0x00 +#define TMP102_CONFIG_REG 0x01 +#define TMP102_TLOW_REG 0x02 +#define TMP102_THIGH_REG 0x03 + +constexpr uint16_t DEFAULT_CONFIG_REG = 0x60A0; // 12-bit resolution, comparator mode, active low, 4Hz + +class TMP102 : public device::I2C, public I2CSPIDriver +{ +public: + TMP102(const I2CSPIDriverConfig &config); + ~TMP102() override; + + int init() override; + int probe() override; + void RunImpl(); + static void print_usage(); + +protected: + void print_status(); + +private: + uORB::PublicationMulti _sensor_temp_pub{ORB_ID(sensor_temp)}; + perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; + + float read_temperature(); + int read_reg(uint8_t address, uint16_t &data); +}; diff --git a/src/drivers/temperature_sensor/tmp102/tmp102_main.cpp b/src/drivers/temperature_sensor/tmp102/tmp102_main.cpp new file mode 100644 index 0000000000..22ea03bcbf --- /dev/null +++ b/src/drivers/temperature_sensor/tmp102/tmp102_main.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file tmp102_main.cpp + * @author Philipp Engljaehringer + * + * Driver for the TMP102 Temperature Sensor connected via I2C. + */ + +#include "tmp102.h" +#include + +void TMP102::print_usage() +{ + PRINT_MODULE_USAGE_NAME("tmp102", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); + PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x48); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +void TMP102::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); + perf_print_counter(_comms_errors); +} + +extern "C" int tmp102_main(int argc, char *argv[]) +{ + using ThisDriver = TMP102; + BusCLIArguments cli{true, false}; + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x48; + + const char *verb = cli.parseDefaultArguments(argc, argv); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_TEMP_DEVTYPE_TMP102); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} diff --git a/src/drivers/transponder/sagetech_mxs/SagetechMXS.hpp b/src/drivers/transponder/sagetech_mxs/SagetechMXS.hpp index ad4314d130..3474f189de 100644 --- a/src/drivers/transponder/sagetech_mxs/SagetechMXS.hpp +++ b/src/drivers/transponder/sagetech_mxs/SagetechMXS.hpp @@ -118,8 +118,6 @@ private: // Subscriptions uORB::Subscription _sensor_gps_sub{ORB_ID(sensor_gps)}; uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; // subscription limited to 1 Hz updates - uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; // regular subscription for additional data - uORB::Subscription _transponder_report_sub{ORB_ID(transponder_report)}; uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)}; diff --git a/src/drivers/uavcan/CMakeLists.txt b/src/drivers/uavcan/CMakeLists.txt index 560c8b4d56..96c53bb073 100644 --- a/src/drivers/uavcan/CMakeLists.txt +++ b/src/drivers/uavcan/CMakeLists.txt @@ -158,6 +158,7 @@ px4_add_module( # Main uavcan_main.cpp uavcan_servers.cpp + node_info.cpp # Actuators actuators/esc.cpp diff --git a/src/drivers/uavcan/actuators/esc.cpp b/src/drivers/uavcan/actuators/esc.cpp index 2af416cbae..9e4bb64509 100644 --- a/src/drivers/uavcan/actuators/esc.cpp +++ b/src/drivers/uavcan/actuators/esc.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2014 PX4 Development Team. All rights reserved. + * Copyright (C) 2014-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,8 +43,6 @@ #include #include -#define MOTOR_BIT(x) (1<<(x)) - using namespace time_literals; UavcanEscController::UavcanEscController(uavcan::INode &node) : @@ -74,18 +72,13 @@ UavcanEscController::init() _uavcan_pub_raw_cmd.getTransferSender().setIfaceMask(iface_mask); } - char param_name[17]; - - for (unsigned i = 0; i < MAX_ACTUATORS; ++i) { - snprintf(param_name, sizeof(param_name), "UAVCAN_EC_FUNC%d", i + 1); - _param_handles[i] = param_find(param_name); - } + _initialized = true; return res; } void -UavcanEscController::update_outputs(uint16_t outputs[MAX_ACTUATORS], unsigned total_outputs) +UavcanEscController::update_outputs(uint16_t outputs[MAX_ACTUATORS], uint8_t output_array_size) { // TODO: configurable rate limit const auto timestamp = _node.getMonotonicTime(); @@ -96,28 +89,12 @@ UavcanEscController::update_outputs(uint16_t outputs[MAX_ACTUATORS], unsigned to _prev_cmd_pub = timestamp; - uavcan::equipment::esc::RawCommand msg = {}; + uavcan::equipment::esc::RawCommand msg{}; - // directly output values from mixer - for (unsigned i = 0; i < total_outputs; i++) { + for (unsigned i = 0; i < output_array_size; i++) { msg.cmd.push_back(static_cast(outputs[i])); } - // but only output as many channels as are configured - uint8_t min_size = 0; - - for (int i = 0; i < MAX_ACTUATORS; i++) { - int32_t val = 0; - - if (param_get(_param_handles[i], &val) == 0) { - if (val > 0) { - min_size = i + 1; - } - } - } - - msg.cmd.resize(min_size); - _uavcan_pub_raw_cmd.broadcast(msg); } @@ -149,6 +126,13 @@ UavcanEscController::esc_status_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(node_id, device_id, NodeInfoPublisher::DeviceCapability::ESC); + } } uint8_t diff --git a/src/drivers/uavcan/actuators/esc.hpp b/src/drivers/uavcan/actuators/esc.hpp index 0518935cad..1a8e45c608 100644 --- a/src/drivers/uavcan/actuators/esc.hpp +++ b/src/drivers/uavcan/actuators/esc.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2014 PX4 Development Team. All rights reserved. + * Copyright (C) 2014-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,13 +47,9 @@ #include #include #include -#include #include -#include #include -#include -#include -#include +#include "../node_info.hpp" class UavcanEscController { @@ -69,13 +65,17 @@ public: int init(); - void update_outputs(uint16_t outputs[MAX_ACTUATORS], unsigned total_outputs); + bool initialized() { return _initialized; }; + + void update_outputs(uint16_t outputs[MAX_ACTUATORS], uint8_t output_array_size); /** * Sets the number of rotors and enable timer */ void set_rotor_count(uint8_t count); + void set_node_info_publisher(NodeInfoPublisher *publisher) { _node_info_publisher = publisher; } + static int max_output_value() { return uavcan::equipment::esc::RawCommand::FieldTypes::cmd::RawValueType::max(); } esc_status_s &esc_status() { return _esc_status; } @@ -97,6 +97,8 @@ private: typedef uavcan::MethodBinder TimerCbBinder; + bool _initialized = false; + esc_status_s _esc_status{}; uORB::PublicationMulti _esc_status_pub{ORB_ID(esc_status)}; @@ -111,6 +113,5 @@ private: uavcan::Publisher _uavcan_pub_raw_cmd; uavcan::Subscriber _uavcan_sub_status; - - param_t _param_handles[MAX_ACTUATORS] {PARAM_INVALID}; + NodeInfoPublisher *_node_info_publisher{nullptr}; }; diff --git a/src/drivers/uavcan/actuators/hardpoint.cpp b/src/drivers/uavcan/actuators/hardpoint.cpp index e1d9e52115..2e0a4a6743 100644 --- a/src/drivers/uavcan/actuators/hardpoint.cpp +++ b/src/drivers/uavcan/actuators/hardpoint.cpp @@ -38,14 +38,13 @@ */ #include "hardpoint.hpp" -#include UavcanHardpointController::UavcanHardpointController(uavcan::INode &node) : _node(node), - _uavcan_pub_raw_cmd(node), + _uavcan_pub_hardpoint(node), _timer(node) { - _uavcan_pub_raw_cmd.setPriority(uavcan::TransferPriority::MiddleLower); + _uavcan_pub_hardpoint.setPriority(uavcan::TransferPriority::MiddleLower); } UavcanHardpointController::~UavcanHardpointController() @@ -59,33 +58,33 @@ UavcanHardpointController::init() /* * Setup timer and call back function for periodic updates */ - _timer.setCallback(TimerCbBinder(this, &UavcanHardpointController::periodic_update)); - return 0; -} - -void -UavcanHardpointController::set_command(uint8_t hardpoint_id, uint16_t command) -{ - _cmd.command = command; - _cmd.hardpoint_id = hardpoint_id; - - /* - * Publish the command message to the bus - */ - _uavcan_pub_raw_cmd.broadcast(_cmd); - - /* - * Start the periodic update timer after a command is set - */ if (!_timer.isRunning()) { - _timer.startPeriodic(uavcan::MonotonicDuration::fromMSec(1000 / MAX_RATE_HZ)); + _timer.setCallback(TimerCbBinder(this, &UavcanHardpointController::periodic_update)); + _timer.startPeriodic(uavcan::MonotonicDuration::fromMSec(1000 / MAX_UPDATE_RATE_HZ)); } + return 0; } void UavcanHardpointController::periodic_update(const uavcan::TimerEvent &) { - // Broadcast command at MAX_RATE_HZ - _uavcan_pub_raw_cmd.broadcast(_cmd); + if (_vehicle_command_sub.updated()) { + vehicle_command_s vehicle_command; + + if (_vehicle_command_sub.copy(&vehicle_command)) { + if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_DO_GRIPPER) { + _cmd.hardpoint_id = vehicle_command.param1; + _cmd.command = vehicle_command.param2; + _next_publish_time = 0; + } + } + } + + const hrt_abstime timestamp_now = hrt_absolute_time(); + + if (timestamp_now > _next_publish_time) { + _next_publish_time = timestamp_now + 1000000 / PUBLISH_RATE_HZ; + _uavcan_pub_hardpoint.broadcast(_cmd); + } } diff --git a/src/drivers/uavcan/actuators/hardpoint.hpp b/src/drivers/uavcan/actuators/hardpoint.hpp index 9587b60a3e..e5be4224fa 100644 --- a/src/drivers/uavcan/actuators/hardpoint.hpp +++ b/src/drivers/uavcan/actuators/hardpoint.hpp @@ -42,7 +42,8 @@ #include #include #include -#include +#include +#include /** * @brief The UavcanHardpointController class @@ -59,17 +60,12 @@ public: */ int init(); - - /* - * set command - */ - void set_command(uint8_t hardpoint_id, uint16_t command); - private: /* * Max update rate to avoid exessive bus traffic */ - static constexpr unsigned MAX_RATE_HZ = 1; ///< XXX make this configurable + static constexpr unsigned MAX_UPDATE_RATE_HZ = 10; + static constexpr unsigned PUBLISH_RATE_HZ = 1; uavcan::equipment::hardpoint::Command _cmd; @@ -83,7 +79,10 @@ private: * libuavcan related things */ uavcan::INode &_node; - uavcan::Publisher _uavcan_pub_raw_cmd; + uavcan::Publisher _uavcan_pub_hardpoint; uavcan::TimerEventForwarder _timer; + uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; + + hrt_abstime _next_publish_time = 0; }; diff --git a/src/drivers/uavcan/arming_status.cpp b/src/drivers/uavcan/arming_status.cpp index 21b1c7f3f4..80ce14065d 100644 --- a/src/drivers/uavcan/arming_status.cpp +++ b/src/drivers/uavcan/arming_status.cpp @@ -66,10 +66,9 @@ void UavcanArmingStatus::periodic_update(const uavcan::TimerEvent &) if (_actuator_armed_sub.update(&actuator_armed)) { uavcan::equipment::safety::ArmingStatus cmd; - if (actuator_armed.lockdown || actuator_armed.kill) { - cmd.status = cmd.STATUS_DISARMED; + bool lockdown_active = actuator_armed.lockdown || actuator_armed.termination || actuator_armed.kill; - } else if (actuator_armed.armed) { + if (!lockdown_active && (actuator_armed.armed || _is_actuator_test_running)) { cmd.status = cmd.STATUS_FULLY_ARMED; } else { diff --git a/src/drivers/uavcan/arming_status.hpp b/src/drivers/uavcan/arming_status.hpp index 3c7bdd041b..4cfaac4b56 100644 --- a/src/drivers/uavcan/arming_status.hpp +++ b/src/drivers/uavcan/arming_status.hpp @@ -57,6 +57,8 @@ public: */ int init(); + void setActuatorTestRunning(bool running) {_is_actuator_test_running = running;} + private: /* * Max update rate to avoid exessive bus traffic @@ -80,4 +82,5 @@ private: uORB::Subscription _actuator_armed_sub{ORB_ID(actuator_armed)}; + bool _is_actuator_test_running = false; }; diff --git a/src/drivers/uavcan/module.yaml b/src/drivers/uavcan/module.yaml index 0579870297..9518e06494 100644 --- a/src/drivers/uavcan/module.yaml +++ b/src/drivers/uavcan/module.yaml @@ -1,3 +1,5 @@ +__max_num_uavcan_lights: &max_num_uavcan_lights 3 # Needs to be equal to MAX_NUM_UAVCAN_LIGHTS constant + module_name: UAVCAN parameters: - group: UAVCAN @@ -24,6 +26,46 @@ parameters: min: 1 max: 255 reboot_required: true + UAVCAN_LGT_NUM: + description: + short: Number of UAVCAN lights to configure + long: | + Number of lights to control via UAVCAN LightsCommand messages. + Set to 0 to disable UAVCAN light control. + Each light uses two parameters: LGT_IDx for the light_id and LGT_FNx for the function. + type: int32 + min: 0 + max: *max_num_uavcan_lights + default: 1 + reboot_required: true + UAVCAN_LGT_ID${i}: + description: + short: Light ${i} ID + long: | + specifies the light_id value for light ${i} in UAVCAN LightsCommand messages. + This determines which physical LED responds to commands for this light slot. + type: int32 + num_instances: *max_num_uavcan_lights + instance_start: 0 + min: 0 + max: 255 + default: 0 + UAVCAN_LGT_FN${i}: + description: + short: Light ${i} function + long: | + Function assigned to light ${i}. + 0: Status - displays system status colors + 1: Anti-collision - white beacon controlled by LGT_ANTCL parameter + type: enum + num_instances: *max_num_uavcan_lights + instance_start: 0 + min: 0 + max: 1 + default: 0 + values: + 0: Status Light + 1: Anti-collision Light actuator_output: show_subgroups_if: 'UAVCAN_ENABLE>=3' config_parameters: diff --git a/src/drivers/uavcan/node_info.cpp b/src/drivers/uavcan/node_info.cpp new file mode 100644 index 0000000000..80c7c87691 --- /dev/null +++ b/src/drivers/uavcan/node_info.cpp @@ -0,0 +1,308 @@ +/**************************************************************************** +* + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "node_info.hpp" + +#include +#include +#include +#include + +using namespace time_literals; + +NodeInfoPublisher::NodeInfoPublisher(uavcan::INode &node, uavcan::NodeInfoRetriever &node_info_retriever) + : TimerBase(node), _node_info_retriever(node_info_retriever) +{ + _node_info_retriever.addListener(this); +} + +NodeInfoPublisher::~NodeInfoPublisher() +{ + _node_info_retriever.removeListener(this); + delete[] _device_informations; +} + +void NodeInfoPublisher::handleNodeInfoRetrieved(uavcan::NodeID node_id, + const uavcan::protocol::GetNodeInfo_::Response &node_info) +{ + const NodeInfo info(node_id, node_info); + registerDevice(info.node_id.get(), &info, UINT32_MAX, DeviceCapability::NONE); + + startTimerIfNotRunning(); +} + +void NodeInfoPublisher::handleNodeInfoUnavailable(uavcan::NodeID node_id) +{ +} + +void NodeInfoPublisher::handleTimerEvent(const uavcan::TimerEvent &event) +{ + // Publish device information using round-robin approach + publishDeviceInformationPeriodic(); +} + +void NodeInfoPublisher::startTimerIfNotRunning() +{ + if (!TimerBase::isRunning()) { + TimerBase::startPeriodic(uavcan::MonotonicDuration::fromMSec(DEVICE_INFO_PUBLISH_INTERVAL_MS)); + } +} + +void NodeInfoPublisher::registerDevice(uint8_t node_id, const NodeInfo *info, uint32_t device_id, + DeviceCapability capability) +{ + const bool is_registering_info = (info != nullptr); + + int multi_capability_index = -1; + + for (size_t i = 0; i < _device_informations_size; ++i) { + if (is_registering_info) { + // Case 1: Check if this entry already has node info - skip this specific entry + if (_device_informations[i].node_id == node_id && + _device_informations[i].has_node_info) { + + continue; // Continue to check other entries with same node_id + } + + // Case 2: Check if node_id already exists with capability but no info - update that entry + if (_device_informations[i].node_id == node_id && + _device_informations[i].capability != DeviceCapability::NONE && + !_device_informations[i].has_node_info) { + populateDeviceInfoFields(_device_informations[i], *info); + publishSingleDeviceInformation(_device_informations[i]); + continue; + } + + } else { // registering capabilities + // Case 1: Check if this exact capability already exists - skip + if (_device_informations[i].node_id == node_id && + _device_informations[i].device_id == device_id && + _device_informations[i].capability == capability) { + return; + } + + // Case 1b: if this node has multiple capabilities, continue + if (_device_informations[i].node_id == node_id && + _device_informations[i].capability != DeviceCapability::NONE && + _device_informations[i].capability != capability) { + multi_capability_index = i; + continue; + } + + // Case 2: Check if node_id already exists with node info but no capability - update that entry + if (_device_informations[i].node_id == node_id && + _device_informations[i].has_node_info && + _device_informations[i].capability == DeviceCapability::NONE) { + _device_informations[i].device_id = device_id; + _device_informations[i].capability = capability; + publishSingleDeviceInformation(_device_informations[i]); + return; + } + } + } + + + + // Case 3: extend array and add entry at the end + if (extendDeviceInformationsArray()) { + _device_informations[_device_informations_size - 1] = DeviceInformation(); + _device_informations[_device_informations_size - 1].node_id = node_id; + + if (multi_capability_index >= 0) { + _device_informations[_device_informations_size - 1] = _device_informations[multi_capability_index]; + _device_informations[_device_informations_size - 1].node_id = node_id; + } + + if (is_registering_info) { + populateDeviceInfoFields(_device_informations[_device_informations_size - 1], *info); + + } else { + _device_informations[_device_informations_size - 1].device_id = device_id; + _device_informations[_device_informations_size - 1].capability = capability; + } + + } else { + PX4_DEBUG("Failed to extend device informations array for %s", + is_registering_info ? "node info" : "capability"); + } +} + +void NodeInfoPublisher::registerDeviceCapability(uint8_t node_id, uint32_t device_id, DeviceCapability capability) +{ + registerDevice(node_id, nullptr, device_id, capability); +} + +void NodeInfoPublisher::publishDeviceInformationPeriodic() +{ + // Using round-robin approach to publish one device info per timer event + if (_device_informations_size == 0) { + return; + } + + size_t devices_checked = 0; + + while (devices_checked < _device_informations_size) { + if (_next_device_to_publish >= _device_informations_size) { + _next_device_to_publish = 0; + } + + const auto &device_info = _device_informations[_next_device_to_publish]; + + if (device_info.has_node_info && device_info.capability != DeviceCapability::NONE) { + publishSingleDeviceInformation(device_info); + _next_device_to_publish++; + return; + } + + _next_device_to_publish++; + devices_checked++; + } + + PX4_DEBUG("No devices ready for periodic publishing"); +} + +void NodeInfoPublisher::publishSingleDeviceInformation(const DeviceInformation &device_info) +{ + const uint64_t now = hrt_absolute_time(); + + device_information_s msg{}; + msg.timestamp = now; + msg.device_type = static_cast(device_info.capability); + msg.device_id = device_info.device_id; + + // Copy pre-populated fields directly from the struct + static_assert(sizeof(msg.model_name) == sizeof(device_info.model_name), "Array size mismatch"); + static_assert(sizeof(msg.vendor_name) == sizeof(device_info.vendor_name), "Array size mismatch"); + static_assert(sizeof(msg.firmware_version) == sizeof(device_info.firmware_version), "Array size mismatch"); + static_assert(sizeof(msg.hardware_version) == sizeof(device_info.hardware_version), "Array size mismatch"); + static_assert(sizeof(msg.serial_number) == sizeof(device_info.serial_number), "Array size mismatch"); + + memcpy(msg.model_name, device_info.model_name, sizeof(msg.model_name)); + msg.model_name[sizeof(msg.model_name) - 1] = '\0'; + + memcpy(msg.vendor_name, device_info.vendor_name, sizeof(msg.vendor_name)); + msg.vendor_name[sizeof(msg.vendor_name) - 1] = '\0'; + + memcpy(msg.firmware_version, device_info.firmware_version, sizeof(msg.firmware_version)); + msg.firmware_version[sizeof(msg.firmware_version) - 1] = '\0'; + + memcpy(msg.hardware_version, device_info.hardware_version, sizeof(msg.hardware_version)); + msg.hardware_version[sizeof(msg.hardware_version) - 1] = '\0'; + + memcpy(msg.serial_number, device_info.serial_number, sizeof(msg.serial_number)); + msg.serial_number[sizeof(msg.serial_number) - 1] = '\0'; + + _device_info_pub.publish(msg); + + PX4_DEBUG("Published device info for node %d, device_id %lu, type %d", + device_info.node_id, static_cast(device_info.device_id), + static_cast(device_info.capability)); +} + +void NodeInfoPublisher::populateDeviceInfoFields(DeviceInformation &device_info, const NodeInfo &info) +{ + device_info.has_node_info = true; + + // Parse the node name to extract vendor and model information + parseNodeName(info.name, device_info); + + snprintf(device_info.firmware_version, sizeof(device_info.firmware_version), + "%d.%d.%lu", info.sw_major, info.sw_minor, static_cast(info.vcs_commit)); + snprintf(device_info.hardware_version, sizeof(device_info.hardware_version), + "%d.%d", info.hw_major, info.hw_minor); + snprintf(device_info.serial_number, sizeof(device_info.serial_number), + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + info.unique_id[0], info.unique_id[1], info.unique_id[2], info.unique_id[3], + info.unique_id[4], info.unique_id[5], info.unique_id[6], info.unique_id[7], + info.unique_id[8], info.unique_id[9], info.unique_id[10], info.unique_id[11], + info.unique_id[12], info.unique_id[13], info.unique_id[14], info.unique_id[15]); +} + +void NodeInfoPublisher::parseNodeName(const char *name, DeviceInformation &device_info) +{ + if (!name || strlen(name) == 0) { + strlcpy(device_info.vendor_name, "", sizeof(device_info.vendor_name)); + strlcpy(device_info.model_name, "", sizeof(device_info.model_name)); + return; + } + + // Find first dot and skip everything before it + const char *after_first_dot = strchr(name, '.'); + + if (after_first_dot == nullptr) { + // No dot - whole string is model, vendor is -1 + strlcpy(device_info.vendor_name, "", sizeof(device_info.vendor_name)); + strlcpy(device_info.model_name, name, sizeof(device_info.model_name)); + return; + } + + after_first_dot++; + + // Find next dot in remaining string + const char *second_dot = strchr(after_first_dot, '.'); + + if (second_dot == nullptr) { + // Only one dot - everything after first dot is model, vendor is -1 + strlcpy(device_info.vendor_name, "", sizeof(device_info.vendor_name)); + strlcpy(device_info.model_name, after_first_dot, sizeof(device_info.model_name)); + return; + } + + // Copy vendor (between first and second dot) + size_t vendor_len = second_dot - after_first_dot; + size_t copy_len = (vendor_len < sizeof(device_info.vendor_name) - 1) ? vendor_len : sizeof(device_info.vendor_name) - 1; + strncpy(device_info.vendor_name, after_first_dot, copy_len); + device_info.vendor_name[copy_len] = '\0'; + + // Copy model (everything after second dot) + strlcpy(device_info.model_name, second_dot + 1, sizeof(device_info.model_name)); +} + +bool NodeInfoPublisher::extendDeviceInformationsArray() +{ + const size_t new_size = _device_informations_size + 1; + DeviceInformation *new_array = new DeviceInformation[new_size]; + + if (!new_array) { + return false; + } + + if (_device_informations_size > 0 && _device_informations != nullptr) { + memcpy(new_array, _device_informations, _device_informations_size * sizeof(DeviceInformation)); + delete[] _device_informations; + } + + _device_informations = new_array; + _device_informations_size = new_size; + return true; +} diff --git a/src/drivers/uavcan/node_info.hpp b/src/drivers/uavcan/node_info.hpp new file mode 100644 index 0000000000..6ac6738669 --- /dev/null +++ b/src/drivers/uavcan/node_info.hpp @@ -0,0 +1,164 @@ +/**************************************************************************** +* + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#include +#include +#include +#include // For UINT8_MAX, UINT32_MAX +#include + +using namespace time_literals; + +constexpr int DEVICE_INFO_PUBLISH_INTERVAL_MS = 1000; +constexpr hrt_abstime DEVICE_INFO_PUBLISH_RATE_LIMIT_US = 100_ms; + +class NodeInfoPublisher : private uavcan::INodeInfoListener, private uavcan::TimerBase +{ +public: + enum class DeviceCapability : uint8_t { + NONE = UINT8_MAX, // Invalid/unset capability value (255) + GENERIC = device_information_s::DEVICE_TYPE_GENERIC, + AIRSPEED = device_information_s::DEVICE_TYPE_AIRSPEED, + ESC = device_information_s::DEVICE_TYPE_ESC, + SERVO = device_information_s::DEVICE_TYPE_SERVO, + GPS = device_information_s::DEVICE_TYPE_GPS, + MAGNETOMETER = device_information_s::DEVICE_TYPE_MAGNETOMETER, + PARACHUTE = device_information_s::DEVICE_TYPE_PARACHUTE, + RANGEFINDER = device_information_s::DEVICE_TYPE_RANGEFINDER, + WINCH = device_information_s::DEVICE_TYPE_WINCH, + BAROMETER = device_information_s::DEVICE_TYPE_BAROMETER, + OPTICAL_FLOW = device_information_s::DEVICE_TYPE_OPTICAL_FLOW, + ACCELEROMETER = device_information_s::DEVICE_TYPE_ACCELEROMETER, + GYROSCOPE = device_information_s::DEVICE_TYPE_GYROSCOPE, + DIFFERENTIAL_PRESSURE = device_information_s::DEVICE_TYPE_DIFFERENTIAL_PRESSURE, + BATTERY = device_information_s::DEVICE_TYPE_BATTERY, + HYGROMETER = device_information_s::DEVICE_TYPE_HYGROMETER, + }; + + NodeInfoPublisher(uavcan::INode &node, uavcan::NodeInfoRetriever &node_info_retriever); + ~NodeInfoPublisher(); + + // Called by sensor bridges to register device capabilities + void registerDeviceCapability(uint8_t node_id, uint32_t device_id, DeviceCapability capability); + +private: + struct NodeInfo { + NodeInfo(uavcan::NodeID id, const uavcan::protocol::GetNodeInfo_::Response &node_info) + : node_id(id), sw_major(node_info.software_version.major), sw_minor(node_info.software_version.minor), + vcs_commit(node_info.software_version.vcs_commit), hw_major(node_info.hardware_version.major), + hw_minor(node_info.hardware_version.minor) + { + memcpy(name, node_info.name.c_str(), node_info.name.capacity()); + name[node_info.name.capacity() - 1] = '\0'; + memcpy(unique_id, &node_info.hardware_version.unique_id.front(), node_info.hardware_version.unique_id.size()); + } + NodeInfo() = default; + + uavcan::NodeID node_id{}; + + char name[uavcan::protocol::GetNodeInfo_::Response::FieldTypes::name::MaxSize]; + uint8_t unique_id[uavcan::protocol::GetNodeInfo_::Response::FieldTypes::hardware_version::FieldTypes::unique_id::MaxSize]; + uint8_t sw_major; + uint8_t sw_minor; + uint32_t vcs_commit; + uint8_t hw_major; + uint8_t hw_minor; + }; + + struct DeviceInformation { + uint8_t node_id{UINT8_MAX}; + uint32_t device_id{UINT32_MAX}; + DeviceCapability capability{DeviceCapability::NONE}; + bool has_node_info{false}; + + char vendor_name[32]; + char model_name[32]; + char firmware_version[24]; + char hardware_version[24]; + char serial_number[33]; + + DeviceInformation() : node_id(UINT8_MAX), device_id(UINT32_MAX), capability(DeviceCapability::NONE), + has_node_info(false) + { + // Initialize string fields + vendor_name[0] = '\0'; + model_name[0] = '\0'; + firmware_version[0] = '\0'; + hardware_version[0] = '\0'; + serial_number[0] = '\0'; + } + + DeviceInformation(uint8_t nid, uint32_t did, DeviceCapability cap) + : node_id(nid), device_id(did), capability(cap), has_node_info(false) + { + // Initialize string fields + vendor_name[0] = '\0'; + model_name[0] = '\0'; + firmware_version[0] = '\0'; + hardware_version[0] = '\0'; + serial_number[0] = '\0'; + } + }; + + void handleNodeInfoRetrieved(uavcan::NodeID node_id, + const uavcan::protocol::GetNodeInfo_::Response &node_info) override; + void handleNodeInfoUnavailable(uavcan::NodeID node_id) override; + + void handleTimerEvent(const uavcan::TimerEvent &event) override; + + void startTimerIfNotRunning(); + + // Register device info or capability, set nodeinfo to nullptr if only registering capability + void registerDevice(uint8_t node_id, const NodeInfo *info, uint32_t device_id, DeviceCapability capability); + + // Publishing methods + void publishDeviceInformationPeriodic(); + void publishSingleDeviceInformation(const DeviceInformation &device_info); + + // Helper functions + void populateDeviceInfoFields(DeviceInformation &device_info, const NodeInfo &info); + void parseNodeName(const char *name, DeviceInformation &device_info); + bool extendDeviceInformationsArray(); + + uavcan::NodeInfoRetriever &_node_info_retriever; + + // Device capability tracking + DeviceInformation *_device_informations{nullptr}; + size_t _device_informations_size{0}; + uORB::Publication _device_info_pub{ORB_ID(device_information)}; + hrt_abstime _last_device_info_publish{0}; + + // Round-robin publishing + size_t _next_device_to_publish{0}; +}; diff --git a/src/drivers/uavcan/rgbled.cpp b/src/drivers/uavcan/rgbled.cpp index 5c4ee8dc21..3ee0e1225e 100644 --- a/src/drivers/uavcan/rgbled.cpp +++ b/src/drivers/uavcan/rgbled.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "rgbled.hpp" +#include UavcanRGBController::UavcanRGBController(uavcan::INode &node) : ModuleParams(nullptr), @@ -44,6 +45,38 @@ UavcanRGBController::UavcanRGBController(uavcan::INode &node) : int UavcanRGBController::init() { + // Cache number of lights (0 disables the feature) + _num_lights = math::min(static_cast(_param_lgt_num.get()), MAX_NUM_UAVCAN_LIGHTS); + + if (_num_lights == 0) { + return 0; // Disabled, don't start timer + } + + // Cache parameter handles and values for each light + for (uint8_t i = 0; i < _num_lights; i++) { + char param_name[17]; + + // Light ID parameter + snprintf(param_name, sizeof(param_name), "UAVCAN_LGT_ID%u", i); + _light_id_params[i] = param_find(param_name); + + if (_light_id_params[i] != PARAM_INVALID) { + int32_t light_id = 0; + param_get(_light_id_params[i], &light_id); + _light_ids[i] = static_cast(light_id); + } + + // Light function parameter + snprintf(param_name, sizeof(param_name), "UAVCAN_LGT_FN%u", i); + _light_fn_params[i] = param_find(param_name); + + if (_light_fn_params[i] != PARAM_INVALID) { + int32_t light_fn = 0; + param_get(_light_fn_params[i], &light_fn); + _light_functions[i] = static_cast(light_fn); + } + } + // Setup timer and call back function for periodic updates _timer.setCallback(TimerCbBinder(this, &UavcanRGBController::periodic_update)); _timer.startPeriodic(uavcan::MonotonicDuration::fromMSec(1000 / MAX_RATE_HZ)); @@ -52,142 +85,108 @@ int UavcanRGBController::init() void UavcanRGBController::periodic_update(const uavcan::TimerEvent &) { - bool publish_lights = false; - uavcan::equipment::indication::LightsCommand cmds; + // Early return if disabled or no lights configured + if (_num_lights == 0) { + return; + } + // Check for status color updates from led_controller LedControlData led_control_data; - if (_led_controller.update(led_control_data) == 1) { - publish_lights = true; + if (_led_controller.update(led_control_data) != 1) { + return; // No update, nothing to do + } - // RGB color in the standard 5-6-5 16-bit palette. - // Monocolor lights should interpret this as brightness setpoint: from zero (0, 0, 0) to full brightness (31, 63, 31). + // Compute status color from led_control_data + uavcan::equipment::indication::RGB565 status_color{}; + uint8_t brightness = led_control_data.leds[0].brightness; + + switch (led_control_data.leds[0].color) { + case led_control_s::COLOR_RED: + status_color = rgb888_to_rgb565(brightness, 0, 0); + break; + + case led_control_s::COLOR_GREEN: + status_color = rgb888_to_rgb565(0, brightness, 0); + break; + + case led_control_s::COLOR_BLUE: + status_color = rgb888_to_rgb565(0, 0, brightness); + break; + + case led_control_s::COLOR_AMBER: // make it the same as yellow + case led_control_s::COLOR_YELLOW: + status_color = rgb888_to_rgb565(brightness, brightness, 0); + break; + + case led_control_s::COLOR_PURPLE: + status_color = rgb888_to_rgb565(brightness, 0, brightness); + break; + + case led_control_s::COLOR_CYAN: + status_color = rgb888_to_rgb565(0, brightness, brightness); + break; + + case led_control_s::COLOR_WHITE: + status_color = rgb888_to_rgb565(brightness, brightness, brightness); + break; + + default: + case led_control_s::COLOR_OFF: + break; + } + + // Build and send light commands for all configured lights + uavcan::equipment::indication::LightsCommand light_command; + + for (uint8_t i = 0; i < _num_lights; i++) { uavcan::equipment::indication::SingleLightCommand cmd; + cmd.light_id = _light_ids[i]; - uint8_t brightness = led_control_data.leds[0].brightness; - - switch (led_control_data.leds[0].color) { - case led_control_s::COLOR_RED: - cmd.color.red = brightness >> 3; - cmd.color.green = 0; - cmd.color.blue = 0; + switch (_light_functions[i]) { + case LightFunction::Status: + cmd.color = status_color; break; - case led_control_s::COLOR_GREEN: - cmd.color.red = 0; - cmd.color.green = brightness >> 2; - cmd.color.blue = 0; - break; - - case led_control_s::COLOR_BLUE: - cmd.color.red = 0; - cmd.color.green = 0; - cmd.color.blue = brightness >> 3; - break; - - case led_control_s::COLOR_AMBER: // make it the same as yellow - - // FALLTHROUGH - case led_control_s::COLOR_YELLOW: - cmd.color.red = (brightness / 2) >> 3; - cmd.color.green = (brightness / 2) >> 2; - cmd.color.blue = 0; - break; - - case led_control_s::COLOR_PURPLE: - cmd.color.red = (brightness / 2) >> 3; - cmd.color.green = 0; - cmd.color.blue = (brightness / 2) >> 3; - break; - - case led_control_s::COLOR_CYAN: - cmd.color.red = 0; - cmd.color.green = (brightness / 2) >> 2; - cmd.color.blue = (brightness / 2) >> 3; - break; - - case led_control_s::COLOR_WHITE: - cmd.color.red = (brightness / 3) >> 3; - cmd.color.green = (brightness / 3) >> 2; - cmd.color.blue = (brightness / 3) >> 3; - break; - - default: // led_control_s::COLOR_OFF - cmd.color.red = 0; - cmd.color.green = 0; - cmd.color.blue = 0; + case LightFunction::AntiCollision: + uint8_t brigtness = is_anticolision_on() ? 255 : 0; + cmd.color = rgb888_to_rgb565(brigtness, brigtness, brigtness); break; } - cmds.commands.push_back(cmd); - + light_command.commands.push_back(cmd); } - if (_armed_sub.updated()) { - publish_lights = true; - - actuator_armed_s armed; - - if (_armed_sub.copy(&armed)) { - - /* Determine the current control mode - * If a light's control mode config >= current control mode, the light will be enabled - * Logic must match UAVCAN_LGT_* param values. - * @value 0 Always off - * @value 1 When autopilot is armed - * @value 2 When autopilot is prearmed - * @value 3 Always on - */ - uint8_t control_mode = 0; - - if (armed.armed) { - control_mode = 1; - - } else if (armed.prearmed) { - control_mode = 2; - - } else { - control_mode = 3; - } - - uavcan::equipment::indication::SingleLightCommand cmd; - - // Beacons - cmd.light_id = uavcan::equipment::indication::SingleLightCommand::LIGHT_ID_ANTI_COLLISION; - cmd.color = brightness_to_rgb565(_param_mode_anti_col.get() >= control_mode ? 255 : 0); - cmds.commands.push_back(cmd); - - // Strobes - cmd.light_id = uavcan::equipment::indication::SingleLightCommand::LIGHT_ID_STROBE; - cmd.color = brightness_to_rgb565(_param_mode_strobe.get() >= control_mode ? 255 : 0); - cmds.commands.push_back(cmd); - - // Nav lights - cmd.light_id = uavcan::equipment::indication::SingleLightCommand::LIGHT_ID_RIGHT_OF_WAY; - cmd.color = brightness_to_rgb565(_param_mode_nav.get() >= control_mode ? 255 : 0); - cmds.commands.push_back(cmd); - - // Landing lights - cmd.light_id = uavcan::equipment::indication::SingleLightCommand::LIGHT_ID_LANDING; - cmd.color = brightness_to_rgb565(_param_mode_land.get() >= control_mode ? 255 : 0); - cmds.commands.push_back(cmd); - } - } - - if (publish_lights) { - _uavcan_pub_lights_cmd.broadcast(cmds); - } + _uavcan_pub_lights_cmd.broadcast(light_command); } -uavcan::equipment::indication::RGB565 UavcanRGBController::brightness_to_rgb565(uint8_t brightness) +bool UavcanRGBController::is_anticolision_on() { - // RGB color in the standard 5-6-5 16-bit palette. - // Monocolor lights should interpret this as brightness setpoint: from zero (0, 0, 0) to full brightness (31, 63, 31). - uavcan::equipment::indication::RGB565 color; + actuator_armed_s actuator_armed{}; + _actuator_armed_sub.copy(&actuator_armed); - color.red = (31.0f * (float)brightness / 255.0f); - color.green = (62.0f * (float)brightness / 255.0f); - color.blue = (31.0f * (float)brightness / 255.0f); + switch (_param_uavcan_lgt_antcl.get()) { + case 3: // Always on + return true; - return color; + case 2: // When autopilot is prearmed + return actuator_armed.armed || actuator_armed.prearmed; + + case 1: // When autopilot is armed + return actuator_armed.armed; + + case 0: // Always off + default: + return false; + } +} + +uavcan::equipment::indication::RGB565 UavcanRGBController::rgb888_to_rgb565(uint8_t red, uint8_t green, uint8_t blue) +{ + // RGB565: Full brightness is (31, 63, 31), off is (0, 0, 0) + uavcan::equipment::indication::RGB565 rgb565{}; + rgb565.red = (red * 31 + 127) / 255; + rgb565.green = (green * 63 + 127) / 255; + rgb565.blue = (blue * 31 + 127) / 255; + return rgb565; } diff --git a/src/drivers/uavcan/rgbled.hpp b/src/drivers/uavcan/rgbled.hpp index be0bc876d3..ee189019e2 100644 --- a/src/drivers/uavcan/rgbled.hpp +++ b/src/drivers/uavcan/rgbled.hpp @@ -54,9 +54,20 @@ private: // Max update rate to avoid excessive bus traffic static constexpr unsigned MAX_RATE_HZ = 20; + // Maximum number of configurable lights + static constexpr uint8_t MAX_NUM_UAVCAN_LIGHTS = 3; + + // Light function types + enum class LightFunction : uint8_t { + Status = 0, // System status colors from led_control + AntiCollision = 1 // White beacon based on arm state + }; + void periodic_update(const uavcan::TimerEvent &); - uavcan::equipment::indication::RGB565 brightness_to_rgb565(uint8_t brightness); + bool is_anticolision_on(); ///< Evaluates current on state of collision lights accordingt to UAVCAN_LGT_ANTCL + + uavcan::equipment::indication::RGB565 rgb888_to_rgb565(uint8_t red, uint8_t green, uint8_t blue); typedef uavcan::MethodBinder TimerCbBinder; @@ -65,14 +76,21 @@ private: uavcan::Publisher _uavcan_pub_lights_cmd; uavcan::TimerEventForwarder _timer; - uORB::Subscription _armed_sub{ORB_ID(actuator_armed)}; + uORB::Subscription _actuator_armed_sub{ORB_ID(actuator_armed)}; LedController _led_controller; + // Cached configuration (set during init, requires reboot to change) + uint8_t _num_lights{0}; + uint8_t _light_ids[MAX_NUM_UAVCAN_LIGHTS] {}; + LightFunction _light_functions[MAX_NUM_UAVCAN_LIGHTS] {}; + + // Cached parameter handles + param_t _light_id_params[MAX_NUM_UAVCAN_LIGHTS] {}; + param_t _light_fn_params[MAX_NUM_UAVCAN_LIGHTS] {}; + DEFINE_PARAMETERS( - (ParamInt) _param_mode_anti_col, - (ParamInt) _param_mode_strobe, - (ParamInt) _param_mode_nav, - (ParamInt) _param_mode_land + (ParamInt) _param_lgt_num, + (ParamInt) _param_uavcan_lgt_antcl ) }; diff --git a/src/drivers/uavcan/sensors/accel.cpp b/src/drivers/uavcan/sensors/accel.cpp index ad0327480e..0efa5c5e6e 100644 --- a/src/drivers/uavcan/sensors/accel.cpp +++ b/src/drivers/uavcan/sensors/accel.cpp @@ -40,10 +40,12 @@ const char *const UavcanAccelBridge::NAME = "accel"; -UavcanAccelBridge::UavcanAccelBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_accel", ORB_ID(sensor_accel)), +UavcanAccelBridge::UavcanAccelBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_accel", ORB_ID(sensor_accel), node_info_publisher), _sub_imu_data(node) -{ } +{ + set_device_type(DRV_ACC_DEVTYPE_UAVCAN); +} int UavcanAccelBridge::init() { @@ -59,7 +61,7 @@ int UavcanAccelBridge::init() void UavcanAccelBridge::imu_sub_cb(const uavcan::ReceivedDataStructure &msg) { - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); const hrt_abstime timestamp_sample = hrt_absolute_time(); @@ -77,17 +79,20 @@ void UavcanAccelBridge::imu_sub_cb(const uavcan::ReceivedDataStructureset_error_count(0); accel->update(timestamp_sample, msg.accelerometer_latest[0], msg.accelerometer_latest[1], msg.accelerometer_latest[2]); + + // Register device capability if not already done + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), accel->get_device_id(), + NodeInfoPublisher::DeviceCapability::ACCELEROMETER); + } } int UavcanAccelBridge::init_driver(uavcan_bridge::Channel *channel) { - // update device id as we now know our device node_id - DeviceId device_id{_device_id}; + // Build device ID using node_id and interface index + uint32_t device_id = make_uavcan_device_id(static_cast(channel->node_id), channel->iface_index); - device_id.devid_s.devtype = DRV_ACC_DEVTYPE_UAVCAN; - device_id.devid_s.address = static_cast(channel->node_id); - - channel->h_driver = new PX4Accelerometer(device_id.devid); + channel->h_driver = new PX4Accelerometer(device_id); if (channel->h_driver == nullptr) { return PX4_ERROR; diff --git a/src/drivers/uavcan/sensors/accel.hpp b/src/drivers/uavcan/sensors/accel.hpp index e1010b7eea..52ec2db920 100644 --- a/src/drivers/uavcan/sensors/accel.hpp +++ b/src/drivers/uavcan/sensors/accel.hpp @@ -38,7 +38,6 @@ #pragma once #include "sensor_bridge.hpp" - #include class UavcanAccelBridge : public UavcanSensorBridgeBase @@ -46,7 +45,7 @@ class UavcanAccelBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanAccelBridge(uavcan::INode &node); + UavcanAccelBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/airspeed.cpp b/src/drivers/uavcan/sensors/airspeed.cpp index 2127817fd0..32da7d3f1a 100644 --- a/src/drivers/uavcan/sensors/airspeed.cpp +++ b/src/drivers/uavcan/sensors/airspeed.cpp @@ -42,8 +42,8 @@ const char *const UavcanAirspeedBridge::NAME = "airspeed"; -UavcanAirspeedBridge::UavcanAirspeedBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_airspeed", ORB_ID(airspeed)), +UavcanAirspeedBridge::UavcanAirspeedBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_airspeed", ORB_ID(airspeed), node_info_publisher), _sub_ias_data(node), _sub_tas_data(node), _sub_oat_data(node) @@ -106,4 +106,10 @@ UavcanAirspeedBridge::ias_sub_cb(const report.true_airspeed_m_s = _last_tas_m_s; publish(msg.getSrcNodeID().get(), &report); + + // Register device capability if not already done + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + 0, NodeInfoPublisher::DeviceCapability::AIRSPEED); // Device ID not defined for airspeed message + } } diff --git a/src/drivers/uavcan/sensors/airspeed.hpp b/src/drivers/uavcan/sensors/airspeed.hpp index 29f0194f06..9560deccd8 100644 --- a/src/drivers/uavcan/sensors/airspeed.hpp +++ b/src/drivers/uavcan/sensors/airspeed.hpp @@ -39,7 +39,6 @@ #include "sensor_bridge.hpp" #include - #include #include #include @@ -49,7 +48,7 @@ class UavcanAirspeedBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanAirspeedBridge(uavcan::INode &node); + UavcanAirspeedBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/baro.cpp b/src/drivers/uavcan/sensors/baro.cpp index 90adfe1759..51c8a4b899 100644 --- a/src/drivers/uavcan/sensors/baro.cpp +++ b/src/drivers/uavcan/sensors/baro.cpp @@ -45,11 +45,13 @@ const char *const UavcanBarometerBridge::NAME = "baro"; -UavcanBarometerBridge::UavcanBarometerBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_baro", ORB_ID(sensor_baro)), +UavcanBarometerBridge::UavcanBarometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_baro", ORB_ID(sensor_baro), node_info_publisher), _sub_air_pressure_data(node), _sub_air_temperature_data(node) -{ } +{ + set_device_type(DRV_BARO_DEVTYPE_UAVCAN); +} int UavcanBarometerBridge::init() { @@ -91,7 +93,7 @@ void UavcanBarometerBridge::air_pressure_sub_cb(const { const hrt_abstime timestamp_sample = hrt_absolute_time(); - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); if (channel == nullptr) { // Something went wrong - no channel to publish on; return @@ -105,17 +107,18 @@ void UavcanBarometerBridge::air_pressure_sub_cb(const return; } - DeviceId device_id{}; - device_id.devid_s.bus = 0; - device_id.devid_s.bus_type = DeviceBusType_UAVCAN; + uint32_t device_id = make_uavcan_device_id(msg); - device_id.devid_s.devtype = DRV_BARO_DEVTYPE_UAVCAN; - device_id.devid_s.address = static_cast(channel->node_id); + // Register barometer capability with NodeInfoPublisher after first successful message + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), device_id, + NodeInfoPublisher::DeviceCapability::BAROMETER); + } // publish sensor_baro_s sensor_baro{}; sensor_baro.timestamp_sample = timestamp_sample; - sensor_baro.device_id = device_id.devid; + sensor_baro.device_id = device_id; sensor_baro.pressure = msg.static_pressure; if (PX4_ISFINITE(_last_temperature_kelvin) && (_last_temperature_kelvin >= 0.f)) { diff --git a/src/drivers/uavcan/sensors/baro.hpp b/src/drivers/uavcan/sensors/baro.hpp index 3fb2821c75..882fe35fc8 100644 --- a/src/drivers/uavcan/sensors/baro.hpp +++ b/src/drivers/uavcan/sensors/baro.hpp @@ -38,7 +38,6 @@ #pragma once #include "sensor_bridge.hpp" - #include #include @@ -47,7 +46,7 @@ class UavcanBarometerBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanBarometerBridge(uavcan::INode &node); + UavcanBarometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/battery.cpp b/src/drivers/uavcan/sensors/battery.cpp index cb1619e0cf..ccf587980f 100644 --- a/src/drivers/uavcan/sensors/battery.cpp +++ b/src/drivers/uavcan/sensors/battery.cpp @@ -39,8 +39,8 @@ const char *const UavcanBatteryBridge::NAME = "battery"; -UavcanBatteryBridge::UavcanBatteryBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_battery", ORB_ID(battery_status)), +UavcanBatteryBridge::UavcanBatteryBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_battery", ORB_ID(battery_status), node_info_publisher), ModuleParams(nullptr), _sub_battery(node), _sub_battery_aux(node), @@ -100,6 +100,11 @@ UavcanBatteryBridge::battery_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(msg.getSrcNodeID().get(), + msg.battery_id, NodeInfoPublisher::DeviceCapability::BATTERY); + } + if (instance >= battery_status_s::MAX_INSTANCES || _batt_update_mod[instance] == BatteryDataType::CBAT) { return; @@ -112,29 +117,23 @@ UavcanBatteryBridge::battery_sub_cb(const uavcan::ReceivedDataStructureupdateDt(_battery_status[instance].timestamp); _battery_status[instance].voltage_v = msg.voltage; _battery_status[instance].current_a = msg.current; - _battery_status[instance].current_average_a = msg.current; if (_batt_update_mod[instance] == BatteryDataType::Raw) { - sumDischarged(_battery_status[instance].timestamp, _battery_status[instance].current_a); - _battery_status[instance].discharged_mah = _discharged_mah; + _battery_status[instance].discharged_mah = _battery[instance]->sumDischarged(fabsf(msg.current)); _battery_status[instance].time_remaining_s = NAN; } _battery_status[instance].remaining = msg.state_of_charge_pct / 100.0f; // between 0 and 1 _battery_status[instance].scale = -1.f; _battery_status[instance].temperature = msg.temperature + atmosphere::kAbsoluteNullCelsius; // Kelvin to Celsius - // _battery_status[instance].cell_count = msg.; _battery_status[instance].connected = true; _battery_status[instance].source = msg.status_flags & uavcan::equipment::power::BatteryInfo::STATUS_FLAG_IN_USE; - // _battery_status[instance].priority = msg.; - _battery_status[instance].capacity = msg.full_charge_capacity_wh; _battery_status[instance].full_charge_capacity_wh = msg.full_charge_capacity_wh; _battery_status[instance].remaining_capacity_wh = msg.remaining_capacity_wh; - // _battery_status[instance].cycle_count = msg.; - // _battery_status[instance].average_time_to_empty = msg.; - _battery_status[instance].id = msg.getSrcNodeID().get(); + _battery_status[instance].id = msg.battery_id; if (_batt_update_mod[instance] == BatteryDataType::Raw) { // Mavlink 2 needs individual cell voltages or cell[0] if cell voltages are not available. @@ -144,21 +143,19 @@ UavcanBatteryBridge::battery_sub_cb(const uavcan::ReceivedDataStructuredetermineWarning(_battery_status[instance].remaining); if (_batt_update_mod[instance] == BatteryDataType::Raw) { publish(msg.getSrcNodeID().get(), &_battery_status[instance]); - _battery_info_pub[instance].publish(_battery_info[instance]); + + if (msg.model_instance_id > 0) { + _battery_info[instance].timestamp = _battery_status[instance].timestamp; + _battery_info[instance].id = _battery_status[instance].id; + snprintf(_battery_info[instance].serial_number, sizeof(_battery_info[instance].serial_number), + "%" PRIu32, msg.model_instance_id); + _battery_info_pub[instance].publish(_battery_info[instance]); + } + } } @@ -182,18 +179,24 @@ UavcanBatteryBridge::battery_aux_sub_cb(const uavcan::ReceivedDataStructure FLT_EPSILON) { + _battery_status[instance].capacity = + _battery_status[instance].full_charge_capacity_wh * 1000.f / msg.nominal_voltage; + } + + _battery[instance]->setCapacityMah(_battery_status[instance].capacity); + _battery[instance]->setStateOfCharge(_battery_status[instance].remaining); + // Absolute value of current as sign not clearly defined and vendors are inconsistent + _battery_status[instance].time_remaining_s = + _battery[instance]->computeRemainingTime(fabsf(_battery_status[instance].current_a)); + _battery_status[instance].current_average_a = _battery[instance]->getCurrentAverage(); + for (uint8_t i = 0; i < _battery_status[instance].cell_count; i++) { _battery_status[instance].voltage_cell_v[i] = msg.voltage_cell[i]; } @@ -234,7 +237,7 @@ void UavcanBatteryBridge::cbat_sub_cb(const uavcan::ReceivedDataStructure Wh _battery_status[instance].remaining_capacity_wh = msg.remaining_capacity * msg.nominal_voltage / 1000.f; // mAh -> Wh _battery_status[instance].nominal_voltage = msg.nominal_voltage; - _battery_status[instance].capacity = msg.design_capacity; // mAh + _battery_status[instance].capacity = msg.full_charge_capacity; // mAh _battery_status[instance].cycle_count = msg.cycle_count; _battery_status[instance].average_time_to_empty = msg.average_time_to_empty; _battery_status[instance].manufacture_date = msg.manufacture_date; @@ -247,19 +250,18 @@ void UavcanBatteryBridge::cbat_sub_cb(const uavcan::ReceivedDataStructure Ah - const float current_a = math::isZero(_battery_status[instance].current_average_a) ? - _battery_status[instance].current_a : _battery_status[instance].current_average_a; + // use Battery class for time_remaining calculation + _battery[instance]->updateDt(_battery_status[instance].timestamp); + _battery[instance]->setStateOfCharge(_battery_status[instance].remaining); + _battery[instance]->setCapacityMah(_battery_status[instance].capacity); _battery_status[instance].time_remaining_s = - math::isZero(current_a) ? NAN : (remaining_ah / current_a * 3600.f); // Ah / A = h * 3600 = s + _battery[instance]->computeRemainingTime(_battery_status[instance].current_a); for (uint8_t i = 0; i < _battery_status[instance].cell_count; i++) { _battery_status[instance].voltage_cell_v[i] = msg.voltage_cell[i]; } - determineWarning(_battery_status[instance].remaining); - _battery_status[instance].warning = _warning; + _battery_status[instance].warning = _battery[instance]->determineWarning(_battery_status[instance].remaining); uint16_t faults = 0; @@ -288,42 +290,10 @@ void UavcanBatteryBridge::cbat_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(msg.getSrcNodeID().get(), + _battery_status[instance].id, NodeInfoPublisher::DeviceCapability::BATTERY); } } @@ -343,9 +313,11 @@ UavcanBatteryBridge::filterData(const uavcan::ReceivedDataStructure 0) { + _battery_info[instance].timestamp = _battery_status[instance].timestamp; + _battery_info[instance].id = _battery_status[instance].id; + snprintf(_battery_info[instance].serial_number, sizeof(_battery_info[instance].serial_number), + "%" PRIu32, msg.model_instance_id); + _battery_info_pub[instance].publish(_battery_info[instance]); + } } diff --git a/src/drivers/uavcan/sensors/battery.hpp b/src/drivers/uavcan/sensors/battery.hpp index ed61cd0817..e0e050e9c4 100644 --- a/src/drivers/uavcan/sensors/battery.hpp +++ b/src/drivers/uavcan/sensors/battery.hpp @@ -54,7 +54,7 @@ class UavcanBatteryBridge : public UavcanSensorBridgeBase, public ModuleParams public: static const char *const NAME; - UavcanBatteryBridge(uavcan::INode &node); + UavcanBatteryBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } @@ -73,8 +73,6 @@ private: void battery_sub_cb(const uavcan::ReceivedDataStructure &msg); void battery_aux_sub_cb(const uavcan::ReceivedDataStructure &msg); void cbat_sub_cb(const uavcan::ReceivedDataStructure &msg); - void sumDischarged(hrt_abstime timestamp, float current_a); - void determineWarning(float remaining); void filterData(const uavcan::ReceivedDataStructure &msg, uint8_t instance); typedef uavcan::MethodBinder < UavcanBatteryBridge *, @@ -107,7 +105,7 @@ private: hrt_abstime _last_timestamp; // Separate battery info publication because UavcanSensorBridgeBase only supports publishing one topic - uORB::PublicationMulti _battery_info_pub[battery_status_s::MAX_INSTANCES] {ORB_ID(battery_info), ORB_ID(battery_info), ORB_ID(battery_info), ORB_ID(battery_info)}; + uORB::PublicationMulti _battery_info_pub[battery_status_s::MAX_INSTANCES] {ORB_ID(battery_info), ORB_ID(battery_info), ORB_ID(battery_info)}; battery_info_s _battery_info[battery_status_s::MAX_INSTANCES] {}; battery_status_s _battery_status[battery_status_s::MAX_INSTANCES] {}; @@ -117,15 +115,13 @@ private: static constexpr int BATTERY_INDEX_1 = 1; static constexpr int BATTERY_INDEX_2 = 2; static constexpr int BATTERY_INDEX_3 = 3; - static constexpr int BATTERY_INDEX_4 = 4; static constexpr int SAMPLE_INTERVAL_US = 500_ms; // Typical message rate for a CAN battery monitor should be 2-5Hz. - static_assert(battery_status_s::MAX_INSTANCES <= BATTERY_INDEX_4, "Battery array too big"); + static_assert(battery_status_s::MAX_INSTANCES <= BATTERY_INDEX_3, "Battery array too big"); Battery battery1 = {BATTERY_INDEX_1, this, SAMPLE_INTERVAL_US, battery_status_s::SOURCE_EXTERNAL}; Battery battery2 = {BATTERY_INDEX_2, this, SAMPLE_INTERVAL_US, battery_status_s::SOURCE_EXTERNAL}; Battery battery3 = {BATTERY_INDEX_3, this, SAMPLE_INTERVAL_US, battery_status_s::SOURCE_EXTERNAL}; - Battery battery4 = {BATTERY_INDEX_4, this, SAMPLE_INTERVAL_US, battery_status_s::SOURCE_EXTERNAL}; - Battery *_battery[battery_status_s::MAX_INSTANCES] = { &battery1, &battery2, &battery3, &battery4 }; + Battery *_battery[battery_status_s::MAX_INSTANCES] = { &battery1, &battery2, &battery3}; }; diff --git a/src/drivers/uavcan/sensors/differential_pressure.cpp b/src/drivers/uavcan/sensors/differential_pressure.cpp index 0fcb6520c2..107547a121 100644 --- a/src/drivers/uavcan/sensors/differential_pressure.cpp +++ b/src/drivers/uavcan/sensors/differential_pressure.cpp @@ -44,10 +44,12 @@ const char *const UavcanDifferentialPressureBridge::NAME = "differential_pressure"; -UavcanDifferentialPressureBridge::UavcanDifferentialPressureBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_differential_pressure", ORB_ID(differential_pressure)), +UavcanDifferentialPressureBridge::UavcanDifferentialPressureBridge(uavcan::INode &node, + NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_differential_pressure", ORB_ID(differential_pressure), node_info_publisher), _sub_air(node) { + set_device_type(DRV_DIFF_PRESS_DEVTYPE_UAVCAN); } int UavcanDifferentialPressureBridge::init() @@ -67,8 +69,6 @@ void UavcanDifferentialPressureBridge::air_sub_cb(const { const hrt_abstime timestamp_sample = hrt_absolute_time(); - _device_id.devid_s.devtype = DRV_DIFF_PRESS_DEVTYPE_UAVCAN; - _device_id.devid_s.address = msg.getSrcNodeID().get() & 0xFF; float diff_press_pa = msg.differential_pressure; int32_t differential_press_rev = 0; param_get(param_find("SENS_DPRES_REV"), &differential_press_rev); @@ -82,10 +82,16 @@ void UavcanDifferentialPressureBridge::air_sub_cb(const differential_pressure_s report{}; report.timestamp_sample = timestamp_sample; - report.device_id = _device_id.devid; + report.device_id = make_uavcan_device_id(msg); report.differential_pressure_pa = diff_press_pa; report.temperature = temperature_c; report.timestamp = hrt_absolute_time(); publish(msg.getSrcNodeID().get(), &report); + + // Register device capability if not already done + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + report.device_id, NodeInfoPublisher::DeviceCapability::DIFFERENTIAL_PRESSURE); + } } diff --git a/src/drivers/uavcan/sensors/differential_pressure.hpp b/src/drivers/uavcan/sensors/differential_pressure.hpp index c0e125711f..2152636eee 100644 --- a/src/drivers/uavcan/sensors/differential_pressure.hpp +++ b/src/drivers/uavcan/sensors/differential_pressure.hpp @@ -38,7 +38,6 @@ #pragma once #include - #include "sensor_bridge.hpp" #include @@ -48,7 +47,7 @@ class UavcanDifferentialPressureBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanDifferentialPressureBridge(uavcan::INode &node); + UavcanDifferentialPressureBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } @@ -63,4 +62,5 @@ private: AirCbBinder; uavcan::Subscriber _sub_air; + }; diff --git a/src/drivers/uavcan/sensors/flow.cpp b/src/drivers/uavcan/sensors/flow.cpp index f084cd98b3..001b78566d 100644 --- a/src/drivers/uavcan/sensors/flow.cpp +++ b/src/drivers/uavcan/sensors/flow.cpp @@ -37,10 +37,11 @@ const char *const UavcanFlowBridge::NAME = "flow"; -UavcanFlowBridge::UavcanFlowBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_flow", ORB_ID(sensor_optical_flow)), +UavcanFlowBridge::UavcanFlowBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_flow", ORB_ID(sensor_optical_flow), node_info_publisher), _sub_flow(node) { + set_device_type(DRV_FLOW_DEVTYPE_UAVCAN); } int @@ -61,13 +62,7 @@ void UavcanFlowBridge::flow_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(msg.getSrcNodeID().get(), + flow.device_id, NodeInfoPublisher::DeviceCapability::OPTICAL_FLOW); + } } diff --git a/src/drivers/uavcan/sensors/flow.hpp b/src/drivers/uavcan/sensors/flow.hpp index 3a5484269e..5cf02a649e 100644 --- a/src/drivers/uavcan/sensors/flow.hpp +++ b/src/drivers/uavcan/sensors/flow.hpp @@ -46,7 +46,7 @@ class UavcanFlowBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanFlowBridge(uavcan::INode &node); + UavcanFlowBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/fuel_tank_status.cpp b/src/drivers/uavcan/sensors/fuel_tank_status.cpp index 7834ef6425..18d727700c 100644 --- a/src/drivers/uavcan/sensors/fuel_tank_status.cpp +++ b/src/drivers/uavcan/sensors/fuel_tank_status.cpp @@ -43,7 +43,7 @@ const char *const UavcanFuelTankStatusBridge::NAME = "fuel_tank_status"; UavcanFuelTankStatusBridge::UavcanFuelTankStatusBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_fuel_tank_status", ORB_ID(fuel_tank_status)), + UavcanSensorBridgeBase("uavcan_fuel_tank_status", ORB_ID(fuel_tank_status), nullptr), _sub_fuel_tank_status_data(node) { } diff --git a/src/drivers/uavcan/sensors/gnss.cpp b/src/drivers/uavcan/sensors/gnss.cpp index d5b12aa609..fb02f1d274 100644 --- a/src/drivers/uavcan/sensors/gnss.cpp +++ b/src/drivers/uavcan/sensors/gnss.cpp @@ -53,13 +53,14 @@ using namespace time_literals; const char *const UavcanGnssBridge::NAME = "gnss"; -UavcanGnssBridge::UavcanGnssBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_gnss", ORB_ID(sensor_gps)), +UavcanGnssBridge::UavcanGnssBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_gnss", ORB_ID(sensor_gps), node_info_publisher), _node(node), _sub_auxiliary(node), _sub_fix(node), _sub_fix2(node), _sub_gnss_heading(node), + _sub_moving_baseline_data(node), _pub_moving_baseline_data(node), _pub_rtcm_stream(node), _channel_using_fix2(new bool[_max_channels]) @@ -76,6 +77,7 @@ UavcanGnssBridge::~UavcanGnssBridge() delete [] _channel_using_fix2; perf_free(_rtcm_stream_pub_perf); perf_free(_moving_baseline_data_pub_perf); + perf_free(_moving_baseline_data_sub_perf); } int @@ -129,6 +131,15 @@ UavcanGnssBridge::init() _moving_baseline_data_pub_perf = perf_alloc(PC_INTERVAL, "uavcan: gnss: moving baseline data rtcm stream pub"); } + // UAVCAN_SUB_MBD + int32_t uavcan_sub_mbd = 0; + param_get(param_find("UAVCAN_SUB_MBD"), &uavcan_sub_mbd); + + if (uavcan_sub_mbd == 1) { + res = _sub_moving_baseline_data.start(MovingBaselineDataCbBinder(this, &UavcanGnssBridge::moving_baseline_data_sub_cb)); + _moving_baseline_data_sub_perf = perf_alloc(PC_INTERVAL, "uavcan: gnss: moving baseline data rtcm stream sub"); + } + return res; } @@ -338,6 +349,7 @@ UavcanGnssBridge::gnss_fix2_sub_cb(const uavcan::ReceivedDataStructure &msg) { @@ -346,6 +358,41 @@ void UavcanGnssBridge::gnss_relative_sub_cb(const _rel_heading_accuracy = math::radians(msg.reported_heading_acc_deg); } + +void UavcanGnssBridge::moving_baseline_data_sub_cb(const + uavcan::ReceivedDataStructure &msg) +{ + perf_count(_moving_baseline_data_sub_perf); + + size_t total_bytes = msg.data.size(); + size_t written = 0; + + while (written < total_bytes) { + gps_dump_s dump = {}; + dump.timestamp = hrt_absolute_time(); + + DeviceId device_id = {}; + device_id.devid_s.bus_type = DeviceBusType::DeviceBusType_UAVCAN; + device_id.devid_s.bus = 0; + device_id.devid_s.address = msg.getSrcNodeID().get() & 0xFF; + device_id.devid_s.devtype = DRV_GPS_DEVTYPE_UAVCAN; + + dump.instance = 0; // TODO: How can we determine the instance? Startup order of CANnodes is non-deterministic. + dump.device_id = device_id.devid; + + size_t remaining = total_bytes - written; + size_t write_len = remaining < sizeof(dump.data) ? remaining : sizeof(dump.data); + + memcpy(dump.data, msg.data.begin() + written, write_len); + dump.len = write_len; + dump.len &= 0x7F; // MSB of len is direction - 0 is from the device + + written += write_len; + + _gps_dump_pub.publish(dump); + } +} + template void UavcanGnssBridge::process_fixx(const uavcan::ReceivedDataStructure &msg, uint8_t fix_type, @@ -357,7 +404,15 @@ void UavcanGnssBridge::process_fixx(const uavcan::ReceivedDataStructure const uint8_t spoofing_state) { sensor_gps_s sensor_gps{}; - sensor_gps.device_id = get_device_id(); + + sensor_gps.device_id = make_uavcan_device_id(msg); + + // Register GPS capability with NodeInfoPublisher after first successful message + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + sensor_gps.device_id, + NodeInfoPublisher::DeviceCapability::GPS); + } /* * FIXME HACK @@ -580,7 +635,17 @@ void UavcanGnssBridge::handleInjectDataTopic() _last_rtcm_injection_time = hrt_absolute_time(); } - updated = _orb_inject_data_sub[_selected_rtcm_instance].update(&msg); + auto &gps_inject_data_sub = _orb_inject_data_sub[_selected_rtcm_instance]; + + const unsigned last_generation = gps_inject_data_sub.get_last_generation(); + + updated = gps_inject_data_sub.update(&msg); + + if (updated) { + if (gps_inject_data_sub.get_last_generation() != last_generation + 1) { + PX4_WARN("gps_inject_data lost, generation %u -> %u", last_generation, gps_inject_data_sub.get_last_generation()); + } + } } while (updated && num_injections < max_num_injections); } @@ -648,4 +713,5 @@ void UavcanGnssBridge::print_status() const UavcanSensorBridgeBase::print_status(); perf_print_counter(_rtcm_stream_pub_perf); perf_print_counter(_moving_baseline_data_pub_perf); + perf_print_counter(_moving_baseline_data_sub_perf); } diff --git a/src/drivers/uavcan/sensors/gnss.hpp b/src/drivers/uavcan/sensors/gnss.hpp index 2a5d7c06ff..72fe9b3453 100644 --- a/src/drivers/uavcan/sensors/gnss.hpp +++ b/src/drivers/uavcan/sensors/gnss.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -67,7 +68,7 @@ class UavcanGnssBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanGnssBridge(uavcan::INode &node); + UavcanGnssBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); ~UavcanGnssBridge(); const char *get_name() const override { return NAME; } @@ -84,6 +85,8 @@ private: void gnss_fix_sub_cb(const uavcan::ReceivedDataStructure &msg); void gnss_fix2_sub_cb(const uavcan::ReceivedDataStructure &msg); void gnss_relative_sub_cb(const uavcan::ReceivedDataStructure &msg); + void moving_baseline_data_sub_cb(const uavcan::ReceivedDataStructure &msg); + template void process_fixx(const uavcan::ReceivedDataStructure &msg, @@ -119,6 +122,10 @@ private: void (UavcanGnssBridge::*)(const uavcan::ReceivedDataStructure &) > RelPosHeadingCbBinder; + typedef uavcan::MethodBinder < UavcanGnssBridge *, + void (UavcanGnssBridge::*)(const uavcan::ReceivedDataStructure &) > + MovingBaselineDataCbBinder; + uavcan::INode &_node; uavcan::Subscriber _sub_auxiliary; @@ -126,6 +133,9 @@ private: uavcan::Subscriber _sub_fix2; uavcan::Subscriber _sub_gnss_heading; + // Used for MSM7 logging for PPK workflows + uavcan::Subscriber _sub_moving_baseline_data; + uavcan::Publisher _pub_moving_baseline_data; uavcan::Publisher _pub_rtcm_stream; @@ -137,6 +147,8 @@ private: hrt_abstime _last_rtcm_injection_time{0}; ///< time of last rtcm injection uint8_t _selected_rtcm_instance{0}; ///< uorb instance that is being used for RTCM corrections + uORB::Publication _gps_dump_pub{ORB_ID(gps_dump)}; // For PPK + bool _system_clock_set{false}; ///< Have we set the system clock at least once from GNSS data? bool *_channel_using_fix2; ///< Flag for whether each channel is using Fix2 or Fix msg @@ -150,6 +162,7 @@ private: perf_counter_t _rtcm_stream_pub_perf{nullptr}; perf_counter_t _moving_baseline_data_pub_perf{nullptr}; + perf_counter_t _moving_baseline_data_sub_perf{nullptr}; hrt_abstime _last_rate_measurement{0}; float _rtcm_injection_rate{0.f}; ///< RTCM message injection rate diff --git a/src/drivers/uavcan/sensors/gnss_relative.cpp b/src/drivers/uavcan/sensors/gnss_relative.cpp index 1636939163..8cb5bf344e 100644 --- a/src/drivers/uavcan/sensors/gnss_relative.cpp +++ b/src/drivers/uavcan/sensors/gnss_relative.cpp @@ -38,10 +38,11 @@ const char *const UavcanGnssRelativeBridge::NAME = "gnss_relative"; -UavcanGnssRelativeBridge::UavcanGnssRelativeBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_gnss_relative", ORB_ID(sensor_gnss_relative)), +UavcanGnssRelativeBridge::UavcanGnssRelativeBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_gnss_relative", ORB_ID(sensor_gnss_relative), node_info_publisher), _sub_rel_pos_heading(node) { + set_device_type(DRV_GPS_DEVTYPE_UAVCAN); } int @@ -70,7 +71,14 @@ void UavcanGnssRelativeBridge::rel_pos_heading_sub_cb(const sensor_gnss_relative.position_length = msg.relative_distance_m; sensor_gnss_relative.position[2] = msg.relative_down_pos_m; - sensor_gnss_relative.device_id = get_device_id(); + sensor_gnss_relative.device_id = make_uavcan_device_id(msg); + + // Register GPS capability with NodeInfoPublisher after first successful message + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + sensor_gnss_relative.device_id, + NodeInfoPublisher::DeviceCapability::GPS); + } sensor_gnss_relative.timestamp = hrt_absolute_time(); diff --git a/src/drivers/uavcan/sensors/gnss_relative.hpp b/src/drivers/uavcan/sensors/gnss_relative.hpp index 87c7e22731..2e5fc80b91 100644 --- a/src/drivers/uavcan/sensors/gnss_relative.hpp +++ b/src/drivers/uavcan/sensors/gnss_relative.hpp @@ -34,7 +34,6 @@ #pragma once #include "sensor_bridge.hpp" - #include #include @@ -46,7 +45,7 @@ class UavcanGnssRelativeBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanGnssRelativeBridge(uavcan::INode &node); + UavcanGnssRelativeBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/gyro.cpp b/src/drivers/uavcan/sensors/gyro.cpp index 4a34213a03..ab72693866 100644 --- a/src/drivers/uavcan/sensors/gyro.cpp +++ b/src/drivers/uavcan/sensors/gyro.cpp @@ -40,10 +40,12 @@ const char *const UavcanGyroBridge::NAME = "gyro"; -UavcanGyroBridge::UavcanGyroBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_gyro", ORB_ID(sensor_gyro)), +UavcanGyroBridge::UavcanGyroBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_gyro", ORB_ID(sensor_gyro), node_info_publisher), _sub_imu_data(node) -{ } +{ + set_device_type(DRV_GYR_DEVTYPE_UAVCAN); +} int UavcanGyroBridge::init() { @@ -59,7 +61,7 @@ int UavcanGyroBridge::init() void UavcanGyroBridge::imu_sub_cb(const uavcan::ReceivedDataStructure &msg) { - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); if (channel == nullptr) { // Something went wrong - no channel to publish on; return @@ -77,17 +79,20 @@ void UavcanGyroBridge::imu_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(msg.getSrcNodeID().get(), + gyro->get_device_id(), NodeInfoPublisher::DeviceCapability::GYROSCOPE); + } } int UavcanGyroBridge::init_driver(uavcan_bridge::Channel *channel) { - // update device id as we now know our device node_id - DeviceId device_id{_device_id}; + // Build device ID using node_id and interface index + uint32_t device_id = make_uavcan_device_id(static_cast(channel->node_id), channel->iface_index); - device_id.devid_s.devtype = DRV_GYR_DEVTYPE_UAVCAN; - device_id.devid_s.address = static_cast(channel->node_id); - - channel->h_driver = new PX4Gyroscope(device_id.devid); + channel->h_driver = new PX4Gyroscope(device_id); if (channel->h_driver == nullptr) { return PX4_ERROR; diff --git a/src/drivers/uavcan/sensors/gyro.hpp b/src/drivers/uavcan/sensors/gyro.hpp index 0ed5c8959f..cdc2bc006e 100644 --- a/src/drivers/uavcan/sensors/gyro.hpp +++ b/src/drivers/uavcan/sensors/gyro.hpp @@ -46,7 +46,7 @@ class UavcanGyroBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanGyroBridge(uavcan::INode &node); + UavcanGyroBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/hygrometer.cpp b/src/drivers/uavcan/sensors/hygrometer.cpp index 98bd4b1155..d9975b226e 100755 --- a/src/drivers/uavcan/sensors/hygrometer.cpp +++ b/src/drivers/uavcan/sensors/hygrometer.cpp @@ -33,15 +33,16 @@ #include "hygrometer.hpp" -#include +#include #include const char *const UavcanHygrometerBridge::NAME = "hygrometer_sensor"; -UavcanHygrometerBridge::UavcanHygrometerBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_hygrometer_sensor", ORB_ID(sensor_hygrometer)), +UavcanHygrometerBridge::UavcanHygrometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_hygrometer_sensor", ORB_ID(sensor_hygrometer), node_info_publisher), _sub_hygro(node) { + set_device_type(DRV_HYGRO_DEVTYPE_UAVCAN); } int UavcanHygrometerBridge::init() @@ -64,10 +65,16 @@ void UavcanHygrometerBridge::hygro_sub_cb(const uavcan::ReceivedDataStructureregisterDeviceCapability(msg.getSrcNodeID().get(), + report.device_id, NodeInfoPublisher::DeviceCapability::HYGROMETER); + } } diff --git a/src/drivers/uavcan/sensors/hygrometer.hpp b/src/drivers/uavcan/sensors/hygrometer.hpp index 871bdef043..2bb9e64e11 100755 --- a/src/drivers/uavcan/sensors/hygrometer.hpp +++ b/src/drivers/uavcan/sensors/hygrometer.hpp @@ -43,7 +43,7 @@ class UavcanHygrometerBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanHygrometerBridge(uavcan::INode &node); + UavcanHygrometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } @@ -58,4 +58,5 @@ private: HygroCbBinder; uavcan::Subscriber _sub_hygro; + }; diff --git a/src/drivers/uavcan/sensors/ice_status.cpp b/src/drivers/uavcan/sensors/ice_status.cpp index 1b6274403b..e3bbd6f1d9 100644 --- a/src/drivers/uavcan/sensors/ice_status.cpp +++ b/src/drivers/uavcan/sensors/ice_status.cpp @@ -41,7 +41,7 @@ const char *const UavcanIceStatusBridge::NAME = "ice_status"; UavcanIceStatusBridge::UavcanIceStatusBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_ice_status", ORB_ID(internal_combustion_engine_status)), + UavcanSensorBridgeBase("uavcan_ice_status", ORB_ID(internal_combustion_engine_status), nullptr), _sub_ice_status_data(node) { } diff --git a/src/drivers/uavcan/sensors/mag.cpp b/src/drivers/uavcan/sensors/mag.cpp index 25ef6fa4d0..36fa8ec415 100644 --- a/src/drivers/uavcan/sensors/mag.cpp +++ b/src/drivers/uavcan/sensors/mag.cpp @@ -44,11 +44,12 @@ const char *const UavcanMagnetometerBridge::NAME = "mag"; -UavcanMagnetometerBridge::UavcanMagnetometerBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_mag", ORB_ID(sensor_mag)), +UavcanMagnetometerBridge::UavcanMagnetometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_mag", ORB_ID(sensor_mag), node_info_publisher), _sub_mag(node), _sub_mag2(node) { + set_device_type(DRV_MAG_DEVTYPE_UAVCAN); } int UavcanMagnetometerBridge::init() @@ -73,7 +74,7 @@ int UavcanMagnetometerBridge::init() void UavcanMagnetometerBridge::mag_sub_cb(const uavcan::ReceivedDataStructure &msg) { - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); if (channel == nullptr) { // Something went wrong - no channel to publish on; return @@ -87,6 +88,12 @@ void UavcanMagnetometerBridge::mag_sub_cb(const return; } + // Register magnetometer capability with NodeInfoPublisher after first successful message + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), mag->get_device_id(), + NodeInfoPublisher::DeviceCapability::MAGNETOMETER); + } + const float x = msg.magnetic_field_ga[0]; const float y = msg.magnetic_field_ga[1]; const float z = msg.magnetic_field_ga[2]; @@ -98,7 +105,7 @@ void UavcanMagnetometerBridge::mag2_sub_cb(const uavcan::ReceivedDataStructure &msg) { - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); if (channel == nullptr || channel->instance < 0) { // Something went wrong - no channel to publish on; return @@ -112,6 +119,13 @@ UavcanMagnetometerBridge::mag2_sub_cb(const return; } + // Register magnetometer capability with NodeInfoPublisher after first successful message + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + mag->get_device_id(), + NodeInfoPublisher::DeviceCapability::MAGNETOMETER); + } + const float x = msg.magnetic_field_ga[0]; const float y = msg.magnetic_field_ga[1]; const float z = msg.magnetic_field_ga[2]; @@ -121,13 +135,10 @@ UavcanMagnetometerBridge::mag2_sub_cb(const int UavcanMagnetometerBridge::init_driver(uavcan_bridge::Channel *channel) { - // update device id as we now know our device node_id - DeviceId device_id{_device_id}; + // Build device ID using node_id and interface index + uint32_t device_id = make_uavcan_device_id(static_cast(channel->node_id), channel->iface_index); - device_id.devid_s.devtype = DRV_MAG_DEVTYPE_UAVCAN; - device_id.devid_s.address = static_cast(channel->node_id); - - channel->h_driver = new PX4Magnetometer(device_id.devid, ROTATION_NONE); + channel->h_driver = new PX4Magnetometer(device_id, ROTATION_NONE); if (channel->h_driver == nullptr) { return PX4_ERROR; diff --git a/src/drivers/uavcan/sensors/mag.hpp b/src/drivers/uavcan/sensors/mag.hpp index f668f2e2b3..14253dc161 100644 --- a/src/drivers/uavcan/sensors/mag.hpp +++ b/src/drivers/uavcan/sensors/mag.hpp @@ -47,7 +47,7 @@ class UavcanMagnetometerBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanMagnetometerBridge(uavcan::INode &node); + UavcanMagnetometerBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/rangefinder.cpp b/src/drivers/uavcan/sensors/rangefinder.cpp index 5e15b8d51f..b476c66947 100644 --- a/src/drivers/uavcan/sensors/rangefinder.cpp +++ b/src/drivers/uavcan/sensors/rangefinder.cpp @@ -42,10 +42,12 @@ const char *const UavcanRangefinderBridge::NAME = "rangefinder"; -UavcanRangefinderBridge::UavcanRangefinderBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_rangefinder", ORB_ID(distance_sensor)), +UavcanRangefinderBridge::UavcanRangefinderBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher) : + UavcanSensorBridgeBase("uavcan_rangefinder", ORB_ID(distance_sensor), node_info_publisher), _sub_range_data(node) -{ } +{ + set_device_type(DRV_DIST_DEVTYPE_UAVCAN); +} int UavcanRangefinderBridge::init() { @@ -66,7 +68,7 @@ int UavcanRangefinderBridge::init() void UavcanRangefinderBridge::range_sub_cb(const uavcan::ReceivedDataStructure &msg) { - uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get()); + uavcan_bridge::Channel *channel = get_channel_for_node(msg.getSrcNodeID().get(), msg.getIfaceIndex()); if (channel == nullptr || channel->instance < 0) { // Something went wrong - no channel to publish on; return @@ -115,17 +117,20 @@ void UavcanRangefinderBridge::range_sub_cb(const } rangefinder->update(hrt_absolute_time(), msg.range, quality); + + // Register device capability if not already done + if (_node_info_publisher != nullptr) { + _node_info_publisher->registerDeviceCapability(msg.getSrcNodeID().get(), + rangefinder->get_device_id(), NodeInfoPublisher::DeviceCapability::RANGEFINDER); + } } int UavcanRangefinderBridge::init_driver(uavcan_bridge::Channel *channel) { - // update device id as we now know our device node_id - DeviceId device_id{_device_id}; + // Build device ID using node_id and interface index + uint32_t device_id = make_uavcan_device_id(static_cast(channel->node_id), channel->iface_index); - device_id.devid_s.devtype = DRV_DIST_DEVTYPE_UAVCAN; - device_id.devid_s.address = static_cast(channel->node_id); - - channel->h_driver = new PX4Rangefinder(device_id.devid, distance_sensor_s::ROTATION_DOWNWARD_FACING); + channel->h_driver = new PX4Rangefinder(device_id, distance_sensor_s::ROTATION_DOWNWARD_FACING); if (channel->h_driver == nullptr) { return PX4_ERROR; diff --git a/src/drivers/uavcan/sensors/rangefinder.hpp b/src/drivers/uavcan/sensors/rangefinder.hpp index 470d23c8af..7c50bcdcb2 100644 --- a/src/drivers/uavcan/sensors/rangefinder.hpp +++ b/src/drivers/uavcan/sensors/rangefinder.hpp @@ -48,7 +48,7 @@ class UavcanRangefinderBridge : public UavcanSensorBridgeBase public: static const char *const NAME; - UavcanRangefinderBridge(uavcan::INode &node); + UavcanRangefinderBridge(uavcan::INode &node, NodeInfoPublisher *node_info_publisher); const char *get_name() const override { return NAME; } diff --git a/src/drivers/uavcan/sensors/safety_button.cpp b/src/drivers/uavcan/sensors/safety_button.cpp index 7607df85c4..a4624c9dda 100644 --- a/src/drivers/uavcan/sensors/safety_button.cpp +++ b/src/drivers/uavcan/sensors/safety_button.cpp @@ -41,7 +41,8 @@ const char *const UavcanSafetyButtonBridge::NAME = "safety_button"; using namespace time_literals; UavcanSafetyButtonBridge::UavcanSafetyButtonBridge(uavcan::INode &node) : - UavcanSensorBridgeBase("uavcan_safety_button", ORB_ID(button_event)), _sub_button(node) + UavcanSensorBridgeBase("uavcan_safety_button", ORB_ID(button_event), nullptr), + _sub_button(node) { } int UavcanSafetyButtonBridge::init() diff --git a/src/drivers/uavcan/sensors/sensor_bridge.cpp b/src/drivers/uavcan/sensors/sensor_bridge.cpp index 1fa67050e1..350dd9a625 100644 --- a/src/drivers/uavcan/sensors/sensor_bridge.cpp +++ b/src/drivers/uavcan/sensors/sensor_bridge.cpp @@ -85,7 +85,8 @@ /* * IUavcanSensorBridge */ -void IUavcanSensorBridge::make_all(uavcan::INode &node, List &list) +void IUavcanSensorBridge::make_all(uavcan::INode &node, List &list, + NodeInfoPublisher *node_info_publisher) { // airspeed #if defined(CONFIG_UAVCAN_SENSOR_AIRSPEED) @@ -93,7 +94,7 @@ void IUavcanSensorBridge::make_all(uavcan::INode &node, Listorb_advert, report); } -uavcan_bridge::Channel *UavcanSensorBridgeBase::get_channel_for_node(int node_id) +uavcan_bridge::Channel *UavcanSensorBridgeBase::get_channel_for_node(int node_id, uint8_t iface_index) { uavcan_bridge::Channel *channel = nullptr; @@ -353,6 +354,7 @@ uavcan_bridge::Channel *UavcanSensorBridgeBase::get_channel_for_node(int node_id // initialize the driver, which registers the class device name and uORB publisher channel->node_id = node_id; + channel->iface_index = iface_index; int ret = init_driver(channel); if (ret != PX4_OK) { diff --git a/src/drivers/uavcan/sensors/sensor_bridge.hpp b/src/drivers/uavcan/sensors/sensor_bridge.hpp index 4cc765f1be..e8fb1a124b 100644 --- a/src/drivers/uavcan/sensors/sensor_bridge.hpp +++ b/src/drivers/uavcan/sensors/sensor_bridge.hpp @@ -42,6 +42,7 @@ #include #include #include +#include /** * A sensor bridge class must implement this interface. @@ -80,7 +81,8 @@ public: * Sensor bridge factory. * Creates all known sensor bridges and puts them in the linked list. */ - static void make_all(uavcan::INode &node, List &list); + static void make_all(uavcan::INode &node, List &list, + NodeInfoPublisher *node_info_publisher); }; namespace uavcan_bridge @@ -90,6 +92,7 @@ struct Channel { orb_advert_t orb_advert{nullptr}; int instance{-1}; void *h_driver{nullptr}; + uint8_t iface_index{0}; }; } // namespace uavcan_bridge @@ -106,13 +109,16 @@ class UavcanSensorBridgeBase : public IUavcanSensorBridge, public device::Device protected: static constexpr unsigned DEFAULT_MAX_CHANNELS = 4; const unsigned _max_channels; + NodeInfoPublisher *_node_info_publisher; UavcanSensorBridgeBase(const char *name, const orb_id_t orb_topic_sensor, + NodeInfoPublisher *node_info_publisher, const unsigned max_channels = DEFAULT_MAX_CHANNELS) : Device(name), _orb_topic(orb_topic_sensor), _channels(new uavcan_bridge::Channel[max_channels]), - _max_channels(max_channels) + _max_channels(max_channels), + _node_info_publisher(node_info_publisher) { set_device_bus_type(DeviceBusType_UAVCAN); set_device_bus(0); @@ -133,7 +139,34 @@ protected: */ virtual int init_driver(uavcan_bridge::Channel *channel) { return PX4_OK; }; - uavcan_bridge::Channel *get_channel_for_node(int node_id); + uavcan_bridge::Channel *get_channel_for_node(int node_id, uint8_t iface_index); + + /** + * Builds a unique device ID from a UAVCAN message + * @param msg UAVCAN message (must have getSrcNodeID() and getIfaceIndex() methods) + * @return Complete device ID with node address and interface encoded + */ + template + uint32_t make_uavcan_device_id(const uavcan::ReceivedDataStructure &msg) const + { + return make_uavcan_device_id(msg.getSrcNodeID().get(), msg.getIfaceIndex()); + } + + /** + * Builds a unique device ID from node ID and interface index + * @param node_id UAVCAN node ID + * @param iface_index CAN interface index (0 = CAN1, 1 = CAN2, etc.) + * @return Complete device ID with node address and interface encoded + */ + uint32_t make_uavcan_device_id(uint8_t node_id, uint8_t iface_index) const + { + device::Device::DeviceId device_id{}; + device_id.devid_s.devtype = get_device_type(); + device_id.devid_s.address = node_id; + device_id.devid_s.bus_type = device::Device::DeviceBusType_UAVCAN; + device_id.devid_s.bus = iface_index; + return device_id.devid; + } public: virtual ~UavcanSensorBridgeBase(); diff --git a/src/drivers/uavcan/uavcan_drivers/stm32h7/driver/src/uc_stm32h7_can.cpp b/src/drivers/uavcan/uavcan_drivers/stm32h7/driver/src/uc_stm32h7_can.cpp index baddaa5997..2a8ff73fc9 100644 --- a/src/drivers/uavcan/uavcan_drivers/stm32h7/driver/src/uc_stm32h7_can.cpp +++ b/src/drivers/uavcan/uavcan_drivers/stm32h7/driver/src/uc_stm32h7_can.cpp @@ -644,7 +644,7 @@ uavcan::int16_t CanIface::configureFilters(const uavcan::CanFilterConfig *filter bool CanIface::waitCCCRBitStateChange(uint32_t mask, bool target_state) { -#if UAVCAN_STM32_NUTTX +#if UAVCAN_STM32H7_NUTTX const unsigned Timeout = 1000; #else const unsigned Timeout = 2000000; @@ -657,7 +657,7 @@ bool CanIface::waitCCCRBitStateChange(uint32_t mask, bool target_state) return true; } -#if UAVCAN_STM32_NUTTX +#if UAVCAN_STM32H7_NUTTX ::usleep(1000); #endif } diff --git a/src/drivers/uavcan/uavcan_main.cpp b/src/drivers/uavcan/uavcan_main.cpp index c3e3ebe5c7..956f5f4193 100644 --- a/src/drivers/uavcan/uavcan_main.cpp +++ b/src/drivers/uavcan/uavcan_main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014-2022 PX4 Development Team. All rights reserved. + * Copyright (c) 2014-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -107,6 +107,7 @@ UavcanNode::UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &sys _time_sync_slave(_node), _node_status_monitor(_node), _node_info_retriever(_node), + _node_info_publisher(_node, _node_info_retriever), _master_timer(_node), _param_getset_client(_node), _param_opcode_client(_node), @@ -529,10 +530,16 @@ UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events) // Actuators #if defined(CONFIG_UAVCAN_OUTPUTS_CONTROLLER) - ret = _esc_controller.init(); + int32_t uavcan_enable = -1; + (void)param_get(param_find("UAVCAN_ENABLE"), &uavcan_enable); - if (ret < 0) { - return ret; + if (uavcan_enable > 2) { + + ret = _esc_controller.init(); + + if (ret < 0) { + return ret; + } } #endif @@ -589,7 +596,7 @@ UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events) } // Sensor bridges - IUavcanSensorBridge::make_all(_node, _sensor_bridges); + IUavcanSensorBridge::make_all(_node, _sensor_bridges, &_node_info_publisher); for (const auto &br : _sensor_bridges) { ret = br->init(); @@ -602,15 +609,15 @@ UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events) PX4_DEBUG("sensor bridge '%s' init ok", br->get_name()); } +#if defined(CONFIG_UAVCAN_OUTPUTS_CONTROLLER) + _esc_controller.set_node_info_publisher(&_node_info_publisher); +#endif + /* Set up shared service clients */ _param_getset_client.setCallback(GetSetCallback(this, &UavcanNode::cb_getset)); _param_opcode_client.setCallback(ExecuteOpcodeCallback(this, &UavcanNode::cb_opcode)); _param_restartnode_client.setCallback(RestartNodeCallback(this, &UavcanNode::cb_restart)); - - int32_t uavcan_enable = 1; - (void)param_get(param_find("UAVCAN_ENABLE"), &uavcan_enable); - if (uavcan_enable > 1) { _servers = new UavcanServers(_node, _node_info_retriever); @@ -962,6 +969,10 @@ UavcanNode::Run() } } +#if defined(CONFIG_UAVCAN_OUTPUTS_CONTROLLER) + _arming_status_controller.setActuatorTestRunning(_mixing_interface_esc.isActuatorTestRunning()); +#endif + perf_end(_cycle_perf); pthread_mutex_unlock(&_node_mutex); @@ -983,9 +994,10 @@ UavcanNode::Run() void UavcanNode::publish_can_interface_statuses() { constexpr hrt_abstime status_pub_interval = 100_ms; + const hrt_abstime now = hrt_absolute_time(); - if (hrt_absolute_time() - _last_can_status_pub >= status_pub_interval) { - _last_can_status_pub = hrt_absolute_time(); + if (now - _last_can_status_pub >= status_pub_interval) { + _last_can_status_pub = now; for (int i = 0; i < _node.getDispatcher().getCanIOManager().getCanDriver().getNumIfaces(); i++) { if (i > UAVCAN_NUM_IFACES) { @@ -1000,7 +1012,7 @@ void UavcanNode::publish_can_interface_statuses() auto iface_perf_cnt = _node.getDispatcher().getCanIOManager().getIfacePerfCounters(i); can_interface_status_s status{ - .timestamp = hrt_absolute_time(), + .timestamp = now, .io_errors = iface_perf_cnt.errors, .frames_tx = iface_perf_cnt.frames_tx, .frames_rx = iface_perf_cnt.frames_rx, @@ -1020,13 +1032,15 @@ void UavcanNode::publish_can_interface_statuses() void UavcanNode::publish_node_statuses() { constexpr hrt_abstime status_pub_interval = 100_ms; + const hrt_abstime now = hrt_absolute_time(); - if (hrt_absolute_time() - _last_node_status_pub >= status_pub_interval) { - _last_node_status_pub = hrt_absolute_time(); + if (now - _last_node_status_pub >= status_pub_interval) { + _last_node_status_pub = now; _node_status_monitor.forEachNode([this](uavcan::NodeID node_id, uavcan::NodeStatusMonitor::NodeStatus node_status) { + auto node_id_val = node_id.get(); - if (node_id.get() == 0) { + if (node_id_val == 0) { return; } @@ -1034,7 +1048,7 @@ void UavcanNode::publish_node_statuses() int uorb_index = -1; for (uint8_t i = 0; i < ORB_MULTI_MAX_INSTANCES; i++) { - if (_node_status_uorb_index_map[i] == node_id.get()) { + if (_node_status_uorb_index_map[i] == node_id_val) { uorb_index = i; break; } @@ -1044,10 +1058,10 @@ void UavcanNode::publish_node_statuses() // use next available index for (uint8_t i = 0; i < ORB_MULTI_MAX_INSTANCES; i++) { if (_node_status_uorb_index_map[i] == 0) { - _node_status_uorb_index_map[i] = node_id.get(); + _node_status_uorb_index_map[i] = node_id_val; uorb_index = i; // advertise - PX4_INFO("advertising node_id %u on index %u", node_id.get(), i); + PX4_INFO("advertising node_id %u on index %u", node_id_val, i); int instance{0}; _node_status_pub_handles[i] = orb_advertise_multi(ORB_ID(dronecan_node_status), nullptr, &instance); break; @@ -1060,7 +1074,7 @@ void UavcanNode::publish_node_statuses() dronecan_node_status_s status{ .timestamp = hrt_absolute_time(), .uptime_sec = node_status.uptime_sec, - .node_id = node_id.get(), + .node_id = node_id_val, .vendor_specific_status_code = node_status.vendor_specific_status_code, .health = node_status.health, .mode = node_status.mode, @@ -1079,7 +1093,22 @@ void UavcanNode::publish_node_statuses() bool UavcanMixingInterfaceESC::updateOutputs(uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs, unsigned num_control_groups_updated) { - _esc_controller.update_outputs(outputs, num_outputs); + if (_esc_controller.initialized()) { + // num_outputs is the maximum possible number of outputs (8) + // output_array_size adapts to the highest output index that is mapped (4 for a quad) + // this allows for sending less CAN frames depending on what output indices are mapped + uint8_t output_array_size = 0; + + for (int i = MAX_ACTUATORS - 1; i >= 0; i--) { + if (mixingOutput().isFunctionSet(i)) { + output_array_size = i + 1; + break; + } + } + + _esc_controller.update_outputs(outputs, output_array_size); + } + return true; } @@ -1134,6 +1163,11 @@ UavcanNode::print_info() printf("\n"); + // See https://github.com/PX4/PX4-Autopilot/issues/22871 + printf("WARNING: CAN error counter values below may increase during this function call due to internal counter reading implementation.\n"); + printf("Do not fully trust these counters until this issue is fixed.\n"); + printf("\n"); + // UAVCAN node perfcounters printf("UAVCAN node status:\n"); printf("\tInternal failures: %" PRIu64 "\n", _node.getInternalFailureCount()); diff --git a/src/drivers/uavcan/uavcan_main.hpp b/src/drivers/uavcan/uavcan_main.hpp index 8af4ae1a3e..56f7c445fe 100644 --- a/src/drivers/uavcan/uavcan_main.hpp +++ b/src/drivers/uavcan/uavcan_main.hpp @@ -45,6 +45,7 @@ #include #include #include +#include "node_info.hpp" #if defined(CONFIG_UAVCAN_OUTPUTS_CONTROLLER) #include "actuators/esc.hpp" @@ -135,6 +136,8 @@ public: MixingOutput &mixingOutput() { return _mixing_output; } + bool isActuatorTestRunning() const { return _mixing_output.isActuatorTestRunning(); } + protected: void Run() override; private: @@ -199,7 +202,7 @@ class UavcanNode : public px4::ScheduledWorkItem, public ModuleParams * 1000000/200 */ - static constexpr unsigned RxQueueLenPerIface = FramePerMSecond * ScheduleIntervalMs; // At + static constexpr unsigned RxQueueLenPerIface = FramePerMSecond * ScheduleIntervalMs; public: typedef UAVCAN_DRIVER::CanInitHelper CanInitHelper; @@ -291,6 +294,7 @@ private: uavcan::NodeStatusMonitor _node_status_monitor; uavcan::NodeInfoRetriever _node_info_retriever; + NodeInfoPublisher _node_info_publisher; List _sensor_bridges; ///< List of active sensor bridges diff --git a/src/drivers/uavcan/uavcan_params.c b/src/drivers/uavcan/uavcan_params.c index 7347c9ca3f..9dd90e2e4c 100644 --- a/src/drivers/uavcan/uavcan_params.c +++ b/src/drivers/uavcan/uavcan_params.c @@ -135,7 +135,7 @@ PARAM_DEFINE_INT32(UAVCAN_ECU_FUELT, 1); * UAVCAN ANTI_COLLISION light operating mode * * This parameter defines the minimum condition under which the system will command - * the ANTI_COLLISION lights on + * lights with anti-collision function to turn on (white). * * 0 - Always off * 1 - When autopilot is armed @@ -153,72 +153,6 @@ PARAM_DEFINE_INT32(UAVCAN_ECU_FUELT, 1); */ PARAM_DEFINE_INT32(UAVCAN_LGT_ANTCL, 2); -/** - * UAVCAN STROBE light operating mode - * - * This parameter defines the minimum condition under which the system will command - * the STROBE lights on - * - * 0 - Always off - * 1 - When autopilot is armed - * 2 - When autopilot is prearmed - * 3 - Always on - * - * @min 0 - * @max 3 - * @value 0 Always off - * @value 1 When autopilot is armed - * @value 2 When autopilot is prearmed - * @value 3 Always on - * @reboot_required true - * @group UAVCAN - */ -PARAM_DEFINE_INT32(UAVCAN_LGT_STROB, 1); - -/** - * UAVCAN RIGHT_OF_WAY light operating mode - * - * This parameter defines the minimum condition under which the system will command - * the RIGHT_OF_WAY lights on - * - * 0 - Always off - * 1 - When autopilot is armed - * 2 - When autopilot is prearmed - * 3 - Always on - * - * @min 0 - * @max 3 - * @value 0 Always off - * @value 1 When autopilot is armed - * @value 2 When autopilot is prearmed - * @value 3 Always on - * @reboot_required true - * @group UAVCAN - */ -PARAM_DEFINE_INT32(UAVCAN_LGT_NAV, 3); - -/** - * UAVCAN LIGHT_ID_LANDING light operating mode - * - * This parameter defines the minimum condition under which the system will command - * the LIGHT_ID_LANDING lights on - * - * 0 - Always off - * 1 - When autopilot is armed - * 2 - When autopilot is prearmed - * 3 - Always on - * - * @min 0 - * @max 3 - * @value 0 Always off - * @value 1 When autopilot is armed - * @value 2 When autopilot is prearmed - * @value 3 Always on - * @reboot_required true - * @group UAVCAN - */ -PARAM_DEFINE_INT32(UAVCAN_LGT_LAND, 0); - /** * publish Arming Status stream * @@ -436,3 +370,15 @@ PARAM_DEFINE_INT32(UAVCAN_SUB_RNG, 0); * @group UAVCAN */ PARAM_DEFINE_INT32(UAVCAN_SUB_BTN, 0); + +/** + * subscription MovingBaselineData + * + * Enable UAVCAN MovingBaselineData subscription. + * ardupilot::gnss::MovingBaselineData + * + * @boolean + * @reboot_required true + * @group UAVCAN + */ +PARAM_DEFINE_INT32(UAVCAN_SUB_MBD, 0); diff --git a/src/drivers/uavcannode/Kconfig b/src/drivers/uavcannode/Kconfig index 532fe3229d..d0edc5d44b 100644 --- a/src/drivers/uavcannode/Kconfig +++ b/src/drivers/uavcannode/Kconfig @@ -34,6 +34,10 @@ if DRIVERS_UAVCANNODE bool "Include GNSS fix" default n + config UAVCANNODE_HARDPOINT_COMMAND + bool "Include hardpoint commands" + default n + config UAVCANNODE_HYGROMETER_MEASUREMENT bool "Include hygrometer measurement" default n diff --git a/src/drivers/uavcannode/Publishers/BatteryInfo.hpp b/src/drivers/uavcannode/Publishers/BatteryInfo.hpp index 686dc05086..00b409400a 100644 --- a/src/drivers/uavcannode/Publishers/BatteryInfo.hpp +++ b/src/drivers/uavcannode/Publishers/BatteryInfo.hpp @@ -36,6 +36,7 @@ #include "UavcanPublisherBase.hpp" #include +#include #include #include @@ -47,15 +48,18 @@ namespace uavcannode class BatteryInfo : public UavcanPublisherBase, private uORB::SubscriptionCallbackWorkItem, - private uavcan::Publisher + private uavcan::Publisher, + private uavcan::Publisher { public: BatteryInfo(px4::WorkItem *work_item, uavcan::INode &node) : UavcanPublisherBase(uavcan::equipment::power::BatteryInfo::DefaultDataTypeID), uORB::SubscriptionCallbackWorkItem(work_item, ORB_ID(battery_status)), - uavcan::Publisher(node) + uavcan::Publisher(node), + uavcan::Publisher(node) { - this->setPriority(uavcan::TransferPriority::MiddleLower); + uavcan::Publisher::setPriority(uavcan::TransferPriority::MiddleLower); + uavcan::Publisher::setPriority(uavcan::TransferPriority::MiddleLower); } void PrintInfo() override @@ -65,36 +69,63 @@ public: uORB::SubscriptionCallbackWorkItem::get_topic()->o_name, uavcan::equipment::power::BatteryInfo::getDataTypeFullName(), uavcan::equipment::power::BatteryInfo::DefaultDataTypeID); + printf("\t%s -> %s:%d\n", + uORB::SubscriptionCallbackWorkItem::get_topic()->o_name, + ardupilot::equipment::power::BatteryInfoAux::getDataTypeFullName(), + ardupilot::equipment::power::BatteryInfoAux::DefaultDataTypeID); } } void BroadcastAnyUpdates() override { - // battery_status -> uavcan::equipment::power::BatteryInfo + // battery_status -> uavcan::equipment::power::BatteryInfo & ardupilot::equipment::power::BatteryInfoAux battery_status_s battery; if (uORB::SubscriptionCallbackWorkItem::update(&battery)) { + ardupilot::equipment::power::BatteryInfoAux battery_info_aux{}; + + battery_info_aux.timestamp.usec = battery.timestamp; + + for (uint8_t i = 0; i < battery.cell_count && i < arraySize(battery_status_s::voltage_cell_v); i++) { + battery_info_aux.voltage_cell.push_back(battery.voltage_cell_v[i]); + } + + battery_info_aux.cycle_count = battery.cycle_count; + battery_info_aux.over_discharge_count = battery.over_discharge_count; + battery_info_aux.max_current = battery.current_a; + battery_info_aux.nominal_voltage = battery.nominal_voltage; + battery_info_aux.is_powering_off = battery.is_powering_off; + battery_info_aux.battery_id = battery.id; + + uavcan::Publisher::broadcast(battery_info_aux); + uavcan::equipment::power::BatteryInfo battery_info{}; battery_info.voltage = battery.voltage_v; - battery_info.current = fabs(battery.current_a); + battery_info.current = battery.current_a; battery_info.temperature = battery.temperature - atmosphere::kAbsoluteNullCelsius; // convert from C to K - battery_info.full_charge_capacity_wh = battery.capacity; - battery_info.remaining_capacity_wh = battery.remaining * battery.capacity; - battery_info.state_of_charge_pct = battery.remaining * 100; + battery_info.full_charge_capacity_wh = battery.full_charge_capacity_wh; + battery_info.remaining_capacity_wh = battery.remaining_capacity_wh; + battery_info.state_of_charge_pct = battery.remaining * 100.0f; battery_info.state_of_charge_pct_stdev = battery.max_error; + battery_info.battery_id = battery.id; battery_info.model_instance_id = 0; // TODO: what goes here? - battery_info.model_name = "ARK BMS Rev 0.2"; - battery_info.battery_id = battery.serial_number; - battery_info.hours_to_full_charge = 0; // TODO: Read BQ40Z80_TIME_TO_FULL + battery_info.model_name = "PX4 CAN Battery"; + + // State of health battery_info.state_of_health_pct = battery.state_of_health; - if (battery.current_a > 0.0f) { - battery_info.status_flags = uavcan::equipment::power::BatteryInfo::STATUS_FLAG_CHARGING; + uint8_t status_flags = 0; - } else { - battery_info.status_flags = uavcan::equipment::power::BatteryInfo::STATUS_FLAG_IN_USE; + if (battery.connected) { + status_flags |= uavcan::equipment::power::BatteryInfo::STATUS_FLAG_IN_USE; } + if (battery.warning == battery_status_s::STATE_CHARGING) { + status_flags |= uavcan::equipment::power::BatteryInfo::STATUS_FLAG_CHARGING; + } + + battery_info.status_flags = status_flags; + uavcan::Publisher::broadcast(battery_info); // ensure callback is registered diff --git a/src/drivers/uavcannode/Publishers/GnssFix2.hpp b/src/drivers/uavcannode/Publishers/GnssFix2.hpp index 4f3223ec48..4f0968c269 100644 --- a/src/drivers/uavcannode/Publishers/GnssFix2.hpp +++ b/src/drivers/uavcannode/Publishers/GnssFix2.hpp @@ -113,10 +113,10 @@ public: } // Diagonal matrix - // position variances -- Xx, Yy, Zz - fix2.covariance.push_back(gps.eph); - fix2.covariance.push_back(gps.eph); - fix2.covariance.push_back(gps.epv); + // position variances -- Xx, Yy, Zz (eph/epv are std dev in meters, must square for variance) + fix2.covariance.push_back(gps.eph * gps.eph); + fix2.covariance.push_back(gps.eph * gps.eph); + fix2.covariance.push_back(gps.epv * gps.epv); // velocity variance -- Vxx, Vyy, Vzz fix2.covariance.push_back(gps.s_variance_m_s); fix2.covariance.push_back(gps.s_variance_m_s); diff --git a/src/drivers/uavcannode/Publishers/MovingBaselineData.hpp b/src/drivers/uavcannode/Publishers/MovingBaselineData.hpp index af6d0dc670..ad90387b42 100644 --- a/src/drivers/uavcannode/Publishers/MovingBaselineData.hpp +++ b/src/drivers/uavcannode/Publishers/MovingBaselineData.hpp @@ -70,44 +70,57 @@ public: void BroadcastAnyUpdates() override { - using ardupilot::gnss::MovingBaselineData; - // gps_inject_data -> ardupilot::gnss::MovingBaselineData - gps_inject_data_s inject_data; + gps_inject_data_s gps_inject_data = {}; + + unsigned last_generation = uORB::SubscriptionCallbackWorkItem::get_last_generation(); + bool updated = false; + + // Drain all available messages from the queue and publish to CAN. + while ((updated = uORB::SubscriptionCallbackWorkItem::update(&gps_inject_data))) { + + unsigned current_generation = uORB::SubscriptionCallbackWorkItem::get_last_generation(); + + if (current_generation != last_generation + 1) { + PX4_WARN("gps_inject_data lost, generation %u -> %u", last_generation, current_generation); + } + + last_generation = current_generation; - if (uORB::SubscriptionCallbackWorkItem::update(&inject_data)) { // Prevent republishing rtcm data we received from uavcan union device::Device::DeviceId device_id; - device_id.devid = inject_data.device_id; + device_id.devid = gps_inject_data.device_id; - if (device_id.devid_s.bus_type != device::Device::DeviceBusType::DeviceBusType_UAVCAN) { - ardupilot::gnss::MovingBaselineData movingbaselinedata{}; + if (device_id.devid_s.bus_type == device::Device::DeviceBusType::DeviceBusType_UAVCAN) { + continue; + } - const size_t capacity = movingbaselinedata.data.capacity(); - size_t written = 0; - int result = 0; + ardupilot::gnss::MovingBaselineData mbd = {}; - while ((result >= 0) && written < inject_data.len) { - size_t chunk_size = inject_data.len - written; + const size_t capacity = mbd.data.capacity(); + size_t written = 0; + int result = 0; - if (chunk_size > capacity) { - chunk_size = capacity; - } + while ((result >= 0) && written < gps_inject_data.len) { + size_t chunk_size = gps_inject_data.len - written; - for (size_t i = 0; i < chunk_size; ++i) { - movingbaselinedata.data.push_back(inject_data.data[written]); - written += 1; - } - - result = uavcan::Publisher::broadcast(movingbaselinedata); - - // ensure callback is registered - uORB::SubscriptionCallbackWorkItem::registerCallback(); - - movingbaselinedata.data.clear(); + if (chunk_size > capacity) { + chunk_size = capacity; } + + for (size_t i = 0; i < chunk_size; i++) { + mbd.data.push_back(gps_inject_data.data[written]); + written += 1; + } + + result = uavcan::Publisher::broadcast(mbd); + + mbd.data.clear(); } } + + // ensure callback is registered + uORB::SubscriptionCallbackWorkItem::registerCallback(); } }; } // namespace uavcannode diff --git a/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp b/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp new file mode 100644 index 0000000000..87aba37593 --- /dev/null +++ b/src/drivers/uavcannode/Subscribers/HardpointCommand.hpp @@ -0,0 +1,123 @@ +/**************************************************************************** + * + * Copyright (c) 2026 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include "UavcanSubscriberBase.hpp" + +#include + +#include +#include + +namespace uavcannode +{ + +class HardpointCommand; + +typedef uavcan::MethodBinder&)> + HardpointCommandBinder; + +class HardpointCommand : + public UavcanSubscriberBase, + private uavcan::Subscriber +{ +public: + HardpointCommand(uavcan::INode &node) : + UavcanSubscriberBase(uavcan::equipment::hardpoint::Command::DefaultDataTypeID), + uavcan::Subscriber(node) + {} + + bool init() + { + if (start(HardpointCommandBinder(this, &HardpointCommand::callback)) < 0) { + PX4_ERR("uavcan::equipment::hardpoint::Command subscription failed"); + return false; + } + + return true; + } + + void PrintInfo() const override + { + printf("\t%s:%d -> %s\n", + uavcan::equipment::hardpoint::Command::getDataTypeFullName(), + uavcan::equipment::hardpoint::Command::DefaultDataTypeID, + _actuator_servos_pub.get_topic()->o_name); + } + +private: + void callback(const uavcan::ReceivedDataStructure &msg) + { + + uint8_t servo_id = msg.hardpoint_id; + actuator_servos_s actuator_servos {}; + + if (servo_id >= actuator_servos_s::NUM_CONTROLS) { + return; + } + + for (uint8_t i = servo_id; i < actuator_servos_s::NUM_CONTROLS; ++i) { + + actuator_servos.timestamp = hrt_absolute_time(); + actuator_servos.timestamp_sample = actuator_servos.timestamp; + + if (msg.command == 1) { + actuator_servos.control[i] = 1; // grip + + } else if (msg.command == 0) { + actuator_servos.control[i] = -1; // release + + } else { + actuator_servos.control[i] = 0; // do nothing + } + + actuator_servos.timestamp = hrt_absolute_time(); + actuator_servos.timestamp_sample = actuator_servos.timestamp; + + // If ID is not 0 (broadcast), do not iterate + if (servo_id != 0) { + break; + } + + } + + _actuator_servos_pub.publish(actuator_servos); + + } + + uORB::Publication _actuator_servos_pub{ORB_ID(actuator_servos)}; + +}; +} // namespace uavcannode diff --git a/src/drivers/uavcannode/UavcanNode.cpp b/src/drivers/uavcannode/UavcanNode.cpp index a79485dbf6..0940791c90 100644 --- a/src/drivers/uavcannode/UavcanNode.cpp +++ b/src/drivers/uavcannode/UavcanNode.cpp @@ -121,6 +121,10 @@ #include "Subscribers/ServoArrayCommand.hpp" #endif // CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND +#if defined(CONFIG_UAVCANNODE_HARDPOINT_COMMAND) +#include "Subscribers/HardpointCommand.hpp" +#endif // CONFIG_UAVCANNODE_HARDPOINT_COMMAND + using namespace time_literals; namespace uavcannode @@ -384,7 +388,13 @@ int UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events #endif // CONFIG_UAVCANNODE_GNSS_FIX #if defined(CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH) - _publisher_list.add(new MagneticFieldStrength2(this, _node)); + int32_t cannode_pub_mag = 1; + param_get(param_find("CANNODE_PUB_MAG"), &cannode_pub_mag); + + if (cannode_pub_mag == 1) { + _publisher_list.add(new MagneticFieldStrength2(this, _node)); + } + #endif // CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH #if defined(CONFIG_UAVCANNODE_RANGE_SENSOR_MEASUREMENT) @@ -421,12 +431,25 @@ int UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events _publisher_list.add(new SafetyButton(this, _node)); #endif // CONFIG_UAVCANNODE_SAFETY_BUTTON +#if defined(CONFIG_UAVCANNODE_STATIC_PRESSURE) || defined(CONFIG_UAVCANNODE_STATIC_TEMPERATURE) + int32_t cannode_pub_bar = 1; + param_get(param_find("CANNODE_PUB_BAR"), &cannode_pub_bar); +#endif + #if defined(CONFIG_UAVCANNODE_STATIC_PRESSURE) - _publisher_list.add(new StaticPressure(this, _node)); + + if (cannode_pub_bar == 1) { + _publisher_list.add(new StaticPressure(this, _node)); + } + #endif // CONFIG_UAVCANNODE_STATIC_PRESSURE #if defined(CONFIG_UAVCANNODE_STATIC_TEMPERATURE) - _publisher_list.add(new StaticTemperature(this, _node)); + + if (cannode_pub_bar == 1) { + _publisher_list.add(new StaticTemperature(this, _node)); + } + #endif // CONFIG_UAVCANNODE_STATIC_TEMPERATURE #if defined(CONFIG_UAVCANNODE_ARMING_STATUS) @@ -466,6 +489,10 @@ int UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events _subscriber_list.add(new ServoArrayCommand(_node)); #endif // CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND +#if defined(CONFIG_UAVCANNODE_HARDPOINT_COMMAND) + _subscriber_list.add(new HardpointCommand(_node)); +#endif // CONFIG_UAVCANNODE_HARDPOINT_COMMAND + for (auto &subscriber : _subscriber_list) { subscriber->init(); } @@ -505,12 +532,16 @@ void UavcanNode::Run() if (can_init_res < 0) { PX4_ERR("CAN driver init failed %i", can_init_res); + ScheduleClear(); + return; } int rv = _node.start(); if (rv < 0) { PX4_ERR("Failed to start the node"); + ScheduleClear(); + return; } // If the node_id was not supplied by the bootloader do Dynamic Node ID allocation @@ -528,6 +559,8 @@ void UavcanNode::Run() if (client_start_res < 0) { PX4_ERR("Failed to start the dynamic node ID client"); + ScheduleClear(); + return; } } } @@ -541,7 +574,7 @@ void UavcanNode::Run() */ if (_dyn_node_id_client.isAllocationComplete()) { - PX4_INFO("Got node ID %d", _dyn_node_id_client.getAllocatedNodeID().get()); + PX4_INFO("Assigned node ID %d", _dyn_node_id_client.getAllocatedNodeID().get()); _node.setNodeID(_dyn_node_id_client.getAllocatedNodeID()); _init_state = Allocated; @@ -818,6 +851,24 @@ extern "C" int uavcannode_start(int argc, char *argv[]) } } + // Use a static node ID if the parameter is set and in range + int32_t cannode_node_id = 0; + param_get(param_find("CANNODE_NODE_ID"), &cannode_node_id); + + if (cannode_node_id < 0 || cannode_node_id > uavcan::NodeID::Max) { + PX4_ERR("Invalid static node ID %ld, using dynamic allocation", cannode_node_id); + node_id = 0; + + } else { + node_id = cannode_node_id; + } + + // Persist the node ID for the bootloader + bootloader_app_shared_t shared_write = {}; + shared_write.node_id = node_id; + shared_write.bus_speed = 0; // we always want to autobaud + bootloader_app_shared_write(&shared_write, BootLoader); + if ( #if defined(SUPPORT_ALT_CAN_BOOTLOADER) board_booted_by_px4() && diff --git a/src/drivers/uavcannode/uavcannode_params.c b/src/drivers/uavcannode/uavcannode_params.c index 8546989954..a87817b885 100644 --- a/src/drivers/uavcannode/uavcannode_params.c +++ b/src/drivers/uavcannode/uavcannode_params.c @@ -31,6 +31,15 @@ * ****************************************************************************/ +/** + * UAVCAN CAN node ID (0 for dynamic allocation). + * + * @min 0 + * @max 127 + * @group UAVCAN + */ +PARAM_DEFINE_INT32(CANNODE_NODE_ID, 0); + /** * UAVCAN CAN bus bitrate. * @@ -85,3 +94,29 @@ PARAM_DEFINE_INT32(CANNODE_PUB_MBD, 0); * @group UAVCAN */ PARAM_DEFINE_INT32(CANNODE_PUB_IMU, 0); + +/** + * Enable barometer publication + * + * Enables publication of static pressure and static temperature + * from the barometer sensor over UAVCAN. + * + * @boolean + * @max 1 + * @reboot_required true + * @group UAVCAN + */ +PARAM_DEFINE_INT32(CANNODE_PUB_BAR, 1); + +/** + * Enable magnetometer publication + * + * Enables publication of magnetic field strength + * from the magnetometer sensor over UAVCAN. + * + * @boolean + * @max 1 + * @reboot_required true + * @group UAVCAN + */ +PARAM_DEFINE_INT32(CANNODE_PUB_MAG, 1); diff --git a/src/drivers/voxl2_io/voxl2_io.cpp b/src/drivers/voxl2_io/voxl2_io.cpp index 66551e468a..cf29e15631 100644 --- a/src/drivers/voxl2_io/voxl2_io.cpp +++ b/src/drivers/voxl2_io/voxl2_io.cpp @@ -58,7 +58,7 @@ Voxl2IO::~Voxl2IO() int Voxl2IO::init() { - PX4_INFO("VOXL2_IO: Driver starting"); + PX4_INFO("Driver starting"); int ret = PX4_OK; @@ -66,18 +66,16 @@ int Voxl2IO::init() ret = update_params(); if (ret != OK) { - PX4_ERR("VOXL2_IO: Failed to update params during init"); + PX4_ERR("Failed to update params during init"); return ret; } // Print initial param values print_params(); - PX4_INFO("VOXL2_IO: "); - // Open serial port if (!_uart_port.isOpen()) { - PX4_INFO("VOXL2_IO: Opening UART ESC device %s, baud rate %" PRIi32, _device, _parameters.baud_rate); + PX4_INFO("Opening UART ESC device %s, baud rate %" PRIi32, _device, _parameters.baud_rate); // Configure UART port if (! _uart_port.setPort(_device)) { @@ -101,11 +99,11 @@ int Voxl2IO::init() ret = get_version_info(); if (ret != 0) { - PX4_ERR("VOXL2_IO: Could not detect the board"); - PX4_ERR("VOXL2_IO: Driver initialization failed. Exiting"); + PX4_ERR("Could not detect the board"); + PX4_ERR("Driver initialization failed. Exiting"); if (_uart_port.open()) { - PX4_INFO("VOXL2_IO: Closing uart port"); + PX4_INFO("Closing uart port"); _uart_port.close(); } @@ -115,7 +113,7 @@ int Voxl2IO::init() //ScheduleOnInterval(_current_update_interval); ScheduleNow(); - PX4_INFO("VOXL2_IO: Driver initialization succeeded"); + PX4_INFO("Driver initialization succeeded"); return ret; } @@ -171,7 +169,7 @@ int Voxl2IO::load_params(voxl2_io_params_t *params) // Validate PWM min and max values if (params->pwm_min > params->pwm_max) { - PX4_ERR("VOXL2_IO: Invalid parameter VOXL2_IO_MIN. Please verify parameters."); + PX4_ERR("Invalid parameter VOXL2_IO_MIN. Please verify parameters."); params->pwm_min = 0; ret = PX4_ERROR; } @@ -181,7 +179,7 @@ int Voxl2IO::load_params(voxl2_io_params_t *params) int Voxl2IO::get_version_info() { - PX4_INFO("VOXL2_IO: Detecting M0065 board..."); + PX4_INFO("Detecting M0065 board..."); voxl2_io_packet_init(&_voxl2_io_packet); Command cmd; @@ -195,7 +193,7 @@ int Voxl2IO::get_version_info() //send the version request command to the board if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { - PX4_ERR("VOXL2_IO: Could not write version request packet to UART port"); + PX4_ERR("Could not write version request packet to UART port"); return -1; } @@ -226,31 +224,31 @@ int Voxl2IO::get_version_info() VOXL2_IO_EXTENDED_VERSION_INFO ver; memcpy(&ver, _voxl2_io_packet.buffer, packet_size); - PX4_INFO("VOXL2_IO: \tVOXL2_IO ID: %i", ver.id); - PX4_INFO("VOXL2_IO: \tBoard Type : %i: %s", ver.hw_version, board_id_to_name(ver.hw_version).c_str()); + PX4_INFO("\tVOXL2_IO ID: %i", ver.id); + PX4_INFO("\tBoard Type : %i: %s", ver.hw_version, board_id_to_name(ver.hw_version).c_str()); uint8_t *u = &ver.unique_id[0]; - PX4_INFO("VOXL2_IO: \tUnique ID : 0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + PX4_INFO("\tUnique ID : 0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", u[11], u[10], u[9], u[8], u[7], u[6], u[5], u[4], u[3], u[2], u[1], u[0]); - PX4_INFO("VOXL2_IO: \tFirmware : version %4d, hash %.12s", ver.sw_version, ver.firmware_git_version); - PX4_INFO("VOXL2_IO: \tBootloader : version %4d, hash %.12s", ver.bootloader_version, ver.bootloader_git_version); - PX4_INFO("VOXL2_IO: \tReply time : %uus", (uint32_t)response_time); + PX4_INFO("\tFirmware : version %4d, hash %.12s", ver.sw_version, ver.firmware_git_version); + PX4_INFO("\tBootloader : version %4d, hash %.12s", ver.bootloader_version, ver.bootloader_git_version); + PX4_INFO("\tReply time : %uus", (uint32_t)response_time); //we requested response from ID 0, so it should match if (ver.id != 0) { - PX4_ERR("VOXL2_IO: Invalid id: %d", ver.id); + PX4_ERR("Invalid id: %d", ver.id); } //check HW (board version) else if (ver.hw_version != VOXL2_IO_HW_VERSION) { - PX4_ERR("VOXL2_IO: Invalid HW version : %d (expected %d)", ver.hw_version, VOXL2_IO_HW_VERSION); + PX4_ERR("Invalid HW version : %d (expected %d)", ver.hw_version, VOXL2_IO_HW_VERSION); return -1; } //check firmware version running on the board else if (ver.sw_version != VOXL2_IO_SW_VERSION) { - PX4_ERR("VOXL2_IO: Invalid FW version : %d (expected %d)", ver.sw_version, VOXL2_IO_SW_VERSION); + PX4_ERR("Invalid FW version : %d (expected %d)", ver.sw_version, VOXL2_IO_SW_VERSION); return -1; } else { @@ -269,13 +267,38 @@ int Voxl2IO::get_version_info() if (!got_response) { - PX4_ERR("VOXL2_IO: Board version info response timeout (%d retries left)", retries_left); + PX4_ERR("Board version info response timeout (%d retries left)", retries_left); } } return (got_response == true ? 0 : -1); } +int Voxl2IO::handle_uart_passthru() +{ + int num_writes = 0; + + // Don't do these faster than 20Hz + if (hrt_elapsed_time(&_last_uart_passthru) > 50_ms) { + _last_uart_passthru = hrt_absolute_time(); + + // Don't do more than a few writes each check + while (_io_serial_passthru_sub.updated() && (num_writes < 4)) { + mavlink_tunnel_s uart_passthru{}; + _io_serial_passthru_sub.copy(&uart_passthru); + + if (_uart_port.write(uart_passthru.payload, uart_passthru.payload_length) != uart_passthru.payload_length) { + PX4_ERR("Failed to send mavlink tunnel data"); + return false; + } + + num_writes++; + } + } + + return num_writes; +} + bool Voxl2IO::updateOutputs(uint16_t outputs[input_rc_s::RC_INPUT_MAX_CHANNELS], unsigned num_outputs, unsigned num_control_groups_updated) { @@ -284,14 +307,14 @@ bool Voxl2IO::updateOutputs(uint16_t outputs[input_rc_s::RC_INPUT_MAX_CHANNELS], return 0; } - //PX4_INFO("VOXL2_IO: Mixer output: %u, %u, %u, %u", outputs[0], outputs[1], outputs[2], outputs[3]); + //PX4_INFO("Mixer output: %u, %u, %u, %u", outputs[0], outputs[1], outputs[2], outputs[3]); //in Run() we call _mixing_output.update(), which calls MixingOutput::limitAndUpdateOutputs which calls _interface.updateOutputs (this function) //So, if Run() is blocked by a custom command, this function will not be called until Run is running again uint32_t output_cmds[VOXL2_IO_OUTPUT_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; if (num_outputs != VOXL2_IO_OUTPUT_CHANNELS) { - PX4_ERR("VOXL2_IO: Num outputs != VOXL2_IO_OUTPUT_CHANNELS!"); + PX4_ERR("Num outputs != VOXL2_IO_OUTPUT_CHANNELS!"); return false; } @@ -312,7 +335,7 @@ bool Voxl2IO::updateOutputs(uint16_t outputs[input_rc_s::RC_INPUT_MAX_CHANNELS], cmd.len = voxl2_io_create_hires_pwm_packet(output_cmds, VOXL2_IO_OUTPUT_CHANNELS, cmd.buf, sizeof(cmd.buf)); if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { - PX4_ERR("VOXL2_IO: Failed to send packet"); + PX4_ERR("Failed to send packet"); return false; } else { @@ -322,7 +345,7 @@ bool Voxl2IO::updateOutputs(uint16_t outputs[input_rc_s::RC_INPUT_MAX_CHANNELS], //if (_pwm_on && _debug){ if (_debug) { - PX4_INFO("VOXL2_IO: Mixer outputs: [%u, %u, %u, %u, %u, %u, %u, %u]", + PX4_INFO("Mixer outputs: [%u, %u, %u, %u, %u, %u, %u, %u]", outputs[0], outputs[1], outputs[2], outputs[3], outputs[4], outputs[5], outputs[6], outputs[7]); } @@ -360,23 +383,23 @@ int Voxl2IO::parse_response(uint8_t *buf, uint8_t len) } else { //parser error switch (ret) { case VOXL2_IO_ERROR_BAD_CHECKSUM: - if(_pwm_on && _debug) PX4_WARN("VOXL2_IO: BAD packet checksum"); + if(_pwm_on && _debug) PX4_WARN("BAD packet checksum"); break; case VOXL2_IO_ERROR_BAD_LENGTH: - if(_pwm_on && _debug) PX4_WARN("VOXL2_IO: BAD packet length"); + if(_pwm_on && _debug) PX4_WARN("BAD packet length"); break; case VOXL2_IO_ERROR_BAD_HEADER: - if(_pwm_on && _debug) PX4_WARN("VOXL2_IO: BAD packet header"); + if(_pwm_on && _debug) PX4_WARN("BAD packet header"); break; case VOXL2_IO_NO_PACKET: - // if(_pwm_on) PX4_WARN("VOXL2_IO: NO packet"); + // if(_pwm_on) PX4_WARN("NO packet"); break; default: - if(_pwm_on && _debug) PX4_WARN("VOXL2_IO: Unknown error: %i", ret); + if(_pwm_on && _debug) PX4_WARN("Unknown error: %i", ret); break; } } @@ -457,8 +480,8 @@ int Voxl2IO::parse_sbus_packet(uint8_t *raw_data, uint32_t data_len) if (rc_updated) { //if (_pwm_on && _debug){ if (_debug) { - //PX4_INFO("VOXL2_IO: Decoded packet, header pos: %i", header); - PX4_INFO("VOXL2_IO: [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]", + //PX4_INFO("Decoded packet, header pos: %i", header); + PX4_INFO("[%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]", _raw_rc_values[0], _raw_rc_values[1], _raw_rc_values[2], _raw_rc_values[3], _raw_rc_values[4], _raw_rc_values[5], _raw_rc_values[6], _raw_rc_values[7], _raw_rc_values[8], @@ -468,7 +491,7 @@ int Voxl2IO::parse_sbus_packet(uint8_t *raw_data, uint32_t data_len) ); if (sbus_frame_drop) { - PX4_WARN("VOXL2_IO: SBUS frame dropped"); + PX4_WARN("SBUS frame dropped"); } } @@ -483,7 +506,7 @@ int Voxl2IO::parse_sbus_packet(uint8_t *raw_data, uint32_t data_len) _rc_pub.publish(input_rc); if (_rc_mode == RC_MODE::SCAN) { - PX4_INFO("VOXL2_IO: Detected VOXL2 IO SBUS RC"); + PX4_INFO("Detected VOXL2 IO SBUS RC"); _rc_mode = RC_MODE::SBUS; } } @@ -498,7 +521,7 @@ int Voxl2IO::receive_uart_packets() if (nread > 0) { if (_debug) { - PX4_INFO("VOXL2_IO: receive_uart_packets read %d bytes", nread); + PX4_INFO("receive_uart_packets read %d bytes", nread); } _bytes_received += nread; @@ -561,6 +584,13 @@ void Voxl2IO::Run() /* check at end of cycle (updateSubscriptions() can potentially change to a different WorkQueue thread) */ _mixing_output.updateSubscriptions(true); + + int num_writes = handle_uart_passthru(); + + if (_debug && num_writes) { + PX4_INFO("UART Passthru wrote %d packets", num_writes); + } + perf_end(_cycle_perf); } @@ -580,17 +610,17 @@ int Voxl2IO::task_spawn(int argc, char *argv[]) while ((ch = px4_getopt(argc - 1, argv, "vdep:", &myoptind, &myoptarg)) != EOF) { switch (ch) { case 'v': - PX4_INFO("VOXL2_IO: Verbose mode enabled"); + PX4_INFO("Verbose mode enabled"); get_instance()->_debug = true; break; case 'd': - PX4_INFO("VOXL2_IO: M0065 PWM outputs disabled"); + PX4_INFO("M0065 PWM outputs disabled"); get_instance()->_outputs_disabled = true; break; case 'e': - PX4_INFO("VOXL2_IO: M0065 using external RC"); + PX4_INFO("M0065 using external RC"); get_instance()->_rc_mode = RC_MODE::EXTERNAL; break; @@ -599,7 +629,7 @@ int Voxl2IO::task_spawn(int argc, char *argv[]) snprintf(get_instance()->_device, 2, "%s", myoptarg); } else { - PX4_ERR("VOXL2_IO: Bad UART port number: %s (must be 2, 6, or 7).", myoptarg); + PX4_ERR("Bad UART port number: %s (must be 2, 6, or 7).", myoptarg); _object.store(nullptr); _task_id = -1; return PX4_ERROR; @@ -608,7 +638,7 @@ int Voxl2IO::task_spawn(int argc, char *argv[]) break; default: - print_usage("VOXL2_IO: Unknown command, parsing flags"); + print_usage("Unknown command, parsing flags"); break; } } @@ -618,7 +648,7 @@ int Voxl2IO::task_spawn(int argc, char *argv[]) } } else { - PX4_ERR("VOXL2_IO: alloc failed"); + PX4_ERR("alloc failed"); } _object.store(nullptr); @@ -636,13 +666,13 @@ int Voxl2IO::calibrate_escs() Command cmd; - PX4_INFO("VOXL2_IO: PWM ESC calibration is starting!"); + PX4_INFO("PWM ESC calibration is starting!"); // Give user 10 seconds to plug in PWM cable for ESCs - PX4_INFO("VOXL2_IO: MIN PWM used for ESC Calibration : %" PRId32, _parameters.pwm_cal_min); - PX4_INFO("VOXL2_IO: MAX PWM used for ESC Calibration : %" PRId32, _parameters.pwm_cal_max); + PX4_INFO("MIN PWM used for ESC Calibration : %" PRId32, _parameters.pwm_cal_min); + PX4_INFO("MAX PWM used for ESC Calibration : %" PRId32, _parameters.pwm_cal_max); PX4_INFO("VOXL2_IO:"); - PX4_INFO("VOXL2_IO: Connect your ESCs! (Calibration will start in ~10 seconds)"); + PX4_INFO("Connect your ESCs! (Calibration will start in ~10 seconds)"); px4_usleep(10000000); @@ -658,7 +688,7 @@ int Voxl2IO::calibrate_escs() } if (_debug) { - PX4_INFO("VOXL2_IO: Scaled max pwms: %u %u %u %u %u %u %u %u", + PX4_INFO("Scaled max pwms: %u %u %u %u %u %u %u %u", max_pwm_cmds[0], max_pwm_cmds[1], max_pwm_cmds[2], max_pwm_cmds[3], max_pwm_cmds[4], max_pwm_cmds[5], max_pwm_cmds[6], max_pwm_cmds[7]); } @@ -666,13 +696,13 @@ int Voxl2IO::calibrate_escs() hrt_abstime start; // Send PWM max every 2.5ms for 5 seconds - PX4_INFO("VOXL2_IO: Sending PWM MAX (%dus) for 5 seconds!", _parameters.pwm_cal_max); + PX4_INFO("Sending PWM MAX (%dus) for 5 seconds!", _parameters.pwm_cal_max); cmd.len = voxl2_io_create_hires_pwm_packet(max_pwm_cmds, VOXL2_IO_OUTPUT_CHANNELS, cmd.buf, sizeof(cmd.buf)); start = hrt_absolute_time(); while (hrt_elapsed_time(&start) < 5000000) { if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { - PX4_ERR("VOXL2_IO: ESC Calibration failed: Failed to send PWM MAX packet"); + PX4_ERR("ESC Calibration failed: Failed to send PWM MAX packet"); _outputs_disabled = false; return -1; } @@ -681,10 +711,10 @@ int Voxl2IO::calibrate_escs() } // Send PWM min every 2.5ms for 5 seconds - PX4_INFO("VOXL2_IO: Sending PWM MIN (%dus) for 5 seconds!", _parameters.pwm_cal_min); + PX4_INFO("Sending PWM MIN (%dus) for 5 seconds!", _parameters.pwm_cal_min); if (_debug) { - PX4_INFO("VOXL2_IO: Scaled min pwms: %u %u %u %u %u %u %u %u", + PX4_INFO("Scaled min pwms: %u %u %u %u %u %u %u %u", min_pwm_cmds[0], min_pwm_cmds[1], min_pwm_cmds[2], min_pwm_cmds[3], min_pwm_cmds[4], min_pwm_cmds[5], min_pwm_cmds[6], min_pwm_cmds[7]); } @@ -696,7 +726,7 @@ int Voxl2IO::calibrate_escs() while (hrt_elapsed_time(&start) < 5000000) { if (_uart_port.write(cmd.buf, cmd.len) != cmd.len) { - PX4_ERR("VOXL2_IO: ESC Calibration failed: Failed to send PWM MIN packet"); + PX4_ERR("ESC Calibration failed: Failed to send PWM MIN packet"); _outputs_disabled = false; return -1; } @@ -704,10 +734,10 @@ int Voxl2IO::calibrate_escs() px4_usleep(2500); } - PX4_INFO("VOXL2_IO: Waiting 5 seconds to finish the calibration (no PWM output)"); + PX4_INFO("Waiting 5 seconds to finish the calibration (no PWM output)"); px4_usleep(5000000); - PX4_INFO("VOXL2_IO: ESC Calibration complete"); + PX4_INFO("ESC Calibration complete"); _outputs_disabled = false; return 0; } @@ -720,7 +750,7 @@ int Voxl2IO::custom_command(int argc, char *argv[]) return print_usage("unknown command: missing args"); } - PX4_INFO("VOXL2_IO: Executing the following command: %s", verb); + PX4_INFO("Executing the following command: %s", verb); /* start if not running */ if (!strcmp(verb, "start")) { @@ -728,12 +758,12 @@ int Voxl2IO::custom_command(int argc, char *argv[]) return Voxl2IO::task_spawn(argc, argv); } - PX4_INFO("VOXL2_IO: Already running"); + PX4_INFO("Already running"); return 0; } if (!is_running()) { - PX4_INFO("VOXL2_IO: Not running"); + PX4_INFO("Not running"); return -1; } @@ -744,7 +774,7 @@ int Voxl2IO::custom_command(int argc, char *argv[]) if (!strcmp(verb, "calibrate_escs")) { if (get_instance()->_outputs_disabled) { - PX4_WARN("VOXL2_IO: Can't calibrate ESCs while outputs are disabled."); + PX4_WARN("Can't calibrate ESCs while outputs are disabled."); return -1; } @@ -760,19 +790,19 @@ int Voxl2IO::custom_command(int argc, char *argv[]) int Voxl2IO::print_status() { - //PX4_INFO("VOXL2_IO: Max update rate: %u Hz", 1000000/_current_update_interval); - //PX4_INFO("VOXL2_IO: PWM Rate: 400 Hz"); // Only support 400 Hz for now - PX4_INFO("VOXL2_IO: Outputs on : %s", _pwm_on ? "yes" : "no"); - PX4_INFO("VOXL2_IO: SW version : %u", _version_info.sw_version); - PX4_INFO("VOXL2_IO: HW version : %u: %s", _version_info.hw_version, + //PX4_INFO("Max update rate: %u Hz", 1000000/_current_update_interval); + //PX4_INFO("PWM Rate: 400 Hz"); // Only support 400 Hz for now + PX4_INFO("Outputs on : %s", _pwm_on ? "yes" : "no"); + PX4_INFO("SW version : %u", _version_info.sw_version); + PX4_INFO("HW version : %u: %s", _version_info.hw_version, board_id_to_name(_version_info.hw_version).c_str()); - PX4_INFO("VOXL2_IO: RC Type : SBUS"); // Only support SBUS through M0065 for now - PX4_INFO("VOXL2_IO: RC Connected : %s", hrt_absolute_time() - _rc_last_valid_time > 500000 ? "no" : "yes"); - PX4_INFO("VOXL2_IO: RC Packets Rxd : %" PRIu16, _sbus_total_frames); - PX4_INFO("VOXL2_IO: UART port : %s", _device); - PX4_INFO("VOXL2_IO: UART open : %s", _uart_port.open() ? "yes" : "no"); - PX4_INFO("VOXL2_IO: Packets sent : %" PRIu32, _packets_sent); - PX4_INFO("VOXL2_IO: "); + PX4_INFO("RC Type : SBUS"); // Only support SBUS through M0065 for now + PX4_INFO("RC Connected : %s", hrt_absolute_time() - _rc_last_valid_time > 500000 ? "no" : "yes"); + PX4_INFO("RC Packets Rxd : %" PRIu16, _sbus_total_frames); + PX4_INFO("UART port : %s", _device); + PX4_INFO("UART open : %s", _uart_port.open() ? "yes" : "no"); + PX4_INFO("Packets sent : %" PRIu32, _packets_sent); + PX4_INFO(""); print_params(); perf_print_counter(_cycle_perf); @@ -831,20 +861,20 @@ std::string Voxl2IO::board_id_to_name(int board_id) void Voxl2IO::print_params() { - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_BAUD : %" PRId32, _parameters.baud_rate); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC1 : %" PRId32, _parameters.function_map[0]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC2 : %" PRId32, _parameters.function_map[1]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC3 : %" PRId32, _parameters.function_map[2]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC4 : %" PRId32, _parameters.function_map[3]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC5 : %" PRId32, _parameters.function_map[4]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC6 : %" PRId32, _parameters.function_map[5]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC7 : %" PRId32, _parameters.function_map[6]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_FUNC8 : %" PRId32, _parameters.function_map[7]); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_DIS : %" PRId32, _parameters.pwm_dis); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_MIN : %" PRId32, _parameters.pwm_min); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_MAX : %" PRId32, _parameters.pwm_max); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_CMIN : %" PRId32, _parameters.pwm_cal_min); - PX4_INFO("VOXL2_IO: Params: VOXL2_IO_CMAX : %" PRId32, _parameters.pwm_cal_max); + PX4_INFO("Params: VOXL2_IO_BAUD : %" PRId32, _parameters.baud_rate); + PX4_INFO("Params: VOXL2_IO_FUNC1 : %" PRId32, _parameters.function_map[0]); + PX4_INFO("Params: VOXL2_IO_FUNC2 : %" PRId32, _parameters.function_map[1]); + PX4_INFO("Params: VOXL2_IO_FUNC3 : %" PRId32, _parameters.function_map[2]); + PX4_INFO("Params: VOXL2_IO_FUNC4 : %" PRId32, _parameters.function_map[3]); + PX4_INFO("Params: VOXL2_IO_FUNC5 : %" PRId32, _parameters.function_map[4]); + PX4_INFO("Params: VOXL2_IO_FUNC6 : %" PRId32, _parameters.function_map[5]); + PX4_INFO("Params: VOXL2_IO_FUNC7 : %" PRId32, _parameters.function_map[6]); + PX4_INFO("Params: VOXL2_IO_FUNC8 : %" PRId32, _parameters.function_map[7]); + PX4_INFO("Params: VOXL2_IO_DIS : %" PRId32, _parameters.pwm_dis); + PX4_INFO("Params: VOXL2_IO_MIN : %" PRId32, _parameters.pwm_min); + PX4_INFO("Params: VOXL2_IO_MAX : %" PRId32, _parameters.pwm_max); + PX4_INFO("Params: VOXL2_IO_CMIN : %" PRId32, _parameters.pwm_cal_min); + PX4_INFO("Params: VOXL2_IO_CMAX : %" PRId32, _parameters.pwm_cal_max); } extern "C" __EXPORT int voxl2_io_main(int argc, char *argv[]); diff --git a/src/drivers/voxl2_io/voxl2_io.hpp b/src/drivers/voxl2_io/voxl2_io.hpp index 31f9cac9da..1f9c6c2eaa 100644 --- a/src/drivers/voxl2_io/voxl2_io.hpp +++ b/src/drivers/voxl2_io/voxl2_io.hpp @@ -55,6 +55,7 @@ #include #include #include +#include #include "voxl2_io_packet.h" #include "voxl2_io_packet_types.h" @@ -188,9 +189,11 @@ private: /* Subscriptions */ uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)}; + uORB::Subscription _io_serial_passthru_sub{ORB_ID(io_serial_passthru)}; bool _pwm_on{false}; bool _outputs_disabled{false}; + hrt_abstime _last_uart_passthru{0}; perf_counter_t _cycle_perf; perf_counter_t _output_update_perf; @@ -208,4 +211,5 @@ private: int update_params(); int calibrate_escs(); std::string board_id_to_name(int board_id); + int handle_uart_passthru(); }; diff --git a/src/drivers/vtx/CMakeLists.txt b/src/drivers/vtx/CMakeLists.txt new file mode 100644 index 0000000000..a82953f579 --- /dev/null +++ b/src/drivers/vtx/CMakeLists.txt @@ -0,0 +1,43 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__vtx + MAIN vtx + COMPILE_FLAGS + SRCS + VTX.cpp + smart_audio.cpp + tramp.cpp + MODULE_CONFIG + module.yaml + ) diff --git a/src/drivers/vtx/Kconfig b/src/drivers/vtx/Kconfig new file mode 100644 index 0000000000..e4d7ac73aa --- /dev/null +++ b/src/drivers/vtx/Kconfig @@ -0,0 +1,18 @@ +menuconfig DRIVERS_VTX + bool "VTX Driver" + default n + select DRIVERS_VTXTABLE + select VTXTABLE_AUX_MAP + ---help--- + Control VTX devices via serial interface. + +if DRIVERS_VTX + + config VTX_CRSF_MSP_SUPPORT + bool "Support using CRSF MSP commands to configure VTX" + depends on DRIVERS_RC_CRSF_RC + default n + ---help--- + Set VTX frequency and power via CRSF MSP messages. + +endif # DRIVERS_VTX diff --git a/src/drivers/vtx/VTX.cpp b/src/drivers/vtx/VTX.cpp new file mode 100644 index 0000000000..790e813694 --- /dev/null +++ b/src/drivers/vtx/VTX.cpp @@ -0,0 +1,482 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "VTX.hpp" + +#include +#include +#include +#include "smart_audio.h" +#include "tramp.h" + +using namespace time_literals; + +VTX::VTX(const char *device) : + ModuleParams(nullptr), + ScheduledWorkItem(MODULE_NAME, px4::serial_port_to_wq(device)), + _perf_cycle(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")), + _perf_error(perf_alloc(PC_COUNT, MODULE_NAME": errors")), + _perf_get_settings(perf_alloc(PC_COUNT, MODULE_NAME": errors get settings")), + _perf_set_power(perf_alloc(PC_COUNT, MODULE_NAME": errors set power")), + _perf_set_frequency(perf_alloc(PC_COUNT, MODULE_NAME": errors set frequency")), + _perf_set_pit_mode(perf_alloc(PC_COUNT, MODULE_NAME": errors set pit mode")) +{ + if (device) { + strlcpy(_serial_path, device, sizeof(_serial_path)); + } +} + +VTX::~VTX() +{ + delete _protocol; + perf_free(_perf_cycle); + perf_free(_perf_error); + perf_free(_perf_get_settings); + perf_free(_perf_set_power); + perf_free(_perf_set_frequency); + perf_free(_perf_set_pit_mode); +} + +int VTX::init() +{ + _param_vtx_device.update(); + _device = (_param_vtx_device.get() >> 8); + const uint8_t protocol = (_param_vtx_device.get() & 0xff); + + if (_protocol == nullptr) { + if (protocol == vtx_s::PROTOCOL_TRAMP) { + _protocol = new vtx::Tramp(); + + } else { + _protocol = new vtx::SmartAudio(); + } + } + + if (_protocol == nullptr) { + PX4_ERR("Protocol alloc failed"); + return PX4_ERROR; + } + + if (_protocol->init(_serial_path) != PX4_OK) { + return PX4_ERROR; + } + + return PX4_OK; +} + +void VTX::Run() +{ + static constexpr auto _INTERVAL{50_ms}; + + if (should_exit()) { + exit_and_cleanup(); + return; + } + + perf_begin(_perf_cycle); + + switch (_state) { + case STATE_INIT: + if (init() == PX4_OK) { + _state = STATE_UPDATE; + _pending = STATE_SET_ALL; + + } else { + perf_count(_perf_error); + } + + break; + + case STATE_GET_SETTINGS: + if (_protocol->get_settings() == PX4_OK) { + if (!_comms_ok) { + // previous get settings failed, send all settings again + _pending |= STATE_SET_ALL; + } + + _pending &= ~STATE_GET_SETTINGS; + _comms_ok = true; + + } else { + perf_count(_perf_get_settings); + _comms_ok = false; + } + + _update_counter = 1_s / _INTERVAL; + _state = STATE_UPDATE; + break; + + case STATE_SET_FREQUENCY: + if ((_frequency ? _protocol->set_frequency(_frequency) : _protocol->set_channel(_band, _channel)) == PX4_OK) { + _pending &= ~STATE_SET_FREQUENCY; + _pending |= STATE_GET_SETTINGS; + + } else { + perf_count(_perf_set_frequency); + } + + _state = STATE_UPDATE; + break; + + case STATE_SET_POWER: + if (_protocol->set_power(_power) == PX4_OK) { + _pending &= ~STATE_SET_POWER; + _pending |= STATE_GET_SETTINGS; + + } else { + perf_count(_perf_set_power); + } + + _state = STATE_UPDATE; + break; + + case STATE_SET_PIT_MODE: + if (_protocol->set_pit_mode(_pit_mode) == PX4_OK) { + _pending &= ~STATE_SET_PIT_MODE; + _pending |= STATE_GET_SETTINGS; + + } else { + perf_count(_perf_set_pit_mode); + } + + _state = STATE_UPDATE; + break; + + default: + // Poll parameters and update settings if needed + int new_band{_band}, new_channel{_channel}, new_frequency{_frequency}, new_power{_power}, new_pit_mode{_pit_mode}; + update_params(&new_band, &new_channel, &new_frequency, &new_power, &new_pit_mode); + + const vtx::Config::ChangeType current_change = vtxtable().get_change(); + + if (_last_config_change != current_change) { + _last_config_change = current_change; + _pending |= STATE_SET_ALL; + } + + if (_band != new_band || _channel != new_channel) { + _band = new_band; + _channel = new_channel; + _pending |= STATE_SET_FREQUENCY; + } + + if (_frequency != new_frequency) { + _frequency = new_frequency; + _pending |= STATE_SET_FREQUENCY; + } + + if (_power != new_power) { + _power = new_power; + _pending |= STATE_SET_POWER; + } + + if (_pit_mode != new_pit_mode) { + _pit_mode = new_pit_mode; + // Some VTX set power to 0 in pit mode, so also set power again + _pending |= STATE_SET_PIT_MODE | STATE_SET_POWER; + } + + if (_update_counter <= 0) { + _pending |= STATE_GET_SETTINGS; + + } else { + _update_counter--; + } + + // Round robin schedule the next pending flag test + uint8_t current{0}; + + while (_pending && !current) { + current = uint8_t(_pending & _schedule); + _schedule <<= 1; + + if (!(_schedule & STATE_MASK)) { + _schedule = STATE_GET_SETTINGS; + break; + } + } + + // Convert pending flags to state + if (current & STATE_GET_SETTINGS) { + _state = STATE_GET_SETTINGS; + + } else if (current & STATE_SET_FREQUENCY) { + _state = STATE_SET_FREQUENCY; + + } else if (current & STATE_SET_POWER) { + _state = STATE_SET_POWER; + + } else if (current & STATE_SET_PIT_MODE) { + _state = STATE_SET_PIT_MODE; + } + + handle_uorb(); + break; + } + + ScheduleDelayed(_INTERVAL); + perf_end(_perf_cycle); +} + +void VTX::update_params(int *new_band, int *new_channel, int *new_frequency, int *new_power, int *new_pit_mode) +{ + _param_vtx_band.update(); + _param_vtx_channel.update(); + _param_vtx_power.update(); + _param_vtx_frequency.update(); + _param_vtx_pit_mode.update(); + _param_vtx_map_config.update(); + const int map_config = _param_vtx_map_config.get(); + + // Set transmit channel based on either parameter or manual auxiliary channel input + if (map_config > 1) { + input_rc_s input_rc{}; + + if (_input_rc_sub.update(&input_rc) && !input_rc.rc_lost) { + int8_t band{0}, channel{0}, power{0}; + vtxtable().map_lookup(input_rc.values, input_rc.channel_count, &band, &channel, &power); + + if (map_config > 2) { + if (band > 0) { _param_vtx_band.commit_no_notification(band - 1); } + + if (channel > 0) { _param_vtx_channel.commit_no_notification(channel - 1); } + } + + if (map_config == 2 || map_config == 4) { + if (power == -1) { + _param_vtx_power.commit_no_notification(0); + _param_vtx_pit_mode.commit_no_notification(true); + + } else if (power > 0) { + _param_vtx_power.commit_no_notification(power - 1); + _param_vtx_pit_mode.commit_no_notification(false); + } + } + } + } + + *new_band = _param_vtx_band.get() % 24; + *new_channel = _param_vtx_channel.get() & 0xF; + *new_power = _param_vtx_power.get() & 0xF; + *new_frequency = _param_vtx_frequency.get(); + *new_pit_mode = _param_vtx_pit_mode.get(); +} + +void VTX::handle_uorb() +{ + vtx_s msg{}; + msg.band = _band; + msg.channel = _channel; + msg.power_level = _power; + msg.device = _device; + + if (!_comms_ok || !_protocol->copy_to(&msg)) { + msg.protocol = vtx_s::PROTOCOL_NONE; + msg.frequency = (_frequency ? _frequency : vtxtable().frequency(_band, _channel)); + msg.mode = _pit_mode ? vtx_s::MODE_PIT : vtx_s::MODE_NORMAL; + } + + // If frequency is set, overwrite band and channel to -1 + if (_frequency) { + msg.band = -1; + msg.channel = -1; + msg.band_letter = 'f'; + strncpy((char *)msg.band_name, "FREQUENCY", sizeof(msg.band_name)); + + } else { + msg.band_letter = vtxtable().band_letter(msg.band); + strncpy((char *)msg.band_name, vtxtable().band_name(msg.band), sizeof(msg.band_name)); + } + + strncpy((char *)msg.power_label, vtxtable().power_label(msg.power_level), sizeof(msg.power_label)); + + // Workarounds for specific devices + if (_device == vtx_s::DEVICE_PEAK_THOR_T67) { + // This device always reports pit mode, but still works fine + msg.frequency = vtxtable().frequency(_band, _channel); + msg.mode = _pit_mode ? vtx_s::MODE_PIT : vtx_s::MODE_NORMAL; + } + + // Only publish if something changed + if (memcmp(&msg, &_vtx_msg, sizeof(msg)) != 0) { + _vtx_msg = msg; + msg.timestamp = hrt_absolute_time(); + _vtx_pub.publish(msg); + } +} + +int VTX::custom_command(int argc, char *argv[]) +{ + if (!strcmp(argv[0], "start")) { + if (is_running()) { + return print_usage("already running"); + } + + int ret = VTX::task_spawn(argc, argv); + + if (ret) { + return ret; + } + } + + if (!is_running()) { + return print_usage("not running"); + } + + // Check if the first argument is a number and delegate to the VtxTable + char *endptr{}; + strtol(argv[0], &endptr, 10); + + if (endptr != argv[0]) { + extern int vtxtable_custom_command(int argc, char *argv[]); + return vtxtable_custom_command(argc, argv); + } + + return print_usage("unknown command"); +} + +int VTX::task_spawn(int argc, char *argv[]) +{ + int myoptind = 1; + int ch; + const char *myoptarg = nullptr; + const char *device_name = nullptr; + + while ((ch = px4_getopt(argc, argv, "d:", &myoptind, &myoptarg)) != EOF) { + switch (ch) { + case 'd': + device_name = myoptarg; + break; + + default: + PX4_WARN("unrecognized flag"); + return -1; + break; + } + } + + if (device_name && (access(device_name, R_OK | W_OK) == 0)) { + auto *const instance = new VTX(device_name); + + if (instance == nullptr) { + PX4_ERR("alloc failed"); + return PX4_ERROR; + } + + _object.store(instance); + _task_id = task_id_is_work_queue; + + instance->ScheduleNow(); + + return PX4_OK; + + } else { + if (device_name) { + PX4_ERR("invalid device (-d) %s", device_name); + + } else { + PX4_INFO("valid device required"); + } + } + + return PX4_ERROR; +} + +int VTX::print_status() +{ + if (_serial_path[0]) { + PX4_INFO("UART device: %s", _serial_path); + } + +#ifdef CONFIG_VTX_CRSF_MSP_SUPPORT + const char *const config_map[] {"Disabled", "MSP", "MSP=Band/Channel, AUX=Power", "MSP=Power, AUX=Band/Channel", "AUX"}; +#else + const char *const config_map[] {"Disabled", "Disabled", "Power", "Band/Channel", "Power/Band/Channel"}; +#endif + const char *const config_str = config_map[_param_vtx_map_config.get() <= 4 ? _param_vtx_map_config.get() : 0]; + PX4_INFO("RC mapping: %s", config_str); + + PX4_INFO("Parameters:"); + PX4_INFO(" band: %d", (_frequency ? -1 : (_band + 1))); + PX4_INFO(" channel: %d", (_frequency ? -1 : (_channel + 1))); + PX4_INFO(" frequency: %u MHz", (_frequency ? _frequency : vtxtable().frequency(_band, _channel))); + PX4_INFO(" power level: %u", _power + 1); + PX4_INFO(" power: %hi = %s", vtxtable().power_value(_power), vtxtable().power_label(_power)); + PX4_INFO(" pit mode: %s", _pit_mode ? "on" : "off"); + + if (!(_comms_ok && _protocol && _protocol->print_settings())) { + PX4_ERR("%s device not found", _param_vtx_device.get() == 1 ? "Tramp" : "SmartAudio"); + } + + perf_print_counter(_perf_cycle); + perf_print_counter(_perf_error); + perf_print_counter(_perf_get_settings); + perf_print_counter(_perf_set_power); + perf_print_counter(_perf_set_frequency); + perf_print_counter(_perf_set_pit_mode); + + return 0; +} + +int VTX::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +This module communicates with a VTX camera via serial port. It can be used to +configure the camera settings and to control the camera's video transmission. +Supported protocols are: +- SmartAudio v1, v2.0, v2.1 +- Tramp + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("vtx", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAM_STRING('d', nullptr, "", "VTX device", false); + + PRINT_MODULE_USAGE_COMMAND_DESCR("", "Sets an entry in the mapping table: "); + + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int vtx_main(int argc, char *argv[]) +{ + return VTX::main(argc, argv); +} diff --git a/src/drivers/vtx/VTX.hpp b/src/drivers/vtx/VTX.hpp new file mode 100644 index 0000000000..90996ab47a --- /dev/null +++ b/src/drivers/vtx/VTX.hpp @@ -0,0 +1,134 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "protocol.h" +#include "../vtxtable/VtxTable.hpp" + +/** + * @author Niklas Hauser + */ +class VTX : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + + VTX(const char *device); + virtual ~VTX(); + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + /** @see ModuleBase::print_status() */ + int print_status() override; + + int init(); + +private: + void Run() override; + + void update_params(int *new_band, int *new_channel, int *new_frequency, int *new_power, int *new_pit_mode); + void handle_uorb(); + + char _serial_path[20] {}; + vtx::Protocol *_protocol{nullptr}; + + DEFINE_PARAMETERS( + (ParamInt) _param_vtx_band, + (ParamInt) _param_vtx_channel, + (ParamInt) _param_vtx_frequency, + (ParamInt) _param_vtx_power, + (ParamBool) _param_vtx_pit_mode, + (ParamInt) _param_vtx_map_config, + (ParamInt) _param_vtx_device + ); + + perf_counter_t _perf_cycle; + perf_counter_t _perf_error; + perf_counter_t _perf_get_settings; + perf_counter_t _perf_set_power; + perf_counter_t _perf_set_frequency; + perf_counter_t _perf_set_pit_mode; + + uORB::PublicationMulti _vtx_pub{ORB_ID(vtx)}; + uORB::Subscription _input_rc_sub{ORB_ID(input_rc)}; + + vtx_s _vtx_msg{}; + + int8_t _band{0}; + int8_t _channel{0}; + int16_t _frequency{0}; + int16_t _power{0}; + uint8_t _device{0}; + bool _pit_mode{}; + + enum : uint8_t { + STATE_INIT = 0, + STATE_GET_SETTINGS = 0b0001, + STATE_SET_PIT_MODE = 0b0010, + STATE_SET_FREQUENCY = 0b0100, + STATE_SET_POWER = 0b1000, + STATE_UPDATE = 0b1'0000, + STATE_SET_ALL = STATE_SET_FREQUENCY | STATE_SET_POWER | STATE_SET_PIT_MODE, + STATE_MASK = 0b1111, + } _state{STATE_INIT}; + uint8_t _pending{}; + uint8_t _schedule{STATE_GET_SETTINGS}; + int8_t _update_counter{}; + + bool _comms_ok{}; + vtx::Config::ChangeType _last_config_change{}; +}; diff --git a/src/drivers/vtx/module.yaml b/src/drivers/vtx/module.yaml new file mode 100644 index 0000000000..a972b26f99 --- /dev/null +++ b/src/drivers/vtx/module.yaml @@ -0,0 +1,133 @@ +module_name: VTX SmartAudio +serial_config: + - command: vtx start -d ${SERIAL_DEV} + port_config_param: + name: VTX_SER_CFG + group: VTX + label: VTX Serial Port + +parameters: + - group: VTX + definitions: + VTX_BAND: + description: + short: VTX band + long: VTX table band 1-24 + type: enum + values: + 0: Band 1 + 1: Band 2 + 2: Band 3 + 3: Band 4 + 4: Band 5 + 5: Band 6 + 6: Band 7 + 7: Band 8 + 8: Band 9 + 9: Band 10 + 10: Band 11 + 11: Band 12 + 12: Band 13 + 13: Band 14 + 14: Band 15 + 15: Band 16 + 16: Band 17 + 17: Band 18 + 18: Band 19 + 19: Band 20 + 20: Band 21 + 21: Band 22 + 22: Band 23 + 23: Band 24 + default: 0 + VTX_CHANNEL: + description: + short: VTX channel + long: VTX table channel 1-16 + type: enum + values: + 0: Channel 1 + 1: Channel 2 + 2: Channel 3 + 3: Channel 4 + 4: Channel 5 + 5: Channel 6 + 6: Channel 7 + 7: Channel 8 + 8: Channel 9 + 9: Channel 10 + 10: Channel 11 + 11: Channel 12 + 12: Channel 13 + 13: Channel 14 + 14: Channel 15 + 15: Channel 16 + default: 0 + VTX_FREQUENCY: + description: + short: VTX frequency in MHz + long: | + If the VTX frequency is set, it will overwrite the band and channel + settings. Set to 0 to use band and channel settings. + type: int32 + min: 0 + max: 32000 + default: 0 + VTX_POWER: + description: + short: VTX power level + long: VTX transmission power level 1-16 + type: enum + values: + 0: Level 1 + 1: Level 2 + 2: Level 3 + 3: Level 4 + 4: Level 5 + 5: Level 6 + 6: Level 7 + 7: Level 8 + 8: Level 9 + 9: Level 10 + 10: Level 11 + 11: Level 12 + 12: Level 13 + 13: Level 14 + 14: Level 15 + 15: Level 16 + default: 0 + VTX_PIT_MODE: + description: + short: VTX pit mode + long: VTX pit mode reduces power to the minimum + type: boolean + default: false + VTX_MAP_CONFIG: + description: + short: VTX mapping configuration + long: | + Configure how VTX settings are controlled. Options include using + MSP commands, AUX channels or a combination of both. To use MSP + commands, you must use a CRSF receiver with MSP support enabled in + the PX4 build. + type: enum + values: + 0: Disabled + 1: MSP for Power, Band and Channel + 2: MSP for Band and Channel, AUX for Power + 3: MSP for Power, AUX for Band and Channel + 4: AUX for Power, Band and Channel + default: 0 + VTX_DEVICE: + description: + short: VTX device + long: Specific VTX device useful for workarounds and optimizations + type: enum + # Note: keep values in sync with msg/Vtx.msg: lower 8-bit is protocol, next 8-bit is device + values: + 0: SmartAudio v1, v2, v2.1 Protocol + 100: Tramp Protocol + 5120: Peak THOR T67 + 10240: Rush MAX SOLO + default: 0 + reboot_required: true diff --git a/src/drivers/vtx/protocol.h b/src/drivers/vtx/protocol.h new file mode 100644 index 0000000000..cc73e7ab8d --- /dev/null +++ b/src/drivers/vtx/protocol.h @@ -0,0 +1,185 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#include +#include +#include +#include +#include "../vtxtable/VtxTable.hpp" + +namespace vtx +{ + +/** + * Parser class for working with Tramp protocol. + * @author Niklas Hauser + */ +class Protocol +{ +public: + /// @brief Constructor + /// @param baudrate The baud rate for the serial connection + constexpr Protocol(uint16_t baudrate) : + _baudrate(baudrate) + {} + virtual inline ~Protocol() + { + if (_serial) { + _serial->close(); + delete _serial; + } + } + + inline int init(const char *device) + { + if (_serial == nullptr) { + _serial = new device::Serial(device, _baudrate); + + } else { + _serial->close(); + } + + if (_serial == nullptr) { + PX4_ERR("Serial alloc failed"); + return PX4_ERROR; + } + +#ifdef CONFIG_BOARD_SERIAL_RC + + // All RC serial ports are RX by default, so we need to swap RX and TX + // to get the TX pin on the RX pin. + if (strcmp(device, CONFIG_BOARD_SERIAL_RC) == 0 && !board_rc_swap_rxtx(device)) { + _serial->setSwapRxTxMode(); + } + +#endif + _serial->setStopbits(device::SerialConfig::StopBits::Two); + _serial->setSingleWireMode(); + + if (!_serial->open()) { + PX4_ERR("Serial open failed"); + delete _serial; + _serial = nullptr; + return PX4_ERROR; + } + + if (reset() != 0) { + return PX4_ERROR; + } + + return PX4_OK; + } + + /// @brief Reset the VTX + /// @return 0 on success, negative error code on failure + virtual int reset() { return 0; } + + /// @brief Get the current settings from the VTX + /// @return 0 on success, negative error code on failure + virtual int get_settings() = 0; + + /// @brief Set the power + /// @param power_level The power level to set, negative values set dBm or mW depending on the implementation + /// @return 0 on success, negative error code on failure + virtual int set_power(int16_t power_level) = 0; + + /// @brief Set the frequency + /// @param frequency_MHz The frequency to set, negative values set pit frequency + /// @return 0 on success, negative error code on failure + virtual int set_frequency(int16_t frequency_MHz) = 0; + + /// @brief Set the frequency based on band and channel + /// @param band The band (0-7) + /// @param channel The channel (0-7) + /// @return 0 on success, negative error code on failure + virtual int set_channel(uint8_t band, uint8_t channel) + { + return set_frequency(vtxtable().frequency(band, channel)); + } + + /// @brief Set the pit mode + /// @param onoff true to enable pit mode, false to disable + /// @return 0 on success, negative error code on failure + virtual int set_pit_mode(bool onoff) = 0; + + /// @brief Print the current settings + /// @return true if device is connected and settings are valid + virtual bool print_settings() = 0; + + /// @brief Copy the current settings to a uORB message + /// @param msg The message to copy the settings to + /// @return true if data is valid and has been copied + virtual bool copy_to(vtx_s *msg) = 0; + +protected: + /// @brief Parse incoming bytes + /// @param value The incoming byte + /// @return Number of remaining bytes to read, 0 if a full message has been received, negative on error + virtual int rx_parser(uint8_t value) = 0; + + inline int rx_msg() + { + using namespace time_literals; + memset(_rx_buf, 0, sizeof(_rx_buf)); + _read_state = 0; + + const hrt_abstime start_time_us = hrt_absolute_time(); + int remaining{3}; + + while (true) { + const int new_bytes = _serial->readAtLeast(_serial_buf, sizeof(_serial_buf), remaining, 20); + + for (int i = 0; i < new_bytes; i++) { + remaining = rx_parser(_serial_buf[i]); + + if (remaining <= 0) { return remaining; } + } + + if (hrt_elapsed_time(&start_time_us) > 200_ms) { + return -ETIMEDOUT; + } + } + + return -1; + } + + const uint16_t _baudrate{}; + device::Serial *_serial{}; + uint8_t _tx_buf[32] {}; + uint8_t _rx_buf[32] {}; + uint8_t _serial_buf[32] {}; + uint8_t _read_state{}; +}; + +} // namespace vtx diff --git a/src/drivers/vtx/smart_audio.cpp b/src/drivers/vtx/smart_audio.cpp new file mode 100644 index 0000000000..724beff0aa --- /dev/null +++ b/src/drivers/vtx/smart_audio.cpp @@ -0,0 +1,368 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "smart_audio.h" +#include +#include +#include +#include +#include + +namespace vtx +{ + +using namespace time_literals; + +int SmartAudio::get_settings() +{ + const uint8_t buf[] = {COMMAND_GET_SETTINGS, 0}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + Settings s; + memcpy(&s, _rx_buf + 2, sizeof(Settings)); + // Fix frequency endianess + s.frequency = __builtin_bswap16(s.frequency); + const uint8_t version = _rx_buf[0] >> 3; + + if (version == 0) { // v1 + s.number_of_power_levels = 4; + s.power_levels[0] = 7; + s.power_levels[1] = 16; + s.power_levels[2] = 25; + s.power_levels[3] = 40; + + } else if (version == 1) { // v2 + s.number_of_power_levels = 8; + + } else if (version == 2) { // v2.1 + if (s.number_of_power_levels > 7) { + s.number_of_power_levels = 7; + } + + for (int i = 0; i < s.number_of_power_levels; i++) { + s.power_levels[i] = s.power_levels[i + 1]; + } + } + + s.version = version; + + // copy the settings to storage + _settings = s; + + return PX4_OK; +} + +bool SmartAudio::print_settings() +{ + if (_settings.version > 2) { return false; } + + PX4_INFO("SmartAudio v%s%s:", ((const char *[]) {"1", "2", "2.1"})[_settings.version], + (_settings.mode & SmartAudio::MODE_SET_FREQUENCY) ? "+fr" : "+ch"); + PX4_INFO(" band: %u", ((_settings.channel >> 3) & 0b111) + 1); + PX4_INFO(" channel: %u", (_settings.channel & 0b111) + 1); + PX4_INFO(" frequency: %u MHz", _settings.frequency); + PX4_INFO(" power level: %u", _settings.current_power_level + 1); + const char *power_label = vtxtable().power_label(_settings.current_power_level); + + if (_settings.version == 2) { + PX4_INFO(" power: %u dBm = %s", _settings.current_power_dBm, power_label); + + } else { + PX4_INFO(" power: %s", power_label); + } + + PX4_INFO(" pit mode: %s", (_settings.mode & (SmartAudio::MODE_IN_RANGE_PIT_MODE | + SmartAudio::MODE_OUT_RANGE_PIT_MODE)) ? "on" : "off"); + PX4_INFO(" lock: %slocked", (_settings.mode & SmartAudio::MODE_UNLOCKED) ? "un" : ""); + return true; +} + +bool SmartAudio::copy_to(vtx_s *msg) +{ + if (_settings.version > 2) { return false; } + + if (_settings.version == 0) { msg->protocol = vtx_s::PROTOCOL_SMART_AUDIO_V1; } + + else if (_settings.version == 1) { msg->protocol = vtx_s::PROTOCOL_SMART_AUDIO_V2; } + + else { msg->protocol = vtx_s::PROTOCOL_SMART_AUDIO_V2_1; } + + msg->band = _settings.channel >> 3; + msg->channel = _settings.channel & 0b111; + msg->frequency = _settings.frequency; + msg->power_level = _settings.current_power_level; + bool pm = (_settings.mode & (SmartAudio::MODE_IN_RANGE_PIT_MODE | SmartAudio::MODE_OUT_RANGE_PIT_MODE)); + msg->mode = pm ? vtx_s::MODE_PIT : vtx_s::MODE_NORMAL; + + return true; +} + +int SmartAudio::set_power(uint8_t power_level, bool is_dBm) +{ + if (power_level >= _settings.number_of_power_levels) { + return PX4_ERROR; + } + + power_level = vtxtable().power_value(power_level); + + if (_settings.version == 2 && is_dBm) { power_level |= 0x80; } + + const uint8_t buf[] = {COMMAND_SET_POWER, 1, power_level}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + return ((_rx_buf[0] == COMMAND_SET_POWER) && (_rx_buf[2] == (power_level & ~0x80))) ? PX4_OK : PX4_ERROR; +} + +int SmartAudio::set_channel(uint8_t band, uint8_t channel) +{ + if (vtxtable().band_attribute(band) == Config::BandAttribute::CUSTOM) { + const uint16_t freq = vtxtable().frequency(band, channel); + + if (freq) { return set_frequency(freq, false); } + } + + const uint8_t value = ((band & 0b111) << 3) | (channel & 0b111); + const uint8_t buf[] = {COMMAND_SET_CHANNEL, 1, value}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + return ((_rx_buf[0] == COMMAND_SET_CHANNEL) && (_rx_buf[2] == value)) ? PX4_OK : PX4_ERROR; +} + +int SmartAudio::set_frequency(uint16_t frequency, bool pit) +{ + pit ? frequency |= 0x8000 : frequency &= ~0x8000; + const uint8_t buf[] = {COMMAND_SET_FREQUENCY, 2, uint8_t(frequency >> 8), uint8_t(frequency)}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + const bool success = (_rx_buf[0] == COMMAND_SET_FREQUENCY) && (_rx_buf[2] == (frequency >> 8)); + + if (_settings.version == 2) { + return (success && (_rx_buf[3] == (frequency & 0xff))) ? PX4_OK : PX4_ERROR; + + } else { + // Some v1/v2 firmwares do not echo the low byte back + // But the CRC is still correct, so we assume success + return success ? PX4_OK : PX4_ERROR; + } +} + +int SmartAudio::set_operating_mode(uint8_t mode) +{ + if (_settings.version == 0) { + return -1; + } + + const uint8_t buf[] = {COMMAND_SET_MODE, 1, mode}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + return ((_rx_buf[0] == COMMAND_SET_MODE) && (_rx_buf[2] == mode)) ? PX4_OK : PX4_ERROR; +} + +int SmartAudio::set_pit_mode(bool onoff) +{ + // only v2 supports pit mode + if (_settings.version == 0) { + return 0; + } + + uint8_t mode{SET_MODE_UNLOCKED}; + + if (onoff) { + if (_settings.mode & MODE_OUT_RANGE_PIT_MODE) { + mode |= SET_MODE_OUT_RANGE; + + } else { + mode |= SET_MODE_IN_RANGE; + } + + } else { + mode |= SET_MODE_DISABLE_PIT_MODE; + } + + return set_operating_mode(mode); +} + +int SmartAudio::transmit(const uint8_t *buf, size_t len) +{ + if (len > 28) { return -1; } + + // copy the message data + memcpy(_tx_buf + 3, buf, len); + // shift the command to the left + // const uint8_t cmd = buf[0]; + _tx_buf[3] = (buf[0] << 1) | 0x01; + // compute the CRC + _tx_buf[3 + len] = crc8(_tx_buf + 1, 2 + len); + // some devices need an additional 0 byte at the end + _tx_buf[4 + len] = 0; + + // send command + if (_serial->write(_tx_buf, 5 + len) < ssize_t(5 + len)) { + return -errno; + } + + _serial->flush(); + + return rx_msg(); +} + +bool SmartAudio::is_rsp(uint8_t cmd, uint8_t length) +{ + if (length == 0) { return false; } + + if (cmd == COMMAND_SET_POWER && length == 0x03) { return true; } + + if (cmd == COMMAND_SET_CHANNEL && length == 0x03) { return true; } + + if (cmd == COMMAND_SET_FREQUENCY && length == 0x04) { return true; } + + if (cmd == COMMAND_SET_MODE && length == 0x03) { return true; } + + if (((cmd == COMMAND_GET_SETTINGS) || (cmd == COMMAND_GET_SETTINGS_V2) || + (cmd == COMMAND_GET_SETTINGS_V21)) && length >= 0x06) { return true; } + + return false; +} + +int SmartAudio::rx_parser(uint8_t c) +{ + enum { + SYNC1 = 0, + SYNC2 = 1, + COMMAND = 2, + LENGTH = 3, + DATA = 4, + CRC = 5, + }; + + switch (_read_state) { + case SYNC1: + PX4_DEBUG("SYNC1 %x", c); + + if (c == 0xAA) { + _read_state = SYNC2; + } + + return 1; + + case SYNC2: + PX4_DEBUG("SYNC2 %x", c); + + if (c == 0x55) { + _read_state = COMMAND; + return 3; + + } else { + _read_state = SYNC1; + return 1; + } + + case COMMAND: + PX4_DEBUG("COMMAND %x", c); + _rx_buf[0] = c; + _read_state = LENGTH; + return 2; + + case LENGTH: + PX4_DEBUG("LENGTH %x", c); + + if (c >= 20) { + _read_state = SYNC1; + return 1; + } + + _rx_buf[1] = c; + + // command response: has one length too many + if (is_rsp(_rx_buf[0], c) && c) { c--; } + + _read_length = c; + _read_data_length = 0; + _read_state = _read_length ? DATA : CRC; + return _read_length + 1; + + case DATA: + PX4_DEBUG("DATA %x", c); + _rx_buf[2 + _read_data_length] = c; + + if (++_read_data_length >= _read_length) { + _read_state = CRC; + } + + return _read_length - _read_data_length + 1; + + case CRC: + PX4_DEBUG("CRC %x", c); + _read_state = SYNC1; + + if (!is_rsp(_rx_buf[0], _rx_buf[1])) { return 1; } + + return (c == crc8(_rx_buf, 2u + _read_length)) ? 0 : -CRC; + } + + return -6000; +} + +uint8_t SmartAudio::crc8(const uint8_t *data, const uint8_t len) +{ + // Implementation adapted from lib/crc/crc.c + uint8_t crc{}; + const uint8_t poly{0xd5}; + + for (uint8_t i = 0 ; i < len; i++) { + crc ^= data[i]; + + for (uint8_t j = 0; j < 8; j++) { + if (crc & (1u << 7u)) { + crc = (uint8_t)((crc << 1u) ^ poly); + + } else { + crc = (uint8_t)(crc << 1u); + } + } + } + + return crc; +} + +} diff --git a/src/drivers/vtx/smart_audio.h b/src/drivers/vtx/smart_audio.h new file mode 100644 index 0000000000..69c82b3adb --- /dev/null +++ b/src/drivers/vtx/smart_audio.h @@ -0,0 +1,129 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#include "protocol.h" + +namespace vtx +{ + +/** + * Implementation for working with SmartAudio protocol. + * @author Niklas Hauser + */ +class SmartAudio final : public Protocol +{ +public: + static constexpr int BAUDRATE{4800}; + + struct Settings { + uint8_t channel; + uint8_t current_power_level; + uint8_t mode; + uint16_t frequency; + uint8_t current_power_dBm; + uint8_t number_of_power_levels; + uint8_t power_levels[8]; + uint8_t version; + } __attribute__((packed)); + + enum { + MODE_SET_FREQUENCY = 0b0001, + MODE_PIT_MODE_ACTIVE = 0b0010, + MODE_IN_RANGE_PIT_MODE = 0b0100, + MODE_OUT_RANGE_PIT_MODE = 0b1000, + MODE_UNLOCKED = 0b10000, + }; + const Settings &settings() const { return _settings; } + + inline SmartAudio() : Protocol(BAUDRATE) + { + _tx_buf[1] = 0xAA; + _tx_buf[2] = 0x55; + } + virtual ~SmartAudio() = default; + + inline int set_power(int16_t power_level) override + { + // negative values do not force dBm mode + if (power_level < 0) { return set_power(-power_level, false); } + + return set_power(power_level, true); + } + inline int set_frequency(int16_t frequency_MHz) override + { + if (frequency_MHz < 0) { return set_frequency(-frequency_MHz, true); } + + return set_frequency(frequency_MHz, false); + } + int set_channel(uint8_t band, uint8_t channel) override; + int get_settings() override; + int set_pit_mode(bool onoff) override; + bool print_settings() override; + bool copy_to(vtx_s *msg) override; + + // Additional methods not part of the Protocol interface + int set_frequency(uint16_t frequency_MHz, bool pit = false); + int set_power(uint8_t power_level, bool is_dBm = true); + int set_operating_mode(uint8_t mode); + +private: + int rx_parser(uint8_t c) override; + int transmit(const uint8_t *buf, size_t len); + static uint8_t crc8(const uint8_t *data, uint8_t len); + static bool is_rsp(uint8_t cmd, uint8_t length); + + enum { + COMMAND_GET_SETTINGS = 0x01, + COMMAND_SET_POWER = 0x02, + COMMAND_SET_CHANNEL = 0x03, + COMMAND_SET_FREQUENCY = 0x04, + COMMAND_SET_MODE = 0x05, + + COMMAND_GET_SETTINGS_V2 = 0x09, + COMMAND_GET_SETTINGS_V21 = 0x11, + }; + + enum { + SET_MODE_IN_RANGE = 0b0001, + SET_MODE_OUT_RANGE = 0b0010, + SET_MODE_DISABLE_PIT_MODE = 0b0100, + SET_MODE_UNLOCKED = 0b1000, + }; + + Settings _settings{.version = 99}; + uint8_t _read_length{}; + uint8_t _read_data_length{}; +}; + +} diff --git a/src/drivers/vtx/tramp.cpp b/src/drivers/vtx/tramp.cpp new file mode 100644 index 0000000000..b841777d7f --- /dev/null +++ b/src/drivers/vtx/tramp.cpp @@ -0,0 +1,294 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "tramp.h" +#include +#include +#include +#include +#include + +namespace vtx +{ + +using namespace time_literals; + +int Tramp::get_settings() +{ + const int rv = get_status(); + + if (rv != 0) { return rv; } + + px4_usleep(30_ms); + return get_temperature(); +} + + +bool Tramp::print_settings() +{ + PX4_INFO("Tramp:"); + PX4_INFO(" frequency: %hu MHz", _settings.frequency); + PX4_INFO(" requested power: %hu mW", _settings.requested_power_mW); + PX4_INFO(" power: %hu mW", _settings.power_mW); + PX4_INFO(" pit mode: %s", _settings.pit_mode ? "on" : "off"); + + PX4_INFO(" temperature: %hi C", _settings.temperature); + + PX4_INFO(" min frequency: %hu MHz", _settings.min_frequency); + PX4_INFO(" max frequency: %hu MHz", _settings.max_frequency); + PX4_INFO(" max power: %hu mW", _settings.max_power_mW); + return true; +} + +bool Tramp::copy_to(vtx_s *msg) +{ + msg->protocol = vtx_s::PROTOCOL_TRAMP; + + msg->frequency = _settings.frequency; + msg->power_level = _requested_power_level; + msg->mode = _settings.pit_mode ? vtx_s::MODE_PIT : vtx_s::MODE_NORMAL; + + return true; +} + +int Tramp::get_status() +{ + const uint8_t buf[] = {COMMAND_GET_SETTINGS}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + _settings.frequency = (_rx_buf[2] | (_rx_buf[3] << 8)); + _settings.requested_power_mW = (_rx_buf[4] | (_rx_buf[5] << 8)); + _settings.control_mode = _rx_buf[6]; + _settings.pit_mode = _rx_buf[7]; + _settings.power_mW = (_rx_buf[8] | (_rx_buf[9] << 8)); + + return PX4_OK; +} + +int Tramp::get_temperature() +{ + const uint8_t buf[] = {COMMAND_GET_TEMPERATURE}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + _settings.temperature = int16_t(_rx_buf[6] | (_rx_buf[7] << 8)); + + return PX4_OK; +} + +int Tramp::reset() +{ + const uint8_t buf[] = {COMMAND_RESET}; + const int rv = transmit(buf, sizeof(buf)); + + if (rv != 0) { return rv; } + + _settings.min_frequency = int16_t(_rx_buf[2] | (_rx_buf[3] << 8)); + _settings.max_frequency = int16_t(_rx_buf[4] | (_rx_buf[5] << 8)); + _settings.max_power_mW = int16_t(_rx_buf[6] | (_rx_buf[7] << 8)); + + return PX4_OK; +} + +int Tramp::set_power(int16_t power_level) +{ + int16_t power_mW; + _requested_power_level = -1; + + if (power_level < 0) { + power_mW = -power_level; + + } else { + power_mW = vtxtable().power_value(power_level); + + if (power_mW == 0) { return -EINVAL; } + + _requested_power_level = power_level; + } + + const uint8_t buf[] = {COMMAND_SET_POWER, uint8_t(power_mW), uint8_t(power_mW >> 8)}; + int rv = transmit(buf, sizeof(buf)); + + if (rv) { return rv; } + + px4_usleep(30_ms); + rv = get_status(); + + if (rv) { return rv; } + + return (_settings.requested_power_mW == power_mW) ? PX4_OK : PX4_ERROR; +} + +int Tramp::set_frequency(int16_t frequency_MHz) +{ + if (frequency_MHz < 0) { return -EINVAL; } // Tramp does not support pit frequency setting + + const uint8_t buf[] = {COMMAND_SET_FREQUENCY, uint8_t(frequency_MHz), uint8_t(frequency_MHz >> 8)}; + int rv = transmit(buf, sizeof(buf)); + + if (rv) { return rv; } + + px4_usleep(30_ms); + rv = get_status(); + + if (rv) { return rv; } + + return (_settings.frequency == frequency_MHz) ? PX4_OK : PX4_ERROR; +} + +int Tramp::set_pit_mode(bool onoff) +{ + const uint8_t mode = onoff ? 0u : 1u; + const uint8_t buf[] = {COMMAND_SET_MODE, mode}; + int rv = transmit(buf, sizeof(buf)); + + if (rv) { return rv; } + + px4_usleep(30_ms); + rv = get_status(); + + if (rv) { return rv; } + + return (_settings.pit_mode == onoff ? 1u : 0u) ? PX4_OK : PX4_ERROR; +} + +int Tramp::transmit(const uint8_t *buf, size_t len) +{ + if (len > 28) { return -1; } + + memset(_tx_buf + 1, 0, sizeof(_tx_buf) - 1); + // copy the message data + memcpy(_tx_buf + 1, buf, len); + // compute the CRC + _tx_buf[offsetof(Frame, crc)] = crc8(_tx_buf); + + // send command + if (_serial->write(_tx_buf, sizeof(Frame)) < ssize_t(sizeof(Frame))) { + return -errno; + } + + _serial->flush(); + + return rx_msg(); +} + +int Tramp::rx_parser(uint8_t c) +{ + enum { + SYNC = 0, + COMMAND = 1, + DATA = 2, + CRC = 3, + END = 4, + }; + static constexpr uint8_t CRCPOS{offsetof(Frame, crc)}; + + switch (_read_state) { + case SYNC: + PX4_DEBUG("SYNC %x", c); + + if (c == 0x0F) { + _rx_buf[0] = c; + _read_state = COMMAND; + return 1; + + } else { + _read_state = SYNC; + return 1; + } + + case COMMAND: + PX4_DEBUG("COMMAND %x", c); + + switch (c) { + case COMMAND_RESET: + case COMMAND_GET_TEMPERATURE: + case COMMAND_GET_SETTINGS: + case COMMAND_SET_POWER: + case COMMAND_SET_FREQUENCY: + case COMMAND_SET_MODE: + _rx_buf[1] = c; + _read_state = DATA; + _read_data_length = 2; + return CRCPOS; + } + + _read_state = SYNC; + return 1; + + case DATA: + PX4_DEBUG("DATA %x", c); + _rx_buf[_read_data_length] = c; + + if (++_read_data_length >= CRCPOS) { + _read_state = CRC; + } + + return sizeof(Frame) - _read_data_length; + + case CRC: + PX4_DEBUG("CRC %x", c); + _read_state = END; + _rx_buf[CRCPOS] = c; + return 1; + + case END: + PX4_DEBUG("END %x", c); + _read_state = SYNC; + + // small letter commands with empty payloads were sent by us + if ((_rx_buf[1] & 0x20) && !_rx_buf[2] && !_rx_buf[3]) { return 1; } + + // large letter command do not get a response + // Check the CRC for the received data + return (_rx_buf[CRCPOS] == crc8(_rx_buf)) ? 0 : -CRC; + } + + return -6000; +} + +uint8_t Tramp::crc8(const uint8_t *data) +{ + uint8_t crc{0}; + + for (uint_fast8_t ii{1}; ii < offsetof(Frame, crc); ii++) { + crc += data[ii]; + } + + return crc; +} + +} diff --git a/src/drivers/vtx/tramp.h b/src/drivers/vtx/tramp.h new file mode 100644 index 0000000000..13b68730a8 --- /dev/null +++ b/src/drivers/vtx/tramp.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#include "protocol.h" + +namespace vtx +{ + +/** + * Implementation for working with Tramp protocol. + * @author Niklas Hauser + */ +class Tramp final : public Protocol +{ +public: + static constexpr int BAUDRATE{9600}; + + struct Settings { + // command 'v' + uint16_t frequency; + uint16_t requested_power_mW; + uint8_t control_mode; + uint8_t pit_mode; + uint16_t power_mW; + + // command 's' + int16_t temperature; + + // command 'r' + uint16_t min_frequency; + uint16_t max_frequency; + uint16_t max_power_mW; + }; + const Settings &settings() const { return _settings; } + + inline Tramp() : Protocol(BAUDRATE) + { + _tx_buf[0] = 0x0F; + } + + int get_settings() override; + int reset() override; + int set_power(int16_t power_mW) override; + int set_frequency(int16_t frequency_MHz) override; + int set_pit_mode(bool onoff) override; + bool print_settings() override; + bool copy_to(vtx_s *msg) override; + + // Additional methods not part of the Protocol interface + int get_status(); + int get_temperature(); + +private: + int rx_parser(uint8_t c) override; + int transmit(const uint8_t *buf, size_t len); + static uint8_t crc8(const uint8_t *data); + + enum { + COMMAND_RESET = 'r', // 0x72 + COMMAND_GET_TEMPERATURE = 's', // 0x73 + COMMAND_GET_SETTINGS = 'v', // 0x76 + COMMAND_SET_POWER = 'P', // 0x50 + COMMAND_SET_FREQUENCY = 'F', // 0x46 + COMMAND_SET_MODE = 'I', // 0x49 + }; + + struct Frame { + uint8_t start{0x0F}; + uint8_t command; + uint8_t payload[12]; + uint8_t crc; + uint8_t end{0x00}; + } __attribute__((packed)); + static_assert(sizeof(Frame) == 16, "Tramp frame size wrong"); + + Settings _settings{}; + uint8_t _read_data_length{}; + int8_t _requested_power_level{-1}; +}; + +} // namespace vtx diff --git a/src/drivers/vtxtable/CMakeLists.txt b/src/drivers/vtxtable/CMakeLists.txt new file mode 100644 index 0000000000..d85a0561ea --- /dev/null +++ b/src/drivers/vtxtable/CMakeLists.txt @@ -0,0 +1,41 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__vtxtable + MAIN vtxtable + COMPILE_FLAGS + SRCS + VtxTable.cpp + DEPENDS + crc + ) diff --git a/src/drivers/vtxtable/Kconfig b/src/drivers/vtxtable/Kconfig new file mode 100644 index 0000000000..1fc96d9d96 --- /dev/null +++ b/src/drivers/vtxtable/Kconfig @@ -0,0 +1,28 @@ +menuconfig DRIVERS_VTXTABLE + bool "VTX Table" + default n + ---help--- + Manages the configuration of VTX frequencies and power levels. + +if DRIVERS_VTXTABLE + + config VTXTABLE_CONFIG_FILE + string "VTX Configuration File Path" + default "/fs/microsd/vtx_config" + ---help--- + Allows saving/loading the VTX table and aux config + from a file system. + + config VTXTABLE_USE_STORAGE + bool + default y if VTXTABLE_CONFIG_FILE != "" + default n if !(VTXTABLE_CONFIG_FILE != "") + + config VTXTABLE_AUX_MAP + bool "VTX Auxiliary Map" + default n + ---help--- + Enable the AUX map for mapping AUX channel ranges to VTX + table settings. + +endif # DRIVERS_VTXTABLE diff --git a/src/drivers/vtxtable/VtxTable.cpp b/src/drivers/vtxtable/VtxTable.cpp new file mode 100644 index 0000000000..8c8174d433 --- /dev/null +++ b/src/drivers/vtxtable/VtxTable.cpp @@ -0,0 +1,369 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "VtxTable.hpp" + +#include +#include +#ifdef CONFIG_VTXTABLE_USE_STORAGE +#include +#endif + +using namespace time_literals; + +static vtx::Config vtxtable_data; + +vtx::Config &vtxtable() +{ + return vtxtable_data; +} + +#ifdef CONFIG_VTXTABLE_USE_STORAGE +int vtxtable_store(const char *filename) +{ + if (filename == nullptr) { filename = CONFIG_VTXTABLE_CONFIG_FILE; } + + const int rv = vtxtable().store(filename); + + if (rv < 0) { + PX4_ERR("%s is not accessible!", filename); + return PX4_ERROR; + } + + PX4_INFO("saved to %s", filename); + return PX4_OK; +} + +int vtxtable_load(const char *filename) +{ + if (filename == nullptr) { filename = CONFIG_VTXTABLE_CONFIG_FILE; } + + const int rv = vtxtable().load(filename); + + if (rv < 0) { + switch (rv) { + case -ENOENT: + PX4_ERR("%s not found!", filename); + break; + + case -EPROTO: + PX4_ERR("VTX config serialization format is unsupported in %s!", filename); + break; + + case -EBADMSG: + PX4_ERR("VTX config has a corrupt CRC in %s!", filename); + break; + + case -EMSGSIZE: + PX4_ERR("VTX config in %s is incomplete!", filename); + break; + + default: + PX4_ERR("Loading VTX config from %s failed!", filename); + break; + } + + return PX4_ERROR; + } + + PX4_INFO("loaded from %s", filename); + return PX4_OK; +} + +static struct work_s storing_work; +#endif + +static void vtxtable_autosave() +{ +#ifdef CONFIG_VTXTABLE_USE_STORAGE + work_queue(LPWORK, &storing_work, [](void *) { vtxtable_store(nullptr); }, nullptr, USEC2TICK(1_s)); +#endif +} + +static int vtxtable_print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +Manages the VTX frequency, power level and RC mapping table for VTX configuration. + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("vtxtable", "driver"); + + PRINT_MODULE_USAGE_COMMAND_DESCR("status", "Shows the current VTX table configuration."); + + PRINT_MODULE_USAGE_COMMAND_DESCR("name", "Sets the VTX table name: "); + + PRINT_MODULE_USAGE_COMMAND_DESCR("bands", "Sets the number of bands: "); + PRINT_MODULE_USAGE_COMMAND_DESCR("band", "Sets the band frequencies: <1-index> "); + PRINT_MODULE_USAGE_COMMAND_DESCR("channels", "Sets the number of channels: "); + + PRINT_MODULE_USAGE_COMMAND_DESCR("powerlevels", "Sets number of power levels: "); + PRINT_MODULE_USAGE_COMMAND_DESCR("powervalues", "Sets the power level values: "); + PRINT_MODULE_USAGE_COMMAND_DESCR("powerlabels", "Sets the power level labels: <3 chars...>"); + +#ifdef CONFIG_VTXTABLE_AUX_MAP + PRINT_MODULE_USAGE_COMMAND_DESCR("", "Sets an entry in the mapping table: <0-index> "); +#endif + PRINT_MODULE_USAGE_COMMAND_DESCR("clear", "Clears the VTX table configuration."); + +#ifdef CONFIG_VTXTABLE_USE_STORAGE + PRINT_MODULE_USAGE_COMMAND_DESCR("save", "Saves the VTX config to a file: "); + PRINT_MODULE_USAGE_COMMAND_DESCR("load", "Loads the VTX config from a file: "); +#endif + + return 0; +} + +void vtxtable_print_status() +{ + if (vtxtable().bands() == 0) { + PX4_INFO("VTX table: "); + + } else { + PX4_INFO("VTX table %ux%u: %s", vtxtable().bands(), vtxtable().channels(), vtxtable().name()); + vtxtable_print_frequencies(); + } + + if (vtxtable().power_levels() == 0) { + PX4_INFO("Power levels: "); + + } else { + PX4_INFO("Power levels:"); + vtxtable_print_power_levels(); + } + +#ifdef CONFIG_VTXTABLE_AUX_MAP + + if (vtxtable().map_size() == 0) { + PX4_INFO("RC mapping: "); + + } else { + PX4_INFO("RC mapping:"); + vtxtable_print_aux_map(); + } + +#endif +} + +int vtxtable_custom_command(int argc, char *argv[]) +{ + if (!strcmp(argv[0], "status")) { + vtxtable_print_status(); + return PX4_OK; + } + + if (!strcmp(argv[0], "name")) { + if (argc < 2) { + return vtxtable_print_usage("not enough arguments"); + } + + vtxtable_autosave(); + return vtxtable().set_name(argv[1]) ? PX4_OK : PX4_ERROR; + } + + if (!strcmp(argv[0], "band")) { + if (argc < 5) { + return vtxtable_print_usage("not enough arguments"); + } + + const size_t band = atoi(argv[1]) - 1; + vtxtable().set_band_name(band, argv[2]); + vtxtable().set_band_letter(band, argv[3][0]); + vtxtable().set_band_attribute(band, + argv[4][0] == 'F' ? vtx::Config::BandAttribute::FACTORY : vtx::Config::BandAttribute::CUSTOM); + + for (int i = 5; i < argc; i++) { + vtxtable().set_frequency(band, i - 5, atoi(argv[i])); + } + + vtxtable_autosave(); + return PX4_OK; + } + + if (!strcmp(argv[0], "bands")) { + if (argc < 2) { + return vtxtable_print_usage("not enough arguments"); + } + + vtxtable_autosave(); + return vtxtable().set_bands(atoi(argv[1])) ? PX4_OK : PX4_ERROR; + } + + if (!strcmp(argv[0], "channels")) { + if (argc < 2) { + return vtxtable_print_usage("not enough arguments"); + } + + vtxtable_autosave(); + return vtxtable().set_channels(atoi(argv[1])) ? PX4_OK : PX4_ERROR; + } + + if (!strcmp(argv[0], "powervalues")) { + uint8_t levels{1}; + + for (; levels < argc; levels++) { + vtxtable().set_power_value(levels - 1, atoi(argv[levels])); + } + + vtxtable_autosave(); + return PX4_OK; + } + + if (!strcmp(argv[0], "powerlabels")) { + uint8_t levels{1}; + + for (; levels < argc; levels++) { + vtxtable().set_power_label(levels - 1, argv[levels]); + } + + vtxtable_autosave(); + return PX4_OK; + } + + if (!strcmp(argv[0], "powerlevels")) { + if (argc < 2) { + return vtxtable_print_usage("not enough arguments"); + } + + vtxtable_autosave(); + return vtxtable().set_power_levels(atoi(argv[1])) ? PX4_OK : PX4_ERROR; + } + +#ifdef CONFIG_VTXTABLE_AUX_MAP + char *endptr {}; + strtol(argv[0], &endptr, 10); + + if (endptr != argv[0]) { + if (argc < 7) { + return vtxtable_print_usage("not enough arguments"); + } + + vtxtable_autosave(); + return vtxtable().set_map_entry( + atoi(argv[0]), atoi(argv[1]) + 4 - 1, atoi(argv[2]), + atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), atoi(argv[6])) ? PX4_OK : PX4_ERROR; + } + +#endif + + if (!strcmp(argv[0], "clear")) { + vtxtable().clear(); + return PX4_OK; + } + +#ifdef CONFIG_VTXTABLE_USE_STORAGE + const char *const filename = (argc == 2) ? argv[1] : nullptr; + + if (!strcmp(argv[0], "save")) { + return vtxtable_store(filename); + } + + if (!strcmp(argv[0], "load")) { + return vtxtable_load(filename); + } + +#endif + + return vtxtable_print_usage("unknown command"); +} + +void vtxtable_print_frequencies() +{ + for (uint8_t b = 0; b < vtxtable().bands(); b++) { + PX4_INFO_RAW("INFO [vtxtable] %c: %-*s=", vtxtable().band_letter(b), vtx::Config::NAME_LENGTH, vtxtable().band_name(b)); + + for (uint8_t c = 0; c < vtxtable().channels(); c++) { + PX4_INFO_RAW(" %4hu", vtxtable().frequency(b, c)); + } + + if (vtxtable().band_attribute(b) == vtx::Config::BandAttribute::CUSTOM) { + PX4_INFO_RAW(" CUSTOM\n"); + + } else { + PX4_INFO_RAW("\n"); + } + } +} + +void vtxtable_print_power_levels() +{ + for (uint8_t p = 0; p < vtxtable().power_levels(); p++) { + PX4_INFO(" %u: %2hi = %s", p + 1, vtxtable().power_value(p), vtxtable().power_label(p)); + } +} + +#ifdef CONFIG_VTXTABLE_AUX_MAP +void vtxtable_print_aux_map() +{ + for (uint8_t i = 0; i < vtx::Config::MAP_LENGTH; i++) { + uint8_t rc_channel{}, band{}, channel{}; + int8_t power_level{}; + uint16_t start_range{}, end_range{}; + vtxtable().map_entry(i, &rc_channel, &band, &channel, &power_level, &start_range, &end_range); + + if (!start_range && !end_range) { break; } + + if (!band && !channel) { + if (power_level == -1) { + PX4_INFO(" %2u: Ch%-2u, %4hu - %4hu = pit mode", + i, rc_channel, start_range, end_range); + + } else { + PX4_INFO(" %2u: Ch%-2u, %4hu - %4hu = %s", + i, rc_channel, start_range, end_range, + vtxtable().power_label(power_level - 1)); + } + + } else { + PX4_INFO(" %2u: Ch%-2u, %4hu - %4hu = %u + %u", + i, rc_channel, start_range, end_range, + band, channel); + } + } +} +#endif + +extern "C" __EXPORT int vtxtable_main(int argc, char *argv[]) +{ + if (argc <= 1) { + return vtxtable_print_usage("missing command"); + } + argc--; argv++; + return vtxtable_custom_command(argc, argv); +} diff --git a/src/drivers/vtxtable/VtxTable.hpp b/src/drivers/vtxtable/VtxTable.hpp new file mode 100644 index 0000000000..de367398cf --- /dev/null +++ b/src/drivers/vtxtable/VtxTable.hpp @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include "config.h" + +/** + * @author Niklas Hauser + */ + +extern vtx::Config &vtxtable(); + +#ifdef CONFIG_VTXTABLE_USE_STORAGE +extern int vtxtable_store(const char *filename); +extern int vtxtable_load(const char *filename); +#endif + +extern void vtxtable_print_frequencies(); +extern void vtxtable_print_power_levels(); +#ifdef CONFIG_VTXTABLE_AUX_MAP +extern void vtxtable_print_aux_map(); +#endif diff --git a/src/drivers/vtxtable/config.h b/src/drivers/vtxtable/config.h new file mode 100644 index 0000000000..f22b76e0f4 --- /dev/null +++ b/src/drivers/vtxtable/config.h @@ -0,0 +1,545 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +extern "C" { +#include +} + +namespace vtx +{ + +/** + * Class storing the VTX frequencies and power levels and the map from RC channels to VTX settings. + * Everything is 0-indexed. + * @author Niklas Hauser + */ +class Config +{ +public: + static constexpr size_t BANDS{24}; + static constexpr size_t CHANNELS{16}; + static constexpr size_t POWER_LEVELS{16}; + static constexpr size_t MAP_LENGTH{160}; + static constexpr size_t NAME_LENGTH{16}; + static constexpr size_t BAND_NAME_LENGTH{12}; + static constexpr size_t POWER_LABEL_LENGTH{4}; + enum class BandAttribute : uint8_t { + FACTORY = 0, + CUSTOM = 1, + }; + // Allows to detect changes in the configuration + using ChangeType = uint16_t; + inline ChangeType get_change() { return _change_value; } + + constexpr Config() = default; + inline ~Config() + { + pthread_mutex_destroy(&_mutex); + } + +#ifdef CONFIG_VTXTABLE_AUX_MAP + // ================================== RC MAP ================================== + inline int set_map_entry(uint8_t index, uint8_t rc_channel, uint8_t band, uint8_t channel, + int8_t power_level, uint16_t start_range, uint16_t end_range) + { + if (index >= MAP_LENGTH) { + return -EINVAL; + } + + LockGuard lg{_mutex}; + _data.rc_map[index].rc_channel = rc_channel; + _data.rc_map[index].band = band; + _data.rc_map[index].channel = channel; + _data.rc_map[index].power_level = power_level; + _data.rc_map[index].start_range = start_range; + _data.rc_map[index].end_range = end_range; + _change_value++; + + return 0; + } + + inline int map_entry(uint8_t index, uint8_t *rc_channel, uint8_t *band, uint8_t *channel, + int8_t *power_level, uint16_t *start_range, uint16_t *end_range) const + { + if (index >= MAP_LENGTH) { + return -EINVAL; + } + + LockGuard lg{_mutex}; + + if (rc_channel) { *rc_channel = _data.rc_map[index].rc_channel; } + + if (band) { *band = _data.rc_map[index].band; } + + if (channel) { *channel = _data.rc_map[index].channel; } + + if (power_level) { *power_level = _data.rc_map[index].power_level; } + + if (start_range) { *start_range = _data.rc_map[index].start_range; } + + if (end_range) { *end_range = _data.rc_map[index].end_range; } + + return 0; + } + + inline int map_lookup(uint16_t *rc_values, size_t rc_count, + int8_t *band, int8_t *channel, int8_t *power_level) const + { + LockGuard lg{_mutex}; + + for (uint8_t i = 0; i < MAP_LENGTH; i++) { + if (_data.rc_map[i].rc_channel >= rc_count || _data.rc_map[i].is_empty()) { + continue; + } + + const uint16_t pwm_value = rc_values[_data.rc_map[i].rc_channel]; + + if (pwm_value >= _data.rc_map[i].start_range && + pwm_value < _data.rc_map[i].end_range) { + if (_data.rc_map[i].band) { *band = _data.rc_map[i].band; } + + if (_data.rc_map[i].channel) { *channel = _data.rc_map[i].channel; } + + if (_data.rc_map[i].power_level) { *power_level = _data.rc_map[i].power_level; } + } + } + + return 0; + } + + inline int map_clear() + { + LockGuard lg{_mutex}; + memset(&_data.rc_map, 0, sizeof(_data.rc_map)); + _change_value++; + return 0; + } + + inline size_t map_size() const + { + LockGuard lg{_mutex}; + size_t count{}; + + for (uint_fast8_t i = 0; i < MAP_LENGTH; i++) { + if (!_data.rc_map[i].is_empty()) { + count++; + } + } + + return count; + } +#endif + + // ================================ VTX TABLE ================================= + inline const char *name() const + { + LockGuard lg{_mutex}; + return _data.table.name; + } + inline bool set_name(const char *name) + { + if (!name) { return false; } + + LockGuard lg{_mutex}; + strncpy(_data.table.name, name, NAME_LENGTH); + _data.table.name[NAME_LENGTH] = 0; + _change_value++; + return true; + } + inline uint16_t frequency(uint8_t band, uint8_t channel) const + { + LockGuard lg{_mutex}; + + if (band >= _data.table.bands || channel >= _data.table.channels) { + return 0; + } + + return _data.table.frequency[band][channel]; + } + inline bool set_frequency(uint8_t band, uint8_t channel, uint16_t frequency) + { + if (band >= BANDS || channel >= CHANNELS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.frequency[band][channel] = frequency; + _change_value++; + return true; + } + inline bool find_band_channel(uint16_t frequency, uint8_t *band, uint8_t *channel) const + { + LockGuard lg{_mutex}; + + for (uint8_t bandi = 0; bandi < _data.table.bands; bandi++) { + for (uint8_t channeli = 0; channeli < _data.table.channels; channeli++) { + if (_data.table.frequency[bandi][channeli] == frequency) { + *band = bandi; + *channel = channeli; + return true; + } + } + } + + return false; + } + + inline size_t channels() const + { + LockGuard lg{_mutex}; + return _data.table.channels; + } + inline bool set_channels(size_t channels) + { + if (channels > CHANNELS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.channels = channels; + _change_value++; + return true; + } + + inline size_t bands() const + { + LockGuard lg{_mutex}; + return _data.table.bands; + } + inline bool set_bands(size_t bands) + { + if (bands > BANDS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.bands = bands; + _change_value++; + return true; + } + + inline const char *band_name(uint8_t band) const + { + LockGuard lg{_mutex}; + + if (band >= _data.table.bands) { + return "?"; + } + + return const_cast(_data.table.band[band]); + } + inline bool set_band_name(uint8_t band, const char *name) + { + if (band >= BANDS || !name) { + return false; + } + + LockGuard lg{_mutex}; + strncpy(_data.table.band[band], name, BAND_NAME_LENGTH); + _data.table.band[band][BAND_NAME_LENGTH] = 0; + _change_value++; + return true; + } + + inline char band_letter(uint8_t band) const + { + LockGuard lg{_mutex}; + + if (band >= _data.table.bands) { + return '?'; + } + + const char c = _data.table.letter[band]; + return c ? c : '?'; + } + inline bool set_band_letter(uint8_t band, char c) + { + if (band >= BANDS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.letter[band] = c; + _change_value++; + return true; + } + + inline BandAttribute band_attribute(uint8_t band) const + { + LockGuard lg{_mutex}; + + if (band >= _data.table.bands) { + return BandAttribute::FACTORY; + } + + return _data.table.attribute[band]; + } + inline bool set_band_attribute(uint8_t band, BandAttribute attribute) + { + if (band >= BANDS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.attribute[band] = attribute; + _change_value++; + return true; + } + + inline size_t power_levels() const + { + LockGuard lg{_mutex}; + return _data.table.power_levels; + } + inline bool set_power_levels(size_t levels) + { + if (levels > POWER_LEVELS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.power_levels = levels; + _change_value++; + return true; + } + + inline int16_t power_value(uint8_t level) const + { + LockGuard lg{_mutex}; + + if (level >= _data.table.power_levels) { + return 0; + } + + return _data.table.power_value[level]; + } + inline bool set_power_value(uint8_t level, int16_t value) + { + if (level >= POWER_LEVELS) { + return false; + } + + LockGuard lg{_mutex}; + _data.table.power_value[level] = value; + _change_value++; + return true; + } + inline const char *power_label(uint8_t level) const + { + LockGuard lg{_mutex}; + + if (level >= _data.table.power_levels) { + return "?"; + } + + return _data.table.power_label[level]; + } + inline bool set_power_label(uint8_t level, const char *label) + { + if (level >= POWER_LEVELS || !label) { + return false; + } + + LockGuard lg{_mutex}; + strncpy(_data.table.power_label[level], label, POWER_LABEL_LENGTH); + _data.table.power_label[level][POWER_LABEL_LENGTH] = 0; + _change_value++; + return true; + } + + inline void table_clear() + { + LockGuard lg{_mutex}; + _data.table = {}; + _change_value++; + } + + inline void clear() + { + LockGuard lg{_mutex}; + _data = {}; + _change_value++; + } + +#ifdef CONFIG_VTXTABLE_USE_STORAGE + inline int store(const char *filename) const + { + LockGuard lg{_mutex}; + int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); + + if (fd < 0) { + return errno; + } + + // first write the magic/version + const uint64_t magic = MAGIC; + int written = write(fd, &magic, sizeof(MAGIC)); + + // Then write the rest of the data + written += write(fd, &_data, sizeof(Storage)); + + // finally compute and write the crc16 + const uint16_t crc = crc16_signature(CRC16_INITIAL, sizeof(Storage), (const uint8_t *)&_data); + written += write(fd, &crc, sizeof(crc)); + + close(fd); + return (written == FILE_SIZE) ? 0 : -EMSGSIZE; + } + + inline int load(const char *filename) + { + if (access(filename, R_OK)) { + return -ENOENT; + } + + LockGuard lg{_mutex}; + int fd = open(filename, O_RDONLY); + + if (fd < 0) { + return errno; + } + + // Check file size first + const off_t file_size = lseek(fd, 0, SEEK_END); + + if (file_size != FILE_SIZE) { + close(fd); + return -EMSGSIZE; + } + + // Check the version next + lseek(fd, 0, SEEK_SET); + uint64_t magic{}; + const int read_size = read(fd, &magic, sizeof(magic)); + + if (read_size != sizeof(magic) || magic != MAGIC) { + close(fd); + return -EPROTO; + } + + // Compute and check crc16 of the data in chunks + const size_t CHUNK{128}; + uint8_t buffer[CHUNK]; + size_t remaining{sizeof(Storage)}; + uint16_t computed_crc{0xffff}; + + while (remaining > 0) { + const int r = read(fd, buffer, (remaining < CHUNK) ? remaining : CHUNK); + + if (r <= 0) { + close(fd); + return -EIO; + } + + computed_crc = crc16_signature(computed_crc, r, buffer) ^ CRC16_OUTPUT_XOR; + remaining -= r; + } + + // read the stored crc16 + uint16_t stored_crc{}; + const int r = read(fd, &stored_crc, sizeof(stored_crc)); + + if (r != sizeof(stored_crc)) { + close(fd); + return -EIO; + } + + if (computed_crc != stored_crc) { + close(fd); + return -EBADMSG; + } + + // now read into the data structure directly + lseek(fd, sizeof(magic), SEEK_SET); + read(fd, &_data, sizeof(Storage)); + close(fd); + + _change_value++; + return 0; + } +#endif + +private: +#ifdef CONFIG_VTXTABLE_AUX_MAP + struct MapEntry { + uint8_t rc_channel; + uint8_t band; + uint8_t channel; + int8_t power_level; + uint16_t start_range; + uint16_t end_range; + constexpr bool is_empty() const { return !start_range && !end_range; } + } __attribute__((packed)); +#endif + + struct Table { + uint16_t frequency[BANDS][CHANNELS] {}; + int16_t power_value[POWER_LEVELS] {}; + char band[BANDS][BAND_NAME_LENGTH + 1] {}; + char power_label[POWER_LEVELS][POWER_LABEL_LENGTH + 1] {}; + char name[NAME_LENGTH + 1] {}; + char letter[BANDS] {}; + BandAttribute attribute[BANDS] {}; + uint8_t bands{}; + uint8_t channels{}; + uint8_t power_levels{}; + } __attribute__((packed)); + + struct Storage { + Table table{}; +#ifdef CONFIG_VTXTABLE_AUX_MAP + MapEntry rc_map[MAP_LENGTH]; +#endif + } __attribute__((packed)); + +#ifdef CONFIG_VTXTABLE_USE_STORAGE + static constexpr uint16_t VERSION {3}; + static constexpr uint64_t MAGIC{0x767478'636e66'0000ull | VERSION}; // "vtxcnf" + version magic + static constexpr size_t FILE_SIZE{sizeof(Storage) + sizeof(MAGIC) + sizeof(uint16_t)}; +#endif + + mutable pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; + Storage _data{}; + ChangeType _change_value{}; +}; + +} diff --git a/src/examples/fake_gps/FakeGps.cpp b/src/examples/fake_gps/FakeGps.cpp index e2f966e023..ad1166e49c 100644 --- a/src/examples/fake_gps/FakeGps.cpp +++ b/src/examples/fake_gps/FakeGps.cpp @@ -87,6 +87,14 @@ void FakeGps::Run() sensor_gps.satellites_used = 14; sensor_gps.timestamp = hrt_absolute_time(); _sensor_gps_pub.publish(sensor_gps); + + sensor_gnss_status_s sensor_gnss_status{}; + sensor_gnss_status.quality_corrections = 0; + sensor_gnss_status.quality_receiver = 9; + sensor_gnss_status.quality_gnss_signals = 10; + sensor_gnss_status.quality_post_processing = 255; + sensor_gnss_status.timestamp = hrt_absolute_time(); + _sensor_gnss_status_pub.publish(sensor_gnss_status); } int FakeGps::task_spawn(int argc, char *argv[]) diff --git a/src/examples/fake_gps/FakeGps.hpp b/src/examples/fake_gps/FakeGps.hpp index eae3b47512..223f372e44 100644 --- a/src/examples/fake_gps/FakeGps.hpp +++ b/src/examples/fake_gps/FakeGps.hpp @@ -41,6 +41,7 @@ #include #include #include +#include class FakeGps : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem { @@ -66,6 +67,7 @@ private: void Run() override; uORB::PublicationMulti _sensor_gps_pub{ORB_ID(sensor_gps)}; + uORB::PublicationMulti _sensor_gnss_status_pub{ORB_ID(sensor_gnss_status)}; double _latitude{29.6603018}; // Latitude in degrees double _longitude{-82.3160500}; // Longitude in degrees diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8afa75fd58..33d58ab640 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -50,6 +50,7 @@ add_subdirectory(dataman_client EXCLUDE_FROM_ALL) add_subdirectory(drivers EXCLUDE_FROM_ALL) add_subdirectory(field_sensor_bias_estimator EXCLUDE_FROM_ALL) add_subdirectory(geo EXCLUDE_FROM_ALL) +add_subdirectory(gnss EXCLUDE_FROM_ALL) add_subdirectory(heatshrink EXCLUDE_FROM_ALL) add_subdirectory(hysteresis EXCLUDE_FROM_ALL) add_subdirectory(lat_lon_alt EXCLUDE_FROM_ALL) @@ -67,10 +68,12 @@ add_subdirectory(pure_pursuit EXCLUDE_FROM_ALL) add_subdirectory(rate_control EXCLUDE_FROM_ALL) add_subdirectory(rc EXCLUDE_FROM_ALL) add_subdirectory(ringbuffer EXCLUDE_FROM_ALL) +add_subdirectory(rl_tools EXCLUDE_FROM_ALL) add_subdirectory(rover_control EXCLUDE_FROM_ALL) add_subdirectory(rtl EXCLUDE_FROM_ALL) add_subdirectory(sensor_calibration EXCLUDE_FROM_ALL) add_subdirectory(slew_rate EXCLUDE_FROM_ALL) +add_subdirectory(sticks EXCLUDE_FROM_ALL) add_subdirectory(stick_yaw EXCLUDE_FROM_ALL) add_subdirectory(systemlib EXCLUDE_FROM_ALL) add_subdirectory(system_identification EXCLUDE_FROM_ALL) diff --git a/src/lib/adsb/AdsbConflict.cpp b/src/lib/adsb/AdsbConflict.cpp index 08d13e12a4..976b322796 100644 --- a/src/lib/adsb/AdsbConflict.cpp +++ b/src/lib/adsb/AdsbConflict.cpp @@ -77,7 +77,7 @@ void AdsbConflict::detect_traffic_conflict(double lat_now, double lon_now, float && (fabsf(_crosstrack_error.distance) < _conflict_detection_params.crosstrack_separation); const bool _crosstrack_separation_check = (fabsf(alt_now - _transponder_report.altitude) < - _conflict_detection_params.crosstrack_separation); + _conflict_detection_params.vertical_separation); bool collision_time_check = false; diff --git a/src/lib/battery/battery.cpp b/src/lib/battery/battery.cpp index 10dbb93a68..16b79a6bbd 100644 --- a/src/lib/battery/battery.cpp +++ b/src/lib/battery/battery.cpp @@ -113,6 +113,8 @@ void Battery::updateTemperature(const float temperature_c) void Battery::updateBatteryStatus(const hrt_abstime ×tamp) { + updateDt(timestamp); + // Require minimum voltage otherwise override connected status if (_voltage_v < LITHIUM_BATTERY_RECOGNITION_VOLTAGE) { _connected = false; @@ -129,7 +131,7 @@ void Battery::updateBatteryStatus(const hrt_abstime ×tamp) resetInternalResistanceEstimation(_voltage_v, _current_a); } - sumDischarged(timestamp, _current_a); + sumDischarged(_current_a); _state_of_charge_volt_based = calculateStateOfChargeVoltageBased(_voltage_v, _current_a); @@ -159,7 +161,7 @@ battery_status_s Battery::getBatteryStatus() battery_status.connected = _connected; battery_status.source = _source; battery_status.priority = _priority; - battery_status.capacity = _params.capacity > 0.f ? static_cast(_params.capacity) : 0; + battery_status.capacity = static_cast(_capacity_mah); battery_status.id = static_cast(_index); battery_status.warning = _warning; battery_status.timestamp = hrt_absolute_time(); @@ -188,28 +190,26 @@ void Battery::updateAndPublishBatteryStatus(const hrt_abstime ×tamp) updateBatteryStatus(timestamp); publishBatteryStatus(getBatteryStatus()); } - -void Battery::sumDischarged(const hrt_abstime ×tamp, float current_a) +void Battery::updateDt(const hrt_abstime ×tamp) { - // Not a valid measurement - if (current_a < 0.f) { - // Because the measurement was invalid we need to stop integration - // and re-initialize with the next valid measurement - _last_timestamp = 0; - return; - } - - // Ignore first update because we don't know dt. if (_last_timestamp != 0) { - const float dt = (timestamp - _last_timestamp) / 1e6; - // mAh since last loop: (current[A] * 1000 = [mA]) * (dt[s] / 3600 = [h]) - _discharged_mah_loop = (current_a * 1e3f) * (dt / 3600.f); - _discharged_mah += _discharged_mah_loop; + _dt = math::min((timestamp - _last_timestamp) / 1e6f, 2.f); // guard to a maximum 2 seconds dt } _last_timestamp = timestamp; } +float Battery::sumDischarged(float current_a) +{ + if (_dt > FLT_EPSILON) { + // mAh since last loop: (current[A] * 1000 = [mA]) * (dt[s] / 3600 = [h]) + _discharged_mah_loop = (current_a * 1e3f) * (_dt / 3600.f); + _discharged_mah += _discharged_mah_loop; + } + + return _discharged_mah; +} + float Battery::calculateStateOfChargeVoltageBased(const float voltage_v, const float current_a) { if (_params.n_cells == 0) { @@ -287,16 +287,16 @@ void Battery::resetInternalResistanceEstimation(const float voltage_v, const flo void Battery::estimateStateOfCharge() { // choose which quantity we're using for final reporting - if ((_params.capacity > 0.f) && _battery_initialized) { + if ((_capacity_mah > 0.f) && _battery_initialized) { // if battery capacity is known, fuse voltage measurement with used capacity // The lower the voltage the more adjust the estimate with it to avoid deep discharge const float weight_v = 3e-2f * (1 - _state_of_charge_volt_based); _state_of_charge = (1 - weight_v) * _state_of_charge + weight_v * _state_of_charge_volt_based; // directly apply current capacity slope calculated using current - _state_of_charge -= _discharged_mah_loop / _params.capacity; + _state_of_charge -= _discharged_mah_loop / _capacity_mah; _state_of_charge = math::max(_state_of_charge, 0.f); - const float state_of_charge_current_based = math::max(1.f - _discharged_mah / _params.capacity, 0.f); + const float state_of_charge_current_based = math::max(1.f - _discharged_mah / _capacity_mah, 0.f); _state_of_charge = math::min(state_of_charge_current_based, _state_of_charge); } else { @@ -330,6 +330,10 @@ uint16_t Battery::determineFaults() faults |= (1 << battery_status_s::FAULT_SPIKES); } + if (PX4_ISFINITE(_temperature_c) && _temperature_c > BAT_TEMP_MAX) { + faults |= (1 << battery_status_s::FAULT_OVER_TEMPERATURE); + } + return faults; } @@ -376,14 +380,18 @@ float Battery::computeRemainingTime(float current_a) // For FW only update when we are in level flight if (!_vehicle_status_is_fw || ((hrt_absolute_time() - _flight_phase_estimation_sub.get().timestamp) < 2_s && _flight_phase_estimation_sub.get().flight_phase == flight_phase_estimation_s::FLIGHT_PHASE_LEVEL)) { - // only update with positive numbers - _current_average_filter_a.update(fmaxf(current_a, 0.f)); + if (_dt > FLT_EPSILON) { + _current_average_filter_a.update(fmaxf(current_a, 0.f), _dt); + + } else { + _current_average_filter_a.update(fmaxf(current_a, 0.f)); + } } } // Remaining time estimation only possible with capacity - if (_params.capacity > 0.f) { - const float remaining_capacity_mah = _state_of_charge * _params.capacity; + if (_capacity_mah > 0.f) { + const float remaining_capacity_mah = _state_of_charge * _capacity_mah; const float current_ma = fmaxf(_current_average_filter_a.getState() * 1e3f, FLT_EPSILON); time_remaining_s = remaining_capacity_mah / current_ma * 3600.f; } @@ -397,7 +405,6 @@ void Battery::updateParams() param_get(_param_handles.v_empty, &_params.v_empty); param_get(_param_handles.v_charged, &_params.v_charged); param_get(_param_handles.n_cells, &_params.n_cells); - param_get(_param_handles.capacity, &_params.capacity); param_get(_param_handles.r_internal, &_params.r_internal); param_get(_param_handles.source, &_params.source); param_get(_param_handles.low_thr, &_params.low_thr); @@ -405,6 +412,10 @@ void Battery::updateParams() param_get(_param_handles.emergen_thr, &_params.emergen_thr); param_get(_param_handles.bat_avrg_current, &_params.bat_avrg_current); + float capacity{0.f}; + param_get(_param_handles.capacity, &capacity); + setCapacityMah(capacity); + if (n_cells != _params.n_cells) { _internal_resistance_initialized = false; } diff --git a/src/lib/battery/battery.h b/src/lib/battery/battery.h index baf6e5ecd6..b432c80e27 100644 --- a/src/lib/battery/battery.h +++ b/src/lib/battery/battery.h @@ -88,7 +88,8 @@ public: void setPriority(const uint8_t priority) { _priority = priority; } void setConnected(const bool connected) { _connected = connected; } - void setStateOfCharge(const float soc) { _state_of_charge = soc; _external_state_of_charge = true; } + void setStateOfCharge(const float soc) { _state_of_charge = math::constrain(soc, 0.f, 1.f); _external_state_of_charge = true; } + void setCapacityMah(const float capacity) { _capacity_mah = math::max(capacity, 0.f); } void updateVoltage(const float voltage_v); void updateCurrent(const float current_a); void updateTemperature(const float temperature_c); @@ -101,6 +102,7 @@ public: void updateBatteryStatus(const hrt_abstime ×tamp); battery_status_s getBatteryStatus(); + float getCurrentAverage() const { return PX4_ISFINITE(_current_average_filter_a.getState()) ? _current_average_filter_a.getState() : -1.f; } void publishBatteryStatus(const battery_status_s &battery_status); /** @@ -110,6 +112,27 @@ public: */ void updateAndPublishBatteryStatus(const hrt_abstime ×tamp); + /** + * Calculates how much time is left before the battery is depleted, + * given the heavily low-pass filtered current consumption. + * Requires the capacity and state of charge e.g. externally set through setCapacity() and setStateOfCharge(). + * + * @param current_a The current draw from the battery in amperes. + * @return Estimated remaining time in seconds. + */ + float computeRemainingTime(float current_a); + + /** + * Updates coulomb counting + * Requires a dt, seeupdateDt() + * + * @param current_a Positive current draw in A + * @return Accumulated used capacity in mAh + */ + float sumDischarged(float current_a); + uint8_t determineWarning(float state_of_charge); + void updateDt(const hrt_abstime ×tamp); + protected: static constexpr float LITHIUM_BATTERY_RECOGNITION_VOLTAGE = 2.1f; @@ -130,7 +153,6 @@ protected: float v_empty; float v_charged; int32_t n_cells; - float capacity; float r_internal; float low_thr; float crit_thr; @@ -145,13 +167,10 @@ protected: void updateParams() override; private: - void sumDischarged(const hrt_abstime ×tamp, float current_a); float calculateStateOfChargeVoltageBased(const float voltage_v, const float current_a); void estimateStateOfCharge(); - uint8_t determineWarning(float state_of_charge); uint16_t determineFaults(); void computeScale(); - float computeRemainingTime(float current_a); uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; uORB::SubscriptionData _flight_phase_estimation_sub{ORB_ID(flight_phase_estimation)}; @@ -176,6 +195,8 @@ private: float _state_of_charge{-1.f}; // [0,1] float _scale{1.f}; uint8_t _warning{battery_status_s::WARNING_NONE}; + float _dt{0.f}; + float _capacity_mah{0.f}; hrt_abstime _last_timestamp{0}; bool _armed{false}; bool _vehicle_status_is_fw{false}; @@ -196,4 +217,10 @@ private: static constexpr float OCV_DEFAULT = 4.2f; // [V] Initial per cell estimate of the open circuit voltage static constexpr float R_COVARIANCE = 0.1f; // Initial per cell covariance of the internal resistance static constexpr float OCV_COVARIANCE = 1.5f; // Initial per cell covariance of the open circuit voltage + + // Temperature [degC] above which an overtemperature fault is declared, + // leading to a failsafe warning recommending immediate landing. Note + // that depending on the setup this may be measured in/close to the + // battery (smart battery) or from a separate power monitor module. + static constexpr float BAT_TEMP_MAX = 100.0f; }; diff --git a/src/lib/battery/module.yaml b/src/lib/battery/module.yaml index b20900fa08..adaaf72395 100644 --- a/src/lib/battery/module.yaml +++ b/src/lib/battery/module.yaml @@ -105,15 +105,20 @@ parameters: description: short: Battery ${i} monitoring source. long: | - This parameter controls the source of battery data. The value 'Power Module' - means that measurements are expected to come from a power module. If the value is set to - 'External' then the system expects to receive mavlink battery status messages. + This parameter controls the source of battery data. The value 'Power Module / Analog' + means that measurements are expected to come from either analog (ADC) inputs + or an I2C power monitor (e.g. INA226). Analog inputs are voltage and current + measurements read from the board's ADC channels, typically from an onboard + voltage divider and current shunt, or an external analog power module. + I2C power monitors are digital sensors on the I2C bus. + If the value is set to 'External' then the system expects to receive MAVLink + or CAN battery status messages, or the battery data is published by an external driver. If the value is set to 'ESCs', the battery information are taken from the esc_status message. - This requires the ESC to provide both voltage as well as current. + This requires the ESC to provide both voltage as well as current (via ESC telemetry). type: enum values: -1: Disabled - 0: Power Module + 0: Power Module / Analog 1: External 2: ESCs reboot_required: true diff --git a/src/lib/drivers/CMakeLists.txt b/src/lib/drivers/CMakeLists.txt index 00c45648d4..051b40ab0c 100644 --- a/src/lib/drivers/CMakeLists.txt +++ b/src/lib/drivers/CMakeLists.txt @@ -37,5 +37,10 @@ add_subdirectory(gyroscope) add_subdirectory(led) add_subdirectory(magnetometer) add_subdirectory(rangefinder) + add_subdirectory(smbus) add_subdirectory(smbus_sbs) + +if (${PX4_PLATFORM} STREQUAL "nuttx") + add_subdirectory(mcp_common) +endif() diff --git a/src/lib/drivers/gyroscope/PX4Gyroscope.hpp b/src/lib/drivers/gyroscope/PX4Gyroscope.hpp index f89514f7a1..9350507860 100644 --- a/src/lib/drivers/gyroscope/PX4Gyroscope.hpp +++ b/src/lib/drivers/gyroscope/PX4Gyroscope.hpp @@ -45,9 +45,6 @@ public: PX4Gyroscope(uint32_t device_id, enum Rotation rotation = ROTATION_NONE); ~PX4Gyroscope(); - uint32_t get_device_id() const { return _device_id; } - - int32_t get_max_rate_hz() const { return math::constrain(_imu_gyro_rate_max, static_cast(100), static_cast(4000)); } void set_device_id(uint32_t device_id) { _device_id = device_id; } void set_device_type(uint8_t devtype); @@ -60,7 +57,9 @@ public: void updateFIFO(sensor_gyro_fifo_s &sample); + uint32_t get_device_id() const { return _device_id; } int get_instance() { return _sensor_pub.get_instance(); }; + int32_t get_max_rate_hz() const { return math::constrain(_imu_gyro_rate_max, static_cast(100), static_cast(4000)); } private: void UpdateClipLimit(); diff --git a/src/lib/drivers/magnetometer/PX4Magnetometer.hpp b/src/lib/drivers/magnetometer/PX4Magnetometer.hpp index a28de5fc12..0a05427af4 100644 --- a/src/lib/drivers/magnetometer/PX4Magnetometer.hpp +++ b/src/lib/drivers/magnetometer/PX4Magnetometer.hpp @@ -53,6 +53,7 @@ public: void update(const hrt_abstime ×tamp_sample, float x, float y, float z); int get_instance() { return _sensor_pub.get_instance(); }; + uint32_t get_device_id() const { return _device_id; } private: uORB::PublicationMulti _sensor_pub{ORB_ID(sensor_mag)}; diff --git a/src/lib/drivers/mcp_common/CMakeLists.txt b/src/lib/drivers/mcp_common/CMakeLists.txt new file mode 100644 index 0000000000..8efcb58921 --- /dev/null +++ b/src/lib/drivers/mcp_common/CMakeLists.txt @@ -0,0 +1,40 @@ +############################################################################ +# +# Copyright (c) 2023 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(mcp_common + MCP.cpp + ${PX4_SOURCE_DIR}/src/drivers/gpio/mcp23009/MCP23009.cpp + ${PX4_SOURCE_DIR}/src/drivers/gpio/mcp23017/MCP23017.cpp +) + +target_link_libraries(mcp_common PUBLIC platform_gpio_mcp) diff --git a/src/lib/drivers/mcp_common/CallbackHandler.hpp b/src/lib/drivers/mcp_common/CallbackHandler.hpp new file mode 100644 index 0000000000..f0aa770cec --- /dev/null +++ b/src/lib/drivers/mcp_common/CallbackHandler.hpp @@ -0,0 +1,61 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + +#include +#include +#include + +class CallbackHandler : public uORB::SubscriptionCallback +{ +public: + uint32_t dev_id; + uint16_t input{0}; + + CallbackHandler(orb_id_t id) : uORB::SubscriptionCallback(id) {} + virtual ~CallbackHandler() {} + + void call() override + { + px4::msg::GpioIn new_input; + + for (int i = 0; i < new_input.MAX_INSTANCES; i++) { + ChangeInstance(i); + + if (update(&new_input) && new_input.device_id == dev_id) { + input = new_input.state; + break; + } + } + } +}; diff --git a/src/lib/drivers/mcp_common/MCP.cpp b/src/lib/drivers/mcp_common/MCP.cpp new file mode 100644 index 0000000000..558aa8293a --- /dev/null +++ b/src/lib/drivers/mcp_common/MCP.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include "MCP.hpp" +#include +#include + +MCP230XX::MCP230XX(const I2CSPIDriverConfig &config) : + I2C(config), + I2CSPIDriver(config), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")), + _comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors")), + _register_check(perf_alloc(PC_COUNT, MODULE_NAME": register check")) +{ +} + +MCP230XX::~MCP230XX() +{ + ScheduleClear(); + perf_free(_cycle_perf); + perf_free(_comms_errors); + perf_free(_register_check); +} + +int MCP230XX::init_uorb() +{ + if (!_gpio_config_sub.registerCallback() || + !_gpio_out_sub.registerCallback()) { + PX4_ERR("callback registration failed"); + return PX4_ERROR; + } + + return PX4_OK; +} + +void MCP230XX::cleanup_uorb() +{ + _gpio_config_sub.unregisterCallback(); + _gpio_out_sub.unregisterCallback(); + mcp230XX_unregister_gpios(mcp_config.first_minor, mcp_config.num_pins, mcp_config._gpio_handle); +} + +int MCP230XX::read(uint16_t *mask) +{ + *mask = 0; + int ret = PX4_OK; + + for (int i = 0; i < mcp_config.num_banks; i++) { + uint8_t gpio_addr; + uint8_t data; + + ret |= get_gpio(i, &gpio_addr); + ret |= read_reg(gpio_addr, data); + + *mask |= (((uint16_t) data) << (8 * i)); + } + + return ret; +} + +int MCP230XX::write(const uint16_t mask_set, const uint16_t mask_clear) +{ + int ret = PX4_OK; + _olat = (_olat & ~mask_clear) | mask_set; + + for (int i = 0; i < mcp_config.num_banks; i++) { + uint8_t reg_addr; + uint8_t data; + uint8_t curr_olat = (uint8_t)((_olat >> (8 * i)) & 0x00FF); + + ret = get_olat(i, ®_addr); + + if (ret != PX4_OK) { + return ret; + } + + ret |= write_reg(reg_addr, curr_olat); + ret |= read_reg(reg_addr, data); + + if (ret != PX4_OK || data != curr_olat) { + return PX4_ERROR; + } + } + + return ret; +} + +int MCP230XX::read_reg(const uint8_t address, uint8_t &data) +{ + int ret = transfer(&address, 1, &data, 1); + + if (ret != PX4_OK) { + perf_count(_comms_errors); + } + + return ret; +} + +int MCP230XX::write_reg(const uint8_t address, const uint8_t value) +{ + uint8_t data[2] = {address, value}; + int ret = transfer(data, 2, nullptr, 0); + + if (ret != PX4_OK) { + perf_count(_comms_errors); + } + + return ret; +} + +int MCP230XX::configure(const uint16_t mask, PinType type) +{ + switch (type) { + case PinType::Input: + _iodir |= mask; + _gppu &= ~mask; + break; + + case PinType::InputPullUp: + _iodir |= mask; + _gppu |= mask; + break; + + case PinType::Output: + _iodir &= ~mask; + break; + + default: + return -EINVAL; + } + + int ret = PX4_OK; + + for (int i = 0; i < mcp_config.num_banks; i++) { + uint8_t curr_iodir = (uint8_t)((_iodir >> (8 * i)) & 0x00FF); + uint8_t curr_gppu = (uint8_t)((_gppu >> (8 * i)) & 0x00FF); + uint8_t iodir_addr; + uint8_t gppu_addr; + + ret = get_iodir(i, &iodir_addr); + ret |= get_gppu(i, &gppu_addr); + + if (ret != PX4_OK) { + return ret; + } + + ret = write_reg(iodir_addr, curr_iodir); + ret |= write_reg(gppu_addr, curr_gppu); + + if (ret != PX4_OK) { + PX4_ERR("MCP configure failed"); + return ret; + } + } + + return PX4_OK; +} + +int MCP230XX::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + PX4_ERR("I2C init failed"); + return ret; + } + + ScheduleNow(); + return PX4_OK; +} + +int MCP230XX::init_communication() +{ + int ret = mcp230XX_register_gpios(mcp_config.i2c_bus, mcp_config.i2c_addr, mcp_config.first_minor, _iodir, mcp_config.num_pins, + mcp_config.device_type, mcp_config._gpio_handle); + ret |= init_uorb(); + return ret; +} + +int MCP230XX::set_up() +{ + int ret = PX4_OK; + uint8_t iodir_addr; + uint8_t olat_addr; + uint8_t gppu_addr; + + for (int i = 0; i < mcp_config.num_banks; i++) { + uint8_t curr_iodir = (uint8_t)((_iodir >> (8 * i)) & 0x00FF); + uint8_t curr_olat = (uint8_t)((_olat >> (8 * i)) & 0x00FF); + uint8_t curr_gppu = (uint8_t)((_gppu >> (8 * i)) & 0x00FF); + + ret |= get_olat(i, &olat_addr); + ret |= get_iodir(i, &iodir_addr); + ret |= get_gppu(i, &gppu_addr); + + if (ret != PX4_OK) { + return ret; + } + + ret |= write_reg(iodir_addr, curr_iodir); + ret |= write_reg(olat_addr, curr_olat); + ret |= write_reg(gppu_addr, curr_gppu); + + if (ret != PX4_OK) { + return ret; + } + } + + return ret; +} + +int MCP230XX::sanity_check() +{ + int ret = PX4_OK; + + for (int i = 0; i < mcp_config.num_banks; i++) { + uint8_t curr_iodir = (uint8_t)((_iodir >> (8 * i)) & 0x00FF); + uint8_t curr_olat = (uint8_t)((_olat >> (8 * i)) & 0x00FF); + uint8_t curr_gppu = (uint8_t)((_gppu >> (8 * i)) & 0x00FF); + + uint8_t iodir_addr; + uint8_t olat_addr; + uint8_t gppu_addr; + + uint8_t read_iodir; + uint8_t read_olat; + uint8_t read_gppu; + + ret |= get_olat(i, &olat_addr); + ret |= get_iodir(i, &iodir_addr); + ret |= get_gppu(i, &gppu_addr); + + ret |= read_reg(iodir_addr, read_iodir); + ret |= read_reg(olat_addr, read_olat); + ret |= read_reg(gppu_addr, read_gppu); + + if (read_iodir != curr_iodir || read_olat != curr_olat || read_gppu != curr_gppu) { + perf_count(_register_check); + return PX4_ERROR; + } + } + + return ret; +} + +int MCP230XX::probe() +{ + // no whoami, try to read IOCONA + uint8_t data; + uint8_t addr; + int ret = PX4_OK; + + for (int i = 0; i < 10; i++) { + ret = get_probe_reg(&addr); + + if (ret == PX4_OK) { + ret = read_reg(addr, data); + + if (ret == PX4_OK) { + return PX4_OK; + } + } + + px4_usleep(10'000); + } + + return PX4_ERROR; +} + +void MCP230XX::RunImpl() +{ + if (should_exit()) { + cleanup_uorb(); + exit_and_cleanup(); + return; + } + + int ret = PX4_OK; + + switch (_curr_state) { + case STATE::INIT_COMMUNICATION: + ret = init_communication(); + + if (ret == PX4_OK) { + _curr_state = STATE::CONFIGURE; + ScheduleNow(); + + } else { + ScheduleDelayed(mcp_config.interval * 1000); + } + + break; + + case STATE::CONFIGURE: + ret = set_up(); + + if (ret == PX4_OK) { + _curr_state = STATE::CHECK; + ScheduleNow(); + + } else { + ScheduleDelayed(mcp_config.interval * 1000); + } + + break; + + case STATE::CHECK: + ret = sanity_check(); + + if (ret == PX4_OK) { + _curr_state = STATE::RUNNING; + ScheduleOnInterval(mcp_config.interval * 1000); + + } else { + _curr_state = STATE::CONFIGURE; + ScheduleDelayed(mcp_config.interval * 1000); + } + + break; + + case STATE::RUNNING: + perf_begin(_cycle_perf); + gpio_config_s config; + + if (_gpio_config_sub.update(&config) && config.device_id == get_device_id()) { + PinType type = PinType::Input; + + switch (config.config) { + case config.INPUT_PULLUP: type = PinType::InputPullUp; break; + + case config.OUTPUT: type = PinType::Output; break; + } + + ret |= write(config.state, config.mask); + ret |= configure(config.mask, type); + } + + gpio_out_s output; + + if (_gpio_out_sub.update(&output) && output.device_id == get_device_id()) { + ret |= write(output.state, output.mask); + } + + { + gpio_in_s _gpio_in; + _gpio_in.timestamp = hrt_absolute_time(); + _gpio_in.device_id = get_device_id(); + uint16_t input = 0; + + if (read(&input) == PX4_OK) { + _gpio_in.state = input; + _to_gpio_in.publish(_gpio_in); + } + } + + _count++; + + if (_count >= _checking_freq || ret != PX4_OK) { + _curr_state = STATE::CHECK; + _count = 0; + ScheduleClear(); + ScheduleNow(); + } + + perf_end(_cycle_perf); + } +} + +void MCP230XX::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); + perf_print_counter(_comms_errors); + perf_print_counter(_register_check); +} + +void MCP230XX::print_usage() +{ + PRINT_MODULE_USAGE_NAME("mcp230xx", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); + PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x27); + PRINT_MODULE_USAGE_PARAM_INT('D', 0, 0, 65535, "Direction (1=Input, 0=Output)", true); + PRINT_MODULE_USAGE_PARAM_INT('O', 0, 0, 65535, "Output", true); + PRINT_MODULE_USAGE_PARAM_INT('P', 0, 0, 65535, "Pullups", true); + PRINT_MODULE_USAGE_PARAM_INT('U', 0, 0, 1000, "Update Interval [ms]", true); + PRINT_MODULE_USAGE_PARAM_INT('M', 0, 0, 255, "First minor number", true); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +I2CSPIDriverBase *MCP230XX::instantiate(const I2CSPIDriverConfig &config, int runtime_instance) +{ + MCP230XX *instance = nullptr; + + switch (config.devid_driver_index) { + case DRV_GPIO_DEVTYPE_MCP23009: + instance = new MCP23009(config); + break; + + case DRV_GPIO_DEVTYPE_MCP23017: + instance = new MCP23017(config); + break; + + default: + instance = nullptr; + break; + } + + if (!instance) { + PX4_ERR("alloc failed"); + return nullptr; + } + + MCP230XX_config_t tmp_config = *static_cast(config.custom_data); + instance->mcp_config = tmp_config; + instance->mcp_config.i2c_bus = config.bus; + instance->mcp_config.i2c_addr = config.i2c_address; + + if (OK != instance->init()) { + delete instance; + return nullptr; + } + + instance->_iodir = instance->mcp_config.direction; + instance->_olat = instance->mcp_config.state; + instance->_gppu = instance->mcp_config.pullup; + + return instance; +} diff --git a/src/drivers/gpio/mcp23009/mcp23009.h b/src/lib/drivers/mcp_common/MCP.hpp similarity index 56% rename from src/drivers/gpio/mcp23009/mcp23009.h rename to src/lib/drivers/mcp_common/MCP.hpp index fce68576c5..b4c1a235dd 100644 --- a/src/drivers/gpio/mcp23009/mcp23009.h +++ b/src/lib/drivers/mcp_common/MCP.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * Copyright (C) 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,6 @@ * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ - #pragma once #include @@ -39,73 +38,91 @@ #include #include #include -#include -#include -#include +#include #include #include +#include +#include -using namespace time_literals; +static constexpr uint8_t I2C_ADDRESS_MCP23009 = 0x25; +static constexpr uint8_t I2C_ADDRESS_MCP23017 = 0x27; -class MCP23009 : public device::I2C, public I2CSPIDriver +enum class +PinType : uint8_t { + Output, + Input, + InputPullUp, +}; + +struct MCP230XX_config_t { + uint16_t device_type; + uint8_t i2c_addr = 0; + uint8_t i2c_bus = 0; + uint8_t first_minor = 0; + uint8_t num_pins = 8; + int num_banks = 1; + uint16_t interval = 10; + mcp_gpio_dev_s _gpio_handle[16]; + CallbackHandler *_callback_handler = nullptr; + + uint16_t direction = 0xFFFF; + uint16_t state = 0x0000; + uint16_t pullup = 0x0000; +}; + +class MCP230XX : public device::I2C, public I2CSPIDriver { public: - MCP23009(const I2CSPIDriverConfig &config); - ~MCP23009() override; + MCP230XX(const I2CSPIDriverConfig &config); + virtual ~MCP230XX(); + static I2CSPIDriverBase *instantiate(const I2CSPIDriverConfig &config, int runtime_instance); + static void print_usage(); void RunImpl(); - - static void print_usage(); - static I2CSPIDriverBase *instantiate(const I2CSPIDriverConfig &config, int runtime_instance); + void print_status() override; + int probe(); + virtual int init(); protected: - int init_uorb(); - int init(uint8_t direction, uint8_t state, uint8_t pull_up); - - int probe() override; - void print_status() override; - void exit_and_cleanup() override; + MCP230XX_config_t mcp_config; private: - enum class - Register : uint8_t { - IODIR = 0x00, - IPOL = 0x01, - GPINTEN = 0x02, - DEFVAL = 0x03, - INTCON = 0x04, - IOCON = 0x05, - GPPU = 0x06, - INTF = 0x07, - INTCAP = 0x08, - GPIO = 0x09, - OLAT = 0x0a - }; - - enum class - PinType : uint8_t { - Output, - Input, - InputPullUp, - }; - uORB::SubscriptionCallbackWorkItem _gpio_out_sub{this, ORB_ID(gpio_out)}; - uORB::SubscriptionCallbackWorkItem _gpio_request_sub{this, ORB_ID(gpio_request)}; uORB::SubscriptionCallbackWorkItem _gpio_config_sub{this, ORB_ID(gpio_config)}; - - uORB::Publication _to_gpio_in{ORB_ID(gpio_in)}; + uORB::PublicationMulti _to_gpio_in{ORB_ID(gpio_in)}; perf_counter_t _cycle_perf; + perf_counter_t _comms_errors; + perf_counter_t _register_check; - // buffer often used (write-only!) registers here - uint8_t _olat; - uint8_t _iodir; - uint8_t _gppu; + virtual int configure(uint16_t mask, PinType type); + virtual int read(uint16_t *mask); + int read_reg(uint8_t address, uint8_t &data); + int write(uint16_t mask_set, uint16_t mask_clear); + int write_reg(uint8_t address, uint8_t value); + int set_up(); + int sanity_check(); + int init_communication(); + int init_uorb(); + void cleanup_uorb(); - int read(uint8_t *mask); - int write(uint8_t mask_set, uint8_t mask_clear); - int configure(uint8_t mask, PinType type); + virtual int get_olat(int bank, uint8_t *addr) = 0; + virtual int get_gppu(int bank, uint8_t *addr) = 0; + virtual int get_iodir(int bank, uint8_t *addr) = 0; + virtual int get_gpio(int bank, uint8_t *addr) = 0; + virtual int get_probe_reg(uint8_t *addr) = 0; - int read_reg(Register address, uint8_t &data); - int write_reg(Register address, uint8_t data); + uint16_t _olat; + uint16_t _iodir; + uint16_t _gppu; + + uint16_t _checking_freq = 10; + int _count = 0; + + enum class STATE : uint8_t { + INIT_COMMUNICATION, + CONFIGURE, + CHECK, + RUNNING + } _curr_state {STATE::INIT_COMMUNICATION}; }; diff --git a/src/lib/drivers/rangefinder/PX4Rangefinder.cpp b/src/lib/drivers/rangefinder/PX4Rangefinder.cpp index 98c479efb1..0858b04afe 100644 --- a/src/lib/drivers/rangefinder/PX4Rangefinder.cpp +++ b/src/lib/drivers/rangefinder/PX4Rangefinder.cpp @@ -35,6 +35,8 @@ #include +using namespace time_literals; + PX4Rangefinder::PX4Rangefinder(const uint32_t device_id, const uint8_t device_orientation) { set_device_id(device_id); @@ -66,10 +68,9 @@ void PX4Rangefinder::set_orientation(const uint8_t device_orientation) _distance_sensor_pub.get().orientation = device_orientation; } -void PX4Rangefinder::update(const hrt_abstime ×tamp_sample, const float distance, const int8_t quality) +void PX4Rangefinder::update(const hrt_abstime ×tamp_sample, const float distance, const int8_t quality, const float *q, uint8_t q_len) { distance_sensor_s &report = _distance_sensor_pub.get(); - report.timestamp = timestamp_sample; report.current_distance = distance; report.signal_quality = quality; @@ -81,5 +82,10 @@ void PX4Rangefinder::update(const hrt_abstime ×tamp_sample, const float dis } } + // Update the quaternion in the sample update + if (q != nullptr) { + memcpy(report.q, q, sizeof(float) * q_len); + } + _distance_sensor_pub.update(); } diff --git a/src/lib/drivers/rangefinder/PX4Rangefinder.hpp b/src/lib/drivers/rangefinder/PX4Rangefinder.hpp index 725f03d321..572b7b5fd5 100644 --- a/src/lib/drivers/rangefinder/PX4Rangefinder.hpp +++ b/src/lib/drivers/rangefinder/PX4Rangefinder.hpp @@ -62,9 +62,12 @@ public: void set_mode(const uint8_t mode) { _distance_sensor_pub.get().mode = mode; } - void update(const hrt_abstime ×tamp_sample, const float distance, const int8_t quality = -1); + // update with quaterion sensor orientation with respect to the vehicle body frame + void update(const hrt_abstime ×tamp_sample, const float distance, const int8_t quality = -1, const float *q = nullptr, + uint8_t q_len = 4); int get_instance() { return _distance_sensor_pub.get_instance(); }; + uint32_t get_device_id() { return _distance_sensor_pub.get().device_id; }; private: uORB::PublicationMultiData _distance_sensor_pub{ORB_ID(distance_sensor)}; diff --git a/src/lib/events/enums.json b/src/lib/events/enums.json index 3b73cff62c..acd73c1447 100644 --- a/src/lib/events/enums.json +++ b/src/lib/events/enums.json @@ -442,13 +442,9 @@ "type": "uint8_t", "description": "Reason for arming/disarming", "entries": { - "0": { - "name": "transition_to_standby", - "description": "Transition to standby" - }, "1": { "name": "stick_gesture", - "description": "Stick gesture" + "description": "stick gesture" }, "2": { "name": "rc_switch", @@ -467,36 +463,20 @@ "description": "mission start" }, "6": { - "name": "auto_disarm_land", + "name": "landing", "description": "landing" }, "7": { - "name": "auto_disarm_preflight", - "description": "auto preflight disarming" + "name": "preflight_inaction", + "description": "preflight inaction" }, "8": { "name": "kill_switch", "description": "kill switch" }, - "9": { - "name": "lockdown", - "description": "lockdown" - }, - "10": { - "name": "failure_detector", - "description": "failure detector" - }, - "11": { - "name": "shutdown", - "description": "shutdown request" - }, - "12": { - "name": "unit_test", - "description": "unit tests" - }, "13": { "name": "rc_button", - "description": "RC (button)" + "description": "RC button" }, "14": { "name": "failsafe", @@ -604,6 +584,10 @@ "name": "external8", "description": "External 8" }, + "24": { + "name": "altitude_cruise", + "description": "Altitude Cruise" + }, "255": { "name": "unknown", "description": "[Unknown]" diff --git a/src/lib/gnss/CMakeLists.txt b/src/lib/gnss/CMakeLists.txt new file mode 100644 index 0000000000..a577c75b92 --- /dev/null +++ b/src/lib/gnss/CMakeLists.txt @@ -0,0 +1,40 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(gnss rtcm.cpp) + +target_include_directories(gnss PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/src/lib/gnss/rtcm.cpp b/src/lib/gnss/rtcm.cpp new file mode 100644 index 0000000000..d20b07ce8a --- /dev/null +++ b/src/lib/gnss/rtcm.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file rtcm.cpp + * + * RTCM3 protocol parsing implementation. + */ + +#include "rtcm.h" +#include + +namespace gnss +{ + +uint32_t rtcm3_crc24q(const uint8_t *data, size_t len) +{ + uint32_t crc = 0; + + for (size_t i = 0; i < len; i++) { + crc ^= static_cast(data[i]) << 16; + + for (int j = 0; j < 8; j++) { + crc <<= 1; + + if (crc & 0x1000000) { + crc ^= RTCM3_CRC24Q_POLY; + } + } + } + + return crc & 0xFFFFFF; +} + +size_t Rtcm3Parser::addData(const uint8_t *data, size_t len) +{ + size_t space_available = BUFFER_SIZE - _buffer_len; + size_t to_copy = (len < space_available) ? len : space_available; + + if (to_copy > 0) { + memcpy(&_buffer[_buffer_len], data, to_copy); + _buffer_len += to_copy; + } + + return to_copy; +} + +const uint8_t *Rtcm3Parser::getNextMessage(size_t *out_len) +{ + while (_buffer_len > 0) { + int to_drop = 0; + + // Find preamble + for (size_t i = 0; i < _buffer_len; i++) { + if (_buffer[i] == RTCM3_PREAMBLE) { + break; + } + + to_drop++; + } + + // Drop everything not being the preamble + if (to_drop > 0) { + _bytes_discarded += to_drop; + discardBytes(to_drop); + } + + // Need at least header to check length + if (_buffer_len < RTCM3_HEADER_LEN) { + return nullptr; + } + + size_t payload_len = rtcm3_payload_length(_buffer); + + if (payload_len > RTCM3_MAX_PAYLOAD_LEN) { + // Invalid length - not a valid frame, discard preamble + _bytes_discarded++; + discardBytes(1); + continue; + } + + size_t frame_len = RTCM3_HEADER_LEN + payload_len + RTCM3_CRC_LEN; + + // Check if we have the complete frame + if (_buffer_len < frame_len) { + return nullptr; + } + + uint32_t calculated_crc = rtcm3_crc24q(_buffer, RTCM3_HEADER_LEN + payload_len); + uint32_t received_crc = (static_cast(_buffer[frame_len - 3]) << 16) | + (static_cast(_buffer[frame_len - 2]) << 8) | + _buffer[frame_len - 1]; + + if (calculated_crc != received_crc) { + _crc_errors++; + discardBytes(1); + continue; + } + + *out_len = frame_len; + return _buffer; + } + + return nullptr; +} + +void Rtcm3Parser::consumeMessage(size_t len) +{ + discardBytes(len); + _messages_parsed++; + _total_frame_bytes += len; +} + +void Rtcm3Parser::discardBytes(size_t count) +{ + if (count >= _buffer_len) { + _buffer_len = 0; + + } else { + memmove(_buffer, &_buffer[count], _buffer_len - count); + _buffer_len -= count; + } +} + +} // namespace gnss diff --git a/src/lib/gnss/rtcm.h b/src/lib/gnss/rtcm.h new file mode 100644 index 0000000000..660682fdc5 --- /dev/null +++ b/src/lib/gnss/rtcm.h @@ -0,0 +1,202 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file rtcm.h + * + * RTCM3 protocol definitions and parsing utilities. + * + * RTCM3 frame structure: + * Byte 0: Preamble (0xD3) + * Byte 1-2: 6 reserved bits (0) + 10-bit payload length + * Byte 3..N: Payload (0-1023 bytes) + * Last 3: CRC-24Q checksum + * + * Total frame size: 3 (header) + payload_length + 3 (CRC) = 6 + payload_length + * Maximum frame size: 6 + 1023 = 1029 bytes + */ + +#pragma once + +#include +#include + +namespace gnss +{ + +// RTCM3 protocol constants +static constexpr uint8_t RTCM3_PREAMBLE = 0xD3; +static constexpr size_t RTCM3_HEADER_LEN = 3; // Preamble + 2 bytes reserved/length +static constexpr size_t RTCM3_CRC_LEN = 3; +static constexpr size_t RTCM3_MAX_PAYLOAD_LEN = 1023; +static constexpr size_t RTCM3_MAX_FRAME_LEN = RTCM3_HEADER_LEN + RTCM3_MAX_PAYLOAD_LEN + RTCM3_CRC_LEN; // 1029 +static constexpr uint32_t RTCM3_CRC24Q_POLY = 0x1864CFB; + +/** + * Calculate CRC-24Q checksum for RTCM3 messages. + * + * @param data Pointer to data buffer + * @param len Length of data + * @return 24-bit CRC value + */ +uint32_t rtcm3_crc24q(const uint8_t *data, size_t len); + +/** + * Extract RTCM3 message type from a frame buffer. + * The message type is the first 12 bits of the payload. + * + * @param frame Pointer to complete RTCM3 frame (starting with preamble) + * @return Message type ID (0 if frame is too short) + */ +inline uint16_t rtcm3_message_type(const uint8_t *frame) +{ + // Message type is first 12 bits of payload (bytes 3-4) + return (static_cast(frame[3]) << 4) | (frame[4] >> 4); +} + +/** + * Extract payload length from RTCM3 frame header. + * + * @param frame Pointer to at least 3 bytes of RTCM3 frame header + * @return Payload length (0-1023) + */ +inline size_t rtcm3_payload_length(const uint8_t *frame) +{ + return ((static_cast(frame[1]) & 0x03) << 8) | frame[2]; +} + +/** + * RTCM3 parser statistics. + */ +struct Rtcm3ParserStats { + uint32_t messages_parsed; ///< Messages successfully parsed and consumed + uint32_t crc_errors; ///< Messages with CRC failures + uint32_t bytes_discarded; ///< Bytes discarded while searching for valid frames + uint32_t total_frame_bytes; ///< Total bytes in successfully parsed frames +}; + +/** + * RTCM3 frame parser for detecting message boundaries in a byte stream. + * + * This parser is designed for scenarios where RTCM data arrives in arbitrary + * chunks (e.g., from uORB messages, serial ports) and needs to be reassembled + * into complete, CRC-validated RTCM messages. + * + * Usage: + * Rtcm3Parser parser; + * parser.addData(chunk1, len1); + * parser.addData(chunk2, len2); + * + * size_t frame_len; + * const uint8_t *frame; + * while ((frame = parser.getNextMessage(&frame_len)) != nullptr) { + * // Process complete RTCM message + * uint16_t msg_type = rtcm3_message_type(frame); + * // ... use the frame ... + * parser.consumeMessage(frame_len); + * } + */ +class Rtcm3Parser +{ +public: + // Buffer size: enough for 2 max-size messages to handle overlap + static constexpr size_t BUFFER_SIZE = RTCM3_MAX_FRAME_LEN * 2; + + Rtcm3Parser() = default; + + /** + * Add data to the parser buffer. + * + * @param data Pointer to incoming data + * @param len Number of bytes to add + * @return Number of bytes actually added (may be less if buffer is full) + */ + size_t addData(const uint8_t *data, size_t len); + + /** + * Get a pointer to the next complete RTCM3 message without consuming it. + * + * Returns a pointer directly into the parser's internal buffer where the + * valid frame starts. Invalid bytes at the buffer start are discarded + * during the search. The returned pointer remains valid until the next + * call to addData() or consumeMessage(). + * + * After processing the message, call consumeMessage() to remove it from + * the buffer. + * + * @param out_len Set to the total frame length + * @return Pointer to the frame in internal buffer, or nullptr + * if no complete valid frame is available + */ + const uint8_t *getNextMessage(size_t *out_len); + + /** + * Consume (remove) the next message from the buffer. + * + * Call this after successfully processing a message obtained via + * getNextMessage(). The length should match what getNextMessage returned. + * + * @param len Number of bytes to remove from the buffer + */ + void consumeMessage(size_t len); + + /** + * Get the number of bytes currently buffered. + */ + size_t bufferedBytes() const { return _buffer_len; } + + /** + * Get parser statistics. + */ + Rtcm3ParserStats getStats() const + { + return {_messages_parsed, _crc_errors, _bytes_discarded, _total_frame_bytes}; + } + +private: + /** + * Remove bytes from the beginning of the buffer. + */ + void discardBytes(size_t count); + + uint8_t _buffer[BUFFER_SIZE] {}; + size_t _buffer_len {0}; + + // Statistics + uint32_t _messages_parsed {0}; + uint32_t _crc_errors {0}; + uint32_t _bytes_discarded {0}; + uint32_t _total_frame_bytes {0}; +}; + +} // namespace gnss diff --git a/src/lib/gnss/test/CMakeLists.txt b/src/lib/gnss/test/CMakeLists.txt new file mode 100644 index 0000000000..e693e1f015 --- /dev/null +++ b/src/lib/gnss/test/CMakeLists.txt @@ -0,0 +1,37 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_unit_gtest(SRC RtcmCrcTest.cpp LINKLIBS gnss) +px4_add_unit_gtest(SRC RtcmParserTest.cpp LINKLIBS gnss) +px4_add_unit_gtest(SRC RtcmBustedSenderTest.cpp LINKLIBS gnss) +px4_add_unit_gtest(SRC RtcmStressTest.cpp LINKLIBS gnss) diff --git a/src/lib/gnss/test/README.md b/src/lib/gnss/test/README.md new file mode 100644 index 0000000000..ff7da7a73e --- /dev/null +++ b/src/lib/gnss/test/README.md @@ -0,0 +1,57 @@ +# RTCM Library Tests + +Unit tests for the RTCM3 parser library. + +## Running Tests + +```bash +# Build and test +make tests TESTFILTER=Rtcm +``` + +## Test Descriptions + +### RtcmCrcTest.cpp (2 tests) + +| Test | Description | +|------|-------------| +| `CRC24Q_EmptyData` | Verifies CRC function handles empty/null input without crashing | +| `CRC24Q_KnownValue` | Verifies CRC produces a valid 24-bit value | + +### RtcmParserTest.cpp (11 tests) + +| Test | Description | +|------|-------------| +| `PayloadLength_MasksReservedBits` | Verifies reserved bits are ignored when extracting length | +| `MessageType_Extraction` | Verifies 12-bit message type is correctly extracted from payload | +| `SingleMinimalFrame` | Parses smallest valid frame (2-byte payload) | +| `SingleMaximalFrame` | Parses largest valid frame (1023-byte payload) | +| `MultipleFramesInSequence` | Parses 3 back-to-back valid frames | +| `FrameArrivesInChunks` | Parses a frame arriving one byte at a time | +| `GarbageBeforeValidFrame` | Skips 50 bytes of garbage, then parses valid frame | +| `ValidFrameBadFrameValid` | Verifies recovery after CRC error between valid frames | +| `BufferOverflowProtection` | Verifies buffer rejects data beyond capacity | +| `EmptyPayloadFrame` | Parses frame with 0-byte payload | +| `GetNextOnEmptyBuffer` | Verifies empty buffer returns nullptr | + +### RtcmBustedSenderTest.cpp (5 tests) + +Tests for handling completely invalid data streams. + +| Test | Description | +|------|-------------| +| `BustedSender_AllZeros` | 1000 bytes of 0x00 - all discarded | +| `BustedSender_AllPreambles` | 500 bytes of 0xD3 - parser waits for incomplete frame | +| `BustedSender_RandomNoise` | 500 random bytes - most discarded or cause CRC errors | +| `BustedSender_ValidHeaderBadCrc` | Well-formed frame with wrong CRC | +| `BustedSender_RepeatedBadCrcFrames` | 100 consecutive bad-CRC frames | + +### RtcmStressTest.cpp (3 tests) + +Performance and stress tests. + +| Test | Description | +|------|-------------| +| `Stress_ManySmallValidFrames` | 1000 valid frames - verifies no data loss | +| `Stress_LongGarbageStreamThenValid` | 10KB garbage then 1 valid frame - exercises `discardBytes()` | +| `Stress_InterleavedGarbageAndValid` | 100 cycles of garbage + valid frame - simulates flaky sender | diff --git a/src/lib/gnss/test/RtcmBustedSenderTest.cpp b/src/lib/gnss/test/RtcmBustedSenderTest.cpp new file mode 100644 index 0000000000..edb7ad5463 --- /dev/null +++ b/src/lib/gnss/test/RtcmBustedSenderTest.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RtcmTestCommon.hpp" + +TEST_F(RtcmTest, BustedSender_AllZeros) +{ + std::vector garbage(1000, 0x00); + parser.addData(garbage.data(), garbage.size()); + + size_t len; + EXPECT_EQ(parser.getNextMessage(&len), nullptr); + EXPECT_EQ(parser.getStats().bytes_discarded, 1000u); + EXPECT_EQ(parser.bufferedBytes(), 0u); +} + +TEST_F(RtcmTest, BustedSender_AllPreambles) +{ + // All preamble bytes (0xD3). The parser sees each 0xD3 as a potential frame start. + // Length extracted from 0xD3,0xD3 is ((0x03)<<8)|0xD3 = 979 bytes. + // Parser waits for full frame which never comes. + std::vector preambles(500, RTCM3_PREAMBLE); + parser.addData(preambles.data(), preambles.size()); + + size_t len; + // Parser should be stuck waiting for more data (incomplete frame) + EXPECT_EQ(parser.getNextMessage(&len), nullptr); + // Buffer retains data waiting for frame completion + EXPECT_GT(parser.bufferedBytes(), 0u); +} + +TEST_F(RtcmTest, BustedSender_RandomNoise) +{ + std::mt19937 rng(12345); + uint8_t noise[500]; + + for (size_t i = 0; i < sizeof(noise); i++) { + noise[i] = rng() & 0xFF; + } + + parser.addData(noise, sizeof(noise)); + + size_t len; + + // Consume any messages that might accidentally form (unlikely but possible) + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + } + + // Most data should be discarded + auto stats = parser.getStats(); + EXPECT_GT(stats.bytes_discarded + stats.crc_errors, 0u); +} + +TEST_F(RtcmTest, BustedSender_ValidHeaderBadCrc) +{ + // Frame with valid header but bad CRC + std::vector frame = { + RTCM3_PREAMBLE, 0x00, 0x04, // Header: 4 byte payload + 0x01, 0x02, 0x03, 0x04, // Payload + 0xDE, 0xAD, 0xBE // Bad CRC + }; + + parser.addData(frame.data(), frame.size()); + + size_t len; + EXPECT_EQ(parser.getNextMessage(&len), nullptr); + EXPECT_EQ(parser.getStats().crc_errors, 1u); +} + +TEST_F(RtcmTest, BustedSender_RepeatedBadCrcFrames) +{ + for (int i = 0; i < 100; i++) { + auto bad = buildBadCrcFrame({static_cast(i), 0x00}); + parser.addData(bad.data(), bad.size()); + } + + size_t len; + + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + } + + auto stats = parser.getStats(); + EXPECT_EQ(stats.messages_parsed, 0u); + // At least 100 CRC errors (may be more due to re-scanning after failures) + EXPECT_GE(stats.crc_errors, 100u); +} diff --git a/src/lib/gnss/test/RtcmCrcTest.cpp b/src/lib/gnss/test/RtcmCrcTest.cpp new file mode 100644 index 0000000000..e4a2b9eb82 --- /dev/null +++ b/src/lib/gnss/test/RtcmCrcTest.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RtcmTestCommon.hpp" + +TEST_F(RtcmTest, CRC24Q_EmptyData) +{ + uint32_t crc = rtcm3_crc24q(nullptr, 0); + EXPECT_EQ(crc, 0u); +} + +TEST_F(RtcmTest, CRC24Q_KnownValue) +{ + // Test with known RTCM data + uint8_t data[] = {0xD3, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}; + uint32_t crc = rtcm3_crc24q(data, sizeof(data)); + // CRC should be a 24-bit value + EXPECT_EQ(crc & 0xFF000000, 0u); + EXPECT_NE(crc, 0u); +} diff --git a/src/lib/gnss/test/RtcmParserTest.cpp b/src/lib/gnss/test/RtcmParserTest.cpp new file mode 100644 index 0000000000..6652412c83 --- /dev/null +++ b/src/lib/gnss/test/RtcmParserTest.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file RtcmParserTest.cpp + * + * Tests for RTCM3 parser with valid and partially valid input. + * Consolidates: GoodSender, PartialSender, Helper, Buffer, Stats, EdgeCase tests. + */ + +#include "RtcmTestCommon.hpp" + +// ============================================================================= +// Helper function tests +// ============================================================================= + +TEST_F(RtcmTest, PayloadLength_MasksReservedBits) +{ + // Reserved bits set to 1, length should still be extracted correctly + uint8_t frame[] = {RTCM3_PREAMBLE, 0xFF, 0xFF}; // Reserved=0x3F, Length=1023 + EXPECT_EQ(rtcm3_payload_length(frame), 1023u); +} + +TEST_F(RtcmTest, MessageType_Extraction) +{ + auto frame = buildValidFrame(1005, {}); + EXPECT_EQ(rtcm3_message_type(frame.data()), 1005u); +} + +// ============================================================================= +// Good sender tests - valid frames, happy path +// ============================================================================= + +TEST_F(RtcmTest, SingleMinimalFrame) +{ + auto frame = buildRawFrame({0x00, 0x00}); + parser.addData(frame.data(), frame.size()); + + size_t len = 0; + const uint8_t *msg = parser.getNextMessage(&len); + + ASSERT_NE(msg, nullptr); + EXPECT_EQ(len, frame.size()); + + parser.consumeMessage(len); + auto stats = parser.getStats(); + EXPECT_EQ(stats.messages_parsed, 1u); + EXPECT_EQ(stats.crc_errors, 0u); +} + +TEST_F(RtcmTest, SingleMaximalFrame) +{ + std::vector payload(RTCM3_MAX_PAYLOAD_LEN, 0xAA); + auto frame = buildRawFrame(payload); + parser.addData(frame.data(), frame.size()); + + size_t len = 0; + const uint8_t *msg = parser.getNextMessage(&len); + + ASSERT_NE(msg, nullptr); + EXPECT_EQ(len, RTCM3_MAX_FRAME_LEN); +} + +TEST_F(RtcmTest, MultipleFramesInSequence) +{ + auto frame1 = buildValidFrame(1005, {0x01, 0x02, 0x03}); + auto frame2 = buildValidFrame(1077, {0x04, 0x05, 0x06, 0x07}); + auto frame3 = buildValidFrame(1087, {0x08}); + + parser.addData(frame1.data(), frame1.size()); + parser.addData(frame2.data(), frame2.size()); + parser.addData(frame3.data(), frame3.size()); + + size_t len; + int count = 0; + + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + count++; + } + + EXPECT_EQ(count, 3); +} + +TEST_F(RtcmTest, FrameArrivesInChunks) +{ + auto frame = buildValidFrame(1005, {0x01, 0x02, 0x03, 0x04, 0x05}); + + // Feed one byte at a time + for (size_t i = 0; i < frame.size() - 1; i++) { + parser.addData(&frame[i], 1); + size_t len; + EXPECT_EQ(parser.getNextMessage(&len), nullptr); + } + + parser.addData(&frame[frame.size() - 1], 1); + + size_t len; + ASSERT_NE(parser.getNextMessage(&len), nullptr); + EXPECT_EQ(len, frame.size()); +} + +// ============================================================================= +// Partially good sender tests - mix of valid and invalid +// ============================================================================= + +TEST_F(RtcmTest, GarbageBeforeValidFrame) +{ + std::vector data; + + // 50 bytes of garbage + for (int i = 0; i < 50; i++) { + data.push_back(0x00 + i); + } + + auto frame = buildValidFrame(1005, {0x01, 0x02}); + data.insert(data.end(), frame.begin(), frame.end()); + + parser.addData(data.data(), data.size()); + + size_t len; + const uint8_t *msg = parser.getNextMessage(&len); + ASSERT_NE(msg, nullptr); + EXPECT_EQ(rtcm3_message_type(msg), 1005u); + + parser.consumeMessage(len); + EXPECT_EQ(parser.getStats().bytes_discarded, 50u); +} + +TEST_F(RtcmTest, ValidFrameBadFrameValid) +{ + auto frame1 = buildValidFrame(1005, {0x01}); + auto bad_frame = buildBadCrcFrame({0x02, 0x03}); + auto frame2 = buildValidFrame(1077, {0x04}); + + parser.addData(frame1.data(), frame1.size()); + parser.addData(bad_frame.data(), bad_frame.size()); + parser.addData(frame2.data(), frame2.size()); + + size_t len; + int valid_count = 0; + + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + valid_count++; + } + + EXPECT_EQ(valid_count, 2); + EXPECT_EQ(parser.getStats().crc_errors, 1u); +} + +// ============================================================================= +// Buffer and edge case tests +// ============================================================================= + +TEST_F(RtcmTest, BufferOverflowProtection) +{ + std::vector large_data(Rtcm3Parser::BUFFER_SIZE + 1000, 0xAA); + size_t added = parser.addData(large_data.data(), large_data.size()); + + EXPECT_EQ(added, Rtcm3Parser::BUFFER_SIZE); +} + +TEST_F(RtcmTest, EmptyPayloadFrame) +{ + auto frame = buildRawFrame({}); + parser.addData(frame.data(), frame.size()); + + size_t len; + ASSERT_NE(parser.getNextMessage(&len), nullptr); + EXPECT_EQ(len, RTCM3_HEADER_LEN + RTCM3_CRC_LEN); +} + +TEST_F(RtcmTest, GetNextOnEmptyBuffer) +{ + size_t len; + EXPECT_EQ(parser.getNextMessage(&len), nullptr); +} diff --git a/src/lib/gnss/test/RtcmStressTest.cpp b/src/lib/gnss/test/RtcmStressTest.cpp new file mode 100644 index 0000000000..0b115c8612 --- /dev/null +++ b/src/lib/gnss/test/RtcmStressTest.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "RtcmTestCommon.hpp" + +TEST_F(RtcmTest, Stress_ManySmallValidFrames) +{ + // Simulate a good sender sending many small messages + // Process as we go to avoid buffer overflow + const int num_frames = 1000; + int count = 0; + + for (int i = 0; i < num_frames; i++) { + auto frame = buildValidFrame(1005 + (i % 100), {static_cast(i & 0xFF)}); + parser.addData(frame.data(), frame.size()); + + // Consume available messages after each add + size_t len; + + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + count++; + } + } + + EXPECT_EQ(count, num_frames); + auto stats = parser.getStats(); + EXPECT_EQ(stats.messages_parsed, static_cast(num_frames)); + EXPECT_EQ(stats.bytes_discarded, 0u); + EXPECT_EQ(stats.crc_errors, 0u); +} + +TEST_F(RtcmTest, Stress_LongGarbageStreamThenValid) +{ + // This tests the pathological case Alex mentioned: lots of invalid data + // causing many memmove operations during preamble search + const size_t garbage_size = 10000; + std::vector garbage(garbage_size); + std::mt19937 rng(99); + + for (auto &byte : garbage) { + // Avoid preamble to ensure maximum discards + byte = (rng() % 0xD2) + 1; // 0x01 to 0xD2, never 0xD3 + } + + // Add in chunks to simulate streaming + size_t offset = 0; + + while (offset < garbage.size()) { + size_t chunk = std::min(256, garbage.size() - offset); + parser.addData(&garbage[offset], chunk); + + // Try to parse (forces discarding) + size_t len; + parser.getNextMessage(&len); + offset += chunk; + } + + // Now add a valid frame + auto valid = buildValidFrame(1005, {0x01, 0x02, 0x03}); + parser.addData(valid.data(), valid.size()); + + size_t len; + const uint8_t *msg = parser.getNextMessage(&len); + ASSERT_NE(msg, nullptr); + + parser.consumeMessage(len); + auto stats = parser.getStats(); + EXPECT_EQ(stats.messages_parsed, 1u); + EXPECT_EQ(stats.bytes_discarded, garbage_size); +} + +TEST_F(RtcmTest, Stress_InterleavedGarbageAndValid) +{ + // Simulate a flaky sender that mixes garbage with valid frames + const int num_valid = 100; + int parsed = 0; + + for (int i = 0; i < num_valid; i++) { + // Add some garbage (variable amount) + std::vector garbage(10 + (i % 50), 0xAA); + parser.addData(garbage.data(), garbage.size()); + + // Add valid frame + auto frame = buildValidFrame(1005, {static_cast(i)}); + parser.addData(frame.data(), frame.size()); + + // Parse what we can + size_t len; + + while (parser.getNextMessage(&len) != nullptr) { + parser.consumeMessage(len); + parsed++; + } + } + + EXPECT_EQ(parsed, num_valid); +} diff --git a/src/lib/gnss/test/RtcmTestCommon.hpp b/src/lib/gnss/test/RtcmTestCommon.hpp new file mode 100644 index 0000000000..f2012d353e --- /dev/null +++ b/src/lib/gnss/test/RtcmTestCommon.hpp @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include "rtcm.h" +#include +#include +#include + +using namespace gnss; + +class RtcmTest : public ::testing::Test +{ +protected: + Rtcm3Parser parser; + + // Helper to build a valid RTCM3 frame with proper CRC + std::vector buildValidFrame(uint16_t msg_type, const std::vector &payload_data) + { + // Payload = 12-bit message type + rest of payload_data + // Message type is stored in first 12 bits of payload + std::vector payload; + payload.push_back((msg_type >> 4) & 0xFF); + payload.push_back(((msg_type & 0x0F) << 4) | (payload_data.empty() ? 0 : (payload_data[0] >> 4))); + + for (size_t i = 0; i < payload_data.size(); i++) { + uint8_t current = (payload_data[i] << 4) & 0xF0; + + if (i + 1 < payload_data.size()) { + current |= (payload_data[i + 1] >> 4) & 0x0F; + } + + payload.push_back(current); + } + + return buildRawFrame(payload); + } + + // Helper to build a frame with raw payload bytes (no message type encoding) + std::vector buildRawFrame(const std::vector &payload) + { + std::vector frame; + size_t payload_len = payload.size(); + + // Header: preamble + length + frame.push_back(RTCM3_PREAMBLE); + frame.push_back((payload_len >> 8) & 0x03); // Upper 2 bits of length (reserved bits = 0) + frame.push_back(payload_len & 0xFF); // Lower 8 bits of length + + // Payload + frame.insert(frame.end(), payload.begin(), payload.end()); + + // CRC + uint32_t crc = rtcm3_crc24q(frame.data(), frame.size()); + frame.push_back((crc >> 16) & 0xFF); + frame.push_back((crc >> 8) & 0xFF); + frame.push_back(crc & 0xFF); + + return frame; + } + + // Helper to build a frame with bad CRC + std::vector buildBadCrcFrame(const std::vector &payload) + { + auto frame = buildRawFrame(payload); + // Corrupt the CRC + frame[frame.size() - 1] ^= 0xFF; + return frame; + } +}; diff --git a/src/lib/hysteresis/hysteresis.cpp b/src/lib/hysteresis/hysteresis.cpp index 22593b2d6e..3cadc7b7ea 100644 --- a/src/lib/hysteresis/hysteresis.cpp +++ b/src/lib/hysteresis/hysteresis.cpp @@ -42,8 +42,12 @@ namespace systemlib { -void -Hysteresis::set_hysteresis_time_from(const bool from_state, const hrt_abstime new_hysteresis_time_us) +Hysteresis::Hysteresis(bool initial_state) +{ + _state = _requested_state = initial_state; +} + +void Hysteresis::set_hysteresis_time_from(const bool from_state, const hrt_abstime new_hysteresis_time_us) { if (from_state) { _time_from_true_us = new_hysteresis_time_us; @@ -53,8 +57,7 @@ Hysteresis::set_hysteresis_time_from(const bool from_state, const hrt_abstime ne } } -void -Hysteresis::set_state_and_update(const bool new_state, const hrt_abstime &now_us) +void Hysteresis::set_state_and_update(const bool new_state, const hrt_abstime &now_us) { if (new_state != _state) { if (new_state != _requested_state) { @@ -69,8 +72,7 @@ Hysteresis::set_state_and_update(const bool new_state, const hrt_abstime &now_us update(now_us); } -void -Hysteresis::update(const hrt_abstime &now_us) +void Hysteresis::update(const hrt_abstime &now_us) { if (_requested_state != _state) { diff --git a/src/lib/hysteresis/hysteresis.h b/src/lib/hysteresis/hysteresis.h index 9c16ce4933..850d204825 100644 --- a/src/lib/hysteresis/hysteresis.h +++ b/src/lib/hysteresis/hysteresis.h @@ -49,12 +49,8 @@ namespace systemlib class Hysteresis { public: - explicit Hysteresis(bool init_state) : - _state(init_state), - _requested_state(init_state) - {} - Hysteresis() = delete; // no default constructor - + Hysteresis() = default; + explicit Hysteresis(bool initial_state); ~Hysteresis() = default; bool get_state() const { return _state; } @@ -67,13 +63,13 @@ public: private: - hrt_abstime _last_time_to_change_state{0}; + hrt_abstime _last_time_to_change_state = 0; - hrt_abstime _time_from_true_us{0}; - hrt_abstime _time_from_false_us{0}; + hrt_abstime _time_from_true_us = 0; + hrt_abstime _time_from_false_us = 0; - bool _state; - bool _requested_state; + bool _state = false; + bool _requested_state = false; }; } // namespace systemlib diff --git a/src/lib/matrix/test/test_data.py b/src/lib/matrix/test/test_data.py index 43bc03e324..95d18a3fb8 100644 --- a/src/lib/matrix/test/test_data.py +++ b/src/lib/matrix/test/test_data.py @@ -1,7 +1,9 @@ -from __future__ import print_function +#!/usr/bin/env python3 + from pylab import * from pprint import pprint import scipy.linalg +import sys # test cases, derived from doc/nasa_rotation_def.pdf @@ -47,7 +49,7 @@ def quat_prod(q, r): def dcm_to_euler(dcm): return array([ arctan(dcm[2,1]/ dcm[2,2]), - arctan(-dcm[2,0]/ std::sqrt(1 - dcm[2,0]**2)), + arctan(-dcm[2,0]/ (1 - dcm[2,0]**2)**0.5), arctan(dcm[1,0]/ dcm[0,0]), ]) @@ -75,6 +77,7 @@ psi = 0.3 print('euler', phi, theta, psi) q = euler_to_quat(phi, theta, psi) +FLT_EPSILON = sys.float_info.epsilon assert(abs(norm(q) - 1) < FLT_EPSILON) assert(abs(norm(q) - 1) < FLT_EPSILON) assert(norm(array(quat_to_euler(q)) - array([phi, theta, psi])) < FLT_EPSILON) diff --git a/src/lib/mixer_module/mixer_module.cpp b/src/lib/mixer_module/mixer_module.cpp index b038268d84..eb67188018 100644 --- a/src/lib/mixer_module/mixer_module.cpp +++ b/src/lib/mixer_module/mixer_module.cpp @@ -120,6 +120,8 @@ void MixingOutput::initParamHandles(const uint8_t instance_start) _param_handles[i].disarmed = param_find(param_name); snprintf(param_name, sizeof(param_name), "%s_%s%d", _param_prefix, "MIN", i + instance_start); _param_handles[i].min = param_find(param_name); + snprintf(param_name, sizeof(param_name), "%s_%s%d", _param_prefix, "CENT", i + instance_start); + _param_handles[i].center = param_find(param_name); snprintf(param_name, sizeof(param_name), "%s_%s%d", _param_prefix, "MAX", i + instance_start); _param_handles[i].max = param_find(param_name); snprintf(param_name, sizeof(param_name), "%s_%s%d", _param_prefix, "FAIL", i + instance_start); @@ -142,9 +144,9 @@ void MixingOutput::printStatus() const PX4_INFO_RAW("Channel Configuration:\n"); for (unsigned i = 0; i < _max_num_outputs; i++) { - PX4_INFO_RAW("Channel %i: func: %3i, value: %i, failsafe: %d, disarmed: %d, min: %d, max: %d\n", i, + PX4_INFO_RAW("Channel %i: func: %3i, value: %i, failsafe: %d, disarmed: %d, min: %d, max: %d, center: %d\n", i, (int)_function_assignment[i], _current_output_value[i], - actualFailsafeValue(i), _disarmed_value[i], _min_value[i], _max_value[i]); + actualFailsafeValue(i), _disarmed_value[i], _min_value[i], _max_value[i], _center_value[i]); } } @@ -173,6 +175,10 @@ void MixingOutput::updateParams() _min_value[i] = val; } + if (_param_handles[i].center != PARAM_INVALID && param_get(_param_handles[i].center, &val) == 0) { + _center_value[i] = val; + } + if (_param_handles[i].max != PARAM_INVALID && param_get(_param_handles[i].max, &val) == 0) { _max_value[i] = val; } @@ -183,6 +189,7 @@ void MixingOutput::updateParams() _max_value[i] = tmp; } + if (_param_handles[i].failsafe != PARAM_INVALID && param_get(_param_handles[i].failsafe, &val) == 0) { _failsafe_value[i] = val; } @@ -372,6 +379,14 @@ void MixingOutput::setAllMinValues(uint16_t value) } } +void MixingOutput::setAllCenterValues(uint16_t value) +{ + for (unsigned i = 0; i < MAX_ACTUATORS; i++) { + _param_handles[i].center = PARAM_INVALID; + _center_value[i] = value; + } +} + void MixingOutput::setAllMaxValues(uint16_t value) { for (unsigned i = 0; i < MAX_ACTUATORS; i++) { @@ -528,10 +543,36 @@ uint16_t MixingOutput::output_limit_calc_single(int i, float value) const value = -1.f * value; } - const float output = math::interpolate(value, -1.f, 1.f, - static_cast(_min_value[i]), static_cast(_max_value[i])); + float output = _disarmed_value[i]; + + if (((_function_assignment[i] >= OutputFunction::Servo1 + && _function_assignment[i] <= OutputFunction::ServoMax) || _function_assignment[i] == OutputFunction::Landing_Gear_Wheel + || (_function_assignment[i] >= OutputFunction::Gimbal_Roll + && _function_assignment[i] <= OutputFunction::Gimbal_Yaw)) + && _param_handles[i].center != PARAM_INVALID + && _center_value[i] >= 800 + && _center_value[i] <= 2200) { + + /* bi-linear interpolation */ + if (value < 0.0f) { + output = math::interpolate(value, -1.f, 0.0f, + static_cast(_min_value[i]), static_cast(_center_value[i])); + + } else { + output = math::interpolate(value, 0.0f, 1.0f, + static_cast(_center_value[i]), static_cast(_max_value[i])); + } + + } + + // Everything except servos, or if center is not set + else { + output = math::interpolate(value, -1.f, 1.f, + static_cast(_min_value[i]), static_cast(_max_value[i])); + } return math::constrain(lroundf(output), 0L, static_cast(UINT16_MAX)); + } void diff --git a/src/lib/mixer_module/mixer_module.hpp b/src/lib/mixer_module/mixer_module.hpp index 7ed8ed8a73..3e4cec0d51 100644 --- a/src/lib/mixer_module/mixer_module.hpp +++ b/src/lib/mixer_module/mixer_module.hpp @@ -163,20 +163,24 @@ public: void setMaxTopicUpdateRate(unsigned max_topic_update_interval_us); const actuator_armed_s &armed() const { return _armed; } + bool isActuatorTestRunning() const { return _actuator_test.inTestMode(); } void setAllFailsafeValues(uint16_t value); void setAllDisarmedValues(uint16_t value); void setAllMinValues(uint16_t value); + void setAllCenterValues(uint16_t value); void setAllMaxValues(uint16_t value); /** Disarmed values: disarmedValue < minValue needs to hold */ uint16_t &disarmedValue(int index) { return _disarmed_value[index]; } uint16_t &minValue(int index) { return _min_value[index]; } + uint16_t ¢erValue(int index) { return _center_value[index]; } uint16_t &maxValue(int index) { return _max_value[index]; } param_t functionParamHandle(int index) const { return _param_handles[index].function; } param_t disarmedParamHandle(int index) const { return _param_handles[index].disarmed; } param_t minParamHandle(int index) const { return _param_handles[index].min; } + param_t centerParamHandle(int index) const { return _param_handles[index].center; } param_t maxParamHandle(int index) const { return _param_handles[index].max; } /** @@ -228,6 +232,7 @@ private: param_t function{PARAM_INVALID}; param_t disarmed{PARAM_INVALID}; param_t min{PARAM_INVALID}; + param_t center{PARAM_INVALID}; param_t max{PARAM_INVALID}; param_t failsafe{PARAM_INVALID}; }; @@ -240,6 +245,7 @@ private: uint16_t _failsafe_value[MAX_ACTUATORS] {}; uint16_t _disarmed_value[MAX_ACTUATORS] {}; uint16_t _min_value[MAX_ACTUATORS] {}; + uint16_t _center_value[MAX_ACTUATORS] {}; uint16_t _max_value[MAX_ACTUATORS] {}; uint16_t _current_output_value[MAX_ACTUATORS] {}; ///< current output values (reordered) uint16_t _reverse_output_mask{0}; ///< reverses the interval [min, max] -> [max, min], NOT motor direction diff --git a/src/lib/mixer_module/mixer_module_tests.cpp b/src/lib/mixer_module/mixer_module_tests.cpp index 7db9a8c513..7f3a6feede 100644 --- a/src/lib/mixer_module/mixer_module_tests.cpp +++ b/src/lib/mixer_module/mixer_module_tests.cpp @@ -54,6 +54,7 @@ static constexpr int MAX_NUM_OUTPUTS = 8; static constexpr int DISARMED_VALUE = 900; static constexpr int FAILSAFE_VALUE = 800; static constexpr int MIN_VALUE = 1000; +static constexpr int CENTER_VALUE = 1500; static constexpr int MAX_VALUE = 2000; class MixerModuleTest : public ::testing::Test @@ -188,6 +189,7 @@ TEST_F(MixerModuleTest, basic) mixing_output.setAllDisarmedValues(DISARMED_VALUE); mixing_output.setAllFailsafeValues(FAILSAFE_VALUE); mixing_output.setAllMinValues(MIN_VALUE); + mixing_output.setAllCenterValues(CENTER_VALUE); mixing_output.setAllMaxValues(MAX_VALUE); EXPECT_EQ(test_module.num_updates, 0); @@ -281,6 +283,7 @@ TEST_F(MixerModuleTest, arming) mixing_output.setAllDisarmedValues(DISARMED_VALUE); mixing_output.setAllFailsafeValues(FAILSAFE_VALUE); mixing_output.setAllMinValues(MIN_VALUE); + mixing_output.setAllCenterValues(CENTER_VALUE); mixing_output.setAllMaxValues(MAX_VALUE); test_module.sendMotors({1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f}); @@ -488,6 +491,7 @@ TEST_F(MixerModuleTest, OutputLimitCalcSingle) mixing_output.setAllMinValues(MIN_VALUE); // default range [1000,2000] mixing_output.setAllMaxValues(MAX_VALUE); + mixing_output.setAllCenterValues(CENTER_VALUE); // Set center to middle value EXPECT_EQ(mixing_output.output_limit_calc_single(0, -1.f), 1000); // In range EXPECT_EQ(mixing_output.output_limit_calc_single(0, -.5f), 1250); EXPECT_EQ(mixing_output.output_limit_calc_single(0, 0.f), 1500); @@ -503,6 +507,7 @@ TEST_F(MixerModuleTest, OutputLimitCalcSingle) mixing_output.setAllMinValues(0); // lower range [0,20] mixing_output.setAllMaxValues(20); + mixing_output.setAllCenterValues(10); // Set center to middle value EXPECT_EQ(mixing_output.output_limit_calc_single(0, -1.f), 0); // In range EXPECT_EQ(mixing_output.output_limit_calc_single(0, -.5f), 5); EXPECT_EQ(mixing_output.output_limit_calc_single(0, 0.f), 10); @@ -518,6 +523,7 @@ TEST_F(MixerModuleTest, OutputLimitCalcSingle) mixing_output.setAllMinValues(20); // inverted range [20,0] mixing_output.setAllMaxValues(0); + mixing_output.setAllCenterValues(10); // Set center to middle value EXPECT_EQ(mixing_output.output_limit_calc_single(0, -1.f), 20); // In range EXPECT_EQ(mixing_output.output_limit_calc_single(0, -.5f), 15); EXPECT_EQ(mixing_output.output_limit_calc_single(0, 0.f), 10); diff --git a/src/lib/modes/ui.hpp b/src/lib/modes/ui.hpp index 9e4156ae00..fe2e5a9689 100644 --- a/src/lib/modes/ui.hpp +++ b/src/lib/modes/ui.hpp @@ -47,6 +47,7 @@ static inline uint32_t getValidNavStates() { return (1u << vehicle_status_s::NAVIGATION_STATE_MANUAL) | (1u << vehicle_status_s::NAVIGATION_STATE_ALTCTL) | + (1u << vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE) | (1u << vehicle_status_s::NAVIGATION_STATE_POSCTL) | (1u << vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION) | (1u << vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER) | @@ -75,7 +76,7 @@ const char *const nav_state_names[vehicle_status_s::NAVIGATION_STATE_MAX] = { "Return", "Position Slow", "7: unallocated", - "8: unallocated", + "Altitude Cruise", "9: unallocated", "Acro", "11: UNUSED", diff --git a/src/lib/motion_planning/HeadingSmoothing.cpp b/src/lib/motion_planning/HeadingSmoothing.cpp index b8094dff08..e28c4d87ce 100644 --- a/src/lib/motion_planning/HeadingSmoothing.cpp +++ b/src/lib/motion_planning/HeadingSmoothing.cpp @@ -42,7 +42,10 @@ void HeadingSmoothing::reset(const float heading, const float heading_rate) { const float wrapped_heading = matrix::wrap_pi(heading); _velocity_smoothing.setCurrentVelocity(wrapped_heading); - _velocity_smoothing.setCurrentAcceleration(heading_rate); + + if (PX4_ISFINITE(heading_rate)) { + _velocity_smoothing.setCurrentAcceleration(heading_rate); + } } void HeadingSmoothing::update(const float heading_setpoint, const float time_elapsed) diff --git a/src/lib/motion_planning/HeadingSmoothing.hpp b/src/lib/motion_planning/HeadingSmoothing.hpp index 5fdb4dde36..0aeccdbac2 100644 --- a/src/lib/motion_planning/HeadingSmoothing.hpp +++ b/src/lib/motion_planning/HeadingSmoothing.hpp @@ -69,7 +69,7 @@ public: * @param heading [rad] [-pi,pi] * @param heading_rate [rad/s] */ - void reset(const float heading, const float heading_rate); + void reset(const float heading, const float heading_rate = NAN); /** * @brief updates the heading setpoint, re-calculates trajectory, and takes an integration step diff --git a/src/lib/parameters/CMakeLists.txt b/src/lib/parameters/CMakeLists.txt index 81b609080a..cfa118b2dd 100644 --- a/src/lib/parameters/CMakeLists.txt +++ b/src/lib/parameters/CMakeLists.txt @@ -123,7 +123,6 @@ add_custom_command(OUTPUT ${parameters_xml} ${parameters_json} ${parameters_json --xml ${parameters_xml} --json ${parameters_json} --compress - --inject-xml ${CMAKE_CURRENT_SOURCE_DIR}/parameters_injected.xml --overrides ${PARAM_DEFAULT_OVERRIDES} --board ${PX4_BOARD} #--verbose @@ -136,13 +135,11 @@ add_custom_command(OUTPUT ${parameters_xml} ${parameters_json} ${parameters_json ${param_src_files} ${generated_serial_params_file} ${generated_module_params_file} - parameters_injected.xml px4params/srcparser.py px4params/srcscanner.py px4params/jsonout.py px4params/xmlout.py px_process_params.py - parameters_injected.xml COMMENT "Generating parameters.xml" ) add_custom_target(parameters_xml DEPENDS ${parameters_xml}) @@ -161,7 +158,7 @@ add_custom_target(parameters_header DEPENDS px4_parameters.hpp) set(SRCS) list(APPEND SRCS - parameters.cpp + parameters.cpp atomic_transaction.cpp autosave.cpp ) diff --git a/src/lib/parameters/param_translation.cpp b/src/lib/parameters/param_translation.cpp index 3a8d63bbf6..837a2d68ba 100644 --- a/src/lib/parameters/param_translation.cpp +++ b/src/lib/parameters/param_translation.cpp @@ -163,5 +163,19 @@ param_modify_on_import_ret param_modify_on_import(bson_node_t node) } } + // 2025-11-17: translate MNT_RANGE_PITCH to MNT_MAX_PITCH, MNT_MIN_PITCH + { + if (strcmp("MNT_RANGE_PITCH", node->name) == 0) { + if (node->d > DBL_EPSILON) { + float mnt_max_pitch = static_cast(node->d) * 0.5f; + float mnt_min_pitch = static_cast(-node->d) * 0.5f; + param_set(param_find("MNT_MAX_PITCH"), &mnt_max_pitch); + param_set(param_find("MNT_MIN_PITCH"), &mnt_min_pitch); + PX4_INFO("migrating %s -> %s, %s", "MNT_RANGE_PITCH", "MNT_MAX_PITCH", "MNT_MIN_PITCH"); + } + + } + } + return param_modify_on_import_ret::PARAM_NOT_MODIFIED; } diff --git a/src/lib/parameters/parameters.cpp b/src/lib/parameters/parameters.cpp index 560d6eec82..772a5c2a9e 100644 --- a/src/lib/parameters/parameters.cpp +++ b/src/lib/parameters/parameters.cpp @@ -438,7 +438,7 @@ param_set_internal(param_t param, const void *val, bool mark_saved, bool notify_ } if (user_config.store(param, new_value)) { - params_unsaved.set(param, !mark_saved); + params_unsaved.set(param, !mark_saved && param_changed); result = PX4_OK; } else { diff --git a/src/lib/parameters/parameters_injected.xml b/src/lib/parameters/parameters_injected.xml deleted file mode 100644 index b927adc289..0000000000 --- a/src/lib/parameters/parameters_injected.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - 3 - - - Speed controller bandwidth - Speed controller bandwidth, in Hz. Higher values result in faster speed and current rise times, but may result in overshoot and higher current consumption. For fixed-wing aircraft, this value should be less than 50 Hz; for multirotors, values up to 100 Hz may provide improvements in responsiveness. - Hz - 10 - 250 - - - Reverse direction - Motor spin direction as detected during initial enumeration. Use 0 or 1 to reverse direction. - 0 - 1 - - - Speed (RPM) controller gain - Speed (RPM) controller gain. Determines controller - aggressiveness; units are amp-seconds per radian. Systems with - higher rotational inertia (large props) will need gain increased; - systems with low rotational inertia (small props) may need gain - decreased. Higher values result in faster response, but may result - in oscillation and excessive overshoot. Lower values result in a - slower, smoother response. - C/rad - 3 - 0.00 - 1.00 - - - Idle speed (e Hz) - Idle speed (e Hz) - Hz - 3 - 0.0 - 100.0 - - - Spin-up rate (e Hz/s) - Spin-up rate (e Hz/s) - 1/s^2 - 5 - 1000 - - - Index of this ESC in throttle command messages. - Index of this ESC in throttle command messages. - 0 - 15 - - - Extended status ID - Extended status ID - 1 - 1000000 - - - Extended status interval (µs) - Extended status interval (µs) - us - 0 - 1000000 - - - ESC status interval (µs) - ESC status interval (µs) - us - 1000000 - - - Motor current limit in amps - Motor current limit in amps. This determines the maximum - current controller setpoint, as well as the maximum allowable - current setpoint slew rate. This value should generally be set to - the continuous current rating listed in the motor’s specification - sheet, or set equal to the motor’s specified continuous power - divided by the motor voltage limit. - A - 3 - 1 - 80 - - - Motor Kv in RPM per volt - Motor Kv in RPM per volt. This can be taken from the motor’s - specification sheet; accuracy will help control performance but - some deviation from the specified value is acceptable. - rpm/V - 0 - 4000 - - - READ ONLY: Motor inductance in henries. - READ ONLY: Motor inductance in henries. This is measured on start-up. - H - 3 - - - Number of motor poles. - Number of motor poles. Used to convert mechanical speeds to - electrical speeds. This number should be taken from the motor’s - specification sheet. - 2 - 40 - - - READ ONLY: Motor resistance in ohms - READ ONLY: Motor resistance in ohms. This is measured on start-up. When - tuning a new motor, check that this value is approximately equal - to the value shown in the motor’s specification sheet. - Ohm - 3 - - - Acceleration limit (V) - Acceleration limit (V) - V - 3 - 0.01 - 1.00 - - - Motor voltage limit in volts - Motor voltage limit in volts. The current controller’s - commanded voltage will never exceed this value. Note that this may - safely be above the nominal voltage of the motor; to determine the - actual motor voltage limit, divide the motor’s rated power by the - motor current limit. - V - 3 - 0 - - - - - device health warning - Set the device health to Warning if the dimensionality of - the GNSS solution is less than this value. 3 for the full (3D) - solution, 2 for planar (2D) solution, 1 for time-only solution, - 0 disables the feature. - - 0 - 3 - - disables the feature - time-only solution - planar (2D) solution - full (3D) solution - - - - - Set the device health to Warning if the number of satellites - used in the GNSS solution is below this threshold. Zero - disables the feature - - - - GNSS dynamic model - Dynamic model used in the GNSS positioning engine. 0 – - Automotive, 1 – Sea, 2 – Airborne. - - 0 - 2 - - Automotive - Sea - Airborne - - - - Broadcast old GNSS fix message - Broadcast the old (deprecated) GNSS fix message - uavcan.equipment.gnss.Fix alongside the new alternative - uavcan.equipment.gnss.Fix2. It is recommended to - disable this feature to reduce the CAN bus traffic. - - 0 - 1 - - Fix2 - Fix and Fix2 - - - - - Set the device health to Warning if the number of satellites - used in the GNSS solution is below this threshold. Zero - disables the feature - - us - 0 - 1000000 - - - diff --git a/src/lib/parameters/px4params/jsonout.py b/src/lib/parameters/px4params/jsonout.py index e4a8b021bd..ba97c740d9 100644 --- a/src/lib/parameters/px4params/jsonout.py +++ b/src/lib/parameters/px4params/jsonout.py @@ -5,7 +5,7 @@ import sys class JsonOutput(): - def __init__(self, groups, board, inject_xml_file_name): + def __init__(self, groups, board): all_json=dict() all_json['version']=1 all_params=[] diff --git a/src/lib/parameters/px4params/srcparser.py b/src/lib/parameters/px4params/srcparser.py index f33d660d7b..e9ed7132e6 100644 --- a/src/lib/parameters/px4params/srcparser.py +++ b/src/lib/parameters/px4params/srcparser.py @@ -363,7 +363,7 @@ class SourceParser(object): 'm/s^3/sqrt(Hz)', 'm/s/sqrt(Hz)', 's/(1000*PWM)', '%m/s', 'min', 'us/C', 'N/(m/s)', 'Nm/rad', 'Nm/(rad/s)', 'Nm', 'N', 'rpm', - 'normalized_thrust/s', 'normalized_thrust', 'norm', 'SD','']) + 'normalized_thrust/s', 'normalized_thrust', 'norm', 'SD', 'dBHz', '']) for group in self.GetParamGroups(): for param in group.GetParams(): name = param.GetName() diff --git a/src/lib/parameters/px_process_params.py b/src/lib/parameters/px_process_params.py index feefa684c8..2d35e3e95d 100755 --- a/src/lib/parameters/px_process_params.py +++ b/src/lib/parameters/px_process_params.py @@ -75,12 +75,6 @@ def main(): metavar="FILENAME", help="Create XML file" " (default FILENAME: parameters.xml)") - parser.add_argument("-i", "--inject-xml", - nargs='?', - const="parameters_injected.xml", - metavar="FILENAME", - help="Inject additional param XML file" - " (default FILENAME: parameters_injected.xml)") parser.add_argument("-b", "--board", nargs='?', const="", @@ -138,8 +132,6 @@ def main(): #inject parameters at front of set cur_dir = os.path.dirname(os.path.realpath(__file__)) - groups_to_inject = injectxmlparams.XMLInject(os.path.join(cur_dir, args.inject_xml)).injected() - param_groups=groups_to_inject+param_groups override_dict = json.loads(args.overrides) if len(override_dict.keys()) > 0: @@ -174,8 +166,7 @@ def main(): if args.verbose: print("Creating Json file " + args.json) cur_dir = os.path.dirname(os.path.realpath(__file__)) - out = jsonout.JsonOutput(param_groups, args.board, - os.path.join(cur_dir, args.inject_xml)) + out = jsonout.JsonOutput(param_groups, args.board) out.Save(args.json) output_files.append(args.json) @@ -184,7 +175,7 @@ def main(): if args.verbose: print("Compressing file " + f) save_compressed(f) - + if __name__ == "__main__": main() diff --git a/src/lib/rate_control/CMakeLists.txt b/src/lib/rate_control/CMakeLists.txt index f95b133eea..2370b2eb5d 100644 --- a/src/lib/rate_control/CMakeLists.txt +++ b/src/lib/rate_control/CMakeLists.txt @@ -34,6 +34,8 @@ px4_add_library(RateControl rate_control.cpp rate_control.hpp + gain_compression.cpp + gain_compression.hpp ) target_compile_options(RateControl PRIVATE ${MAX_CUSTOM_OPT_LEVEL}) target_include_directories(RateControl PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/lib/rate_control/gain_compression.cpp b/src/lib/rate_control/gain_compression.cpp new file mode 100644 index 0000000000..7e1e172de4 --- /dev/null +++ b/src/lib/rate_control/gain_compression.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "gain_compression.hpp" + +using matrix::Vector3f; +using namespace time_literals; + +GainCompression3d::GainCompression3d(ModuleParams *parent) : ModuleParams(parent) +{ + updateParams(); + _gain_compression_pub.advertise(); +} + +void GainCompression3d::reset() +{ + for (unsigned i = 0; i < 3; i++) { + _compression_gains[i].reset(); + } +} + +void GainCompression3d::updateParams() +{ + ModuleParams::updateParams(); + + for (unsigned i = 0; i < 3; i++) { + _compression_gains[i].setCompressionGainMin(_param_fw_gc_gain_min.get()); + } +} + +void GainCompression3d::update(const Vector3f &input, const float dt) +{ + if (!_param_fw_gc_en.get()) { + reset(); + _gains.setOne(); + return; + } + + Vector3f hpf; + Vector3f lpf; + const float sample_freq = 1.f / math::constrain(dt, 1e-3f, 100e-3f); + + for (unsigned i = 0; i < 3; i++) { + _compression_gains[i].setLpfCutoffFrequency(sample_freq, _kLpfCutoffFrequency); + _compression_gains[i].setHpfCutoffFrequency(sample_freq, _kHpfCutoffFrequency); + + _gains(i) = _compression_gains[i].update(input(i), dt); + + hpf(i) = _compression_gains[i].getSpectralDamperHpf(); + lpf(i) = _compression_gains[i].getSpectralDamperLpf(); + } + + const hrt_abstime now = hrt_absolute_time(); + + if ((now - _time_last_publication) > 100_ms) { + gain_compression_s msg; + msg.timestamp = now; + _gains.copyTo(msg.compression_gains); + hpf.copyTo(msg.spectral_damper_hpf); + lpf.copyTo(msg.spectral_damper_out); + _gain_compression_pub.publish(msg); + + _time_last_publication = now; + } +} + +float GainCompression::update(const float input, const float dt) +{ + _hpf = _alpha_hpf * _hpf + _alpha_hpf * (input - _input_prev); + _lpf.update(_hpf * _hpf); + + _input_prev = input; + + const float ka = fmaxf(_compression_gain - _compression_gain_min, 0.f); + const float spectral_damping = -_kSpectralDamperGain * ka * _lpf.getState(); + + const float leakage = _kLeakageGain * (1.f - _compression_gain); + + const float ka_dot = spectral_damping + leakage; + _compression_gain = math::constrain(_compression_gain + ka_dot * dt, _compression_gain_min, 1.f); + + return _compression_gain; +} diff --git a/src/lib/rate_control/gain_compression.hpp b/src/lib/rate_control/gain_compression.hpp new file mode 100644 index 0000000000..20611e9ac9 --- /dev/null +++ b/src/lib/rate_control/gain_compression.hpp @@ -0,0 +1,119 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* Description: + * This class produces a multiplicative gain that can be used on the output of a controller + * to dynamically reduce the loop gain when oscillations are detected. + * + * Algorithm based on + * Orr, Jeb, and Tannen Van Zwieten. "Robust, practical adaptive control for launch vehicles." + * AIAA Guidance, Navigation, and Control Conference. 2012. + * https://ntrs.nasa.gov/api/citations/20120015662/downloads/20120015662.pdf + */ + +#pragma once + +// PX4 includes +#include + +// Libraries +#include +#include + +// uORB includes +#include +#include + +class GainCompression +{ +public: + void reset() { _compression_gain = 1.f; } + float update(float input, float dt); + + void setLpfCutoffFrequency(float sample_freq, float cutoff) + { + _lpf.setCutoffFreq(sample_freq, cutoff); + } + void setHpfCutoffFrequency(float sample_freq, float cutoff) { _alpha_hpf = sample_freq / (sample_freq + 2.f * M_PI_F * cutoff); } + + float getSpectralDamperHpf() const { return _hpf * _hpf; } + float getSpectralDamperLpf() const { return _lpf.getState(); } + void setCompressionGainMin(float gain_min) { _compression_gain_min = gain_min; } + +private: + float _compression_gain{1.f}; + float _compression_gain_min{0.3f}; + + float _alpha_hpf{0.f}; + float _hpf{0.f}; + + float _input_prev{0.f}; + + AlphaFilter _lpf; + + static constexpr float _kSpectralDamperGain{200.f}; // tuned based on flight test data to obtain a quick response + static constexpr float _kLeakageGain{0.1f}; // 1/time_constant, slow enough to not interfere with the controller + +}; + +class GainCompression3d : public ModuleParams +{ +public: + GainCompression3d(ModuleParams *parent); + ~GainCompression3d() = default; + + void reset(); + void update(const matrix::Vector3f &input, float dt); + const matrix::Vector3f &getGains() const { return _gains; }; + + +protected: + void updateParams() override; + +private: + // uORB publications + uORB::Publication _gain_compression_pub{ORB_ID(gain_compression)}; + + GainCompression _compression_gains[3]; + matrix::Vector3f _gains{1.f, 1.f, 1.f}; + + hrt_abstime _time_last_publication{0}; + + static constexpr float _kLpfCutoffFrequency{5.f}; // Just above the control bandwidth of most UAVs + static constexpr float _kHpfCutoffFrequency{2.f * _kLpfCutoffFrequency}; // 1 Octave above LPF cutoff, as recommended by the reference paper + + DEFINE_PARAMETERS( + (ParamBool) _param_fw_gc_en, + (ParamFloat) _param_fw_gc_gain_min + ) +}; diff --git a/src/lib/rate_control/gain_compression_params.c b/src/lib/rate_control/gain_compression_params.c new file mode 100644 index 0000000000..7a3cda5660 --- /dev/null +++ b/src/lib/rate_control/gain_compression_params.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * Enable rate gain compression + * + * @boolean + * @group FW Rate Control + */ +PARAM_DEFINE_INT32(FW_GC_EN, 1); + +/** + * Compression gain lower limit + * + * The range of the compression gain is between this parameter and 1.0 + * + * @min 0.0 + * @max 1.0 + * @increment 0.01 + * @decimal 2 + * @group FW Rate Control + */ +PARAM_DEFINE_FLOAT(FW_GC_GAIN_MIN, 0.3f); diff --git a/src/lib/ringbuffer/CMakeLists.txt b/src/lib/ringbuffer/CMakeLists.txt index 78a26de166..538c1ae907 100644 --- a/src/lib/ringbuffer/CMakeLists.txt +++ b/src/lib/ringbuffer/CMakeLists.txt @@ -38,3 +38,4 @@ px4_add_library(ringbuffer target_include_directories(ringbuffer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) px4_add_unit_gtest(SRC RingbufferTest.cpp LINKLIBS ringbuffer) +px4_add_unit_gtest(SRC TimestampedRingBufferTest.cpp) diff --git a/src/modules/ekf2/EKF/RingBuffer.h b/src/lib/ringbuffer/TimestampedRingBuffer.hpp similarity index 85% rename from src/modules/ekf2/EKF/RingBuffer.h rename to src/lib/ringbuffer/TimestampedRingBuffer.hpp index 2e4ff02bb3..a96f1c35a0 100644 --- a/src/modules/ekf2/EKF/RingBuffer.h +++ b/src/lib/ringbuffer/TimestampedRingBuffer.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2015-2022 PX4 Development Team. All rights reserved. + * Copyright (C) 2015-2026 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,31 +32,31 @@ ****************************************************************************/ /** - * @file RingBuffer.h + * @file TimestampedRingBuffer.h * @author Roman Bapst - * Template RingBuffer. + * @brief Template ring buffer for timestamped samples (requires data_type::time_us). + * Note: This is not the same as `Ringbuffer` (byte FIFO) in `src/lib/ringbuffer/Ringbuffer.hpp`. */ -#ifndef EKF_RINGBUFFER_H -#define EKF_RINGBUFFER_H +#pragma once #include #include #include template -class RingBuffer +class TimestampedRingBuffer { public: - explicit RingBuffer(size_t size) { allocate(size); } - RingBuffer() = delete; - ~RingBuffer() { delete[] _buffer; } + explicit TimestampedRingBuffer(size_t size) { allocate(size); } + TimestampedRingBuffer() = delete; + ~TimestampedRingBuffer() { delete[] _buffer; } // no copy, assignment, move, move assignment - RingBuffer(const RingBuffer &) = delete; - RingBuffer &operator=(const RingBuffer &) = delete; - RingBuffer(RingBuffer &&) = delete; - RingBuffer &operator=(RingBuffer &&) = delete; + TimestampedRingBuffer(const TimestampedRingBuffer &) = delete; + TimestampedRingBuffer &operator=(const TimestampedRingBuffer &) = delete; + TimestampedRingBuffer(TimestampedRingBuffer &&) = delete; + TimestampedRingBuffer &operator=(TimestampedRingBuffer &&) = delete; bool allocate(uint8_t size) { @@ -69,9 +69,7 @@ public: return false; } - if (_buffer != nullptr) { - delete[] _buffer; - } + delete[] _buffer; _buffer = new data_type[size] {}; @@ -191,5 +189,3 @@ private: bool _first_write{true}; }; - -#endif // !EKF_RINGBUFFER_H diff --git a/src/modules/ekf2/test/test_EKF_ringbuffer.cpp b/src/lib/ringbuffer/TimestampedRingBufferTest.cpp similarity index 89% rename from src/modules/ekf2/test/test_EKF_ringbuffer.cpp rename to src/lib/ringbuffer/TimestampedRingBufferTest.cpp index 0338bea816..83f5fa7940 100644 --- a/src/modules/ekf2/test/test_EKF_ringbuffer.cpp +++ b/src/lib/ringbuffer/TimestampedRingBufferTest.cpp @@ -33,7 +33,7 @@ #include #include -#include "EKF/ekf.h" +#include "TimestampedRingBuffer.hpp" struct sample { uint64_t time_us; @@ -41,16 +41,16 @@ struct sample { }; -class EkfRingBufferTest : public ::testing::Test +class TimestampedRingBufferTest : public ::testing::Test { public: sample _x, _y, _z; - RingBuffer *_buffer{nullptr}; + TimestampedRingBuffer *_buffer{nullptr}; void SetUp() override { - _buffer = new RingBuffer(3); + _buffer = new TimestampedRingBuffer(3); _x.time_us = 1000000; _x.data[0] = _x.data[1] = _x.data[2] = 1.5f; @@ -67,7 +67,7 @@ public: } }; -TEST_F(EkfRingBufferTest, goodInitialisation) +TEST_F(TimestampedRingBufferTest, goodInitialisation) { // WHEN: buffer was allocated // THEN: allocation should have succeed @@ -75,7 +75,7 @@ TEST_F(EkfRingBufferTest, goodInitialisation) } -TEST_F(EkfRingBufferTest, badInitialisation) +TEST_F(TimestampedRingBufferTest, badInitialisation) { // WHEN: buffer allocation input is bad // THEN: allocation should fail @@ -85,7 +85,7 @@ TEST_F(EkfRingBufferTest, badInitialisation) // ASSERT_EQ(false, _buffer->allocate(0)); } -TEST_F(EkfRingBufferTest, orderOfSamples) +TEST_F(TimestampedRingBufferTest, orderOfSamples) { ASSERT_EQ(true, _buffer->allocate(3)); // GIVEN: allocated buffer @@ -103,7 +103,7 @@ TEST_F(EkfRingBufferTest, orderOfSamples) EXPECT_EQ(_y.time_us, _buffer->get_newest().time_us); } -TEST_F(EkfRingBufferTest, popSample) +TEST_F(TimestampedRingBufferTest, popSample) { ASSERT_EQ(true, _buffer->allocate(3)); _buffer->push(_x); @@ -128,7 +128,7 @@ TEST_F(EkfRingBufferTest, popSample) // TODO: When changing the order of popping sample it does not behave as expected, fix this } -TEST_F(EkfRingBufferTest, askingForTooNewSample) +TEST_F(TimestampedRingBufferTest, askingForTooNewSample) { ASSERT_EQ(true, _buffer->allocate(3)); _buffer->push(_x); @@ -142,7 +142,7 @@ TEST_F(EkfRingBufferTest, askingForTooNewSample) EXPECT_EQ(false, _buffer->pop_first_older_than(_y.time_us + 100000, &pop)); } -TEST_F(EkfRingBufferTest, reallocateBuffer) +TEST_F(TimestampedRingBufferTest, reallocateBuffer) { ASSERT_EQ(true, _buffer->allocate(5)); _buffer->push(_x); diff --git a/src/lib/rl_tools/CMakeLists.txt b/src/lib/rl_tools/CMakeLists.txt new file mode 100644 index 0000000000..83402f2c45 --- /dev/null +++ b/src/lib/rl_tools/CMakeLists.txt @@ -0,0 +1,15 @@ +if(CONFIG_LIB_RL_TOOLS) + px4_add_git_submodule(TARGET git_rl_tools PATH "rl_tools") + add_library(rl_tools INTERFACE) + target_include_directories(rl_tools INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/rl_tools/include + ) + + target_compile_features(rl_tools INTERFACE cxx_std_17) + + target_compile_options(rl_tools INTERFACE + -Wno-unused-parameter + -Wno-unused-variable + -Wno-unused-local-typedefs + ) +endif() diff --git a/src/lib/rl_tools/Kconfig b/src/lib/rl_tools/Kconfig new file mode 100644 index 0000000000..8014b02bcf --- /dev/null +++ b/src/lib/rl_tools/Kconfig @@ -0,0 +1,7 @@ +config LIB_RL_TOOLS + bool "RLtools" + default n + ---help--- + RLtools is a header-only library for reinforcement learning and neural networks. + It enables running trained RL policies on embedded devices. + This library is used for running RL-based controllers on the PX4 autopilot. diff --git a/src/lib/rl_tools/rl_tools b/src/lib/rl_tools/rl_tools new file mode 160000 index 0000000000..15940da2a8 --- /dev/null +++ b/src/lib/rl_tools/rl_tools @@ -0,0 +1 @@ +Subproject commit 15940da2a8334d7532c4a5650ee4e09526206414 diff --git a/src/lib/rtl/rtl_time_estimator.cpp b/src/lib/rtl/rtl_time_estimator.cpp index ddc851c5e3..c7cc22bfbb 100644 --- a/src/lib/rtl/rtl_time_estimator.cpp +++ b/src/lib/rtl/rtl_time_estimator.cpp @@ -54,6 +54,7 @@ RtlTimeEstimator::RtlTimeEstimator() : ModuleParams(nullptr) _param_fw_climb_rate = param_find("FW_T_CLMB_R_SP"); _param_fw_sink_rate = param_find("FW_T_SINK_R_SP"); _param_fw_airspeed_trim = param_find("FW_AIRSPD_TRIM"); + _param_fw_gnd_spd_min = param_find("FW_GND_SPD_MIN"); _param_mpc_xy_cruise = param_find("MPC_XY_CRUISE"); _param_rover_cruise_speed = param_find("RO_SPEED_LIM"); }; @@ -142,7 +143,18 @@ float RtlTimeEstimator::getCruiseGroundSpeed(const matrix::Vector2f &direction_n const float ground_speed = sqrtf(cruise_speed * cruise_speed - wind_across_dir * wind_across_dir) + fminf( 0.f, wind_along_dir); - cruise_speed = ground_speed; + // Assume that minimum ground speed is always satisfied. If + // windspeed < cas2tas(FW_AIRSPD_MAX) - FW_GND_SPD_MIN + // the assumption always holds. Otherwise it breaks down when + // flying upwind, and the RTL time estimate is optimistic. + + float fw_gnd_spd_min = 5.0f; + + if (_param_fw_gnd_spd_min != PARAM_INVALID) { + param_get(_param_fw_gnd_spd_min, &fw_gnd_spd_min); + } + + cruise_speed = fmaxf(ground_speed, fw_gnd_spd_min); } return cruise_speed; diff --git a/src/lib/rtl/rtl_time_estimator.h b/src/lib/rtl/rtl_time_estimator.h index 7ca79fba1f..c919f96e3c 100644 --- a/src/lib/rtl/rtl_time_estimator.h +++ b/src/lib/rtl/rtl_time_estimator.h @@ -129,6 +129,7 @@ private: param_t _param_fw_sink_rate{PARAM_INVALID}; /**< FW descend speed parameter */ param_t _param_fw_airspeed_trim{PARAM_INVALID}; /**< FW cruise airspeed parameter */ + param_t _param_fw_gnd_spd_min{PARAM_INVALID}; /**< FW min groundspeed parameter */ param_t _param_mpc_xy_cruise{PARAM_INVALID}; /**< MC horizontal cruise speed parameter */ param_t _param_rover_cruise_speed{PARAM_INVALID}; /**< Rover cruise speed parameter */ diff --git a/src/lib/sticks/CMakeLists.txt b/src/lib/sticks/CMakeLists.txt new file mode 100644 index 0000000000..3d17b2a140 --- /dev/null +++ b/src/lib/sticks/CMakeLists.txt @@ -0,0 +1,37 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(Sticks + Sticks.cpp +) +target_include_directories(Sticks PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/modules/flight_mode_manager/tasks/Utility/Sticks.cpp b/src/lib/sticks/Sticks.cpp similarity index 81% rename from src/modules/flight_mode_manager/tasks/Utility/Sticks.cpp rename to src/lib/sticks/Sticks.cpp index fb5bc40673..26a66cf271 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/Sticks.cpp +++ b/src/lib/sticks/Sticks.cpp @@ -50,17 +50,10 @@ bool Sticks::checkAndUpdateStickInputs() manual_control_setpoint_s manual_control_setpoint; if (_manual_control_setpoint_sub.update(&manual_control_setpoint)) { - // Linear scale - _positions(0) = manual_control_setpoint.pitch; - _positions(1) = manual_control_setpoint.roll; - _positions(2) = -manual_control_setpoint.throttle; - _positions(3) = manual_control_setpoint.yaw; - - // Exponential scale - _positions_expo(0) = math::expo_deadzone(_positions(0), _param_mpc_xy_man_expo.get(), _param_mpc_hold_dz.get()); - _positions_expo(1) = math::expo_deadzone(_positions(1), _param_mpc_xy_man_expo.get(), _param_mpc_hold_dz.get()); - _positions_expo(2) = math::expo_deadzone(_positions(2), _param_mpc_z_man_expo.get(), _param_mpc_hold_dz.get()); - _positions_expo(3) = math::expo_deadzone(_positions(3), _param_mpc_yaw_expo.get(), _param_mpc_hold_dz.get()); + _positions(0) = manual_control_setpoint.roll; + _positions(1) = manual_control_setpoint.pitch; + _positions(2) = manual_control_setpoint.yaw; + _positions(3) = manual_control_setpoint.throttle; _aux_positions(0) = manual_control_setpoint.aux1; _aux_positions(1) = manual_control_setpoint.aux2; @@ -85,7 +78,6 @@ bool Sticks::checkAndUpdateStickInputs() if (!_input_available) { // Timeout: set all sticks to zero _positions.zero(); - _positions_expo.zero(); } return _input_available; diff --git a/src/modules/flight_mode_manager/tasks/Utility/Sticks.hpp b/src/lib/sticks/Sticks.hpp similarity index 72% rename from src/modules/flight_mode_manager/tasks/Utility/Sticks.hpp rename to src/lib/sticks/Sticks.hpp index 3ab13368e8..1da031a283 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/Sticks.hpp +++ b/src/lib/sticks/Sticks.hpp @@ -58,21 +58,19 @@ public: bool isAvailable() { return _input_available; }; - // Position : 0 : pitch, 1 : roll, 2 : throttle, 3 : yaw - const matrix::Vector4f &getPosition() { return _positions; }; // Raw stick position, no deadzone - const matrix::Vector4f &getPositionExpo() { return _positions_expo; }; // Deadzone and expo applied - // Helper functions to get stick values more intuitively - float getRoll() const { return _positions(1); } - float getRollExpo() const { return _positions_expo(1); } - float getPitch() const { return _positions(0); } - float getPitchExpo() const { return _positions_expo(0); } - float getYaw() const { return _positions(3); } - float getYawExpo() const { return _positions_expo(3); } - float getThrottleZeroCentered() const { return -_positions(2); } // Convert Z-axis(down) command to Up-axis frame - float getThrottleZeroCenteredExpo() const { return -_positions_expo(2); } - const matrix::Vector2f getPitchRoll() { return _positions.slice<2, 1>(0, 0); } - const matrix::Vector2f getPitchRollExpo() { return _positions_expo.slice<2, 1>(0, 0); } + float getRoll() const { return _positions(0); } + float getPitch() const { return _positions(1); } + float getYaw() const { return _positions(2); } + float getThrottleZeroCentered() const { return _positions(3); } + + float getRollExpo(float expo = .6f) const { return math::expo_deadzone(getRoll(), expo, _param_man_deadzone.get()); } + float getPitchExpo(float expo = .6f) const { return math::expo_deadzone(getPitch(), expo, _param_man_deadzone.get()); } + float getYawExpo(float expo = .6f) const { return math::expo_deadzone(getYaw(), expo, _param_man_deadzone.get()); } + float getThrottleZeroCenteredExpo(float expo = .6f) const { return math::expo_deadzone(getThrottleZeroCentered(), expo, _param_man_deadzone.get()); } + + const matrix::Vector2f getPitchRoll() { return {getPitch(), getRoll()}; } + const matrix::Vector2f getPitchRollExpo() { return {getPitchExpo(), getRollExpo()}; } const matrix::Vector &getAux() const { return _aux_positions; } @@ -92,8 +90,7 @@ public: private: bool _input_available{false}; - matrix::Vector4f _positions; ///< unmodified manual stick inputs that usually move vehicle in x, y, z and yaw direction - matrix::Vector4f _positions_expo; ///< modified manual sticks using expo function + matrix::Vector4f _positions; ///< unmodified manual stick inputs roll, pitch, yaw ,throttle matrix::Vector _aux_positions; @@ -101,9 +98,6 @@ private: uORB::Subscription _failsafe_flags_sub{ORB_ID(failsafe_flags)}; DEFINE_PARAMETERS( - (ParamFloat) _param_mpc_hold_dz, - (ParamFloat) _param_mpc_xy_man_expo, - (ParamFloat) _param_mpc_z_man_expo, - (ParamFloat) _param_mpc_yaw_expo + (ParamFloat) _param_man_deadzone ) }; diff --git a/src/lib/tecs/TECS.cpp b/src/lib/tecs/TECS.cpp index 5ff73eb83c..69d124239d 100644 --- a/src/lib/tecs/TECS.cpp +++ b/src/lib/tecs/TECS.cpp @@ -590,7 +590,9 @@ void TECSControl::_calcThrottleControlUpdate(float dt, const STERateLimit &limit if (_throttle_setpoint >= param.throttle_max) { throttle_integ_input = math::min(0.f, throttle_integ_input); - } else if (_throttle_setpoint <= param.throttle_min) { + } + + if (_throttle_setpoint <= param.throttle_min) { throttle_integ_input = math::max(0.f, throttle_integ_input); } diff --git a/src/lib/tunes/tune_definition.desc b/src/lib/tunes/tune_definition.desc index c615a16c09..493106f94c 100644 --- a/src/lib/tunes/tune_definition.desc +++ b/src/lib/tunes/tune_definition.desc @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2018 PX4 Development Team. All rights reserved. + * Copyright (c) 2018 - 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,13 +32,13 @@ ****************************************************************************/ /** - * Driver for the PX4 audio . + * Driver for PX4 audio * - * The tune_control supports a set of predefined "alarm" tunes and - * one user-supplied tune. + * The tune_control supports a set of predefined "alarm" tunes and one user-supplied tune. * - * Tunes follow the syntax of the Microsoft GWBasic/QBasic PLAY - * statement, with some exceptions and extensions. + * Tunes follow the syntax of the Microsoft GWBasic/QBasic PLAY statement, with some exceptions and extensions. + * This is equivalent to Modern MML https://en.wikipedia.org/wiki/Music_Macro_Language#Modern_MML + * With the exception that symbols must be upper-cased, and that the `V` symbol is ignored. * * From Wikibooks: * @@ -70,7 +70,9 @@ * ML Stand for Music Legato. Note duration is full length of that indicated by Ln. * MS Stand for Music Staccato. Note duration is 3/4ths of the length indicated by Ln. * Pn Causes a silence (pause) for the length of note indicated (same as Ln). + * Rn Same as P (pause). * Tn Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120. + * Vn Ignored. In specification sets the volume of the instrument (subsequent notes). * . When placed after a note, it causes the duration of the note to be 3/2 of the set duration. * This is how to get "dotted" notes. "L4 C#." would play C sharp as a dotted quarter note. * It can be used for a pause as well. diff --git a/src/lib/tunes/tunes.cpp b/src/lib/tunes/tunes.cpp index 961e10ba64..02a5b16055 100644 --- a/src/lib/tunes/tunes.cpp +++ b/src/lib/tunes/tunes.cpp @@ -219,6 +219,13 @@ Tunes::Status Tunes::get_next_note(unsigned &frequency, unsigned &duration, unsi _next_tune++; switch (c) { + + case 'V': // Select volume. + // Consume volume if specified in tune but ignore + // MML compatibility + next_number(); + break; + case 'L': // Select note length. _note_length = next_number(); @@ -288,6 +295,7 @@ Tunes::Status Tunes::get_next_note(unsigned &frequency, unsigned &duration, unsi break; case 'P': // Pause for a note length. + case 'R': frequency = 0; duration = 0; note_length = next_number(); diff --git a/src/lib/version/px_update_git_header.py b/src/lib/version/px_update_git_header.py index bd1836fb03..4b9b06d252 100755 --- a/src/lib/version/px_update_git_header.py +++ b/src/lib/version/px_update_git_header.py @@ -97,9 +97,10 @@ except: if tag_or_branch is None: # replace / so it can be used as directory name tag_or_branch = git_branch_name.replace('/', '-') - # either a release or main branch (used for metadata) + # either a release or master branch (used for metadata) + # CI uploads to 'master/' on S3 for legacy QGC compatibility if not tag_or_branch.startswith('release-'): - tag_or_branch = 'main' + tag_or_branch = 'master' header += f""" #define PX4_GIT_VERSION_STR "{git_version}" @@ -109,7 +110,7 @@ header += f""" #define PX4_GIT_OEM_VERSION_STR "{oem_tag}" -#define PX4_GIT_TAG_OR_BRANCH_NAME "{tag_or_branch}" // special variable: git tag, release or main branch +#define PX4_GIT_TAG_OR_BRANCH_NAME "{tag_or_branch}" // special variable: git tag, release or master branch """ @@ -129,8 +130,12 @@ if (os.path.exists('src/modules/mavlink/mavlink/.git')): if (os.path.exists('platforms/nuttx/NuttX/nuttx/.git')): nuttx_git_tags = subprocess.check_output('git -c versionsort.suffix=- tag --sort=v:refname'.split(), cwd='platforms/nuttx/NuttX/nuttx', stderr=subprocess.STDOUT).decode('utf-8').strip() - nuttx_git_tag = re.findall(r'nuttx-[0-9]+\.[0-9]+\.[0-9]+', nuttx_git_tags)[-1].replace("nuttx-", "v") - nuttx_git_tag = re.sub('-.*', '.0', nuttx_git_tag) + # may be empty if shallow clone + if (len(nuttx_git_tags) > 0): + nuttx_git_tag = re.findall(r'nuttx-[0-9]+\.[0-9]+\.[0-9]+', nuttx_git_tags)[-1].replace("nuttx-", "v") + nuttx_git_tag = re.sub('-.*', '.0', nuttx_git_tag) + else: + nuttx_git_tag = "v0.0.0" nuttx_git_version = subprocess.check_output('git rev-parse --verify HEAD'.split(), cwd='platforms/nuttx/NuttX/nuttx', stderr=subprocess.STDOUT).decode('utf-8').strip() nuttx_git_version_short = nuttx_git_version[0:16] diff --git a/src/lib/wind_estimator/WindEstimator.cpp b/src/lib/wind_estimator/WindEstimator.cpp index ee6c6c9ed8..93602d75a6 100644 --- a/src/lib/wind_estimator/WindEstimator.cpp +++ b/src/lib/wind_estimator/WindEstimator.cpp @@ -68,6 +68,7 @@ WindEstimator::initialise(const matrix::Vector3f &velI, const float hor_vel_vari } _wind_estimator_reset = true; + _time_initialised = hrt_absolute_time(); return true; } @@ -94,10 +95,14 @@ WindEstimator::update(uint64_t time_now) const float dt = (float)(time_now - _time_last_update) * 1e-6f; _time_last_update = time_now; + // if airspeed scale is at default (1.0) and we are in the first 5 minutes of flight time, multiply _tas_scale_psd by 100 for faster learning + const float tas_psd_multiplier = (fabsf(_scale_init - 1.0f) < FLT_EPSILON && (time_now - _time_initialised < kTASScaleFastLearnTime)) ? + kTASScalePSDMultiplier : 1.f; + matrix::Matrix3f Qk; Qk(INDEX_W_N, INDEX_W_N) = _wind_psd * dt; Qk(INDEX_W_E, INDEX_W_E) = Qk(INDEX_W_N, INDEX_W_N); - Qk(INDEX_TAS_SCALE, INDEX_TAS_SCALE) = _tas_scale_psd * dt; + Qk(INDEX_TAS_SCALE, INDEX_TAS_SCALE) = _tas_scale_psd * tas_psd_multiplier * dt; _P += Qk; } diff --git a/src/lib/wind_estimator/WindEstimator.hpp b/src/lib/wind_estimator/WindEstimator.hpp index 462f88ff26..b69ee9cb85 100644 --- a/src/lib/wind_estimator/WindEstimator.hpp +++ b/src/lib/wind_estimator/WindEstimator.hpp @@ -94,6 +94,14 @@ public: void set_beta_gate(uint8_t gate_size) {_beta_gate = gate_size; } void set_scale_init(float scale_init) {_scale_init = 1.f / math::constrain(scale_init, 0.1f, 10.f); } + void reset_scale_to_init() + { + _state(INDEX_TAS_SCALE) = _scale_init; + auto P_wind = _P.slice<2, 2>(0, 0); + _P.setZero(); + _P.slice<2, 2>(0, 0) = P_wind; + } + private: enum { INDEX_W_N = 0, @@ -131,6 +139,10 @@ private: uint64_t _time_last_airspeed_fuse = 0; ///< timestamp of last airspeed fusion uint64_t _time_last_beta_fuse = 0; ///< timestamp of last sideslip fusion uint64_t _time_last_update = 0; ///< timestamp of last covariance prediction + uint64_t _time_initialised = 0; ///< timestamp when estimator is initialised + + static constexpr float kTASScalePSDMultiplier = 100; + static constexpr hrt_abstime kTASScaleFastLearnTime = 300_s; bool _wind_estimator_reset = false; ///< wind estimator was reset in this cycle diff --git a/src/modules/airspeed_selector/AirspeedValidator.hpp b/src/modules/airspeed_selector/AirspeedValidator.hpp index ec78b9ef8f..f902e8a9de 100644 --- a/src/modules/airspeed_selector/AirspeedValidator.hpp +++ b/src/modules/airspeed_selector/AirspeedValidator.hpp @@ -121,6 +121,7 @@ public: void set_tas_scale_apply(int tas_scale_apply) { _tas_scale_apply = tas_scale_apply; } void set_CAS_scale_validated(float scale) { _CAS_scale_validated = scale; } void set_scale_init(float scale) { _wind_estimator.set_scale_init(scale); } + void reset_scale_estimator() { _wind_estimator.reset_scale_to_init(); } void set_enable_data_stuck_check(bool enable) { _data_stuck_check_enabled = enable; } void set_enable_innovation_check(bool enable) { _innovation_check_enabled = enable; } diff --git a/src/modules/airspeed_selector/airspeed_selector_main.cpp b/src/modules/airspeed_selector/airspeed_selector_main.cpp index b3209e2f33..1fa832bee1 100644 --- a/src/modules/airspeed_selector/airspeed_selector_main.cpp +++ b/src/modules/airspeed_selector/airspeed_selector_main.cpp @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include #include @@ -127,7 +127,7 @@ private: uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)}; uORB::Subscription _vehicle_local_position_sub{ORB_ID(vehicle_local_position)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; - uORB::Subscription _vehicle_thrust_setpoint_0_sub{ORB_ID(vehicle_thrust_setpoint), 0}; + uORB::Subscription _vehicle_rates_setpoint_sub{ORB_ID(vehicle_rates_setpoint)}; uORB::Subscription _position_setpoint_sub{ORB_ID(position_setpoint)}; uORB::Subscription _launch_detection_status_sub{ORB_ID(launch_detection_status)}; uORB::SubscriptionMultiArray _airspeed_subs{ORB_ID::airspeed}; @@ -494,10 +494,24 @@ void AirspeedModule::update_params() param_get(_param_handle_fw_thr_max, &_param_fw_thr_max); } + const float prev_scale[MAX_NUM_AIRSPEED_SENSORS] = { + _param_airspeed_scale[0], + _param_airspeed_scale[1], + _param_airspeed_scale[2] + }; + _param_airspeed_scale[0] = _param_airspeed_scale_1.get(); _param_airspeed_scale[1] = _param_airspeed_scale_2.get(); _param_airspeed_scale[2] = _param_airspeed_scale_3.get(); + for (int i = 0; i < MAX_NUM_AIRSPEED_SENSORS; i++) { + if (fabsf(_param_airspeed_scale[i] - prev_scale[i]) > FLT_EPSILON) { + _airspeed_validator[i].set_scale_init(_param_airspeed_scale[i]); + _airspeed_validator[i].reset_scale_estimator(); + _airspeed_validator[i].set_CAS_scale_validated(_param_airspeed_scale[i]); + } + } + _wind_estimator_sideslip.set_wind_process_noise_spectral_density(_param_aspd_wind_nsd.get()); _wind_estimator_sideslip.set_tas_scale_process_noise_spectral_density(_param_aspd_scale_nsd.get()); _wind_estimator_sideslip.set_tas_noise(_param_west_tas_noise.get()); @@ -827,16 +841,16 @@ float AirspeedModule::get_synthetic_airspeed(float throttle) void AirspeedModule::update_throttle_filter(hrt_abstime now) { if (_vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) { - vehicle_thrust_setpoint_s vehicle_thrust_setpoint_0{}; - _vehicle_thrust_setpoint_0_sub.copy(&vehicle_thrust_setpoint_0); + vehicle_rates_setpoint_s vehicle_rates_setpoint{}; + _vehicle_rates_setpoint_sub.copy(&vehicle_rates_setpoint); - float forward_thrust = vehicle_thrust_setpoint_0.xyz[0]; + float forward_thrust = vehicle_rates_setpoint.thrust_body[0]; // if VTOL, use the total thrust vector length (otherwise needs special handling for tailsitters and tiltrotors) if (_vehicle_status.is_vtol) { - forward_thrust = sqrtf(vehicle_thrust_setpoint_0.xyz[0] * vehicle_thrust_setpoint_0.xyz[0] + - vehicle_thrust_setpoint_0.xyz[1] * vehicle_thrust_setpoint_0.xyz[1] + - vehicle_thrust_setpoint_0.xyz[2] * vehicle_thrust_setpoint_0.xyz[2]); + forward_thrust = sqrtf(vehicle_rates_setpoint.thrust_body[0] * vehicle_rates_setpoint.thrust_body[0] + + vehicle_rates_setpoint.thrust_body[1] * vehicle_rates_setpoint.thrust_body[1] + + vehicle_rates_setpoint.thrust_body[2] * vehicle_rates_setpoint.thrust_body[2]); } const float dt = static_cast(now - _t_last_throttle_fw) * 1e-6f; diff --git a/src/modules/airspeed_selector/airspeed_selector_params.c b/src/modules/airspeed_selector/airspeed_selector_params.c index a7db4cb30c..34d74cbfc5 100644 --- a/src/modules/airspeed_selector/airspeed_selector_params.c +++ b/src/modules/airspeed_selector/airspeed_selector_params.c @@ -95,7 +95,6 @@ PARAM_DEFINE_INT32(ASPD_SCALE_APPLY, 2); * @min 0.5 * @max 2.0 * @decimal 2 - * @reboot_required true * @group Airspeed Validator * @volatile */ @@ -109,7 +108,6 @@ PARAM_DEFINE_FLOAT(ASPD_SCALE_1, 1.0f); * @min 0.5 * @max 2.0 * @decimal 2 - * @reboot_required true * @group Airspeed Validator * @volatile */ @@ -123,7 +121,6 @@ PARAM_DEFINE_FLOAT(ASPD_SCALE_2, 1.0f); * @min 0.5 * @max 2.0 * @decimal 2 - * @reboot_required true * @group Airspeed Validator * @volatile */ diff --git a/src/modules/commander/Commander.cpp b/src/modules/commander/Commander.cpp index 0e2c50ec4f..ead99ad3d6 100644 --- a/src/modules/commander/Commander.cpp +++ b/src/modules/commander/Commander.cpp @@ -302,6 +302,26 @@ int Commander::custom_command(int argc, char *argv[]) return 0; } + if (!strcmp(argv[0], "safety")) { + if (argc < 2) { + PX4_ERR("missing argument"); + return 1; + } + + if (!strcmp(argv[1], "on")) { + send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE, vehicle_command_s::SAFETY_ON); + + } else if (!strcmp(argv[1], "off")) { + send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE, vehicle_command_s::SAFETY_OFF); + + } else { + PX4_ERR("invlaid argument, use [on|off]"); + return 1; + } + + return 0; + } + if (!strcmp(argv[0], "arm")) { float param2 = 0.f; @@ -380,6 +400,9 @@ int Commander::custom_command(int argc, char *argv[]) send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_MODE, 1, PX4_CUSTOM_MAIN_MODE_POSCTL, PX4_CUSTOM_SUB_MODE_POSCTL_SLOW); + } else if (!strcmp(argv[1], "altitude_cruise")) { + send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_MODE, 1, PX4_CUSTOM_MAIN_MODE_ALTITUDE_CRUISE); + } else if (!strcmp(argv[1], "auto:mission")) { send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_MODE, 1, PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_MISSION); @@ -459,6 +482,22 @@ int Commander::custom_command(int argc, char *argv[]) } } + if (!strcmp(argv[0], "set_heading")) { + if (argc > 1) { + const float heading = atof(argv[1]); + const float heading_accuracy = NAN; + + bool ret = send_vehicle_command(vehicle_command_s::VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE, + 0.f, 0.f, heading, 0.f, 0.0, 0.0, heading_accuracy); + return (ret ? 0 : 1); + + } else { + PX4_ERR("missing argument"); + return 0; + } + } + + if (!strcmp(argv[0], "poweroff")) { bool ret = send_vehicle_command(vehicle_command_s::VEHICLE_CMD_PREFLIGHT_REBOOT_SHUTDOWN, @@ -476,6 +515,7 @@ int Commander::custom_command(int argc, char *argv[]) int Commander::print_status() { PX4_INFO("%s", isArmed() ? "Armed" : "Disarmed"); + PX4_INFO("prearm safety: %s", _safety.isSafetyOff() ? "Off" : "On"); PX4_INFO("navigation mode: %s", mode_util::nav_state_names[_vehicle_status.nav_state]); PX4_INFO("user intended navigation mode: %s", mode_util::nav_state_names[_vehicle_status.nav_state_user_intention]); PX4_INFO("in failsafe: %s", _failsafe.inFailsafe() ? "yes" : "no"); @@ -492,10 +532,30 @@ extern "C" __EXPORT int commander_main(int argc, char *argv[]) static constexpr const char *arm_disarm_reason_str(arm_disarm_reason_t calling_reason) { - switch (calling_reason) { - case arm_disarm_reason_t::transition_to_standby: return ""; + static_assert((uint8_t)arm_disarm_reason_t::stick_gesture == vehicle_status_s::ARM_DISARM_REASON_STICK_GESTURE, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::rc_switch == vehicle_status_s::ARM_DISARM_REASON_RC_SWITCH, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::command_internal == vehicle_status_s::ARM_DISARM_REASON_COMMAND_INTERNAL, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::command_external == vehicle_status_s::ARM_DISARM_REASON_COMMAND_EXTERNAL, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::mission_start == vehicle_status_s::ARM_DISARM_REASON_MISSION_START, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::landing == vehicle_status_s::ARM_DISARM_REASON_LANDING, + "(dis)arm enum mismatch"); + static_assert( + (uint8_t)arm_disarm_reason_t::preflight_inaction == vehicle_status_s::ARM_DISARM_REASON_PREFLIGHT_INACTION, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::kill_switch == vehicle_status_s::ARM_DISARM_REASON_KILL_SWITCH, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::rc_button == vehicle_status_s::ARM_DISARM_REASON_RC_BUTTON, + "(dis)arm enum mismatch"); + static_assert((uint8_t)arm_disarm_reason_t::failsafe == vehicle_status_s::ARM_DISARM_REASON_FAILSAFE, + "(dis)arm enum mismatch"); - case arm_disarm_reason_t::stick_gesture: return "Stick gesture"; + switch (calling_reason) { + case arm_disarm_reason_t::stick_gesture: return "stick gesture"; case arm_disarm_reason_t::rc_switch: return "RC switch"; @@ -505,21 +565,13 @@ static constexpr const char *arm_disarm_reason_str(arm_disarm_reason_t calling_r case arm_disarm_reason_t::mission_start: return "mission start"; - case arm_disarm_reason_t::auto_disarm_land: return "landing"; + case arm_disarm_reason_t::landing: return "landing"; - case arm_disarm_reason_t::auto_disarm_preflight: return "auto preflight disarming"; + case arm_disarm_reason_t::preflight_inaction: return "auto preflight disarming"; case arm_disarm_reason_t::kill_switch: return "kill-switch"; - case arm_disarm_reason_t::lockdown: return "lockdown"; - - case arm_disarm_reason_t::failure_detector: return "failure detector"; - - case arm_disarm_reason_t::shutdown: return "shutdown request"; - - case arm_disarm_reason_t::unit_test: return "unit tests"; - - case arm_disarm_reason_t::rc_button: return "RC (button)"; + case arm_disarm_reason_t::rc_button: return "RC button"; case arm_disarm_reason_t::failsafe: return "failsafe"; } @@ -607,7 +659,7 @@ transition_result_t Commander::arm(arm_disarm_reason_t calling_reason, bool run_ events::send(events::ID("commander_armed_by"), events::Log::Info, "Armed by {1}", calling_reason); - if (_param_com_home_en.get() && !_mission_in_progress) { + if (_param_com_home_en.get() && !_mission_in_progress && !_config_overrides.disable_auto_set_home) { _home_position.setHomePosition(); } @@ -794,6 +846,9 @@ Commander::handle_command(const vehicle_command_s &cmd) } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_ALTCTL) { desired_nav_state = vehicle_status_s::NAVIGATION_STATE_ALTCTL; + } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_ALTITUDE_CRUISE) { + desired_nav_state = vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE; + } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_POSCTL) { switch (custom_sub_mode) { default: @@ -862,6 +917,12 @@ Commander::handle_command(const vehicle_command_s &cmd) } else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_OFFBOARD) { desired_nav_state = vehicle_status_s::NAVIGATION_STATE_OFFBOARD; + + } else { + main_ret = TRANSITION_DENIED; + mavlink_log_critical(&_mavlink_log_pub, "Unsupported main mode\t"); + events::send(events::ID("commander_unsupported_main_mode"), events::Log::Error, + "Unsupported main mode"); } } else { @@ -879,6 +940,12 @@ Commander::handle_command(const vehicle_command_s &cmd) } else { desired_nav_state = vehicle_status_s::NAVIGATION_STATE_MANUAL; } + + } else { + main_ret = TRANSITION_DENIED; + mavlink_log_critical(&_mavlink_log_pub, "Unsupported base mode\t"); + events::send(events::ID("commander_unsupported_base_mode"), events::Log::Error, + "Unsupported base mode"); } } @@ -1474,6 +1541,29 @@ Commander::handle_command(const vehicle_command_s &cmd) answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED); break; + case vehicle_command_s::VEHICLE_CMD_DO_SET_SAFETY_SWITCH_STATE: { + // reject if armed, only allow pre or post flight for safety + if (isArmed()) { + answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED); + + } else { + int commanded_state = (int)cmd.param1; + + if (commanded_state == vehicle_command_s::SAFETY_OFF) { + _safety.deactivateSafety(); + answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED); + + } else if (commanded_state == vehicle_command_s::SAFETY_ON) { + _safety.activateSafety(); + answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED); + + } else { + answer_command(cmd, vehicle_command_ack_s::VEHICLE_CMD_RESULT_FAILED); + } + } + } + break; + case vehicle_command_s::VEHICLE_CMD_START_RX_PAIR: case vehicle_command_s::VEHICLE_CMD_CUSTOM_0: case vehicle_command_s::VEHICLE_CMD_CUSTOM_1: @@ -1515,6 +1605,8 @@ Commander::handle_command(const vehicle_command_s &cmd) case vehicle_command_s::VEHICLE_CMD_DO_GRIPPER: case vehicle_command_s::VEHICLE_CMD_EXTERNAL_POSITION_ESTIMATE: case vehicle_command_s::VEHICLE_CMD_REQUEST_CAMERA_INFORMATION: + case vehicle_command_s::VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE: + case vehicle_command_s::VEHICLE_CMD_DO_AUTOTUNE_ENABLE: /* ignore commands that are handled by other parts of the system */ break; @@ -1767,7 +1859,7 @@ void Commander::run() _power_button_state_sub.copy(&button_state); tune_control_s tune_control{}; - button_state.timestamp = hrt_absolute_time(); + tune_control.timestamp = hrt_absolute_time(); tune_control_pub = orb_advertise(ORB_ID(tune_control), &tune_control); } @@ -1815,7 +1907,8 @@ void Commander::run() _mission_in_progress = (_vehicle_status.nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION) && !_mission_result_sub.get().finished; - _home_position.update(_param_com_home_en.get(), !isArmed() && _vehicle_land_detected.landed && !_mission_in_progress); + _home_position.update(_param_com_home_en.get(), !isArmed() && _vehicle_land_detected.landed && !_mission_in_progress + && !_config_overrides.disable_auto_set_home); handleAutoDisarm(); @@ -1921,20 +2014,7 @@ void Commander::run() _vehicle_status.timestamp = hrt_absolute_time(); _vehicle_status_pub.publish(_vehicle_status); - // failure_detector_status publish - failure_detector_status_s fd_status{}; - fd_status.fd_roll = _failure_detector.getStatusFlags().roll; - fd_status.fd_pitch = _failure_detector.getStatusFlags().pitch; - fd_status.fd_alt = _failure_detector.getStatusFlags().alt; - fd_status.fd_ext = _failure_detector.getStatusFlags().ext; - fd_status.fd_arm_escs = _failure_detector.getStatusFlags().arm_escs; - fd_status.fd_battery = _failure_detector.getStatusFlags().battery; - fd_status.fd_imbalanced_prop = _failure_detector.getStatusFlags().imbalanced_prop; - fd_status.fd_motor = _failure_detector.getStatusFlags().motor; - fd_status.imbalanced_prop_metric = _failure_detector.getImbalancedPropMetric(); - fd_status.motor_failure_mask = _failure_detector.getMotorFailures(); - fd_status.timestamp = hrt_absolute_time(); - _failure_detector_status_pub.publish(fd_status); + _failure_detector.publishStatus(); } checkWorkerThread(); @@ -2118,7 +2198,7 @@ void Commander::landDetectorUpdate() } // automatically set or update home position - if (_param_com_home_en.get() && !_mission_in_progress) { + if (_param_com_home_en.get() && !_mission_in_progress && !_config_overrides.disable_auto_set_home) { // set the home position when taking off if (!_vehicle_land_detected.landed) { if (was_landed) { @@ -2275,35 +2355,19 @@ void Commander::handleAutoDisarm() if (_auto_disarm_landed.get_state() && !_multicopter_throw_launch.isThrowLaunchInProgress()) { if (_have_taken_off_since_arming) { - disarm(arm_disarm_reason_t::auto_disarm_land); + disarm(arm_disarm_reason_t::landing); } else { - disarm(arm_disarm_reason_t::auto_disarm_preflight); + disarm(arm_disarm_reason_t::preflight_inaction); } } } // Auto disarm after 5 seconds if kill switch is engaged - bool auto_disarm = _actuator_armed.kill; - - // auto disarm if locked down to avoid user confusion - // skipped in HITL where lockdown is enabled for safety - if (_vehicle_status.hil_state != vehicle_status_s::HIL_STATE_ON) { - auto_disarm |= _actuator_armed.lockdown; - } - - //don't disarm if throw launch is in progress - auto_disarm &= !_multicopter_throw_launch.isThrowLaunchInProgress(); - - _auto_disarm_killed.set_state_and_update(auto_disarm, hrt_absolute_time()); + _auto_disarm_killed.set_state_and_update(_actuator_armed.kill, hrt_absolute_time()); if (_auto_disarm_killed.get_state()) { - if (_actuator_armed.kill) { - disarm(arm_disarm_reason_t::kill_switch, true); - - } else { - disarm(arm_disarm_reason_t::lockdown, true); - } + disarm(arm_disarm_reason_t::kill_switch, true); } } else { @@ -3018,6 +3082,8 @@ The commander module contains the state machine for mode switching and failsafe PRINT_MODULE_USAGE_ARG("mag|baro|accel|gyro|level|esc|airspeed", "Calibration type", false); PRINT_MODULE_USAGE_ARG("quick", "Quick calibration [mag, accel (not recommended)]", false); PRINT_MODULE_USAGE_COMMAND_DESCR("check", "Run preflight checks"); + PRINT_MODULE_USAGE_COMMAND_DESCR("safety", "Change prearm safety state"); + PRINT_MODULE_USAGE_ARG("on|off", "[on] to activate safety, [off] to deactivate safety and allow control surface movements", false); PRINT_MODULE_USAGE_COMMAND("arm"); PRINT_MODULE_USAGE_PARAM_FLAG('f', "Force arming (do not run preflight checks)", true); PRINT_MODULE_USAGE_COMMAND("disarm"); @@ -3026,7 +3092,7 @@ The commander module contains the state machine for mode switching and failsafe PRINT_MODULE_USAGE_COMMAND("land"); PRINT_MODULE_USAGE_COMMAND_DESCR("transition", "VTOL transition"); PRINT_MODULE_USAGE_COMMAND_DESCR("mode", "Change flight mode"); - PRINT_MODULE_USAGE_ARG("manual|acro|offboard|stabilized|altctl|posctl|position:slow|auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1", + PRINT_MODULE_USAGE_ARG("manual|acro|offboard|stabilized|altctl|posctl|altitude_cruise|position:slow|auto:mission|auto:loiter|auto:rtl|auto:takeoff|auto:land|auto:precland|ext1", "Flight mode", false); PRINT_MODULE_USAGE_COMMAND("pair"); PRINT_MODULE_USAGE_COMMAND("termination"); @@ -3034,6 +3100,8 @@ The commander module contains the state machine for mode switching and failsafe PRINT_MODULE_USAGE_COMMAND("set_ekf_origin"); PRINT_MODULE_USAGE_ARG("lat, lon, alt", "Origin Latitude, Longitude, Altitude", false); PRINT_MODULE_USAGE_COMMAND_DESCR("lat|lon|alt", "Origin latitude longitude altitude"); + PRINT_MODULE_USAGE_COMMAND_DESCR("set_heading", "Set current heading"); + PRINT_MODULE_USAGE_ARG("heading", "degrees from True North [0 360]", false); PRINT_MODULE_USAGE_COMMAND_DESCR("poweroff", "Power off board (if supported)"); #endif PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); diff --git a/src/modules/commander/Commander.hpp b/src/modules/commander/Commander.hpp index 1d7841cdc8..e4f0fef7ca 100644 --- a/src/modules/commander/Commander.hpp +++ b/src/modules/commander/Commander.hpp @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -230,7 +229,7 @@ private: _health_and_arming_checks.externalChecks() #endif }; - UserModeIntention _user_mode_intention {this, _vehicle_status, _health_and_arming_checks, &_mode_management}; + UserModeIntention _user_mode_intention {_vehicle_status, _health_and_arming_checks, &_mode_management}; const failsafe_flags_s &_failsafe_flags{_health_and_arming_checks.failsafeFlags()}; HomePosition _home_position{_failsafe_flags}; @@ -313,7 +312,6 @@ private: // Publications uORB::Publication _actuator_armed_pub{ORB_ID(actuator_armed)}; uORB::Publication _actuator_test_pub{ORB_ID(actuator_test)}; - uORB::Publication _failure_detector_status_pub{ORB_ID(failure_detector_status)}; uORB::Publication _vehicle_command_ack_pub{ORB_ID(vehicle_command_ack)}; uORB::Publication _vehicle_command_pub{ORB_ID(vehicle_command)}; uORB::Publication _vehicle_control_mode_pub{ORB_ID(vehicle_control_mode)}; diff --git a/src/modules/commander/HealthAndArmingChecks/checks/airspeedCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/airspeedCheck.cpp index 8836febb8d..48c2dc8261 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/airspeedCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/airspeedCheck.cpp @@ -54,9 +54,9 @@ void AirspeedChecks::checkAndReport(const Context &context, Report &reporter) reporter.setIsPresent(health_component_t::differential_pressure); - const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_1 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_2 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_3; + const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_1 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_2 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_3; const float airspeed_calibrated_from_sensor = airspeed_from_sensor ? airspeed_validated.calibrated_airspeed_m_s : NAN; diff --git a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp index 9b35c80992..7bc47dc855 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.cpp @@ -82,7 +82,7 @@ void EscChecks::checkAndReport(const Context &context, Report &reporter) checkEscStatus(context, reporter, esc_status); reporter.setIsPresent(health_component_t::motors_escs); - } else if (_param_escs_checks_required.get() + } else if (_param_com_arm_chk_escs.get() && now - _start_time > 5_s) { // Wait a bit after startup to allow esc's to init /* EVENT @@ -102,40 +102,37 @@ void EscChecks::checkAndReport(const Context &context, Report &reporter) void EscChecks::checkEscStatus(const Context &context, Report &reporter, const esc_status_s &esc_status) { - const NavModes required_modes = _param_escs_checks_required.get() ? NavModes::All : NavModes::None; + const NavModes required_modes = _param_com_arm_chk_escs.get() ? NavModes::All : NavModes::None; if (esc_status.esc_count > 0) { - + // Check if one or more the ESCs are offline char esc_fail_msg[50]; esc_fail_msg[0] = '\0'; - int online_bitmask = (1 << esc_status.esc_count) - 1; + for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { + const bool mapped = math::isInRange(esc_status.esc[i].actuator_function, actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1, + uint8_t(actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + actuator_motors_s::NUM_CONTROLS - 1)); + const bool offline = (esc_status.esc_online_flags & (1 << i)) == 0; - // Check if one or more the ESCs are offline - if (online_bitmask != esc_status.esc_online_flags) { - - for (int index = 0; index < esc_status.esc_count; index++) { - if ((esc_status.esc_online_flags & (1 << index)) == 0) { - uint8_t motor_index = esc_status.esc[index].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + 1; - /* EVENT - * @description - * - * This check can be configured via COM_ARM_CHK_ESCS parameter. - * - */ - reporter.healthFailure(required_modes, health_component_t::motors_escs, events::ID("check_escs_offline"), - events::Log::Critical, "ESC {1} offline", motor_index); - snprintf(esc_fail_msg + strlen(esc_fail_msg), sizeof(esc_fail_msg) - strlen(esc_fail_msg), "ESC%d ", motor_index); - esc_fail_msg[sizeof(esc_fail_msg) - 1] = '\0'; - } - } - - if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "%soffline. %s\t", esc_fail_msg, context.isArmed() ? "Land now!" : ""); + if (mapped && offline) { + /* EVENT + * @description + * + * This check can be configured via COM_ARM_CHK_ESCS parameter. + * + */ + reporter.healthFailure(required_modes, health_component_t::motors_escs, events::ID("check_escs_offline"), + events::Log::Critical, "ESC {1} offline", i + 1); + snprintf(esc_fail_msg + strlen(esc_fail_msg), sizeof(esc_fail_msg) - strlen(esc_fail_msg), "ESC%d ", i + 1); + esc_fail_msg[sizeof(esc_fail_msg) - 1] = '\0'; } } - for (int index = 0; index < esc_status.esc_count; index++) { + if ((esc_fail_msg[0] != '\0') && reporter.mavlink_log_pub()) { + mavlink_log_critical(reporter.mavlink_log_pub(), "%soffline. %s\t", esc_fail_msg, context.isArmed() ? "Land now!" : ""); + } + + for (int index = 0; index < math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); ++index) { if (esc_status.esc[index].failures != 0) { diff --git a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp index 7e32563e46..a96c147234 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/escCheck.hpp @@ -54,6 +54,6 @@ private: const hrt_abstime _start_time{hrt_absolute_time()}; DEFINE_PARAMETERS_CUSTOM_PARENT(HealthAndArmingCheckBase, - (ParamBool) _param_escs_checks_required + (ParamBool) _param_com_arm_chk_escs ) }; diff --git a/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.cpp index 2b90f78c84..010cbacf7f 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.cpp @@ -272,6 +272,22 @@ void EstimatorChecks::checkEstimatorStatus(const Context &context, Report &repor _gnss_spoofed = false; } + if (estimator_status.gps_check_fail_flags & (1 << estimator_status_s::GPS_CHECK_FAIL_JAMMED)) { + if (!_gnss_jammed) { + _gnss_jammed = true; + + if (reporter.mavlink_log_pub()) { + mavlink_log_critical(reporter.mavlink_log_pub(), "GNSS signal jammed\t"); + } + + events::send(events::ID("check_estimator_gnss_warning_jamming"), {events::Log::Alert, events::LogInternal::Info}, + "GNSS signal jammed"); + } + + } else { + _gnss_jammed = false; + } + if (!context.isArmed() && ekf_gps_check_fail) { NavModesMessageFail required_modes; events::Log log_level; @@ -435,6 +451,18 @@ void EstimatorChecks::checkEstimatorStatus(const Context &context, Report &repor events::ID("check_estimator_gps_spoofed"), log_level, "GPS signal spoofed"); + } else if (estimator_status.gps_check_fail_flags & (1 << estimator_status_s::GPS_CHECK_FAIL_JAMMED)) { + message = "Preflight%s: GPS signal jammed"; + /* EVENT + * @description + * + * Can be configured with EKF2_GPS_CHECK and COM_ARM_WO_GPS. + * + */ + reporter.armingCheckFailure(required_modes, health_component_t::gps, + events::ID("check_estimator_gps_jammed"), + log_level, "GPS signal jammed"); + } else { if (!ekf_gps_fusion) { // Likely cause unknown @@ -594,15 +622,15 @@ void EstimatorChecks::checkEstimatorStatusFlags(const Context &context, Report & void EstimatorChecks::checkGps(const Context &context, Report &reporter, const sensor_gps_s &vehicle_gps_position) const { - if (vehicle_gps_position.jamming_state == sensor_gps_s::JAMMING_STATE_CRITICAL) { + if (vehicle_gps_position.jamming_state == sensor_gps_s::JAMMING_STATE_DETECTED) { /* EVENT */ reporter.armingCheckFailure(NavModes::None, health_component_t::gps, events::ID("check_estimator_gps_jamming_critical"), - events::Log::Critical, "GPS reports critical jamming state"); + events::Log::Critical, "GPS jamming detected"); if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "GPS reports critical jamming state\t"); + mavlink_log_critical(reporter.mavlink_log_pub(), "GPS jamming detected\t"); } } } @@ -621,8 +649,7 @@ void EstimatorChecks::lowPositionAccuracy(const Context &context, Report &report position_valid_but_low_accuracy = (_param_com_low_eph.get() > FLT_EPSILON && lpos.eph > _param_com_low_eph.get()); } - if (!reporter.failsafeFlags().position_accuracy_low && position_valid_but_low_accuracy - && _param_com_pos_low_act.get()) { + if (position_valid_but_low_accuracy && _param_com_pos_low_act.get()) { // only report if armed if (context.isArmed()) { diff --git a/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.hpp index 13b351c986..afbea3d481 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/estimatorCheck.hpp @@ -103,6 +103,7 @@ private: bool _gps_was_fused{false}; bool _gnss_spoofed{false}; + bool _gnss_jammed{false}; bool _nav_failure_imminent_warned{false}; diff --git a/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.cpp index 863b7e9b6b..cbd59351ba 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.cpp @@ -86,9 +86,21 @@ void PowerChecks::checkAndReport(const Context &context, Report &reporter) const float high_error_threshold = 5.4f; const auto now = hrt_absolute_time(); + + bool old_state_low = _voltage_low_hysteresis.get_state(); + bool old_state_high = _voltage_high_hysteresis.get_state(); + _voltage_low_hysteresis.set_state_and_update(avionics_power_rail_voltage < low_error_threshold, now); _voltage_high_hysteresis.set_state_and_update(avionics_power_rail_voltage > high_error_threshold, now); + if (_voltage_low_hysteresis.get_state() && !old_state_low) { + _latest_low_failure_val = avionics_power_rail_voltage; + } + + if (_voltage_high_hysteresis.get_state() && !old_state_high) { + _latest_high_failure_val = avionics_power_rail_voltage; + } + if (_voltage_low_hysteresis.get_state()) { /* EVENT @@ -101,11 +113,11 @@ void PowerChecks::checkAndReport(const Context &context, Report &reporter) */ reporter.healthFailure(NavModes::All, health_component_t::system, events::ID("check_avionics_power_low"), - events::Log::Error, "Avionics Power low: {1:.2} Volt", avionics_power_rail_voltage, low_error_threshold); + events::Log::Error, "Avionics Power low: {1:.2} Volt", _latest_low_failure_val, low_error_threshold); if (reporter.mavlink_log_pub()) { mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Avionics Power low: %6.2f Volt", - (double)avionics_power_rail_voltage); + (double)_latest_low_failure_val); } } else if (_voltage_high_hysteresis.get_state()) { @@ -119,11 +131,11 @@ void PowerChecks::checkAndReport(const Context &context, Report &reporter) */ reporter.healthFailure(NavModes::All, health_component_t::system, events::ID("check_avionics_power_high"), - events::Log::Error, "Avionics Power high: {1:.2} Volt", avionics_power_rail_voltage, high_error_threshold); + events::Log::Error, "Avionics Power high: {1:.2} Volt", _latest_high_failure_val, high_error_threshold); if (reporter.mavlink_log_pub()) { mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Avionics Power high: %6.2f Volt", - (double)avionics_power_rail_voltage); + (double)_latest_high_failure_val); } } diff --git a/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.hpp index 76d8b9aae0..e14d75d67e 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/powerCheck.hpp @@ -57,4 +57,7 @@ private: (ParamInt) _param_cbrk_supply_chk, (ParamInt) _param_com_power_count ) + + float _latest_low_failure_val = 0.0f; + float _latest_high_failure_val = 0.0f; }; diff --git a/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.cpp index e41d3c0653..f16505e4a2 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * Copyright (c) 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,11 +33,6 @@ #include "rcCalibrationCheck.hpp" -/** - * Maximum deadzone value - */ -#define RC_INPUT_MAX_DEADZONE_US 500 - /** * Minimum value */ @@ -61,9 +56,6 @@ RcCalibrationChecks::RcCalibrationChecks() snprintf(nbuf, sizeof(nbuf), "RC%d_MAX", i + 1); _param_handles[i].max = param_find(nbuf); - - snprintf(nbuf, sizeof(nbuf), "RC%d_DZ", i + 1); - _param_handles[i].dz = param_find(nbuf); } updateParams(); @@ -75,7 +67,8 @@ void RcCalibrationChecks::checkAndReport(const Context &context, Report &reporte return; } - if (_param_com_rc_in_mode.get() != 0 && _param_com_rc_in_mode.get() != 2 && _param_com_rc_in_mode.get() != 3) { + // return early when stick input from RC is disabled (MAVLink only or manual control disabled) + if (_param_com_rc_in_mode.get() == 1 || _param_com_rc_in_mode.get() == 4) { return; } @@ -83,7 +76,6 @@ void RcCalibrationChecks::checkAndReport(const Context &context, Report &reporte float param_min = _param_values[i].min; float param_max = _param_values[i].max; float param_trim = _param_values[i].trim; - float param_dz = _param_values[i].dz; /* assert min..center..max ordering */ if (param_min < RC_INPUT_LOWEST_MIN_US) { @@ -147,22 +139,6 @@ void RcCalibrationChecks::checkAndReport(const Context &context, Report &reporte (int)param_trim, (int)param_max); } } - - /* assert deadzone is sane */ - if (param_dz > RC_INPUT_MAX_DEADZONE_US) { - /* EVENT - * @description - * Recalibrate the RC. - */ - reporter.armingCheckFailure(NavModes::All, health_component_t::remote_control, - events::ID("check_rc_dz_too_high"), - events::Log::Error, "RC calibration for channel {1} invalid: DZ greater than {2}", i + 1, RC_INPUT_MAX_DEADZONE_US); - - if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: RC ERROR: RC%d_DZ > %u", i + 1, - RC_INPUT_MAX_DEADZONE_US); - } - } } } @@ -175,11 +151,9 @@ void RcCalibrationChecks::updateParams() _param_values[i].min = 0.0f; _param_values[i].max = 0.0f; _param_values[i].trim = 0.0f; - _param_values[i].dz = RC_INPUT_MAX_DEADZONE_US * 2.0f; param_get(_param_handles[i].min, &_param_values[i].min); param_get(_param_handles[i].trim, &_param_values[i].trim); param_get(_param_handles[i].max, &_param_values[i].max); - param_get(_param_handles[i].dz, &_param_values[i].dz); } } diff --git a/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.hpp index 6a2d30a83f..d0b4a80d8d 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/rcCalibrationCheck.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2022 PX4 Development Team. All rights reserved. + * Copyright (c) 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,13 +53,11 @@ private: param_t min; param_t trim; param_t max; - param_t dz; }; struct ParamValues { float min; float trim; float max; - float dz; }; ParamHandles _param_handles[input_rc_s::RC_INPUT_MAX_CHANNELS]; diff --git a/src/modules/commander/HomePosition.cpp b/src/modules/commander/HomePosition.cpp index 3825ffe9f5..4eb0f068de 100644 --- a/src/modules/commander/HomePosition.cpp +++ b/src/modules/commander/HomePosition.cpp @@ -40,7 +40,9 @@ #include "commander_helper.h" HomePosition::HomePosition(const failsafe_flags_s &failsafe_flags): ModuleParams(nullptr), - _failsafe_flags(failsafe_flags) {} + _failsafe_flags(failsafe_flags), + _param_ekf2_gps_ctrl_handle(param_find("EKF2_GPS_CTRL")) +{} bool HomePosition::hasMovedFromCurrentHomeLocation() { @@ -299,6 +301,19 @@ void HomePosition::setHomePosValid() _valid = true; } +bool HomePosition::isGpsHorizontalFusionEnabled() +{ + // If parameter doesn't exist, allow GPS usage + if (_param_ekf2_gps_ctrl_handle == PARAM_INVALID) { + return true; + } + + // Check if bit 0 (horizontal position fusion) is set + int32_t ekf2_gps_ctrl = 0; + param_get(_param_ekf2_gps_ctrl_handle, &ekf2_gps_ctrl); + return (ekf2_gps_ctrl & 1); +} + void HomePosition::updateHomePositionYaw(float yaw) { home_position_s home = _home_position_pub.get(); @@ -348,7 +363,8 @@ void HomePosition::update(bool set_automatically, bool check_if_changed) const bool epv_valid = vehicle_gps_position.epv < kHomePositionGPSRequiredEPV; const bool evh_valid = vehicle_gps_position.s_variance_m_s < kHomePositionGPSRequiredEVH; - _gps_position_for_home_valid = time_valid && fix_valid && eph_valid && epv_valid && evh_valid; + _gps_position_for_home_valid = time_valid && fix_valid && eph_valid && epv_valid && evh_valid + && isGpsHorizontalFusionEnabled(); if (_param_com_home_en.get() && _gps_position_for_home_valid && _last_gps_timestamp != 0 && _last_baro_timestamp != 0 && _takeoff_time != 0 && now < _takeoff_time + kHomePositionCorrectionTimeWindow) { diff --git a/src/modules/commander/HomePosition.hpp b/src/modules/commander/HomePosition.hpp index dd218c902e..fd5eb1e72d 100644 --- a/src/modules/commander/HomePosition.hpp +++ b/src/modules/commander/HomePosition.hpp @@ -74,6 +74,7 @@ public: private: bool hasMovedFromCurrentHomeLocation(); + bool isGpsHorizontalFusionEnabled(); void setHomePosValid(); void updateHomePositionYaw(float yaw); @@ -113,4 +114,5 @@ private: DEFINE_PARAMETERS( (ParamBool) _param_com_home_en ) + param_t _param_ekf2_gps_ctrl_handle{PARAM_INVALID}; }; diff --git a/src/modules/commander/ModeManagement.cpp b/src/modules/commander/ModeManagement.cpp index b26bb99993..b7212f05b8 100644 --- a/src/modules/commander/ModeManagement.cpp +++ b/src/modules/commander/ModeManagement.cpp @@ -107,7 +107,7 @@ uint8_t Modes::addExternalMode(const Modes::Mode &mode) int matching_idx = -1; for (int i = 0; i < MAX_NUM; ++i) { - char hash_param_name[20]; + char hash_param_name[17]; snprintf(hash_param_name, sizeof(hash_param_name), "COM_MODE%d_HASH", i); const param_t handle = param_find(hash_param_name); int32_t current_hash{}; @@ -164,7 +164,7 @@ uint8_t Modes::addExternalMode(const Modes::Mode &mode) if (new_mode_idx != -1 && !_modes[new_mode_idx].valid) { if (need_to_update_param) { - char hash_param_name[20]; + char hash_param_name[17]; snprintf(hash_param_name, sizeof(hash_param_name), "COM_MODE%d_HASH", new_mode_idx); const param_t handle = param_find(hash_param_name); @@ -232,6 +232,7 @@ void ModeManagement::checkNewRegistrations(UpdateRequest &update_request) static_assert(sizeof(request.name) == sizeof(reply.name), "size mismatch"); memcpy(reply.name, request.name, sizeof(request.name)); reply.request_id = request.request_id; + reply.not_user_selectable = request.not_user_selectable; reply.px4_ros2_api_version = register_ext_component_request_s::LATEST_PX4_ROS2_API_VERSION; // validate @@ -562,6 +563,10 @@ void ModeManagement::updateActiveConfigOverrides(uint8_t nav_state, config_overr current_overrides.disable_auto_disarm = true; } + if (executor_overrides.disable_auto_set_home) { + current_overrides.disable_auto_set_home = true; + } + if (executor_overrides.defer_failsafes) { current_overrides.defer_failsafes = true; current_overrides.defer_failsafes_timeout_s = executor_overrides.defer_failsafes_timeout_s; diff --git a/src/modules/commander/ModeUtil/control_mode.cpp b/src/modules/commander/ModeUtil/control_mode.cpp index fbebc7b93d..59858a51e8 100644 --- a/src/modules/commander/ModeUtil/control_mode.cpp +++ b/src/modules/commander/ModeUtil/control_mode.cpp @@ -63,6 +63,7 @@ void getVehicleControlMode(uint8_t nav_state, uint8_t vehicle_type, break; case vehicle_status_s::NAVIGATION_STATE_ALTCTL: + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: vehicle_control_mode.flag_control_manual_enabled = true; vehicle_control_mode.flag_control_altitude_enabled = true; vehicle_control_mode.flag_control_climb_rate_enabled = true; diff --git a/src/modules/commander/ModeUtil/conversions.hpp b/src/modules/commander/ModeUtil/conversions.hpp index 045db4570f..e6bb4e2102 100644 --- a/src/modules/commander/ModeUtil/conversions.hpp +++ b/src/modules/commander/ModeUtil/conversions.hpp @@ -50,6 +50,8 @@ static inline navigation_mode_t navigation_mode(uint8_t nav_state) case vehicle_status_s::NAVIGATION_STATE_ALTCTL: return navigation_mode_t::altctl; + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: return navigation_mode_t::altitude_cruise; + case vehicle_status_s::NAVIGATION_STATE_POSCTL: return navigation_mode_t::posctl; case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION: return navigation_mode_t::auto_mission; diff --git a/src/modules/commander/ModeUtil/mode_requirements.cpp b/src/modules/commander/ModeUtil/mode_requirements.cpp index 9e64c529f2..850a0cf6e9 100644 --- a/src/modules/commander/ModeUtil/mode_requirements.cpp +++ b/src/modules/commander/ModeUtil/mode_requirements.cpp @@ -69,6 +69,13 @@ void getModeRequirements(uint8_t vehicle_type, failsafe_flags_s &flags) setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTCTL, flags.mode_req_local_alt); setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTCTL, flags.mode_req_manual_control); + // NAVIGATION_STATE_ALTITUDE_CRUISE + setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE, flags.mode_req_angular_velocity); + setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE, flags.mode_req_attitude); + setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE, flags.mode_req_local_alt); + setRequirement(vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE, + flags.mode_req_manual_control); // COM_RCL_EXCEPT can override this + // NAVIGATION_STATE_POSCTL setRequirement(vehicle_status_s::NAVIGATION_STATE_POSCTL, flags.mode_req_angular_velocity); setRequirement(vehicle_status_s::NAVIGATION_STATE_POSCTL, flags.mode_req_attitude); diff --git a/src/modules/commander/Safety.cpp b/src/modules/commander/Safety.cpp index 8abf304535..51419db6a2 100644 --- a/src/modules/commander/Safety.cpp +++ b/src/modules/commander/Safety.cpp @@ -76,3 +76,10 @@ void Safety::activateSafety() _safety_off = false; } } + +void Safety::deactivateSafety() +{ + if (!_safety_disabled) { + _safety_off = true; + } +} diff --git a/src/modules/commander/Safety.hpp b/src/modules/commander/Safety.hpp index 6d52c797ac..971ea702ea 100644 --- a/src/modules/commander/Safety.hpp +++ b/src/modules/commander/Safety.hpp @@ -49,6 +49,7 @@ public: bool safetyButtonHandler(); void activateSafety(); + void deactivateSafety(); bool isButtonAvailable() const { return _button_available; } bool isSafetyOff() const { return _safety_off; } bool isSafetyDisabled() const { return _safety_disabled; } diff --git a/src/modules/commander/UserModeIntention.cpp b/src/modules/commander/UserModeIntention.cpp index 086f9501b3..2085995d6c 100644 --- a/src/modules/commander/UserModeIntention.cpp +++ b/src/modules/commander/UserModeIntention.cpp @@ -34,9 +34,9 @@ #include "UserModeIntention.hpp" -UserModeIntention::UserModeIntention(ModuleParams *parent, const vehicle_status_s &vehicle_status, +UserModeIntention::UserModeIntention(const vehicle_status_s &vehicle_status, const HealthAndArmingChecks &health_and_arming_checks, ModeChangeHandler *handler) - : ModuleParams(parent), _vehicle_status(vehicle_status), _health_and_arming_checks(health_and_arming_checks), + : _vehicle_status(vehicle_status), _health_and_arming_checks(health_and_arming_checks), _handler(handler) { } @@ -59,7 +59,7 @@ bool UserModeIntention::change(uint8_t user_intended_nav_state, ModeChangeSource allow_change = _health_and_arming_checks.canRun(user_intended_nav_state); // Check fallback - if (!allow_change && allow_fallback && _param_com_posctl_navl.get() == 0) { + if (!allow_change && allow_fallback) { if (user_intended_nav_state == vehicle_status_s::NAVIGATION_STATE_POSCTL) { allow_change = _health_and_arming_checks.canRun(vehicle_status_s::NAVIGATION_STATE_ALTCTL); // We still use the original user intended mode. The failsafe state machine will then set the @@ -77,7 +77,8 @@ bool UserModeIntention::change(uint8_t user_intended_nav_state, ModeChangeSource // Special case termination state: even though this mode prevents arming, // still don't switch out of it after disarm and thus store it in _nav_state_after_disarming. - if (!_health_and_arming_checks.modePreventsArming(user_intended_nav_state) + if ((!_health_and_arming_checks.modePreventsArming(user_intended_nav_state) + && !isTakeOffIntended(user_intended_nav_state)) || user_intended_nav_state == vehicle_status_s::NAVIGATION_STATE_TERMINATION) { _nav_state_after_disarming = user_intended_nav_state; } diff --git a/src/modules/commander/UserModeIntention.hpp b/src/modules/commander/UserModeIntention.hpp index b8b6827e06..e37bf467b1 100644 --- a/src/modules/commander/UserModeIntention.hpp +++ b/src/modules/commander/UserModeIntention.hpp @@ -35,7 +35,6 @@ #include #include "HealthAndArmingChecks/HealthAndArmingChecks.hpp" -#include enum class ModeChangeSource { User, ///< RC or MAVLink @@ -58,10 +57,10 @@ public: }; -class UserModeIntention : ModuleParams +class UserModeIntention { public: - UserModeIntention(ModuleParams *parent, const vehicle_status_s &vehicle_status, + UserModeIntention(const vehicle_status_s &vehicle_status, const HealthAndArmingChecks &health_and_arming_checks, ModeChangeHandler *handler); ~UserModeIntention() = default; @@ -92,6 +91,7 @@ public: private: bool isArmed() const { return _vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED; } + bool isTakeOffIntended(uint8_t user_intented_nav_state) const {return user_intented_nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF || user_intented_nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF;} const vehicle_status_s &_vehicle_status; const HealthAndArmingChecks &_health_and_arming_checks; @@ -102,8 +102,4 @@ private: bool _ever_had_mode_change{false}; ///< true if there was ever a mode change call (also if the same mode as already set) bool _had_mode_change{false}; ///< true if there was a mode change call since the last getHadModeChangeAndClear() - - DEFINE_PARAMETERS( - (ParamInt) _param_com_posctl_navl - ); }; diff --git a/src/modules/commander/accelerometer_calibration.cpp b/src/modules/commander/accelerometer_calibration.cpp index ba8bc59b3e..13990e01c9 100644 --- a/src/modules/commander/accelerometer_calibration.cpp +++ b/src/modules/commander/accelerometer_calibration.cpp @@ -366,17 +366,24 @@ int do_accel_calibration(orb_advert_t *mavlink_log_pub) const Matrix3f accel_T = mat_A.I() * CONSTANTS_ONE_G; // update calibration - worker_data.calibration[i].set_offset(offset); - worker_data.calibration[i].set_scale(accel_T.diag()); + const Dcmf &R = worker_data.calibration[i].rotation(); + + const Vector3f sensor_frame_offsets{R.transpose() *offset}; + const Matrix3f sensor_frame_scale{R.transpose() *accel_T * R}; + + worker_data.calibration[i].set_offset(sensor_frame_offsets); + worker_data.calibration[i].set_scale(sensor_frame_scale.diag()); #if defined(DEBUD_BUILD) PX4_INFO("accel %d: offset", i); - offset.print(); + sensor_frame_offsets.print(); PX4_INFO("accel %d: mat_A", i); mat_A.print(); PX4_INFO("accel %d: accel_T", i); accel_T.print(); + PX4_INFO("accel %d: scale matrix", i); + sensor_frame_scale.print(); #endif // DEBUD_BUILD worker_data.calibration[i].PrintStatus(); diff --git a/src/modules/commander/commander_params.c b/src/modules/commander/commander_params.c index 565c6406be..eb3c2109e4 100644 --- a/src/modules/commander/commander_params.c +++ b/src/modules/commander/commander_params.c @@ -166,41 +166,38 @@ PARAM_DEFINE_INT32(COM_HOME_EN, 1); PARAM_DEFINE_INT32(COM_HOME_IN_AIR, 0); /** - * RC control input mode + * Manual control input source configuration * - * A value of 0 enables RC transmitter control (only). A valid RC transmitter calibration is required. - * A value of 1 allows joystick control only. RC input handling and the associated checks are disabled. - * A value of 2 allows either RC Transmitter or Joystick input. The first valid input is used, will fallback to other sources if the input stream becomes invalid. - * A value of 3 allows either input from RC or joystick. The first available source is selected and used until reboot. - * A value of 4 ignores any stick input. - * A value of 5 allows either RC Transmitter or Joystick input. But RC has priority and whenever avaiable is immedietely used. - * A value of 6 allows either RC Transmitter or Joystick input. But Joystick has priority and whenever avaiable is immedietely used. + * Selects stick input selection behavior: + * either a traditional remote control receiver (RC) or a MAVLink joystick (MANUAL_CONTROL message) + * + * Priority sources are immediately switched to whenever they get valid. + * + * 0 RC only. Requires valid RC calibration. + * 1 MAVLink only. RC and related checks are disabled. + * 2 Switches only if current source becomes invalid. + * 3 Locks to the first valid source until reboot. + * 4 Ignores all sources. + * 5 RC priority, then MAVLink (lower instance before higher) + * 6 MAVLink priority (lower instance before higher), then RC + * 7 RC priority, then MAVLink (higher instance before lower) + * 8 MAVLink priority (higher instance before lower), then RC * * @group Commander * @min 0 - * @max 4 - * @value 0 RC Transmitter only - * @value 1 Joystick only - * @value 2 RC and Joystick with fallback - * @value 3 RC or Joystick keep first - * @value 4 Stick input disabled - * @value 5 RC priority, Joystick fallback - * @value 6 Joystick priority, RC fallback + * @max 8 + * @value 0 RC only + * @value 1 MAVLink only + * @value 2 RC or MAVLink with fallback + * @value 3 RC or MAVLink keep first + * @value 4 Disable manual control + * @value 5 Prio: RC > MAVL 1 > MAVL 2 + * @value 6 Prio: MAVL 1 > MAVL 2 > RC + * @value 7 Prio: RC > MAVL 2 > MAVL 1 + * @value 8 Prio: MAVL 2 > MAVL 1 > RC */ PARAM_DEFINE_INT32(COM_RC_IN_MODE, 3); -/** - * Manual control input arm/disarm command duration - * - * The default value of 1000 requires the stick to be held in the arm or disarm position for 1 second. - * - * @group Commander - * @min 100 - * @max 1500 - * @unit ms - */ -PARAM_DEFINE_INT32(COM_RC_ARM_HYST, 1000); - /** * Time-out for auto disarm after landing * @@ -234,14 +231,16 @@ PARAM_DEFINE_FLOAT(COM_DISARM_LAND, 2.0f); PARAM_DEFINE_FLOAT(COM_DISARM_PRFLT, 10.0f); /** - * GPS preflight check + * Arming without GNSS configuration * - * Measures taken when a check defined by EKF2_GPS_CHECK is failing. + * Configures whether arming is allowed without GNSS, for modes that require a global position + * (specifically, in those modes when a check defined by EKF2_GPS_CHECK fails). + * The settings deny arming and warn, allow arming and warn, or silently allow arming. * * @group Commander * @value 0 Deny arming - * @value 1 Warning only - * @value 2 Disabled + * @value 1 Allow arming (with warning) + * @value 2 Allow arming (no warning) */ PARAM_DEFINE_INT32(COM_ARM_WO_GPS, 1); @@ -249,8 +248,7 @@ PARAM_DEFINE_INT32(COM_ARM_WO_GPS, 1); * Arm switch is a momentary button * * 0: Arming/disarming triggers on switch transition. - * 1: Arming/disarming triggers when holding the momentary button down - * for COM_RC_ARM_HYST like the stick gesture. + * 1: Arming/disarming triggers when holding the momentary button down like the stick gesture. * * @group Commander * @boolean @@ -461,18 +459,6 @@ PARAM_DEFINE_FLOAT(COM_RC_STICK_OV, 30.0f); */ PARAM_DEFINE_INT32(COM_ARM_MIS_REQ, 0); -/** - * Position mode navigation loss response - * - * This sets the flight mode that will be used if navigation accuracy is no longer adequate for position control in manual Position mode. - * - * @value 0 Altitude mode - * @value 1 Land mode (descend) - * - * @group Commander - */ -PARAM_DEFINE_INT32(COM_POSCTL_NAVL, 0); - /** * Require arm authorization to arm * @@ -621,15 +607,17 @@ PARAM_DEFINE_INT32(NAV_RCL_ACT, 2); /** * Manual control loss exceptions * - * Specify modes where manual control loss is ignored and no failsafe is triggered. + * Specify modes in which stick input is ignored and no failsafe action is triggered. * External modes requiring stick input will still failsafe. + * Auto modes are: Hold, Takeoff, Land, RTL, Descend, Follow Target, Precland, Orbit. * * @min 0 - * @max 15 + * @max 31 * @bit 0 Mission - * @bit 1 Hold + * @bit 1 Auto modes * @bit 2 Offboard * @bit 3 External Mode + * @bit 4 Altitude Cruise * @group Commander */ PARAM_DEFINE_INT32(COM_RCL_EXCEPT, 0); @@ -637,13 +625,16 @@ PARAM_DEFINE_INT32(COM_RCL_EXCEPT, 0); /** * Datalink loss exceptions * - * Specify modes in which datalink loss is ignored and the failsafe action not triggered. + * Specify modes in which ground control station connection loss is ignored and no failsafe action is triggered. + * See also COM_RCL_EXCEPT. * * @min 0 - * @max 7 + * @max 31 * @bit 0 Mission - * @bit 1 Hold + * @bit 1 Auto modes * @bit 2 Offboard + * @bit 3 External Mode + * @bit 4 Altitude Cruise * @group Commander */ PARAM_DEFINE_INT32(COM_DLL_EXCEPT, 0); diff --git a/src/modules/commander/failsafe/emscripten_template.html b/src/modules/commander/failsafe/emscripten_template.html index 1b21012de6..0e90830ee2 100644 --- a/src/modules/commander/failsafe/emscripten_template.html +++ b/src/modules/commander/failsafe/emscripten_template.html @@ -182,21 +182,23 @@ diff --git a/src/modules/commander/failsafe/failsafe.cpp b/src/modules/commander/failsafe/failsafe.cpp index 5c3578fb89..b0c19db29b 100644 --- a/src/modules/commander/failsafe/failsafe.cpp +++ b/src/modules/commander/failsafe/failsafe.cpp @@ -442,18 +442,53 @@ FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int par return options; } +bool Failsafe::isFailsafeIgnored(uint8_t user_intended_mode, int32_t exception_mask_parameter) +{ + switch (user_intended_mode) { + case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION: + return exception_mask_parameter & (int)LinkLossExceptionBits::Mission; + + case vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER: + case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF: + case vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF: + case vehicle_status_s::NAVIGATION_STATE_AUTO_LAND: + case vehicle_status_s::NAVIGATION_STATE_AUTO_RTL: + case vehicle_status_s::NAVIGATION_STATE_DESCEND: + case vehicle_status_s::NAVIGATION_STATE_AUTO_FOLLOW_TARGET: + case vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND: + case vehicle_status_s::NAVIGATION_STATE_ORBIT: + return exception_mask_parameter & (int)LinkLossExceptionBits::AutoModes; + + case vehicle_status_s::NAVIGATION_STATE_OFFBOARD: + return exception_mask_parameter & (int)LinkLossExceptionBits::Offboard; + + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL1: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL2: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL3: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL4: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL5: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL6: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL7: + case vehicle_status_s::NAVIGATION_STATE_EXTERNAL8: + return exception_mask_parameter & (int)LinkLossExceptionBits::ExternalMode; + + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: + return exception_mask_parameter & (int)LinkLossExceptionBits::AltitudeCruise; + + default: + return false; + } +} + void Failsafe::checkStateAndMode(const hrt_abstime &time_us, const State &state, const failsafe_flags_s &status_flags) { updateArmingState(time_us, state.armed, status_flags); - const bool in_forward_flight = state.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING - || state.vtol_in_transition_mode; - // Do not enter failsafe while doing a vtol takeoff after the vehicle has started a transition and before it reaches the loiter // altitude. The vtol takeoff navigaton mode will set mission_finished to true as soon as the loiter is established - const bool ignore_any_link_loss_vtol_takeoff_fixedwing = state.user_intended_mode == - vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF + const bool in_forward_flight = (state.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) || state.vtol_in_transition_mode; + const bool ignore_any_link_loss_vtol_takeoff_fixedwing = (state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF) && in_forward_flight && !state.mission_finished; // Manual control (RC or joystick) loss @@ -462,56 +497,23 @@ void Failsafe::checkStateAndMode(const hrt_abstime &time_us, const State &state, _manual_control_lost_at_arming = false; } - const bool rc_loss_ignored_mission = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION - && (_param_com_rcl_except.get() & (int)ManualControlLossExceptionBits::Mission); - const bool rc_loss_ignored_loiter = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER - && (_param_com_rcl_except.get() & (int)ManualControlLossExceptionBits::Hold); - const bool rc_loss_ignored_offboard = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_OFFBOARD - && (_param_com_rcl_except.get() & (int)ManualControlLossExceptionBits::Offboard); - const bool rc_loss_ignored_takeoff = (state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF) - && (_param_com_rcl_except.get() & (int)ManualControlLossExceptionBits::Hold); + const bool rc_loss_ignored = isFailsafeIgnored(state.user_intended_mode, _param_com_rcl_except.get()) + || ignore_any_link_loss_vtol_takeoff_fixedwing || _manual_control_lost_at_arming; - const bool rc_loss_ignored_external_mode = - (state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL1 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL2 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL3 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL4 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL5 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL6 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL7 || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_EXTERNAL8) - && (_param_com_rcl_except.get() & (int)ManualControlLossExceptionBits::ExternalMode); - - const bool rc_loss_ignored = rc_loss_ignored_mission || rc_loss_ignored_loiter || rc_loss_ignored_offboard || - rc_loss_ignored_takeoff || rc_loss_ignored_external_mode || ignore_any_link_loss_vtol_takeoff_fixedwing - || _manual_control_lost_at_arming; - - if (_param_com_rc_in_mode.get() != int32_t(RcInMode::StickInputDisabled) && !rc_loss_ignored) { + if (_param_com_rc_in_mode.get() != int32_t(RcInMode::DisableManualControl) && !rc_loss_ignored) { CHECK_FAILSAFE(status_flags, manual_control_signal_lost, fromNavDllOrRclActParam(_param_nav_rcl_act.get()).causedBy(Cause::ManualControlLoss)); } - // GCS connection loss + // Ground control station connection loss const bool dll_loss_ignored_land = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_LAND || state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND; - const bool dll_loss_ignored_mission = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION - && (_param_com_dll_except.get() & (int)DatalinkLossExceptionBits::Mission); - const bool dll_loss_ignored_loiter = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER - && (_param_com_dll_except.get() & (int)DatalinkLossExceptionBits::Hold); - const bool dll_loss_ignored_offboard = state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_OFFBOARD - && (_param_com_dll_except.get() & (int)DatalinkLossExceptionBits::Offboard); - const bool dll_loss_ignored_takeoff = (state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF || - state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF) - && (_param_com_dll_except.get() & (int)DatalinkLossExceptionBits::Hold); - - const bool dll_loss_ignored = dll_loss_ignored_mission || dll_loss_ignored_loiter || dll_loss_ignored_offboard || - dll_loss_ignored_takeoff || ignore_any_link_loss_vtol_takeoff_fixedwing || dll_loss_ignored_land; + const bool dll_loss_ignored = isFailsafeIgnored(state.user_intended_mode, _param_com_dll_except.get()) + || ignore_any_link_loss_vtol_takeoff_fixedwing || dll_loss_ignored_land; if (_param_nav_dll_act.get() != int32_t(gcs_connection_loss_failsafe_mode::Disabled) && !dll_loss_ignored) { - CHECK_FAILSAFE(status_flags, gcs_connection_lost, - fromNavDllOrRclActParam(_param_nav_dll_act.get()).causedBy(Cause::GCSConnectionLoss)); + CHECK_FAILSAFE(status_flags, gcs_connection_lost, fromNavDllOrRclActParam(_param_nav_dll_act.get()).causedBy(Cause::GCSConnectionLoss)); } // VTOL transition failure (quadchute) @@ -528,7 +530,8 @@ void Failsafe::checkStateAndMode(const hrt_abstime &time_us, const State &state, // If manual control loss and GCS connection loss are disabled and we lose both command links and the mission finished, // trigger RTL to avoid losing the vehicle - if ((_param_com_rc_in_mode.get() == int32_t(RcInMode::StickInputDisabled) || rc_loss_ignored_mission) + if ((_param_com_rc_in_mode.get() == int32_t(RcInMode::DisableManualControl) + || isFailsafeIgnored(state.user_intended_mode, _param_com_rcl_except.get())) && _param_nav_dll_act.get() == int32_t(gcs_connection_loss_failsafe_mode::Disabled) && state.mission_finished) { _last_state_mission_control_lost = checkFailsafe(_caller_id_mission_control_lost, _last_state_mission_control_lost, @@ -666,48 +669,31 @@ FailsafeBase::Action Failsafe::checkModeFallback(const failsafe_flags_s &status_ if (action == Action::Disarm) { return action; } - } - // posctrl - switch (position_control_navigation_loss_response(_param_com_posctl_navl.get())) { - case position_control_navigation_loss_response::Altitude_Manual: // AltCtrl/Manual - - // PosCtrl/PositionSlow -> AltCtrl - if ((user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSCTL || - user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSITION_SLOW) - && !modeCanRun(status_flags, user_intended_mode)) { - action = Action::FallbackAltCtrl; - user_intended_mode = vehicle_status_s::NAVIGATION_STATE_ALTCTL; - } - - // AltCtrl -> Stabilized - if (user_intended_mode == vehicle_status_s::NAVIGATION_STATE_ALTCTL - && !modeCanRun(status_flags, user_intended_mode)) { - action = Action::FallbackStab; - user_intended_mode = vehicle_status_s::NAVIGATION_STATE_STAB; - } - - break; - - case position_control_navigation_loss_response::Land_Descend: // Land/Terminate - - // PosCtrl/PositionSlow -> Land - if ((user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSCTL || - user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSITION_SLOW) - && !modeCanRun(status_flags, user_intended_mode)) { - action = Action::Land; - user_intended_mode = vehicle_status_s::NAVIGATION_STATE_AUTO_LAND; - - // Land -> Descend - if (!modeCanRun(status_flags, user_intended_mode)) { - action = Action::Descend; - user_intended_mode = vehicle_status_s::NAVIGATION_STATE_DESCEND; + if (action == Action::FallbackPosCtrl || action == Action::FallbackAltCtrl || action == Action::FallbackStab) { + // Check if RC is available, if not use the mode specified in NAV_RCL_ACT + if (status_flags.manual_control_signal_lost) { + ActionOptions rc_loss_action = fromNavDllOrRclActParam(_param_nav_rcl_act.get()); + action = rc_loss_action.action; } - } - break; + } } + // PosCtrl/PositionSlow -> AltCtrl + if ((user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSCTL || + user_intended_mode == vehicle_status_s::NAVIGATION_STATE_POSITION_SLOW) + && !modeCanRun(status_flags, user_intended_mode)) { + action = Action::FallbackAltCtrl; + user_intended_mode = vehicle_status_s::NAVIGATION_STATE_ALTCTL; + } + + // AltCtrl -> Stabilized + if (user_intended_mode == vehicle_status_s::NAVIGATION_STATE_ALTCTL + && !modeCanRun(status_flags, user_intended_mode)) { + action = Action::FallbackStab; + user_intended_mode = vehicle_status_s::NAVIGATION_STATE_STAB; + } // Last, check can_run for intended mode if (!modeCanRun(status_flags, user_intended_mode)) { diff --git a/src/modules/commander/failsafe/failsafe.h b/src/modules/commander/failsafe/failsafe.h index d7ac7c75c2..d5b3f0a79e 100644 --- a/src/modules/commander/failsafe/failsafe.h +++ b/src/modules/commander/failsafe/failsafe.h @@ -53,17 +53,12 @@ protected: private: void updateArmingState(const hrt_abstime &time_us, bool armed, const failsafe_flags_s &status_flags); - enum class ManualControlLossExceptionBits : int32_t { + enum class LinkLossExceptionBits : int32_t { Mission = (1 << 0), - Hold = (1 << 1), + AutoModes = (1 << 1), Offboard = (1 << 2), - ExternalMode = (1 << 3) - }; - - enum class DatalinkLossExceptionBits : int32_t { - Mission = (1 << 0), - Hold = (1 << 1), - Offboard = (1 << 2) + ExternalMode = (1 << 3), + AltitudeCruise = (1 << 4) }; // COM_LOW_BAT_ACT parameter values @@ -85,11 +80,6 @@ private: Disarm = 7, }; - enum class position_control_navigation_loss_response : int32_t { - Altitude_Manual = 0, - Land_Descend = 1, - }; - enum class actuator_failure_failsafe_mode : int32_t { Warning_only = 0, Hold_mode = 1, @@ -132,11 +122,15 @@ private: // COM_RC_IN_MODE parameter values enum class RcInMode : int32_t { - RcTransmitterOnly = 0, // RC Transmitter only - JoystickOnly = 1, // Joystick only - RcAndJoystickWithFallback = 2, // RC And Joystick with fallback - RcOrJoystickKeepFirst = 3, // RC or Joystick keep first - StickInputDisabled = 4 // input disabled + RcOnly = 0, + MavLinkOnly = 1, + RcOrMavlinkWithFallback = 2, + RcOrMavlinkKeepFirst = 3, + DisableManualControl = 4, + PriorityRcThenMavlinkAscending = 5, + PriorityMavlinkAscendingThenRc = 6, + PriorityRcThenMavlinkDescending = 7, + PriorityMavlinkDescendingThenRc = 8 }; enum class command_after_high_wind_failsafe : int32_t { @@ -175,6 +169,8 @@ private: static ActionOptions fromPosLowActParam(int param_value); static ActionOptions fromRemainingFlightTimeLowActParam(int param_value); + static bool isFailsafeIgnored(uint8_t user_intended_mode, int32_t exception_mask_parameter); + const int _caller_id_mode_fallback{genCallerId()}; bool _last_state_mode_fallback{false}; const int _caller_id_mission_control_lost{genCallerId()}; @@ -202,7 +198,6 @@ private: (ParamInt) _param_com_rcl_except, (ParamInt) _param_com_dll_except, (ParamInt) _param_com_rc_in_mode, - (ParamInt) _param_com_posctl_navl, (ParamInt) _param_gf_action, (ParamFloat) _param_com_spoolup_time, (ParamInt) _param_com_imb_prop_act, diff --git a/src/modules/commander/failsafe/failsafe_test.cpp b/src/modules/commander/failsafe/failsafe_test.cpp index 18b927409f..81eba458ae 100644 --- a/src/modules/commander/failsafe/failsafe_test.cpp +++ b/src/modules/commander/failsafe/failsafe_test.cpp @@ -35,6 +35,7 @@ #include "framework.h" #include +#include "../ModeUtil/mode_requirements.hpp" // to run: make tests TESTFILTER=failsafe_test @@ -50,16 +51,19 @@ protected: void checkStateAndMode(const hrt_abstime &time_us, const State &state, const failsafe_flags_s &status_flags) override { - CHECK_FAILSAFE(status_flags, manual_control_signal_lost, - ActionOptions(Action::RTL).clearOn(ClearCondition::OnModeChangeOrDisarm)); + CHECK_FAILSAFE(status_flags, manual_control_signal_lost, ActionOptions(Action::RTL).clearOn(ClearCondition::OnModeChangeOrDisarm)); CHECK_FAILSAFE(status_flags, gcs_connection_lost, Action::Descend); if (state.user_intended_mode == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION) { CHECK_FAILSAFE(status_flags, mission_failure, Action::Descend); } - CHECK_FAILSAFE(status_flags, wind_limit_exceeded, - ActionOptions(Action::RTL).allowUserTakeover(UserTakeoverAllowed::Never)); + CHECK_FAILSAFE(status_flags, wind_limit_exceeded, ActionOptions(Action::RTL).allowUserTakeover(UserTakeoverAllowed::Never)); + CHECK_FAILSAFE(status_flags, battery_low_remaining_time, ActionOptions(Action::RTL).causedBy(Cause::RemainingFlightTimeLow)); + CHECK_FAILSAFE(status_flags, offboard_control_signal_lost, ActionOptions(Action::Hold)); + + CHECK_FAILSAFE(status_flags, navigator_failure, ActionOptions(Action::Warn)); + CHECK_FAILSAFE(status_flags, fd_imbalanced_prop, ActionOptions(Action::None)); _last_state_test = checkFailsafe(_caller_id_test, _last_state_test, status_flags.fd_motor_failure && status_flags.fd_critical_failure, ActionOptions(Action::Terminate).cannotBeDeferred()); @@ -258,6 +262,107 @@ TEST_F(FailsafeTest, takeover_denied) ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Terminate); } +TEST_F(FailsafeTest, can_takeover_degraded_failsafe) +{ + FailsafeTester failsafe(nullptr); + + FailsafeBase::State state{}; + state.armed = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_MANUAL; + state.vehicle_type = vehicle_status_s::VEHICLE_TYPE_ROTARY_WING; + hrt_abstime time = 3847124342; + failsafe_flags_s failsafe_flags{}; + mode_util::getModeRequirements(state.vehicle_type, failsafe_flags); // Load mode requirements to degrade without valid position estimate + bool user_intended_mode_updated = false; + + uint8_t updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + + // Battery time low -> Hold for the delay + time += 10_ms; + failsafe_flags.battery_low_remaining_time = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Hold); + + // Delay over -> RTL + time += 5_s; + failsafe_flags.battery_low_remaining_time = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::RTL); + + // Global position gets invalid -> Land + time += 10_ms; + failsafe_flags.global_position_invalid = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Land); + + // User wants takeover -> Altitude mode + Warning + time += 10_ms; + user_intended_mode_updated = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_ALTCTL; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Warn); + ASSERT_TRUE(failsafe.userTakeoverActive()); +} + +TEST_F(FailsafeTest, no_delay_for_warn) +{ + // Ensure there is no Hold/delay when the current action is Warn + FailsafeTester failsafe(nullptr); + + FailsafeBase::State state{}; + state.armed = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_MANUAL; + state.vehicle_type = vehicle_status_s::VEHICLE_TYPE_ROTARY_WING; + hrt_abstime time = 3847124342; + failsafe_flags_s failsafe_flags{}; + bool user_intended_mode_updated = false; + + uint8_t updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + + // Navigator failure -> Warn + time += 10_ms; + failsafe_flags.navigator_failure = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Warn); + + // Imbalanced props -> Warn (no delay) + time += 5_s; + failsafe_flags.fd_imbalanced_prop = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Warn); +} + +TEST_F(FailsafeTest, no_immediate_takeover_when_failsafe_on_mode_switch) +{ + FailsafeTester failsafe(nullptr); + + failsafe_flags_s failsafe_flags{}; + FailsafeBase::State state{}; + state.armed = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_POSCTL; + state.vehicle_type = vehicle_status_s::VEHICLE_TYPE_ROTARY_WING; + hrt_abstime time = 3847124342; + bool user_intended_mode_updated = false; + + uint8_t updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + + // Switch to offboard but no offboard signal -> No immediate user takeover flagged but rather Hold + time += 10_ms; + user_intended_mode_updated = true; + state.user_intended_mode = vehicle_status_s::NAVIGATION_STATE_OFFBOARD; + failsafe_flags.offboard_control_signal_lost = true; + updated_user_intented_mode = failsafe.update(time, state, user_intended_mode_updated, false, failsafe_flags); + ASSERT_EQ(updated_user_intented_mode, state.user_intended_mode); + ASSERT_EQ(failsafe.selectedAction(), FailsafeBase::Action::Hold); + ASSERT_FALSE(failsafe.userTakeoverActive()); +} + TEST_F(FailsafeTest, defer) { FailsafeTester failsafe(nullptr); diff --git a/src/modules/commander/failsafe/framework.cpp b/src/modules/commander/failsafe/framework.cpp index ab3e30c847..f8e7e29a0e 100644 --- a/src/modules/commander/failsafe/framework.cpp +++ b/src/modules/commander/failsafe/framework.cpp @@ -488,6 +488,7 @@ void FailsafeBase::getSelectedAction(const State &state, const failsafe_flags_s // Check if we should enter delayed Hold const bool action_can_be_delayed = selected_action != Action::None && + selected_action != Action::Warn && selected_action != Action::Disarm && selected_action != Action::Terminate && selected_action != Action::Hold; @@ -499,9 +500,9 @@ void FailsafeBase::getSelectedAction(const State &state, const failsafe_flags_s allow_user_takeover = UserTakeoverAllowed::AlwaysModeSwitchOnly; } - // User takeover is activated on user intented mode update (w/o action change, so takeover is not immediately - // requested when entering failsafe) or rc stick movements - bool want_user_takeover_mode_switch = user_intended_mode_updated && _selected_action == selected_action; + // User takeover interrupting a failsafe is triggered by a change of the user-intended mode + // (only if a failsafe action is already active otherwise there can be immediate takeover when entering a failsafe) or by stick movement + bool want_user_takeover_mode_switch = user_intended_mode_updated && (_selected_action > Action::Warn); bool want_user_takeover = want_user_takeover_mode_switch || rc_sticks_takeover_request; bool takeover_allowed = (allow_user_takeover == UserTakeoverAllowed::Always && (_user_takeover_active || want_user_takeover)) diff --git a/src/modules/commander/failure_detector/CMakeLists.txt b/src/modules/commander/failure_detector/CMakeLists.txt index 8c68bc6d71..e6cd9d57c8 100644 --- a/src/modules/commander/failure_detector/CMakeLists.txt +++ b/src/modules/commander/failure_detector/CMakeLists.txt @@ -33,4 +33,5 @@ px4_add_library(failure_detector FailureDetector.cpp + FailureInjector.cpp ) diff --git a/src/modules/commander/failure_detector/FailureDetector.cpp b/src/modules/commander/failure_detector/FailureDetector.cpp index e475328566..cbba4c68e0 100644 --- a/src/modules/commander/failure_detector/FailureDetector.cpp +++ b/src/modules/commander/failure_detector/FailureDetector.cpp @@ -42,123 +42,6 @@ using namespace time_literals; -void FailureInjector::update() -{ - vehicle_command_s vehicle_command; - - while (_vehicle_command_sub.update(&vehicle_command)) { - if (vehicle_command.command != vehicle_command_s::VEHICLE_CMD_INJECT_FAILURE) { - continue; - } - - bool handled = false; - bool supported = false; - - const int failure_unit = static_cast(vehicle_command.param1 + 0.5f); - const int failure_type = static_cast(vehicle_command.param2 + 0.5f); - const int instance = static_cast(vehicle_command.param3 + 0.5f); - - if (failure_unit == vehicle_command_s::FAILURE_UNIT_SYSTEM_MOTOR) { - handled = true; - - if (failure_type == vehicle_command_s::FAILURE_TYPE_OK) { - PX4_INFO("CMD_INJECT_FAILURE, motors ok"); - supported = false; - - // 0 to signal all - if (instance == 0) { - supported = true; - - for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; i++) { - PX4_INFO("CMD_INJECT_FAILURE, motor %d ok", i); - _esc_blocked &= ~(1 << i); - _esc_wrong &= ~(1 << i); - } - - } else if (instance >= 1 && instance <= esc_status_s::CONNECTED_ESC_MAX) { - supported = true; - - PX4_INFO("CMD_INJECT_FAILURE, motor %d ok", instance - 1); - _esc_blocked &= ~(1 << (instance - 1)); - _esc_wrong &= ~(1 << (instance - 1)); - } - } - - else if (failure_type == vehicle_command_s::FAILURE_TYPE_OFF) { - PX4_WARN("CMD_INJECT_FAILURE, motors off"); - supported = true; - - // 0 to signal all - if (instance == 0) { - for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; i++) { - PX4_INFO("CMD_INJECT_FAILURE, motor %d off", i); - _esc_blocked |= 1 << i; - } - - } else if (instance >= 1 && instance <= esc_status_s::CONNECTED_ESC_MAX) { - PX4_INFO("CMD_INJECT_FAILURE, motor %d off", instance - 1); - _esc_blocked |= 1 << (instance - 1); - } - } - - else if (failure_type == vehicle_command_s::FAILURE_TYPE_WRONG) { - PX4_INFO("CMD_INJECT_FAILURE, motors wrong"); - supported = true; - - // 0 to signal all - if (instance == 0) { - for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; i++) { - PX4_INFO("CMD_INJECT_FAILURE, motor %d wrong", i); - _esc_wrong |= 1 << i; - } - - } else if (instance >= 1 && instance <= esc_status_s::CONNECTED_ESC_MAX) { - PX4_INFO("CMD_INJECT_FAILURE, motor %d wrong", instance - 1); - _esc_wrong |= 1 << (instance - 1); - } - } - } - - if (handled) { - vehicle_command_ack_s ack{}; - ack.command = vehicle_command.command; - ack.from_external = false; - ack.result = supported ? - vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED : - vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; - ack.timestamp = hrt_absolute_time(); - _command_ack_pub.publish(ack); - } - } - -} - -void FailureInjector::manipulateEscStatus(esc_status_s &status) -{ - if (_esc_blocked != 0 || _esc_wrong != 0) { - unsigned offline = 0; - - for (int i = 0; i < status.esc_count; i++) { - const unsigned i_esc = status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; - - if (_esc_blocked & (1 << i_esc)) { - unsigned function = status.esc[i].actuator_function; - memset(&status.esc[i], 0, sizeof(status.esc[i])); - status.esc[i].actuator_function = function; - offline |= 1 << i; - - } else if (_esc_wrong & (1 << i_esc)) { - // Create wrong rerport for this motor by scaling key values up and down - status.esc[i].esc_voltage *= 0.1f; - status.esc[i].esc_current *= 0.1f; - status.esc[i].esc_rpm *= 10.0f; - } - } - - status.esc_online_flags &= ~offline; - } -} - FailureDetector::FailureDetector(ModuleParams *parent) : ModuleParams(parent) { @@ -168,7 +51,7 @@ bool FailureDetector::update(const vehicle_status_s &vehicle_status, const vehic { _failure_injector.update(); - failure_detector_status_u status_prev = _status; + failure_detector_status_u status_prev = _failure_detector_status; if (vehicle_control_mode.flag_control_attitude_enabled) { updateAttitudeStatus(vehicle_status); @@ -178,10 +61,10 @@ bool FailureDetector::update(const vehicle_status_s &vehicle_status, const vehic } } else { - _status.flags.roll = false; - _status.flags.pitch = false; - _status.flags.alt = false; - _status.flags.ext = false; + _failure_detector_status.flags.roll = false; + _failure_detector_status.flags.pitch = false; + _failure_detector_status.flags.alt = false; + _failure_detector_status.flags.ext = false; } // esc_status subscriber is shared between subroutines @@ -194,7 +77,7 @@ bool FailureDetector::update(const vehicle_status_s &vehicle_status, const vehic updateEscsStatus(vehicle_status, esc_status); } - if (_param_fd_actuator_en.get()) { + if (_param_fd_act_en.get()) { updateMotorStatus(vehicle_status, esc_status); } } @@ -203,7 +86,25 @@ bool FailureDetector::update(const vehicle_status_s &vehicle_status, const vehic updateImbalancedPropStatus(); } - return _status.value != status_prev.value; + return _failure_detector_status.value != status_prev.value; +} + +void FailureDetector::publishStatus() +{ + failure_detector_status_s failure_detector_status{}; + failure_detector_status.fd_roll = _failure_detector_status.flags.roll; + failure_detector_status.fd_pitch = _failure_detector_status.flags.pitch; + failure_detector_status.fd_alt = _failure_detector_status.flags.alt; + failure_detector_status.fd_ext = _failure_detector_status.flags.ext; + failure_detector_status.fd_arm_escs = _failure_detector_status.flags.arm_escs; + failure_detector_status.fd_battery = _failure_detector_status.flags.battery; + failure_detector_status.fd_imbalanced_prop = _failure_detector_status.flags.imbalanced_prop; + failure_detector_status.fd_motor = _failure_detector_status.flags.motor; + failure_detector_status.imbalanced_prop_metric = _imbalanced_prop_lpf.getState(); + failure_detector_status.motor_failure_mask = _motor_failure_mask; + failure_detector_status.motor_stop_mask = _failure_injector.getMotorStopMask(); + failure_detector_status.timestamp = hrt_absolute_time(); + _failure_detector_status_pub.publish(failure_detector_status); } void FailureDetector::updateAttitudeStatus(const vehicle_status_s &vehicle_status) @@ -240,17 +141,17 @@ void FailureDetector::updateAttitudeStatus(const vehicle_status_s &vehicle_statu const bool roll_status = (max_roll > FLT_EPSILON) && (fabsf(roll) > max_roll); const bool pitch_status = (max_pitch > FLT_EPSILON) && (fabsf(pitch) > max_pitch); - hrt_abstime time_now = hrt_absolute_time(); + hrt_abstime now = hrt_absolute_time(); // Update hysteresis _roll_failure_hysteresis.set_hysteresis_time_from(false, (hrt_abstime)(1_s * _param_fd_fail_r_ttri.get())); _pitch_failure_hysteresis.set_hysteresis_time_from(false, (hrt_abstime)(1_s * _param_fd_fail_p_ttri.get())); - _roll_failure_hysteresis.set_state_and_update(roll_status, time_now); - _pitch_failure_hysteresis.set_state_and_update(pitch_status, time_now); + _roll_failure_hysteresis.set_state_and_update(roll_status, now); + _pitch_failure_hysteresis.set_state_and_update(pitch_status, now); // Update status - _status.flags.roll = _roll_failure_hysteresis.get_state(); - _status.flags.pitch = _pitch_failure_hysteresis.get_state(); + _failure_detector_status.flags.roll = _roll_failure_hysteresis.get_state(); + _failure_detector_status.flags.pitch = _pitch_failure_hysteresis.get_state(); } } @@ -263,19 +164,17 @@ void FailureDetector::updateExternalAtsStatus() uint32_t pulse_width = pwm_input.pulse_width; bool ats_trigger_status = (pulse_width >= (uint32_t)_param_fd_ext_ats_trig.get()) && (pulse_width < 3_ms); - hrt_abstime time_now = hrt_absolute_time(); - // Update hysteresis _ext_ats_failure_hysteresis.set_hysteresis_time_from(false, 100_ms); // 5 consecutive pulses at 50hz - _ext_ats_failure_hysteresis.set_state_and_update(ats_trigger_status, time_now); + _ext_ats_failure_hysteresis.set_state_and_update(ats_trigger_status, hrt_absolute_time()); - _status.flags.ext = _ext_ats_failure_hysteresis.get_state(); + _failure_detector_status.flags.ext = _ext_ats_failure_hysteresis.get_state(); } } void FailureDetector::updateEscsStatus(const vehicle_status_s &vehicle_status, const esc_status_s &esc_status) { - hrt_abstime time_now = hrt_absolute_time(); + hrt_abstime now = hrt_absolute_time(); if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { const int limited_esc_count = math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); @@ -289,16 +188,16 @@ void FailureDetector::updateEscsStatus(const vehicle_status_s &vehicle_status, c } _esc_failure_hysteresis.set_hysteresis_time_from(false, 300_ms); - _esc_failure_hysteresis.set_state_and_update(is_esc_failure, time_now); + _esc_failure_hysteresis.set_state_and_update(is_esc_failure, now); if (_esc_failure_hysteresis.get_state()) { - _status.flags.arm_escs = true; + _failure_detector_status.flags.arm_escs = true; } } else { // reset ESC bitfield - _esc_failure_hysteresis.set_state_and_update(false, time_now); - _status.flags.arm_escs = false; + _esc_failure_hysteresis.set_state_and_update(false, now); + _failure_detector_status.flags.arm_escs = false; } } @@ -354,7 +253,7 @@ void FailureDetector::updateImbalancedPropStatus() const float metric_lpf = _imbalanced_prop_lpf.update(metric); const bool is_imbalanced = metric_lpf > _param_fd_imb_prop_thr.get(); - _status.flags.imbalanced_prop = is_imbalanced; + _failure_detector_status.flags.imbalanced_prop = is_imbalanced; } } } @@ -362,113 +261,79 @@ void FailureDetector::updateImbalancedPropStatus() void FailureDetector::updateMotorStatus(const vehicle_status_s &vehicle_status, const esc_status_s &esc_status) { - // What need to be checked: - // - // 1. ESC telemetry disappears completely -> dead ESC or power loss on that ESC - // 2. ESC failures like overvoltage, overcurrent etc. But DShot driver for example is not populating the field 'esc_report.failures' - // 3. Motor current too low. Compare drawn motor current to expected value from a parameter - // -- ESC voltage does not really make sense and is highly dependent on the setup + // 1. Telemetry times out -> communication or power lost on that ESC + // 2. Too low current draw compared to commanded thrust + // Overvoltage, overcurrent do not have checks yet esc_report.failures are handled separately - // First wait for some ESC telemetry that has the required fields. Before that happens, don't check this ESC - // Then check - - const hrt_abstime time_now = hrt_absolute_time(); + const hrt_abstime now = hrt_absolute_time(); // Only check while armed if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { - const int limited_esc_count = math::min(esc_status.esc_count, esc_status_s::CONNECTED_ESC_MAX); - actuator_motors_s actuator_motors{}; _actuator_motors_sub.copy(&actuator_motors); // Check individual ESC reports - for (int esc_status_idx = 0; esc_status_idx < limited_esc_count; esc_status_idx++) { - - const esc_report_s &cur_esc_report = esc_status.esc[esc_status_idx]; - + for (uint8_t i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { // Map the esc status index to the actuator function index - const unsigned i_esc = cur_esc_report.actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; + const uint8_t actuator_function_index = + esc_status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; - if (i_esc >= actuator_motors_s::NUM_CONTROLS) { + if (actuator_function_index >= actuator_motors_s::NUM_CONTROLS) { + continue; // Invalid mapping + } + + const bool timeout = now > esc_status.esc[i].timestamp + 300_ms; + const float current = esc_status.esc[i].esc_current; + + // First wait for ESC telemetry reporting non-zero current. Before that happens, don't check it. + if (current > FLT_EPSILON) { + _esc_has_reported_current[i] = true; + } + + if (!_esc_has_reported_current[i]) { continue; } - // Check if ESC telemetry was available and valid at some point. This is a prerequisite for the failure detection. - if (!(_motor_failure_esc_valid_current_mask & (1 << i_esc)) && cur_esc_report.esc_current > 0.0f) { - _motor_failure_esc_valid_current_mask |= (1 << i_esc); + _motor_failure_mask &= ~(1u << actuator_function_index); // Reset bit in mask to accumulate failures again + _motor_failure_mask |= (static_cast(timeout) << actuator_function_index); // Telemetry timeout + + // Current limits + float thrust = 0.f; + + if (PX4_ISFINITE(actuator_motors.control[actuator_function_index])) { + // Normalized motor thrust commands before thrust model factor is applied, NAN means motor is turned off -> 0 thrust + thrust = fabsf(actuator_motors.control[actuator_function_index]); } - // Check for telemetry timeout - const hrt_abstime telemetry_age = time_now - cur_esc_report.timestamp; - const bool esc_timed_out = telemetry_age > 300_ms; + bool thrust_above_threshold = thrust > _param_fd_act_mot_thr.get(); + bool current_too_low = current < (thrust * _param_fd_act_mot_c2t.get()) - _param_fd_act_low_off.get(); + bool current_too_high = current > (thrust * _param_fd_act_mot_c2t.get()) + _param_fd_act_high_off.get(); - const bool esc_was_valid = _motor_failure_esc_valid_current_mask & (1 << i_esc); - const bool esc_timeout_currently_flagged = _motor_failure_esc_timed_out_mask & (1 << i_esc); + _esc_undercurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); + _esc_overcurrent_hysteresis[i].set_hysteresis_time_from(false, _param_fd_act_mot_tout.get() * 1_ms); - if (esc_was_valid && esc_timed_out && !esc_timeout_currently_flagged) { - // Set flag - _motor_failure_esc_timed_out_mask |= (1 << i_esc); - - } else if (!esc_timed_out && esc_timeout_currently_flagged) { - // Reset flag - _motor_failure_esc_timed_out_mask &= ~(1 << i_esc); + if (!_esc_undercurrent_hysteresis[i].get_state()) { + // Do not clear mid operation because a reaction could be to stop the motor and that would be conidered healthy again + _esc_undercurrent_hysteresis[i].set_state_and_update(thrust_above_threshold && current_too_low && !timeout, now); } - // Check if ESC current is too low - if (cur_esc_report.esc_current > FLT_EPSILON) { - _motor_failure_esc_has_current[i_esc] = true; + if (!_esc_overcurrent_hysteresis[i].get_state()) { + // Do not clear mid operation because a reaction could be to stop the motor and that would be conidered healthy again + _esc_overcurrent_hysteresis[i].set_state_and_update(current_too_high && !timeout, now); } - if (_motor_failure_esc_has_current[i_esc]) { - float esc_throttle = 0.f; - - if (PX4_ISFINITE(actuator_motors.control[i_esc])) { - esc_throttle = fabsf(actuator_motors.control[i_esc]); - } - - const bool throttle_above_threshold = esc_throttle > _param_fd_motor_throttle_thres.get(); - const bool current_too_low = cur_esc_report.esc_current < esc_throttle * - _param_fd_motor_current2throttle_thres.get(); - - if (throttle_above_threshold && current_too_low && !esc_timed_out) { - if (_motor_failure_undercurrent_start_time[i_esc] == 0) { - _motor_failure_undercurrent_start_time[i_esc] = time_now; - } - - } else { - if (_motor_failure_undercurrent_start_time[i_esc] != 0) { - _motor_failure_undercurrent_start_time[i_esc] = 0; - } - } - - if (_motor_failure_undercurrent_start_time[i_esc] != 0 - && (time_now - _motor_failure_undercurrent_start_time[i_esc]) > _param_fd_motor_time_thres.get() * 1_ms - && (_motor_failure_esc_under_current_mask & (1 << i_esc)) == 0) { - // Set flag - _motor_failure_esc_under_current_mask |= (1 << i_esc); - - } // else: this flag is never cleared, as the motor is stopped, so throttle < threshold - } + _motor_failure_mask |= (static_cast(_esc_undercurrent_hysteresis[i].get_state()) << actuator_function_index); + _motor_failure_mask |= (static_cast(_esc_overcurrent_hysteresis[i].get_state()) << actuator_function_index); } - bool critical_esc_failure = (_motor_failure_esc_timed_out_mask != 0 || _motor_failure_esc_under_current_mask != 0); - - if (critical_esc_failure && !(_status.flags.motor)) { - // Add motor failure flag to bitfield - _status.flags.motor = true; - - } else if (!critical_esc_failure && _status.flags.motor) { - // Reset motor failure flag - _status.flags.motor = false; - } + _failure_detector_status.flags.motor = (_motor_failure_mask != 0u); } else { // Disarmed - // reset ESC bitfield - for (int i_esc = 0; i_esc < actuator_motors_s::NUM_CONTROLS; i_esc++) { - _motor_failure_undercurrent_start_time[i_esc] = 0; + for (uint8_t i = 0; i < esc_status_s::CONNECTED_ESC_MAX; ++i) { + _esc_undercurrent_hysteresis[i].set_state_and_update(false, now); + _esc_overcurrent_hysteresis[i].set_state_and_update(false, now); } - _motor_failure_esc_under_current_mask = 0; - _status.flags.motor = false; + _failure_detector_status.flags.motor = false; } } diff --git a/src/modules/commander/failure_detector/FailureDetector.hpp b/src/modules/commander/failure_detector/FailureDetector.hpp index e89719d2aa..26182f4c3c 100644 --- a/src/modules/commander/failure_detector/FailureDetector.hpp +++ b/src/modules/commander/failure_detector/FailureDetector.hpp @@ -1,4 +1,3 @@ - /**************************************************************************** * * Copyright (c) 2018 PX4 Development Team. All rights reserved. @@ -43,6 +42,8 @@ #pragma once +#include "FailureInjector.hpp" + #include #include #include @@ -50,19 +51,18 @@ #include // subscriptions -#include #include +#include #include +#include +#include +#include #include #include #include -#include -#include #include #include #include -#include -#include union failure_detector_status_u { struct { @@ -80,20 +80,6 @@ union failure_detector_status_u { using uORB::SubscriptionData; -class FailureInjector -{ -public: - void update(); - - void manipulateEscStatus(esc_status_s &status); -private: - uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; - uORB::Publication _command_ack_pub{ORB_ID(vehicle_command_ack)}; - - uint32_t _esc_blocked{}; - uint32_t _esc_wrong{}; -}; - class FailureDetector : public ModuleParams { public: @@ -101,10 +87,9 @@ public: ~FailureDetector() = default; bool update(const vehicle_status_s &vehicle_status, const vehicle_control_mode_s &vehicle_control_mode); - const failure_detector_status_u &getStatus() const { return _status; } - const decltype(failure_detector_status_u::flags) &getStatusFlags() const { return _status.flags; } - float getImbalancedPropMetric() const { return _imbalanced_prop_lpf.getState(); } - uint16_t getMotorFailures() const { return _motor_failure_esc_timed_out_mask | _motor_failure_esc_under_current_mask; } + const failure_detector_status_u &getStatus() const { return _failure_detector_status; } + + void publishStatus(); private: void updateAttitudeStatus(const vehicle_status_s &vehicle_status); @@ -113,7 +98,7 @@ private: void updateMotorStatus(const vehicle_status_s &vehicle_status, const esc_status_s &esc_status); void updateImbalancedPropStatus(); - failure_detector_status_u _status{}; + failure_detector_status_u _failure_detector_status{}; systemlib::Hysteresis _roll_failure_hysteresis{false}; systemlib::Hysteresis _pitch_failure_hysteresis{false}; @@ -126,11 +111,10 @@ private: hrt_abstime _imu_status_timestamp_prev{0}; // Motor failure check - uint8_t _motor_failure_esc_valid_current_mask{}; // ESC 1-8, true if ESC telemetry was valid at some point - uint8_t _motor_failure_esc_timed_out_mask{}; // ESC telemetry no longer available -> failure - uint8_t _motor_failure_esc_under_current_mask{}; // ESC drawing too little current -> failure - bool _motor_failure_esc_has_current[actuator_motors_s::NUM_CONTROLS] {false}; // true if some ESC had non-zero current (some don't support it) - hrt_abstime _motor_failure_undercurrent_start_time[actuator_motors_s::NUM_CONTROLS] {}; + bool _esc_has_reported_current[esc_status_s::CONNECTED_ESC_MAX] {}; // true if ESC reported non-zero current before (some never report any) + systemlib::Hysteresis _esc_undercurrent_hysteresis[esc_status_s::CONNECTED_ESC_MAX]; + systemlib::Hysteresis _esc_overcurrent_hysteresis[esc_status_s::CONNECTED_ESC_MAX]; + uint16_t _motor_failure_mask = 0; // actuator function indexed uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; uORB::Subscription _esc_status_sub{ORB_ID(esc_status)}; // TODO: multi-instance @@ -139,6 +123,8 @@ private: uORB::Subscription _vehicle_imu_status_sub{ORB_ID(vehicle_imu_status)}; uORB::Subscription _actuator_motors_sub{ORB_ID(actuator_motors)}; + uORB::Publication _failure_detector_status_pub{ORB_ID(failure_detector_status)}; + FailureInjector _failure_injector; DEFINE_PARAMETERS( @@ -152,9 +138,11 @@ private: (ParamInt) _param_fd_imb_prop_thr, // Actuator failure - (ParamBool) _param_fd_actuator_en, - (ParamFloat) _param_fd_motor_throttle_thres, - (ParamFloat) _param_fd_motor_current2throttle_thres, - (ParamInt) _param_fd_motor_time_thres + (ParamBool) _param_fd_act_en, + (ParamFloat) _param_fd_act_mot_thr, + (ParamFloat) _param_fd_act_mot_c2t, + (ParamInt) _param_fd_act_mot_tout, + (ParamFloat) _param_fd_act_low_off, + (ParamFloat) _param_fd_act_high_off ) }; diff --git a/src/modules/commander/failure_detector/FailureInjector.cpp b/src/modules/commander/failure_detector/FailureInjector.cpp new file mode 100644 index 0000000000..e1633500c3 --- /dev/null +++ b/src/modules/commander/failure_detector/FailureInjector.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "FailureInjector.hpp" + +#include +#include + +FailureInjector::FailureInjector() +{ + int32_t param_sys_failure_en = 0; + + if ((param_get(param_find("SYS_FAILURE_EN"), ¶m_sys_failure_en) == PX4_OK) + && (param_sys_failure_en == 1)) { + _failure_injection_enabled = true; + } +} + +void FailureInjector::update() +{ + if (!_failure_injection_enabled) { return; } + + vehicle_command_s vehicle_command; + + while (_vehicle_command_sub.update(&vehicle_command)) { + const int failure_unit = static_cast(vehicle_command.param1 + 0.5f); + const int failure_type = static_cast(vehicle_command.param2 + 0.5f); + + if (vehicle_command.command != vehicle_command_s::VEHICLE_CMD_INJECT_FAILURE + || failure_unit != vehicle_command_s::FAILURE_UNIT_SYSTEM_MOTOR) { + continue; + } + + const int instance = static_cast(vehicle_command.param3 + 0.5f); + bool supported = false; + + for (int i = 0; i < esc_status_s::CONNECTED_ESC_MAX; i++) { + if (instance != 0 && i != (instance - 1)) { + continue; + } + + switch (failure_type) { + case vehicle_command_s::FAILURE_TYPE_OK: + supported = true; + PX4_INFO("CMD_INJECT_FAILURE, motor %d ok", i + 1); + _motor_stop_mask &= ~(1 << i); + _esc_telemetry_blocked_mask &= ~(1 << i); + _esc_telemetry_wrong_mask &= ~(1 << i); + break; + + case vehicle_command_s::FAILURE_TYPE_OFF: + supported = true; + PX4_INFO("CMD_INJECT_FAILURE, motor %d off", i + 1); + _motor_stop_mask |= 1 << i; + break; + + case vehicle_command_s::FAILURE_TYPE_STUCK: + supported = true; + PX4_INFO("CMD_INJECT_FAILURE, motor %d no esc telemetry", i + 1); + _esc_telemetry_blocked_mask |= 1 << i; + break; + + case vehicle_command_s::FAILURE_TYPE_WRONG: + supported = true; + PX4_INFO("CMD_INJECT_FAILURE, motor %d esc telemetry wrong", i); + _esc_telemetry_wrong_mask |= 1 << i; + break; + } + } + + vehicle_command_ack_s ack{}; + ack.command = vehicle_command.command; + ack.from_external = false; + ack.result = supported ? + vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED : + vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; + ack.timestamp = hrt_absolute_time(); + _command_ack_pub.publish(ack); + } +} + +void FailureInjector::manipulateEscStatus(esc_status_s &status) +{ + if (!_failure_injection_enabled) { return; } + + if (_esc_telemetry_blocked_mask != 0 || _esc_telemetry_wrong_mask != 0) { + for (int i = 0; i < status.esc_count; i++) { + const unsigned i_esc = status.esc[i].actuator_function - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1; + + if (_esc_telemetry_blocked_mask & (1 << i_esc)) { + unsigned function = status.esc[i].actuator_function; + memset(&status.esc[i], 0, sizeof(status.esc[i])); + status.esc[i].actuator_function = function; + status.esc_online_flags &= ~(1 << i); + + } else if (_esc_telemetry_wrong_mask & (1 << i_esc)) { + // Create wrong rerport for this motor by scaling key values up and down + status.esc[i].esc_voltage *= 0.1f; + status.esc[i].esc_current *= 0.1f; + status.esc[i].esc_rpm *= 10.0f; + } + } + } +} diff --git a/src/modules/commander/failure_detector/FailureInjector.hpp b/src/modules/commander/failure_detector/FailureInjector.hpp new file mode 100644 index 0000000000..86f2199723 --- /dev/null +++ b/src/modules/commander/failure_detector/FailureInjector.hpp @@ -0,0 +1,59 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +class FailureInjector +{ +public: + FailureInjector(); + + void update(); + + void manipulateEscStatus(esc_status_s &status); + uint32_t getMotorStopMask() { return _motor_stop_mask; } +private: + uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; + uORB::Publication _command_ack_pub{ORB_ID(vehicle_command_ack)}; + + bool _failure_injection_enabled = false; + uint32_t _motor_stop_mask{}; + uint32_t _esc_telemetry_blocked_mask{}; + uint32_t _esc_telemetry_wrong_mask{}; +}; diff --git a/src/modules/commander/failure_detector/failure_detector_params.c b/src/modules/commander/failure_detector/failure_detector_params.c index e472c304b8..9324820472 100644 --- a/src/modules/commander/failure_detector/failure_detector_params.c +++ b/src/modules/commander/failure_detector/failure_detector_params.c @@ -169,12 +169,13 @@ PARAM_DEFINE_INT32(FD_IMB_PROP_THR, 30); * * @group Failure Detector */ -PARAM_DEFINE_INT32(FD_ACT_EN, 1); +PARAM_DEFINE_INT32(FD_ACT_EN, 0); /** - * Motor Failure Throttle Threshold + * Motor Failure Thrust Threshold * - * Motor failure triggers only above this throttle value. + * Failure detection per motor only triggers above this thrust value. + * Set to 1 to disable the detection. * * @group Failure Detector * @unit norm @@ -186,9 +187,11 @@ PARAM_DEFINE_INT32(FD_ACT_EN, 1); PARAM_DEFINE_FLOAT(FD_ACT_MOT_THR, 0.2f); /** - * Motor Failure Current/Throttle Threshold + * Motor Failure Current/Throttle Scale * - * Motor failure triggers only below this current value + * Determines the slope between expected steady state current and linearized, normalized thrust command. + * E.g. FD_ACT_MOT_C2T A represents the expected steady state current at 100%. + * FD_ACT_LOW_OFF and FD_ACT_HIGH_OFF offset the threshold from that slope. * * @group Failure Detector * @min 0.0 @@ -197,13 +200,12 @@ PARAM_DEFINE_FLOAT(FD_ACT_MOT_THR, 0.2f); * @decimal 2 * @increment 1 */ -PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 2.0f); +PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 35.f); /** - * Motor Failure Time Threshold + * Motor Failure Hysteresis Time * - * Motor failure triggers only if the throttle threshold and the - * current to throttle threshold are violated for this time. + * Motor failure only triggers after current thresholds are exceeded for this time. * * @group Failure Detector * @unit ms @@ -211,4 +213,32 @@ PARAM_DEFINE_FLOAT(FD_ACT_MOT_C2T, 2.0f); * @max 10000 * @increment 100 */ -PARAM_DEFINE_INT32(FD_ACT_MOT_TOUT, 100); +PARAM_DEFINE_INT32(FD_ACT_MOT_TOUT, 1000); + +/** + * Undercurrent motor failure limit offset + * + * threshold = FD_ACT_MOT_C2T * thrust - FD_ACT_LOW_OFF + * + * @group Failure Detector + * @min 0 + * @max 30 + * @unit A + * @decimal 2 + * @increment 1 + */ +PARAM_DEFINE_FLOAT(FD_ACT_LOW_OFF, 10.f); + +/** + * Overcurrent motor failure limit offset + * + * threshold = FD_ACT_MOT_C2T * thrust + FD_ACT_HIGH_OFF + * + * @group Failure Detector + * @min 0 + * @max 30 + * @unit A + * @decimal 2 + * @increment 1 + */ +PARAM_DEFINE_FLOAT(FD_ACT_HIGH_OFF, 10.f); diff --git a/src/modules/commander/mag_calibration.cpp b/src/modules/commander/mag_calibration.cpp index 7aeadeab55..fb6dfa0282 100644 --- a/src/modules/commander/mag_calibration.cpp +++ b/src/modules/commander/mag_calibration.cpp @@ -520,12 +520,36 @@ calibrate_return mag_calibrate_all(orb_advert_t *mavlink_log_pub, int32_t cal_ma const unsigned int calibration_points_maxcount = worker_data.calibration_sides * worker_data.calibration_points_perside; + uORB::SubscriptionMultiArray mag_sub{ORB_ID::sensor_mag}; + int mag_available_enabled_count = 0; + for (uint8_t cur_mag = 0; cur_mag < MAX_MAGS; cur_mag++) { - uORB::SubscriptionData mag_sub{ORB_ID(sensor_mag), cur_mag}; + if (!mag_sub[cur_mag].advertised()) { + continue; + } - if (mag_sub.advertised() && (mag_sub.get().device_id != 0) && (mag_sub.get().timestamp > 0)) { - worker_data.calibration[cur_mag].set_device_id(mag_sub.get().device_id); + sensor_mag_s mag_data; + + if (!mag_sub[cur_mag].copy(&mag_data) || mag_data.device_id == 0) { + continue; + } + + int calibration_index = calibration::FindCurrentCalibrationIndex("MAG", mag_data.device_id); + + if (calibration_index >= 0) { + int priority = calibration::GetCalibrationParamInt32("MAG", "PRIO", calibration_index); + + if (priority != 0) { + ++mag_available_enabled_count; + } + + } else { + ++mag_available_enabled_count; + } + + if ((mag_data.device_id != 0) && (mag_data.timestamp > 0)) { + worker_data.calibration[cur_mag].set_device_id(mag_data.device_id); } // reset calibration index to match uORB numbering @@ -547,6 +571,11 @@ calibrate_return mag_calibrate_all(orb_advert_t *mavlink_log_pub, int32_t cal_ma } } + if (mag_available_enabled_count <= 0) { + calibration_log_critical(mavlink_log_pub, "Failed: No magnetometer available or enabled"); + return calibrate_return_error; + } + if (result == calibrate_return_ok) { result = calibrate_from_orientation(mavlink_log_pub, // uORB handle to write output worker_data.side_data_collected, // Sides to calibrate diff --git a/src/modules/commander/module.yaml b/src/modules/commander/module.yaml index d2113d9359..67f97e3a7e 100644 --- a/src/modules/commander/module.yaml +++ b/src/modules/commander/module.yaml @@ -38,6 +38,7 @@ parameters: 8: Stabilized 12: Follow Me 13: Precision Land + 16: Altitude Cruise 100: External Mode 1 101: External Mode 2 102: External Mode 3 diff --git a/src/modules/commander/px4_custom_mode.h b/src/modules/commander/px4_custom_mode.h index e4936982ff..fc901d1492 100644 --- a/src/modules/commander/px4_custom_mode.h +++ b/src/modules/commander/px4_custom_mode.h @@ -51,7 +51,8 @@ enum PX4_CUSTOM_MAIN_MODE { PX4_CUSTOM_MAIN_MODE_STABILIZED, PX4_CUSTOM_MAIN_MODE_RATTITUDE_LEGACY, PX4_CUSTOM_MAIN_MODE_SIMPLE, /* unused, but reserved for future use */ - PX4_CUSTOM_MAIN_MODE_TERMINATION + PX4_CUSTOM_MAIN_MODE_TERMINATION, + PX4_CUSTOM_MAIN_MODE_ALTITUDE_CRUISE }; enum PX4_CUSTOM_SUB_MODE_AUTO { @@ -112,6 +113,10 @@ static inline union px4_custom_mode get_px4_custom_mode(uint8_t nav_state) custom_mode.main_mode = PX4_CUSTOM_MAIN_MODE_ALTCTL; break; + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: + custom_mode.main_mode = PX4_CUSTOM_MAIN_MODE_ALTITUDE_CRUISE; + break; + case vehicle_status_s::NAVIGATION_STATE_POSCTL: custom_mode.main_mode = PX4_CUSTOM_MAIN_MODE_POSCTL; break; diff --git a/src/modules/control_allocator/ControlAllocator.cpp b/src/modules/control_allocator/ControlAllocator.cpp index e0dc14bcbe..17385a117c 100644 --- a/src/modules/control_allocator/ControlAllocator.cpp +++ b/src/modules/control_allocator/ControlAllocator.cpp @@ -74,6 +74,8 @@ ControlAllocator::ControlAllocator() : } parameters_updated(); + + _slew_limited_ice_shedding_output.setSlewRate(ICE_SHEDDING_MAX_SLEWRATE); } ControlAllocator::~ControlAllocator() @@ -339,6 +341,7 @@ ControlAllocator::Run() if (_vehicle_status_sub.update(&vehicle_status)) { _armed = vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED; + _is_vtol = vehicle_status.is_vtol; ActuatorEffectiveness::FlightPhase flight_phase{ActuatorEffectiveness::FlightPhase::HOVER_FLIGHT}; @@ -641,10 +644,44 @@ ControlAllocator::publish_control_allocator_status(int matrix_index) // Handled motor failures control_allocator_status.handled_motor_failure_mask = _handled_motor_failure_bitmask; + control_allocator_status.motor_stop_mask = _motor_stop_mask; _control_allocator_status_pub[matrix_index].publish(control_allocator_status); } +float +ControlAllocator::get_ice_shedding_output(hrt_abstime now, bool any_stopped_motor_failed) +{ + const float period_sec = _param_ice_shedding_period.get(); + + const bool feature_disabled_by_param = period_sec <= FLT_EPSILON; + const bool in_forward_flight = _actuator_effectiveness->getFlightPhase() == ActuatorEffectiveness::FlightPhase::FORWARD_FLIGHT; + + // If any stopped motor has failed, the feature will create much more + // torque than in the nominal case, and becomes pointless anyway as we + // cannot go back to multicopter + const bool apply_shedding = _is_vtol && in_forward_flight && !any_stopped_motor_failed; + + if (feature_disabled_by_param || !apply_shedding) { + // Bypass slew limit and immediately set zero, to not + // interfere with backtransition in any way + _slew_limited_ice_shedding_output.setForcedValue(0.0f); + + } else { + // Raw square wave output + const float elapsed_in_period = fmodf(static_cast(now) / 1_s, period_sec); + const float raw_ice_shedding_output = elapsed_in_period < ICE_SHEDDING_ON_SEC ? ICE_SHEDDING_OUTPUT : 0.0f; + + // Apply slew rate limit + const float dt = static_cast(now - _last_ice_shedding_update) / 1_s; + _slew_limited_ice_shedding_output.update(raw_ice_shedding_output, dt); + } + + _last_ice_shedding_update = now; + + return _slew_limited_ice_shedding_output.getState(); +} + void ControlAllocator::publish_actuator_controls() { @@ -665,7 +702,15 @@ ControlAllocator::publish_actuator_controls() int actuator_idx = 0; int actuator_idx_matrix[ActuatorEffectiveness::MAX_NUM_MATRICES] {}; - uint32_t stopped_motors = _actuator_effectiveness->getStoppedMotors() | _handled_motor_failure_bitmask; + const uint32_t stopped_motors_due_to_effectiveness = _actuator_effectiveness->getStoppedMotors(); + + const uint32_t stopped_motors = stopped_motors_due_to_effectiveness + | _handled_motor_failure_bitmask + | _motor_stop_mask; + + const bool any_stopped_motor_failed = 0 != (stopped_motors_due_to_effectiveness & (_handled_motor_failure_bitmask | _motor_stop_mask)); + + const float ice_shedding_output = get_ice_shedding_output(actuator_motors.timestamp, any_stopped_motor_failed); // motors int motors_idx; @@ -677,6 +722,10 @@ ControlAllocator::publish_actuator_controls() if (stopped_motors & (1u << motors_idx)) { actuator_motors.control[motors_idx] = NAN; + + if (ice_shedding_output > FLT_EPSILON) { + actuator_motors.control[motors_idx] = ice_shedding_output; + } } ++actuator_idx_matrix[selected_matrix]; @@ -716,8 +765,13 @@ ControlAllocator::check_for_motor_failures() if ((FailureMode)_param_ca_failure_mode.get() > FailureMode::IGNORE && _failure_detector_status_sub.update(&failure_detector_status)) { - if (failure_detector_status.fd_motor) { + if (_motor_stop_mask != failure_detector_status.motor_stop_mask) { + _motor_stop_mask = failure_detector_status.motor_stop_mask; + PX4_WARN("Stopping motors (%d)", _motor_stop_mask); + } + + if (failure_detector_status.fd_motor) { if (_handled_motor_failure_bitmask != failure_detector_status.motor_failure_mask) { // motor failure bitmask changed switch ((FailureMode)_param_ca_failure_mode.get()) { @@ -818,13 +872,110 @@ int ControlAllocator::print_status() PX4_INFO("Instance: %i", i); } - PX4_INFO(" Effectiveness.T ="); - effectiveness.T().print(); + PX4_INFO(" Effectiveness ="); + int num_configured = _control_allocation[i]->numConfiguredActuators(); + + // print column numbering + if (num_configured > 1) { + printf(" "); + + for (int col = 0; col < num_configured; col++) { + printf("|%2u ", col); + } + + printf("\n"); + } + + // Print effectiveness matrix with row labels + const char *row_labels[] = {"Mx", "My", "Mz", "Fx", "Fy", "Fz"}; + + for (int row = 0; row < 6; row++) { + printf("%2s|", row_labels[row]); + + for (int col = 0; col < num_configured; col++) { + double d = static_cast(effectiveness(row, col)); + + // avoid -0.0 for display + if (fabs(d - 0.0) < 1e-9) { + // print fixed width zero + printf(" 0 "); + + } else if ((fabs(d) < 1e-4) || (fabs(d) >= 10.0)) { + printf("% .1e ", d); + + } else { + printf("% 6.5f ", d); + } + } + + printf("\n"); + } + PX4_INFO(" minimum ="); - _control_allocation[i]->getActuatorMin().T().print(); + + // print column numbering + if (num_configured > 1) { + printf(" "); + + for (int col = 0; col < num_configured; col++) { + printf("|%2u ", col); + } + + printf("\n"); + } + + printf(" |"); + + for (int col = 0; col < num_configured; col++) { + double d = static_cast(_control_allocation[i]->getActuatorMin()(col)); + + // avoid -0.0 for display + if (fabs(d - 0.0) < 1e-9) { + // print fixed width zero + printf(" 0 "); + + } else if ((fabs(d) < 1e-4) || (fabs(d) >= 10.0)) { + printf("% .1e ", d); + + } else { + printf("% 6.5f ", d); + } + } + + printf("\n"); PX4_INFO(" maximum ="); - _control_allocation[i]->getActuatorMax().T().print(); - PX4_INFO(" Configured actuators: %i", _control_allocation[i]->numConfiguredActuators()); + + // print column numbering + if (num_configured > 1) { + printf(" "); + + for (int col = 0; col < num_configured; col++) { + printf("|%2u ", col); + } + + printf("\n"); + } + + printf(" |"); + + for (int col = 0; col < num_configured; col++) { + double d = static_cast(_control_allocation[i]->getActuatorMax()(col)); + + // avoid -0.0 for display + if (fabs(d - 0.0) < 1e-9) { + // print fixed width zero + printf(" 0 "); + + } else if ((fabs(d) < 1e-4) || (fabs(d) >= 10.0)) { + printf("% .1e ", d); + + } else { + printf("% 6.5f ", d); + } + } + + printf("\n"); + PX4_INFO(" Configured actuators: %i", num_configured); } if (_handled_motor_failure_bitmask) { diff --git a/src/modules/control_allocator/ControlAllocator.hpp b/src/modules/control_allocator/ControlAllocator.hpp index 14c30026d1..02fe81529f 100644 --- a/src/modules/control_allocator/ControlAllocator.hpp +++ b/src/modules/control_allocator/ControlAllocator.hpp @@ -89,6 +89,11 @@ public: static constexpr int MAX_NUM_MOTORS = actuator_motors_s::NUM_CONTROLS; static constexpr int MAX_NUM_SERVOS = actuator_servos_s::NUM_CONTROLS; + static constexpr float ICE_SHEDDING_MAX_SLEWRATE = 0.1f; + static constexpr float ICE_SHEDDING_ON_SEC = 2.0f; + static constexpr float ICE_SHEDDING_OUTPUT = 0.01f; + + using ActuatorVector = ActuatorEffectiveness::ActuatorVector; ControlAllocator(); @@ -139,6 +144,8 @@ private: void publish_actuator_controls(); + float get_ice_shedding_output(hrt_abstime now, bool any_stopped_motor_failed); + AllocationMethod _allocation_method_id{AllocationMethod::NONE}; ControlAllocation *_control_allocation[ActuatorEffectiveness::MAX_NUM_MATRICES] {}; ///< class for control allocation calculations int _num_control_allocation{0}; @@ -201,10 +208,12 @@ private: // Reflects motor failures that are currently handled, not motor failures that are reported. // For example, the system might report two motor failures, but only the first one is handled by CA uint16_t _handled_motor_failure_bitmask{0}; + uint16_t _motor_stop_mask{0}; perf_counter_t _loop_perf; /**< loop duration performance counter */ bool _armed{false}; + bool _is_vtol{false}; hrt_abstime _last_run{0}; hrt_abstime _timestamp_sample{0}; hrt_abstime _last_status_pub{0}; @@ -213,11 +222,16 @@ private: Params _params{}; bool _has_slew_rate{false}; + + SlewRate _slew_limited_ice_shedding_output; + hrt_abstime _last_ice_shedding_update{}; + DEFINE_PARAMETERS( (ParamInt) _param_ca_airframe, (ParamInt) _param_ca_method, (ParamInt) _param_ca_failure_mode, - (ParamInt) _param_r_rev + (ParamInt) _param_r_rev, + (ParamFloat) _param_ice_shedding_period ) }; diff --git a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.cpp b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.cpp index 46fea5f33e..1a781035a4 100644 --- a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.cpp +++ b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include "ActuatorEffectivenessControlSurfaces.hpp" @@ -58,10 +59,11 @@ ActuatorEffectivenessControlSurfaces::ActuatorEffectivenessControlSurfaces(Modul _param_handles[i].scale_spoiler = param_find(buffer); } - _flaps_setpoint_with_slewrate.setSlewRate(kFlapSlewRate); + _flaps_setpoint_with_slewrate.setSlewRate(_param_ca_flap_slew.get()); _spoilers_setpoint_with_slewrate.setSlewRate(kSpoilersSlewRate); _count_handle = param_find("CA_SV_CS_COUNT"); + _param_handle_ca_cs_laun_lk = param_find("CA_CS_LAUN_LK"); updateParams(); } @@ -74,6 +76,45 @@ void ActuatorEffectivenessControlSurfaces::updateParams() return; } + // Update flap slewrates + _flaps_setpoint_with_slewrate.setSlewRate(_param_ca_flap_slew.get()); + + // Helper to check if a PWM center parameter is enabled, and clamp it to valid range + auto check_pwm_center = [](const char *prefix, int channel) -> bool { + char param_name[17]; + snprintf(param_name, sizeof(param_name), "%s_CENT%d", prefix, channel); + param_t param = param_find(param_name); + + if (param != PARAM_INVALID) + { + int32_t value; + + if (param_get(param, &value) == PX4_OK && value != -1) { + // Clamp PWM center to valid range [800, 2200] + if (value < 800 || value > 2200) { + int32_t clamped = (value < 800) ? 800 : 2200; + PX4_WARN("%s_CENT%d (%d) out of range, clamping to %d", prefix, channel, (int)value, (int)clamped); + param_set(param, &clamped); + } + + return true; + } + } + + return false; + }; + + // Check if any PWM_MAIN or PWM_AUX center is configured + bool pwm_center_set = false; + + for (int i = 1; i <= 8; i++) { + if (check_pwm_center("PWM_MAIN", i) || check_pwm_center("PWM_AUX", i)) { + pwm_center_set = true; + } + } + + param_get(_param_handle_ca_cs_laun_lk, &_param_ca_cs_laun_lk); + for (int i = 0; i < _count; i++) { param_get(_param_handles[i].type, (int32_t *)&_params[i].type); @@ -84,6 +125,20 @@ void ActuatorEffectivenessControlSurfaces::updateParams() } param_get(_param_handles[i].trim, &_params[i].trim); + + // If PWM center is set and CA_SV_CS trim is non-zero, warn and reset to 0 + if (pwm_center_set && fabsf(_params[i].trim) > FLT_EPSILON) { + /* EVENT + * @description Display warning in GCS when TRIM settings were present and now CENTER are set. + */ + events::send(events::ID("control_surfaces_reset_trim"), events::Log::Warning, + "CA_SV_CS{1}_TRIM ({2}) is reset to 0 as PWM CENTER is used", i, _params[i].trim); + + _params[i].trim = 0.0f; + // Update the parameter storage + param_set(_param_handles[i].trim, &_params[i].trim); + } + param_get(_param_handles[i].scale_flap, &_params[i].scale_flap); param_get(_param_handles[i].scale_spoiler, &_params[i].scale_spoiler); @@ -182,3 +237,14 @@ void ActuatorEffectivenessControlSurfaces::applySpoilers(float spoilers_control, actuator_sp(i + first_actuator_idx) += _spoilers_setpoint_with_slewrate.getState() * _params[i].scale_spoiler; } } + +void ActuatorEffectivenessControlSurfaces::applyLaunchLock(int first_actuator_idx, + ActuatorVector &actuator_sp) +{ + for (int i = 0; i < _count; ++i) { + + if (_param_ca_cs_laun_lk & (1u << i)) { + actuator_sp(i + first_actuator_idx) = NAN; + } + } +} diff --git a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.hpp b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.hpp index 5e64e5a738..7da030fc18 100644 --- a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.hpp +++ b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessControlSurfaces.hpp @@ -38,7 +38,6 @@ #include #include -static constexpr float kFlapSlewRate = 0.5f; // slew rate for normalized flaps setpoint [1/s] static constexpr float kSpoilersSlewRate = 0.5f; // slew rate for normalized spoilers setpoint [1/s] class ActuatorEffectivenessControlSurfaces : public ModuleParams, public ActuatorEffectiveness @@ -91,6 +90,7 @@ public: void applyFlaps(float flaps_control, int first_actuator_idx, float dt, ActuatorVector &actuator_sp); void applySpoilers(float spoilers_control, int first_actuator_idx, float dt, ActuatorVector &actuator_sp); + void applyLaunchLock(int first_actuator_idx, ActuatorVector &actuator_sp); private: void updateParams() override; @@ -105,10 +105,15 @@ private: }; ParamHandles _param_handles[MAX_COUNT]; param_t _count_handle; + param_t _param_handle_ca_cs_laun_lk; Params _params[MAX_COUNT] {}; int32_t _count{0}; + int32_t _param_ca_cs_laun_lk{0}; SlewRate _flaps_setpoint_with_slewrate; SlewRate _spoilers_setpoint_with_slewrate; + DEFINE_PARAMETERS( + (ParamFloat) _param_ca_flap_slew + ) }; diff --git a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessFixedWing.cpp b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessFixedWing.cpp index e91783cf80..9a3c48e560 100644 --- a/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessFixedWing.cpp +++ b/src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessFixedWing.cpp @@ -65,6 +65,18 @@ void ActuatorEffectivenessFixedWing::updateSetpoint(const matrix::Vector +#include class ActuatorEffectivenessFixedWing : public ModuleParams, public ActuatorEffectiveness { @@ -60,6 +61,7 @@ private: uORB::Subscription _flaps_setpoint_sub{ORB_ID(flaps_setpoint)}; uORB::Subscription _spoilers_setpoint_sub{ORB_ID(spoilers_setpoint)}; + uORB::Subscription _launch_detection_status_sub{ORB_ID(launch_detection_status)}; int _first_control_surface_idx{0}; ///< applies to matrix 1 diff --git a/src/modules/control_allocator/module.yaml b/src/modules/control_allocator/module.yaml index 99d0d5ed85..93e8c6ddc4 100644 --- a/src/modules/control_allocator/module.yaml +++ b/src/modules/control_allocator/module.yaml @@ -312,7 +312,11 @@ parameters: CA_SV_CS${i}_TRIM: description: short: Control Surface ${i} trim - long: Can be used to add an offset to the servo control. + long: | + Can be used to add an offset to the servo control. + + NOTE: Do not use for PWM servos. Use the PWM CENTER parameters instead (e.g., PWM_MAIN_CENT, PWM_AUX_CENT) instead. + This parameter can only be set if all PWM Center parameters are set to default. type: float decimal: 2 min: -1.0 @@ -332,6 +336,15 @@ parameters: instance_start: 0 default: 0 + CA_SV_FLAP_SLEW: + description: + short: Control Surface slew rate for normalized flaps setpoint + type: float + decimal: 1 + min: 0.0 + max: 5.0 + default: 0.5 + CA_SV_CS${i}_SPOIL: description: short: Control Surface ${i} configuration as spoiler @@ -343,6 +356,22 @@ parameters: instance_start: 0 default: 0 + CA_CS_LAUN_LK: + description: + short: Control surface launch lock enabled + long: If actuator launch lock is enabled, this surface is kept at the disarmed value. + type: bitmask + bit: + 0: Control Surface 1 + 1: Control Surface 2 + 2: Control Surface 3 + 3: Control Surface 4 + 4: Control Surface 5 + 5: Control Surface 6 + 6: Control Surface 7 + 7: Control Surface 8 + default: 0 + # Tilts CA_SV_TL_COUNT: description: @@ -592,6 +621,22 @@ parameters: 1: Remove first failed motor from effectiveness default: 0 + CA_ICE_PERIOD: + description: + short: Ice shedding cycle period + long: | + Ice shedding prevents ice buildup in VTOL aircraft motors by + periodically spinning inactive rotors. When enabled (period + > 0), every cycle lasts for the defined period and includes + a 2‑second spin at 0.01 motor output. If period <= 0, the + feature is disabled. + type: float + decimal: 1 + unit: s + increment: 0.1 + min: 0.0 + default: 0.0 + # Mixer mixer: actuator_types: @@ -630,7 +675,7 @@ mixer: rules: - select_identifier: 'servo-type' # restrict torque based on servo type - apply_identifiers: ['servo-torque-roll', 'servo-torque-pitch', 'servo-torque-yaw', 'servo-scale-flap', 'servo-scale-spoiler'] + apply_identifiers: ['servo-torque-roll', 'servo-torque-pitch', 'servo-torque-yaw', 'servo-scale-flap', 'servo-scale-spoiler', 'servo-launch-lock'] items: # Convention: horizontal surfaces: up=positive, vertical: right=positive, mixed: up=positive. # By default the scale is set to 1/N, where N is the amount of actuators with an effect on @@ -829,6 +874,12 @@ mixer: label: 'Spoiler Scale' advanced: true identifier: 'servo-scale-spoiler' + - name: 'CA_CS_LAUN_LK' + label: 'Launch Lock' + advanced: true + identifier: 'servo-launch-lock' + index_offset: 0 + show_as: 'bitset' 2: # Standard VTOL title: 'Standard VTOL' diff --git a/src/modules/dataman/dataman.cpp b/src/modules/dataman/dataman.cpp index 8cefa477bc..ae5d294fda 100644 --- a/src/modules/dataman/dataman.cpp +++ b/src/modules/dataman/dataman.cpp @@ -63,7 +63,11 @@ __BEGIN_DECLS __EXPORT int dataman_main(int argc, char *argv[]); __END_DECLS +#ifdef CONFIG_FS_LITTLEFS +static constexpr int TASK_STACK_SIZE = 2000; /* littlefs needs more stack */ +#else static constexpr int TASK_STACK_SIZE = 1420; +#endif #ifdef CONFIG_DATAMAN_PERSISTENT_STORAGE /* Private File based Operations */ diff --git a/src/modules/ekf2/EKF/aid_sources/airspeed/airspeed_fusion.cpp b/src/modules/ekf2/EKF/aid_sources/airspeed/airspeed_fusion.cpp index 2e324663de..49d5b4f396 100644 --- a/src/modules/ekf2/EKF/aid_sources/airspeed/airspeed_fusion.cpp +++ b/src/modules/ekf2/EKF/aid_sources/airspeed/airspeed_fusion.cpp @@ -93,10 +93,8 @@ void Ekf::controlAirDataFusion(const imuSample &imu_delayed) updateAirspeed(airspeed_sample, _aid_src_airspeed); - _innov_check_fail_status.flags.reject_airspeed = - _aid_src_airspeed.innovation_rejected; // TODO: remove this redundant flag - - const bool continuing_conditions_passing = _control_status.flags.in_air + const bool continuing_conditions_passing = _control_status.flags.in_air && (_control_status.flags.fixed_wing + || _control_status.flags.in_transition_to_fw) && !_control_status.flags.fake_pos; const bool is_airspeed_significant = airspeed_sample.true_airspeed > _params.ekf2_arsp_thr; @@ -126,20 +124,38 @@ void Ekf::controlAirDataFusion(const imuSample &imu_delayed) } } else if (starting_conditions_passing) { - ECL_INFO("starting airspeed fusion"); + const bool do_vel_reset = _horizontal_deadreckon_time_exceeded + || (_control_status.flags.inertial_dead_reckoning && !is_airspeed_consistent); + + const Vector2f wind_vel_var = getWindVelocityVariance(); + const bool do_wind_reset = (!_control_status.flags.wind || ((wind_vel_var(0) + wind_vel_var(1)) > sq(_params.initial_wind_uncertainty))) + && !_external_wind_init; + + if (do_vel_reset) { + if (do_wind_reset) { + resetWindCov(); + _state.wind_vel.zero(); + } - if (_control_status.flags.inertial_dead_reckoning && !is_airspeed_consistent) { resetVelUsingAirspeed(airspeed_sample); + ECL_INFO("Reset velocity using airspeed (%.3f)", + (double)airspeed_sample.true_airspeed); - } else if (!_external_wind_init && !_synthetic_airspeed - && (!_control_status.flags.wind - || getWindVelocityVariance().longerThan(sq(_params.initial_wind_uncertainty)))) { + } else if (do_wind_reset) { resetWindUsingAirspeed(airspeed_sample); + ECL_INFO("Reset wind using airspeed (%.3f)", + (double)airspeed_sample.true_airspeed); _aid_src_airspeed.time_last_fuse = _time_delayed_us; + + } else { + fuseAirspeed(airspeed_sample, _aid_src_airspeed); } - _control_status.flags.wind = true; - _control_status.flags.fuse_aspd = true; + if (do_vel_reset || do_wind_reset || _aid_src_airspeed.fused) { + ECL_INFO("starting airspeed fusion"); + _control_status.flags.wind = true; + _control_status.flags.fuse_aspd = true; + } } } else if (_control_status.flags.fuse_aspd && !isRecent(_airspeed_sample_delayed.time_us, (uint64_t)1e6)) { diff --git a/src/modules/ekf2/EKF/aid_sources/aux_global_position/aux_global_position.hpp b/src/modules/ekf2/EKF/aid_sources/aux_global_position/aux_global_position.hpp index 8740c2851e..8777be409a 100644 --- a/src/modules/ekf2/EKF/aid_sources/aux_global_position/aux_global_position.hpp +++ b/src/modules/ekf2/EKF/aid_sources/aux_global_position/aux_global_position.hpp @@ -43,7 +43,7 @@ // WelfordMean for rate #include "../../common.h" -#include "../../RingBuffer.h" +#include #if defined(CONFIG_EKF2_AUX_GLOBAL_POSITION) && defined(MODULE_NAME) @@ -95,7 +95,7 @@ private: }; estimator_aid_source2d_s _aid_src_aux_global_position{}; - RingBuffer _aux_global_position_buffer{20}; // TODO: size with _obs_buffer_length and actual publication rate + TimestampedRingBuffer _aux_global_position_buffer{20}; // TODO: size with _obs_buffer_length and actual publication rate uint64_t _time_last_buffer_push{0}; enum class Ctrl : uint8_t { diff --git a/src/modules/ekf2/EKF/aid_sources/external_vision/ev_vel.h b/src/modules/ekf2/EKF/aid_sources/external_vision/ev_vel.h index d392246888..10d6b64cf4 100644 --- a/src/modules/ekf2/EKF/aid_sources/external_vision/ev_vel.h +++ b/src/modules/ekf2/EKF/aid_sources/external_vision/ev_vel.h @@ -57,7 +57,7 @@ public: virtual ~ExternalVisionVel() = default; virtual bool fuseVelocity(estimator_aid_source3d_s &aid_src, float gate) { - _ekf.fuseLocalFrameVelocity(aid_src, aid_src.timestamp, _measurement, + _ekf.fuseLocalFrameVelocity(aid_src, _sample.time_us, _measurement, _measurement_var, gate); return aid_src.fused; diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp index 83f82da3ce..e9077e8bdd 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.cpp @@ -49,6 +49,11 @@ bool GnssChecks::run(const gnssSample &gnss, uint64_t time_us) bool passed = false; + // Run strict checks while not flying yet + if (!_control_status.flags.in_air) { + _initial_checks_passed = false; + } + if (_initial_checks_passed) { if (runSimplifiedChecks(gnss)) { _time_last_pass_us = time_us; @@ -91,6 +96,7 @@ bool GnssChecks::runSimplifiedChecks(const gnssSample &gnss) _check_fail_status.flags.sacc = (gnss.sacc > 10.f); _check_fail_status.flags.spoofed = gnss.spoofed; + _check_fail_status.flags.jammed = gnss.jammed; bool passed = true; @@ -99,7 +105,8 @@ bool GnssChecks::runSimplifiedChecks(const gnssSample &gnss) (_check_fail_status.flags.hacc && isCheckEnabled(GnssChecksMask::kHacc)) || (_check_fail_status.flags.vacc && isCheckEnabled(GnssChecksMask::kVacc)) || (_check_fail_status.flags.sacc && isCheckEnabled(GnssChecksMask::kSacc)) || - (_check_fail_status.flags.spoofed && isCheckEnabled(GnssChecksMask::kSpoofed)) + (_check_fail_status.flags.spoofed && isCheckEnabled(GnssChecksMask::kSpoofed)) || + (_check_fail_status.flags.jammed && isCheckEnabled(GnssChecksMask::kJammed)) ) { passed = false; } @@ -126,6 +133,7 @@ bool GnssChecks::runInitialFixChecks(const gnssSample &gnss) _check_fail_status.flags.sacc = (gnss.sacc > _params.ekf2_req_sacc); _check_fail_status.flags.spoofed = gnss.spoofed; + _check_fail_status.flags.jammed = gnss.jammed; runOnGroundGnssChecks(gnss); @@ -153,7 +161,8 @@ bool GnssChecks::runInitialFixChecks(const gnssSample &gnss) (_check_fail_status.flags.vdrift && isCheckEnabled(GnssChecksMask::kVdrift)) || (_check_fail_status.flags.hspeed && isCheckEnabled(GnssChecksMask::kHspd)) || (_check_fail_status.flags.vspeed && isCheckEnabled(GnssChecksMask::kVspd)) || - (_check_fail_status.flags.spoofed && isCheckEnabled(GnssChecksMask::kSpoofed)) + (_check_fail_status.flags.spoofed && isCheckEnabled(GnssChecksMask::kSpoofed)) || + (_check_fail_status.flags.jammed && isCheckEnabled(GnssChecksMask::kJammed)) ) { passed = false; } diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.hpp b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.hpp index 70b133ee70..0d2fe978e7 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.hpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_checks.hpp @@ -63,6 +63,7 @@ public: uint16_t hspeed : 1; ///< 8 - true if horizontal speed is excessive (can only be used when stationary on ground) uint16_t vspeed : 1; ///< 9 - true if vertical speed error is excessive uint16_t spoofed: 1; ///< 10 - true if the GNSS data is spoofed + uint16_t jammed : 1; ///< 11 - true if the GNSS data is jammed } flags; uint16_t value; }; @@ -108,7 +109,8 @@ private: kHspd = (1 << 7), kVspd = (1 << 8), kSpoofed = (1 << 9), - kFix = (1 << 10) + kFix = (1 << 10), + kJammed = (1 << 11) }; bool isCheckEnabled(GnssChecksMask check) { return (_params.check_mask & static_cast(check)); } diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_height_control.cpp b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_height_control.cpp index c604e416b8..80ec82a883 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_height_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_height_control.cpp @@ -106,7 +106,7 @@ void Ekf::controlGnssHeightFusion(const gnssSample &gps_sample) const bool is_fusion_failing = isTimedOut(aid_src.time_last_fuse, _params.hgt_fusion_timeout_max); - if (isHeightResetRequired() && (_height_sensor_ref == HeightSensor::GNSS)) { + if (isHeightResetRequired() && (_height_sensor_ref == HeightSensor::GNSS) && isGnssHgtResetAllowed()) { // All height sources are failing ECL_WARN("%s height fusion reset required, all height sources failing", HGT_SRC_NAME); @@ -121,6 +121,11 @@ void Ekf::controlGnssHeightFusion(const gnssSample &gps_sample) // Some other height source is still working ECL_WARN("stopping %s height fusion, fusion failing", HGT_SRC_NAME); stopGpsHgtFusion(); + + if (!isGnssHgtResetAllowed()) { + _control_status.flags.gnss_hgt_fault = true; + _time_last_gnss_hgt_rejected = _time_delayed_us; + } } } else { @@ -129,34 +134,57 @@ void Ekf::controlGnssHeightFusion(const gnssSample &gps_sample) } } else { - if (starting_conditions_passing) { - if (_params.ekf2_hgt_ref == static_cast(HeightSensor::GNSS)) { - ECL_INFO("starting %s height fusion, resetting height", HGT_SRC_NAME); - _height_sensor_ref = HeightSensor::GNSS; + if (altitude_initialisation_conditions_passing) { + // Altitude not initialized, GNSS is the configured height reference + _information_events.flags.reset_hgt_to_gps = true; + initialiseAltitudeTo(measurement, measurement_var); + bias_est.reset(); + // Start fusion if GPS vertical position control is also enabled + if (starting_conditions_passing) { + _height_sensor_ref = HeightSensor::GNSS; + resetAidSourceStatusZeroInnovation(aid_src); + aid_src.time_last_fuse = _time_delayed_us; + bias_est.setFusionActive(); + _control_status.flags.gps_hgt = true; + } + + } else if (starting_conditions_passing) { + if (_params.ekf2_hgt_ref == static_cast(HeightSensor::GNSS) && isGnssHgtResetAllowed()) { + _height_sensor_ref = HeightSensor::GNSS; _information_events.flags.reset_hgt_to_gps = true; - initialiseAltitudeTo(measurement, measurement_var); + resetAltitudeTo(measurement, measurement_var); bias_est.reset(); resetAidSourceStatusZeroInnovation(aid_src); + aid_src.time_last_fuse = _time_delayed_us; + bias_est.setFusionActive(); + _control_status.flags.gps_hgt = true; + _control_status.flags.gnss_hgt_fault = false; + } else { - ECL_INFO("starting %s height fusion", HGT_SRC_NAME); - bias_est.setBias(-_gpos.altitude() + measurement); + bool is_gnss_hgt_consistent = true; + + if (_control_status.flags.gnss_hgt_fault) { + if (aid_src.innovation_rejected) { + _time_last_gnss_hgt_rejected = _time_delayed_us; + } + + is_gnss_hgt_consistent = isTimedOut(_time_last_gnss_hgt_rejected, _params.hgt_fusion_timeout_max); + } + + if (is_gnss_hgt_consistent) { + if (_params.ekf2_hgt_ref != static_cast(HeightSensor::GNSS)) { + bias_est.setBias(-_gpos.altitude() + measurement); + } + + aid_src.time_last_fuse = _time_delayed_us; + bias_est.setFusionActive(); + _control_status.flags.gps_hgt = true; + _control_status.flags.gnss_hgt_fault = false; + } } - - aid_src.time_last_fuse = _time_delayed_us; - bias_est.setFusionActive(); - _control_status.flags.gps_hgt = true; - - } if (altitude_initialisation_conditions_passing) { - - // Do not start GNSS altitude aiding, but use measurement - // to initialize altitude and bias of other height sensors - _information_events.flags.reset_hgt_to_gps = true; - - initialiseAltitudeTo(measurement, measurement_var); - bias_est.reset(); } } @@ -181,3 +209,12 @@ void Ekf::stopGpsHgtFusion() _control_status.flags.gps_hgt = false; } } + +bool Ekf::isGnssHgtResetAllowed() +{ + const bool allowed = !(static_cast(_params.ekf2_gps_mode) == GnssMode::kDeadReckoning + && isOtherSourceOfVerticalPositionAidingThan(_control_status.flags.gps_hgt)) + || !PX4_ISFINITE(_local_origin_alt); + + return allowed; +} diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_yaw_control.cpp b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_yaw_control.cpp index a0d2c4cb66..709fb76211 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gnss_yaw_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gnss_yaw_control.cpp @@ -159,7 +159,6 @@ void Ekf::fuseGnssYaw(float antenna_yaw_offset) auto &aid_src = _aid_src_gnss_yaw; if (aid_src.innovation_rejected) { - _innov_check_fail_status.flags.reject_yaw = true; return; } @@ -189,7 +188,6 @@ void Ekf::fuseGnssYaw(float antenna_yaw_offset) } _fault_status.flags.bad_hdg = false; - _innov_check_fail_status.flags.reject_yaw = false; if ((fabsf(aid_src.test_ratio_filtered) > 0.2f) && !_control_status.flags.in_air && isTimedOut(aid_src.time_last_fuse, (uint64_t)1e6) diff --git a/src/modules/ekf2/EKF/aid_sources/gnss/gps_control.cpp b/src/modules/ekf2/EKF/aid_sources/gnss/gps_control.cpp index d265a0bc26..6b523fad28 100644 --- a/src/modules/ekf2/EKF/aid_sources/gnss/gps_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gnss/gps_control.cpp @@ -104,12 +104,17 @@ void Ekf::controlGpsFusion(const imuSample &imu_delayed) bool do_vel_pos_reset = false; - if (!_control_status.flags.gnss_fault && (_control_status.flags.gnss_vel || _control_status.flags.gnss_pos)) { + if (!_control_status.flags.gnss_fault && _control_status.flags.in_air && isYawFailure()) { + const bool velocity_fusion_failure = _aid_src_gnss_vel.innovation_rejected + && isTimedOut(_time_last_hor_vel_fuse, _params.EKFGSF_reset_delay) + && (_time_last_hor_vel_fuse > _time_last_on_ground_us); - if (_control_status.flags.in_air - && isYawFailure() - && isTimedOut(_time_last_hor_vel_fuse, _params.EKFGSF_reset_delay) - && (_time_last_hor_vel_fuse > _time_last_on_ground_us)) { + const bool position_fusion_failure = _aid_src_gnss_pos.innovation_rejected + && isTimedOut(_time_last_hor_pos_fuse, _params.EKFGSF_reset_delay) + && (_time_last_hor_pos_fuse > _time_last_on_ground_us); + + if ((_control_status.flags.gnss_vel && velocity_fusion_failure) + || (_control_status.flags.gnss_pos && position_fusion_failure)) { do_vel_pos_reset = tryYawEmergencyReset(); } } @@ -124,7 +129,8 @@ void Ekf::controlGnssVelFusion(estimator_aid_source3d_s &aid_src, const bool for const bool continuing_conditions_passing = (_params.ekf2_gps_ctrl & static_cast(GnssCtrl::VEL)) && _control_status.flags.tilt_align && _control_status.flags.yaw_align - && !_control_status.flags.gnss_fault; + && !_control_status.flags.gnss_fault + && !_control_status.flags.gnss_hgt_fault; const bool starting_conditions_passing = continuing_conditions_passing && _gnss_checks.passed(); if (_control_status.flags.gnss_vel) { @@ -180,7 +186,8 @@ void Ekf::controlGnssPosFusion(estimator_aid_source2d_s &aid_src, const bool for const bool continuing_conditions_passing = gnss_pos_enabled && _control_status.flags.tilt_align - && _control_status.flags.yaw_align; + && _control_status.flags.yaw_align + && !_control_status.flags.gnss_hgt_fault; const bool starting_conditions_passing = continuing_conditions_passing && _gnss_checks.passed(); const bool gpos_init_conditions_passing = gnss_pos_enabled && _gnss_checks.passed(); @@ -522,14 +529,6 @@ bool Ekf::resetYawToEKFGSF() return false; } - // don't allow reset if there's just been a yaw reset - const bool yaw_alignment_changed = (_control_status_prev.flags.yaw_align != _control_status.flags.yaw_align); - const bool quat_reset = (_state_reset_status.reset_count.quat != _state_reset_count_prev.quat); - - if (yaw_alignment_changed || quat_reset) { - return false; - } - ECL_INFO("yaw estimator reset heading %.3f -> %.3f rad", (double)getEulerYaw(_R_to_earth), (double)_yawEstimator.getYaw()); diff --git a/src/modules/ekf2/EKF/aid_sources/gravity/gravity_fusion.cpp b/src/modules/ekf2/EKF/aid_sources/gravity/gravity_fusion.cpp index c88f7f7542..3a5e5447bb 100644 --- a/src/modules/ekf2/EKF/aid_sources/gravity/gravity_fusion.cpp +++ b/src/modules/ekf2/EKF/aid_sources/gravity/gravity_fusion.cpp @@ -81,6 +81,8 @@ void Ekf::controlGravityFusion(const imuSample &imu) 0.25f); // innovation gate // update the states and covariance using sequential fusion + bool fused[3] {}; + for (uint8_t index = 0; index <= 2; index++) { // Calculate Kalman gains and observation jacobians if (index == 0) { @@ -108,10 +110,16 @@ void Ekf::controlGravityFusion(const imuSample &imu) const bool accel_clipping = imu.delta_vel_clipping[0] || imu.delta_vel_clipping[1] || imu.delta_vel_clipping[2]; if (_control_status.flags.gravity_vector && !_aid_src_gravity.innovation_rejected && !accel_clipping) { - measurementUpdate(K, H, _aid_src_gravity.observation_variance[index], _aid_src_gravity.innovation[index]); + fused[index] = measurementUpdate(K, H, + _aid_src_gravity.observation_variance[index], _aid_src_gravity.innovation[index]); } } - _aid_src_gravity.fused = true; - _aid_src_gravity.time_last_fuse = imu.time_us; + if (fused[0] && fused[1] && fused[2]) { + _aid_src_gravity.fused = true; + _aid_src_gravity.time_last_fuse = imu.time_us; + + } else { + _aid_src_gravity.fused = false; + } } diff --git a/src/modules/ekf2/EKF/aid_sources/magnetometer/mag_control.cpp b/src/modules/ekf2/EKF/aid_sources/magnetometer/mag_control.cpp index 991f7bc75f..06dd0b4c80 100644 --- a/src/modules/ekf2/EKF/aid_sources/magnetometer/mag_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/magnetometer/mag_control.cpp @@ -149,11 +149,6 @@ void Ekf::controlMagFusion(const imuSample &imu_sample) innov_var, // innovation variance math::max(_params.ekf2_mag_gate, 1.f)); // innovation gate - // Perform an innovation consistency check and report the result - _innov_check_fail_status.flags.reject_mag_x = (aid_src.test_ratio[0] > 1.f); - _innov_check_fail_status.flags.reject_mag_y = (aid_src.test_ratio[1] > 1.f); - _innov_check_fail_status.flags.reject_mag_z = (aid_src.test_ratio[2] > 1.f); - // determine if we should use mag fusion bool continuing_conditions_passing = ((_params.ekf2_mag_type == MagFuseType::INIT) || (_params.ekf2_mag_type == MagFuseType::AUTO) @@ -173,7 +168,14 @@ void Ekf::controlMagFusion(const imuSample &imu_sample) checkMagHeadingConsistency(mag_sample); + if (_control_status.flags.mag_fault && _control_status.flags.mag_heading_consistent + && _control_status.flags.mag + && isTimedOut(_time_last_heading_fuse, _params.reset_timeout_max)) { + _control_status.flags.mag_fault = false; + } + { + const bool mag_consistent_or_no_ne_aiding = _control_status.flags.mag_heading_consistent || !isNorthEastAidingActive(); const bool common_conditions_passing = _control_status.flags.mag && ((_control_status.flags.yaw_align && mag_consistent_or_no_ne_aiding) @@ -181,7 +183,8 @@ void Ekf::controlMagFusion(const imuSample &imu_sample) && !_control_status.flags.mag_fault && !_control_status.flags.mag_field_disturbed && !_control_status.flags.ev_yaw - && !_control_status.flags.gnss_yaw; + && !_control_status.flags.gnss_yaw + && (!_control_status.flags.yaw_manual || _control_status.flags.mag_aligned_in_flight); _control_status.flags.mag_3D = common_conditions_passing && (_params.ekf2_mag_type == MagFuseType::AUTO) @@ -192,8 +195,6 @@ void Ekf::controlMagFusion(const imuSample &imu_sample) || (_params.ekf2_mag_type == MagFuseType::AUTO && !_control_status.flags.mag_3D)); } - // TODO: allow clearing mag_fault if mag_3d is good? - if (_control_status.flags.mag_3D && !_control_status_prev.flags.mag_3D) { ECL_INFO("starting mag 3D fusion"); @@ -210,9 +211,18 @@ void Ekf::controlMagFusion(const imuSample &imu_sample) if (continuing_conditions_passing && _control_status.flags.yaw_align) { - if ((checkHaglYawResetReq() && (_control_status.flags.mag_hdg || _control_status.flags.mag_3D)) - || (wmm_updated && no_ne_aiding_or_not_moving)) { + if (checkHaglYawResetReq() && (_control_status.flags.mag_hdg || _control_status.flags.mag_3D + || _control_status.flags.yaw_manual)) { ECL_INFO("reset to %s", AID_SRC_NAME); + const bool reset_heading = ((_control_status.flags.mag_hdg || _control_status.flags.mag_3D) && !isNorthEastAidingActive()); + resetMagStates(_mag_lpf.getState(), reset_heading); + + // record the start time for the magnetic field alignment + _control_status.flags.mag_aligned_in_flight = true; + _flt_mag_align_start_time = _time_delayed_us; + aid_src.time_last_fuse = imu_sample.time_us; + + } else if (wmm_updated && no_ne_aiding_or_not_moving) { const bool reset_heading = _control_status.flags.mag_hdg || _control_status.flags.mag_3D; resetMagStates(_mag_lpf.getState(), reset_heading); aid_src.time_last_fuse = imu_sample.time_us; @@ -446,12 +456,6 @@ void Ekf::resetMagStates(const Vector3f &mag, bool reset_heading) (double)mag_B_before_reset(0), (double)mag_B_before_reset(1), (double)mag_B_before_reset(2), (double)_state.mag_B(0), (double)_state.mag_B(1), (double)_state.mag_B(2)); } - - // record the start time for the magnetic field alignment - if (_control_status.flags.in_air && reset_heading) { - _control_status.flags.mag_aligned_in_flight = true; - _flt_mag_align_start_time = _time_delayed_us; - } } void Ekf::checkMagHeadingConsistency(const magSample &mag_sample) @@ -473,16 +477,17 @@ void Ekf::checkMagHeadingConsistency(const magSample &mag_sample) const Vector3f mag_earth_pred = R_to_earth * (mag_sample.mag - mag_bias); const float declination = getMagDeclination(); const float measured_hdg = -atan2f(mag_earth_pred(1), mag_earth_pred(0)) + declination; + float innovation = wrap_pi(getEulerYaw(_R_to_earth) - measured_hdg); if (_control_status.flags.yaw_align) { - const float innovation = wrap_pi(getEulerYaw(_R_to_earth) - measured_hdg); _mag_heading_innov_lpf.update(innovation); } else { - _mag_heading_innov_lpf.reset(0.f); + innovation = 0.f; + _mag_heading_innov_lpf.reset(innovation); } - if (fabsf(_mag_heading_innov_lpf.getState()) < _params.ekf2_head_noise) { + if ((fabsf(_mag_heading_innov_lpf.getState()) < _params.ekf2_head_noise) && (fabsf(innovation) < _params.ekf2_head_noise)) { // Check if there has been enough change in horizontal velocity to make yaw observable if (isNorthEastAidingActive() && (_accel_horiz_lpf.getState().longerThan(_params.ekf2_mag_acclim))) { @@ -593,8 +598,6 @@ void Ekf::resetMagHeading(const Vector3f &mag) // update quaternion states and corresponding covarainces resetQuatStateYaw(yaw_new, yaw_new_variance); - _time_last_heading_fuse = _time_delayed_us; - _mag_heading_innov_lpf.reset(0.f); _control_status.flags.mag_heading_consistent = true; } diff --git a/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_control.cpp b/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_control.cpp index 7774147610..fa6f70ab4e 100644 --- a/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_control.cpp @@ -233,9 +233,6 @@ void Ekf::resetFlowFusion(const flowSample &flow_sample) resetHorizontalVelocityTo(getFilteredFlowVelNE(), flow_vel_var); resetAidSourceStatusZeroInnovation(_aid_src_optical_flow); - - _innov_check_fail_status.flags.reject_optflow_X = false; - _innov_check_fail_status.flags.reject_optflow_Y = false; } void Ekf::resetTerrainToFlow() @@ -265,10 +262,6 @@ void Ekf::resetTerrainToFlow() resetAidSourceStatusZeroInnovation(_aid_src_optical_flow); - _innov_check_fail_status.flags.reject_optflow_X = false; - _innov_check_fail_status.flags.reject_optflow_Y = false; - - // record the state change if (_state_reset_status.reset_count.hagl == _state_reset_count_prev.hagl) { _state_reset_status.hagl_change = delta_terrain; @@ -291,9 +284,6 @@ void Ekf::stopFlowFusion() _fault_status.flags.bad_optflow_X = false; _fault_status.flags.bad_optflow_Y = false; - _innov_check_fail_status.flags.reject_optflow_X = false; - _innov_check_fail_status.flags.reject_optflow_Y = false; - _flow_counter = 0; } } diff --git a/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_fusion.cpp b/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_fusion.cpp index 8e193cc46b..e2c72be9be 100644 --- a/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_fusion.cpp +++ b/src/modules/ekf2/EKF/aid_sources/optical_flow/optical_flow_fusion.cpp @@ -48,8 +48,6 @@ bool Ekf::fuseOptFlow(VectorState &H, const bool update_terrain) // if either axis fails we abort the fusion if (_aid_src_optical_flow.innovation_rejected) { - _innov_check_fail_status.flags.reject_optflow_X = true; - _innov_check_fail_status.flags.reject_optflow_Y = true; return false; } @@ -100,9 +98,6 @@ bool Ekf::fuseOptFlow(VectorState &H, const bool update_terrain) _fault_status.flags.bad_optflow_X = false; _fault_status.flags.bad_optflow_Y = false; - _innov_check_fail_status.flags.reject_optflow_X = (_aid_src_optical_flow.test_ratio[0] > 1.f); - _innov_check_fail_status.flags.reject_optflow_Y = (_aid_src_optical_flow.test_ratio[1] > 1.f); - _aid_src_optical_flow.time_last_fuse = _time_delayed_us; _aid_src_optical_flow.fused = true; diff --git a/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_control.cpp b/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_control.cpp index 35d56422f2..3e092e8342 100644 --- a/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_control.cpp +++ b/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_control.cpp @@ -81,6 +81,7 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) // If we are supposed to be using range finder data but have bad range measurements // and are on the ground, then synthesise a measurement at the expected on ground value if (!_control_status.flags.in_air + && _control_status.flags.vehicle_at_rest && _range_sensor.isRegularlySendingData() && _range_sensor.isDataReady()) { @@ -99,20 +100,42 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) if (rng_data_ready && _range_sensor.getSampleAddress()) { - updateRangeHagl(aid_src); + const float measurement = math::max(_range_sensor.getDistBottom(), _params.ekf2_min_rng); + const float measurement_variance = getRngVar(); + + float innovation_variance; + sym::ComputeHaglInnovVar(P, measurement_variance, &innovation_variance); + + const float innov_gate = math::max(_params.ekf2_rng_gate, 1.f); + updateAidSourceStatus(aid_src, + _range_sensor.getSampleAddress()->time_us, // sample timestamp + measurement, // observation + measurement_variance, // observation variance + getHagl() - measurement, // innovation + innovation_variance, // innovation variance + innov_gate); // innovation gate + const bool measurement_valid = PX4_ISFINITE(aid_src.observation) && PX4_ISFINITE(aid_src.observation_variance); + // z special case if there is bad vertical acceleration data, then don't reject measurement, + // but limit innovation to prevent spikes that could destabilise the filter + if (_fault_status.flags.bad_acc_vertical && aid_src.innovation_rejected + && measurement_valid && _range_sensor.isDataHealthy() + ) { + const float innov_limit = innov_gate * sqrtf(aid_src.innovation_variance); + aid_src.innovation = math::constrain(aid_src.innovation, -innov_limit, innov_limit); + aid_src.innovation_rejected = false; + } + const bool continuing_conditions_passing = ((_params.ekf2_rng_ctrl == static_cast(RngCtrl::ENABLED)) || (_params.ekf2_rng_ctrl == static_cast(RngCtrl::CONDITIONAL))) && _control_status.flags.tilt_align - && measurement_valid - && _range_sensor.isDataHealthy() - && _rng_consistency_check.isKinematicallyConsistent(); + && measurement_valid; const bool starting_conditions_passing = continuing_conditions_passing && isNewestSampleRecent(_time_last_range_buffer_push, 2 * estimator::sensor::RNG_MAX_INTERVAL) - && _range_sensor.isRegularlySendingData(); - + && _range_sensor.isRegularlySendingData() + && _range_sensor.isDataHealthy(); const bool do_conditional_range_aid = (_control_status.flags.rng_terrain || _control_status.flags.rng_hgt) && (_params.ekf2_rng_ctrl == static_cast(RngCtrl::CONDITIONAL)) @@ -127,7 +150,7 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) stopRngHgtFusion(); } - } else { + } else if (starting_conditions_passing) { if (_params.ekf2_hgt_ref == static_cast(HeightSensor::RANGE)) { if (do_conditional_range_aid) { // Range finder is used while hovering to stabilize the height estimate. Don't reset but use it as height reference. @@ -164,6 +187,7 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) _control_status.flags.rng_hgt = true; if (!_control_status.flags.opt_flow_terrain && aid_src.innovation_rejected) { + ECL_INFO("starting %s height fusion, resetting terrain", HGT_SRC_NAME); resetTerrainToRng(aid_src); resetAidSourceStatusZeroInnovation(aid_src); } @@ -174,11 +198,26 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) if (_control_status.flags.rng_hgt || _control_status.flags.rng_terrain) { if (continuing_conditions_passing) { - fuseHaglRng(aid_src, _control_status.flags.rng_hgt, _control_status.flags.rng_terrain); + if (do_conditional_range_aid) { + _height_sensor_ref = HeightSensor::RANGE; + + } else if (_height_sensor_ref == HeightSensor::RANGE) { + _height_sensor_ref = HeightSensor::UNKNOWN; + } + + if (_range_sensor.isDataHealthy() + && _control_status.flags.rng_kin_consistent + ) { + fuseHaglRng(aid_src, _control_status.flags.rng_hgt, _control_status.flags.rng_terrain); + } const bool is_fusion_failing = isTimedOut(aid_src.time_last_fuse, _params.hgt_fusion_timeout_max); - if (isHeightResetRequired() && _control_status.flags.rng_hgt && (_height_sensor_ref == HeightSensor::RANGE)) { + if (isHeightResetRequired() + && _control_status.flags.rng_hgt + && (_height_sensor_ref == HeightSensor::RANGE) + && starting_conditions_passing + ) { // All height sources are failing ECL_WARN("%s height fusion reset required, all height sources failing", HGT_SRC_NAME); @@ -200,7 +239,7 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) stopRngHgtFusion(); stopRngTerrFusion(); - } else { + } else if (starting_conditions_passing) { resetTerrainToRng(aid_src); resetAidSourceStatusZeroInnovation(aid_src); } @@ -240,32 +279,6 @@ void Ekf::controlRangeHaglFusion(const imuSample &imu_sample) } } -void Ekf::updateRangeHagl(estimator_aid_source1d_s &aid_src) -{ - const float measurement = math::max(_range_sensor.getDistBottom(), _params.ekf2_min_rng); - const float measurement_variance = getRngVar(); - - float innovation_variance; - sym::ComputeHaglInnovVar(P, measurement_variance, &innovation_variance); - - const float innov_gate = math::max(_params.ekf2_rng_gate, 1.f); - updateAidSourceStatus(aid_src, - _range_sensor.getSampleAddress()->time_us, // sample timestamp - measurement, // observation - measurement_variance, // observation variance - getHagl() - measurement, // innovation - innovation_variance, // innovation variance - innov_gate); // innovation gate - - // z special case if there is bad vertical acceleration data, then don't reject measurement, - // but limit innovation to prevent spikes that could destabilise the filter - if (_fault_status.flags.bad_acc_vertical && aid_src.innovation_rejected) { - const float innov_limit = innov_gate * sqrtf(aid_src.innovation_variance); - aid_src.innovation = math::constrain(aid_src.innovation, -innov_limit, innov_limit); - aid_src.innovation_rejected = false; - } -} - float Ekf::getRngVar() const { return fmaxf( diff --git a/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_fusion.cpp b/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_fusion.cpp index c2fd636720..2703e48259 100644 --- a/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_fusion.cpp +++ b/src/modules/ekf2/EKF/aid_sources/range_finder/range_height_fusion.cpp @@ -37,7 +37,6 @@ bool Ekf::fuseHaglRng(estimator_aid_source1d_s &aid_src, bool update_height, bool update_terrain) { if (aid_src.innovation_rejected) { - _innov_check_fail_status.flags.reject_hagl = true; return false; } @@ -60,9 +59,6 @@ bool Ekf::fuseHaglRng(estimator_aid_source1d_s &aid_src, bool update_height, boo measurementUpdate(K, H, aid_src.observation_variance, aid_src.innovation); - // record last successful fusion event - _innov_check_fail_status.flags.reject_hagl = false; - aid_src.time_last_fuse = _time_delayed_us; aid_src.fused = true; diff --git a/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.cpp b/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.cpp index ab1c747e01..3d7f462801 100644 --- a/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.cpp +++ b/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.cpp @@ -64,7 +64,7 @@ void SensorRangeFinder::updateValidity(uint64_t current_time_us) { updateDtDataLpf(current_time_us); - if (_is_faulty || isSampleOutOfDate(current_time_us) || !isDataContinuous()) { + if (isSampleOutOfDate(current_time_us) || !isDataContinuous()) { _is_sample_valid = false; _is_regularly_sending_data = false; return; diff --git a/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.hpp b/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.hpp index e3e4f6e6cd..044261492c 100644 --- a/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.hpp +++ b/src/modules/ekf2/EKF/aid_sources/range_finder/sensor_range_finder.hpp @@ -41,8 +41,6 @@ #ifndef EKF_SENSOR_RANGE_FINDER_HPP #define EKF_SENSOR_RANGE_FINDER_HPP -#include "Sensor.hpp" - #include #include @@ -60,17 +58,17 @@ struct rangeSample { static constexpr uint64_t RNG_MAX_INTERVAL = 200e3; ///< Maximum allowable time interval between range finder measurements (uSec) -class SensorRangeFinder : public Sensor +class SensorRangeFinder { public: SensorRangeFinder() = default; - ~SensorRangeFinder() override = default; + ~SensorRangeFinder() = default; void runChecks(uint64_t current_time_us, const matrix::Dcmf &R_to_earth); - bool isHealthy() const override { return _is_sample_valid; } - bool isDataHealthy() const override { return _is_sample_ready && _is_sample_valid; } + bool isHealthy() const { return _is_sample_valid; } + bool isDataHealthy() const { return _is_sample_ready && _is_sample_valid; } bool isDataReady() const { return _is_sample_ready; } - bool isRegularlySendingData() const override { return _is_regularly_sending_data; } + bool isRegularlySendingData() const { return _is_regularly_sending_data; } bool isStuckDetectorEnabled() const { return _stuck_threshold > 0.f; } void setSample(const rangeSample &sample) @@ -120,8 +118,6 @@ public: float getValidMinVal() const { return _rng_valid_min_val; } float getValidMaxVal() const { return _rng_valid_max_val; } - void setFaulty(bool faulty = true) { _is_faulty = faulty; } - private: void updateSensorToEarthRotation(const matrix::Dcmf &R_to_earth); @@ -141,7 +137,6 @@ private: bool _is_sample_valid{}; ///< true if range finder sample retrieved from buffer is valid bool _is_regularly_sending_data{false}; ///< true if the interval between two samples is less than the maximum expected interval uint64_t _time_last_valid_us{}; ///< time the last range finder measurement was ready (uSec) - bool _is_faulty{false}; ///< the sensor should not be used anymore /* * Stuck check diff --git a/src/modules/ekf2/EKF/aid_sources/sideslip/sideslip_fusion.cpp b/src/modules/ekf2/EKF/aid_sources/sideslip/sideslip_fusion.cpp index 0684f164ca..48e5cb7670 100644 --- a/src/modules/ekf2/EKF/aid_sources/sideslip/sideslip_fusion.cpp +++ b/src/modules/ekf2/EKF/aid_sources/sideslip/sideslip_fusion.cpp @@ -62,7 +62,6 @@ void Ekf::controlBetaFusion(const imuSample &imu_delayed) if (beta_fusion_time_triggered) { updateSideslip(_aid_src_sideslip); - _innov_check_fail_status.flags.reject_sideslip = _aid_src_sideslip.innovation_rejected; if (fuseSideslip(_aid_src_sideslip)) { _control_status.flags.wind = true; diff --git a/src/modules/ekf2/EKF/common.h b/src/modules/ekf2/EKF/common.h index de4eb07ad6..982cb4c1af 100644 --- a/src/modules/ekf2/EKF/common.h +++ b/src/modules/ekf2/EKF/common.h @@ -202,6 +202,7 @@ struct gnssSample { float yaw_acc{}; ///< 1-std yaw error (rad) float yaw_offset{}; ///< Heading/Yaw offset for dual antenna GPS - refer to description for GPS_YAW_OFFSET bool spoofed{}; ///< true if GNSS data is spoofed + bool jammed{}; ///< true if GNSS data is jammed }; struct magSample { @@ -267,6 +268,7 @@ struct systemFlagUpdate { bool is_fixed_wing{false}; bool gnd_effect{false}; bool constant_pos{false}; + bool in_transition_to_fw{false}; }; struct parameters { @@ -525,26 +527,6 @@ bool bad_sideslip : uint32_t value; }; -// define structure used to communicate innovation test failures -union innovation_fault_status_u { - struct { - bool reject_hor_vel : 1; ///< 0 - true if horizontal velocity observations have been rejected - bool reject_ver_vel : 1; ///< 1 - true if vertical velocity observations have been rejected - bool reject_hor_pos : 1; ///< 2 - true if horizontal position observations have been rejected - bool reject_ver_pos : 1; ///< 3 - true if true if vertical position observations have been rejected - bool reject_mag_x : 1; ///< 4 - true if the X magnetometer observation has been rejected - bool reject_mag_y : 1; ///< 5 - true if the Y magnetometer observation has been rejected - bool reject_mag_z : 1; ///< 6 - true if the Z magnetometer observation has been rejected - bool reject_yaw : 1; ///< 7 - true if the yaw observation has been rejected - bool reject_airspeed : 1; ///< 8 - true if the airspeed observation has been rejected - bool reject_sideslip : 1; ///< 9 - true if the synthetic sideslip observation has been rejected - bool reject_hagl : 1; ///< 10 - unused - bool reject_optflow_X : 1; ///< 11 - true if the X optical flow observation has been rejected - bool reject_optflow_Y : 1; ///< 12 - true if the Y optical flow observation has been rejected - } flags; - uint16_t value; -}; - // bitmask containing filter control status union filter_control_status_u { struct { @@ -607,7 +589,12 @@ uint64_t mag_heading_consistent : uint64_t baro_fault : 1; ///< 43 - true when the baro has been declared faulty and is no longer being used uint64_t gnss_vel : 1; ///< 44 - true if GNSS velocity measurement fusion is intended uint64_t gnss_fault : - 1; ///< 45 - true if GNSS measurements have been declared faulty and are no longer used + 1; ///< 45 - true if GNSS measurements (lat, lon, vel) have been declared faulty and are no longer used + uint64_t yaw_manual : 1; ///< 46 - true if yaw has been reset manually +uint64_t gnss_hgt_fault : + 1; ///< 47 - true if GNSS measurements (alt) have been declared faulty and are no longer used + uint64_t in_transition_to_fw : 1; ///< 48 - true if the vehicle is in transition to fw + } flags; uint64_t value; }; diff --git a/src/modules/ekf2/EKF/control.cpp b/src/modules/ekf2/EKF/control.cpp index 0998f86b43..95ee21c014 100644 --- a/src/modules/ekf2/EKF/control.cpp +++ b/src/modules/ekf2/EKF/control.cpp @@ -58,6 +58,7 @@ void Ekf::controlFusionModes(const imuSample &imu_delayed) set_in_air_status(system_flags_delayed.in_air); set_is_fixed_wing(system_flags_delayed.is_fixed_wing); + set_in_transition_to_fw(system_flags_delayed.in_transition_to_fw); if (system_flags_delayed.gnd_effect) { set_gnd_effect(); diff --git a/src/modules/ekf2/EKF/ekf.cpp b/src/modules/ekf2/EKF/ekf.cpp index 06b50c4c3d..ac04d5e9c3 100644 --- a/src/modules/ekf2/EKF/ekf.cpp +++ b/src/modules/ekf2/EKF/ekf.cpp @@ -91,7 +91,6 @@ void Ekf::reset() _control_status_prev.flags.in_air = true; _fault_status.value = 0; - _innov_check_fail_status.value = 0; #if defined(CONFIG_EKF2_GNSS) _gnss_checks.resetHard(); @@ -330,7 +329,7 @@ bool Ekf::resetGlobalPosToExternalObservation(const double latitude, const doubl const Vector2f innov = (_gpos - gpos_corrected).xy(); const Vector2f innov_var = Vector2f(getStateVariance()) + obs_var; - const float sq_gate = sq(5.f); // magic hardcoded gate + const float sq_gate = sq(10.f); // magic hardcoded gate const float test_ratio = sq(innov(0)) / (sq_gate * innov_var(0)) + sq(innov(1)) / (sq_gate * innov_var(1)); const bool innov_rejected = (test_ratio > 1.f); @@ -344,6 +343,14 @@ bool Ekf::resetGlobalPosToExternalObservation(const double latitude, const doubl _information_events.flags.reset_pos_to_ext_obs = true; resetHorizontalPositionTo(gpos_corrected.latitude_deg(), gpos_corrected.longitude_deg(), obs_var); + + Vector2f new_vel = _state.vel.xy() - _state.wind_vel; + resetHorizontalVelocityTo(new_vel, Vector2f(P(State::vel.idx, State::vel.idx), P(State::vel.idx + 1, State::vel.idx + 1))); + + // bump up wind uncertainty to ensure velocity remains correct + // eventual reset-by-fusion will have larger effect on wind state + P.uncorrelateCovarianceSetVariance<2>(State::wind_vel.idx, 10.f); + _state.wind_vel.setZero(); _last_known_gpos.setLatLon(gpos_corrected); } else { @@ -351,17 +358,23 @@ bool Ekf::resetGlobalPosToExternalObservation(const double latitude, const doubl VectorState H; VectorState K; + Vector2f innov_var_temp = Vector2f(getStateVariance()) + 0.1f; for (unsigned index = 0; index < 2; index++) { - K = VectorState(P.row(State::pos.idx + index)) / innov_var(index); + // Artificially setting the observation variance to a small value to + // increase the Kalman gain to basically 1 to force a reset of the position + // through fusion. This also enforces a strong correction of the correlated states + // (e.g.: velocity, heading, wind) + // The update of the covariance matrix is still performed with the correct observation variance + // to not artificially reduce the state uncertainty and cross-correlations. + K = VectorState(P.row(State::pos.idx + index)) / innov_var_temp(index); H(State::pos.idx + index) = 1.f; - // Artificially set the position Kalman gain to 1 in order to force a reset - // of the position through fusion. This allows the EKF to use part of the information - // to continue learning the correlated states (e.g.: velocity, heading, wind) while - // performing a position reset. - K(State::pos.idx + index) = 1.f; - measurementUpdate(K, H, obs_var, innov(index)); + clearInhibitedStateKalmanGains(K); + fuse(K, innov(index)); + + K = VectorState(P.row(State::pos.idx + index)) / innov_var(index); + measurementUpdate(K, H, obs_var, 0.f); H(State::pos.idx + index) = 0.f; // Reset the whole vector to 0 } @@ -411,7 +424,7 @@ void Ekf::updateParameters() } template -static void printRingBuffer(const char *name, RingBuffer *rb) +static void printRingBuffer(const char *name, TimestampedRingBuffer *rb) { if (rb) { printf("%s: %d/%d entries (%d/%d Bytes) (%zu Bytes per entry)\n", diff --git a/src/modules/ekf2/EKF/ekf.h b/src/modules/ekf2/EKF/ekf.h index b421bcb889..80ef94b9fc 100644 --- a/src/modules/ekf2/EKF/ekf.h +++ b/src/modules/ekf2/EKF/ekf.h @@ -416,6 +416,22 @@ public: bool resetGlobalPosToExternalObservation(double latitude, double longitude, float altitude, float eph, float epv, uint64_t timestamp_observation); + void resetHeadingToExternalObservation(float heading, float heading_accuracy) + { + if (_control_status.flags.yaw_align) { + resetYawByFusion(heading, heading_accuracy); + + } else { + resetQuatStateYaw(heading, heading_accuracy); + _control_status.flags.yaw_align = true; + } + + // Force the mag consistency check to pass again since an external heading reset is often done to + // counter mag disturbances. + _control_status.flags.mag_heading_consistent = false; + _control_status.flags.yaw_manual = true; + } + void updateParameters(); friend class AuxGlobalPosition; @@ -565,6 +581,8 @@ private: estimator_aid_source2d_s _aid_src_gnss_pos{}; estimator_aid_source3d_s _aid_src_gnss_vel{}; + uint64_t _time_last_gnss_hgt_rejected{0}; + # if defined(CONFIG_EKF2_GNSS_YAW) estimator_aid_source1d_s _aid_src_gnss_yaw {}; # endif // CONFIG_EKF2_GNSS_YAW @@ -647,8 +665,8 @@ private: bool initialiseAltitudeTo(float altitude, float vpos_var = NAN); // update quaternion states and covariances using an innovation, observation variance and Jacobian vector - bool fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H_YAW); - void computeYawInnovVarAndH(float variance, float &innovation_variance, VectorState &H_YAW) const; + bool fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H_YAW, const bool reset = false); + void computeYawInnovVarAndH(float observation_variance, float &innovation_variance, VectorState &H_YAW) const; void updateIMUBiasInhibit(const imuSample &imu_delayed); @@ -749,7 +767,6 @@ private: # if defined(CONFIG_EKF2_RANGE_FINDER) // update the terrain vertical position estimate using a height above ground measurement from the range finder bool fuseHaglRng(estimator_aid_source1d_s &aid_src, bool update_height, bool update_terrain); - void updateRangeHagl(estimator_aid_source1d_s &aid_src); void resetTerrainToRng(estimator_aid_source1d_s &aid_src); float getRngVar() const; # endif // CONFIG_EKF2_RANGE_FINDER @@ -871,6 +888,7 @@ private: void controlGnssHeightFusion(const gnssSample &gps_sample); void stopGpsHgtFusion(); + bool isGnssHgtResetAllowed(); # if defined(CONFIG_EKF2_GNSS_YAW) void controlGnssYawFusion(const gnssSample &gps_sample); @@ -999,6 +1017,9 @@ private: // yaw : Euler yaw angle (rad) // yaw_variance : yaw error variance (rad^2) void resetQuatStateYaw(float yaw, float yaw_variance); + void propagateQuatReset(const Quatf &quat_before_reset); + void resetYawByFusion(float yaw, float yaw_variance); + void resetHorizontalVelocityToMatchYaw(float delta_yaw); HeightSensor _height_sensor_ref{HeightSensor::UNKNOWN}; PositionSensor _position_sensor_ref{PositionSensor::GNSS}; diff --git a/src/modules/ekf2/EKF/ekf_helper.cpp b/src/modules/ekf2/EKF/ekf_helper.cpp index 5820494f8e..d568487da6 100644 --- a/src/modules/ekf2/EKF/ekf_helper.cpp +++ b/src/modules/ekf2/EKF/ekf_helper.cpp @@ -1263,10 +1263,15 @@ void Ekf::clearInhibitedStateKalmanGains(VectorState &K) const float Ekf::getHeadingInnov() const { + float innov = 0.f; + #if defined(CONFIG_EKF2_MAGNETOMETER) if (_control_status.flags.mag_hdg || _control_status.flags.mag_3D) { - return Vector3f(_aid_src_mag.innovation).max(); + innov = Vector3f(_aid_src_mag.innovation).max(); + + } else { + innov = _mag_heading_innov_lpf.getState(); } #endif // CONFIG_EKF2_MAGNETOMETER @@ -1274,7 +1279,7 @@ float Ekf::getHeadingInnov() const #if defined(CONFIG_EKF2_GNSS_YAW) if (_control_status.flags.gnss_yaw) { - return _aid_src_gnss_yaw.innovation; + innov = _aid_src_gnss_yaw.innovation; } #endif // CONFIG_EKF2_GNSS_YAW @@ -1282,12 +1287,12 @@ float Ekf::getHeadingInnov() const #if defined(CONFIG_EKF2_EXTERNAL_VISION) if (_control_status.flags.ev_yaw) { - return _aid_src_ev_yaw.innovation; + innov = _aid_src_ev_yaw.innovation; } #endif // CONFIG_EKF2_EXTERNAL_VISION - return 0.f; + return innov; } float Ekf::getHeadingInnovVar() const diff --git a/src/modules/ekf2/EKF/estimator_interface.cpp b/src/modules/ekf2/EKF/estimator_interface.cpp index 5c30c72afc..b6f71444e9 100644 --- a/src/modules/ekf2/EKF/estimator_interface.cpp +++ b/src/modules/ekf2/EKF/estimator_interface.cpp @@ -128,7 +128,7 @@ void EstimatorInterface::setMagData(const magSample &mag_sample) // Allocate the required buffer size if not previously done if (_mag_buffer == nullptr) { - _mag_buffer = new RingBuffer(_obs_buffer_length); + _mag_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_mag_buffer == nullptr || !_mag_buffer->valid()) { delete _mag_buffer; @@ -159,7 +159,7 @@ void EstimatorInterface::setMagData(const magSample &mag_sample) #endif // CONFIG_EKF2_MAGNETOMETER #if defined(CONFIG_EKF2_GNSS) -void EstimatorInterface::setGpsData(const gnssSample &gnss_sample) +void EstimatorInterface::setGpsData(const gnssSample &gnss_sample, const bool pps_compensation) { if (!_initialised) { return; @@ -167,7 +167,7 @@ void EstimatorInterface::setGpsData(const gnssSample &gnss_sample) // Allocate the required buffer size if not previously done if (_gps_buffer == nullptr) { - _gps_buffer = new RingBuffer(_obs_buffer_length); + _gps_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_gps_buffer == nullptr || !_gps_buffer->valid()) { delete _gps_buffer; @@ -177,8 +177,10 @@ void EstimatorInterface::setGpsData(const gnssSample &gnss_sample) } } + const int64_t delay = pps_compensation ? 0 : static_cast(_params.ekf2_gps_delay * 1000); + const int64_t time_us = gnss_sample.time_us - - static_cast(_params.ekf2_gps_delay * 1000) + - delay - static_cast(_dt_ekf_avg * 5e5f); // seconds to microseconds divided by 2 if (time_us >= static_cast(_gps_buffer->get_newest().time_us + _min_obs_interval_us)) { @@ -214,7 +216,7 @@ void EstimatorInterface::setBaroData(const baroSample &baro_sample) // Allocate the required buffer size if not previously done if (_baro_buffer == nullptr) { - _baro_buffer = new RingBuffer(_obs_buffer_length); + _baro_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_baro_buffer == nullptr || !_baro_buffer->valid()) { delete _baro_buffer; @@ -253,7 +255,7 @@ void EstimatorInterface::setAirspeedData(const airspeedSample &airspeed_sample) // Allocate the required buffer size if not previously done if (_airspeed_buffer == nullptr) { - _airspeed_buffer = new RingBuffer(_obs_buffer_length); + _airspeed_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_airspeed_buffer == nullptr || !_airspeed_buffer->valid()) { delete _airspeed_buffer; @@ -291,7 +293,7 @@ void EstimatorInterface::setRangeData(const sensor::rangeSample &range_sample) // Allocate the required buffer size if not previously done if (_range_buffer == nullptr) { - _range_buffer = new RingBuffer(_obs_buffer_length); + _range_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_range_buffer == nullptr || !_range_buffer->valid()) { delete _range_buffer; @@ -330,7 +332,7 @@ void EstimatorInterface::setOpticalFlowData(const flowSample &flow) // Allocate the required buffer size if not previously done if (_flow_buffer == nullptr) { - _flow_buffer = new RingBuffer(_imu_buffer_length); + _flow_buffer = new TimestampedRingBuffer(_imu_buffer_length); if (_flow_buffer == nullptr || !_flow_buffer->valid()) { delete _flow_buffer; @@ -368,7 +370,7 @@ void EstimatorInterface::setExtVisionData(const extVisionSample &evdata) // Allocate the required buffer size if not previously done if (_ext_vision_buffer == nullptr) { - _ext_vision_buffer = new RingBuffer(_obs_buffer_length); + _ext_vision_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_ext_vision_buffer == nullptr || !_ext_vision_buffer->valid()) { delete _ext_vision_buffer; @@ -408,7 +410,7 @@ void EstimatorInterface::setAuxVelData(const auxVelSample &auxvel_sample) // Allocate the required buffer size if not previously done if (_auxvel_buffer == nullptr) { - _auxvel_buffer = new RingBuffer(_obs_buffer_length); + _auxvel_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_auxvel_buffer == nullptr || !_auxvel_buffer->valid()) { delete _auxvel_buffer; @@ -445,7 +447,7 @@ void EstimatorInterface::setSystemFlagData(const systemFlagUpdate &system_flags) // Allocate the required buffer size if not previously done if (_system_flag_buffer == nullptr) { - _system_flag_buffer = new RingBuffer(_obs_buffer_length); + _system_flag_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_system_flag_buffer == nullptr || !_system_flag_buffer->valid()) { delete _system_flag_buffer; @@ -481,7 +483,7 @@ void EstimatorInterface::setDragData(const imuSample &imu) // Allocate the required buffer size if not previously done if (_drag_buffer == nullptr) { - _drag_buffer = new RingBuffer(_obs_buffer_length); + _drag_buffer = new TimestampedRingBuffer(_obs_buffer_length); if (_drag_buffer == nullptr || !_drag_buffer->valid()) { delete _drag_buffer; diff --git a/src/modules/ekf2/EKF/estimator_interface.h b/src/modules/ekf2/EKF/estimator_interface.h index 64d3e4ffc3..f7f6e559c9 100644 --- a/src/modules/ekf2/EKF/estimator_interface.h +++ b/src/modules/ekf2/EKF/estimator_interface.h @@ -62,7 +62,7 @@ #endif #include "common.h" -#include "RingBuffer.h" +#include #include "imu_down_sampler/imu_down_sampler.hpp" #include "output_predictor/output_predictor.h" @@ -89,7 +89,7 @@ public: void setIMUData(const imuSample &imu_sample); #if defined(CONFIG_EKF2_GNSS) - void setGpsData(const gnssSample &gnss_sample); + void setGpsData(const gnssSample &gnss_sample, const bool pps_compensation = false); const gnssSample &get_gps_sample_delayed() const { return _gps_sample_delayed; } @@ -190,9 +190,6 @@ public: // return true if the attitude is usable bool attitude_valid() const { return _control_status.flags.tilt_align; } - // get vehicle landed status data - bool get_in_air_status() const { return _control_status.flags.in_air; } - #if defined(CONFIG_EKF2_WIND) bool get_wind_status() const { return _control_status.flags.wind || _external_wind_init; } #endif // CONFIG_EKF2_WIND @@ -200,6 +197,8 @@ public: // set vehicle is fixed wing status void set_is_fixed_wing(bool is_fixed_wing) { _control_status.flags.fixed_wing = is_fixed_wing; } + void set_in_transition_to_fw(bool in_transition) { _control_status.flags.in_transition_to_fw = in_transition; } + // set flag if static pressure rise due to ground effect is expected // use _params.ekf2_gnd_eff_dz to adjust for expected rise in static pressure // flag will clear after GNDEFFECT_TIMEOUT uSec @@ -311,9 +310,6 @@ public: const fault_status_u &fault_status() const { return _fault_status; } const decltype(fault_status_u::flags) &fault_status_flags() const { return _fault_status.flags; } - const innovation_fault_status_u &innov_check_fail_status() const { return _innov_check_fail_status; } - const decltype(innovation_fault_status_u::flags) &innov_check_fail_status_flags() const { return _innov_check_fail_status.flags; } - const information_event_status_u &information_event_status() const { return _information_events; } const decltype(information_event_status_u::flags) &information_event_flags() const { return _information_events.flags; } void clear_information_events() { _information_events.value = 0; } @@ -373,7 +369,7 @@ protected: #endif // CONFIG_EKF2_EXTERNAL_VISION #if defined(CONFIG_EKF2_RANGE_FINDER) - RingBuffer *_range_buffer {nullptr}; + TimestampedRingBuffer *_range_buffer {nullptr}; uint64_t _time_last_range_buffer_push{0}; sensor::SensorRangeFinder _range_sensor{}; @@ -381,7 +377,7 @@ protected: #endif // CONFIG_EKF2_RANGE_FINDER #if defined(CONFIG_EKF2_OPTICAL_FLOW) - RingBuffer *_flow_buffer {nullptr}; + TimestampedRingBuffer *_flow_buffer {nullptr}; flowSample _flow_sample_delayed{}; @@ -401,7 +397,7 @@ protected: float _local_origin_alt{NAN}; #if defined(CONFIG_EKF2_GNSS) - RingBuffer *_gps_buffer {nullptr}; + TimestampedRingBuffer *_gps_buffer {nullptr}; uint64_t _time_last_gps_buffer_push{0}; gnssSample _gps_sample_delayed{}; @@ -427,12 +423,10 @@ protected: #endif // CONFIG_EKF2_GNSS #if defined(CONFIG_EKF2_DRAG_FUSION) - RingBuffer *_drag_buffer {nullptr}; + TimestampedRingBuffer *_drag_buffer {nullptr}; dragSample _drag_down_sampled{}; // down sampled drag specific force data (filter prediction rate -> observation rate) #endif // CONFIG_EKF2_DRAG_FUSION - innovation_fault_status_u _innov_check_fail_status{}; - bool _horizontal_deadreckon_time_exceeded{true}; bool _vertical_position_deadreckon_time_exceeded{true}; bool _vertical_velocity_deadreckon_time_exceeded{true}; @@ -442,29 +436,29 @@ protected: // data buffer instances static constexpr uint8_t kBufferLengthDefault = 12; - RingBuffer _imu_buffer{kBufferLengthDefault}; + TimestampedRingBuffer _imu_buffer{kBufferLengthDefault}; #if defined(CONFIG_EKF2_MAGNETOMETER) - RingBuffer *_mag_buffer {nullptr}; + TimestampedRingBuffer *_mag_buffer {nullptr}; uint64_t _time_last_mag_buffer_push{0}; #endif // CONFIG_EKF2_MAGNETOMETER #if defined(CONFIG_EKF2_AIRSPEED) - RingBuffer *_airspeed_buffer {nullptr}; + TimestampedRingBuffer *_airspeed_buffer {nullptr}; bool _synthetic_airspeed{false}; #endif // CONFIG_EKF2_AIRSPEED #if defined(CONFIG_EKF2_EXTERNAL_VISION) - RingBuffer *_ext_vision_buffer {nullptr}; + TimestampedRingBuffer *_ext_vision_buffer {nullptr}; uint64_t _time_last_ext_vision_buffer_push{0}; #endif // CONFIG_EKF2_EXTERNAL_VISION #if defined(CONFIG_EKF2_AUXVEL) - RingBuffer *_auxvel_buffer {nullptr}; + TimestampedRingBuffer *_auxvel_buffer {nullptr}; #endif // CONFIG_EKF2_AUXVEL - RingBuffer *_system_flag_buffer {nullptr}; + TimestampedRingBuffer *_system_flag_buffer {nullptr}; #if defined(CONFIG_EKF2_BAROMETER) - RingBuffer *_baro_buffer {nullptr}; + TimestampedRingBuffer *_baro_buffer {nullptr}; uint64_t _time_last_baro_buffer_push{0}; #endif // CONFIG_EKF2_BAROMETER diff --git a/src/modules/ekf2/EKF/height_control.cpp b/src/modules/ekf2/EKF/height_control.cpp index bc7f95f0e3..2f2e0b26be 100644 --- a/src/modules/ekf2/EKF/height_control.cpp +++ b/src/modules/ekf2/EKF/height_control.cpp @@ -112,8 +112,10 @@ void Ekf::checkHeightSensorRefFallback() || ((fallback_list[i] == HeightSensor::GNSS) && _control_status.flags.gps_hgt) || ((fallback_list[i] == HeightSensor::RANGE) && _control_status.flags.rng_hgt) || ((fallback_list[i] == HeightSensor::EV) && _control_status.flags.ev_hgt)) { - ECL_INFO("fallback to secondary height reference"); + _height_sensor_ref = fallback_list[i]; + + ECL_WARN("fallback to secondary height reference %d", (int)_height_sensor_ref); break; } } diff --git a/src/modules/ekf2/EKF/output_predictor/output_predictor.h b/src/modules/ekf2/EKF/output_predictor/output_predictor.h index f9643b3ec2..2309fc7954 100644 --- a/src/modules/ekf2/EKF/output_predictor/output_predictor.h +++ b/src/modules/ekf2/EKF/output_predictor/output_predictor.h @@ -36,7 +36,7 @@ #include -#include "../RingBuffer.h" +#include #include #include @@ -165,8 +165,8 @@ private: LatLonAlt _global_ref{0.0, 0.0, 0.f}; - RingBuffer _output_buffer{12}; - RingBuffer _output_vert_buffer{12}; + TimestampedRingBuffer _output_buffer{12}; + TimestampedRingBuffer _output_vert_buffer{12}; matrix::Vector3f _accel_bias{}; matrix::Vector3f _gyro_bias{}; diff --git a/src/modules/ekf2/EKF/yaw_fusion.cpp b/src/modules/ekf2/EKF/yaw_fusion.cpp index 9560d8110f..816d3f842a 100644 --- a/src/modules/ekf2/EKF/yaw_fusion.cpp +++ b/src/modules/ekf2/EKF/yaw_fusion.cpp @@ -37,7 +37,7 @@ #include -bool Ekf::fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H_YAW) +bool Ekf::fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H_YAW, bool reset) { // check if the innovation variance calculation is badly conditioned if (aid_src_status.innovation_variance >= aid_src_status.observation_variance) { @@ -68,10 +68,13 @@ bool Ekf::fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H Kfusion(row) *= heading_innov_var_inv; } + if (reset && fabsf(H_YAW(State::quat_nominal.idx + 2)) > FLT_EPSILON) { + // Reset the yaw estimate by forcing the measurement into the state + Kfusion(State::quat_nominal.idx + 2) = 1.f / H_YAW(State::quat_nominal.idx + 2); + } + // set the heading unhealthy if the test fails if (aid_src_status.innovation_rejected) { - _innov_check_fail_status.flags.reject_yaw = true; - // if we are in air we don't want to fuse the measurement // we allow to use it when on the ground because the large innovation could be caused // by interference or a large initial gyro bias @@ -93,9 +96,6 @@ bool Ekf::fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H } else { return false; } - - } else { - _innov_check_fail_status.flags.reject_yaw = false; } measurementUpdate(Kfusion, H_YAW, aid_src_status.observation_variance, aid_src_status.innovation); @@ -110,12 +110,12 @@ bool Ekf::fuseYaw(estimator_aid_source1d_s &aid_src_status, const VectorState &H return true; } -void Ekf::computeYawInnovVarAndH(float variance, float &innovation_variance, VectorState &H_YAW) const +void Ekf::computeYawInnovVarAndH(float observation_variance, float &innovation_variance, VectorState &H_YAW) const { - sym::ComputeYawInnovVarAndH(_state.vector(), P, variance, &innovation_variance, &H_YAW); + sym::ComputeYawInnovVarAndH(_state.vector(), P, observation_variance, &innovation_variance, &H_YAW); } -void Ekf::resetQuatStateYaw(float yaw, float yaw_variance) +void Ekf::resetQuatStateYaw(const float yaw, const float yaw_variance) { // save a copy of the quaternion state for later use in calculating the amount of reset change const Quatf quat_before_reset = _state.quat_nominal; @@ -129,12 +129,21 @@ void Ekf::resetQuatStateYaw(float yaw, float yaw_variance) // update the rotation matrix using the new yaw value _R_to_earth = updateYawInRotMat(yaw, Dcmf(_state.quat_nominal)); - // calculate the amount that the quaternion has changed by - const Quatf quat_after_reset(_R_to_earth); - const Quatf q_error((quat_after_reset * quat_before_reset.inversed()).normalized()); - // update quaternion states - _state.quat_nominal = quat_after_reset; + _state.quat_nominal = Quatf(_R_to_earth); + + _time_last_heading_fuse = _time_delayed_us; + + propagateQuatReset(quat_before_reset); + + // rotate horizontal velocity by the yaw change + const float yaw_diff = wrap_pi(yaw - getEulerYaw(quat_before_reset)); + resetHorizontalVelocityToMatchYaw(yaw_diff); +} + +void Ekf::propagateQuatReset(const Quatf &quat_before_reset) +{ + const Quatf q_error((_state.quat_nominal * quat_before_reset.inversed()).normalized()); // add the reset amount to the output observer buffered data _output_predictor.resetQuaternion(q_error); @@ -160,6 +169,35 @@ void Ekf::resetQuatStateYaw(float yaw, float yaw_variance) } _state_reset_status.reset_count.quat++; - - _time_last_heading_fuse = _time_delayed_us; +} + +void Ekf::resetYawByFusion(const float yaw, const float yaw_variance) +{ + const Quatf quat_before_reset = _state.quat_nominal; + + estimator_aid_source1d_s aid_src_status{}; + aid_src_status.observation = yaw; + aid_src_status.observation_variance = yaw_variance; + aid_src_status.innovation = wrap_pi(getEulerYaw(_state.quat_nominal) - yaw); + + VectorState H_YAW; + + computeYawInnovVarAndH(aid_src_status.observation_variance, aid_src_status.innovation_variance, H_YAW); + + const bool reset_yaw = true; + fuseYaw(aid_src_status, H_YAW, reset_yaw); + + propagateQuatReset(quat_before_reset); + + resetHorizontalVelocityToMatchYaw(-aid_src_status.innovation); +} + +void Ekf::resetHorizontalVelocityToMatchYaw(const float delta_yaw) +{ + if (!isNorthEastAidingActive() && fabsf(delta_yaw) > 0.3f) { + const matrix::Dcm2f R_yaw(delta_yaw); + const Vector2f vel_rotated = R_yaw * Vector2f(_state.vel); + const float vel_var = fmaxf(P(State::vel.idx, State::vel.idx), P(State::vel.idx + 1, State::vel.idx + 1)); + resetHorizontalVelocityTo(vel_rotated, vel_var); + } } diff --git a/src/modules/ekf2/EKF2.cpp b/src/modules/ekf2/EKF2.cpp index 40b642c9b0..98e2be7828 100644 --- a/src/modules/ekf2/EKF2.cpp +++ b/src/modules/ekf2/EKF2.cpp @@ -35,7 +35,6 @@ #include "EKF2.hpp" using namespace time_literals; -using math::constrain; using matrix::Eulerf; using matrix::Quatf; using matrix::Vector3f; @@ -580,6 +579,24 @@ void EKF2::Run() command_ack.timestamp = hrt_absolute_time(); _vehicle_command_ack_pub.publish(command_ack); } + + if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_EXTERNAL_ATTITUDE_ESTIMATE) { + if (PX4_ISFINITE(vehicle_command.param3)) { + const float heading = wrap_pi(math::radians(vehicle_command.param3)); + static constexpr float kDefaultHeadingAccuracyDeg = 20.f; + const float heading_accuracy = math::radians(PX4_ISFINITE(vehicle_command.param7) + ? vehicle_command.param7 + : kDefaultHeadingAccuracyDeg); + _ekf.resetHeadingToExternalObservation(heading, heading_accuracy); + command_ack.result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED; + + } else { + command_ack.result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; + } + + command_ack.timestamp = hrt_absolute_time(); + _vehicle_command_ack_pub.publish(command_ack); + } } } @@ -730,7 +747,6 @@ void EKF2::Run() // push imu data into estimator _ekf.setIMUData(imu_sample_new); - PublishAttitude(now); // publish attitude immediately (uses quaternion from output predictor) // integrate time to monitor time slippage if (_start_time_us > 0) { @@ -837,6 +853,9 @@ void EKF2::Run() #endif // CONFIG_EKF2_MAGNETOMETER } + PublishAttitude(now); // publish attitude immediately (uses quaternion from output predictor) + + // publish ekf2_timestamps _ekf2_timestamps_pub.publish(ekf2_timestamps); } @@ -1878,13 +1897,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime ×tamp) _filter_fault_status_changes++; } - // innovation check fail status - if (_ekf.innov_check_fail_status().value != _innov_check_fail_status) { - update = true; - _innov_check_fail_status = _ekf.innov_check_fail_status().value; - _innov_check_fail_status_changes++; - } - if (update) { estimator_status_flags_s status_flags{}; status_flags.timestamp_sample = _ekf.time_delayed_us(); @@ -1935,6 +1947,9 @@ void EKF2::PublishStatusFlags(const hrt_abstime ×tamp) status_flags.cs_constant_pos = _ekf.control_status_flags().constant_pos; status_flags.cs_baro_fault = _ekf.control_status_flags().baro_fault; status_flags.cs_gnss_vel = _ekf.control_status_flags().gnss_vel; + status_flags.cs_gnss_fault = _ekf.control_status_flags().gnss_fault; + status_flags.cs_yaw_manual = _ekf.control_status_flags().yaw_manual; + status_flags.cs_gnss_hgt_fault = _ekf.control_status_flags().gnss_hgt_fault; status_flags.fault_status_changes = _filter_fault_status_changes; status_flags.fs_bad_mag_x = _ekf.fault_status_flags().bad_mag_x; @@ -1949,18 +1964,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime ×tamp) status_flags.fs_bad_acc_vertical = _ekf.fault_status_flags().bad_acc_vertical; status_flags.fs_bad_acc_clipping = _ekf.fault_status_flags().bad_acc_clipping; - status_flags.innovation_fault_status_changes = _innov_check_fail_status_changes; - status_flags.reject_hor_vel = _ekf.innov_check_fail_status_flags().reject_hor_vel; - status_flags.reject_ver_vel = _ekf.innov_check_fail_status_flags().reject_ver_vel; - status_flags.reject_hor_pos = _ekf.innov_check_fail_status_flags().reject_hor_pos; - status_flags.reject_ver_pos = _ekf.innov_check_fail_status_flags().reject_ver_pos; - status_flags.reject_yaw = _ekf.innov_check_fail_status_flags().reject_yaw; - status_flags.reject_airspeed = _ekf.innov_check_fail_status_flags().reject_airspeed; - status_flags.reject_sideslip = _ekf.innov_check_fail_status_flags().reject_sideslip; - status_flags.reject_hagl = _ekf.innov_check_fail_status_flags().reject_hagl; - status_flags.reject_optflow_x = _ekf.innov_check_fail_status_flags().reject_optflow_X; - status_flags.reject_optflow_y = _ekf.innov_check_fail_status_flags().reject_optflow_Y; - status_flags.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); _estimator_status_flags_pub.publish(status_flags); @@ -2065,10 +2068,10 @@ void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps) if (_airspeed_validated_sub.update(&airspeed_validated)) { if (PX4_ISFINITE(airspeed_validated.true_airspeed_m_s) - && (airspeed_validated.airspeed_source > airspeed_validated_s::GROUND_MINUS_WIND) + && (airspeed_validated.airspeed_source > airspeed_validated_s::SOURCE_GROUND_MINUS_WIND) ) { - _ekf.setSyntheticAirspeed(airspeed_validated.airspeed_source == airspeed_validated_s::SYNTHETIC); + _ekf.setSyntheticAirspeed(airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SYNTHETIC); float cas2tas = 1.f; @@ -2431,8 +2434,12 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps) const float altitude_amsl = static_cast(vehicle_gps_position.altitude_msl_m); const float altitude_ellipsoid = static_cast(vehicle_gps_position.altitude_ellipsoid_m); + // if pps_compensation is active but not valid, the timestamp_sample will be equal to timestamp + const bool pps_compensation = vehicle_gps_position.timestamp_sample > 0 + && vehicle_gps_position.timestamp_sample != vehicle_gps_position.timestamp; + gnssSample gnss_sample{ - .time_us = vehicle_gps_position.timestamp, + .time_us = pps_compensation ? vehicle_gps_position.timestamp_sample : vehicle_gps_position.timestamp, .lat = vehicle_gps_position.latitude_deg, .lon = vehicle_gps_position.longitude_deg, .alt = altitude_amsl, @@ -2447,10 +2454,11 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps) .yaw = vehicle_gps_position.heading, //TODO: move to different message .yaw_acc = vehicle_gps_position.heading_accuracy, .yaw_offset = vehicle_gps_position.heading_offset, - .spoofed = vehicle_gps_position.spoofing_state == sensor_gps_s::SPOOFING_STATE_MULTIPLE, + .spoofed = vehicle_gps_position.spoofing_state == sensor_gps_s::SPOOFING_STATE_DETECTED, + .jammed = vehicle_gps_position.jamming_state == sensor_gps_s::JAMMING_STATE_DETECTED, }; - _ekf.setGpsData(gnss_sample); + _ekf.setGpsData(gnss_sample, pps_compensation); const float geoid_height = altitude_ellipsoid - altitude_amsl; @@ -2589,14 +2597,18 @@ void EKF2::UpdateSystemFlagsSample(ekf2_timestamps_s &ekf2_timestamps) // vehicle_status vehicle_status_s vehicle_status; + bool armed = false; + if (_status_sub.copy(&vehicle_status) && (ekf2_timestamps.timestamp < vehicle_status.timestamp + 3_s)) { // initially set in_air from arming_state (will be overridden if land detector is available) - flags.in_air = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); + armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); + flags.in_air = armed; // let the EKF know if the vehicle motion is that of a fixed wing (forward flight only relative to wind) flags.is_fixed_wing = (vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING); + flags.in_transition_to_fw = vehicle_status.in_transition_to_fw; #if defined(CONFIG_EKF2_SIDESLIP) @@ -2618,6 +2630,9 @@ void EKF2::UpdateSystemFlagsSample(ekf2_timestamps_s &ekf2_timestamps) flags.at_rest = vehicle_land_detected.at_rest; flags.in_air = !vehicle_land_detected.landed; flags.gnd_effect = vehicle_land_detected.in_ground_effect; + + // Enable constant position fusion for engine warmup when landed and armed + flags.constant_pos = _param_ekf2_engine_wrm.get() && !flags.in_air && armed; } launch_detection_status_s launch_detection_status; diff --git a/src/modules/ekf2/EKF2.hpp b/src/modules/ekf2/EKF2.hpp index c95e3c3623..ff372df248 100644 --- a/src/modules/ekf2/EKF2.hpp +++ b/src/modules/ekf2/EKF2.hpp @@ -414,11 +414,9 @@ private: uint64_t _filter_control_status{0}; uint32_t _filter_fault_status{0}; - uint32_t _innov_check_fail_status{0}; uint32_t _filter_control_status_changes{0}; uint32_t _filter_fault_status_changes{0}; - uint32_t _innov_check_fail_status_changes{0}; uint32_t _filter_information_event_changes{0}; uORB::PublicationMulti _ekf2_timestamps_pub{ORB_ID(ekf2_timestamps)}; @@ -489,6 +487,7 @@ private: (ParamExtFloat) _param_ekf2_delay_max, (ParamExtInt) _param_ekf2_imu_ctrl, (ParamExtFloat) _param_ekf2_vel_lim, + (ParamBool) _param_ekf2_engine_wrm, #if defined(CONFIG_EKF2_AUXVEL) (ParamExtFloat) diff --git a/src/modules/ekf2/module.yaml b/src/modules/ekf2/module.yaml index cd815ed56f..b0462ec5f8 100644 --- a/src/modules/ekf2/module.yaml +++ b/src/modules/ekf2/module.yaml @@ -183,3 +183,11 @@ parameters: max: 299792458 unit: m/s decimal: 1 + + EKF2_ENGINE_WRM: + description: + short: Enable constant position fusion during engine warmup + long: When enabled, constant position fusion is enabled when the vehicle is landed and armed. + This is intended for IC engine warmup (e.g., fuel engines on catapult) to allow mode transitions to auto/takeoff despite vibrations from running engines. + type: boolean + default: 0 diff --git a/src/modules/ekf2/params_gnss.yaml b/src/modules/ekf2/params_gnss.yaml index bcc186e0ba..04bff36346 100644 --- a/src/modules/ekf2/params_gnss.yaml +++ b/src/modules/ekf2/params_gnss.yaml @@ -20,8 +20,8 @@ parameters: EKF2_GPS_MODE: description: short: Fusion reset mode - long: 'Automatic: reset on fusion timeout if no other source of position is available - Dead-reckoning: reset on fusion timeout if no source of velocity is available' + long: 'Automatic: reset on fusion timeout if no other source of position is available. + Dead-reckoning: reset on fusion timeout if no source of velocity is available.' type: enum values: 0: Automatic @@ -29,7 +29,9 @@ parameters: default: 0 EKF2_GPS_DELAY: description: - short: GPS measurement delay relative to IMU measurements + short: GPS measurement delay relative to IMU measurement + long: GPS measurement delay relative to IMU measurement if PPS time correction + is not available/enabled (PPS_CAP_ENABLE). type: float default: 110 min: 0 @@ -126,9 +128,10 @@ parameters: 8: Vertical speed offset (EKF2_REQ_VDRIFT) 9: Spoofing 10: GPS fix type (EKF2_REQ_FIX) + 11: Jamming default: 2047 min: 0 - max: 2047 + max: 4095 EKF2_REQ_EPH: description: short: Required EPH to use GPS diff --git a/src/modules/ekf2/params_terrain.yaml b/src/modules/ekf2/params_terrain.yaml index 5fc361c5cd..6a0b61295d 100644 --- a/src/modules/ekf2/params_terrain.yaml +++ b/src/modules/ekf2/params_terrain.yaml @@ -28,7 +28,7 @@ parameters: where the range finder may be inside its minimum measurements distance when on ground. type: float - default: 0.1 + default: 0.01 min: 0.01 unit: m decimal: 2 diff --git a/src/modules/ekf2/test/CMakeLists.txt b/src/modules/ekf2/test/CMakeLists.txt index 3761758282..43749e49ac 100644 --- a/src/modules/ekf2/test/CMakeLists.txt +++ b/src/modules/ekf2/test/CMakeLists.txt @@ -54,7 +54,6 @@ px4_add_unit_gtest(SRC test_EKF_initialization.cpp LINKLIBS ecl_EKF ecl_sensor_s px4_add_unit_gtest(SRC test_EKF_mag.cpp LINKLIBS ecl_EKF ecl_sensor_sim) px4_add_unit_gtest(SRC test_EKF_mag_declination_generated.cpp LINKLIBS ecl_EKF ecl_test_helper) px4_add_unit_gtest(SRC test_EKF_measurementSampling.cpp LINKLIBS ecl_EKF ecl_sensor_sim) -px4_add_unit_gtest(SRC test_EKF_ringbuffer.cpp LINKLIBS ecl_EKF ecl_sensor_sim) px4_add_unit_gtest(SRC test_EKF_terrain.cpp LINKLIBS ecl_EKF ecl_sensor_sim ecl_test_helper) px4_add_unit_gtest(SRC test_EKF_utils.cpp LINKLIBS ecl_EKF ecl_sensor_sim) px4_add_unit_gtest(SRC test_EKF_withReplayData.cpp LINKLIBS ecl_EKF ecl_sensor_sim) diff --git a/src/modules/ekf2/test/change_indication/ekf_gsf_reset.csv b/src/modules/ekf2/test/change_indication/ekf_gsf_reset.csv index 2d7f7c2aca..2e572c5051 100644 --- a/src/modules/ekf2/test/change_indication/ekf_gsf_reset.csv +++ b/src/modules/ekf2/test/change_indication/ekf_gsf_reset.csv @@ -67,325 +67,325 @@ Timestamp,state[0],state[1],state[2],state[3],state[4],state[5],state[6],state[7 6490000,1,-0.0093,-0.011,0.00023,0.0049,0.0057,-0.052,0,0,-4.9e+02,-0.0015,-0.0057,-7.5e-05,0,0,-0.00015,0,0,0,0,0,0,0,0,-4.9e+02,0.0018,0.0018,0.0001,0.26,0.26,1.5,0.15,0.15,0.26,0.00012,0.00012,2.8e-06,0.04,0.04,0.04,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.7 6590000,1,-0.0093,-0.011,0.00016,0.0037,0.0057,-0.099,0,0,-4.9e+02,-0.0014,-0.0057,-7.6e-05,0,0,2.9e-05,0,0,0,0,0,0,0,0,-4.9e+02,0.0015,0.0015,9.6e-05,0.2,0.2,1.1,0.12,0.12,0.23,9.7e-05,9.7e-05,2.6e-06,0.04,0.04,0.04,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.7 6690000,1,-0.0093,-0.011,9.4e-05,0.0046,0.0053,-0.076,0,0,-4.9e+02,-0.0014,-0.0057,-7.6e-05,0,0,-0.00029,0,0,0,0,0,0,0,0,-4.9e+02,0.0016,0.0016,9.9e-05,0.23,0.23,0.78,0.14,0.14,0.21,9.7e-05,9.7e-05,2.6e-06,0.04,0.04,0.04,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.7 -6790000,0.71,0.0012,-0.014,0.71,0.0049,0.0052,-0.11,0,0,-4.9e+02,-0.0014,-0.0057,-7.5e-05,0,0,-7e-05,0.21,8e-05,0.43,3.5e-05,0.00033,-0.0024,0,0,-4.9e+02,0.0013,0.0013,0.053,0.18,0.18,0.6,0.11,0.11,0.2,7.8e-05,7.7e-05,2.4e-06,0.04,0.04,0.04,0.0015,0.0012,0.0014,0.0018,0.0015,0.0014,1,1,1.7 -6890000,0.71,0.0013,-0.014,0.7,0.00052,0.0065,-0.12,0,0,-4.9e+02,-0.0015,-0.0057,-7.6e-05,0,0,-9.8e-05,0.21,1.3e-05,0.43,6.1e-07,0.00089,-0.00086,0,0,-4.9e+02,0.0013,0.0013,0.047,0.21,0.21,0.46,0.13,0.14,0.18,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0014,0.00065,0.0013,0.0017,0.0014,0.0013,1,1,1.8 -6990000,0.71,0.0013,-0.014,0.71,-0.00025,0.0048,-0.12,0,0,-4.9e+02,-0.0014,-0.0057,-7.7e-05,-2.8e-05,-0.00025,-0.00041,0.21,-3.9e-05,0.43,-0.00025,0.00056,-0.00042,0,0,-4.9e+02,0.0013,0.0013,0.044,0.23,0.24,0.36,0.17,0.17,0.16,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00044,0.0013,0.0017,0.0013,0.0013,1,1,1.8 -7090000,0.71,0.0012,-0.014,0.71,-0.00081,0.0013,-0.13,0,0,-4.9e+02,-0.0014,-0.0057,-7.9e-05,0.0002,-0.00056,-0.00078,0.21,-3.8e-05,0.43,-0.00038,0.00025,-0.00041,0,0,-4.9e+02,0.0013,0.0013,0.043,0.27,0.27,0.29,0.2,0.21,0.16,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00034,0.0013,0.0017,0.0013,0.0013,1,1,1.8 -7190000,0.71,0.0013,-0.014,0.71,-0.0025,0.0021,-0.15,0,0,-4.9e+02,-0.0014,-0.0057,-7.8e-05,0.00014,-0.0005,-0.00057,0.21,-3.1e-05,0.43,-0.00036,0.00035,-0.00045,0,0,-4.9e+02,0.0013,0.0013,0.042,0.3,0.31,0.24,0.25,0.25,0.15,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00027,0.0013,0.0016,0.0013,0.0013,1,1,1.8 -7290000,0.71,0.0015,-0.014,0.71,-0.0044,0.01,-0.15,0,0,-4.9e+02,-0.0015,-0.0057,-7.5e-05,-0.00022,-0.00021,-0.0012,0.21,-3.3e-05,0.43,-0.00035,0.00077,-0.00038,0,0,-4.9e+02,0.0013,0.0013,0.042,0.34,0.35,0.2,0.3,0.31,0.14,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00023,0.0013,0.0016,0.0013,0.0013,1,1,1.9 -7390000,0.71,0.0016,-0.014,0.71,-0.0037,0.015,-0.16,0,0,-4.9e+02,-0.0016,-0.0057,-7.3e-05,-0.00029,-4.1e-05,-0.0014,0.21,-2.9e-05,0.43,-0.00035,0.00086,-0.00031,0,0,-4.9e+02,0.0013,0.0013,0.041,0.38,0.39,0.18,0.37,0.37,0.13,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.0002,0.0013,0.0016,0.0013,0.0013,1,1,1.9 -7490000,0.71,0.0015,-0.014,0.71,-0.0038,0.012,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.4e-05,-0.00019,-7.7e-05,-0.0022,0.21,-2.2e-05,0.43,-0.00032,0.00079,-0.00042,0,0,-4.9e+02,0.0013,0.0013,0.041,0.43,0.43,0.15,0.44,0.45,0.12,7.6e-05,7.6e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00017,0.0013,0.0016,0.0013,0.0013,1,1,1.9 -7590000,0.71,0.0017,-0.014,0.71,-0.0034,0.021,-0.17,0,0,-4.9e+02,-0.0016,-0.0057,-7e-05,-0.00024,0.0002,-0.003,0.21,-2.1e-05,0.43,-0.00035,0.00087,-0.00026,0,0,-4.9e+02,0.0013,0.0013,0.04,0.48,0.48,0.14,0.53,0.53,0.12,7.5e-05,7.5e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00015,0.0013,0.0016,0.0013,0.0013,1,1,1.9 -7690000,0.71,0.0017,-0.014,0.71,-0.0046,0.018,-0.16,0,0,-4.9e+02,-0.0016,-0.0057,-7.1e-05,-0.00025,0.00018,-0.0051,0.21,-1.8e-05,0.43,-0.00033,0.00084,-0.00033,0,0,-4.9e+02,0.0014,0.0013,0.04,0.53,0.53,0.13,0.63,0.63,0.11,7.5e-05,7.5e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00014,0.0013,0.0016,0.0013,0.0013,1,1,2 -7790000,0.71,0.0017,-0.014,0.71,-0.011,0.017,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.4e-05,-0.00037,5.8e-05,-0.0071,0.21,-1.7e-05,0.43,-0.00034,0.00079,-0.00038,0,0,-4.9e+02,0.0014,0.0013,0.04,0.58,0.58,0.12,0.74,0.74,0.11,7.4e-05,7.5e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00013,0.0013,0.0016,0.0013,0.0013,1,1,2 -7890000,0.71,0.0017,-0.014,0.71,-0.011,0.022,-0.16,0,0,-4.9e+02,-0.0016,-0.0057,-7.2e-05,-0.00039,0.0002,-0.0096,0.21,-1.6e-05,0.43,-0.00035,0.00079,-0.0003,0,0,-4.9e+02,0.0014,0.0014,0.04,0.64,0.63,0.11,0.87,0.86,0.1,7.3e-05,7.4e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00012,0.0013,0.0016,0.0013,0.0013,1,1,2 -7990000,0.71,0.0017,-0.014,0.71,-0.0091,0.023,-0.16,0,0,-4.9e+02,-0.0016,-0.0056,-7.1e-05,-0.00038,0.00028,-0.011,0.21,-1.4e-05,0.43,-0.00035,0.00086,-0.00038,0,0,-4.9e+02,0.0014,0.0014,0.04,0.7,0.68,0.1,1,0.99,0.099,7.1e-05,7.3e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00011,0.0013,0.0016,0.0013,0.0013,1,1,2 -8090000,0.71,0.0017,-0.014,0.71,-0.0051,0.025,-0.17,0,0,-4.9e+02,-0.0016,-0.0056,-6.9e-05,-0.00031,0.00035,-0.011,0.21,-1.2e-05,0.43,-0.00034,0.0009,-0.00035,0,0,-4.9e+02,0.0014,0.0014,0.04,0.76,0.74,0.1,1.2,1.1,0.097,7e-05,7.3e-05,2.4e-06,0.04,0.04,0.037,0.0013,0.0001,0.0013,0.0016,0.0013,0.0013,1,1,2.1 -8190000,0.71,0.0018,-0.014,0.71,-0.014,0.029,-0.18,0,0,-4.9e+02,-0.0016,-0.0057,-7e-05,-0.00045,0.00036,-0.013,0.21,-1.2e-05,0.43,-0.00036,0.00085,-0.00036,0,0,-4.9e+02,0.0014,0.0014,0.04,0.82,0.79,0.099,1.4,1.3,0.094,6.8e-05,7.2e-05,2.4e-06,0.04,0.04,0.037,0.0013,9.3e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 -8290000,0.71,0.0017,-0.014,0.71,-0.018,0.023,-0.17,0,0,-4.9e+02,-0.0015,-0.0057,-7.4e-05,-0.00057,0.00031,-0.017,0.21,-1e-05,0.43,-0.00032,0.00079,-0.00034,0,0,-4.9e+02,0.0014,0.0014,0.039,0.88,0.84,0.097,1.6,1.5,0.091,6.6e-05,7.1e-05,2.4e-06,0.04,0.04,0.036,0.0013,8.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 -8390000,0.71,0.0017,-0.014,0.71,-0.0012,0.00048,-0.17,0,0,-4.9e+02,-0.0015,-0.0056,-7.1e-05,-0.00052,0.00039,-0.021,0.21,-9.6e-06,0.43,-0.00031,0.00084,-0.00031,0,0,-4.9e+02,0.0014,0.0014,0.039,25,25,0.097,1e+02,1e+02,0.091,6.4e-05,7e-05,2.4e-06,0.04,0.04,0.035,0.0013,8.3e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 -8490000,0.71,0.0017,-0.014,0.71,-0.0029,0.0026,-0.17,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.00052,0.00039,-0.025,0.21,-9.3e-06,0.43,-0.00032,0.0008,-0.00028,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.096,1e+02,1e+02,0.089,6.2e-05,6.9e-05,2.4e-06,0.04,0.04,0.034,0.0013,7.8e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 -8590000,0.71,0.0022,-0.014,0.71,-0.00042,0.00097,-0.17,0,0,-4.9e+02,-0.0017,-0.0057,-7e-05,-0.00052,0.00039,-0.029,0.21,-1.2e-05,0.43,-0.00043,0.00076,-0.00028,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.088,6e-05,6.8e-05,2.4e-06,0.04,0.04,0.033,0.0013,7.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 -8690000,0.71,0.0021,-0.014,0.71,-0.0034,0.003,-0.16,0,0,-4.9e+02,-0.0017,-0.0056,-6.7e-05,-0.00052,0.00039,-0.035,0.21,-1.1e-05,0.43,-0.00041,0.00085,-0.00029,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.096,1e+02,1e+02,0.088,5.8e-05,6.7e-05,2.4e-06,0.04,0.04,0.033,0.0013,7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 -8790000,0.71,0.002,-0.014,0.71,-0.0056,0.0053,-0.15,0,0,-4.9e+02,-0.0016,-0.0057,-7e-05,-0.00052,0.00043,-0.041,0.21,-9.5e-06,0.43,-0.00038,0.0008,-0.00029,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.087,5.6e-05,6.6e-05,2.4e-06,0.04,0.04,0.032,0.0013,6.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 -8890000,0.71,0.0019,-0.014,0.71,-0.0077,0.0061,-0.15,0,0,-4.9e+02,-0.0016,-0.0057,-7.3e-05,-0.00065,0.00043,-0.045,0.21,-8.2e-06,0.43,-0.00036,0.00078,-0.00033,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.086,5.3e-05,6.4e-05,2.4e-06,0.04,0.04,0.03,0.0013,6.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 -8990000,0.71,0.0019,-0.014,0.71,-0.01,0.0057,-0.14,0,0,-4.9e+02,-0.0015,-0.0058,-7.7e-05,-0.00088,0.00044,-0.051,0.21,-7e-06,0.43,-0.00032,0.00071,-0.00034,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.096,1e+02,1e+02,0.087,5.1e-05,6.3e-05,2.4e-06,0.04,0.04,0.029,0.0013,6.1e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 -9090000,0.71,0.002,-0.014,0.71,-0.014,0.0071,-0.14,0,0,-4.9e+02,-0.0015,-0.0058,-7.7e-05,-0.001,0.00055,-0.053,0.21,-7.3e-06,0.43,-0.00034,0.00067,-0.00034,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1.1e+02,1.1e+02,0.086,4.9e-05,6.2e-05,2.4e-06,0.04,0.04,0.028,0.0013,5.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 -9190000,0.71,0.0019,-0.014,0.71,-0.012,0.01,-0.14,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.00088,0.0006,-0.057,0.21,-6.7e-06,0.43,-0.00033,0.00081,-0.00025,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.094,1.1e+02,1.1e+02,0.085,4.6e-05,6e-05,2.4e-06,0.04,0.04,0.027,0.0013,5.6e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 -9290000,0.71,0.0018,-0.014,0.71,-0.011,0.01,-0.14,0,0,-4.9e+02,-0.0014,-0.0056,-7.3e-05,-0.00098,0.0006,-0.061,0.21,-5.5e-06,0.43,-0.00028,0.00082,-0.00024,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.093,1.1e+02,1.1e+02,0.085,4.4e-05,5.8e-05,2.4e-06,0.04,0.04,0.025,0.0013,5.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 -9390000,0.71,0.0016,-0.014,0.71,-0.011,0.011,-0.14,0,0,-4.9e+02,-0.0014,-0.0056,-7.4e-05,-0.0011,0.0006,-0.065,0.21,-4.7e-06,0.43,-0.00024,0.00081,-0.00022,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.093,1.2e+02,1.2e+02,0.086,4.2e-05,5.7e-05,2.4e-06,0.04,0.04,0.024,0.0013,5.2e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 -9490000,0.71,0.0015,-0.014,0.71,-0.0079,0.013,-0.13,0,0,-4.9e+02,-0.0013,-0.0055,-7.1e-05,-0.001,0.00062,-0.068,0.21,-4.1e-06,0.43,-0.00021,0.00089,-0.00013,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.091,1.2e+02,1.2e+02,0.085,4e-05,5.5e-05,2.4e-06,0.04,0.04,0.023,0.0013,5e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 -9590000,0.71,0.0017,-0.014,0.71,-0.01,0.019,-0.13,0,0,-4.9e+02,-0.0014,-0.0055,-6.8e-05,-0.0011,0.00082,-0.072,0.21,-4.9e-06,0.43,-0.00027,0.0009,-0.00013,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.09,1.3e+02,1.3e+02,0.085,3.8e-05,5.4e-05,2.4e-06,0.04,0.04,0.021,0.0013,4.8e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 -9690000,0.71,0.0019,-0.014,0.71,-0.018,0.019,-0.12,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.0014,0.00095,-0.077,0.21,-5.2e-06,0.43,-0.00029,0.00079,-0.00017,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.089,1.3e+02,1.3e+02,0.086,3.6e-05,5.2e-05,2.4e-06,0.04,0.04,0.02,0.0013,4.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 -9790000,0.71,0.0018,-0.014,0.71,-0.013,0.023,-0.11,0,0,-4.9e+02,-0.0014,-0.0055,-7e-05,-0.0014,0.001,-0.082,0.21,-4.9e-06,0.43,-0.00027,0.00084,-0.0001,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.087,1.4e+02,1.4e+02,0.085,3.4e-05,5e-05,2.4e-06,0.04,0.04,0.019,0.0013,4.5e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 -9890000,0.71,0.0019,-0.014,0.71,-0.017,0.026,-0.11,0,0,-4.9e+02,-0.0015,-0.0056,-7e-05,-0.0015,0.0011,-0.085,0.21,-5e-06,0.43,-0.00028,0.00081,-0.00011,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.084,1.4e+02,1.4e+02,0.085,3.2e-05,4.9e-05,2.4e-06,0.04,0.04,0.018,0.0013,4.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 -9990000,0.71,0.002,-0.014,0.71,-0.021,0.024,-0.1,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.0017,0.0012,-0.089,0.21,-4.7e-06,0.43,-0.00028,0.00077,-0.00014,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.083,1.5e+02,1.5e+02,0.086,3.1e-05,4.7e-05,2.4e-06,0.04,0.04,0.017,0.0013,4.3e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 -10090000,0.71,0.0021,-0.014,0.71,-0.023,0.029,-0.096,0,0,-4.9e+02,-0.0015,-0.0056,-7e-05,-0.0017,0.0013,-0.091,0.21,-5.1e-06,0.43,-0.00031,0.00077,-0.00013,0,0,-4.9e+02,0.0013,0.0012,0.039,25,25,0.08,1.6e+02,1.6e+02,0.085,2.9e-05,4.6e-05,2.4e-06,0.04,0.04,0.016,0.0013,4.1e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 -10190000,0.71,0.0022,-0.014,0.71,-0.034,0.026,-0.096,0,0,-4.9e+02,-0.0015,-0.0058,-7.6e-05,-0.0019,0.0013,-0.093,0.21,-4.9e-06,0.43,-0.0003,0.00064,-0.00016,0,0,-4.9e+02,0.0012,0.0012,0.039,25,25,0.078,1.7e+02,1.7e+02,0.084,2.7e-05,4.4e-05,2.4e-06,0.04,0.04,0.014,0.0013,4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 -10290000,0.71,0.0021,-0.013,0.71,-0.041,0.022,-0.084,0,0,-4.9e+02,-0.0015,-0.0059,-8e-05,-0.0021,0.0015,-0.098,0.21,-4.6e-06,0.43,-0.00029,0.00056,-0.00018,0,0,-4.9e+02,0.0012,0.0012,0.039,25,25,0.076,1.8e+02,1.8e+02,0.085,2.6e-05,4.2e-05,2.3e-06,0.04,0.04,0.014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 -10390000,0.71,0.0019,-0.013,0.71,0.0086,-0.019,-0.067,0,0,-4.9e+02,-0.0015,-0.0059,-8.1e-05,-0.0021,0.0015,-0.11,0.21,-4.1e-06,0.43,-0.00026,0.00058,-0.00014,0,0,-4.9e+02,0.0012,0.0012,0.039,0.25,0.25,0.065,0.5,0.5,0.077,2.4e-05,4.1e-05,2.3e-06,0.04,0.04,0.011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 -10490000,0.71,0.0019,-0.013,0.71,0.0066,-0.019,-0.056,0,0,-4.9e+02,-0.0014,-0.0059,-8.5e-05,-0.0023,0.0016,-0.11,0.21,-3.7e-06,0.43,-0.00024,0.00052,-0.00017,0,0,-4.9e+02,0.0012,0.0012,0.039,0.25,0.25,0.064,0.51,0.51,0.077,2.3e-05,3.9e-05,2.3e-06,0.04,0.04,0.011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 -10590000,0.71,0.0023,-0.013,0.71,0.0057,-0.0075,-0.044,0,0,-4.9e+02,-0.0015,-0.0059,-8.1e-05,-0.0025,0.0022,-0.11,0.21,-5e-06,0.43,-0.00032,0.00052,-0.00017,0,0,-4.9e+02,0.0012,0.0011,0.039,0.13,0.13,0.056,0.17,0.17,0.072,2.2e-05,3.7e-05,2.3e-06,0.039,0.039,0.0092,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 -10690000,0.71,0.0022,-0.013,0.71,0.0029,-0.0081,-0.04,0,0,-4.9e+02,-0.0015,-0.0059,-8.3e-05,-0.0026,0.0022,-0.11,0.21,-4.6e-06,0.43,-0.0003,0.00051,-0.00018,0,0,-4.9e+02,0.0012,0.0011,0.038,0.14,0.14,0.056,0.18,0.18,0.073,2e-05,3.6e-05,2.3e-06,0.039,0.039,0.0087,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 -10790000,0.71,0.0021,-0.013,0.71,0.0031,-0.0056,-0.036,0,0,-4.9e+02,-0.0015,-0.0059,-8.2e-05,-0.0027,0.0026,-0.12,0.21,-4.5e-06,0.43,-0.00029,0.00054,-0.00017,0,0,-4.9e+02,0.0011,0.0011,0.038,0.093,0.094,0.05,0.11,0.11,0.068,1.9e-05,3.4e-05,2.3e-06,0.039,0.039,0.0076,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 -10890000,0.71,0.002,-0.013,0.71,0.0018,-0.0055,-0.037,0,0,-4.9e+02,-0.0014,-0.0059,-8.3e-05,-0.0028,0.0025,-0.12,0.21,-4.2e-06,0.43,-0.00027,0.00056,-0.00016,0,0,-4.9e+02,0.0011,0.0011,0.038,0.1,0.1,0.049,0.11,0.11,0.068,1.8e-05,3.3e-05,2.3e-06,0.039,0.039,0.0072,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 -10990000,0.71,0.0018,-0.014,0.71,0.0065,-0.00058,-0.034,0,0,-4.9e+02,-0.0013,-0.0057,-8.1e-05,-0.0028,0.0035,-0.12,0.21,-3.7e-06,0.43,-0.00025,0.0007,-0.00012,0,0,-4.9e+02,0.0011,0.001,0.038,0.079,0.08,0.045,0.079,0.079,0.066,1.7e-05,3e-05,2.3e-06,0.037,0.037,0.0064,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 -11090000,0.71,0.0018,-0.014,0.71,0.0064,0.003,-0.029,0,0,-4.9e+02,-0.0014,-0.0056,-7.7e-05,-0.0027,0.0033,-0.12,0.21,-3.8e-06,0.43,-0.00026,0.00076,-7.6e-05,0,0,-4.9e+02,0.0011,0.00098,0.038,0.09,0.091,0.044,0.085,0.085,0.066,1.6e-05,2.9e-05,2.3e-06,0.037,0.037,0.0061,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 -11190000,0.71,0.0018,-0.014,0.71,0.0098,0.0044,-0.031,0,0,-4.9e+02,-0.0013,-0.0057,-8e-05,-0.0025,0.0044,-0.12,0.21,-3.9e-06,0.43,-0.00027,0.00077,-9.4e-05,0,0,-4.9e+02,0.00096,0.0009,0.038,0.074,0.075,0.041,0.066,0.066,0.063,1.5e-05,2.7e-05,2.3e-06,0.036,0.036,0.0055,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 -11290000,0.71,0.0017,-0.014,0.71,0.009,0.003,-0.03,0,0,-4.9e+02,-0.0013,-0.0057,-8.5e-05,-0.0029,0.0047,-0.12,0.21,-3.5e-06,0.43,-0.00024,0.00071,-0.00012,0,0,-4.9e+02,0.00096,0.00089,0.038,0.085,0.087,0.041,0.072,0.072,0.064,1.4e-05,2.6e-05,2.3e-06,0.036,0.036,0.0052,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 -11390000,0.71,0.0017,-0.013,0.71,0.0046,0.002,-0.029,0,0,-4.9e+02,-0.0013,-0.0058,-8.7e-05,-0.0035,0.0045,-0.12,0.21,-3.4e-06,0.43,-0.00024,0.00064,-0.00017,0,0,-4.9e+02,0.00085,0.00081,0.038,0.071,0.073,0.037,0.058,0.058,0.061,1.3e-05,2.4e-05,2.3e-06,0.033,0.034,0.0047,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 -11490000,0.71,0.0015,-0.013,0.71,0.00076,-0.00069,-0.027,0,0,-4.9e+02,-0.0012,-0.006,-9.4e-05,-0.0041,0.0054,-0.12,0.21,-3.2e-06,0.43,-0.00021,0.00055,-0.00023,0,0,-4.9e+02,0.00085,0.0008,0.038,0.083,0.085,0.037,0.064,0.064,0.061,1.2e-05,2.3e-05,2.3e-06,0.033,0.034,0.0045,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 -11590000,0.71,0.0014,-0.013,0.71,-0.0023,-0.0004,-0.027,0,0,-4.9e+02,-0.0012,-0.006,-9.6e-05,-0.0046,0.0055,-0.12,0.21,-2.9e-06,0.43,-0.00018,0.00053,-0.00024,0,0,-4.9e+02,0.00074,0.00071,0.038,0.07,0.072,0.035,0.054,0.054,0.06,1.2e-05,2.1e-05,2.3e-06,0.031,0.032,0.0041,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 -11690000,0.71,0.0011,-0.013,0.71,-0.0039,-0.0014,-0.029,0,0,-4.9e+02,-0.0011,-0.006,-9.9e-05,-0.0055,0.0056,-0.12,0.21,-2.5e-06,0.43,-0.00013,0.00051,-0.00027,0,0,-4.9e+02,0.00074,0.00071,0.038,0.081,0.084,0.034,0.06,0.06,0.06,1.1e-05,2e-05,2.3e-06,0.031,0.031,0.0039,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 -11790000,0.71,0.0011,-0.013,0.71,-0.0078,0.00025,-0.027,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0071,0.0057,-0.12,0.21,-2.4e-06,0.43,-0.00011,0.00049,-0.00028,0,0,-4.9e+02,0.00064,0.00063,0.038,0.068,0.07,0.032,0.051,0.051,0.058,1e-05,1.8e-05,2.3e-06,0.028,0.029,0.0035,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 -11890000,0.71,0.001,-0.013,0.71,-0.0088,-0.0025,-0.025,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0078,0.0063,-0.12,0.21,-2.4e-06,0.43,-7.7e-05,0.00046,-0.00033,0,0,-4.9e+02,0.00064,0.00062,0.038,0.079,0.082,0.031,0.058,0.058,0.058,9.8e-06,1.8e-05,2.3e-06,0.028,0.029,0.0034,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 -11990000,0.71,0.0013,-0.013,0.71,-0.012,0.0022,-0.027,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0073,0.0068,-0.12,0.21,-3.3e-06,0.43,-0.00015,0.00047,-0.00032,0,0,-4.9e+02,0.00055,0.00055,0.037,0.066,0.068,0.03,0.049,0.049,0.057,9.2e-06,1.6e-05,2.3e-06,0.026,0.027,0.0031,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 -12090000,0.71,0.0015,-0.013,0.71,-0.014,0.0054,-0.03,0,0,-4.9e+02,-0.0012,-0.006,-9.6e-05,-0.0062,0.006,-0.12,0.21,-3.4e-06,0.43,-0.00018,0.00052,-0.00028,0,0,-4.9e+02,0.00055,0.00054,0.037,0.076,0.079,0.029,0.056,0.057,0.057,8.8e-06,1.6e-05,2.3e-06,0.025,0.027,0.003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 -12190000,0.71,0.0012,-0.013,0.71,-0.0071,0.0049,-0.023,0,0,-4.9e+02,-0.0011,-0.0059,-9.8e-05,-0.006,0.0062,-0.13,0.21,-2.7e-06,0.43,-0.00013,0.00059,-0.00027,0,0,-4.9e+02,0.00048,0.00048,0.037,0.063,0.065,0.028,0.048,0.048,0.055,8.2e-06,1.4e-05,2.3e-06,0.023,0.025,0.0027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 -12290000,0.71,0.0011,-0.013,0.71,-0.0084,0.0054,-0.02,0,0,-4.9e+02,-0.001,-0.0059,-9.8e-05,-0.0065,0.0058,-0.13,0.21,-2.4e-06,0.43,-0.0001,0.0006,-0.00026,0,0,-4.9e+02,0.00048,0.00048,0.037,0.073,0.075,0.027,0.056,0.056,0.056,7.9e-06,1.4e-05,2.3e-06,0.023,0.025,0.0026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 -12390000,0.71,0.001,-0.013,0.71,-0.0056,0.004,-0.016,0,0,-4.9e+02,-0.0011,-0.0059,-0.0001,-0.0051,0.0075,-0.13,0.21,-2.8e-06,0.43,-0.00014,0.0006,-0.00025,0,0,-4.9e+02,0.00042,0.00043,0.037,0.06,0.062,0.026,0.048,0.048,0.055,7.4e-06,1.3e-05,2.3e-06,0.021,0.024,0.0024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 -12490000,0.71,0.00098,-0.013,0.71,-0.0073,0.0036,-0.016,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0056,0.0087,-0.13,0.21,-3e-06,0.43,-0.00017,0.00054,-0.00025,0,0,-4.9e+02,0.00042,0.00042,0.037,0.069,0.071,0.025,0.055,0.055,0.055,7.1e-06,1.3e-05,2.3e-06,0.021,0.024,0.0023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 -12590000,0.71,0.0012,-0.013,0.71,-0.014,0.0044,-0.019,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0048,0.008,-0.13,0.21,-3.3e-06,0.43,-0.00021,0.00051,-0.00024,0,0,-4.9e+02,0.00037,0.00038,0.037,0.057,0.059,0.024,0.047,0.047,0.054,6.8e-06,1.2e-05,2.3e-06,0.019,0.022,0.0021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 -12690000,0.71,0.0014,-0.013,0.71,-0.017,0.0053,-0.021,0,0,-4.9e+02,-0.0012,-0.006,-0.0001,-0.003,0.0093,-0.13,0.21,-4.3e-06,0.43,-0.00028,0.0005,-0.00025,0,0,-4.9e+02,0.00037,0.00038,0.037,0.065,0.067,0.024,0.055,0.055,0.054,6.5e-06,1.1e-05,2.3e-06,0.019,0.022,0.0021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 -12790000,0.71,0.0013,-0.013,0.71,-0.02,0.0033,-0.022,0,0,-4.9e+02,-0.0012,-0.006,-0.0001,-0.0045,0.0081,-0.13,0.21,-3.6e-06,0.43,-0.00022,0.00048,-0.00027,0,0,-4.9e+02,0.00033,0.00034,0.037,0.054,0.056,0.023,0.047,0.047,0.053,6.2e-06,1.1e-05,2.3e-06,0.018,0.021,0.0019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 -12890000,0.71,0.0011,-0.013,0.71,-0.02,0.0021,-0.019,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0058,0.0077,-0.13,0.21,-3.2e-06,0.43,-0.00019,0.00047,-0.00026,0,0,-4.9e+02,0.00033,0.00034,0.037,0.061,0.063,0.023,0.054,0.055,0.053,6e-06,1.1e-05,2.3e-06,0.018,0.021,0.0018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 -12990000,0.71,0.001,-0.013,0.71,-0.0092,0.0023,-0.018,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0033,0.008,-0.13,0.21,-3e-06,0.43,-0.0002,0.00058,-0.0002,0,0,-4.9e+02,0.0003,0.00031,0.037,0.051,0.052,0.021,0.047,0.047,0.052,5.7e-06,9.9e-06,2.3e-06,0.016,0.02,0.0017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 -13090000,0.71,0.00097,-0.013,0.71,-0.0099,0.00035,-0.016,0,0,-4.9e+02,-0.0011,-0.006,-0.00011,-0.0044,0.0096,-0.13,0.21,-3.4e-06,0.43,-0.00021,0.00052,-0.00023,0,0,-4.9e+02,0.0003,0.00031,0.037,0.057,0.059,0.021,0.054,0.054,0.052,5.5e-06,9.6e-06,2.3e-06,0.016,0.02,0.0016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 -13190000,0.71,0.00096,-0.013,0.71,-0.0024,0.0012,-0.012,0,0,-4.9e+02,-0.0011,-0.006,-0.00011,-0.0026,0.011,-0.13,0.21,-3.7e-06,0.43,-0.00025,0.00057,-0.00021,0,0,-4.9e+02,0.00027,0.00029,0.037,0.048,0.049,0.02,0.047,0.047,0.051,5.2e-06,9.1e-06,2.3e-06,0.015,0.019,0.0015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 -13290000,0.71,0.00081,-0.013,0.71,-0.00094,0.0019,-0.007,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.004,0.0095,-0.13,0.21,-2.8e-06,0.43,-0.00019,0.00059,-0.00019,0,0,-4.9e+02,0.00027,0.00028,0.037,0.053,0.055,0.02,0.054,0.054,0.051,5.1e-06,8.9e-06,2.3e-06,0.015,0.018,0.0015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 -13390000,0.71,0.00072,-0.013,0.71,0.00011,0.0026,-0.0026,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0034,0.0087,-0.13,0.21,-2.6e-06,0.43,-0.00017,0.00063,-0.00019,0,0,-4.9e+02,0.00025,0.00026,0.037,0.045,0.046,0.019,0.047,0.047,0.05,4.8e-06,8.5e-06,2.3e-06,0.014,0.018,0.0014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 -13490000,0.71,0.00072,-0.013,0.71,8.4e-05,0.0027,0.00045,0,0,-4.9e+02,-0.001,-0.0059,-0.0001,-0.0034,0.0079,-0.13,0.21,-2.2e-06,0.43,-0.00016,0.00064,-0.00017,0,0,-4.9e+02,0.00025,0.00026,0.037,0.05,0.052,0.019,0.054,0.054,0.05,4.7e-06,8.2e-06,2.3e-06,0.014,0.017,0.0013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 -13590000,0.71,0.00073,-0.013,0.71,-0.00012,0.003,-0.00091,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0032,0.0091,-0.13,0.21,-2.7e-06,0.43,-0.00018,0.00063,-0.00019,0,0,-4.9e+02,0.00023,0.00025,0.037,0.042,0.044,0.018,0.046,0.047,0.05,4.5e-06,7.9e-06,2.3e-06,0.013,0.017,0.0013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 -13690000,0.71,0.00072,-0.013,0.71,0.00081,0.0055,-0.0036,0,0,-4.9e+02,-0.001,-0.0059,-9.9e-05,-0.0026,0.0079,-0.13,0.21,-2.3e-06,0.43,-0.00017,0.00065,-0.00016,0,0,-4.9e+02,0.00023,0.00024,0.037,0.047,0.048,0.018,0.053,0.054,0.049,4.3e-06,7.7e-06,2.3e-06,0.013,0.017,0.0012,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 -13790000,0.71,0.00076,-0.013,0.71,0.00052,0.0023,-0.0046,0,0,-4.9e+02,-0.0011,-0.006,-9.9e-05,-0.0011,0.0086,-0.13,0.21,-2.7e-06,0.43,-0.0002,0.00066,-0.00014,0,0,-4.9e+02,0.00022,0.00023,0.037,0.04,0.041,0.017,0.046,0.046,0.048,4.2e-06,7.3e-06,2.3e-06,0.013,0.016,0.0011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 -13890000,0.71,0.0006,-0.013,0.71,0.0023,0.0023,-0.0073,0,0,-4.9e+02,-0.001,-0.0059,-9.9e-05,-0.0025,0.0075,-0.13,0.21,-2e-06,0.43,-0.00016,0.00066,-0.00015,0,0,-4.9e+02,0.00022,0.00023,0.037,0.044,0.045,0.017,0.053,0.053,0.049,4e-06,7.1e-06,2.3e-06,0.012,0.016,0.0011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 -13990000,0.71,0.00066,-0.013,0.71,0.0018,0.00059,-0.0067,0,0,-4.9e+02,-0.001,-0.0059,-9.8e-05,-0.0012,0.008,-0.13,0.21,-2.2e-06,0.43,-0.0002,0.00066,-0.00013,0,0,-4.9e+02,0.00021,0.00022,0.037,0.037,0.039,0.016,0.046,0.046,0.048,3.9e-06,6.8e-06,2.3e-06,0.012,0.015,0.001,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 -14090000,0.71,0.00073,-0.013,0.71,0.0014,0.002,-0.0065,0,0,-4.9e+02,-0.0011,-0.0059,-9.4e-05,0.00031,0.0069,-0.13,0.21,-2e-06,0.43,-0.00019,0.0007,-8.9e-05,0,0,-4.9e+02,0.00021,0.00022,0.037,0.041,0.043,0.016,0.052,0.053,0.048,3.8e-06,6.7e-06,2.3e-06,0.012,0.015,0.00099,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 -14190000,0.71,0.00068,-0.014,0.71,0.0044,0.0018,-0.0079,0,0,-4.9e+02,-0.0011,-0.0059,-9.3e-05,0.0008,0.0066,-0.13,0.21,-1.8e-06,0.43,-0.00019,0.00072,-7.2e-05,0,0,-4.9e+02,0.0002,0.00021,0.037,0.035,0.037,0.015,0.046,0.046,0.047,3.6e-06,6.4e-06,2.3e-06,0.011,0.015,0.00094,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 -14290000,0.71,0.00076,-0.014,0.71,0.0046,0.0032,-0.0063,0,0,-4.9e+02,-0.0011,-0.0059,-9.1e-05,0.0017,0.0065,-0.13,0.21,-1.9e-06,0.43,-0.0002,0.00072,-5.3e-05,0,0,-4.9e+02,0.0002,0.00021,0.037,0.038,0.04,0.015,0.052,0.052,0.047,3.5e-06,6.2e-06,2.3e-06,0.011,0.014,0.00091,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 -14390000,0.71,0.00064,-0.014,0.71,0.007,0.0049,-0.0082,0,0,-4.9e+02,-0.0011,-0.0058,-8.9e-05,0.0014,0.005,-0.13,0.21,-1e-06,0.43,-0.00016,0.00075,-3.7e-05,0,0,-4.9e+02,0.00019,0.0002,0.037,0.033,0.035,0.015,0.046,0.046,0.046,3.4e-06,6e-06,2.3e-06,0.011,0.014,0.00086,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 -14490000,0.71,0.00053,-0.014,0.71,0.008,0.0064,-0.0099,0,0,-4.9e+02,-0.001,-0.0058,-8.9e-05,8.8e-05,0.0045,-0.13,0.21,-5.5e-07,0.43,-0.00014,0.00072,-3.7e-05,0,0,-4.9e+02,0.00019,0.0002,0.037,0.036,0.038,0.014,0.052,0.052,0.046,3.3e-06,5.8e-06,2.3e-06,0.011,0.014,0.00083,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 -14590000,0.71,0.00042,-0.013,0.71,0.0061,0.0048,-0.011,0,0,-4.9e+02,-0.001,-0.0059,-8.9e-05,-0.00077,0.0042,-0.13,0.21,-4.6e-07,0.43,-0.00013,0.00069,-5.1e-05,0,0,-4.9e+02,0.00018,0.00019,0.037,0.031,0.033,0.014,0.045,0.045,0.046,3.2e-06,5.6e-06,2.3e-06,0.01,0.014,0.00079,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 -14690000,0.71,0.00037,-0.013,0.71,0.0079,0.0029,-0.0076,0,0,-4.9e+02,-0.001,-0.0058,-8.7e-05,-0.00069,0.0033,-0.13,0.21,-6.3e-08,0.43,-0.00011,0.0007,-3.6e-05,0,0,-4.9e+02,0.00018,0.00019,0.037,0.034,0.036,0.014,0.051,0.052,0.046,3.1e-06,5.5e-06,2.3e-06,0.01,0.013,0.00077,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 -14790000,0.71,0.00035,-0.013,0.71,0.0055,0.0014,-0.0059,0,0,-4.9e+02,-0.001,-0.0058,-8.6e-05,-0.00081,0.0031,-0.13,0.21,-1.2e-07,0.43,-0.00012,0.00068,-3.7e-05,0,0,-4.9e+02,0.00017,0.00018,0.037,0.03,0.031,0.013,0.045,0.045,0.045,3e-06,5.2e-06,2.3e-06,0.0098,0.013,0.00073,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 -14890000,0.71,0.00032,-0.013,0.71,0.0077,0.0032,-0.0079,0,0,-4.9e+02,-0.001,-0.0058,-8.5e-05,-0.0011,0.0025,-0.13,0.21,1.5e-07,0.43,-0.00011,0.00068,-3.4e-05,0,0,-4.9e+02,0.00017,0.00018,0.037,0.032,0.034,0.013,0.051,0.051,0.045,2.9e-06,5.1e-06,2.3e-06,0.0096,0.013,0.00071,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 -14990000,0.71,0.00027,-0.013,0.71,0.0068,0.0021,-0.0059,0,0,-4.9e+02,-0.001,-0.0059,-8.7e-05,-0.0015,0.003,-0.13,0.21,-5.1e-08,0.43,-0.00012,0.00066,-4.6e-05,0,0,-4.9e+02,0.00017,0.00017,0.037,0.028,0.03,0.013,0.045,0.045,0.045,2.8e-06,4.9e-06,2.3e-06,0.0094,0.012,0.00067,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 -15090000,0.71,0.0002,-0.013,0.71,0.0075,0.0022,-0.0072,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.0016,0.0034,-0.13,0.21,-1.5e-07,0.43,-0.00013,0.00064,-4.7e-05,0,0,-4.9e+02,0.00017,0.00017,0.037,0.03,0.032,0.013,0.05,0.051,0.044,2.7e-06,4.8e-06,2.3e-06,0.0092,0.012,0.00065,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 -15190000,0.71,0.00016,-0.013,0.71,0.0073,0.0027,-0.0063,0,0,-4.9e+02,-0.00099,-0.0059,-8.9e-05,-0.0022,0.0037,-0.13,0.21,-1.4e-07,0.43,-0.00014,0.00061,-5.4e-05,0,0,-4.9e+02,0.00016,0.00017,0.037,0.027,0.028,0.012,0.044,0.045,0.044,2.6e-06,4.6e-06,2.3e-06,0.009,0.012,0.00063,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 -15290000,0.71,0.00019,-0.013,0.71,0.0077,0.0038,-0.005,0,0,-4.9e+02,-0.001,-0.0059,-8.7e-05,-0.0013,0.0034,-0.13,0.21,-7.9e-08,0.43,-0.00015,0.00061,-2.9e-05,0,0,-4.9e+02,0.00016,0.00017,0.037,0.029,0.031,0.012,0.05,0.05,0.044,2.6e-06,4.5e-06,2.3e-06,0.0089,0.012,0.00061,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 -15390000,0.71,0.0002,-0.013,0.71,0.0071,0.005,-0.004,0,0,-4.9e+02,-0.001,-0.0058,-8.2e-05,-0.00042,0.0019,-0.13,0.21,2.9e-07,0.43,-0.00014,0.00064,-5.7e-06,0,0,-4.9e+02,0.00016,0.00016,0.037,0.025,0.027,0.012,0.044,0.044,0.043,2.5e-06,4.4e-06,2.3e-06,0.0087,0.012,0.00058,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 -15490000,0.71,0.00021,-0.013,0.71,0.0086,0.0041,-0.0032,0,0,-4.9e+02,-0.001,-0.0059,-8.6e-05,-0.00082,0.0032,-0.13,0.21,-1.7e-07,0.43,-0.00016,0.00061,-2.4e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.027,0.029,0.012,0.049,0.05,0.044,2.4e-06,4.3e-06,2.3e-06,0.0086,0.011,0.00056,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 -15590000,0.71,0.00018,-0.013,0.71,0.0072,0.0032,-0.0024,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.0014,0.0039,-0.13,0.21,-5.3e-07,0.43,-0.00016,0.0006,-4.9e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.024,0.026,0.011,0.044,0.044,0.043,2.3e-06,4.1e-06,2.3e-06,0.0084,0.011,0.00054,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 -15690000,0.71,0.00022,-0.013,0.71,0.0075,0.0032,-0.0025,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.00096,0.0043,-0.13,0.21,-8.4e-07,0.43,-0.00017,0.0006,-5.2e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.026,0.028,0.011,0.049,0.049,0.043,2.3e-06,4e-06,2.3e-06,0.0083,0.011,0.00052,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 -15790000,0.71,0.00018,-0.013,0.71,0.0081,0.0017,-0.0043,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.0012,0.0045,-0.13,0.21,-9.4e-07,0.43,-0.00018,0.00059,-5.6e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.023,0.025,0.011,0.043,0.044,0.042,2.2e-06,3.9e-06,2.3e-06,0.0081,0.011,0.0005,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 -15890000,0.71,0.0002,-0.013,0.71,0.0088,0.0016,-0.0029,0,0,-4.9e+02,-0.0011,-0.0059,-8.7e-05,-0.00043,0.0048,-0.13,0.21,-1.1e-06,0.43,-0.00019,0.00059,-4.7e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.025,0.027,0.011,0.048,0.049,0.042,2.1e-06,3.8e-06,2.3e-06,0.008,0.011,0.00049,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 -15990000,0.71,0.00017,-0.013,0.71,0.0086,0.0017,-0.00056,0,0,-4.9e+02,-0.0011,-0.0059,-8.3e-05,0.00023,0.004,-0.13,0.21,-1e-06,0.43,-0.0002,0.0006,-2.9e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.022,0.024,0.011,0.043,0.043,0.042,2.1e-06,3.6e-06,2.3e-06,0.0079,0.01,0.00047,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 -16090000,0.71,0.00021,-0.013,0.71,0.011,0.0034,0.0016,0,0,-4.9e+02,-0.0011,-0.0059,-7.9e-05,0.001,0.0027,-0.13,0.21,-7.4e-07,0.43,-0.00017,0.00065,-1.3e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.024,0.026,0.01,0.048,0.049,0.042,2e-06,3.6e-06,2.3e-06,0.0078,0.01,0.00046,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 -16190000,0.71,0.00026,-0.013,0.71,0.01,0.0036,0.0018,0,0,-4.9e+02,-0.0011,-0.0059,-7.8e-05,0.0018,0.0029,-0.13,0.21,-1e-06,0.43,-0.00018,0.00065,-6.5e-06,0,0,-4.9e+02,0.00015,0.00014,0.037,0.021,0.023,0.01,0.043,0.043,0.041,2e-06,3.4e-06,2.3e-06,0.0077,0.01,0.00044,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 -16290000,0.71,0.00027,-0.014,0.71,0.012,0.0046,0.001,0,0,-4.9e+02,-0.0011,-0.0058,-7.4e-05,0.0021,0.0016,-0.13,0.21,-5.8e-07,0.43,-0.00016,0.00067,8.3e-06,0,0,-4.9e+02,0.00015,0.00014,0.037,0.023,0.025,0.01,0.048,0.048,0.041,1.9e-06,3.4e-06,2.3e-06,0.0076,0.01,0.00043,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 -16390000,0.71,0.00033,-0.014,0.71,0.01,0.0031,0.001,0,0,-4.9e+02,-0.0011,-0.0058,-7.5e-05,0.0033,0.0027,-0.13,0.21,-1.4e-06,0.43,-0.00019,0.00066,1.3e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.02,0.023,0.0098,0.042,0.043,0.041,1.9e-06,3.2e-06,2.3e-06,0.0075,0.0098,0.00042,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 -16490000,0.71,0.00042,-0.014,0.71,0.0088,0.0044,-0.0009,0,0,-4.9e+02,-0.0011,-0.0058,-7.4e-05,0.0042,0.0029,-0.13,0.21,-1.6e-06,0.43,-0.0002,0.00066,2.7e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.022,0.024,0.0098,0.047,0.048,0.041,1.8e-06,3.2e-06,2.3e-06,0.0074,0.0097,0.00041,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 -16590000,0.71,0.00052,-0.013,0.71,0.0068,0.0053,-0.0021,0,0,-4.9e+02,-0.0012,-0.0058,-7.5e-05,0.0043,0.0026,-0.13,0.21,-1.6e-06,0.43,-0.00019,0.00066,2.3e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.02,0.022,0.0095,0.042,0.042,0.04,1.8e-06,3.1e-06,2.3e-06,0.0073,0.0095,0.00039,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 -16690000,0.71,0.00048,-0.013,0.71,0.0077,0.0056,-0.00026,0,0,-4.9e+02,-0.0011,-0.0059,-7.8e-05,0.0037,0.0032,-0.13,0.21,-1.8e-06,0.43,-0.00019,0.00065,1.2e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.021,0.024,0.0094,0.047,0.047,0.04,1.7e-06,3e-06,2.3e-06,0.0072,0.0094,0.00038,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 -16790000,0.71,0.00048,-0.013,0.71,0.0058,0.0063,-2.4e-05,0,0,-4.9e+02,-0.0011,-0.0058,-7.9e-05,0.0035,0.0029,-0.13,0.21,-1.7e-06,0.43,-0.00017,0.00065,-7.7e-07,0,0,-4.9e+02,0.00014,0.00013,0.037,0.019,0.021,0.0093,0.042,0.042,0.04,1.7e-06,2.9e-06,2.3e-06,0.0071,0.0092,0.00037,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 -16890000,0.71,0.00054,-0.013,0.71,0.0055,0.0072,0.0013,0,0,-4.9e+02,-0.0012,-0.0059,-8e-05,0.0039,0.0034,-0.13,0.21,-2e-06,0.43,-0.00018,0.00064,3.8e-06,0,0,-4.9e+02,0.00014,0.00013,0.037,0.02,0.023,0.0092,0.046,0.047,0.04,1.6e-06,2.8e-06,2.3e-06,0.007,0.0091,0.00036,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 -16990000,0.71,0.0005,-0.013,0.71,0.0055,0.0049,0.0019,0,0,-4.9e+02,-0.0012,-0.0059,-8.1e-05,0.0038,0.0045,-0.13,0.21,-2.5e-06,0.43,-0.0002,0.00063,-6.3e-06,0,0,-4.9e+02,0.00014,0.00013,0.037,0.018,0.021,0.009,0.041,0.042,0.039,1.6e-06,2.7e-06,2.3e-06,0.0069,0.009,0.00035,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 -17090000,0.71,0.00055,-0.013,0.71,0.0058,0.0064,0.0024,0,0,-4.9e+02,-0.0012,-0.0059,-8e-05,0.0048,0.0048,-0.13,0.21,-2.8e-06,0.43,-0.00021,0.00063,6e-06,0,0,-4.9e+02,0.00014,0.00013,0.037,0.02,0.022,0.0089,0.046,0.047,0.039,1.5e-06,2.7e-06,2.3e-06,0.0068,0.0089,0.00034,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 -17190000,0.71,0.0006,-0.013,0.71,0.0059,0.0074,0.0023,0,0,-4.9e+02,-0.0012,-0.0059,-7.5e-05,0.0056,0.0047,-0.13,0.21,-3.1e-06,0.43,-0.00022,0.00064,8.5e-06,0,0,-4.9e+02,0.00013,0.00013,0.037,0.018,0.02,0.0087,0.041,0.042,0.039,1.5e-06,2.6e-06,2.3e-06,0.0067,0.0087,0.00033,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 -17290000,0.71,0.00063,-0.013,0.71,0.0077,0.0081,0.005,0,0,-4.9e+02,-0.0012,-0.0059,-7.8e-05,0.0059,0.0056,-0.13,0.21,-3.4e-06,0.43,-0.00023,0.00063,1.1e-05,0,0,-4.9e+02,0.00013,0.00013,0.037,0.019,0.022,0.0087,0.045,0.046,0.039,1.5e-06,2.5e-06,2.3e-06,0.0067,0.0086,0.00033,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 -17390000,0.71,0.00068,-0.013,0.71,0.0075,0.0085,0.0059,0,0,-4.9e+02,-0.0012,-0.0059,-7.2e-05,0.0067,0.0054,-0.13,0.21,-3.6e-06,0.43,-0.00025,0.00064,2.9e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.017,0.02,0.0085,0.041,0.041,0.039,1.4e-06,2.5e-06,2.2e-06,0.0066,0.0085,0.00032,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 -17490000,0.71,0.00063,-0.013,0.71,0.0092,0.0086,0.0072,0,0,-4.9e+02,-0.0012,-0.0059,-7.2e-05,0.0062,0.0051,-0.13,0.21,-3.4e-06,0.43,-0.00025,0.00063,2.4e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.019,0.021,0.0085,0.045,0.046,0.039,1.4e-06,2.4e-06,2.2e-06,0.0065,0.0084,0.00031,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 -17590000,0.71,0.0006,-0.013,0.71,0.0099,0.0079,0.011,0,0,-4.9e+02,-0.0012,-0.0059,-6.9e-05,0.0065,0.0053,-0.13,0.21,-3.6e-06,0.43,-0.00025,0.00064,2.2e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.017,0.019,0.0083,0.04,0.041,0.038,1.4e-06,2.3e-06,2.2e-06,0.0064,0.0083,0.0003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 -17690000,0.71,0.00057,-0.013,0.71,0.011,0.0094,0.01,0,0,-4.9e+02,-0.0012,-0.0059,-6.8e-05,0.0066,0.0051,-0.13,0.21,-3.5e-06,0.43,-0.00026,0.00064,3e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.018,0.021,0.0082,0.045,0.046,0.038,1.3e-06,2.3e-06,2.2e-06,0.0064,0.0082,0.0003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 -17790000,0.71,0.00056,-0.013,0.71,0.012,0.01,0.0095,0,0,-4.9e+02,-0.0012,-0.0059,-5.9e-05,0.0076,0.004,-0.13,0.21,-3.5e-06,0.43,-0.00025,0.00066,3.9e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.016,0.019,0.0081,0.04,0.041,0.038,1.3e-06,2.2e-06,2.2e-06,0.0063,0.008,0.00029,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 -17890000,0.71,0.00055,-0.013,0.71,0.015,0.011,0.0098,0,0,-4.9e+02,-0.0012,-0.0059,-5.6e-05,0.0074,0.0033,-0.13,0.21,-3.2e-06,0.43,-0.00025,0.00067,4.4e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.018,0.021,0.008,0.044,0.045,0.038,1.3e-06,2.2e-06,2.2e-06,0.0063,0.008,0.00028,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 -17990000,0.71,0.00048,-0.013,0.71,0.016,0.0084,0.011,0,0,-4.9e+02,-0.0012,-0.0059,-5.5e-05,0.0072,0.0036,-0.13,0.21,-3.3e-06,0.43,-0.00025,0.00066,4.1e-05,0,0,-4.9e+02,0.00012,0.00012,0.037,0.016,0.019,0.0079,0.04,0.041,0.037,1.2e-06,2.1e-06,2.2e-06,0.0062,0.0078,0.00027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 -18090000,0.71,0.00047,-0.013,0.71,0.017,0.0076,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-6.1e-05,0.0067,0.0046,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00064,3.6e-05,0,0,-4.9e+02,0.00012,0.00012,0.037,0.017,0.02,0.0079,0.044,0.045,0.038,1.2e-06,2.1e-06,2.2e-06,0.0061,0.0078,0.00027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 -18190000,0.71,0.00043,-0.013,0.71,0.018,0.0086,0.013,0,0,-4.9e+02,-0.0012,-0.0059,-5.6e-05,0.0069,0.0042,-0.13,0.21,-3.5e-06,0.43,-0.00026,0.00065,3.7e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.018,0.0077,0.04,0.041,0.037,1.2e-06,2e-06,2.2e-06,0.0061,0.0076,0.00026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 -18290000,0.71,0.00034,-0.013,0.71,0.018,0.0081,0.014,0,0,-4.9e+02,-0.0012,-0.0059,-5.9e-05,0.0064,0.0045,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00064,3.1e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.017,0.02,0.0077,0.044,0.045,0.037,1.2e-06,2e-06,2.2e-06,0.006,0.0076,0.00026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 -18390000,0.71,0.00031,-0.013,0.71,0.02,0.01,0.015,0,0,-4.9e+02,-0.0012,-0.0059,-5.3e-05,0.0062,0.0037,-0.13,0.21,-3.3e-06,0.43,-0.00026,0.00065,3.3e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.015,0.018,0.0075,0.039,0.04,0.037,1.1e-06,1.9e-06,2.2e-06,0.0059,0.0074,0.00025,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 -18490000,0.71,0.00037,-0.013,0.71,0.021,0.011,0.014,0,0,-4.9e+02,-0.0012,-0.0059,-5.2e-05,0.0068,0.0038,-0.13,0.21,-3.5e-06,0.43,-0.00026,0.00066,3.7e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.02,0.0075,0.043,0.045,0.037,1.1e-06,1.9e-06,2.2e-06,0.0059,0.0074,0.00025,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 -18590000,0.71,0.00038,-0.013,0.71,0.02,0.012,0.013,0,0,-4.9e+02,-0.0012,-0.0059,-4.4e-05,0.0076,0.0032,-0.13,0.21,-3.6e-06,0.43,-0.00026,0.00067,4.2e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.015,0.018,0.0074,0.039,0.04,0.037,1.1e-06,1.8e-06,2.2e-06,0.0058,0.0073,0.00024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 -18690000,0.71,0.0003,-0.013,0.71,0.022,0.012,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-4.6e-05,0.0069,0.0033,-0.13,0.21,-3.5e-06,0.43,-0.00025,0.00066,3.6e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.019,0.0074,0.043,0.044,0.036,1e-06,1.8e-06,2.2e-06,0.0058,0.0072,0.00024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 -18790000,0.71,0.00032,-0.013,0.71,0.021,0.011,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-4.5e-05,0.0071,0.0038,-0.13,0.21,-3.7e-06,0.43,-0.00026,0.00065,3.3e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.015,0.018,0.0073,0.039,0.04,0.036,1e-06,1.7e-06,2.2e-06,0.0057,0.0071,0.00023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 -18890000,0.71,0.00041,-0.013,0.71,0.021,0.013,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-3.9e-05,0.008,0.0033,-0.13,0.21,-3.8e-06,0.43,-0.00027,0.00067,4.6e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.019,0.0072,0.043,0.044,0.036,1e-06,1.7e-06,2.2e-06,0.0057,0.007,0.00023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 -18990000,0.71,0.00046,-0.013,0.71,0.021,0.014,0.011,0,0,-4.9e+02,-0.0013,-0.0059,-3.3e-05,0.0087,0.0034,-0.13,0.21,-4.1e-06,0.43,-0.00028,0.00068,4.8e-05,0,0,-4.9e+02,0.00011,0.0001,0.037,0.015,0.017,0.0071,0.039,0.04,0.036,9.7e-07,1.6e-06,2.2e-06,0.0056,0.0069,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 -19090000,0.71,0.0005,-0.013,0.71,0.021,0.015,0.013,0,0,-4.9e+02,-0.0013,-0.0059,-3.3e-05,0.0093,0.0037,-0.13,0.21,-4.3e-06,0.43,-0.00029,0.00069,5.2e-05,0,0,-4.9e+02,0.00011,0.0001,0.037,0.016,0.019,0.0071,0.042,0.044,0.036,9.6e-07,1.6e-06,2.2e-06,0.0056,0.0069,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 -19190000,0.71,0.00055,-0.013,0.71,0.02,0.015,0.013,0,0,-4.9e+02,-0.0013,-0.0059,-2.6e-05,0.0098,0.0038,-0.13,0.21,-4.5e-06,0.43,-0.0003,0.00069,5.5e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.014,0.017,0.007,0.038,0.04,0.036,9.3e-07,1.5e-06,2.1e-06,0.0055,0.0068,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 -19290000,0.71,0.00058,-0.013,0.71,0.02,0.015,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-2.9e-05,0.0097,0.0042,-0.13,0.21,-4.5e-06,0.43,-0.00031,0.00068,5.8e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.015,0.019,0.007,0.042,0.044,0.036,9.2e-07,1.5e-06,2.1e-06,0.0055,0.0067,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 -19390000,0.71,0.00054,-0.013,0.71,0.019,0.014,0.018,0,0,-4.9e+02,-0.0013,-0.0059,-2.3e-05,0.0096,0.0041,-0.13,0.21,-4.6e-06,0.43,-0.0003,0.00068,5.3e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.014,0.017,0.0069,0.038,0.04,0.036,8.9e-07,1.5e-06,2.1e-06,0.0054,0.0066,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 -19490000,0.71,0.00055,-0.013,0.71,0.019,0.015,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-1.8e-05,0.0096,0.0034,-0.13,0.21,-4.4e-06,0.43,-0.0003,0.00069,5.6e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.015,0.018,0.0069,0.042,0.044,0.035,8.8e-07,1.4e-06,2.1e-06,0.0054,0.0066,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 -19590000,0.71,0.00062,-0.013,0.71,0.017,0.014,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-6.3e-06,0.01,0.0031,-0.13,0.21,-4.6e-06,0.43,-0.00031,0.0007,6.4e-05,0,0,-4.9e+02,0.00011,9.8e-05,0.036,0.014,0.017,0.0068,0.038,0.039,0.035,8.5e-07,1.4e-06,2.1e-06,0.0054,0.0065,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 -19690000,0.71,0.00067,-0.013,0.71,0.017,0.012,0.016,0,0,-4.9e+02,-0.0013,-0.0059,-9.7e-06,0.011,0.0037,-0.13,0.21,-4.8e-06,0.43,-0.00031,0.0007,5.6e-05,0,0,-4.9e+02,0.00011,9.8e-05,0.036,0.015,0.018,0.0068,0.042,0.043,0.035,8.4e-07,1.4e-06,2.1e-06,0.0053,0.0064,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 -19790000,0.71,0.00074,-0.013,0.71,0.015,0.01,0.017,0,0,-4.9e+02,-0.0013,-0.0059,-5.3e-06,0.011,0.0041,-0.13,0.21,-5.1e-06,0.43,-0.00032,0.0007,5.5e-05,0,0,-4.9e+02,0.00011,9.6e-05,0.036,0.014,0.017,0.0067,0.038,0.039,0.035,8.2e-07,1.3e-06,2.1e-06,0.0053,0.0063,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 -19890000,0.71,0.00066,-0.013,0.71,0.015,0.012,0.018,0,0,-4.9e+02,-0.0013,-0.0058,2.9e-06,0.011,0.003,-0.13,0.21,-4.8e-06,0.43,-0.00031,0.00071,6.2e-05,0,0,-4.9e+02,0.00011,9.6e-05,0.036,0.015,0.018,0.0067,0.041,0.043,0.035,8.1e-07,1.3e-06,2.1e-06,0.0052,0.0063,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 -19990000,0.71,0.00063,-0.013,0.71,0.013,0.012,0.02,0,0,-4.9e+02,-0.0013,-0.0058,1.8e-05,0.011,0.0022,-0.13,0.21,-4.6e-06,0.43,-0.00031,0.00073,6.7e-05,0,0,-4.9e+02,0.0001,9.4e-05,0.036,0.014,0.017,0.0066,0.038,0.039,0.035,7.9e-07,1.3e-06,2.1e-06,0.0052,0.0062,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 -20090000,0.71,0.00066,-0.013,0.71,0.013,0.013,0.02,0,0,-4.9e+02,-0.0013,-0.0058,2.8e-05,0.012,0.0014,-0.13,0.21,-4.5e-06,0.43,-0.00032,0.00075,7.7e-05,0,0,-4.9e+02,0.00011,9.5e-05,0.036,0.014,0.018,0.0066,0.041,0.043,0.035,7.8e-07,1.2e-06,2.1e-06,0.0052,0.0062,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 -20190000,0.71,0.00069,-0.013,0.71,0.012,0.011,0.022,0,0,-4.9e+02,-0.0013,-0.0058,3.7e-05,0.012,0.0011,-0.13,0.21,-4.4e-06,0.43,-0.00031,0.00075,7.6e-05,0,0,-4.9e+02,0.0001,9.3e-05,0.036,0.013,0.016,0.0065,0.038,0.039,0.034,7.6e-07,1.2e-06,2.1e-06,0.0051,0.0061,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 -20290000,0.71,0.0007,-0.013,0.71,0.01,0.011,0.021,0,0,-4.9e+02,-0.0013,-0.0058,4.1e-05,0.012,0.001,-0.13,0.21,-4.5e-06,0.43,-0.00032,0.00076,7.7e-05,0,0,-4.9e+02,0.0001,9.3e-05,0.036,0.014,0.018,0.0065,0.041,0.043,0.034,7.5e-07,1.2e-06,2.1e-06,0.0051,0.0061,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 -20390000,0.71,0.00065,-0.013,0.7,0.0086,0.0091,0.022,0,0,-4.9e+02,-0.0013,-0.0058,4.5e-05,0.012,0.0011,-0.13,0.21,-4.5e-06,0.43,-0.00031,0.00076,6.7e-05,0,0,-4.9e+02,0.0001,9.1e-05,0.036,0.013,0.016,0.0064,0.037,0.039,0.034,7.3e-07,1.1e-06,2e-06,0.005,0.006,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 -20490000,0.71,0.00071,-0.013,0.7,0.0087,0.009,0.022,0,0,-4.9e+02,-0.0013,-0.0058,4.2e-05,0.012,0.0014,-0.13,0.21,-4.6e-06,0.43,-0.00031,0.00075,6.6e-05,0,0,-4.9e+02,0.0001,9.1e-05,0.036,0.014,0.017,0.0064,0.041,0.043,0.034,7.2e-07,1.1e-06,2e-06,0.005,0.0059,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 -20590000,0.71,0.00074,-0.013,0.7,0.0078,0.0069,0.02,0,0,-4.9e+02,-0.0013,-0.0058,4.2e-05,0.012,0.0019,-0.13,0.21,-4.8e-06,0.43,-0.00031,0.00074,6.6e-05,0,0,-4.9e+02,9.9e-05,8.9e-05,0.036,0.013,0.016,0.0063,0.037,0.039,0.034,7e-07,1.1e-06,2e-06,0.005,0.0058,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 -20690000,0.71,0.00077,-0.013,0.7,0.0085,0.007,0.021,0,0,-4.9e+02,-0.0013,-0.0058,4.6e-05,0.012,0.0017,-0.13,0.21,-4.7e-06,0.43,-0.00032,0.00075,6.7e-05,0,0,-4.9e+02,0.0001,9e-05,0.036,0.014,0.017,0.0064,0.041,0.043,0.034,6.9e-07,1.1e-06,2e-06,0.005,0.0058,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 -20790000,0.71,0.0008,-0.013,0.7,0.0063,0.0065,0.022,0,0,-4.9e+02,-0.0013,-0.0058,5.1e-05,0.013,0.0018,-0.13,0.21,-4.8e-06,0.43,-0.00032,0.00075,6.2e-05,0,0,-4.9e+02,9.8e-05,8.8e-05,0.036,0.013,0.016,0.0063,0.037,0.039,0.034,6.7e-07,1e-06,2e-06,0.0049,0.0057,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 -20890000,0.71,0.00081,-0.013,0.7,0.0062,0.0062,0.021,0,0,-4.9e+02,-0.0013,-0.0058,5.8e-05,0.013,0.0014,-0.13,0.21,-4.8e-06,0.43,-0.00032,0.00077,6.6e-05,0,0,-4.9e+02,9.9e-05,8.8e-05,0.036,0.014,0.017,0.0063,0.04,0.043,0.034,6.7e-07,1e-06,2e-06,0.0049,0.0057,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 -20990000,0.71,0.00083,-0.013,0.7,0.0045,0.0039,0.021,0,0,-4.9e+02,-0.0013,-0.0058,6.3e-05,0.013,0.0016,-0.13,0.21,-4.8e-06,0.43,-0.00034,0.00077,6.3e-05,0,0,-4.9e+02,9.6e-05,8.6e-05,0.036,0.013,0.016,0.0062,0.037,0.039,0.033,6.5e-07,9.9e-07,2e-06,0.0048,0.0056,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 -21090000,0.71,0.00081,-0.013,0.7,0.0055,0.0031,0.022,0,0,-4.9e+02,-0.0013,-0.0058,6.8e-05,0.013,0.0012,-0.13,0.21,-4.6e-06,0.43,-0.00033,0.00078,6e-05,0,0,-4.9e+02,9.7e-05,8.6e-05,0.036,0.014,0.017,0.0062,0.04,0.043,0.034,6.4e-07,9.9e-07,2e-06,0.0048,0.0056,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 -21190000,0.71,0.00081,-0.013,0.7,0.0057,0.0022,0.021,0,0,-4.9e+02,-0.0013,-0.0058,6.8e-05,0.013,0.0013,-0.13,0.21,-4.6e-06,0.43,-0.00033,0.00077,5.8e-05,0,0,-4.9e+02,9.5e-05,8.5e-05,0.036,0.013,0.016,0.0061,0.037,0.039,0.033,6.3e-07,9.5e-07,2e-06,0.0048,0.0055,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 -21290000,0.71,0.0009,-0.013,0.7,0.005,0.0023,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.8e-05,0.013,0.00089,-0.13,0.21,-4.6e-06,0.43,-0.00034,0.0008,6.1e-05,0,0,-4.9e+02,9.5e-05,8.5e-05,0.036,0.014,0.017,0.0061,0.04,0.043,0.033,6.2e-07,9.4e-07,1.9e-06,0.0048,0.0055,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 -21390000,0.71,0.00088,-0.013,0.7,0.004,0.00029,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.3e-05,0.013,0.0011,-0.13,0.21,-4.8e-06,0.43,-0.00033,0.00079,6.2e-05,0,0,-4.9e+02,9.3e-05,8.3e-05,0.036,0.013,0.016,0.0061,0.037,0.039,0.033,6e-07,9.1e-07,1.9e-06,0.0047,0.0054,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 -21490000,0.71,0.00088,-0.013,0.7,0.0045,0.00071,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.8e-05,0.013,0.0007,-0.13,0.21,-4.7e-06,0.43,-0.00032,0.00079,6.6e-05,0,0,-4.9e+02,9.4e-05,8.3e-05,0.036,0.014,0.017,0.0061,0.04,0.043,0.033,6e-07,9e-07,1.9e-06,0.0047,0.0054,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 -21590000,0.71,0.00087,-0.013,0.7,0.0034,0.0012,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.6e-05,0.013,0.00074,-0.13,0.21,-4.9e-06,0.43,-0.00032,0.00079,6.4e-05,0,0,-4.9e+02,9.1e-05,8.2e-05,0.036,0.013,0.015,0.006,0.037,0.039,0.033,5.8e-07,8.7e-07,1.9e-06,0.0047,0.0054,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 -21690000,0.71,0.00084,-0.013,0.7,0.005,0.0015,0.025,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.013,0.00033,-0.13,0.21,-4.8e-06,0.43,-0.00031,0.00079,6.4e-05,0,0,-4.9e+02,9.2e-05,8.2e-05,0.036,0.013,0.017,0.006,0.04,0.042,0.033,5.8e-07,8.7e-07,1.9e-06,0.0047,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 -21790000,0.71,0.00084,-0.013,0.7,0.0031,0.0037,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.1e-05,0.013,0.00051,-0.13,0.21,-5.3e-06,0.43,-0.00033,0.00079,6.6e-05,0,0,-4.9e+02,9e-05,8.1e-05,0.036,0.012,0.015,0.006,0.037,0.039,0.033,5.6e-07,8.3e-07,1.9e-06,0.0046,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 -21890000,0.71,0.00083,-0.013,0.7,0.0039,0.0042,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.2e-05,0.013,0.00043,-0.13,0.21,-5.3e-06,0.43,-0.00033,0.00079,6.4e-05,0,0,-4.9e+02,9.1e-05,8.1e-05,0.036,0.013,0.016,0.006,0.04,0.042,0.033,5.6e-07,8.3e-07,1.9e-06,0.0046,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 -21990000,0.71,0.00085,-0.013,0.7,0.0027,0.0049,0.025,0,0,-4.9e+02,-0.0013,-0.0058,6.9e-05,0.013,0.00025,-0.13,0.21,-5.7e-06,0.43,-0.00034,0.00079,6.5e-05,0,0,-4.9e+02,8.9e-05,7.9e-05,0.036,0.012,0.015,0.0059,0.036,0.038,0.033,5.5e-07,8e-07,1.9e-06,0.0046,0.0052,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22090000,0.71,0.00087,-0.013,0.7,0.0025,0.0065,0.024,0,0,-4.9e+02,-0.0013,-0.0058,6.9e-05,0.014,0.00031,-0.13,0.21,-5.7e-06,0.43,-0.00034,0.00079,6.5e-05,0,0,-4.9e+02,8.9e-05,8e-05,0.036,0.013,0.016,0.0059,0.04,0.042,0.033,5.4e-07,8e-07,1.9e-06,0.0046,0.0052,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22190000,0.71,0.00085,-0.013,0.7,0.002,0.0065,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.5e-05,0.014,0.00037,-0.13,0.21,-5.5e-06,0.43,-0.00035,0.0008,5.5e-05,0,0,-4.9e+02,8.7e-05,7.8e-05,0.036,0.012,0.015,0.0059,0.036,0.038,0.033,5.3e-07,7.7e-07,1.8e-06,0.0045,0.0051,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22290000,0.71,0.00087,-0.013,0.7,0.0014,0.0062,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.3e-05,0.013,0.00043,-0.13,0.21,-5.5e-06,0.43,-0.00035,0.00079,5.6e-05,0,0,-4.9e+02,8.8e-05,7.8e-05,0.036,0.013,0.016,0.0059,0.04,0.042,0.033,5.2e-07,7.7e-07,1.8e-06,0.0045,0.0051,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22390000,0.71,0.00089,-0.013,0.7,-0.00096,0.0059,0.026,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.014,0.00063,-0.13,0.21,-5.4e-06,0.43,-0.00035,0.0008,5.7e-05,0,0,-4.9e+02,8.6e-05,7.7e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.033,5.1e-07,7.4e-07,1.8e-06,0.0045,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22490000,0.71,0.00093,-0.013,0.7,-0.0021,0.0067,0.027,0,0,-4.9e+02,-0.0013,-0.0058,8.1e-05,0.014,0.00077,-0.13,0.21,-5.4e-06,0.43,-0.00037,0.0008,5.5e-05,0,0,-4.9e+02,8.7e-05,7.7e-05,0.036,0.013,0.016,0.0058,0.039,0.042,0.033,5.1e-07,7.4e-07,1.8e-06,0.0045,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22590000,0.71,0.00096,-0.013,0.7,-0.0038,0.0061,0.026,0,0,-4.9e+02,-0.0014,-0.0058,8.4e-05,0.015,0.00094,-0.13,0.21,-5.3e-06,0.43,-0.00038,0.00081,5.2e-05,0,0,-4.9e+02,8.5e-05,7.6e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.032,5e-07,7.1e-07,1.8e-06,0.0044,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22690000,0.71,0.001,-0.013,0.7,-0.0051,0.0075,0.027,0,0,-4.9e+02,-0.0014,-0.0058,9e-05,0.015,0.00082,-0.13,0.21,-5.3e-06,0.43,-0.00039,0.00082,5.1e-05,0,0,-4.9e+02,8.5e-05,7.6e-05,0.036,0.013,0.016,0.0058,0.039,0.042,0.033,4.9e-07,7.1e-07,1.8e-06,0.0044,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22790000,0.71,0.001,-0.013,0.7,-0.0071,0.0064,0.028,0,0,-4.9e+02,-0.0014,-0.0058,7.9e-05,0.015,0.0016,-0.13,0.21,-5.5e-06,0.43,-0.00038,0.00081,5.7e-05,0,0,-4.9e+02,8.3e-05,7.5e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.032,4.8e-07,6.8e-07,1.8e-06,0.0044,0.0049,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22890000,0.71,0.00099,-0.013,0.7,-0.0075,0.0073,0.03,0,0,-4.9e+02,-0.0014,-0.0058,7.9e-05,0.015,0.0015,-0.13,0.21,-5.4e-06,0.43,-0.00038,0.0008,5.3e-05,0,0,-4.9e+02,8.4e-05,7.5e-05,0.036,0.013,0.016,0.0058,0.039,0.042,0.032,4.8e-07,6.8e-07,1.7e-06,0.0044,0.0049,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -22990000,0.71,0.00097,-0.013,0.7,-0.0076,0.0064,0.03,0,0,-4.9e+02,-0.0014,-0.0058,8.8e-05,0.015,0.0014,-0.13,0.21,-5.1e-06,0.43,-0.00038,0.00081,5e-05,0,0,-4.9e+02,8.2e-05,7.4e-05,0.036,0.012,0.015,0.0057,0.036,0.038,0.032,4.7e-07,6.6e-07,1.7e-06,0.0044,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -23090000,0.71,0.00092,-0.013,0.7,-0.008,0.0062,0.031,0,0,-4.9e+02,-0.0014,-0.0058,8e-05,0.014,0.0016,-0.13,0.21,-5.3e-06,0.43,-0.00038,0.00079,4.8e-05,0,0,-4.9e+02,8.3e-05,7.4e-05,0.036,0.013,0.016,0.0057,0.039,0.042,0.032,4.7e-07,6.6e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 -23190000,0.71,0.00097,-0.013,0.7,-0.0093,0.0043,0.032,0,0,-4.9e+02,-0.0014,-0.0058,8.3e-05,0.015,0.0018,-0.13,0.21,-5.3e-06,0.43,-0.00037,0.00079,4e-05,0,0,-4.9e+02,8.1e-05,7.3e-05,0.036,0.012,0.014,0.0057,0.036,0.038,0.032,4.6e-07,6.3e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0012,1,1,0.01 -23290000,0.71,0.00089,-0.013,0.7,-0.0092,0.0037,0.032,0,0,-4.9e+02,-0.0014,-0.0058,8.4e-05,0.014,0.0016,-0.13,0.21,-5.2e-06,0.43,-0.00037,0.00079,3.9e-05,0,0,-4.9e+02,8.2e-05,7.3e-05,0.036,0.013,0.016,0.0057,0.039,0.042,0.032,4.5e-07,6.3e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0012,1,1,0.01 -23390000,0.71,0.00095,-0.013,0.7,-0.0095,0.0026,0.03,0,0,-4.9e+02,-0.0014,-0.0058,8.7e-05,0.014,0.0016,-0.13,0.21,-5.3e-06,0.43,-0.00035,0.00078,4e-05,0,0,-4.9e+02,8e-05,7.2e-05,0.036,0.012,0.014,0.0057,0.036,0.038,0.032,4.4e-07,6.1e-07,1.7e-06,0.0043,0.0047,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0012,1,1,0.01 -23490000,0.71,0.0033,-0.011,0.7,-0.016,0.0028,-0.0031,0,0,-4.9e+02,-0.0014,-0.0058,9.3e-05,0.014,0.0014,-0.13,0.21,-5.3e-06,0.43,-0.00034,0.00081,6.4e-05,0,0,-4.9e+02,8.1e-05,7.2e-05,0.036,0.013,0.015,0.0057,0.039,0.042,0.032,4.4e-07,6.1e-07,1.7e-06,0.0043,0.0047,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0012,1,1,0.01 -23590000,0.71,0.0086,-0.0027,0.7,-0.027,0.0028,-0.035,0,0,-4.9e+02,-0.0013,-0.0058,8.9e-05,0.014,0.0014,-0.13,0.21,-5.2e-06,0.43,-0.00034,0.00087,0.00013,0,0,-4.9e+02,7.9e-05,7.1e-05,0.036,0.012,0.014,0.0056,0.036,0.038,0.032,4.3e-07,5.9e-07,1.6e-06,0.0042,0.0047,0.00012,0.0013,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -23690000,0.71,0.0082,0.0031,0.71,-0.058,-0.005,-0.085,0,0,-4.9e+02,-0.0014,-0.0058,9e-05,0.014,0.0014,-0.13,0.21,-5.2e-06,0.43,-0.00034,0.00081,0.0001,0,0,-4.9e+02,8e-05,7.1e-05,0.036,0.013,0.015,0.0056,0.039,0.042,0.032,4.3e-07,5.9e-07,1.6e-06,0.0042,0.0047,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -23790000,0.71,0.0052,-0.00025,0.71,-0.083,-0.017,-0.14,0,0,-4.9e+02,-0.0013,-0.0058,9.1e-05,0.013,0.00092,-0.13,0.21,-4.5e-06,0.43,-0.0004,0.0008,0.00045,0,0,-4.9e+02,7.8e-05,7e-05,0.036,0.012,0.014,0.0056,0.036,0.038,0.032,4.2e-07,5.7e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -23890000,0.71,0.0026,-0.0063,0.71,-0.1,-0.025,-0.19,0,0,-4.9e+02,-0.0013,-0.0058,9.1e-05,0.014,0.0011,-0.13,0.21,-4.3e-06,0.43,-0.00042,0.00086,0.00036,0,0,-4.9e+02,7.8e-05,7e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4.2e-07,5.7e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -23990000,0.71,0.0013,-0.011,0.71,-0.1,-0.029,-0.25,0,0,-4.9e+02,-0.0013,-0.0058,9.6e-05,0.014,0.0011,-0.13,0.21,-4e-06,0.43,-0.0004,0.00086,0.00034,0,0,-4.9e+02,7.7e-05,6.9e-05,0.036,0.012,0.015,0.0056,0.036,0.038,0.032,4.1e-07,5.5e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24090000,0.71,0.0025,-0.0096,0.71,-0.1,-0.028,-0.29,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.013,0.00076,-0.13,0.21,-3.6e-06,0.43,-0.00042,0.00083,0.00037,0,0,-4.9e+02,7.7e-05,6.9e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4.1e-07,5.5e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24190000,0.71,0.0036,-0.0073,0.71,-0.11,-0.03,-0.34,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.00064,-0.13,0.21,-2.9e-06,0.43,-0.00043,0.00086,0.00037,0,0,-4.9e+02,7.6e-05,6.8e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,4e-07,5.4e-07,1.6e-06,0.0042,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24290000,0.71,0.0041,-0.0065,0.71,-0.12,-0.034,-0.4,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.013,0.00061,-0.13,0.21,-2.6e-06,0.43,-0.00046,0.0009,0.00044,0,0,-4.9e+02,7.6e-05,6.9e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4e-07,5.4e-07,1.6e-06,0.0042,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24390000,0.71,0.0042,-0.0067,0.71,-0.13,-0.041,-0.45,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.0012,-0.13,0.21,2.4e-07,0.43,-0.00035,0.00095,0.00043,0,0,-4.9e+02,7.5e-05,6.7e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.9e-07,5.2e-07,1.5e-06,0.0041,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24490000,0.71,0.005,-0.0025,0.71,-0.14,-0.046,-0.5,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.0012,-0.13,0.21,2.4e-07,0.43,-0.00035,0.00096,0.00042,0,0,-4.9e+02,7.5e-05,6.8e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.9e-07,5.2e-07,1.5e-06,0.0041,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 -24590000,0.71,0.0055,0.0012,0.71,-0.16,-0.057,-0.55,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0012,-0.13,0.21,1.3e-06,0.43,1.1e-05,0.00061,0.00037,0,0,-4.9e+02,7.4e-05,6.7e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.8e-07,5e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -24690000,0.71,0.0056,0.0021,0.71,-0.18,-0.07,-0.64,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0011,-0.13,0.21,2.3e-06,0.43,-3.4e-05,0.00065,0.00055,0,0,-4.9e+02,7.5e-05,6.7e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.8e-07,5e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -24790000,0.71,0.0053,0.00084,0.71,-0.2,-0.084,-0.72,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0011,-0.13,0.21,1.6e-06,0.43,-2.5e-06,0.00062,0.00032,0,0,-4.9e+02,7.3e-05,6.6e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.7e-07,4.9e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -24890000,0.71,0.0071,0.0025,0.71,-0.22,-0.095,-0.74,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0012,-0.13,0.21,2.4e-06,0.43,-0.00011,0.00077,0.00034,0,0,-4.9e+02,7.4e-05,6.6e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.7e-07,4.9e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -24990000,0.71,0.0089,0.0043,0.71,-0.24,-0.1,-0.8,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.012,0.00082,-0.13,0.21,1.8e-06,0.43,-0.0002,0.00087,-4.5e-06,0,0,-4.9e+02,7.2e-05,6.5e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.7e-07,4.8e-07,1.5e-06,0.0041,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25090000,0.71,0.0092,0.0037,0.71,-0.27,-0.11,-0.85,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.012,0.00091,-0.13,0.21,1.4e-06,0.43,-0.00021,0.00088,-4e-05,0,0,-4.9e+02,7.3e-05,6.5e-05,0.036,0.013,0.017,0.0055,0.039,0.042,0.031,3.7e-07,4.8e-07,1.5e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25190000,0.71,0.0087,0.0023,0.71,-0.3,-0.13,-0.9,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.0012,-0.13,0.21,6.7e-06,0.43,4.6e-05,0.00085,9.5e-05,0,0,-4.9e+02,7.2e-05,6.4e-05,0.035,0.012,0.016,0.0054,0.036,0.038,0.031,3.6e-07,4.6e-07,1.5e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25290000,0.71,0.011,0.0091,0.71,-0.33,-0.14,-0.95,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.0012,-0.13,0.21,6.6e-06,0.43,7.2e-05,0.0008,0.0001,0,0,-4.9e+02,7.2e-05,6.5e-05,0.035,0.013,0.017,0.0054,0.039,0.042,0.031,3.6e-07,4.6e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25390000,0.71,0.012,0.016,0.71,-0.36,-0.16,-1,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.00096,-0.13,0.21,1e-05,0.43,0.00047,0.00048,0.00014,0,0,-4.9e+02,7.1e-05,6.3e-05,0.035,0.012,0.016,0.0054,0.036,0.038,0.031,3.5e-07,4.5e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25490000,0.71,0.012,0.017,0.71,-0.41,-0.18,-1.1,0,0,-4.9e+02,-0.0013,-0.0058,0.00014,0.01,0.00084,-0.13,0.21,9.2e-06,0.43,0.00065,0.00016,0.00032,0,0,-4.9e+02,7.2e-05,6.4e-05,0.035,0.013,0.018,0.0054,0.039,0.042,0.031,3.5e-07,4.5e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25590000,0.71,0.012,0.015,0.71,-0.45,-0.21,-1.1,0,0,-4.9e+02,-0.0012,-0.0058,0.00015,0.0097,0.0012,-0.13,0.21,1.5e-05,0.43,0.00094,0.00016,0.00034,0,0,-4.9e+02,7.1e-05,6.3e-05,0.034,0.012,0.018,0.0054,0.036,0.038,0.031,3.5e-07,4.4e-07,1.4e-06,0.004,0.0042,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 -25690000,0.71,0.015,0.022,0.71,-0.49,-0.23,-1.2,0,0,-4.9e+02,-0.0012,-0.0058,0.00016,0.0097,0.0012,-0.13,0.21,1.6e-05,0.43,0.00093,0.00018,0.00042,0,0,-4.9e+02,7.1e-05,6.3e-05,0.034,0.013,0.02,0.0054,0.039,0.042,0.031,3.5e-07,4.4e-07,1.4e-06,0.004,0.0042,0.00011,0.0012,3.9e-05,0.0012,0.0014,0.0012,0.0011,1,1,0.01 -25790000,0.71,0.018,0.028,0.71,-0.54,-0.26,-1.2,0,0,-4.9e+02,-0.0012,-0.0058,0.00016,0.0091,0.00052,-0.13,0.21,1.9e-05,0.43,0.0013,-6.7e-05,-3.2e-05,0,0,-4.9e+02,7e-05,6.2e-05,0.033,0.013,0.019,0.0054,0.036,0.038,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0014,0.0011,0.0011,1,1,0.01 -25890000,0.71,0.018,0.028,0.71,-0.62,-0.29,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00017,0.0093,0.00045,-0.13,0.21,2.1e-05,0.43,0.0014,1.4e-06,-9.8e-05,0,0,-4.9e+02,7.1e-05,6.3e-05,0.033,0.014,0.022,0.0054,0.039,0.042,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0014,0.0011,0.0011,1,1,0.01 -25990000,0.7,0.017,0.025,0.71,-0.67,-0.32,-1.3,0,0,-4.9e+02,-0.0012,-0.0059,0.00019,0.0084,0.00078,-0.13,0.21,2.8e-05,0.43,0.0023,-0.00056,-0.00055,0,0,-4.9e+02,7e-05,6.2e-05,0.032,0.013,0.021,0.0054,0.036,0.039,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0013,0.0011,0.0011,1,1,0.01 -26090000,0.7,0.022,0.035,0.71,-0.74,-0.35,-1.3,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.0085,0.00095,-0.13,0.21,2.4e-05,0.43,0.0024,-0.00048,-0.0012,0,0,-4.9e+02,7.1e-05,6.2e-05,0.032,0.014,0.024,0.0054,0.039,0.043,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0013,0.0011,0.0011,1,1,0.01 -26190000,0.7,0.024,0.045,0.71,-0.79,-0.39,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00018,0.0074,-0.00018,-0.13,0.21,3.8e-05,0.43,0.0023,0.00041,-0.0014,0,0,-4.9e+02,7.1e-05,6.1e-05,0.03,0.014,0.024,0.0053,0.036,0.039,0.031,3.3e-07,4.2e-07,1.4e-06,0.004,0.0042,0.0001,0.001,3.9e-05,0.001,0.0013,0.001,0.001,1,1,0.01 -26290000,0.7,0.025,0.047,0.71,-0.89,-0.43,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00018,0.0073,-0.00016,-0.13,0.21,3.7e-05,0.43,0.0023,0.00028,-0.0014,0,0,-4.9e+02,7.1e-05,6.1e-05,0.03,0.015,0.028,0.0054,0.039,0.043,0.031,3.3e-07,4.2e-07,1.4e-06,0.004,0.0042,0.0001,0.001,3.9e-05,0.00099,0.0013,0.001,0.00099,1,1,0.01 -26390000,0.7,0.024,0.044,0.71,-0.96,-0.49,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00021,0.0064,0.00061,-0.13,0.21,4.4e-05,0.44,0.0036,-0.00018,-0.0024,0,0,-4.9e+02,7.1e-05,6.1e-05,0.028,0.014,0.027,0.0053,0.036,0.039,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0042,0.0001,0.00096,3.9e-05,0.00095,0.0012,0.00096,0.00095,1,1,0.01 -26490000,0.7,0.031,0.06,0.71,-1.1,-0.53,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.0002,0.0064,0.00062,-0.13,0.21,3.8e-05,0.44,0.0039,-0.00099,-0.0026,0,0,-4.9e+02,7.2e-05,6.1e-05,0.028,0.016,0.031,0.0053,0.039,0.044,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0042,0.0001,0.00092,3.9e-05,0.00092,0.0012,0.00092,0.00091,1,1,0.01 -26590000,0.7,0.037,0.076,0.71,-1.2,-0.59,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00019,0.0049,-0.00038,-0.13,0.21,3.7e-05,0.44,0.0041,-0.00065,-0.0048,0,0,-4.9e+02,7.2e-05,6e-05,0.025,0.015,0.031,0.0053,0.036,0.04,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.9e-05,0.00087,3.9e-05,0.00086,0.001,0.00087,0.00086,1,1,0.01 -26690000,0.7,0.039,0.079,0.71,-1.3,-0.65,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00019,0.0049,-0.00047,-0.13,0.21,4.3e-05,0.44,0.0039,-0.00013,-0.004,0,0,-4.9e+02,7.2e-05,6.1e-05,0.025,0.017,0.038,0.0053,0.04,0.045,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.9e-05,0.00081,3.9e-05,0.0008,0.001,0.00081,0.00079,1,1,0.01 -26790000,0.7,0.036,0.073,0.71,-1.4,-0.74,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00022,0.0032,0.00039,-0.13,0.21,8.2e-05,0.44,0.0054,0.00061,-0.0037,0,0,-4.9e+02,7.2e-05,6e-05,0.022,0.016,0.036,0.0053,0.036,0.041,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.8e-05,0.00076,3.9e-05,0.00075,0.00092,0.00076,0.00074,1,1,0.01 -26890000,0.7,0.045,0.095,0.71,-1.6,-0.8,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00023,0.0033,0.00038,-0.13,0.21,8.7e-05,0.44,0.0053,0.0012,-0.0041,0,0,-4.9e+02,7.3e-05,6e-05,0.022,0.018,0.043,0.0053,0.04,0.046,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.8e-05,0.00072,3.9e-05,0.0007,0.00092,0.00072,0.0007,1,1,0.01 -26990000,0.7,0.051,0.12,0.71,-1.7,-0.89,-1.3,0,0,-4.9e+02,-0.00098,-0.0059,0.00022,0.0014,-0.0015,-0.13,0.21,0.00012,0.44,0.006,0.0034,-0.0056,0,0,-4.9e+02,7.4e-05,6e-05,0.019,0.017,0.042,0.0053,0.037,0.041,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.7e-05,0.00065,3.9e-05,0.00063,0.00079,0.00065,0.00062,1,1,0.01 -27090000,0.7,0.052,0.12,0.71,-1.9,-0.98,-1.2,0,0,-4.9e+02,-0.00098,-0.0059,0.00022,0.0013,-0.0015,-0.13,0.21,0.00012,0.44,0.006,0.0035,-0.0052,0,0,-4.9e+02,7.4e-05,6e-05,0.019,0.02,0.052,0.0053,0.04,0.048,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.6e-05,0.00059,3.9e-05,0.00056,0.00078,0.0006,0.00056,1,1,0.01 -27190000,0.7,0.05,0.11,0.7,-2.1,-1,-1.2,0,0,-4.9e+02,-0.00097,-0.0059,0.00022,0.0002,-0.0017,-0.13,0.21,4.5e-05,0.44,0.002,0.0027,-0.0049,0,0,-4.9e+02,7.5e-05,6e-05,0.016,0.02,0.051,0.0053,0.043,0.05,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.6e-05,0.00055,3.9e-05,0.00051,0.00066,0.00055,0.00051,1,1,0.01 -27290000,0.71,0.044,0.095,0.7,-2.3,-1.1,-1.2,0,0,-4.9e+02,-0.00097,-0.0059,0.00023,0.00025,-0.0017,-0.13,0.21,5.2e-05,0.44,0.0018,0.0034,-0.0049,0,0,-4.9e+02,7.6e-05,6.1e-05,0.016,0.022,0.059,0.0053,0.047,0.057,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.5e-05,0.00052,3.9e-05,0.00048,0.00066,0.00052,0.00048,1,1,0.01 -27390000,0.71,0.038,0.079,0.7,-2.4,-1.1,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00022,-0.001,-0.0034,-0.13,0.21,9.9e-06,0.44,-0.00061,0.0031,-0.0063,0,0,-4.9e+02,7.6e-05,6e-05,0.013,0.021,0.052,0.0053,0.049,0.059,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.5e-05,0.00049,3.9e-05,0.00046,0.00055,0.00049,0.00046,1,1,0.01 -27490000,0.71,0.032,0.064,0.7,-2.5,-1.1,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00022,-0.00093,-0.0034,-0.13,0.21,1.5e-05,0.44,-0.00069,0.0032,-0.0067,0,0,-4.9e+02,7.7e-05,6.1e-05,0.013,0.023,0.056,0.0053,0.054,0.067,0.03,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.4e-05,0.00048,3.9e-05,0.00045,0.00055,0.00048,0.00044,1,1,0.01 +6790000,0.71,0.0012,-0.014,0.71,-0.0056,0.0034,-0.11,0,0,-4.9e+02,-0.0014,-0.0057,-7.5e-05,0,0,-6.5e-05,0.21,0.00022,0.43,0.0002,0.00068,-0.0026,0,0,-4.9e+02,0.0013,0.0013,0.055,0.18,0.18,0.6,0.1,0.1,0.2,7.8e-05,7.7e-05,2.4e-06,0.04,0.04,0.04,0.0015,0.0014,0.0015,0.0019,0.0015,0.0015,1,1,1.7 +6890000,0.71,0.0013,-0.014,0.7,-0.0077,0.0039,-0.12,0,0,-4.9e+02,-0.0015,-0.0057,-7.6e-05,0,0,-9.4e-05,0.21,3.8e-05,0.43,6.6e-05,0.001,-0.00079,0,0,-4.9e+02,0.0013,0.0013,0.047,0.18,0.18,0.46,0.1,0.1,0.18,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0014,0.00069,0.0013,0.0017,0.0014,0.0013,1,1,1.8 +6990000,0.71,0.0013,-0.014,0.71,-0.0079,0.0041,-0.12,0,0,-4.9e+02,-0.0014,-0.0057,-7.8e-05,-8.6e-06,-0.00026,-0.00041,0.21,-2.9e-05,0.43,-0.00021,0.00062,-0.00035,0,0,-4.9e+02,0.0013,0.0013,0.045,0.19,0.19,0.36,0.11,0.11,0.16,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00046,0.0013,0.0017,0.0013,0.0013,1,1,1.8 +7090000,0.71,0.0012,-0.014,0.71,-0.0084,0.0027,-0.13,0,0,-4.9e+02,-0.0014,-0.0057,-7.9e-05,0.00025,-0.00058,-0.00078,0.21,-3.1e-05,0.43,-0.00035,0.00028,-0.00036,0,0,-4.9e+02,0.0013,0.0013,0.043,0.2,0.2,0.29,0.12,0.12,0.16,7.8e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00035,0.0013,0.0017,0.0013,0.0013,1,1,1.8 +7190000,0.71,0.0013,-0.014,0.71,-0.01,0.0026,-0.15,0,0,-4.9e+02,-0.0014,-0.0057,-7.9e-05,0.0002,-0.00051,-0.00057,0.21,-2.5e-05,0.43,-0.00033,0.00038,-0.00041,0,0,-4.9e+02,0.0013,0.0013,0.042,0.21,0.21,0.24,0.14,0.14,0.15,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00028,0.0013,0.0016,0.0013,0.0013,1,1,1.8 +7290000,0.71,0.0015,-0.014,0.71,-0.012,0.005,-0.15,0,0,-4.9e+02,-0.0015,-0.0057,-7.5e-05,-0.00016,-0.00022,-0.0012,0.21,-2.7e-05,0.43,-0.00031,0.0008,-0.00035,0,0,-4.9e+02,0.0013,0.0013,0.042,0.22,0.23,0.2,0.16,0.16,0.14,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.04,0.0013,0.00023,0.0013,0.0016,0.0013,0.0013,1,1,1.9 +7390000,0.71,0.0016,-0.014,0.71,-0.012,0.0077,-0.16,0,0,-4.9e+02,-0.0016,-0.0057,-7.3e-05,-0.00023,-5.2e-05,-0.0014,0.21,-2.4e-05,0.43,-0.0003,0.00089,-0.00029,0,0,-4.9e+02,0.0013,0.0013,0.041,0.24,0.25,0.18,0.18,0.18,0.13,7.7e-05,7.6e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.0002,0.0013,0.0016,0.0013,0.0013,1,1,1.9 +7490000,0.71,0.0015,-0.014,0.71,-0.013,0.0067,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.4e-05,-0.00012,-8.9e-05,-0.0022,0.21,-1.7e-05,0.43,-0.00028,0.00081,-0.0004,0,0,-4.9e+02,0.0013,0.0013,0.041,0.27,0.27,0.15,0.21,0.21,0.12,7.6e-05,7.6e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00018,0.0013,0.0016,0.0013,0.0013,1,1,1.9 +7590000,0.71,0.0016,-0.014,0.71,-0.014,0.011,-0.17,0,0,-4.9e+02,-0.0016,-0.0057,-7.1e-05,-0.00018,0.00019,-0.003,0.21,-1.7e-05,0.43,-0.00031,0.00089,-0.00024,0,0,-4.9e+02,0.0013,0.0013,0.041,0.29,0.29,0.14,0.25,0.25,0.12,7.6e-05,7.5e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00016,0.0013,0.0016,0.0013,0.0013,1,1,1.9 +7690000,0.71,0.0016,-0.014,0.71,-0.015,0.011,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.2e-05,-0.00018,0.00016,-0.0051,0.21,-1.4e-05,0.43,-0.00028,0.00086,-0.00031,0,0,-4.9e+02,0.0014,0.0013,0.04,0.32,0.32,0.13,0.29,0.29,0.11,7.5e-05,7.5e-05,2.4e-06,0.04,0.04,0.039,0.0013,0.00014,0.0013,0.0016,0.0013,0.0013,1,1,2 +7790000,0.71,0.0017,-0.014,0.71,-0.019,0.011,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.5e-05,-0.0003,3.6e-05,-0.0071,0.21,-1.3e-05,0.43,-0.00029,0.00081,-0.00036,0,0,-4.9e+02,0.0014,0.0013,0.04,0.36,0.36,0.12,0.34,0.34,0.11,7.4e-05,7.5e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00013,0.0013,0.0016,0.0013,0.0013,1,1,2 +7890000,0.71,0.0017,-0.014,0.71,-0.02,0.014,-0.16,0,0,-4.9e+02,-0.0015,-0.0057,-7.3e-05,-0.00031,0.00017,-0.0096,0.21,-1.2e-05,0.43,-0.0003,0.00081,-0.00028,0,0,-4.9e+02,0.0014,0.0014,0.04,0.39,0.39,0.11,0.4,0.4,0.1,7.3e-05,7.4e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00012,0.0013,0.0016,0.0013,0.0013,1,1,2 +7990000,0.71,0.0017,-0.014,0.71,-0.02,0.015,-0.16,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.0003,0.00025,-0.011,0.21,-1e-05,0.43,-0.0003,0.00088,-0.00036,0,0,-4.9e+02,0.0014,0.0014,0.04,0.43,0.43,0.1,0.47,0.47,0.099,7.1e-05,7.4e-05,2.4e-06,0.04,0.04,0.038,0.0013,0.00011,0.0013,0.0016,0.0013,0.0013,1,1,2 +8090000,0.71,0.0016,-0.014,0.71,-0.018,0.017,-0.17,0,0,-4.9e+02,-0.0015,-0.0056,-7e-05,-0.00023,0.00032,-0.011,0.21,-9.1e-06,0.43,-0.00028,0.00092,-0.00033,0,0,-4.9e+02,0.0014,0.0014,0.04,0.47,0.47,0.1,0.55,0.55,0.097,7e-05,7.3e-05,2.4e-06,0.04,0.04,0.037,0.0013,0.0001,0.0013,0.0016,0.0013,0.0013,1,1,2.1 +8190000,0.71,0.0017,-0.014,0.71,-0.024,0.02,-0.18,0,0,-4.9e+02,-0.0016,-0.0057,-7.1e-05,-0.00037,0.00033,-0.013,0.21,-9.4e-06,0.43,-0.00031,0.00087,-0.00034,0,0,-4.9e+02,0.0014,0.0014,0.04,0.52,0.51,0.099,0.64,0.64,0.094,6.8e-05,7.2e-05,2.4e-06,0.04,0.04,0.037,0.0013,9.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 +8290000,0.71,0.0017,-0.014,0.71,-0.0003,0.00012,-0.17,0,0,-4.9e+02,-0.0015,-0.0057,-7.5e-05,-0.00049,0.00033,-0.017,0.21,-7.5e-06,0.43,-0.00026,0.00081,-0.00033,0,0,-4.9e+02,0.0014,0.0014,0.039,25,25,0.097,1e+02,1e+02,0.091,6.6e-05,7.1e-05,2.4e-06,0.04,0.04,0.036,0.0013,8.8e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 +8390000,0.71,0.0016,-0.014,0.71,-0.0017,0.0016,-0.17,0,0,-4.9e+02,-0.0015,-0.0056,-7.2e-05,-0.00049,0.00033,-0.021,0.21,-6.8e-06,0.43,-0.00025,0.00085,-0.00029,0,0,-4.9e+02,0.0014,0.0014,0.039,25,25,0.097,1e+02,1e+02,0.091,6.5e-05,7e-05,2.4e-06,0.04,0.04,0.035,0.0013,8.3e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.1 +8490000,0.71,0.0017,-0.014,0.71,-0.0034,0.0035,-0.17,0,0,-4.9e+02,-0.0015,-0.0056,-7.3e-05,-0.00049,0.00033,-0.025,0.21,-6.7e-06,0.43,-0.00026,0.00082,-0.00026,0,0,-4.9e+02,0.0014,0.0014,0.039,25,25,0.096,50,50,0.089,6.3e-05,6.9e-05,2.4e-06,0.04,0.04,0.034,0.0013,7.8e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 +8590000,0.71,0.0021,-0.014,0.71,-0.0071,0.0078,-0.17,0,0,-4.9e+02,-0.0017,-0.0057,-7.1e-05,-0.00049,0.00033,-0.029,0.21,-9.7e-06,0.43,-0.00038,0.00078,-0.00026,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,51,51,0.088,6e-05,6.8e-05,2.4e-06,0.04,0.04,0.033,0.0013,7.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 +8690000,0.71,0.002,-0.014,0.71,0,0,-0.16,0,0,-4.9e+02,-0.0016,-0.0056,-6.8e-05,-0.00049,0.00033,-0.035,0.21,-8.1e-06,0.43,-0.00035,0.00086,-0.00028,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.096,1e+02,1e+02,0.088,5.8e-05,6.7e-05,2.4e-06,0.04,0.04,0.033,0.0013,7.1e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 +8790000,0.71,0.0019,-0.014,0.71,-0.0021,0.0025,-0.15,0,0,-4.9e+02,-0.0016,-0.0057,-7.1e-05,-0.00049,0.00033,-0.041,0.21,-7.2e-06,0.43,-0.00033,0.00081,-0.00027,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.087,5.6e-05,6.6e-05,2.4e-06,0.04,0.04,0.032,0.0013,6.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.2 +8890000,0.71,0.0019,-0.014,0.71,-0.0041,0.0034,-0.15,0,0,-4.9e+02,-0.0015,-0.0057,-7.4e-05,-0.00049,0.00033,-0.045,0.21,-6e-06,0.43,-0.0003,0.0008,-0.00032,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.086,5.4e-05,6.4e-05,2.4e-06,0.04,0.04,0.03,0.0013,6.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 +8990000,0.71,0.0018,-0.014,0.71,-0.0063,0.0034,-0.14,0,0,-4.9e+02,-0.0015,-0.0058,-7.8e-05,-0.00074,0.00034,-0.051,0.21,-4.9e-06,0.43,-0.00026,0.00073,-0.00033,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.096,1e+02,1e+02,0.087,5.2e-05,6.3e-05,2.4e-06,0.04,0.04,0.029,0.0013,6.2e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 +9090000,0.71,0.002,-0.014,0.71,-0.01,0.0045,-0.14,0,0,-4.9e+02,-0.0015,-0.0058,-7.8e-05,-0.00085,0.00044,-0.053,0.21,-5.3e-06,0.43,-0.00029,0.00069,-0.00033,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.095,1e+02,1e+02,0.086,4.9e-05,6.2e-05,2.4e-06,0.04,0.04,0.028,0.0013,5.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 +9190000,0.71,0.0018,-0.014,0.71,-0.0084,0.007,-0.14,0,0,-4.9e+02,-0.0015,-0.0056,-7.3e-05,-0.00074,0.0005,-0.057,0.21,-4.7e-06,0.43,-0.00027,0.00082,-0.00024,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.094,1.1e+02,1.1e+02,0.085,4.7e-05,6e-05,2.4e-06,0.04,0.04,0.027,0.0013,5.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.3 +9290000,0.71,0.0017,-0.014,0.71,-0.008,0.0073,-0.14,0,0,-4.9e+02,-0.0014,-0.0056,-7.4e-05,-0.00083,0.0005,-0.061,0.21,-3.7e-06,0.43,-0.00023,0.00083,-0.00023,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.093,1.1e+02,1.1e+02,0.085,4.4e-05,5.9e-05,2.4e-06,0.04,0.04,0.025,0.0013,5.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 +9390000,0.71,0.0015,-0.014,0.71,-0.008,0.0082,-0.14,0,0,-4.9e+02,-0.0013,-0.0056,-7.5e-05,-0.00093,0.00049,-0.065,0.21,-2.9e-06,0.43,-0.00019,0.00083,-0.00021,0,0,-4.9e+02,0.0013,0.0014,0.039,25,25,0.093,1.1e+02,1.1e+02,0.086,4.2e-05,5.7e-05,2.4e-06,0.04,0.04,0.024,0.0013,5.2e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 +9490000,0.71,0.0014,-0.014,0.71,-0.0052,0.01,-0.13,0,0,-4.9e+02,-0.0013,-0.0055,-7.2e-05,-0.00088,0.00052,-0.068,0.21,-2.4e-06,0.43,-0.00015,0.00091,-0.00012,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.091,1.2e+02,1.2e+02,0.085,4e-05,5.5e-05,2.4e-06,0.04,0.04,0.023,0.0013,5e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 +9590000,0.71,0.0016,-0.014,0.71,-0.0075,0.015,-0.13,0,0,-4.9e+02,-0.0014,-0.0055,-6.9e-05,-0.00094,0.00072,-0.072,0.21,-3.3e-06,0.43,-0.00021,0.00092,-0.00011,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.09,1.2e+02,1.2e+02,0.085,3.8e-05,5.4e-05,2.4e-06,0.04,0.04,0.021,0.0013,4.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.4 +9690000,0.71,0.0018,-0.014,0.71,-0.014,0.016,-0.12,0,0,-4.9e+02,-0.0014,-0.0056,-7.3e-05,-0.0012,0.00085,-0.077,0.21,-3.6e-06,0.43,-0.00024,0.0008,-0.00016,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.089,1.3e+02,1.3e+02,0.086,3.6e-05,5.2e-05,2.4e-06,0.04,0.04,0.02,0.0013,4.7e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 +9790000,0.71,0.0018,-0.014,0.71,-0.0099,0.02,-0.11,0,0,-4.9e+02,-0.0014,-0.0055,-7.1e-05,-0.0013,0.00093,-0.082,0.21,-3.4e-06,0.43,-0.00021,0.00085,-9e-05,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.087,1.3e+02,1.3e+02,0.085,3.4e-05,5.1e-05,2.4e-06,0.04,0.04,0.019,0.0013,4.6e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 +9890000,0.71,0.0019,-0.014,0.71,-0.013,0.022,-0.11,0,0,-4.9e+02,-0.0014,-0.0056,-7.1e-05,-0.0013,0.001,-0.085,0.21,-3.5e-06,0.43,-0.00023,0.00083,-9.7e-05,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.084,1.4e+02,1.4e+02,0.085,3.2e-05,4.9e-05,2.4e-06,0.04,0.04,0.018,0.0013,4.4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 +9990000,0.71,0.0019,-0.014,0.71,-0.017,0.021,-0.1,0,0,-4.9e+02,-0.0014,-0.0056,-7.3e-05,-0.0015,0.0011,-0.089,0.21,-3.3e-06,0.43,-0.00022,0.00078,-0.00013,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.083,1.4e+02,1.4e+02,0.086,3.1e-05,4.7e-05,2.4e-06,0.04,0.04,0.017,0.0013,4.3e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.5 +10090000,0.71,0.0021,-0.014,0.71,-0.018,0.025,-0.096,0,0,-4.9e+02,-0.0015,-0.0056,-7.1e-05,-0.0015,0.0012,-0.091,0.21,-3.7e-06,0.43,-0.00026,0.00079,-0.00012,0,0,-4.9e+02,0.0013,0.0013,0.039,25,25,0.08,1.5e+02,1.5e+02,0.085,2.9e-05,4.6e-05,2.4e-06,0.04,0.04,0.016,0.0013,4.2e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 +10190000,0.71,0.0021,-0.014,0.71,-0.029,0.022,-0.096,0,0,-4.9e+02,-0.0015,-0.0058,-7.7e-05,-0.0018,0.0012,-0.093,0.21,-3.6e-06,0.43,-0.00025,0.00065,-0.00015,0,0,-4.9e+02,0.0012,0.0012,0.039,25,25,0.078,1.6e+02,1.6e+02,0.084,2.7e-05,4.4e-05,2.4e-06,0.04,0.04,0.014,0.0013,4e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 +10290000,0.71,0.002,-0.013,0.71,-0.036,0.018,-0.084,0,0,-4.9e+02,-0.0015,-0.0059,-8.1e-05,-0.002,0.0014,-0.098,0.21,-3.3e-06,0.43,-0.00024,0.00057,-0.00017,0,0,-4.9e+02,0.0012,0.0012,0.039,25,25,0.076,1.6e+02,1.6e+02,0.085,2.6e-05,4.3e-05,2.3e-06,0.04,0.04,0.014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 +10390000,0.71,0.0019,-0.013,0.71,0.0087,-0.019,-0.067,0,0,-4.9e+02,-0.0014,-0.0059,-8.2e-05,-0.002,0.0014,-0.11,0.21,-2.8e-06,0.43,-0.00021,0.00059,-0.00013,0,0,-4.9e+02,0.0012,0.0012,0.039,0.25,0.25,0.065,0.5,0.5,0.077,2.4e-05,4.1e-05,2.3e-06,0.04,0.04,0.011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.6 +10490000,0.71,0.0018,-0.013,0.71,0.0068,-0.019,-0.056,0,0,-4.9e+02,-0.0014,-0.0059,-8.5e-05,-0.0022,0.0015,-0.11,0.21,-2.4e-06,0.43,-0.00018,0.00053,-0.00015,0,0,-4.9e+02,0.0012,0.0012,0.039,0.25,0.25,0.064,0.51,0.51,0.077,2.3e-05,3.9e-05,2.3e-06,0.04,0.04,0.011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 +10590000,0.71,0.0022,-0.013,0.71,0.0059,-0.0077,-0.044,0,0,-4.9e+02,-0.0015,-0.0059,-8.2e-05,-0.0024,0.0021,-0.11,0.21,-3.7e-06,0.43,-0.00027,0.00052,-0.00016,0,0,-4.9e+02,0.0012,0.0011,0.039,0.13,0.13,0.056,0.17,0.17,0.072,2.2e-05,3.7e-05,2.3e-06,0.039,0.039,0.0092,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 +10690000,0.71,0.0021,-0.013,0.71,0.0032,-0.0085,-0.04,0,0,-4.9e+02,-0.0015,-0.0059,-8.3e-05,-0.0025,0.0021,-0.11,0.21,-3.3e-06,0.43,-0.00025,0.00052,-0.00017,0,0,-4.9e+02,0.0012,0.0011,0.038,0.14,0.14,0.056,0.18,0.18,0.073,2.1e-05,3.6e-05,2.3e-06,0.039,0.039,0.0087,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 +10790000,0.71,0.002,-0.013,0.71,0.0034,-0.0059,-0.036,0,0,-4.9e+02,-0.0014,-0.0059,-8.3e-05,-0.0026,0.0025,-0.12,0.21,-3.2e-06,0.43,-0.00024,0.00055,-0.00016,0,0,-4.9e+02,0.0011,0.0011,0.038,0.093,0.094,0.05,0.11,0.11,0.068,1.9e-05,3.4e-05,2.3e-06,0.039,0.039,0.0076,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.7 +10890000,0.71,0.0019,-0.013,0.71,0.0022,-0.0059,-0.037,0,0,-4.9e+02,-0.0014,-0.0059,-8.3e-05,-0.0027,0.0024,-0.12,0.21,-2.9e-06,0.43,-0.00023,0.00057,-0.00015,0,0,-4.9e+02,0.0011,0.0011,0.038,0.1,0.1,0.049,0.11,0.11,0.068,1.8e-05,3.3e-05,2.3e-06,0.039,0.039,0.0072,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 +10990000,0.71,0.0017,-0.014,0.71,0.0069,-0.00092,-0.034,0,0,-4.9e+02,-0.0013,-0.0057,-8.2e-05,-0.0027,0.0034,-0.12,0.21,-2.4e-06,0.43,-0.0002,0.00071,-0.00011,0,0,-4.9e+02,0.0011,0.001,0.038,0.079,0.08,0.045,0.079,0.079,0.066,1.7e-05,3.1e-05,2.3e-06,0.037,0.037,0.0064,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 +11090000,0.71,0.0018,-0.014,0.71,0.0068,0.0026,-0.029,0,0,-4.9e+02,-0.0013,-0.0056,-7.8e-05,-0.0026,0.0032,-0.12,0.21,-2.6e-06,0.43,-0.00021,0.00077,-6.6e-05,0,0,-4.9e+02,0.0011,0.00099,0.038,0.09,0.091,0.044,0.085,0.085,0.066,1.6e-05,2.9e-05,2.3e-06,0.037,0.037,0.0061,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 +11190000,0.71,0.0017,-0.014,0.71,0.01,0.004,-0.031,0,0,-4.9e+02,-0.0013,-0.0057,-8e-05,-0.0025,0.0043,-0.12,0.21,-2.6e-06,0.43,-0.00022,0.00078,-8.4e-05,0,0,-4.9e+02,0.00097,0.00091,0.038,0.074,0.075,0.041,0.066,0.066,0.063,1.5e-05,2.7e-05,2.3e-06,0.036,0.036,0.0055,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.8 +11290000,0.71,0.0016,-0.014,0.71,0.0095,0.0026,-0.03,0,0,-4.9e+02,-0.0012,-0.0057,-8.5e-05,-0.0029,0.0046,-0.12,0.21,-2.2e-06,0.43,-0.0002,0.00072,-0.00011,0,0,-4.9e+02,0.00097,0.0009,0.038,0.085,0.087,0.041,0.072,0.072,0.064,1.4e-05,2.6e-05,2.3e-06,0.036,0.036,0.0052,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 +11390000,0.71,0.0016,-0.013,0.71,0.005,0.0016,-0.029,0,0,-4.9e+02,-0.0012,-0.0058,-8.8e-05,-0.0035,0.0044,-0.12,0.21,-2.2e-06,0.43,-0.00019,0.00065,-0.00016,0,0,-4.9e+02,0.00086,0.00081,0.038,0.071,0.073,0.037,0.058,0.058,0.061,1.3e-05,2.4e-05,2.3e-06,0.033,0.034,0.0047,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 +11490000,0.71,0.0015,-0.013,0.71,0.0012,-0.0011,-0.027,0,0,-4.9e+02,-0.0012,-0.006,-9.5e-05,-0.0041,0.0053,-0.12,0.21,-1.9e-06,0.43,-0.00016,0.00055,-0.00022,0,0,-4.9e+02,0.00085,0.0008,0.038,0.083,0.085,0.037,0.064,0.064,0.061,1.3e-05,2.3e-05,2.3e-06,0.033,0.034,0.0045,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 +11590000,0.71,0.0013,-0.013,0.71,-0.0019,-0.00077,-0.027,0,0,-4.9e+02,-0.0012,-0.006,-9.7e-05,-0.0047,0.0054,-0.12,0.21,-1.7e-06,0.43,-0.00014,0.00053,-0.00023,0,0,-4.9e+02,0.00075,0.00072,0.038,0.07,0.072,0.035,0.054,0.054,0.06,1.2e-05,2.1e-05,2.3e-06,0.031,0.032,0.0041,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,2.9 +11690000,0.71,0.0011,-0.013,0.71,-0.0034,-0.0018,-0.029,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0055,0.0055,-0.12,0.21,-1.2e-06,0.43,-8.2e-05,0.00052,-0.00026,0,0,-4.9e+02,0.00075,0.00071,0.038,0.081,0.084,0.034,0.06,0.06,0.06,1.1e-05,2e-05,2.3e-06,0.031,0.032,0.0039,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 +11790000,0.71,0.0011,-0.013,0.71,-0.0074,-0.0001,-0.027,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0072,0.0056,-0.12,0.21,-1.2e-06,0.43,-6.6e-05,0.00049,-0.00027,0,0,-4.9e+02,0.00064,0.00063,0.038,0.068,0.07,0.032,0.051,0.051,0.058,1e-05,1.8e-05,2.3e-06,0.028,0.029,0.0035,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 +11890000,0.71,0.00098,-0.013,0.71,-0.0084,-0.0029,-0.025,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0079,0.0062,-0.12,0.21,-1.1e-06,0.43,-3.5e-05,0.00046,-0.00032,0,0,-4.9e+02,0.00064,0.00062,0.038,0.079,0.082,0.031,0.058,0.058,0.058,9.9e-06,1.8e-05,2.3e-06,0.028,0.029,0.0034,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 +11990000,0.71,0.0013,-0.013,0.71,-0.012,0.0019,-0.027,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0074,0.0067,-0.12,0.21,-2e-06,0.43,-0.00011,0.00047,-0.00032,0,0,-4.9e+02,0.00056,0.00055,0.037,0.066,0.068,0.03,0.049,0.049,0.057,9.2e-06,1.6e-05,2.3e-06,0.026,0.027,0.0031,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3 +12090000,0.71,0.0014,-0.013,0.71,-0.013,0.0051,-0.03,0,0,-4.9e+02,-0.0012,-0.006,-9.7e-05,-0.0063,0.0059,-0.12,0.21,-2.2e-06,0.43,-0.00014,0.00052,-0.00027,0,0,-4.9e+02,0.00056,0.00054,0.037,0.076,0.079,0.029,0.056,0.057,0.057,8.8e-06,1.6e-05,2.3e-06,0.026,0.027,0.003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 +12190000,0.71,0.0012,-0.013,0.71,-0.0067,0.0046,-0.023,0,0,-4.9e+02,-0.0011,-0.0059,-9.8e-05,-0.0061,0.0061,-0.13,0.21,-1.5e-06,0.43,-8.5e-05,0.00059,-0.00026,0,0,-4.9e+02,0.00048,0.00048,0.037,0.063,0.065,0.028,0.048,0.048,0.055,8.2e-06,1.4e-05,2.3e-06,0.023,0.026,0.0027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 +12290000,0.71,0.001,-0.013,0.71,-0.008,0.0051,-0.02,0,0,-4.9e+02,-0.001,-0.0059,-9.8e-05,-0.0067,0.0057,-0.13,0.21,-1.2e-06,0.43,-6e-05,0.0006,-0.00025,0,0,-4.9e+02,0.00048,0.00048,0.037,0.073,0.075,0.027,0.056,0.056,0.056,7.9e-06,1.4e-05,2.3e-06,0.023,0.025,0.0026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 +12390000,0.71,0.001,-0.013,0.71,-0.0053,0.0038,-0.016,0,0,-4.9e+02,-0.001,-0.0059,-0.0001,-0.0053,0.0074,-0.13,0.21,-1.6e-06,0.43,-0.0001,0.0006,-0.00024,0,0,-4.9e+02,0.00042,0.00043,0.037,0.06,0.062,0.026,0.048,0.048,0.055,7.5e-06,1.3e-05,2.3e-06,0.021,0.024,0.0024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.1 +12490000,0.71,0.00094,-0.013,0.71,-0.0069,0.0034,-0.016,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0058,0.0086,-0.13,0.21,-1.8e-06,0.43,-0.00013,0.00054,-0.00024,0,0,-4.9e+02,0.00042,0.00042,0.037,0.069,0.071,0.025,0.055,0.055,0.055,7.2e-06,1.3e-05,2.3e-06,0.021,0.024,0.0023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 +12590000,0.71,0.0011,-0.013,0.71,-0.014,0.0042,-0.019,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.005,0.0078,-0.13,0.21,-2.1e-06,0.43,-0.00017,0.00051,-0.00024,0,0,-4.9e+02,0.00037,0.00038,0.037,0.057,0.059,0.024,0.047,0.047,0.054,6.8e-06,1.2e-05,2.3e-06,0.019,0.022,0.0021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 +12690000,0.71,0.0014,-0.013,0.71,-0.017,0.0051,-0.021,0,0,-4.9e+02,-0.0012,-0.006,-0.0001,-0.0032,0.0092,-0.13,0.21,-3.1e-06,0.43,-0.00024,0.0005,-0.00025,0,0,-4.9e+02,0.00037,0.00038,0.037,0.065,0.067,0.024,0.055,0.055,0.054,6.5e-06,1.2e-05,2.3e-06,0.019,0.022,0.0021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 +12790000,0.71,0.0012,-0.013,0.71,-0.02,0.0031,-0.022,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0047,0.008,-0.13,0.21,-2.4e-06,0.43,-0.00018,0.00048,-0.00026,0,0,-4.9e+02,0.00033,0.00034,0.037,0.054,0.056,0.023,0.047,0.047,0.053,6.2e-06,1.1e-05,2.3e-06,0.018,0.021,0.0019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.2 +12890000,0.71,0.0011,-0.013,0.71,-0.019,0.0019,-0.019,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.006,0.0076,-0.13,0.21,-2e-06,0.43,-0.00015,0.00047,-0.00025,0,0,-4.9e+02,0.00033,0.00034,0.037,0.061,0.063,0.023,0.054,0.055,0.053,6e-06,1.1e-05,2.3e-06,0.018,0.021,0.0018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 +12990000,0.71,0.001,-0.013,0.71,-0.0089,0.0022,-0.018,0,0,-4.9e+02,-0.0011,-0.006,-0.0001,-0.0035,0.0079,-0.13,0.21,-1.8e-06,0.43,-0.00016,0.00058,-0.00019,0,0,-4.9e+02,0.0003,0.00031,0.037,0.051,0.053,0.021,0.047,0.047,0.052,5.7e-06,1e-05,2.3e-06,0.016,0.02,0.0017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 +13090000,0.71,0.00094,-0.013,0.71,-0.0096,0.00018,-0.016,0,0,-4.9e+02,-0.0011,-0.006,-0.00011,-0.0047,0.0095,-0.13,0.21,-2.2e-06,0.43,-0.00017,0.00052,-0.00023,0,0,-4.9e+02,0.0003,0.00031,0.037,0.057,0.059,0.021,0.054,0.054,0.052,5.5e-06,9.7e-06,2.3e-06,0.016,0.02,0.0016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 +13190000,0.71,0.00094,-0.013,0.71,-0.0022,0.0011,-0.012,0,0,-4.9e+02,-0.0011,-0.006,-0.00011,-0.0028,0.011,-0.13,0.21,-2.6e-06,0.43,-0.00021,0.00057,-0.0002,0,0,-4.9e+02,0.00027,0.00029,0.037,0.048,0.049,0.02,0.047,0.047,0.051,5.2e-06,9.2e-06,2.3e-06,0.015,0.019,0.0015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.3 +13290000,0.71,0.00078,-0.013,0.71,-0.00066,0.0018,-0.007,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0043,0.0094,-0.13,0.21,-1.6e-06,0.43,-0.00015,0.00058,-0.00019,0,0,-4.9e+02,0.00027,0.00028,0.037,0.053,0.055,0.02,0.054,0.054,0.051,5.1e-06,8.9e-06,2.3e-06,0.015,0.018,0.0015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 +13390000,0.71,0.00069,-0.013,0.71,0.00036,0.0025,-0.0026,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0037,0.0086,-0.13,0.21,-1.4e-06,0.43,-0.00013,0.00063,-0.00018,0,0,-4.9e+02,0.00025,0.00027,0.037,0.045,0.046,0.019,0.047,0.047,0.05,4.9e-06,8.5e-06,2.3e-06,0.014,0.018,0.0014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 +13490000,0.71,0.0007,-0.013,0.71,0.00035,0.0026,0.00045,0,0,-4.9e+02,-0.001,-0.0059,-0.0001,-0.0037,0.0078,-0.13,0.21,-1.1e-06,0.43,-0.00012,0.00064,-0.00016,0,0,-4.9e+02,0.00025,0.00026,0.037,0.05,0.052,0.019,0.054,0.054,0.05,4.7e-06,8.3e-06,2.3e-06,0.014,0.018,0.0013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 +13590000,0.71,0.00071,-0.013,0.71,0.00011,0.0029,-0.00092,0,0,-4.9e+02,-0.001,-0.006,-0.0001,-0.0035,0.009,-0.13,0.21,-1.5e-06,0.43,-0.00015,0.00063,-0.00018,0,0,-4.9e+02,0.00023,0.00025,0.037,0.042,0.044,0.018,0.046,0.047,0.05,4.5e-06,7.9e-06,2.3e-06,0.013,0.017,0.0013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.4 +13690000,0.71,0.00069,-0.013,0.71,0.0011,0.0054,-0.0036,0,0,-4.9e+02,-0.001,-0.0059,-0.0001,-0.0029,0.0078,-0.13,0.21,-1.1e-06,0.43,-0.00013,0.00065,-0.00015,0,0,-4.9e+02,0.00023,0.00025,0.037,0.047,0.048,0.018,0.053,0.054,0.049,4.4e-06,7.7e-06,2.3e-06,0.013,0.017,0.0012,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 +13790000,0.71,0.00073,-0.013,0.71,0.00075,0.0022,-0.0047,0,0,-4.9e+02,-0.001,-0.006,-9.9e-05,-0.0014,0.0085,-0.13,0.21,-1.5e-06,0.43,-0.00017,0.00066,-0.00014,0,0,-4.9e+02,0.00022,0.00023,0.037,0.04,0.041,0.017,0.046,0.046,0.048,4.2e-06,7.3e-06,2.3e-06,0.013,0.016,0.0011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 +13890000,0.71,0.00057,-0.013,0.71,0.0026,0.0022,-0.0073,0,0,-4.9e+02,-0.001,-0.0059,-9.9e-05,-0.0028,0.0074,-0.13,0.21,-8.2e-07,0.43,-0.00012,0.00066,-0.00014,0,0,-4.9e+02,0.00022,0.00023,0.037,0.044,0.045,0.017,0.053,0.053,0.049,4.1e-06,7.2e-06,2.3e-06,0.012,0.016,0.0011,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 +13990000,0.71,0.00064,-0.013,0.71,0.002,0.00051,-0.0067,0,0,-4.9e+02,-0.001,-0.0059,-9.8e-05,-0.0014,0.0078,-0.13,0.21,-1.1e-06,0.43,-0.00016,0.00066,-0.00012,0,0,-4.9e+02,0.00021,0.00022,0.037,0.037,0.039,0.016,0.046,0.046,0.048,3.9e-06,6.9e-06,2.3e-06,0.012,0.015,0.001,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.5 +14090000,0.71,0.00071,-0.013,0.71,0.0016,0.0019,-0.0065,0,0,-4.9e+02,-0.0011,-0.0059,-9.4e-05,8.8e-05,0.0068,-0.13,0.21,-8.9e-07,0.43,-0.00016,0.00069,-8.3e-05,0,0,-4.9e+02,0.00021,0.00022,0.037,0.041,0.043,0.016,0.053,0.053,0.048,3.8e-06,6.7e-06,2.3e-06,0.012,0.015,0.00099,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 +14190000,0.71,0.00066,-0.014,0.71,0.0046,0.0018,-0.0079,0,0,-4.9e+02,-0.0011,-0.0059,-9.3e-05,0.00058,0.0065,-0.13,0.21,-6.6e-07,0.43,-0.00015,0.00072,-6.5e-05,0,0,-4.9e+02,0.0002,0.00021,0.037,0.035,0.037,0.015,0.046,0.046,0.047,3.6e-06,6.4e-06,2.3e-06,0.011,0.015,0.00094,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 +14290000,0.71,0.00074,-0.014,0.71,0.0048,0.0031,-0.0063,0,0,-4.9e+02,-0.0011,-0.0059,-9.2e-05,0.0015,0.0064,-0.13,0.21,-7.8e-07,0.43,-0.00016,0.00072,-4.7e-05,0,0,-4.9e+02,0.0002,0.00021,0.037,0.038,0.04,0.015,0.052,0.052,0.047,3.5e-06,6.2e-06,2.3e-06,0.011,0.014,0.00091,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 +14390000,0.71,0.00062,-0.014,0.71,0.0073,0.0048,-0.0082,0,0,-4.9e+02,-0.001,-0.0058,-8.9e-05,0.0012,0.0049,-0.13,0.21,7.5e-08,0.43,-0.00012,0.00075,-3.1e-05,0,0,-4.9e+02,0.00019,0.0002,0.037,0.033,0.035,0.015,0.046,0.046,0.046,3.4e-06,6e-06,2.3e-06,0.011,0.014,0.00086,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.6 +14490000,0.71,0.00051,-0.014,0.71,0.0082,0.0063,-0.0099,0,0,-4.9e+02,-0.001,-0.0058,-8.9e-05,-0.00012,0.0044,-0.13,0.21,5.8e-07,0.43,-0.0001,0.00071,-3.1e-05,0,0,-4.9e+02,0.00019,0.0002,0.037,0.036,0.038,0.014,0.052,0.052,0.046,3.3e-06,5.8e-06,2.3e-06,0.011,0.014,0.00083,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 +14590000,0.71,0.0004,-0.013,0.71,0.0063,0.0048,-0.011,0,0,-4.9e+02,-0.001,-0.0059,-8.9e-05,-0.00098,0.0041,-0.13,0.21,6.7e-07,0.43,-9.4e-05,0.00068,-4.4e-05,0,0,-4.9e+02,0.00018,0.00019,0.037,0.031,0.033,0.014,0.045,0.045,0.046,3.2e-06,5.6e-06,2.3e-06,0.01,0.014,0.00079,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 +14690000,0.71,0.00035,-0.013,0.71,0.0081,0.0029,-0.0077,0,0,-4.9e+02,-0.001,-0.0058,-8.7e-05,-0.00089,0.0032,-0.13,0.21,1.1e-06,0.43,-7.7e-05,0.0007,-2.9e-05,0,0,-4.9e+02,0.00018,0.00019,0.037,0.034,0.036,0.014,0.051,0.052,0.046,3.1e-06,5.5e-06,2.3e-06,0.01,0.013,0.00077,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 +14790000,0.71,0.00034,-0.013,0.71,0.0057,0.0014,-0.0059,0,0,-4.9e+02,-0.001,-0.0058,-8.7e-05,-0.001,0.003,-0.13,0.21,1e-06,0.43,-8.2e-05,0.00067,-3e-05,0,0,-4.9e+02,0.00017,0.00018,0.037,0.03,0.031,0.013,0.045,0.045,0.045,3e-06,5.3e-06,2.3e-06,0.0098,0.013,0.00073,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.7 +14890000,0.71,0.0003,-0.013,0.71,0.008,0.0031,-0.008,0,0,-4.9e+02,-0.00099,-0.0058,-8.6e-05,-0.0013,0.0024,-0.13,0.21,1.3e-06,0.43,-6.7e-05,0.00068,-2.7e-05,0,0,-4.9e+02,0.00018,0.00018,0.037,0.032,0.034,0.013,0.051,0.051,0.045,2.9e-06,5.1e-06,2.3e-06,0.0097,0.013,0.00071,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 +14990000,0.71,0.00025,-0.013,0.71,0.007,0.0021,-0.006,0,0,-4.9e+02,-0.00099,-0.0059,-8.7e-05,-0.0017,0.0029,-0.13,0.21,1.1e-06,0.43,-7.7e-05,0.00066,-3.9e-05,0,0,-4.9e+02,0.00017,0.00017,0.037,0.028,0.03,0.013,0.045,0.045,0.045,2.8e-06,4.9e-06,2.3e-06,0.0094,0.012,0.00067,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 +15090000,0.71,0.00018,-0.013,0.71,0.0078,0.0021,-0.0072,0,0,-4.9e+02,-0.00099,-0.0059,-8.8e-05,-0.0018,0.0033,-0.13,0.21,9.8e-07,0.43,-8.9e-05,0.00064,-4e-05,0,0,-4.9e+02,0.00017,0.00017,0.037,0.03,0.032,0.013,0.05,0.051,0.044,2.7e-06,4.8e-06,2.3e-06,0.0093,0.012,0.00065,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 +15190000,0.71,0.00015,-0.013,0.71,0.0075,0.0027,-0.0063,0,0,-4.9e+02,-0.00098,-0.0059,-8.9e-05,-0.0024,0.0035,-0.13,0.21,9.8e-07,0.43,-9.8e-05,0.00061,-4.7e-05,0,0,-4.9e+02,0.00016,0.00017,0.037,0.027,0.028,0.012,0.044,0.045,0.044,2.6e-06,4.6e-06,2.3e-06,0.0091,0.012,0.00063,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.8 +15290000,0.71,0.00017,-0.013,0.71,0.008,0.0037,-0.005,0,0,-4.9e+02,-0.001,-0.0059,-8.7e-05,-0.0015,0.0033,-0.13,0.21,1e-06,0.43,-0.00012,0.00061,-2.2e-05,0,0,-4.9e+02,0.00016,0.00017,0.037,0.029,0.031,0.012,0.05,0.05,0.044,2.6e-06,4.5e-06,2.3e-06,0.0089,0.012,0.00061,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 +15390000,0.71,0.00018,-0.013,0.71,0.0073,0.005,-0.004,0,0,-4.9e+02,-0.001,-0.0058,-8.3e-05,-0.0006,0.0018,-0.13,0.21,1.4e-06,0.43,-0.0001,0.00063,1.5e-06,0,0,-4.9e+02,0.00016,0.00016,0.037,0.025,0.027,0.012,0.044,0.044,0.043,2.5e-06,4.4e-06,2.3e-06,0.0087,0.012,0.00058,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 +15490000,0.71,0.0002,-0.013,0.71,0.0088,0.0041,-0.0032,0,0,-4.9e+02,-0.001,-0.0059,-8.6e-05,-0.00099,0.0031,-0.13,0.21,9.4e-07,0.43,-0.00012,0.00061,-1.7e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.027,0.029,0.012,0.049,0.05,0.044,2.4e-06,4.3e-06,2.3e-06,0.0086,0.011,0.00056,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 +15590000,0.71,0.00016,-0.013,0.71,0.0074,0.0031,-0.0024,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.0016,0.0038,-0.13,0.21,5.9e-07,0.43,-0.00012,0.00059,-4.2e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.024,0.026,0.011,0.044,0.044,0.043,2.3e-06,4.1e-06,2.3e-06,0.0084,0.011,0.00054,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,3.9 +15690000,0.71,0.00021,-0.013,0.71,0.0077,0.0032,-0.0025,0,0,-4.9e+02,-0.001,-0.0059,-8.9e-05,-0.0011,0.0042,-0.13,0.21,2.8e-07,0.43,-0.00013,0.0006,-4.5e-05,0,0,-4.9e+02,0.00016,0.00016,0.037,0.026,0.028,0.011,0.049,0.049,0.043,2.3e-06,4e-06,2.3e-06,0.0083,0.011,0.00052,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 +15790000,0.71,0.00017,-0.013,0.71,0.0083,0.0017,-0.0043,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.0013,0.0044,-0.13,0.21,1.7e-07,0.43,-0.00014,0.00059,-4.9e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.023,0.025,0.011,0.043,0.044,0.042,2.2e-06,3.9e-06,2.3e-06,0.0082,0.011,0.0005,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 +15890000,0.71,0.00018,-0.013,0.71,0.009,0.0016,-0.0029,0,0,-4.9e+02,-0.001,-0.0059,-8.8e-05,-0.00059,0.0047,-0.13,0.21,-3.2e-08,0.43,-0.00015,0.00059,-4e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.025,0.027,0.011,0.048,0.049,0.042,2.2e-06,3.8e-06,2.3e-06,0.0081,0.011,0.00049,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 +15990000,0.71,0.00016,-0.013,0.71,0.0088,0.0017,-0.00057,0,0,-4.9e+02,-0.0011,-0.0059,-8.3e-05,8.5e-05,0.0039,-0.13,0.21,7.9e-08,0.43,-0.00016,0.0006,-2.2e-05,0,0,-4.9e+02,0.00015,0.00015,0.037,0.022,0.024,0.011,0.043,0.043,0.042,2.1e-06,3.6e-06,2.3e-06,0.0079,0.01,0.00047,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4 +16090000,0.71,0.00019,-0.013,0.71,0.011,0.0034,0.0016,0,0,-4.9e+02,-0.0011,-0.0059,-7.9e-05,0.00089,0.0026,-0.13,0.21,3.6e-07,0.43,-0.00014,0.00064,-5.8e-06,0,0,-4.9e+02,0.00015,0.00015,0.037,0.024,0.026,0.01,0.048,0.049,0.042,2e-06,3.6e-06,2.3e-06,0.0078,0.01,0.00046,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 +16190000,0.71,0.00024,-0.013,0.71,0.01,0.0036,0.0018,0,0,-4.9e+02,-0.0011,-0.0059,-7.8e-05,0.0017,0.0028,-0.13,0.21,4.5e-08,0.43,-0.00015,0.00065,4.5e-08,0,0,-4.9e+02,0.00015,0.00014,0.037,0.021,0.023,0.01,0.043,0.043,0.041,2e-06,3.4e-06,2.3e-06,0.0077,0.01,0.00044,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 +16290000,0.71,0.00026,-0.014,0.71,0.013,0.0046,0.001,0,0,-4.9e+02,-0.0011,-0.0058,-7.4e-05,0.002,0.0015,-0.13,0.21,5.2e-07,0.43,-0.00013,0.00066,1.5e-05,0,0,-4.9e+02,0.00015,0.00014,0.037,0.023,0.025,0.01,0.048,0.048,0.041,1.9e-06,3.4e-06,2.3e-06,0.0076,0.01,0.00043,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 +16390000,0.71,0.00031,-0.014,0.71,0.01,0.0031,0.00099,0,0,-4.9e+02,-0.0011,-0.0058,-7.5e-05,0.0031,0.0026,-0.13,0.21,-2.7e-07,0.43,-0.00015,0.00066,1.9e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.02,0.023,0.0098,0.042,0.043,0.041,1.9e-06,3.2e-06,2.3e-06,0.0075,0.0098,0.00042,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.1 +16490000,0.71,0.0004,-0.014,0.71,0.0091,0.0044,-0.00091,0,0,-4.9e+02,-0.0011,-0.0058,-7.4e-05,0.004,0.0028,-0.13,0.21,-4.9e-07,0.43,-0.00016,0.00065,3.3e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.022,0.024,0.0098,0.047,0.048,0.041,1.8e-06,3.2e-06,2.3e-06,0.0074,0.0097,0.00041,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 +16590000,0.71,0.00051,-0.013,0.71,0.007,0.0053,-0.0021,0,0,-4.9e+02,-0.0011,-0.0058,-7.5e-05,0.0042,0.0025,-0.13,0.21,-5.2e-07,0.43,-0.00015,0.00065,2.9e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.02,0.022,0.0095,0.042,0.042,0.04,1.8e-06,3.1e-06,2.3e-06,0.0073,0.0095,0.00039,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 +16690000,0.71,0.00047,-0.013,0.71,0.0079,0.0056,-0.00027,0,0,-4.9e+02,-0.0011,-0.0059,-7.8e-05,0.0036,0.0031,-0.13,0.21,-6.8e-07,0.43,-0.00015,0.00064,1.8e-05,0,0,-4.9e+02,0.00014,0.00014,0.037,0.021,0.024,0.0094,0.047,0.047,0.04,1.7e-06,3e-06,2.3e-06,0.0072,0.0094,0.00038,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 +16790000,0.71,0.00047,-0.013,0.71,0.006,0.0063,-3.5e-05,0,0,-4.9e+02,-0.0011,-0.0058,-7.9e-05,0.0034,0.0027,-0.13,0.21,-6.5e-07,0.43,-0.00013,0.00065,5.6e-06,0,0,-4.9e+02,0.00014,0.00013,0.037,0.019,0.021,0.0093,0.042,0.042,0.04,1.7e-06,2.9e-06,2.3e-06,0.0071,0.0093,0.00037,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.2 +16890000,0.71,0.00052,-0.013,0.71,0.0057,0.0072,0.0013,0,0,-4.9e+02,-0.0012,-0.0059,-8.1e-05,0.0038,0.0033,-0.13,0.21,-9.3e-07,0.43,-0.00015,0.00064,1e-05,0,0,-4.9e+02,0.00014,0.00013,0.037,0.02,0.023,0.0092,0.046,0.047,0.04,1.6e-06,2.9e-06,2.3e-06,0.007,0.0091,0.00036,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 +16990000,0.71,0.00049,-0.013,0.71,0.0057,0.0049,0.0019,0,0,-4.9e+02,-0.0012,-0.0059,-8.1e-05,0.0037,0.0044,-0.13,0.21,-1.4e-06,0.43,-0.00016,0.00063,-9.4e-08,0,0,-4.9e+02,0.00014,0.00013,0.037,0.018,0.021,0.009,0.041,0.042,0.039,1.6e-06,2.7e-06,2.3e-06,0.0069,0.009,0.00035,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 +17090000,0.71,0.00054,-0.013,0.71,0.006,0.0064,0.0024,0,0,-4.9e+02,-0.0012,-0.0059,-8e-05,0.0047,0.0047,-0.13,0.21,-1.7e-06,0.43,-0.00018,0.00063,1.2e-05,0,0,-4.9e+02,0.00014,0.00013,0.037,0.02,0.022,0.0089,0.046,0.047,0.039,1.6e-06,2.7e-06,2.3e-06,0.0068,0.0089,0.00034,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 +17190000,0.71,0.00059,-0.013,0.71,0.0061,0.0074,0.0022,0,0,-4.9e+02,-0.0012,-0.0059,-7.6e-05,0.0055,0.0046,-0.13,0.21,-2e-06,0.43,-0.00018,0.00064,1.4e-05,0,0,-4.9e+02,0.00013,0.00013,0.037,0.018,0.02,0.0087,0.041,0.042,0.039,1.5e-06,2.6e-06,2.3e-06,0.0068,0.0087,0.00033,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.3 +17290000,0.71,0.00062,-0.013,0.71,0.0079,0.0081,0.005,0,0,-4.9e+02,-0.0012,-0.0059,-7.8e-05,0.0058,0.0055,-0.13,0.21,-2.4e-06,0.43,-0.0002,0.00063,1.7e-05,0,0,-4.9e+02,0.00013,0.00013,0.037,0.019,0.022,0.0087,0.045,0.046,0.039,1.5e-06,2.6e-06,2.3e-06,0.0067,0.0086,0.00033,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 +17390000,0.71,0.00067,-0.013,0.71,0.0077,0.0085,0.0058,0,0,-4.9e+02,-0.0012,-0.0059,-7.2e-05,0.0066,0.0053,-0.13,0.21,-2.5e-06,0.43,-0.00021,0.00063,3.5e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.017,0.02,0.0085,0.041,0.041,0.039,1.4e-06,2.5e-06,2.2e-06,0.0066,0.0085,0.00032,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 +17490000,0.71,0.00062,-0.013,0.71,0.0094,0.0086,0.0072,0,0,-4.9e+02,-0.0012,-0.0059,-7.2e-05,0.0061,0.005,-0.13,0.21,-2.3e-06,0.43,-0.00021,0.00063,3e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.019,0.021,0.0085,0.045,0.046,0.039,1.4e-06,2.4e-06,2.2e-06,0.0065,0.0084,0.00031,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 +17590000,0.71,0.00058,-0.013,0.71,0.01,0.0079,0.011,0,0,-4.9e+02,-0.0012,-0.0059,-6.9e-05,0.0065,0.0052,-0.13,0.21,-2.6e-06,0.43,-0.00021,0.00063,2.7e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.017,0.019,0.0083,0.04,0.041,0.038,1.4e-06,2.3e-06,2.2e-06,0.0065,0.0083,0.0003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.4 +17690000,0.71,0.00056,-0.013,0.71,0.011,0.0094,0.01,0,0,-4.9e+02,-0.0012,-0.0059,-6.8e-05,0.0066,0.005,-0.13,0.21,-2.5e-06,0.43,-0.00022,0.00063,3.5e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.018,0.021,0.0082,0.045,0.046,0.038,1.3e-06,2.3e-06,2.2e-06,0.0064,0.0082,0.0003,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 +17790000,0.71,0.00055,-0.013,0.71,0.012,0.01,0.0095,0,0,-4.9e+02,-0.0012,-0.0059,-5.9e-05,0.0075,0.0039,-0.13,0.21,-2.5e-06,0.43,-0.00021,0.00066,4.5e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.016,0.019,0.0081,0.04,0.041,0.038,1.3e-06,2.2e-06,2.2e-06,0.0063,0.0081,0.00029,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 +17890000,0.71,0.00054,-0.013,0.71,0.015,0.011,0.0098,0,0,-4.9e+02,-0.0012,-0.0059,-5.6e-05,0.0073,0.0032,-0.13,0.21,-2.1e-06,0.43,-0.00021,0.00066,5e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.018,0.021,0.008,0.044,0.045,0.038,1.3e-06,2.2e-06,2.2e-06,0.0063,0.008,0.00028,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 +17990000,0.71,0.00047,-0.013,0.71,0.016,0.0084,0.011,0,0,-4.9e+02,-0.0012,-0.0059,-5.6e-05,0.0071,0.0035,-0.13,0.21,-2.3e-06,0.43,-0.00022,0.00066,4.6e-05,0,0,-4.9e+02,0.00012,0.00012,0.037,0.016,0.019,0.0079,0.04,0.041,0.037,1.2e-06,2.1e-06,2.2e-06,0.0062,0.0078,0.00027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.5 +18090000,0.71,0.00046,-0.013,0.71,0.017,0.0076,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-6.1e-05,0.0066,0.0045,-0.13,0.21,-2.4e-06,0.43,-0.00023,0.00064,4.2e-05,0,0,-4.9e+02,0.00013,0.00012,0.037,0.017,0.02,0.0079,0.044,0.045,0.038,1.2e-06,2.1e-06,2.2e-06,0.0061,0.0078,0.00027,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 +18190000,0.71,0.00042,-0.013,0.71,0.018,0.0086,0.013,0,0,-4.9e+02,-0.0012,-0.0059,-5.7e-05,0.0068,0.0041,-0.13,0.21,-2.5e-06,0.43,-0.00023,0.00064,4.2e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.018,0.0077,0.04,0.041,0.037,1.2e-06,2e-06,2.2e-06,0.0061,0.0076,0.00026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 +18290000,0.71,0.00033,-0.013,0.71,0.019,0.0081,0.014,0,0,-4.9e+02,-0.0012,-0.0059,-5.9e-05,0.0064,0.0044,-0.13,0.21,-2.5e-06,0.43,-0.00023,0.00063,3.7e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.017,0.02,0.0077,0.044,0.045,0.037,1.2e-06,2e-06,2.2e-06,0.006,0.0076,0.00026,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 +18390000,0.71,0.0003,-0.013,0.71,0.021,0.01,0.015,0,0,-4.9e+02,-0.0012,-0.0059,-5.3e-05,0.0062,0.0036,-0.13,0.21,-2.3e-06,0.43,-0.00022,0.00064,3.8e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.015,0.018,0.0075,0.039,0.04,0.037,1.1e-06,1.9e-06,2.2e-06,0.006,0.0075,0.00025,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.6 +18490000,0.71,0.00037,-0.013,0.71,0.021,0.011,0.014,0,0,-4.9e+02,-0.0012,-0.0059,-5.2e-05,0.0067,0.0037,-0.13,0.21,-2.4e-06,0.43,-0.00022,0.00065,4.2e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.02,0.0075,0.043,0.045,0.037,1.1e-06,1.9e-06,2.2e-06,0.0059,0.0074,0.00025,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 +18590000,0.71,0.00038,-0.013,0.71,0.021,0.012,0.013,0,0,-4.9e+02,-0.0012,-0.0059,-4.4e-05,0.0075,0.0031,-0.13,0.21,-2.5e-06,0.43,-0.00022,0.00067,4.7e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.015,0.018,0.0074,0.039,0.04,0.037,1.1e-06,1.8e-06,2.2e-06,0.0058,0.0073,0.00024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 +18690000,0.71,0.00029,-0.013,0.71,0.022,0.012,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-4.6e-05,0.0068,0.0032,-0.13,0.21,-2.4e-06,0.43,-0.00022,0.00066,4.1e-05,0,0,-4.9e+02,0.00012,0.00011,0.037,0.016,0.019,0.0074,0.043,0.044,0.036,1.1e-06,1.8e-06,2.2e-06,0.0058,0.0072,0.00024,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 +18790000,0.71,0.00031,-0.013,0.71,0.021,0.011,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-4.5e-05,0.0071,0.0037,-0.13,0.21,-2.7e-06,0.43,-0.00022,0.00065,3.8e-05,0,0,-4.9e+02,0.00012,0.00011,0.036,0.015,0.018,0.0073,0.039,0.04,0.036,1e-06,1.7e-06,2.2e-06,0.0057,0.0071,0.00023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.7 +18890000,0.71,0.0004,-0.013,0.71,0.021,0.013,0.012,0,0,-4.9e+02,-0.0012,-0.0059,-3.9e-05,0.008,0.0032,-0.13,0.21,-2.7e-06,0.43,-0.00023,0.00067,5.1e-05,0,0,-4.9e+02,0.00012,0.00011,0.036,0.016,0.019,0.0072,0.043,0.044,0.036,1e-06,1.7e-06,2.2e-06,0.0057,0.0071,0.00023,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 +18990000,0.71,0.00045,-0.013,0.71,0.021,0.014,0.011,0,0,-4.9e+02,-0.0013,-0.0059,-3.3e-05,0.0086,0.0033,-0.13,0.21,-3e-06,0.43,-0.00024,0.00068,5.2e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.015,0.017,0.0071,0.039,0.04,0.036,9.8e-07,1.6e-06,2.2e-06,0.0056,0.0069,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 +19090000,0.71,0.0005,-0.013,0.71,0.021,0.015,0.013,0,0,-4.9e+02,-0.0013,-0.0059,-3.3e-05,0.0093,0.0036,-0.13,0.21,-3.3e-06,0.43,-0.00025,0.00068,5.6e-05,0,0,-4.9e+02,0.00012,0.0001,0.036,0.016,0.019,0.0071,0.042,0.044,0.036,9.6e-07,1.6e-06,2.2e-06,0.0056,0.0069,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 +19190000,0.71,0.00054,-0.013,0.71,0.02,0.015,0.013,0,0,-4.9e+02,-0.0013,-0.0059,-2.6e-05,0.0098,0.0038,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00069,6e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.014,0.017,0.007,0.038,0.04,0.036,9.3e-07,1.5e-06,2.1e-06,0.0055,0.0068,0.00022,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.8 +19290000,0.71,0.00057,-0.013,0.71,0.021,0.015,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-3e-05,0.0097,0.0042,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00068,6.2e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.015,0.019,0.007,0.042,0.044,0.036,9.2e-07,1.5e-06,2.1e-06,0.0055,0.0067,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 +19390000,0.71,0.00053,-0.013,0.71,0.02,0.014,0.018,0,0,-4.9e+02,-0.0013,-0.0059,-2.3e-05,0.0096,0.004,-0.13,0.21,-3.6e-06,0.43,-0.00026,0.00068,5.7e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.014,0.017,0.0069,0.038,0.04,0.036,8.9e-07,1.5e-06,2.1e-06,0.0055,0.0066,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 +19490000,0.71,0.00054,-0.013,0.71,0.02,0.015,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-1.8e-05,0.0096,0.0033,-0.13,0.21,-3.4e-06,0.43,-0.00026,0.00069,6e-05,0,0,-4.9e+02,0.00011,0.0001,0.036,0.015,0.018,0.0069,0.042,0.044,0.035,8.8e-07,1.4e-06,2.1e-06,0.0054,0.0066,0.00021,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 +19590000,0.71,0.00062,-0.013,0.71,0.017,0.014,0.015,0,0,-4.9e+02,-0.0013,-0.0059,-6.4e-06,0.01,0.003,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.0007,6.8e-05,0,0,-4.9e+02,0.00011,9.8e-05,0.036,0.014,0.017,0.0068,0.038,0.039,0.035,8.6e-07,1.4e-06,2.1e-06,0.0054,0.0065,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,4.9 +19690000,0.71,0.00066,-0.013,0.71,0.017,0.012,0.016,0,0,-4.9e+02,-0.0013,-0.0059,-9.9e-06,0.011,0.0037,-0.13,0.21,-3.8e-06,0.43,-0.00027,0.0007,6e-05,0,0,-4.9e+02,0.00011,9.8e-05,0.036,0.015,0.018,0.0068,0.042,0.043,0.035,8.4e-07,1.4e-06,2.1e-06,0.0053,0.0064,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 +19790000,0.71,0.00074,-0.013,0.71,0.015,0.01,0.017,0,0,-4.9e+02,-0.0013,-0.0059,-5.4e-06,0.011,0.004,-0.13,0.21,-4.1e-06,0.43,-0.00028,0.0007,5.9e-05,0,0,-4.9e+02,0.00011,9.6e-05,0.036,0.014,0.017,0.0067,0.038,0.039,0.035,8.2e-07,1.3e-06,2.1e-06,0.0053,0.0063,0.0002,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 +19890000,0.71,0.00065,-0.013,0.71,0.015,0.012,0.018,0,0,-4.9e+02,-0.0013,-0.0058,2.8e-06,0.011,0.003,-0.13,0.21,-3.7e-06,0.43,-0.00027,0.00071,6.6e-05,0,0,-4.9e+02,0.00011,9.6e-05,0.036,0.015,0.018,0.0067,0.041,0.043,0.035,8.1e-07,1.3e-06,2.1e-06,0.0052,0.0063,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 +19990000,0.71,0.00062,-0.013,0.71,0.013,0.012,0.02,0,0,-4.9e+02,-0.0013,-0.0058,1.8e-05,0.011,0.0021,-0.13,0.21,-3.6e-06,0.43,-0.00027,0.00072,7e-05,0,0,-4.9e+02,0.0001,9.4e-05,0.036,0.014,0.017,0.0066,0.038,0.039,0.035,7.9e-07,1.3e-06,2.1e-06,0.0052,0.0062,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5 +20090000,0.71,0.00065,-0.013,0.71,0.013,0.013,0.02,0,0,-4.9e+02,-0.0013,-0.0058,2.8e-05,0.012,0.0013,-0.13,0.21,-3.5e-06,0.43,-0.00028,0.00074,8.1e-05,0,0,-4.9e+02,0.00011,9.5e-05,0.036,0.014,0.018,0.0066,0.041,0.043,0.035,7.8e-07,1.2e-06,2.1e-06,0.0052,0.0062,0.00019,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 +20190000,0.71,0.00069,-0.013,0.71,0.012,0.011,0.022,0,0,-4.9e+02,-0.0013,-0.0058,3.7e-05,0.012,0.001,-0.13,0.21,-3.4e-06,0.43,-0.00027,0.00074,8e-05,0,0,-4.9e+02,0.0001,9.3e-05,0.036,0.013,0.016,0.0065,0.038,0.039,0.034,7.6e-07,1.2e-06,2.1e-06,0.0051,0.0061,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 +20290000,0.71,0.0007,-0.013,0.71,0.01,0.011,0.021,0,0,-4.9e+02,-0.0013,-0.0058,4.1e-05,0.012,0.00096,-0.13,0.21,-3.5e-06,0.43,-0.00028,0.00075,8.1e-05,0,0,-4.9e+02,0.0001,9.3e-05,0.036,0.014,0.018,0.0065,0.041,0.043,0.034,7.5e-07,1.2e-06,2.1e-06,0.0051,0.0061,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 +20390000,0.71,0.00065,-0.013,0.71,0.0088,0.0091,0.022,0,0,-4.9e+02,-0.0013,-0.0058,4.5e-05,0.012,0.001,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00075,7.1e-05,0,0,-4.9e+02,0.0001,9.1e-05,0.036,0.013,0.016,0.0064,0.037,0.039,0.034,7.3e-07,1.1e-06,2e-06,0.0051,0.006,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.1 +20490000,0.71,0.0007,-0.013,0.71,0.0089,0.009,0.022,0,0,-4.9e+02,-0.0013,-0.0058,4.1e-05,0.012,0.0013,-0.13,0.21,-3.5e-06,0.43,-0.00027,0.00074,7e-05,0,0,-4.9e+02,0.0001,9.1e-05,0.036,0.014,0.017,0.0064,0.041,0.043,0.034,7.2e-07,1.1e-06,2e-06,0.005,0.0059,0.00018,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 +20590000,0.71,0.00073,-0.013,0.71,0.008,0.007,0.02,0,0,-4.9e+02,-0.0013,-0.0058,4.2e-05,0.012,0.0019,-0.13,0.21,-3.7e-06,0.43,-0.00027,0.00074,6.9e-05,0,0,-4.9e+02,0.0001,8.9e-05,0.036,0.013,0.016,0.0063,0.037,0.039,0.034,7e-07,1.1e-06,2e-06,0.005,0.0059,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 +20690000,0.71,0.00076,-0.013,0.71,0.0087,0.007,0.021,0,0,-4.9e+02,-0.0013,-0.0058,4.5e-05,0.012,0.0016,-0.13,0.21,-3.7e-06,0.43,-0.00027,0.00074,7.1e-05,0,0,-4.9e+02,0.0001,9e-05,0.036,0.014,0.017,0.0064,0.041,0.043,0.034,6.9e-07,1.1e-06,2e-06,0.005,0.0058,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 +20790000,0.71,0.0008,-0.013,0.7,0.0065,0.0066,0.021,0,0,-4.9e+02,-0.0013,-0.0058,5.1e-05,0.013,0.0018,-0.13,0.21,-3.7e-06,0.43,-0.00028,0.00075,6.5e-05,0,0,-4.9e+02,9.8e-05,8.8e-05,0.036,0.013,0.016,0.0063,0.037,0.039,0.034,6.7e-07,1e-06,2e-06,0.0049,0.0057,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.2 +20890000,0.71,0.00081,-0.013,0.7,0.0064,0.0062,0.021,0,0,-4.9e+02,-0.0013,-0.0058,5.8e-05,0.013,0.0013,-0.13,0.21,-3.7e-06,0.43,-0.00028,0.00076,7e-05,0,0,-4.9e+02,9.9e-05,8.8e-05,0.036,0.014,0.017,0.0063,0.04,0.043,0.034,6.7e-07,1e-06,2e-06,0.0049,0.0057,0.00017,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 +20990000,0.71,0.00083,-0.013,0.7,0.0047,0.0039,0.021,0,0,-4.9e+02,-0.0013,-0.0058,6.3e-05,0.013,0.0016,-0.13,0.21,-3.7e-06,0.43,-0.0003,0.00076,6.7e-05,0,0,-4.9e+02,9.6e-05,8.6e-05,0.036,0.013,0.016,0.0062,0.037,0.039,0.033,6.5e-07,9.9e-07,2e-06,0.0049,0.0056,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 +21090000,0.71,0.00081,-0.013,0.7,0.0056,0.0031,0.022,0,0,-4.9e+02,-0.0013,-0.0058,6.8e-05,0.013,0.0011,-0.13,0.21,-3.5e-06,0.43,-0.00029,0.00077,6.4e-05,0,0,-4.9e+02,9.7e-05,8.6e-05,0.036,0.014,0.017,0.0062,0.04,0.043,0.034,6.4e-07,9.9e-07,2e-06,0.0048,0.0056,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 +21190000,0.71,0.00081,-0.013,0.7,0.0059,0.0022,0.021,0,0,-4.9e+02,-0.0013,-0.0058,6.8e-05,0.013,0.0013,-0.13,0.21,-3.5e-06,0.43,-0.00029,0.00077,6.1e-05,0,0,-4.9e+02,9.5e-05,8.5e-05,0.036,0.013,0.016,0.0061,0.037,0.039,0.033,6.3e-07,9.5e-07,2e-06,0.0048,0.0055,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.3 +21290000,0.71,0.00089,-0.013,0.7,0.0052,0.0023,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.8e-05,0.013,0.00082,-0.13,0.21,-3.5e-06,0.43,-0.00029,0.00079,6.5e-05,0,0,-4.9e+02,9.5e-05,8.5e-05,0.036,0.014,0.017,0.0061,0.04,0.043,0.033,6.2e-07,9.5e-07,1.9e-06,0.0048,0.0055,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 +21390000,0.71,0.00088,-0.013,0.7,0.0042,0.0003,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.3e-05,0.013,0.00099,-0.13,0.21,-3.7e-06,0.43,-0.00029,0.00078,6.5e-05,0,0,-4.9e+02,9.3e-05,8.3e-05,0.036,0.013,0.016,0.0061,0.037,0.039,0.033,6e-07,9.1e-07,1.9e-06,0.0047,0.0054,0.00016,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 +21490000,0.71,0.00087,-0.013,0.7,0.0047,0.00072,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.8e-05,0.013,0.00064,-0.13,0.21,-3.7e-06,0.43,-0.00028,0.00078,7e-05,0,0,-4.9e+02,9.4e-05,8.4e-05,0.036,0.014,0.017,0.0061,0.04,0.043,0.033,6e-07,9.1e-07,1.9e-06,0.0047,0.0054,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 +21590000,0.71,0.00086,-0.013,0.7,0.0035,0.0012,0.023,0,0,-4.9e+02,-0.0013,-0.0058,7.6e-05,0.013,0.00067,-0.13,0.21,-3.8e-06,0.43,-0.00028,0.00078,6.7e-05,0,0,-4.9e+02,9.2e-05,8.2e-05,0.036,0.013,0.015,0.006,0.037,0.039,0.033,5.8e-07,8.7e-07,1.9e-06,0.0047,0.0054,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.4 +21690000,0.71,0.00084,-0.013,0.7,0.0052,0.0015,0.025,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.013,0.00026,-0.13,0.21,-3.7e-06,0.43,-0.00027,0.00078,6.7e-05,0,0,-4.9e+02,9.2e-05,8.2e-05,0.036,0.013,0.017,0.006,0.04,0.042,0.033,5.8e-07,8.7e-07,1.9e-06,0.0047,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 +21790000,0.71,0.00083,-0.013,0.7,0.0033,0.0037,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.1e-05,0.013,0.00044,-0.13,0.21,-4.3e-06,0.43,-0.00029,0.00078,6.9e-05,0,0,-4.9e+02,9e-05,8.1e-05,0.036,0.013,0.015,0.006,0.037,0.039,0.033,5.6e-07,8.3e-07,1.9e-06,0.0046,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 +21890000,0.71,0.00083,-0.013,0.7,0.004,0.0042,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.2e-05,0.013,0.00036,-0.13,0.21,-4.2e-06,0.43,-0.00029,0.00078,6.7e-05,0,0,-4.9e+02,9.1e-05,8.1e-05,0.036,0.013,0.016,0.006,0.04,0.042,0.033,5.6e-07,8.3e-07,1.9e-06,0.0046,0.0053,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,5.5 +21990000,0.71,0.00085,-0.013,0.7,0.0028,0.0049,0.025,0,0,-4.9e+02,-0.0013,-0.0058,6.9e-05,0.014,0.00019,-0.13,0.21,-4.6e-06,0.43,-0.0003,0.00078,6.9e-05,0,0,-4.9e+02,8.9e-05,7.9e-05,0.036,0.012,0.015,0.0059,0.036,0.038,0.033,5.5e-07,8e-07,1.9e-06,0.0046,0.0052,0.00015,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22090000,0.71,0.00087,-0.013,0.7,0.0027,0.0065,0.024,0,0,-4.9e+02,-0.0013,-0.0058,6.9e-05,0.014,0.00024,-0.13,0.21,-4.6e-06,0.43,-0.0003,0.00078,6.9e-05,0,0,-4.9e+02,8.9e-05,8e-05,0.036,0.013,0.016,0.0059,0.04,0.042,0.033,5.4e-07,8e-07,1.9e-06,0.0046,0.0052,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22190000,0.71,0.00084,-0.013,0.7,0.0022,0.0065,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.5e-05,0.014,0.00031,-0.13,0.21,-4.4e-06,0.43,-0.00031,0.00079,5.8e-05,0,0,-4.9e+02,8.7e-05,7.8e-05,0.036,0.012,0.015,0.0059,0.036,0.038,0.033,5.3e-07,7.7e-07,1.8e-06,0.0045,0.0051,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22290000,0.71,0.00087,-0.013,0.7,0.0015,0.0062,0.024,0,0,-4.9e+02,-0.0013,-0.0058,7.3e-05,0.013,0.00036,-0.13,0.21,-4.5e-06,0.43,-0.00031,0.00078,5.9e-05,0,0,-4.9e+02,8.8e-05,7.8e-05,0.036,0.013,0.016,0.0059,0.04,0.042,0.033,5.2e-07,7.7e-07,1.8e-06,0.0045,0.0051,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22390000,0.71,0.00089,-0.013,0.7,-0.0008,0.0059,0.026,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.014,0.00057,-0.13,0.21,-4.4e-06,0.43,-0.00031,0.00079,6e-05,0,0,-4.9e+02,8.6e-05,7.7e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.033,5.1e-07,7.4e-07,1.8e-06,0.0045,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22490000,0.71,0.00093,-0.013,0.7,-0.0019,0.0067,0.027,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.014,0.0007,-0.13,0.21,-4.4e-06,0.43,-0.00033,0.0008,5.8e-05,0,0,-4.9e+02,8.7e-05,7.7e-05,0.036,0.013,0.016,0.0058,0.04,0.042,0.033,5.1e-07,7.4e-07,1.8e-06,0.0045,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22590000,0.71,0.00095,-0.013,0.7,-0.0036,0.0061,0.026,0,0,-4.9e+02,-0.0014,-0.0058,8.4e-05,0.015,0.00088,-0.13,0.21,-4.3e-06,0.43,-0.00034,0.00081,5.5e-05,0,0,-4.9e+02,8.5e-05,7.6e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.032,5e-07,7.1e-07,1.8e-06,0.0044,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22690000,0.71,0.001,-0.013,0.7,-0.0049,0.0075,0.027,0,0,-4.9e+02,-0.0014,-0.0058,9e-05,0.015,0.00076,-0.13,0.21,-4.2e-06,0.43,-0.00035,0.00082,5.4e-05,0,0,-4.9e+02,8.5e-05,7.6e-05,0.036,0.013,0.016,0.0058,0.039,0.042,0.033,4.9e-07,7.1e-07,1.8e-06,0.0044,0.005,0.00014,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22790000,0.71,0.001,-0.013,0.7,-0.0069,0.0064,0.028,0,0,-4.9e+02,-0.0014,-0.0058,7.9e-05,0.015,0.0015,-0.13,0.21,-4.4e-06,0.43,-0.00034,0.0008,6e-05,0,0,-4.9e+02,8.3e-05,7.5e-05,0.036,0.012,0.015,0.0058,0.036,0.038,0.032,4.8e-07,6.8e-07,1.8e-06,0.0044,0.0049,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22890000,0.71,0.00099,-0.013,0.7,-0.0073,0.0073,0.03,0,0,-4.9e+02,-0.0014,-0.0058,7.9e-05,0.015,0.0014,-0.13,0.21,-4.4e-06,0.43,-0.00034,0.00079,5.6e-05,0,0,-4.9e+02,8.4e-05,7.5e-05,0.036,0.013,0.016,0.0058,0.039,0.042,0.032,4.8e-07,6.8e-07,1.7e-06,0.0044,0.0049,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +22990000,0.71,0.00097,-0.013,0.7,-0.0075,0.0064,0.03,0,0,-4.9e+02,-0.0014,-0.0058,8.8e-05,0.015,0.0013,-0.13,0.21,-4.1e-06,0.43,-0.00034,0.0008,5.3e-05,0,0,-4.9e+02,8.2e-05,7.4e-05,0.036,0.012,0.015,0.0057,0.036,0.038,0.032,4.7e-07,6.6e-07,1.7e-06,0.0044,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +23090000,0.71,0.00092,-0.013,0.7,-0.0079,0.0063,0.031,0,0,-4.9e+02,-0.0014,-0.0058,8e-05,0.014,0.0015,-0.13,0.21,-4.2e-06,0.43,-0.00034,0.00079,5.1e-05,0,0,-4.9e+02,8.3e-05,7.4e-05,0.036,0.013,0.016,0.0057,0.039,0.042,0.032,4.7e-07,6.6e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +23190000,0.71,0.00097,-0.013,0.7,-0.0092,0.0043,0.032,0,0,-4.9e+02,-0.0014,-0.0058,8.2e-05,0.015,0.0017,-0.13,0.21,-4.2e-06,0.43,-0.00033,0.00078,4.3e-05,0,0,-4.9e+02,8.1e-05,7.3e-05,0.036,0.012,0.014,0.0057,0.036,0.038,0.032,4.6e-07,6.3e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +23290000,0.71,0.00089,-0.013,0.7,-0.009,0.0038,0.032,0,0,-4.9e+02,-0.0014,-0.0058,8.4e-05,0.014,0.0016,-0.13,0.21,-4.2e-06,0.43,-0.00033,0.00078,4.1e-05,0,0,-4.9e+02,8.2e-05,7.3e-05,0.036,0.013,0.016,0.0057,0.039,0.042,0.032,4.5e-07,6.3e-07,1.7e-06,0.0043,0.0048,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +23390000,0.71,0.00095,-0.013,0.7,-0.0093,0.0026,0.03,0,0,-4.9e+02,-0.0014,-0.0058,8.7e-05,0.014,0.0016,-0.13,0.21,-4.3e-06,0.43,-0.00031,0.00078,4.3e-05,0,0,-4.9e+02,8e-05,7.2e-05,0.036,0.012,0.014,0.0057,0.036,0.038,0.032,4.4e-07,6.1e-07,1.7e-06,0.0043,0.0047,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0013,1,1,0.01 +23490000,0.71,0.0033,-0.011,0.7,-0.016,0.0028,-0.0031,0,0,-4.9e+02,-0.0014,-0.0058,9.3e-05,0.014,0.0013,-0.13,0.21,-4.2e-06,0.43,-0.0003,0.00081,6.7e-05,0,0,-4.9e+02,8.1e-05,7.2e-05,0.036,0.013,0.015,0.0057,0.039,0.042,0.032,4.4e-07,6.1e-07,1.7e-06,0.0043,0.0047,0.00013,0.0013,3.9e-05,0.0013,0.0016,0.0013,0.0012,1,1,0.01 +23590000,0.71,0.0086,-0.0027,0.7,-0.027,0.0028,-0.035,0,0,-4.9e+02,-0.0013,-0.0058,8.9e-05,0.014,0.0013,-0.13,0.21,-4.2e-06,0.43,-0.0003,0.00086,0.00014,0,0,-4.9e+02,7.9e-05,7.1e-05,0.036,0.012,0.014,0.0056,0.036,0.038,0.032,4.3e-07,5.9e-07,1.6e-06,0.0043,0.0047,0.00012,0.0013,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +23690000,0.71,0.0082,0.003,0.71,-0.058,-0.005,-0.085,0,0,-4.9e+02,-0.0013,-0.0058,9e-05,0.014,0.0013,-0.13,0.21,-4.2e-06,0.43,-0.0003,0.0008,0.0001,0,0,-4.9e+02,8e-05,7.1e-05,0.036,0.013,0.015,0.0056,0.039,0.042,0.032,4.3e-07,5.9e-07,1.6e-06,0.0042,0.0047,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +23790000,0.71,0.0052,-0.00025,0.71,-0.082,-0.017,-0.14,0,0,-4.9e+02,-0.0013,-0.0058,9.1e-05,0.013,0.00086,-0.13,0.21,-3.4e-06,0.43,-0.00036,0.0008,0.00045,0,0,-4.9e+02,7.8e-05,7e-05,0.036,0.012,0.014,0.0056,0.036,0.038,0.032,4.2e-07,5.7e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +23890000,0.71,0.0026,-0.0063,0.71,-0.099,-0.025,-0.19,0,0,-4.9e+02,-0.0013,-0.0058,9.1e-05,0.014,0.001,-0.13,0.21,-3.3e-06,0.43,-0.00038,0.00085,0.00036,0,0,-4.9e+02,7.9e-05,7e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4.2e-07,5.7e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +23990000,0.71,0.0012,-0.011,0.71,-0.1,-0.029,-0.25,0,0,-4.9e+02,-0.0013,-0.0058,9.6e-05,0.014,0.001,-0.13,0.21,-3e-06,0.43,-0.00036,0.00085,0.00034,0,0,-4.9e+02,7.7e-05,6.9e-05,0.036,0.012,0.015,0.0056,0.036,0.038,0.032,4.1e-07,5.5e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24090000,0.71,0.0025,-0.0096,0.71,-0.1,-0.028,-0.29,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.014,0.0007,-0.13,0.21,-2.5e-06,0.43,-0.00038,0.00082,0.00038,0,0,-4.9e+02,7.7e-05,6.9e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4.1e-07,5.5e-07,1.6e-06,0.0042,0.0046,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24190000,0.71,0.0036,-0.0073,0.71,-0.11,-0.03,-0.34,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.00059,-0.13,0.21,-1.8e-06,0.43,-0.00038,0.00085,0.00037,0,0,-4.9e+02,7.6e-05,6.8e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,4e-07,5.4e-07,1.6e-06,0.0042,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24290000,0.71,0.0041,-0.0065,0.71,-0.12,-0.034,-0.4,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.013,0.00055,-0.13,0.21,-1.5e-06,0.43,-0.00042,0.0009,0.00044,0,0,-4.9e+02,7.7e-05,6.9e-05,0.036,0.013,0.016,0.0056,0.039,0.042,0.032,4e-07,5.4e-07,1.6e-06,0.0042,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24390000,0.71,0.0042,-0.0067,0.71,-0.13,-0.041,-0.45,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.0012,-0.13,0.21,1.3e-06,0.43,-0.0003,0.00094,0.00043,0,0,-4.9e+02,7.5e-05,6.7e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.9e-07,5.2e-07,1.5e-06,0.0041,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24490000,0.71,0.005,-0.0025,0.71,-0.14,-0.046,-0.5,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.013,0.0012,-0.13,0.21,1.3e-06,0.43,-0.0003,0.00095,0.00042,0,0,-4.9e+02,7.6e-05,6.8e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.9e-07,5.2e-07,1.5e-06,0.0041,0.0045,0.00012,0.0012,3.9e-05,0.0012,0.0016,0.0012,0.0012,1,1,0.01 +24590000,0.71,0.0055,0.0012,0.71,-0.16,-0.057,-0.55,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0012,-0.13,0.21,2.3e-06,0.43,5.4e-05,0.0006,0.00037,0,0,-4.9e+02,7.4e-05,6.7e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.8e-07,5e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +24690000,0.71,0.0056,0.0021,0.71,-0.18,-0.07,-0.64,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.001,-0.13,0.21,3.3e-06,0.43,9.8e-06,0.00064,0.00056,0,0,-4.9e+02,7.5e-05,6.7e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.8e-07,5e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +24790000,0.71,0.0053,0.00083,0.71,-0.2,-0.084,-0.72,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.012,0.0011,-0.13,0.21,2.6e-06,0.43,4.2e-05,0.00061,0.00032,0,0,-4.9e+02,7.3e-05,6.6e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.7e-07,4.9e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +24890000,0.71,0.0071,0.0025,0.71,-0.22,-0.095,-0.74,0,0,-4.9e+02,-0.0013,-0.0058,0.00012,0.012,0.0011,-0.13,0.21,3.4e-06,0.43,-6.5e-05,0.00076,0.00034,0,0,-4.9e+02,7.4e-05,6.6e-05,0.036,0.013,0.016,0.0055,0.039,0.042,0.031,3.7e-07,4.9e-07,1.5e-06,0.0041,0.0044,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +24990000,0.71,0.0089,0.0043,0.71,-0.24,-0.1,-0.8,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.012,0.00076,-0.13,0.21,2.8e-06,0.43,-0.00015,0.00086,-4.5e-06,0,0,-4.9e+02,7.2e-05,6.5e-05,0.036,0.012,0.015,0.0055,0.036,0.038,0.031,3.7e-07,4.8e-07,1.5e-06,0.0041,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25090000,0.71,0.0092,0.0037,0.71,-0.27,-0.11,-0.85,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.012,0.00085,-0.13,0.21,2.4e-06,0.43,-0.00016,0.00087,-4.1e-05,0,0,-4.9e+02,7.3e-05,6.5e-05,0.036,0.013,0.017,0.0055,0.039,0.042,0.031,3.7e-07,4.8e-07,1.5e-06,0.0041,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25190000,0.71,0.0087,0.0023,0.71,-0.3,-0.13,-0.9,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.0012,-0.13,0.21,7.7e-06,0.43,9.3e-05,0.00084,9.5e-05,0,0,-4.9e+02,7.2e-05,6.4e-05,0.035,0.012,0.016,0.0054,0.036,0.038,0.031,3.6e-07,4.6e-07,1.5e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25290000,0.71,0.011,0.0091,0.71,-0.33,-0.14,-0.95,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.0012,-0.13,0.21,7.6e-06,0.43,0.00012,0.00079,0.0001,0,0,-4.9e+02,7.2e-05,6.5e-05,0.035,0.013,0.017,0.0054,0.039,0.042,0.031,3.6e-07,4.6e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25390000,0.71,0.012,0.016,0.71,-0.36,-0.16,-1,0,0,-4.9e+02,-0.0013,-0.0058,0.00013,0.011,0.0009,-0.13,0.21,1.1e-05,0.43,0.00052,0.00047,0.00014,0,0,-4.9e+02,7.1e-05,6.3e-05,0.035,0.012,0.016,0.0054,0.036,0.038,0.031,3.5e-07,4.5e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25490000,0.71,0.012,0.017,0.71,-0.41,-0.18,-1.1,0,0,-4.9e+02,-0.0013,-0.0058,0.00014,0.01,0.00078,-0.13,0.21,1e-05,0.43,0.00069,0.00015,0.00032,0,0,-4.9e+02,7.2e-05,6.4e-05,0.035,0.013,0.018,0.0054,0.039,0.042,0.031,3.5e-07,4.5e-07,1.4e-06,0.004,0.0043,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25590000,0.71,0.012,0.015,0.71,-0.45,-0.21,-1.1,0,0,-4.9e+02,-0.0012,-0.0058,0.00015,0.0098,0.0012,-0.13,0.21,1.6e-05,0.43,0.00099,0.00015,0.00033,0,0,-4.9e+02,7.1e-05,6.3e-05,0.034,0.012,0.018,0.0054,0.036,0.038,0.031,3.5e-07,4.4e-07,1.4e-06,0.004,0.0042,0.00011,0.0012,3.9e-05,0.0012,0.0015,0.0012,0.0012,1,1,0.01 +25690000,0.71,0.015,0.022,0.71,-0.49,-0.23,-1.2,0,0,-4.9e+02,-0.0012,-0.0058,0.00016,0.0098,0.0011,-0.13,0.21,1.7e-05,0.43,0.00098,0.00017,0.00042,0,0,-4.9e+02,7.1e-05,6.3e-05,0.034,0.013,0.02,0.0054,0.039,0.042,0.031,3.5e-07,4.4e-07,1.4e-06,0.004,0.0042,0.00011,0.0012,3.9e-05,0.0012,0.0014,0.0012,0.0011,1,1,0.01 +25790000,0.71,0.018,0.028,0.71,-0.54,-0.26,-1.2,0,0,-4.9e+02,-0.0012,-0.0058,0.00016,0.0091,0.00045,-0.13,0.21,2e-05,0.43,0.0014,-7.6e-05,-3.4e-05,0,0,-4.9e+02,7e-05,6.2e-05,0.033,0.013,0.019,0.0054,0.036,0.038,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0014,0.0011,0.0011,1,1,0.01 +25890000,0.71,0.018,0.028,0.71,-0.62,-0.29,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00017,0.0093,0.00038,-0.13,0.21,2.2e-05,0.43,0.0014,-7.7e-06,-0.0001,0,0,-4.9e+02,7.1e-05,6.3e-05,0.033,0.014,0.022,0.0054,0.039,0.042,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0014,0.0011,0.0011,1,1,0.01 +25990000,0.7,0.017,0.025,0.71,-0.67,-0.32,-1.3,0,0,-4.9e+02,-0.0012,-0.0059,0.00019,0.0084,0.00072,-0.13,0.21,2.9e-05,0.43,0.0023,-0.00057,-0.00056,0,0,-4.9e+02,7e-05,6.2e-05,0.032,0.013,0.021,0.0054,0.036,0.039,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0013,0.0011,0.0011,1,1,0.01 +26090000,0.7,0.022,0.035,0.71,-0.74,-0.35,-1.3,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.0085,0.00089,-0.13,0.21,2.5e-05,0.43,0.0024,-0.00049,-0.0012,0,0,-4.9e+02,7.1e-05,6.2e-05,0.032,0.014,0.024,0.0054,0.039,0.043,0.031,3.4e-07,4.3e-07,1.4e-06,0.004,0.0042,0.0001,0.0011,3.9e-05,0.0011,0.0013,0.0011,0.0011,1,1,0.01 +26190000,0.7,0.024,0.045,0.71,-0.79,-0.39,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00018,0.0074,-0.00025,-0.13,0.21,3.9e-05,0.43,0.0023,0.0004,-0.0014,0,0,-4.9e+02,7.1e-05,6.1e-05,0.03,0.014,0.024,0.0053,0.036,0.039,0.031,3.3e-07,4.2e-07,1.4e-06,0.004,0.0042,0.0001,0.001,3.9e-05,0.001,0.0013,0.001,0.001,1,1,0.01 +26290000,0.7,0.025,0.047,0.71,-0.89,-0.43,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,0.00018,0.0074,-0.00023,-0.13,0.21,3.8e-05,0.43,0.0023,0.00028,-0.0014,0,0,-4.9e+02,7.1e-05,6.1e-05,0.03,0.015,0.028,0.0054,0.039,0.043,0.031,3.3e-07,4.2e-07,1.4e-06,0.004,0.0042,0.0001,0.00099,3.9e-05,0.00099,0.0013,0.001,0.00099,1,1,0.01 +26390000,0.7,0.024,0.044,0.71,-0.96,-0.49,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00021,0.0065,0.00054,-0.13,0.21,4.5e-05,0.44,0.0036,-0.00019,-0.0024,0,0,-4.9e+02,7.1e-05,6.1e-05,0.028,0.014,0.027,0.0053,0.036,0.039,0.031,3.3e-07,4.1e-07,1.3e-06,0.004,0.0042,0.0001,0.00096,3.9e-05,0.00095,0.0012,0.00096,0.00095,1,1,0.01 +26490000,0.7,0.031,0.06,0.71,-1.1,-0.53,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.0002,0.0065,0.00055,-0.13,0.21,3.8e-05,0.44,0.004,-0.00099,-0.0026,0,0,-4.9e+02,7.2e-05,6.1e-05,0.028,0.016,0.031,0.0053,0.039,0.044,0.031,3.3e-07,4.2e-07,1.3e-06,0.0039,0.0042,0.0001,0.00092,3.9e-05,0.00092,0.0012,0.00092,0.00091,1,1,0.01 +26590000,0.7,0.037,0.076,0.71,-1.2,-0.59,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00019,0.0049,-0.00046,-0.13,0.21,3.7e-05,0.44,0.0041,-0.00065,-0.0048,0,0,-4.9e+02,7.2e-05,6e-05,0.025,0.015,0.031,0.0053,0.036,0.04,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.9e-05,0.00087,3.9e-05,0.00086,0.001,0.00087,0.00086,1,1,0.01 +26690000,0.7,0.039,0.079,0.71,-1.3,-0.65,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00019,0.0049,-0.00055,-0.13,0.21,4.4e-05,0.44,0.004,-0.00014,-0.004,0,0,-4.9e+02,7.2e-05,6.1e-05,0.025,0.017,0.037,0.0053,0.04,0.045,0.031,3.3e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.9e-05,0.00081,3.9e-05,0.0008,0.001,0.00081,0.00079,1,1,0.01 +26790000,0.7,0.036,0.073,0.71,-1.4,-0.74,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00022,0.0033,0.00031,-0.13,0.21,8.2e-05,0.44,0.0055,0.00061,-0.0037,0,0,-4.9e+02,7.3e-05,6e-05,0.022,0.016,0.036,0.0053,0.036,0.041,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.8e-05,0.00076,3.9e-05,0.00075,0.00092,0.00076,0.00074,1,1,0.01 +26890000,0.7,0.045,0.095,0.71,-1.6,-0.8,-1.3,0,0,-4.9e+02,-0.0011,-0.0059,0.00023,0.0034,0.0003,-0.13,0.21,8.8e-05,0.44,0.0053,0.0012,-0.0041,0,0,-4.9e+02,7.3e-05,6e-05,0.022,0.018,0.043,0.0053,0.04,0.046,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.8e-05,0.00072,3.9e-05,0.0007,0.00091,0.00072,0.0007,1,1,0.01 +26990000,0.7,0.051,0.12,0.71,-1.7,-0.89,-1.3,0,0,-4.9e+02,-0.00098,-0.0059,0.00022,0.0014,-0.0016,-0.13,0.21,0.00013,0.44,0.006,0.0034,-0.0056,0,0,-4.9e+02,7.4e-05,6e-05,0.019,0.017,0.042,0.0053,0.037,0.041,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.7e-05,0.00065,3.9e-05,0.00063,0.00079,0.00065,0.00062,1,1,0.01 +27090000,0.7,0.052,0.12,0.71,-1.9,-0.98,-1.2,0,0,-4.9e+02,-0.00098,-0.0059,0.00022,0.0013,-0.0016,-0.13,0.21,0.00013,0.44,0.006,0.0035,-0.0052,0,0,-4.9e+02,7.4e-05,6e-05,0.019,0.02,0.052,0.0053,0.04,0.048,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.6e-05,0.00059,3.9e-05,0.00056,0.00078,0.0006,0.00056,1,1,0.01 +27190000,0.7,0.05,0.11,0.7,-2.1,-1,-1.2,0,0,-4.9e+02,-0.00097,-0.0059,0.00022,0.00024,-0.0018,-0.13,0.21,4.5e-05,0.44,0.002,0.0027,-0.0049,0,0,-4.9e+02,7.5e-05,6e-05,0.016,0.02,0.051,0.0053,0.043,0.05,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.6e-05,0.00055,3.9e-05,0.00051,0.00066,0.00055,0.00051,1,1,0.01 +27290000,0.71,0.044,0.095,0.7,-2.3,-1.1,-1.2,0,0,-4.9e+02,-0.00097,-0.0059,0.00023,0.00028,-0.0018,-0.13,0.21,5.3e-05,0.44,0.0019,0.0034,-0.0049,0,0,-4.9e+02,7.6e-05,6.1e-05,0.016,0.022,0.059,0.0053,0.047,0.057,0.031,3.2e-07,4.1e-07,1.3e-06,0.0039,0.0041,9.5e-05,0.00052,3.9e-05,0.00048,0.00066,0.00052,0.00048,1,1,0.01 +27390000,0.71,0.038,0.079,0.7,-2.4,-1.1,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00021,-0.00096,-0.0035,-0.13,0.21,9.8e-06,0.44,-0.00058,0.0031,-0.0063,0,0,-4.9e+02,7.6e-05,6e-05,0.013,0.021,0.052,0.0053,0.049,0.059,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.5e-05,0.00049,3.9e-05,0.00046,0.00055,0.00049,0.00046,1,1,0.01 +27490000,0.71,0.032,0.064,0.7,-2.5,-1.1,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00022,-0.0009,-0.0034,-0.13,0.21,1.5e-05,0.44,-0.00066,0.0032,-0.0067,0,0,-4.9e+02,7.7e-05,6.1e-05,0.013,0.023,0.056,0.0053,0.054,0.067,0.03,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.4e-05,0.00048,3.9e-05,0.00045,0.00055,0.00048,0.00044,1,1,0.01 27590000,0.72,0.028,0.051,0.69,-2.6,-1.1,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00023,-0.0016,-0.0028,-0.13,0.21,-4.1e-05,0.44,-0.0033,0.0027,-0.0065,0,0,-4.9e+02,7.7e-05,6.1e-05,0.011,0.021,0.047,0.0053,0.056,0.068,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.4e-05,0.00046,3.9e-05,0.00044,0.00047,0.00046,0.00044,1,1,0.01 -27690000,0.72,0.027,0.05,0.69,-2.6,-1.2,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00023,-0.0016,-0.0026,-0.13,0.21,-3.6e-05,0.44,-0.0034,0.0026,-0.0067,0,0,-4.9e+02,7.8e-05,6.1e-05,0.011,0.022,0.049,0.0053,0.062,0.077,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.3e-05,0.00046,3.9e-05,0.00044,0.00047,0.00046,0.00043,1,1,0.01 -27790000,0.72,0.027,0.051,0.69,-2.6,-1.2,-1.2,0,0,-4.9e+02,-0.00091,-0.0059,0.00022,-0.0022,-0.0024,-0.13,0.21,-6.4e-05,0.44,-0.0052,0.002,-0.0072,0,0,-4.9e+02,7.9e-05,6.1e-05,0.0097,0.02,0.042,0.0053,0.064,0.077,0.03,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.2e-05,0.00045,3.9e-05,0.00043,0.00041,0.00045,0.00043,1,1,0.01 -27890000,0.72,0.027,0.049,0.69,-2.7,-1.2,-1.2,0,0,-4.9e+02,-0.00091,-0.0059,0.00023,-0.0022,-0.0024,-0.13,0.21,-6.5e-05,0.44,-0.0051,0.002,-0.0072,0,0,-4.9e+02,7.9e-05,6.1e-05,0.0097,0.021,0.043,0.0053,0.07,0.087,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.2e-05,0.00044,3.9e-05,0.00043,0.00041,0.00044,0.00042,1,1,0.01 -27990000,0.72,0.026,0.046,0.69,-2.7,-1.2,-1.2,0,0,-4.9e+02,-0.00093,-0.0059,0.00024,-0.002,-0.0014,-0.13,0.21,-8.1e-05,0.44,-0.0065,0.0014,-0.0071,0,0,-4.9e+02,8e-05,6.1e-05,0.0086,0.02,0.038,0.0053,0.072,0.087,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9.1e-05,0.00043,3.9e-05,0.00042,0.00037,0.00043,0.00042,1,1,0.01 -28090000,0.72,0.032,0.059,0.69,-2.8,-1.2,-1.2,0,0,-4.9e+02,-0.00093,-0.0059,0.00023,-0.0022,-0.0012,-0.13,0.21,-8e-05,0.44,-0.0066,0.0013,-0.0072,0,0,-4.9e+02,8.1e-05,6.1e-05,0.0086,0.021,0.039,0.0053,0.078,0.097,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9.1e-05,0.00042,3.9e-05,0.00042,0.00036,0.00042,0.00041,1,1,0.01 -28190000,0.72,0.037,0.072,0.69,-2.8,-1.2,-0.93,0,0,-4.9e+02,-0.00094,-0.0059,0.00024,-0.0022,-0.00077,-0.13,0.21,-9.9e-05,0.44,-0.0074,0.00088,-0.0071,0,0,-4.9e+02,8.1e-05,6.1e-05,0.0079,0.02,0.034,0.0053,0.08,0.097,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.00041,3.9e-05,0.00041,0.00033,0.00041,0.00041,1,1,0.01 -28290000,0.73,0.029,0.055,0.69,-2.8,-1.2,-0.069,0,0,-4.9e+02,-0.00093,-0.0059,0.00024,-0.0024,-0.00065,-0.13,0.21,-0.0001,0.44,-0.0075,0.0013,-0.0069,0,0,-4.9e+02,8.2e-05,6.1e-05,0.0079,0.02,0.035,0.0053,0.087,0.11,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 -28390000,0.73,0.012,0.024,0.69,-2.8,-1.2,0.79,0,0,-4.9e+02,-0.00094,-0.0059,0.00023,-0.0023,-0.00035,-0.13,0.21,-8.9e-05,0.44,-0.0076,0.0013,-0.007,0,0,-4.9e+02,8.3e-05,6.2e-05,0.0079,0.02,0.035,0.0054,0.094,0.12,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 -28490000,0.73,0.0028,0.0059,0.69,-2.8,-1.2,1.1,0,0,-4.9e+02,-0.00094,-0.0059,0.00023,-0.0019,-6e-05,-0.13,0.21,-7e-05,0.44,-0.0077,0.0014,-0.0069,0,0,-4.9e+02,8.4e-05,6.2e-05,0.0079,0.021,0.035,0.0054,0.1,0.13,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 -28590000,0.73,0.00088,0.0024,0.69,-2.7,-1.2,0.98,0,0,-4.9e+02,-0.00094,-0.0059,0.00024,-0.002,1.4e-05,-0.13,0.21,-7.2e-05,0.44,-0.0077,0.0015,-0.0069,0,0,-4.9e+02,8.4e-05,6.2e-05,0.0079,0.021,0.033,0.0054,0.11,0.14,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 -28690000,0.73,0.00018,0.0015,0.69,-2.6,-1.2,0.99,0,0,-4.9e+02,-0.00095,-0.0059,0.00024,-0.0017,0.00038,-0.13,0.21,-5.5e-05,0.44,-0.0078,0.0014,-0.0068,0,0,-4.9e+02,8.5e-05,6.2e-05,0.0079,0.022,0.033,0.0054,0.12,0.15,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.8e-05,0.0004,3.9e-05,0.0004,0.00033,0.00039,0.0004,1,1,0.01 -28790000,0.73,-1.9e-05,0.0014,0.69,-2.6,-1.2,0.99,0,0,-4.9e+02,-0.00098,-0.0059,0.00025,-0.0013,0.00064,-0.12,0.21,-9.6e-05,0.44,-0.0092,0.0006,-0.006,0,0,-4.9e+02,8.6e-05,6.2e-05,0.0075,0.021,0.028,0.0054,0.12,0.15,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.8e-05,0.00039,3.9e-05,0.0004,0.00031,0.00039,0.00039,1,1,0.01 -28890000,0.73,-9.5e-06,0.0016,0.69,-2.5,-1.2,0.98,0,0,-4.9e+02,-0.00099,-0.0059,0.00025,-0.00099,0.00099,-0.12,0.21,-8e-05,0.44,-0.0093,0.00056,-0.0059,0,0,-4.9e+02,8.6e-05,6.2e-05,0.0075,0.021,0.028,0.0054,0.13,0.16,0.031,3.1e-07,4e-07,1.3e-06,0.0038,0.004,8.7e-05,0.00039,3.9e-05,0.0004,0.00031,0.00039,0.00039,1,1,0.01 -28990000,0.73,0.00034,0.0023,0.68,-2.5,-1.1,0.98,0,0,-4.9e+02,-0.001,-0.0059,0.00025,0.00029,0.0015,-0.12,0.21,-0.00011,0.44,-0.011,-0.00036,-0.0047,0,0,-4.9e+02,8.7e-05,6.2e-05,0.0073,0.02,0.025,0.0054,0.13,0.16,0.031,3e-07,4e-07,1.3e-06,0.0038,0.004,8.7e-05,0.00039,3.9e-05,0.0004,0.0003,0.00039,0.00039,1,1,0.01 -29090000,0.73,0.00051,0.0027,0.68,-2.4,-1.1,0.97,0,0,-4.9e+02,-0.001,-0.0059,0.00025,0.00046,0.0019,-0.12,0.21,-9.6e-05,0.44,-0.011,-0.00041,-0.0046,0,0,-4.9e+02,8.7e-05,6.2e-05,0.0073,0.021,0.025,0.0054,0.14,0.17,0.031,3e-07,4e-07,1.2e-06,0.0038,0.004,8.6e-05,0.00039,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 -29190000,0.73,0.00076,0.0031,0.68,-2.4,-1.1,0.97,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.00083,0.002,-0.12,0.21,-0.00013,0.44,-0.011,-0.00065,-0.0041,0,0,-4.9e+02,8.8e-05,6.1e-05,0.0072,0.02,0.023,0.0054,0.14,0.17,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.6e-05,0.00038,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 -29290000,0.73,0.0011,0.0039,0.68,-2.3,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.00084,0.0024,-0.12,0.21,-0.00012,0.44,-0.011,-0.00072,-0.0041,0,0,-4.9e+02,8.8e-05,6.2e-05,0.0072,0.021,0.024,0.0054,0.14,0.18,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 -29390000,0.73,0.0017,0.0054,0.68,-2.3,-1.1,1,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.0015,0.003,-0.12,0.21,-0.00016,0.44,-0.012,-0.0014,-0.0033,0,0,-4.9e+02,8.8e-05,6.1e-05,0.0071,0.02,0.023,0.0054,0.15,0.18,0.03,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.00029,0.00038,0.00039,1,1,0.01 -29490000,0.73,0.0022,0.0065,0.68,-2.3,-1.1,1,0,0,-4.9e+02,-0.0011,-0.0059,0.00027,0.0015,0.0033,-0.12,0.21,-0.00015,0.44,-0.012,-0.0014,-0.0033,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.024,0.0054,0.15,0.19,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.00029,0.00038,0.00039,1,1,0.01 -29590000,0.73,0.0027,0.0075,0.68,-2.2,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.0021,0.0034,-0.12,0.21,-0.00016,0.44,-0.012,-0.0016,-0.0029,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.02,0.023,0.0054,0.15,0.19,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.4e-05,0.00038,3.9e-05,0.00039,0.00029,0.00038,0.00038,1,1,0.01 -29690000,0.73,0.003,0.0081,0.68,-2.2,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.002,0.0037,-0.12,0.21,-0.00016,0.44,-0.012,-0.0017,-0.0029,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.024,0.0054,0.16,0.2,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.4e-05,0.00038,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 +27690000,0.72,0.027,0.05,0.69,-2.6,-1.2,-1.2,0,0,-4.9e+02,-0.00092,-0.0059,0.00023,-0.0016,-0.0027,-0.13,0.21,-3.6e-05,0.44,-0.0034,0.0026,-0.0068,0,0,-4.9e+02,7.8e-05,6.1e-05,0.011,0.022,0.049,0.0053,0.062,0.077,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.3e-05,0.00046,3.9e-05,0.00044,0.00047,0.00046,0.00043,1,1,0.01 +27790000,0.72,0.027,0.051,0.69,-2.6,-1.2,-1.2,0,0,-4.9e+02,-0.00091,-0.0059,0.00022,-0.0021,-0.0025,-0.13,0.21,-6.4e-05,0.44,-0.0052,0.002,-0.0072,0,0,-4.9e+02,7.9e-05,6.1e-05,0.0097,0.02,0.042,0.0053,0.064,0.077,0.03,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.2e-05,0.00045,3.9e-05,0.00043,0.00041,0.00045,0.00043,1,1,0.01 +27890000,0.72,0.027,0.049,0.69,-2.7,-1.2,-1.2,0,0,-4.9e+02,-0.00091,-0.0059,0.00023,-0.0022,-0.0025,-0.13,0.21,-6.6e-05,0.44,-0.0051,0.002,-0.0072,0,0,-4.9e+02,7.9e-05,6.1e-05,0.0097,0.021,0.043,0.0053,0.07,0.087,0.031,3.2e-07,4e-07,1.3e-06,0.0039,0.0041,9.2e-05,0.00044,3.9e-05,0.00043,0.00041,0.00044,0.00042,1,1,0.01 +27990000,0.72,0.026,0.046,0.69,-2.7,-1.2,-1.2,0,0,-4.9e+02,-0.00093,-0.0059,0.00024,-0.002,-0.0015,-0.13,0.21,-8.2e-05,0.44,-0.0065,0.0014,-0.0071,0,0,-4.9e+02,8e-05,6.1e-05,0.0086,0.02,0.038,0.0053,0.072,0.087,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9.1e-05,0.00043,3.9e-05,0.00042,0.00037,0.00043,0.00042,1,1,0.01 +28090000,0.72,0.032,0.059,0.69,-2.8,-1.2,-1.2,0,0,-4.9e+02,-0.00093,-0.0059,0.00023,-0.0021,-0.0013,-0.13,0.21,-8.1e-05,0.44,-0.0066,0.0013,-0.0072,0,0,-4.9e+02,8.1e-05,6.1e-05,0.0086,0.021,0.039,0.0053,0.078,0.097,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9.1e-05,0.00042,3.9e-05,0.00042,0.00036,0.00042,0.00041,1,1,0.01 +28190000,0.72,0.037,0.072,0.69,-2.8,-1.2,-0.93,0,0,-4.9e+02,-0.00094,-0.0059,0.00024,-0.0022,-0.00082,-0.13,0.21,-9.9e-05,0.44,-0.0074,0.00088,-0.0071,0,0,-4.9e+02,8.1e-05,6.1e-05,0.0079,0.02,0.034,0.0053,0.08,0.097,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.00041,3.9e-05,0.00041,0.00033,0.00041,0.00041,1,1,0.01 +28290000,0.73,0.029,0.055,0.69,-2.8,-1.2,-0.069,0,0,-4.9e+02,-0.00093,-0.0059,0.00024,-0.0023,-0.0007,-0.13,0.21,-0.0001,0.44,-0.0075,0.0013,-0.0069,0,0,-4.9e+02,8.2e-05,6.1e-05,0.0079,0.02,0.035,0.0053,0.087,0.11,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 +28390000,0.73,0.012,0.024,0.69,-2.8,-1.2,0.79,0,0,-4.9e+02,-0.00094,-0.0059,0.00023,-0.0023,-0.0004,-0.13,0.21,-8.9e-05,0.44,-0.0076,0.0013,-0.007,0,0,-4.9e+02,8.3e-05,6.2e-05,0.0079,0.02,0.035,0.0054,0.094,0.12,0.03,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 +28490000,0.73,0.0028,0.0059,0.69,-2.8,-1.2,1.1,0,0,-4.9e+02,-0.00094,-0.0059,0.00023,-0.0019,-0.00011,-0.13,0.21,-7.1e-05,0.44,-0.0077,0.0014,-0.0069,0,0,-4.9e+02,8.4e-05,6.2e-05,0.0079,0.021,0.035,0.0054,0.1,0.13,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 +28590000,0.73,0.00088,0.0024,0.69,-2.7,-1.2,0.98,0,0,-4.9e+02,-0.00094,-0.0059,0.00024,-0.002,-4.1e-05,-0.13,0.21,-7.3e-05,0.44,-0.0076,0.0015,-0.0069,0,0,-4.9e+02,8.4e-05,6.2e-05,0.0079,0.021,0.033,0.0054,0.11,0.14,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.9e-05,0.0004,3.9e-05,0.0004,0.00033,0.0004,0.0004,1,1,0.01 +28690000,0.73,0.00018,0.0015,0.69,-2.6,-1.2,0.99,0,0,-4.9e+02,-0.00095,-0.0059,0.00024,-0.0017,0.00033,-0.13,0.21,-5.6e-05,0.44,-0.0077,0.0014,-0.0068,0,0,-4.9e+02,8.5e-05,6.2e-05,0.0079,0.022,0.033,0.0054,0.12,0.15,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.8e-05,0.0004,3.9e-05,0.0004,0.00033,0.00039,0.0004,1,1,0.01 +28790000,0.73,-2e-05,0.0014,0.69,-2.6,-1.2,0.99,0,0,-4.9e+02,-0.00098,-0.0059,0.00024,-0.0012,0.00059,-0.12,0.21,-9.7e-05,0.44,-0.0092,0.0006,-0.006,0,0,-4.9e+02,8.6e-05,6.2e-05,0.0075,0.021,0.028,0.0054,0.12,0.15,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.8e-05,0.00039,3.9e-05,0.0004,0.00031,0.00039,0.00039,1,1,0.01 +28890000,0.73,-1.1e-05,0.0016,0.69,-2.5,-1.2,0.98,0,0,-4.9e+02,-0.00099,-0.0059,0.00025,-0.00095,0.00094,-0.12,0.21,-8e-05,0.44,-0.0093,0.00056,-0.0059,0,0,-4.9e+02,8.6e-05,6.2e-05,0.0075,0.021,0.028,0.0054,0.13,0.16,0.031,3.1e-07,4e-07,1.3e-06,0.0039,0.0041,8.7e-05,0.00039,3.9e-05,0.0004,0.00031,0.00039,0.00039,1,1,0.01 +28990000,0.73,0.00034,0.0023,0.68,-2.5,-1.1,0.98,0,0,-4.9e+02,-0.001,-0.0059,0.00025,0.00033,0.0014,-0.12,0.21,-0.00011,0.44,-0.011,-0.00037,-0.0047,0,0,-4.9e+02,8.7e-05,6.2e-05,0.0073,0.02,0.025,0.0054,0.13,0.16,0.031,3e-07,4e-07,1.3e-06,0.0038,0.004,8.7e-05,0.00039,3.9e-05,0.0004,0.0003,0.00039,0.00039,1,1,0.01 +29090000,0.73,0.00051,0.0027,0.68,-2.4,-1.1,0.97,0,0,-4.9e+02,-0.001,-0.0059,0.00025,0.0005,0.0018,-0.12,0.21,-9.7e-05,0.44,-0.011,-0.00042,-0.0046,0,0,-4.9e+02,8.7e-05,6.2e-05,0.0073,0.021,0.025,0.0054,0.14,0.17,0.031,3e-07,4e-07,1.2e-06,0.0038,0.004,8.6e-05,0.00039,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 +29190000,0.73,0.00075,0.0031,0.68,-2.4,-1.1,0.97,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.00087,0.0019,-0.12,0.21,-0.00013,0.44,-0.011,-0.00065,-0.0042,0,0,-4.9e+02,8.8e-05,6.1e-05,0.0072,0.02,0.023,0.0054,0.14,0.17,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.6e-05,0.00038,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 +29290000,0.73,0.0011,0.0039,0.68,-2.3,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.00088,0.0024,-0.12,0.21,-0.00012,0.44,-0.011,-0.00073,-0.0041,0,0,-4.9e+02,8.8e-05,6.2e-05,0.0072,0.021,0.024,0.0054,0.14,0.18,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.0003,0.00038,0.00039,1,1,0.01 +29390000,0.73,0.0017,0.0054,0.68,-2.3,-1.1,1,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.0016,0.003,-0.12,0.21,-0.00016,0.44,-0.012,-0.0014,-0.0033,0,0,-4.9e+02,8.8e-05,6.1e-05,0.0071,0.02,0.023,0.0054,0.15,0.18,0.03,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.00029,0.00038,0.00039,1,1,0.01 +29490000,0.73,0.0022,0.0065,0.68,-2.3,-1.1,1,0,0,-4.9e+02,-0.0011,-0.0059,0.00027,0.0016,0.0033,-0.12,0.21,-0.00015,0.44,-0.012,-0.0014,-0.0033,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.024,0.0054,0.15,0.19,0.031,3e-07,3.9e-07,1.2e-06,0.0038,0.004,8.5e-05,0.00038,3.9e-05,0.00039,0.00029,0.00038,0.00039,1,1,0.01 +29590000,0.73,0.0027,0.0075,0.68,-2.2,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.0022,0.0033,-0.12,0.21,-0.00016,0.44,-0.012,-0.0016,-0.0029,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.02,0.023,0.0054,0.15,0.19,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.4e-05,0.00038,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 +29690000,0.73,0.003,0.0081,0.68,-2.2,-1.1,0.99,0,0,-4.9e+02,-0.0011,-0.0059,0.00026,0.0021,0.0037,-0.12,0.21,-0.00016,0.44,-0.012,-0.0017,-0.0029,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.024,0.0054,0.16,0.2,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.4e-05,0.00038,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 29790000,0.73,0.0034,0.0086,0.68,-2.2,-1.1,0.98,0,0,-4.9e+02,-0.0012,-0.0059,0.00025,0.0031,0.0036,-0.12,0.21,-0.00018,0.44,-0.013,-0.0019,-0.0023,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.02,0.023,0.0054,0.16,0.2,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.3e-05,0.00037,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 29890000,0.73,0.0034,0.0087,0.68,-2.1,-1.1,0.96,0,0,-4.9e+02,-0.0012,-0.0059,0.00025,0.0028,0.0042,-0.12,0.21,-0.00018,0.44,-0.013,-0.002,-0.0023,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.025,0.0054,0.17,0.21,0.031,2.9e-07,3.8e-07,1.2e-06,0.0038,0.004,8.3e-05,0.00037,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 -29990000,0.73,0.0036,0.0088,0.68,-2.1,-1.1,0.95,0,0,-4.9e+02,-0.0012,-0.0059,0.00023,0.0032,0.0039,-0.12,0.21,-0.0002,0.44,-0.013,-0.0022,-0.002,0,0,-4.9e+02,8.8e-05,6e-05,0.0071,0.02,0.024,0.0053,0.17,0.21,0.03,2.9e-07,3.7e-07,1.2e-06,0.0038,0.0039,8.2e-05,0.00037,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 -30090000,0.73,0.0035,0.0087,0.68,-2.1,-1.1,0.94,0,0,-4.9e+02,-0.0012,-0.0059,0.00023,0.0029,0.0043,-0.12,0.21,-0.0002,0.44,-0.013,-0.0022,-0.002,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.025,0.0054,0.18,0.22,0.03,2.9e-07,3.7e-07,1.2e-06,0.0038,0.0039,8.2e-05,0.00037,3.9e-05,0.00039,0.00028,0.00037,0.00038,1,1,0.01 +29990000,0.73,0.0036,0.0088,0.68,-2.1,-1.1,0.95,0,0,-4.9e+02,-0.0012,-0.0059,0.00023,0.0033,0.0039,-0.12,0.21,-0.0002,0.44,-0.013,-0.0022,-0.002,0,0,-4.9e+02,8.8e-05,6e-05,0.0071,0.02,0.024,0.0053,0.17,0.21,0.03,2.9e-07,3.7e-07,1.2e-06,0.0038,0.0039,8.2e-05,0.00037,3.9e-05,0.00039,0.00029,0.00037,0.00038,1,1,0.01 +30090000,0.73,0.0035,0.0087,0.68,-2.1,-1.1,0.94,0,0,-4.9e+02,-0.0012,-0.0059,0.00023,0.0029,0.0043,-0.12,0.21,-0.00021,0.44,-0.013,-0.0023,-0.002,0,0,-4.9e+02,8.9e-05,6.1e-05,0.0071,0.021,0.025,0.0054,0.18,0.22,0.03,2.9e-07,3.7e-07,1.2e-06,0.0038,0.0039,8.2e-05,0.00037,3.9e-05,0.00039,0.00028,0.00037,0.00038,1,1,0.01 30190000,0.73,0.0036,0.0084,0.68,-2.1,-1.1,0.92,0,0,-4.9e+02,-0.0012,-0.0059,0.00021,0.0037,0.0038,-0.12,0.21,-0.00022,0.44,-0.013,-0.0024,-0.0016,0,0,-4.9e+02,8.8e-05,6e-05,0.007,0.02,0.025,0.0053,0.18,0.22,0.031,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8.1e-05,0.00037,3.9e-05,0.00038,0.00028,0.00037,0.00038,1,1,0.01 -30290000,0.73,0.0034,0.0082,0.68,-2,-1.1,0.91,0,0,-4.9e+02,-0.0012,-0.0059,0.00021,0.0035,0.0041,-0.12,0.21,-0.00023,0.44,-0.013,-0.0024,-0.0016,0,0,-4.9e+02,8.8e-05,6.1e-05,0.007,0.021,0.026,0.0054,0.19,0.23,0.03,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8.1e-05,0.00037,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30390000,0.73,0.0035,0.0079,0.68,-2,-1.1,0.9,0,0,-4.9e+02,-0.0012,-0.0059,0.00019,0.0042,0.004,-0.12,0.21,-0.00022,0.43,-0.013,-0.0025,-0.0014,0,0,-4.9e+02,8.7e-05,6e-05,0.007,0.021,0.025,0.0053,0.19,0.23,0.03,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8.1e-05,0.00037,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30490000,0.73,0.0034,0.0077,0.68,-2,-1.1,0.88,0,0,-4.9e+02,-0.0012,-0.0059,0.0002,0.0041,0.0042,-0.12,0.21,-0.00022,0.43,-0.013,-0.0025,-0.0014,0,0,-4.9e+02,8.8e-05,6e-05,0.007,0.022,0.027,0.0054,0.2,0.24,0.031,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30590000,0.73,0.0034,0.0072,0.68,-1.9,-1,0.85,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.0049,0.0039,-0.12,0.21,-0.00024,0.43,-0.012,-0.0025,-0.001,0,0,-4.9e+02,8.6e-05,6e-05,0.0069,0.021,0.026,0.0053,0.2,0.24,0.03,2.8e-07,3.5e-07,1.1e-06,0.0037,0.0038,8e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30690000,0.73,0.0031,0.0069,0.68,-1.9,-1,0.84,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.0046,0.0043,-0.12,0.21,-0.00025,0.43,-0.012,-0.0025,-0.001,0,0,-4.9e+02,8.6e-05,6e-05,0.0069,0.022,0.028,0.0053,0.21,0.25,0.03,2.8e-07,3.5e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30790000,0.73,0.0031,0.0064,0.68,-1.9,-1,0.83,0,0,-4.9e+02,-0.0012,-0.0059,0.00015,0.0054,0.0037,-0.12,0.21,-0.00025,0.43,-0.012,-0.0026,-0.00079,0,0,-4.9e+02,8.4e-05,6e-05,0.0068,0.021,0.027,0.0053,0.21,0.25,0.03,2.8e-07,3.4e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.8e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 -30890000,0.73,0.003,0.006,0.68,-1.9,-1,0.82,0,0,-4.9e+02,-0.0012,-0.0059,0.00015,0.0054,0.0042,-0.12,0.21,-0.00024,0.43,-0.012,-0.0026,-0.00077,0,0,-4.9e+02,8.5e-05,6e-05,0.0068,0.022,0.029,0.0053,0.22,0.26,0.03,2.8e-07,3.4e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.8e-05,0.00038,0.00027,0.00036,0.00038,1,1,0.01 -30990000,0.73,0.003,0.0053,0.68,-1.8,-1,0.81,0,0,-4.9e+02,-0.0013,-0.0058,0.00012,0.0062,0.0037,-0.12,0.21,-0.00026,0.43,-0.012,-0.0027,-0.00042,0,0,-4.9e+02,8.3e-05,5.9e-05,0.0067,0.021,0.028,0.0053,0.22,0.26,0.03,2.7e-07,3.3e-07,1.1e-06,0.0037,0.0038,7.8e-05,0.00036,3.8e-05,0.00038,0.00027,0.00036,0.00038,1,1,0.01 -31090000,0.73,0.0027,0.0048,0.68,-1.8,-1,0.8,0,0,-4.9e+02,-0.0013,-0.0059,0.00012,0.006,0.0042,-0.12,0.21,-0.00026,0.43,-0.012,-0.0027,-0.00042,0,0,-4.9e+02,8.3e-05,6e-05,0.0067,0.022,0.03,0.0053,0.23,0.27,0.031,2.7e-07,3.3e-07,1.1e-06,0.0037,0.0038,7.8e-05,0.00036,3.8e-05,0.00038,0.00027,0.00036,0.00037,1,1,0.01 -31190000,0.73,0.0026,0.0044,0.68,-1.8,-1,0.79,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.0062,0.0042,-0.12,0.21,-0.00028,0.43,-0.011,-0.0028,-0.00025,0,0,-4.9e+02,8.1e-05,5.9e-05,0.0066,0.021,0.028,0.0053,0.23,0.27,0.03,2.7e-07,3.2e-07,1.1e-06,0.0037,0.0038,7.7e-05,0.00036,3.8e-05,0.00038,0.00027,0.00036,0.00037,1,1,0.01 -31290000,0.73,0.0023,0.0038,0.68,-1.8,-1,0.8,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.006,0.0047,-0.12,0.21,-0.00028,0.43,-0.011,-0.0028,-0.00028,0,0,-4.9e+02,8.2e-05,6e-05,0.0066,0.022,0.03,0.0053,0.24,0.28,0.03,2.7e-07,3.2e-07,1.1e-06,0.0037,0.0038,7.7e-05,0.00036,3.8e-05,0.00038,0.00027,0.00035,0.00037,1,1,0.01 -31390000,0.73,0.0022,0.0032,0.68,-1.7,-0.99,0.79,0,0,-4.9e+02,-0.0013,-0.0058,8.4e-05,0.0064,0.0046,-0.12,0.21,-0.00031,0.43,-0.011,-0.0028,-2.2e-05,0,0,-4.9e+02,7.9e-05,5.9e-05,0.0065,0.021,0.029,0.0053,0.24,0.28,0.03,2.7e-07,3.1e-07,1e-06,0.0037,0.0037,7.7e-05,0.00036,3.8e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 -31490000,0.73,0.002,0.0025,0.68,-1.7,-0.99,0.79,0,0,-4.9e+02,-0.0013,-0.0058,8.1e-05,0.0062,0.0052,-0.12,0.21,-0.0003,0.43,-0.011,-0.0029,1.4e-05,0,0,-4.9e+02,8e-05,5.9e-05,0.0065,0.022,0.031,0.0053,0.25,0.29,0.03,2.7e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.8e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 -31590000,0.73,0.002,0.002,0.68,-1.7,-0.97,0.79,0,0,-4.9e+02,-0.0013,-0.0058,5.4e-05,0.0071,0.0049,-0.12,0.21,-0.0003,0.43,-0.01,-0.0029,0.00026,0,0,-4.9e+02,7.8e-05,5.9e-05,0.0063,0.021,0.029,0.0053,0.25,0.29,0.03,2.6e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.8e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 -31690000,0.73,0.0017,0.0013,0.68,-1.6,-0.97,0.79,0,0,-4.9e+02,-0.0013,-0.0058,5.6e-05,0.0068,0.0053,-0.12,0.21,-0.0003,0.43,-0.01,-0.0029,0.00022,0,0,-4.9e+02,7.8e-05,5.9e-05,0.0063,0.022,0.031,0.0053,0.26,0.3,0.03,2.6e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.8e-05,0.00037,0.00026,0.00035,0.00037,1,1,0.01 -31790000,0.73,0.0016,0.00054,0.69,-1.6,-0.95,0.79,0,0,-4.9e+02,-0.0013,-0.0058,3.1e-05,0.0078,0.0053,-0.12,0.21,-0.0003,0.43,-0.0099,-0.0029,0.00056,0,0,-4.9e+02,7.6e-05,5.9e-05,0.0062,0.021,0.029,0.0052,0.26,0.3,0.03,2.6e-07,3e-07,1e-06,0.0037,0.0037,7.5e-05,0.00036,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -31890000,0.73,0.0013,-0.00018,0.69,-1.6,-0.95,0.79,0,0,-4.9e+02,-0.0013,-0.0058,3.2e-05,0.0076,0.0058,-0.12,0.21,-0.0003,0.43,-0.0099,-0.003,0.00059,0,0,-4.9e+02,7.6e-05,5.9e-05,0.0062,0.022,0.031,0.0053,0.27,0.31,0.03,2.6e-07,3e-07,1e-06,0.0037,0.0037,7.5e-05,0.00036,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -31990000,0.73,0.0012,-0.00078,0.69,-1.6,-0.93,0.78,0,0,-4.9e+02,-0.0013,-0.0058,1.8e-07,0.0081,0.0058,-0.12,0.21,-0.0003,0.43,-0.0094,-0.003,0.00076,0,0,-4.9e+02,7.4e-05,5.8e-05,0.006,0.021,0.03,0.0052,0.27,0.31,0.03,2.6e-07,2.9e-07,9.8e-07,0.0036,0.0037,7.5e-05,0.00036,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -32090000,0.73,0.00086,-0.0015,0.69,-1.5,-0.93,0.79,0,0,-4.9e+02,-0.0013,-0.0058,-4.5e-07,0.0079,0.0064,-0.12,0.21,-0.0003,0.43,-0.0094,-0.003,0.00077,0,0,-4.9e+02,7.5e-05,5.9e-05,0.006,0.022,0.032,0.0053,0.28,0.32,0.03,2.6e-07,2.9e-07,9.8e-07,0.0036,0.0037,7.4e-05,0.00035,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -32190000,0.73,0.00066,-0.0025,0.69,-1.5,-0.91,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-3.5e-05,0.0084,0.0065,-0.12,0.2,-0.00031,0.43,-0.009,-0.0031,0.001,0,0,-4.9e+02,7.3e-05,5.8e-05,0.0059,0.021,0.03,0.0052,0.28,0.32,0.03,2.6e-07,2.9e-07,9.6e-07,0.0036,0.0036,7.4e-05,0.00035,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -32290000,0.73,0.00038,-0.0032,0.69,-1.5,-0.91,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-3.4e-05,0.0081,0.0072,-0.12,0.2,-0.00031,0.43,-0.009,-0.0031,0.001,0,0,-4.9e+02,7.3e-05,5.8e-05,0.0059,0.022,0.032,0.0052,0.29,0.33,0.03,2.6e-07,2.9e-07,9.5e-07,0.0036,0.0036,7.4e-05,0.00035,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 -32390000,0.73,0.00029,-0.004,0.69,-1.5,-0.89,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-5.2e-05,0.0086,0.0071,-0.12,0.2,-0.0003,0.43,-0.0086,-0.0031,0.0012,0,0,-4.9e+02,7.1e-05,5.8e-05,0.0057,0.021,0.03,0.0052,0.29,0.33,0.03,2.5e-07,2.8e-07,9.4e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 -32490000,0.73,0.00014,-0.0042,0.69,-1.4,-0.88,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-5e-05,0.0084,0.0077,-0.12,0.2,-0.0003,0.43,-0.0085,-0.0031,0.0012,0,0,-4.9e+02,7.2e-05,5.8e-05,0.0057,0.022,0.032,0.0052,0.3,0.34,0.03,2.5e-07,2.8e-07,9.3e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 -32590000,0.72,0.00019,-0.0045,0.69,-1.4,-0.87,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-7.1e-05,0.0087,0.0077,-0.12,0.21,-0.00031,0.43,-0.0082,-0.0031,0.0013,0,0,-4.9e+02,7e-05,5.8e-05,0.0056,0.021,0.03,0.0052,0.3,0.34,0.03,2.5e-07,2.8e-07,9.1e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 -32690000,0.72,0.00016,-0.0046,0.69,-1.4,-0.86,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-7.1e-05,0.0087,0.0082,-0.12,0.2,-0.00031,0.43,-0.0081,-0.0032,0.0014,0,0,-4.9e+02,7e-05,5.8e-05,0.0056,0.022,0.032,0.0052,0.31,0.35,0.03,2.5e-07,2.8e-07,9.1e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 -32790000,0.72,0.00028,-0.0046,0.69,-1.3,-0.84,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-9.1e-05,0.009,0.0082,-0.12,0.2,-0.00031,0.43,-0.0078,-0.0032,0.0015,0,0,-4.9e+02,6.8e-05,5.7e-05,0.0054,0.022,0.03,0.0052,0.3,0.35,0.03,2.5e-07,2.7e-07,8.9e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 -32890000,0.72,0.00036,-0.0046,0.69,-1.3,-0.84,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-0.0001,0.0089,0.0089,-0.12,0.2,-0.00031,0.43,-0.0078,-0.0032,0.0016,0,0,-4.9e+02,6.9e-05,5.8e-05,0.0054,0.022,0.031,0.0052,0.32,0.36,0.03,2.5e-07,2.7e-07,8.9e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 -32990000,0.72,0.00058,-0.0047,0.69,-1.3,-0.82,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.0093,0.0092,-0.11,0.2,-0.00031,0.43,-0.0073,-0.0032,0.0017,0,0,-4.9e+02,6.7e-05,5.7e-05,0.0052,0.021,0.029,0.0051,0.31,0.36,0.03,2.5e-07,2.7e-07,8.7e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 -33090000,0.72,0.00054,-0.0047,0.69,-1.3,-0.82,0.77,0,0,-4.9e+02,-0.0014,-0.0057,-9.8e-05,0.0091,0.0095,-0.11,0.21,-0.00031,0.43,-0.0073,-0.0032,0.0017,0,0,-4.9e+02,6.8e-05,5.7e-05,0.0053,0.022,0.031,0.0052,0.33,0.37,0.03,2.5e-07,2.7e-07,8.7e-07,0.0036,0.0036,7.1e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 -33190000,0.72,0.004,-0.0039,0.7,-1.2,-0.8,0.72,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.0092,0.0095,-0.11,0.21,-0.00031,0.43,-0.0069,-0.0032,0.0017,0,0,-4.9e+02,6.6e-05,5.7e-05,0.0051,0.022,0.029,0.0051,0.32,0.37,0.03,2.4e-07,2.6e-07,8.5e-07,0.0036,0.0035,7.1e-05,0.00035,3.8e-05,0.00037,0.00022,0.00035,0.00036,1,1,0.01 -33290000,0.67,0.016,-0.0033,0.74,-1.2,-0.78,0.7,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.009,0.0099,-0.11,0.2,-0.00029,0.43,-0.0071,-0.0033,0.0017,0,0,-4.9e+02,6.6e-05,5.7e-05,0.0051,0.022,0.031,0.0051,0.34,0.38,0.03,2.4e-07,2.6e-07,8.5e-07,0.0036,0.0035,7.1e-05,0.00035,3.8e-05,0.00037,0.00022,0.00035,0.00036,1,1,0.01 -33390000,0.56,0.014,-0.0036,0.83,-1.2,-0.77,0.89,0,0,-4.9e+02,-0.0014,-0.0057,-0.00012,0.0092,0.01,-0.11,0.21,-0.00035,0.43,-0.0064,-0.0032,0.0018,0,0,-4.9e+02,6.5e-05,5.6e-05,0.0047,0.021,0.028,0.0051,0.33,0.38,0.03,2.4e-07,2.6e-07,8.3e-07,0.0036,0.0035,7e-05,0.00032,3.8e-05,0.00036,0.00021,0.00032,0.00036,1,1,0.01 -33490000,0.43,0.0071,-0.0011,0.9,-1.2,-0.76,0.91,0,0,-4.9e+02,-0.0014,-0.0057,-0.00014,0.0092,0.01,-0.11,0.21,-0.00044,0.43,-0.0059,-0.002,0.0019,0,0,-4.9e+02,6.5e-05,5.6e-05,0.0041,0.022,0.029,0.0051,0.34,0.38,0.03,2.4e-07,2.6e-07,8.1e-07,0.0036,0.0035,7.1e-05,0.00025,3.7e-05,0.00036,0.00017,0.00024,0.00036,1,1,0.01 -33590000,0.27,0.001,-0.0036,0.96,-1.2,-0.75,0.87,0,0,-4.9e+02,-0.0014,-0.0057,-0.00017,0.0092,0.01,-0.11,0.21,-0.00068,0.43,-0.0039,-0.0014,0.002,0,0,-4.9e+02,6.4e-05,5.5e-05,0.0031,0.02,0.027,0.0051,0.34,0.37,0.03,2.4e-07,2.6e-07,7.9e-07,0.0036,0.0035,7.1e-05,0.00016,3.6e-05,0.00036,0.00012,0.00015,0.00036,1,1,0.01 -33690000,0.098,-0.0026,-0.0066,1,-1.1,-0.74,0.88,0,0,-4.9e+02,-0.0014,-0.0057,-0.00018,0.0092,0.01,-0.11,0.21,-0.00074,0.43,-0.0036,-0.001,0.0021,0,0,-4.9e+02,6.4e-05,5.5e-05,0.0024,0.021,0.028,0.0051,0.35,0.37,0.03,2.4e-07,2.6e-07,7.8e-07,0.0036,0.0035,7.1e-05,0.0001,3.5e-05,0.00036,8.3e-05,9.8e-05,0.00036,1,1,0.01 -33790000,-0.074,-0.0044,-0.0084,1,-1.1,-0.72,0.86,0,0,-4.9e+02,-0.0014,-0.0057,-0.0002,0.0092,0.01,-0.11,0.21,-0.0009,0.43,-0.0021,-0.001,0.0023,0,0,-4.9e+02,6.2e-05,5.4e-05,0.0019,0.02,0.026,0.0051,0.35,0.37,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,6.8e-05,3.5e-05,0.00036,5.5e-05,6.1e-05,0.00036,1,1,0.01 -33890000,-0.24,-0.0058,-0.009,0.97,-1,-0.69,0.85,0,0,-4.9e+02,-0.0015,-0.0057,-0.00021,0.0092,0.01,-0.11,0.21,-0.001,0.43,-0.0013,-0.0011,0.0024,0,0,-4.9e+02,6.2e-05,5.4e-05,0.0016,0.022,0.028,0.0051,0.36,0.38,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,4.8e-05,3.4e-05,0.00036,3.8e-05,4.1e-05,0.00036,1,1,0.01 -33990000,-0.39,-0.0045,-0.012,0.92,-0.94,-0.64,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00021,0.0092,0.01,-0.11,0.21,-0.00099,0.43,-0.0011,-0.00064,0.0025,0,0,-4.9e+02,6e-05,5.3e-05,0.0015,0.021,0.027,0.0051,0.36,0.37,0.03,2.4e-07,2.5e-07,7.7e-07,0.0036,0.0035,7.1e-05,3.6e-05,3.4e-05,0.00036,2.8e-05,2.9e-05,0.00036,1,1,0.01 -34090000,-0.5,-0.0036,-0.014,0.87,-0.88,-0.59,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00021,0.0091,0.011,-0.11,0.21,-0.00097,0.43,-0.0013,-0.00052,0.0025,0,0,-4.9e+02,6e-05,5.3e-05,0.0014,0.023,0.03,0.0051,0.37,0.38,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,3e-05,3.4e-05,0.00036,2.2e-05,2.3e-05,0.00036,1,1,0.01 -34190000,-0.57,-0.0035,-0.012,0.82,-0.86,-0.54,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.0002,0.007,0.014,-0.11,0.21,-0.00096,0.43,-0.0011,-0.00031,0.0028,0,0,-4.9e+02,5.7e-05,5.1e-05,0.0013,0.023,0.029,0.0051,0.5,0.5,0.03,2.4e-07,2.5e-07,7.6e-07,0.0035,0.0035,7e-05,2.5e-05,3.4e-05,0.00036,1.8e-05,1.8e-05,0.00036,1,1,0.01 -34290000,-0.61,-0.0045,-0.0092,0.79,-0.8,-0.48,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.0002,0.0067,0.014,-0.11,0.21,-0.00098,0.43,-0.00094,-0.00018,0.0028,0,0,-4.9e+02,5.7e-05,5.1e-05,0.0012,0.025,0.032,0.0051,0.5,0.5,0.03,2.4e-07,2.5e-07,7.6e-07,0.0035,0.0035,7e-05,2.2e-05,3.4e-05,0.00036,1.5e-05,1.5e-05,0.00036,1,1,0.01 -34390000,-0.63,-0.0051,-0.0063,0.77,-0.78,-0.44,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00017,0.0035,0.018,-0.11,0.21,-0.00095,0.43,-0.00093,1.9e-05,0.0029,0,0,-4.9e+02,5.3e-05,4.9e-05,0.0012,0.025,0.031,0.0051,0.17,0.17,0.03,2.4e-07,2.5e-07,7.5e-07,0.0034,0.0035,7e-05,2e-05,3.3e-05,0.00036,1.3e-05,1.3e-05,0.00036,1,1,0.01 -34490000,-0.65,-0.006,-0.0041,0.76,-0.72,-0.39,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00017,0.0033,0.019,-0.11,0.21,-0.00096,0.43,-0.00087,-2.2e-05,0.003,0,0,-4.9e+02,5.3e-05,4.9e-05,0.0011,0.027,0.035,0.0051,0.17,0.17,0.03,2.4e-07,2.5e-07,7.5e-07,0.0034,0.0035,7e-05,1.8e-05,3.3e-05,0.00036,1.2e-05,1.2e-05,0.00036,1,1,0.01 -34590000,-0.66,-0.0061,-0.0026,0.75,-0.7,-0.37,0.82,0,0,-4.9e+02,-0.0015,-0.0058,-0.00014,-0.0016,0.024,-0.11,0.21,-0.00092,0.43,-0.00094,3e-05,0.0032,0,0,-4.9e+02,5e-05,4.6e-05,0.0011,0.027,0.034,0.0051,0.1,0.1,0.03,2.4e-07,2.5e-07,7.5e-07,0.0033,0.0034,6.9e-05,1.6e-05,3.3e-05,0.00036,1.1e-05,1e-05,0.00036,1,1,0.01 -34690000,-0.67,-0.0065,-0.0018,0.75,-0.65,-0.32,0.81,0,0,-4.9e+02,-0.0015,-0.0058,-0.00014,-0.0019,0.025,-0.11,0.21,-0.00094,0.43,-0.0008,0.00023,0.0031,0,0,-4.9e+02,5e-05,4.7e-05,0.0011,0.03,0.037,0.0051,0.1,0.1,0.03,2.4e-07,2.5e-07,7.5e-07,0.0033,0.0034,6.9e-05,1.6e-05,3.3e-05,0.00036,9.9e-06,9.4e-06,0.00036,1,1,0.01 -34790000,-0.67,-0.0058,-0.0012,0.74,-0.63,-0.31,0.81,0,0,-4.9e+02,-0.0015,-0.0058,-8.8e-05,-0.0093,0.032,-0.11,0.21,-0.00096,0.43,-0.00065,0.00032,0.0033,0,0,-4.9e+02,4.5e-05,4.4e-05,0.001,0.029,0.035,0.0051,0.074,0.075,0.03,2.4e-07,2.5e-07,7.4e-07,0.0032,0.0033,6.9e-05,1.4e-05,3.3e-05,0.00036,9.1e-06,8.6e-06,0.00036,1,1,0.01 +30290000,0.73,0.0034,0.0082,0.68,-2,-1.1,0.91,0,0,-4.9e+02,-0.0012,-0.0059,0.00021,0.0035,0.004,-0.12,0.21,-0.00023,0.44,-0.013,-0.0024,-0.0017,0,0,-4.9e+02,8.9e-05,6.1e-05,0.007,0.021,0.026,0.0054,0.19,0.23,0.03,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8.1e-05,0.00037,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30390000,0.73,0.0035,0.0079,0.68,-2,-1.1,0.9,0,0,-4.9e+02,-0.0012,-0.0059,0.00019,0.0043,0.004,-0.12,0.21,-0.00022,0.43,-0.013,-0.0025,-0.0014,0,0,-4.9e+02,8.7e-05,6e-05,0.007,0.021,0.025,0.0053,0.19,0.23,0.03,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8.1e-05,0.00037,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30490000,0.73,0.0034,0.0077,0.68,-2,-1.1,0.88,0,0,-4.9e+02,-0.0012,-0.0059,0.0002,0.0042,0.0042,-0.12,0.21,-0.00022,0.43,-0.013,-0.0025,-0.0014,0,0,-4.9e+02,8.8e-05,6e-05,0.007,0.022,0.027,0.0054,0.2,0.24,0.031,2.8e-07,3.6e-07,1.2e-06,0.0038,0.0039,8e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30590000,0.73,0.0034,0.0072,0.68,-1.9,-1,0.85,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.005,0.0039,-0.12,0.21,-0.00024,0.43,-0.012,-0.0025,-0.001,0,0,-4.9e+02,8.6e-05,6e-05,0.0069,0.021,0.026,0.0053,0.2,0.24,0.03,2.8e-07,3.5e-07,1.1e-06,0.0038,0.0038,8e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30690000,0.73,0.0031,0.0069,0.68,-1.9,-1,0.84,0,0,-4.9e+02,-0.0012,-0.0059,0.00018,0.0047,0.0043,-0.12,0.21,-0.00025,0.43,-0.012,-0.0025,-0.001,0,0,-4.9e+02,8.6e-05,6e-05,0.0069,0.022,0.028,0.0053,0.21,0.25,0.03,2.8e-07,3.5e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30790000,0.73,0.0031,0.0064,0.68,-1.9,-1,0.83,0,0,-4.9e+02,-0.0012,-0.0059,0.00015,0.0054,0.0037,-0.12,0.21,-0.00025,0.43,-0.012,-0.0026,-0.00079,0,0,-4.9e+02,8.4e-05,6e-05,0.0068,0.021,0.027,0.0053,0.21,0.25,0.03,2.8e-07,3.4e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.9e-05,0.00038,0.00028,0.00036,0.00038,1,1,0.01 +30890000,0.73,0.003,0.006,0.68,-1.9,-1,0.82,0,0,-4.9e+02,-0.0012,-0.0059,0.00015,0.0054,0.0041,-0.12,0.21,-0.00024,0.43,-0.012,-0.0026,-0.00077,0,0,-4.9e+02,8.5e-05,6e-05,0.0068,0.022,0.029,0.0053,0.22,0.26,0.03,2.8e-07,3.4e-07,1.1e-06,0.0037,0.0038,7.9e-05,0.00036,3.9e-05,0.00038,0.00027,0.00036,0.00038,1,1,0.01 +30990000,0.73,0.003,0.0053,0.68,-1.8,-1,0.81,0,0,-4.9e+02,-0.0013,-0.0058,0.00012,0.0063,0.0037,-0.12,0.21,-0.00026,0.43,-0.012,-0.0027,-0.00042,0,0,-4.9e+02,8.3e-05,5.9e-05,0.0067,0.021,0.028,0.0053,0.22,0.26,0.03,2.7e-07,3.3e-07,1.1e-06,0.0037,0.0038,7.8e-05,0.00036,3.9e-05,0.00038,0.00027,0.00036,0.00038,1,1,0.01 +31090000,0.73,0.0027,0.0048,0.68,-1.8,-1,0.8,0,0,-4.9e+02,-0.0013,-0.0059,0.00012,0.006,0.0042,-0.12,0.21,-0.00026,0.43,-0.012,-0.0027,-0.00043,0,0,-4.9e+02,8.3e-05,6e-05,0.0067,0.022,0.03,0.0053,0.23,0.27,0.031,2.7e-07,3.3e-07,1.1e-06,0.0037,0.0038,7.8e-05,0.00036,3.9e-05,0.00038,0.00027,0.00036,0.00037,1,1,0.01 +31190000,0.73,0.0026,0.0044,0.68,-1.8,-1,0.79,0,0,-4.9e+02,-0.0013,-0.0058,0.0001,0.0063,0.0042,-0.12,0.21,-0.00028,0.43,-0.011,-0.0028,-0.00025,0,0,-4.9e+02,8.1e-05,5.9e-05,0.0066,0.021,0.028,0.0053,0.23,0.27,0.03,2.7e-07,3.2e-07,1.1e-06,0.0037,0.0038,7.7e-05,0.00036,3.9e-05,0.00038,0.00027,0.00035,0.00037,1,1,0.01 +31290000,0.73,0.0023,0.0038,0.68,-1.8,-1,0.8,0,0,-4.9e+02,-0.0013,-0.0058,0.00011,0.006,0.0046,-0.12,0.21,-0.00028,0.43,-0.011,-0.0028,-0.00028,0,0,-4.9e+02,8.2e-05,6e-05,0.0066,0.022,0.03,0.0053,0.24,0.28,0.03,2.7e-07,3.2e-07,1.1e-06,0.0037,0.0038,7.7e-05,0.00036,3.9e-05,0.00038,0.00027,0.00035,0.00037,1,1,0.01 +31390000,0.73,0.0022,0.0031,0.68,-1.7,-0.99,0.79,0,0,-4.9e+02,-0.0013,-0.0058,8.4e-05,0.0064,0.0045,-0.12,0.21,-0.00031,0.43,-0.011,-0.0028,-2.4e-05,0,0,-4.9e+02,7.9e-05,5.9e-05,0.0065,0.021,0.029,0.0053,0.24,0.28,0.03,2.7e-07,3.1e-07,1e-06,0.0037,0.0037,7.7e-05,0.00036,3.9e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 +31490000,0.73,0.002,0.0025,0.68,-1.7,-0.99,0.79,0,0,-4.9e+02,-0.0013,-0.0058,8e-05,0.0063,0.0051,-0.12,0.21,-0.00031,0.43,-0.011,-0.0029,1.2e-05,0,0,-4.9e+02,8e-05,5.9e-05,0.0065,0.022,0.031,0.0053,0.25,0.29,0.03,2.7e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.9e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 +31590000,0.73,0.002,0.002,0.68,-1.7,-0.97,0.79,0,0,-4.9e+02,-0.0013,-0.0058,5.4e-05,0.0072,0.0049,-0.12,0.21,-0.0003,0.43,-0.01,-0.0029,0.00025,0,0,-4.9e+02,7.8e-05,5.9e-05,0.0063,0.021,0.029,0.0053,0.25,0.29,0.03,2.6e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.9e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 +31690000,0.73,0.0017,0.0013,0.68,-1.6,-0.97,0.79,0,0,-4.9e+02,-0.0013,-0.0058,5.6e-05,0.0068,0.0053,-0.12,0.21,-0.0003,0.43,-0.01,-0.0029,0.00022,0,0,-4.9e+02,7.8e-05,5.9e-05,0.0063,0.022,0.031,0.0053,0.26,0.3,0.03,2.6e-07,3.1e-07,1e-06,0.0037,0.0037,7.6e-05,0.00036,3.9e-05,0.00038,0.00026,0.00035,0.00037,1,1,0.01 +31790000,0.73,0.0016,0.00054,0.69,-1.6,-0.95,0.79,0,0,-4.9e+02,-0.0013,-0.0058,3.1e-05,0.0078,0.0052,-0.12,0.21,-0.00031,0.43,-0.0099,-0.003,0.00056,0,0,-4.9e+02,7.6e-05,5.9e-05,0.0062,0.021,0.029,0.0052,0.26,0.3,0.03,2.6e-07,3e-07,1e-06,0.0037,0.0037,7.5e-05,0.00036,3.9e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +31890000,0.73,0.0013,-0.00019,0.69,-1.6,-0.95,0.79,0,0,-4.9e+02,-0.0013,-0.0058,3.2e-05,0.0077,0.0058,-0.12,0.21,-0.0003,0.43,-0.0099,-0.003,0.00059,0,0,-4.9e+02,7.6e-05,5.9e-05,0.0062,0.022,0.031,0.0053,0.27,0.31,0.03,2.6e-07,3e-07,1e-06,0.0037,0.0037,7.5e-05,0.00036,3.9e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +31990000,0.73,0.0012,-0.00079,0.69,-1.6,-0.93,0.78,0,0,-4.9e+02,-0.0013,-0.0058,9e-08,0.0082,0.0057,-0.12,0.2,-0.0003,0.43,-0.0094,-0.003,0.00076,0,0,-4.9e+02,7.4e-05,5.8e-05,0.006,0.021,0.03,0.0052,0.27,0.31,0.03,2.6e-07,2.9e-07,9.8e-07,0.0037,0.0037,7.5e-05,0.00035,3.9e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +32090000,0.73,0.00086,-0.0015,0.69,-1.5,-0.93,0.79,0,0,-4.9e+02,-0.0013,-0.0058,-5.5e-07,0.008,0.0063,-0.12,0.21,-0.0003,0.43,-0.0094,-0.003,0.00077,0,0,-4.9e+02,7.5e-05,5.9e-05,0.006,0.022,0.032,0.0053,0.28,0.32,0.03,2.6e-07,2.9e-07,9.8e-07,0.0036,0.0037,7.4e-05,0.00035,3.9e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +32190000,0.73,0.00066,-0.0025,0.69,-1.5,-0.91,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-3.5e-05,0.0084,0.0065,-0.12,0.2,-0.00031,0.43,-0.009,-0.0031,0.001,0,0,-4.9e+02,7.3e-05,5.8e-05,0.0059,0.021,0.03,0.0052,0.28,0.32,0.03,2.6e-07,2.9e-07,9.6e-07,0.0036,0.0036,7.4e-05,0.00035,3.9e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +32290000,0.73,0.00038,-0.0032,0.69,-1.5,-0.91,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-3.4e-05,0.0082,0.0071,-0.12,0.2,-0.00031,0.43,-0.009,-0.0031,0.001,0,0,-4.9e+02,7.3e-05,5.8e-05,0.0059,0.022,0.032,0.0052,0.29,0.33,0.03,2.6e-07,2.9e-07,9.5e-07,0.0036,0.0036,7.4e-05,0.00035,3.8e-05,0.00037,0.00025,0.00035,0.00037,1,1,0.01 +32390000,0.73,0.00029,-0.004,0.69,-1.5,-0.89,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-5.2e-05,0.0087,0.0071,-0.12,0.2,-0.0003,0.43,-0.0085,-0.0031,0.0012,0,0,-4.9e+02,7.1e-05,5.8e-05,0.0057,0.021,0.03,0.0052,0.29,0.33,0.03,2.5e-07,2.8e-07,9.4e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 +32490000,0.73,0.00014,-0.0042,0.69,-1.4,-0.88,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-5e-05,0.0084,0.0076,-0.12,0.2,-0.0003,0.43,-0.0085,-0.0031,0.0012,0,0,-4.9e+02,7.2e-05,5.8e-05,0.0057,0.022,0.032,0.0052,0.3,0.34,0.03,2.5e-07,2.8e-07,9.3e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 +32590000,0.72,0.00019,-0.0045,0.69,-1.4,-0.87,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-7.1e-05,0.0088,0.0077,-0.12,0.2,-0.00031,0.43,-0.0081,-0.0031,0.0013,0,0,-4.9e+02,7e-05,5.8e-05,0.0056,0.021,0.03,0.0052,0.3,0.34,0.03,2.5e-07,2.8e-07,9.1e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 +32690000,0.72,0.00016,-0.0046,0.69,-1.4,-0.86,0.79,0,0,-4.9e+02,-0.0014,-0.0058,-7.1e-05,0.0087,0.0081,-0.12,0.2,-0.00031,0.43,-0.0081,-0.0032,0.0014,0,0,-4.9e+02,7e-05,5.8e-05,0.0056,0.022,0.032,0.0052,0.31,0.35,0.03,2.5e-07,2.8e-07,9.1e-07,0.0036,0.0036,7.3e-05,0.00035,3.8e-05,0.00037,0.00024,0.00035,0.00037,1,1,0.01 +32790000,0.72,0.00028,-0.0047,0.69,-1.3,-0.84,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-9.1e-05,0.0091,0.0082,-0.12,0.2,-0.00031,0.43,-0.0077,-0.0032,0.0015,0,0,-4.9e+02,6.8e-05,5.7e-05,0.0054,0.022,0.03,0.0052,0.3,0.35,0.03,2.5e-07,2.7e-07,8.9e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 +32890000,0.72,0.00036,-0.0046,0.69,-1.3,-0.84,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-0.0001,0.009,0.0089,-0.12,0.2,-0.00031,0.43,-0.0078,-0.0032,0.0016,0,0,-4.9e+02,6.9e-05,5.8e-05,0.0054,0.022,0.031,0.0052,0.32,0.36,0.03,2.5e-07,2.7e-07,8.9e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 +32990000,0.72,0.00058,-0.0047,0.69,-1.3,-0.82,0.78,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.0094,0.0092,-0.11,0.2,-0.00031,0.43,-0.0073,-0.0032,0.0017,0,0,-4.9e+02,6.7e-05,5.7e-05,0.0052,0.021,0.029,0.0051,0.31,0.36,0.03,2.5e-07,2.7e-07,8.7e-07,0.0036,0.0036,7.2e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 +33090000,0.72,0.00054,-0.0047,0.69,-1.3,-0.82,0.77,0,0,-4.9e+02,-0.0014,-0.0057,-9.8e-05,0.0092,0.0095,-0.11,0.2,-0.00031,0.43,-0.0073,-0.0032,0.0017,0,0,-4.9e+02,6.8e-05,5.7e-05,0.0052,0.022,0.031,0.0052,0.33,0.37,0.03,2.5e-07,2.7e-07,8.7e-07,0.0036,0.0036,7.1e-05,0.00035,3.8e-05,0.00037,0.00023,0.00035,0.00036,1,1,0.01 +33190000,0.72,0.004,-0.0039,0.7,-1.2,-0.8,0.72,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.0093,0.0095,-0.11,0.21,-0.00031,0.43,-0.0069,-0.0032,0.0017,0,0,-4.9e+02,6.6e-05,5.7e-05,0.0051,0.022,0.029,0.0051,0.32,0.37,0.03,2.4e-07,2.6e-07,8.5e-07,0.0036,0.0035,7.1e-05,0.00035,3.8e-05,0.00037,0.00022,0.00035,0.00036,1,1,0.01 +33290000,0.67,0.016,-0.0033,0.74,-1.2,-0.78,0.7,0,0,-4.9e+02,-0.0014,-0.0057,-0.00011,0.0091,0.0098,-0.11,0.2,-0.00029,0.43,-0.0071,-0.0033,0.0017,0,0,-4.9e+02,6.6e-05,5.7e-05,0.0051,0.022,0.031,0.0051,0.34,0.38,0.03,2.4e-07,2.6e-07,8.5e-07,0.0036,0.0035,7.1e-05,0.00035,3.8e-05,0.00037,0.00022,0.00035,0.00036,1,1,0.01 +33390000,0.56,0.014,-0.0036,0.83,-1.2,-0.77,0.89,0,0,-4.9e+02,-0.0014,-0.0057,-0.00012,0.0093,0.01,-0.11,0.21,-0.00036,0.43,-0.0064,-0.0032,0.0018,0,0,-4.9e+02,6.5e-05,5.6e-05,0.0047,0.021,0.028,0.0051,0.33,0.37,0.03,2.4e-07,2.6e-07,8.3e-07,0.0036,0.0035,7e-05,0.00032,3.8e-05,0.00036,0.00021,0.00032,0.00036,1,1,0.01 +33490000,0.43,0.0071,-0.0011,0.9,-1.2,-0.76,0.91,0,0,-4.9e+02,-0.0014,-0.0057,-0.00014,0.0093,0.01,-0.11,0.21,-0.00044,0.43,-0.0059,-0.0021,0.0019,0,0,-4.9e+02,6.5e-05,5.6e-05,0.0041,0.022,0.029,0.0051,0.34,0.38,0.03,2.4e-07,2.6e-07,8.1e-07,0.0036,0.0035,7.1e-05,0.00025,3.7e-05,0.00036,0.00017,0.00024,0.00036,1,1,0.01 +33590000,0.27,0.001,-0.0036,0.96,-1.2,-0.75,0.87,0,0,-4.9e+02,-0.0014,-0.0057,-0.00017,0.0093,0.01,-0.11,0.21,-0.00069,0.43,-0.0039,-0.0014,0.002,0,0,-4.9e+02,6.4e-05,5.5e-05,0.0031,0.02,0.027,0.0051,0.34,0.37,0.03,2.4e-07,2.6e-07,7.9e-07,0.0036,0.0035,7.1e-05,0.00016,3.6e-05,0.00036,0.00012,0.00015,0.00036,1,1,0.01 +33690000,0.098,-0.0026,-0.0066,1,-1.1,-0.74,0.88,0,0,-4.9e+02,-0.0014,-0.0057,-0.00018,0.0093,0.01,-0.11,0.21,-0.00074,0.43,-0.0036,-0.001,0.0021,0,0,-4.9e+02,6.4e-05,5.5e-05,0.0024,0.021,0.028,0.0051,0.35,0.37,0.03,2.4e-07,2.6e-07,7.8e-07,0.0036,0.0035,7.1e-05,0.0001,3.5e-05,0.00036,8.3e-05,9.8e-05,0.00036,1,1,0.01 +33790000,-0.074,-0.0044,-0.0084,1,-1.1,-0.72,0.86,0,0,-4.9e+02,-0.0014,-0.0057,-0.0002,0.0093,0.01,-0.11,0.21,-0.0009,0.43,-0.0021,-0.001,0.0023,0,0,-4.9e+02,6.2e-05,5.4e-05,0.0019,0.02,0.026,0.0051,0.35,0.37,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,6.8e-05,3.5e-05,0.00036,5.5e-05,6.1e-05,0.00036,1,1,0.01 +33890000,-0.24,-0.0058,-0.009,0.97,-1,-0.69,0.85,0,0,-4.9e+02,-0.0014,-0.0057,-0.00021,0.0093,0.01,-0.11,0.21,-0.001,0.43,-0.0013,-0.0011,0.0024,0,0,-4.9e+02,6.2e-05,5.4e-05,0.0016,0.022,0.028,0.0051,0.36,0.38,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,4.8e-05,3.4e-05,0.00036,3.8e-05,4.1e-05,0.00036,1,1,0.01 +33990000,-0.39,-0.0045,-0.012,0.92,-0.94,-0.64,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00021,0.0092,0.01,-0.11,0.21,-0.001,0.43,-0.0011,-0.00064,0.0025,0,0,-4.9e+02,6e-05,5.3e-05,0.0015,0.021,0.027,0.0051,0.36,0.37,0.03,2.4e-07,2.5e-07,7.7e-07,0.0036,0.0035,7.1e-05,3.6e-05,3.4e-05,0.00036,2.8e-05,2.9e-05,0.00036,1,1,0.01 +34090000,-0.5,-0.0036,-0.014,0.87,-0.88,-0.59,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00021,0.0092,0.011,-0.11,0.21,-0.00097,0.43,-0.0013,-0.00053,0.0025,0,0,-4.9e+02,6e-05,5.3e-05,0.0014,0.023,0.03,0.0051,0.37,0.38,0.03,2.4e-07,2.6e-07,7.7e-07,0.0036,0.0035,7.1e-05,3e-05,3.4e-05,0.00036,2.2e-05,2.3e-05,0.00036,1,1,0.01 +34190000,-0.57,-0.0035,-0.012,0.82,-0.86,-0.54,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.0002,0.007,0.014,-0.11,0.21,-0.00097,0.43,-0.0011,-0.00031,0.0028,0,0,-4.9e+02,5.7e-05,5.1e-05,0.0013,0.023,0.029,0.0051,0.5,0.5,0.03,2.4e-07,2.5e-07,7.6e-07,0.0035,0.0035,7e-05,2.5e-05,3.4e-05,0.00036,1.8e-05,1.8e-05,0.00036,1,1,0.01 +34290000,-0.61,-0.0045,-0.0092,0.79,-0.8,-0.48,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.0002,0.0067,0.014,-0.11,0.21,-0.00098,0.43,-0.00093,-0.00018,0.0028,0,0,-4.9e+02,5.7e-05,5.1e-05,0.0012,0.025,0.032,0.0051,0.5,0.5,0.03,2.4e-07,2.5e-07,7.6e-07,0.0035,0.0035,7e-05,2.2e-05,3.4e-05,0.00036,1.5e-05,1.5e-05,0.00036,1,1,0.01 +34390000,-0.63,-0.0051,-0.0063,0.77,-0.78,-0.44,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00017,0.0036,0.018,-0.11,0.21,-0.00095,0.43,-0.00093,1.7e-05,0.0029,0,0,-4.9e+02,5.3e-05,4.9e-05,0.0012,0.025,0.031,0.0051,0.17,0.17,0.03,2.4e-07,2.5e-07,7.5e-07,0.0034,0.0035,7e-05,2e-05,3.3e-05,0.00036,1.3e-05,1.3e-05,0.00036,1,1,0.01 +34490000,-0.65,-0.006,-0.0041,0.76,-0.72,-0.39,0.82,0,0,-4.9e+02,-0.0015,-0.0057,-0.00017,0.0034,0.019,-0.11,0.21,-0.00096,0.43,-0.00087,-2.3e-05,0.003,0,0,-4.9e+02,5.3e-05,4.9e-05,0.0011,0.027,0.035,0.0051,0.17,0.17,0.03,2.4e-07,2.5e-07,7.5e-07,0.0034,0.0035,7e-05,1.8e-05,3.3e-05,0.00036,1.2e-05,1.2e-05,0.00036,1,1,0.01 +34590000,-0.66,-0.0061,-0.0027,0.75,-0.7,-0.37,0.82,0,0,-4.9e+02,-0.0015,-0.0058,-0.00014,-0.0015,0.024,-0.11,0.21,-0.00092,0.43,-0.00094,2.9e-05,0.0032,0,0,-4.9e+02,5e-05,4.7e-05,0.0011,0.027,0.034,0.0051,0.1,0.1,0.03,2.4e-07,2.5e-07,7.5e-07,0.0033,0.0034,6.9e-05,1.6e-05,3.3e-05,0.00036,1.1e-05,1e-05,0.00036,1,1,0.01 +34690000,-0.67,-0.0065,-0.0018,0.75,-0.65,-0.32,0.81,0,0,-4.9e+02,-0.0015,-0.0058,-0.00014,-0.0018,0.025,-0.11,0.21,-0.00094,0.43,-0.0008,0.00023,0.0031,0,0,-4.9e+02,5e-05,4.7e-05,0.0011,0.03,0.037,0.0051,0.1,0.1,0.03,2.4e-07,2.5e-07,7.5e-07,0.0033,0.0034,6.9e-05,1.6e-05,3.3e-05,0.00036,9.9e-06,9.4e-06,0.00036,1,1,0.01 +34790000,-0.67,-0.0058,-0.0012,0.74,-0.63,-0.31,0.81,0,0,-4.9e+02,-0.0015,-0.0058,-8.8e-05,-0.0092,0.032,-0.11,0.21,-0.00096,0.43,-0.00065,0.00032,0.0033,0,0,-4.9e+02,4.5e-05,4.4e-05,0.001,0.029,0.035,0.0051,0.074,0.075,0.03,2.4e-07,2.5e-07,7.4e-07,0.0032,0.0033,6.9e-05,1.4e-05,3.3e-05,0.00036,9.1e-06,8.6e-06,0.00036,1,1,0.01 34890000,-0.67,-0.0058,-0.0011,0.74,-0.58,-0.27,0.8,0,0,-4.9e+02,-0.0015,-0.0058,-8.8e-05,-0.0094,0.032,-0.11,0.21,-0.00096,0.43,-0.00066,0.00028,0.0033,0,0,-4.9e+02,4.5e-05,4.4e-05,0.001,0.032,0.039,0.0051,0.076,0.077,0.03,2.4e-07,2.5e-07,7.4e-07,0.0032,0.0033,6.9e-05,1.4e-05,3.3e-05,0.00036,8.4e-06,7.9e-06,0.00036,1,1,0.01 -34990000,-0.67,-0.013,-0.0036,0.74,0.47,0.33,-0.031,0,0,-4.9e+02,-0.0016,-0.0059,-3.8e-05,-0.017,0.041,-0.11,0.21,-0.00096,0.43,-0.00054,0.00033,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00099,0.033,0.045,0.0053,0.06,0.061,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.3e-05,3.3e-05,0.00036,7.9e-06,7.4e-06,0.00036,1,1,0.01 -35090000,-0.67,-0.013,-0.0036,0.74,0.6,0.36,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,-4e-05,-0.017,0.041,-0.11,0.21,-0.00096,0.43,-0.0005,0.00027,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00099,0.036,0.049,0.0054,0.063,0.065,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.2e-05,3.3e-05,0.00036,7.5e-06,6.9e-06,0.00036,1,1,0.01 -35190000,-0.67,-0.012,-0.0034,0.74,0.62,0.37,-0.091,0,0,-4.9e+02,-0.0016,-0.0059,-5.7e-06,-0.017,0.041,-0.11,0.21,-0.0011,0.43,-0.00046,0.00032,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00098,0.039,0.052,0.0054,0.053,0.055,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.2e-05,3.3e-05,0.00036,7.1e-06,6.4e-06,0.00036,1,1,0.01 -35290000,-0.67,-0.012,-0.0035,0.74,0.65,0.41,-0.088,0,0,-4.9e+02,-0.0016,-0.0059,-7.1e-06,-0.017,0.041,-0.11,0.21,-0.0011,0.43,-0.00039,0.00032,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00097,0.042,0.056,0.0054,0.057,0.06,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.7e-06,6.1e-06,0.00036,1,1,0.01 -35390000,-0.67,-0.012,-0.0032,0.74,0.66,0.4,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,3.2e-05,-0.017,0.041,-0.11,0.21,-0.0012,0.43,-0.00032,0.0003,0.0036,0,0,-4.9e+02,4e-05,3.9e-05,0.00096,0.044,0.058,0.0054,0.05,0.054,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.5e-06,5.8e-06,0.00036,1,1,0.01 -35490000,-0.67,-0.012,-0.0032,0.74,0.69,0.44,-0.088,0,0,-4.9e+02,-0.0016,-0.0059,3e-05,-0.017,0.041,-0.11,0.21,-0.0012,0.43,-0.00023,0.00026,0.0036,0,0,-4.9e+02,4e-05,3.9e-05,0.00095,0.048,0.063,0.0054,0.055,0.06,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.2e-06,5.5e-06,0.00036,1,1,0.01 +34990000,-0.67,-0.013,-0.0036,0.74,0.47,0.33,-0.031,0,0,-4.9e+02,-0.0016,-0.0059,-3.9e-05,-0.017,0.041,-0.11,0.21,-0.00096,0.43,-0.00054,0.00033,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.001,0.033,0.045,0.0053,0.06,0.061,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.3e-05,3.3e-05,0.00036,7.9e-06,7.4e-06,0.00036,1,1,0.01 +35090000,-0.67,-0.013,-0.0036,0.74,0.6,0.36,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,-4e-05,-0.017,0.041,-0.11,0.21,-0.00097,0.43,-0.0005,0.00027,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00099,0.036,0.049,0.0054,0.063,0.065,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.2e-05,3.3e-05,0.00036,7.5e-06,6.9e-06,0.00036,1,1,0.01 +35190000,-0.67,-0.012,-0.0034,0.74,0.62,0.37,-0.091,0,0,-4.9e+02,-0.0016,-0.0059,-5.8e-06,-0.017,0.041,-0.11,0.21,-0.0011,0.43,-0.00046,0.00031,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00098,0.039,0.052,0.0054,0.053,0.055,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.2e-05,3.3e-05,0.00036,7.1e-06,6.4e-06,0.00036,1,1,0.01 +35290000,-0.67,-0.012,-0.0035,0.74,0.65,0.41,-0.088,0,0,-4.9e+02,-0.0016,-0.0059,-7.2e-06,-0.017,0.041,-0.11,0.21,-0.0011,0.43,-0.00039,0.00032,0.0035,0,0,-4.9e+02,4.1e-05,4e-05,0.00097,0.042,0.056,0.0054,0.057,0.06,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.7e-06,6.1e-06,0.00036,1,1,0.01 +35390000,-0.67,-0.012,-0.0032,0.74,0.66,0.4,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,3.2e-05,-0.017,0.041,-0.11,0.21,-0.0012,0.43,-0.00032,0.0003,0.0036,0,0,-4.9e+02,4e-05,3.9e-05,0.00096,0.045,0.058,0.0054,0.05,0.054,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.5e-06,5.8e-06,0.00036,1,1,0.01 +35490000,-0.67,-0.012,-0.0032,0.74,0.69,0.44,-0.088,0,0,-4.9e+02,-0.0016,-0.0059,2.9e-05,-0.017,0.041,-0.11,0.21,-0.0012,0.43,-0.00023,0.00025,0.0036,0,0,-4.9e+02,4e-05,3.9e-05,0.00095,0.049,0.063,0.0054,0.055,0.06,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1.1e-05,3.3e-05,0.00036,6.2e-06,5.5e-06,0.00036,1,1,0.01 35590000,-0.67,-0.011,-0.003,0.74,0.68,0.42,-0.091,0,0,-4.9e+02,-0.0016,-0.0059,8e-05,-0.017,0.041,-0.11,0.21,-0.0013,0.43,-0.00028,0.00028,0.0036,0,0,-4.9e+02,3.8e-05,3.8e-05,0.00093,0.05,0.063,0.0054,0.05,0.055,0.03,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1e-05,3.3e-05,0.00036,6e-06,5.2e-06,0.00036,1,1,0.01 -35690000,-0.67,-0.011,-0.003,0.74,0.71,0.46,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,7.9e-05,-0.018,0.041,-0.11,0.21,-0.0013,0.43,-0.0002,0.00027,0.0036,0,0,-4.9e+02,3.8e-05,3.8e-05,0.00093,0.054,0.068,0.0054,0.057,0.063,0.031,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1e-05,3.3e-05,0.00036,5.8e-06,5e-06,0.00036,1,1,0.01 +35690000,-0.67,-0.011,-0.003,0.74,0.71,0.46,-0.089,0,0,-4.9e+02,-0.0016,-0.0059,7.9e-05,-0.017,0.041,-0.11,0.21,-0.0013,0.43,-0.0002,0.00027,0.0036,0,0,-4.9e+02,3.8e-05,3.8e-05,0.00093,0.054,0.068,0.0054,0.057,0.063,0.031,2.4e-07,2.5e-07,7.4e-07,0.003,0.0031,6.9e-05,1e-05,3.3e-05,0.00036,5.8e-06,5e-06,0.00036,1,1,0.01 35790000,-0.67,-0.01,-0.0028,0.74,0.69,0.42,-0.092,0,0,-4.9e+02,-0.0016,-0.006,0.00013,-0.027,0.049,-0.11,0.21,-0.0014,0.43,-0.00021,0.00031,0.0037,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00091,0.054,0.066,0.0054,0.052,0.058,0.03,2.4e-07,2.5e-07,7.4e-07,0.0029,0.003,6.9e-05,9.5e-06,3.3e-05,0.00036,5.6e-06,4.8e-06,0.00036,1,1,0.023 -35890000,-0.67,-0.01,-0.0029,0.74,0.71,0.46,-0.088,0,0,-4.9e+02,-0.0016,-0.006,0.00013,-0.027,0.049,-0.11,0.21,-0.0014,0.43,-0.00019,0.0003,0.0037,0,0,-4.9e+02,3.6e-05,3.7e-05,0.0009,0.058,0.071,0.0054,0.06,0.067,0.03,2.4e-07,2.5e-07,7.4e-07,0.0029,0.003,6.9e-05,9.3e-06,3.3e-05,0.00036,5.4e-06,4.6e-06,0.00036,1,1,0.048 -35990000,-0.67,-0.0091,-0.0027,0.74,0.67,0.42,-0.092,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-0.00024,0.00034,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.057,0.067,0.0054,0.056,0.062,0.031,2.4e-07,2.5e-07,7.3e-07,0.0028,0.0029,6.9e-05,8.8e-06,3.2e-05,0.00036,5.3e-06,4.4e-06,0.00036,1,1,0.073 -36090000,-0.67,-0.0092,-0.0027,0.74,0.7,0.45,-0.089,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-0.00019,0.00032,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.061,0.071,0.0054,0.064,0.072,0.031,2.4e-07,2.5e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.7e-06,3.2e-05,0.00036,5.1e-06,4.3e-06,0.00036,1,1,0.098 -36190000,-0.67,-0.0092,-0.0027,0.74,0.72,0.48,-0.084,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-9.1e-05,0.00031,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.066,0.076,0.0054,0.074,0.084,0.031,2.4e-07,2.5e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.5e-06,3.2e-05,0.00036,5e-06,4.1e-06,0.00036,1,1,0.12 -36290000,-0.67,-0.0092,-0.0027,0.74,0.75,0.52,-0.079,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-6.6e-05,0.0003,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00087,0.071,0.082,0.0054,0.086,0.098,0.031,2.4e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.4e-06,3.2e-05,0.00036,4.9e-06,4e-06,0.00036,1,1,0.15 -36390000,-0.67,-0.0093,-0.0027,0.74,0.77,0.55,-0.076,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-6.3e-05,0.00034,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00087,0.076,0.087,0.0054,0.1,0.11,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.3e-06,3.2e-05,0.00036,4.8e-06,3.9e-06,0.00036,1,1,0.17 -36490000,-0.67,-0.0093,-0.0027,0.74,0.8,0.58,-0.072,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-8.7e-05,0.00035,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00087,0.081,0.092,0.0054,0.12,0.13,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.2e-06,3.2e-05,0.00036,4.7e-06,3.8e-06,0.00036,1,1,0.2 -36590000,-0.67,-0.0094,-0.0027,0.74,0.82,0.62,-0.066,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-3.4e-05,0.00038,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.086,0.098,0.0054,0.13,0.15,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.1e-06,3.2e-05,0.00036,4.6e-06,3.7e-06,0.00036,1,1,0.22 -36690000,-0.67,-0.0094,-0.0027,0.74,0.85,0.65,-0.062,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,3.2e-06,0.00039,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.092,0.1,0.0055,0.15,0.18,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,8e-06,3.2e-05,0.00036,4.5e-06,3.6e-06,0.00036,1,1,0.25 -36790000,-0.67,-0.0094,-0.0027,0.74,0.88,0.68,-0.056,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0015,0.43,5.3e-05,0.00035,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.098,0.11,0.0054,0.18,0.2,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.9e-06,3.2e-05,0.00036,4.5e-06,3.5e-06,0.00036,1,1,0.27 -36890000,-0.67,-0.0095,-0.0027,0.74,0.9,0.72,-0.051,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.038,0.058,-0.11,0.21,-0.0015,0.43,9.7e-05,0.00035,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.1,0.12,0.0054,0.2,0.23,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.8e-06,3.2e-05,0.00036,4.4e-06,3.4e-06,0.00036,1,1,0.3 -36990000,-0.67,-0.0095,-0.0026,0.74,0.93,0.75,-0.046,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.038,0.057,-0.11,0.21,-0.0015,0.43,0.00012,0.00035,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.11,0.12,0.0055,0.23,0.26,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.7e-06,3.2e-05,0.00036,4.3e-06,3.3e-06,0.00036,1,1,0.33 -37090000,-0.67,-0.0096,-0.0025,0.74,0.96,0.78,-0.04,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00013,0.00038,0.0038,0,0,-4.9e+02,3.6e-05,3.6e-05,0.00087,0.12,0.13,0.0055,0.26,0.3,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.6e-06,3.2e-05,0.00036,4.3e-06,3.3e-06,0.00036,1,1,0.35 -37190000,-0.67,-0.0096,-0.0025,0.74,0.98,0.82,-0.034,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00013,0.00039,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.12,0.14,0.0054,0.29,0.34,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.6e-06,3.2e-05,0.00036,4.2e-06,3.2e-06,0.00036,1,1,0.38 -37290000,-0.67,-0.0096,-0.0026,0.74,1,0.85,-0.029,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00015,0.00038,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.13,0.14,0.0055,0.33,0.38,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.5e-06,3.2e-05,0.00036,4.2e-06,3.1e-06,0.00036,1,1,0.4 -37390000,-0.67,-0.0096,-0.0025,0.74,1,0.88,-0.024,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00018,0.00039,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.14,0.15,0.0054,0.37,0.42,0.031,2.6e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.4e-06,3.2e-05,0.00036,4.1e-06,3.1e-06,0.00036,1,1,0.43 -37490000,-0.67,-0.0097,-0.0025,0.74,1.1,0.91,-0.018,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00022,0.00042,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.14,0.16,0.0054,0.41,0.48,0.031,2.6e-07,2.7e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.4e-06,3.2e-05,0.00036,4.1e-06,3e-06,0.00036,1,1,0.45 -37590000,-0.67,-0.0097,-0.0024,0.74,1.1,0.95,-0.011,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00024,0.00042,0.0038,0,0,-4.9e+02,3.7e-05,3.7e-05,0.00087,0.15,0.17,0.0055,0.46,0.53,0.032,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.6e-05,7.3e-06,3.2e-05,0.00036,4e-06,3e-06,0.00036,1,1,0.48 -37690000,-0.67,-0.0098,-0.0025,0.74,1.1,0.98,-0.0037,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00026,0.00041,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00087,0.16,0.17,0.0054,0.51,0.59,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.6e-05,7.3e-06,3.2e-05,0.00036,4e-06,2.9e-06,0.00036,1,1,0.5 -37790000,-0.67,-0.0098,-0.0025,0.74,1.1,1,0.0033,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00027,0.00042,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00087,0.17,0.18,0.0054,0.57,0.65,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.2e-06,3.2e-05,0.00036,3.9e-06,2.9e-06,0.00036,1,1,0.53 -37890000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.0094,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00028,0.0004,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00087,0.18,0.19,0.0054,0.63,0.72,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.2e-06,3.2e-05,0.00036,3.9e-06,2.8e-06,0.00036,1,1,0.55 -37990000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.017,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00029,0.0004,0.0038,0,0,-4.9e+02,3.8e-05,3.8e-05,0.00087,0.18,0.2,0.0054,0.7,0.8,0.032,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.1e-06,3.2e-05,0.00036,3.9e-06,2.8e-06,0.00036,1,1,0.58 -38090000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.026,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00031,0.00042,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00087,0.19,0.21,0.0054,0.77,0.88,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.1e-06,3.2e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.61 -38190000,-0.67,-0.0098,-0.0025,0.74,1.2,1.2,0.032,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00041,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00088,0.2,0.22,0.0054,0.85,0.96,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7e-06,3.2e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.63 -38290000,-0.67,-0.0099,-0.0025,0.74,1.3,1.2,0.039,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00039,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00088,0.21,0.23,0.0054,0.93,1.1,0.032,2.6e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.5e-05,7e-06,3.2e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.66 -38390000,-0.67,-0.0099,-0.0025,0.74,1.3,1.2,0.045,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00041,0.0038,0,0,-4.9e+02,3.9e-05,3.9e-05,0.00088,0.22,0.24,0.0054,1,1.1,0.032,2.6e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.2e-05,0.00036,3.8e-06,2.6e-06,0.00036,1,1,0.68 -38490000,-0.67,-0.0099,-0.0024,0.74,1.3,1.3,0.051,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00033,0.00043,0.0038,0,0,-4.9e+02,3.9e-05,3.9e-05,0.00088,0.23,0.25,0.0054,1.1,1.3,0.031,2.6e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.2e-05,0.00036,3.7e-06,2.6e-06,0.00036,1,1,0.71 -38590000,-0.67,-0.0099,-0.0024,0.74,1.4,1.3,0.056,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00033,0.00044,0.0038,0,0,-4.9e+02,3.9e-05,4e-05,0.00088,0.24,0.26,0.0054,1.2,1.4,0.032,2.7e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.2e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.73 -38690000,-0.67,-0.01,-0.0024,0.74,1.4,1.3,0.062,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00035,0.00046,0.0038,0,0,-4.9e+02,3.9e-05,4e-05,0.00088,0.25,0.27,0.0054,1.3,1.5,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.2e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.76 -38790000,-0.67,-0.01,-0.0024,0.74,1.4,1.4,0.068,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00036,0.00045,0.0038,0,0,-4.9e+02,4e-05,4e-05,0.00088,0.26,0.28,0.0054,1.4,1.6,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.2e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.79 -38890000,-0.67,-0.01,-0.0024,0.74,1.4,1.4,0.57,0,0,-4.9e+02,-0.0016,-0.006,0.00014,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00037,0.00042,0.0038,0,0,-4.9e+02,4e-05,4e-05,0.00088,0.26,0.28,0.0054,1.6,1.7,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.2e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.81 +35890000,-0.67,-0.01,-0.0029,0.74,0.71,0.46,-0.088,0,0,-4.9e+02,-0.0016,-0.006,0.00013,-0.027,0.049,-0.11,0.21,-0.0014,0.43,-0.00019,0.0003,0.0037,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00091,0.058,0.071,0.0054,0.06,0.067,0.03,2.4e-07,2.5e-07,7.4e-07,0.0029,0.003,6.9e-05,9.3e-06,3.3e-05,0.00036,5.4e-06,4.6e-06,0.00036,1,1,0.048 +35990000,-0.67,-0.0091,-0.0027,0.74,0.67,0.42,-0.092,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-0.00024,0.00033,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.057,0.067,0.0054,0.056,0.062,0.031,2.4e-07,2.5e-07,7.3e-07,0.0028,0.0029,6.9e-05,8.8e-06,3.3e-05,0.00036,5.3e-06,4.4e-06,0.00036,1,1,0.073 +36090000,-0.67,-0.0092,-0.0027,0.74,0.7,0.45,-0.088,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-0.00019,0.00032,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.061,0.072,0.0054,0.064,0.072,0.031,2.4e-07,2.5e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.7e-06,3.3e-05,0.00036,5.1e-06,4.3e-06,0.00036,1,1,0.098 +36190000,-0.67,-0.0092,-0.0027,0.74,0.72,0.48,-0.084,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.059,-0.11,0.21,-0.0014,0.43,-9.1e-05,0.00031,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.066,0.076,0.0054,0.074,0.084,0.031,2.4e-07,2.5e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.5e-06,3.3e-05,0.00036,5e-06,4.1e-06,0.00036,1,1,0.12 +36290000,-0.67,-0.0092,-0.0027,0.74,0.75,0.52,-0.079,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-6.6e-05,0.0003,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.071,0.082,0.0054,0.086,0.098,0.031,2.4e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.4e-06,3.3e-05,0.00036,4.9e-06,4e-06,0.00036,1,1,0.15 +36390000,-0.67,-0.0093,-0.0027,0.74,0.77,0.55,-0.076,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-6.3e-05,0.00034,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00088,0.076,0.087,0.0054,0.1,0.11,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.3e-06,3.3e-05,0.00036,4.8e-06,3.9e-06,0.00036,1,1,0.17 +36490000,-0.67,-0.0093,-0.0027,0.74,0.8,0.58,-0.072,0,0,-4.9e+02,-0.0016,-0.006,0.00019,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-8.7e-05,0.00035,0.0038,0,0,-4.9e+02,3.4e-05,3.5e-05,0.00087,0.081,0.092,0.0054,0.12,0.13,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.2e-06,3.3e-05,0.00036,4.7e-06,3.8e-06,0.00036,1,1,0.2 +36590000,-0.67,-0.0094,-0.0027,0.74,0.82,0.62,-0.066,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,-3.4e-05,0.00038,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.086,0.098,0.0054,0.13,0.15,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.8e-05,8.1e-06,3.3e-05,0.00036,4.6e-06,3.7e-06,0.00036,1,1,0.22 +36690000,-0.67,-0.0094,-0.0027,0.74,0.85,0.65,-0.062,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0014,0.43,3.2e-06,0.00039,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.092,0.1,0.0055,0.15,0.18,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,8e-06,3.3e-05,0.00036,4.5e-06,3.6e-06,0.00036,1,1,0.25 +36790000,-0.67,-0.0094,-0.0027,0.74,0.88,0.68,-0.056,0,0,-4.9e+02,-0.0016,-0.006,0.00018,-0.038,0.058,-0.11,0.21,-0.0015,0.43,5.3e-05,0.00035,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.098,0.11,0.0054,0.18,0.2,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.9e-06,3.3e-05,0.00036,4.5e-06,3.5e-06,0.00036,1,1,0.27 +36890000,-0.67,-0.0095,-0.0027,0.74,0.9,0.72,-0.051,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.038,0.058,-0.11,0.21,-0.0015,0.43,9.7e-05,0.00034,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.1,0.12,0.0054,0.2,0.23,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.8e-06,3.3e-05,0.00036,4.4e-06,3.4e-06,0.00036,1,1,0.3 +36990000,-0.67,-0.0095,-0.0026,0.74,0.93,0.75,-0.046,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.038,0.057,-0.11,0.21,-0.0015,0.43,0.00012,0.00035,0.0038,0,0,-4.9e+02,3.5e-05,3.6e-05,0.00087,0.11,0.12,0.0055,0.23,0.26,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.7e-06,3.3e-05,0.00036,4.3e-06,3.3e-06,0.00036,1,1,0.33 +37090000,-0.67,-0.0096,-0.0025,0.74,0.96,0.78,-0.04,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00013,0.00038,0.0038,0,0,-4.9e+02,3.6e-05,3.6e-05,0.00087,0.12,0.13,0.0055,0.26,0.3,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.7e-05,7.6e-06,3.3e-05,0.00036,4.3e-06,3.3e-06,0.00036,1,1,0.35 +37190000,-0.67,-0.0096,-0.0025,0.74,0.98,0.82,-0.034,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00013,0.00038,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.12,0.14,0.0054,0.29,0.34,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.6e-06,3.3e-05,0.00036,4.2e-06,3.2e-06,0.00036,1,1,0.38 +37290000,-0.67,-0.0096,-0.0026,0.74,1,0.85,-0.029,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00015,0.00038,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.13,0.14,0.0055,0.33,0.38,0.031,2.5e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.5e-06,3.3e-05,0.00036,4.2e-06,3.1e-06,0.00036,1,1,0.4 +37390000,-0.67,-0.0097,-0.0025,0.74,1,0.88,-0.024,0,0,-4.9e+02,-0.0016,-0.006,0.00017,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00018,0.00039,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.14,0.15,0.0054,0.37,0.43,0.031,2.6e-07,2.6e-07,7.4e-07,0.0028,0.0029,6.6e-05,7.4e-06,3.3e-05,0.00036,4.1e-06,3.1e-06,0.00036,1,1,0.43 +37490000,-0.67,-0.0097,-0.0025,0.74,1.1,0.91,-0.018,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00022,0.00042,0.0038,0,0,-4.9e+02,3.6e-05,3.7e-05,0.00087,0.14,0.16,0.0054,0.41,0.48,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.6e-05,7.4e-06,3.3e-05,0.00036,4.1e-06,3e-06,0.00036,1,1,0.45 +37590000,-0.67,-0.0097,-0.0024,0.74,1.1,0.95,-0.011,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.057,-0.11,0.21,-0.0015,0.43,0.00024,0.00042,0.0038,0,0,-4.9e+02,3.7e-05,3.7e-05,0.00087,0.15,0.17,0.0055,0.46,0.53,0.032,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.6e-05,7.3e-06,3.3e-05,0.00036,4e-06,3e-06,0.00036,1,1,0.48 +37690000,-0.67,-0.0098,-0.0025,0.74,1.1,0.98,-0.0037,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00026,0.00041,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00087,0.16,0.17,0.0054,0.51,0.59,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.6e-05,7.3e-06,3.3e-05,0.00036,4e-06,2.9e-06,0.00036,1,1,0.5 +37790000,-0.67,-0.0098,-0.0025,0.74,1.1,1,0.0033,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00027,0.00042,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00087,0.17,0.18,0.0054,0.57,0.65,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.2e-06,3.3e-05,0.00036,3.9e-06,2.9e-06,0.00036,1,1,0.53 +37890000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.0094,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00028,0.0004,0.0038,0,0,-4.9e+02,3.7e-05,3.8e-05,0.00088,0.18,0.19,0.0054,0.63,0.72,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.2e-06,3.3e-05,0.00036,3.9e-06,2.8e-06,0.00036,1,1,0.55 +37990000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.017,0,0,-4.9e+02,-0.0016,-0.006,0.00016,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00029,0.0004,0.0038,0,0,-4.9e+02,3.8e-05,3.8e-05,0.00088,0.18,0.2,0.0054,0.7,0.8,0.032,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.1e-06,3.3e-05,0.00036,3.9e-06,2.8e-06,0.00036,1,1,0.58 +38090000,-0.67,-0.0098,-0.0025,0.74,1.2,1.1,0.026,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00031,0.00041,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00088,0.19,0.21,0.0054,0.77,0.88,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7.1e-06,3.3e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.61 +38190000,-0.67,-0.0098,-0.0025,0.74,1.2,1.2,0.032,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00041,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00088,0.2,0.22,0.0054,0.85,0.96,0.031,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7e-06,3.3e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.63 +38290000,-0.67,-0.0099,-0.0025,0.74,1.3,1.2,0.039,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00039,0.0038,0,0,-4.9e+02,3.8e-05,3.9e-05,0.00088,0.21,0.23,0.0054,0.93,1.1,0.032,2.6e-07,2.7e-07,7.5e-07,0.0028,0.0029,6.5e-05,7e-06,3.3e-05,0.00036,3.8e-06,2.7e-06,0.00036,1,1,0.66 +38390000,-0.67,-0.0099,-0.0025,0.74,1.3,1.2,0.045,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00032,0.00041,0.0038,0,0,-4.9e+02,3.9e-05,3.9e-05,0.00088,0.22,0.24,0.0054,1,1.1,0.032,2.6e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.3e-05,0.00036,3.8e-06,2.6e-06,0.00036,1,1,0.68 +38490000,-0.67,-0.0099,-0.0024,0.74,1.3,1.3,0.051,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00033,0.00043,0.0038,0,0,-4.9e+02,3.9e-05,4e-05,0.00088,0.23,0.25,0.0054,1.1,1.3,0.031,2.6e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.3e-05,0.00036,3.7e-06,2.6e-06,0.00036,1,1,0.71 +38590000,-0.67,-0.0099,-0.0024,0.74,1.4,1.3,0.056,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00033,0.00044,0.0038,0,0,-4.9e+02,3.9e-05,4e-05,0.00088,0.24,0.26,0.0054,1.2,1.4,0.032,2.7e-07,2.7e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.9e-06,3.3e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.73 +38690000,-0.67,-0.01,-0.0024,0.74,1.4,1.3,0.062,0,0,-4.9e+02,-0.0016,-0.006,0.00015,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00035,0.00045,0.0038,0,0,-4.9e+02,3.9e-05,4e-05,0.00088,0.25,0.27,0.0054,1.3,1.5,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.3e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.76 +38790000,-0.67,-0.01,-0.0024,0.74,1.4,1.4,0.068,0,0,-4.9e+02,-0.0016,-0.006,0.00014,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00036,0.00045,0.0038,0,0,-4.9e+02,4e-05,4e-05,0.00088,0.26,0.28,0.0054,1.4,1.6,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.3e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.79 +38890000,-0.67,-0.01,-0.0024,0.74,1.4,1.4,0.57,0,0,-4.9e+02,-0.0016,-0.006,0.00014,-0.037,0.056,-0.11,0.21,-0.0015,0.43,0.00037,0.00042,0.0038,0,0,-4.9e+02,4e-05,4e-05,0.00088,0.26,0.28,0.0054,1.6,1.7,0.032,2.7e-07,2.8e-07,7.5e-07,0.0027,0.0029,6.4e-05,6.8e-06,3.3e-05,0.00036,3.7e-06,2.5e-06,0.00036,1,1,0.81 diff --git a/src/modules/ekf2/test/change_indication/iris_gps.csv b/src/modules/ekf2/test/change_indication/iris_gps.csv index 3b9312e0f6..6878e1cce7 100644 --- a/src/modules/ekf2/test/change_indication/iris_gps.csv +++ b/src/modules/ekf2/test/change_indication/iris_gps.csv @@ -69,283 +69,283 @@ Timestamp,state[0],state[1],state[2],state[3],state[4],state[5],state[6],state[7 6690000,1,-0.0088,-0.011,0.00052,0.0022,0.018,-0.044,0,0,-4.9e+02,-0.0017,-0.0056,-9e-05,0,0,-0.13,0,0,0,0,0,0,0,0,-4.9e+02,0.0016,0.0016,9.9e-05,0.23,0.23,0.035,0.14,0.14,0.068,9.8e-05,9.8e-05,2.6e-06,0.04,0.04,0.0031,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.7 6790000,1,-0.0089,-0.011,0.00049,0.003,0.016,-0.043,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,0,0,-0.13,0,0,0,0,0,0,0,0,-4.9e+02,0.0014,0.0014,9.3e-05,0.18,0.18,0.034,0.11,0.11,0.068,8e-05,8.1e-05,2.4e-06,0.04,0.04,0.003,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.7 6890000,1,-0.0087,-0.011,0.0004,0.0023,0.016,-0.039,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,0,0,-0.13,0,0,0,0,0,0,0,0,-4.9e+02,0.0015,0.0015,9.6e-05,0.21,0.21,0.032,0.14,0.14,0.067,8e-05,8.1e-05,2.4e-06,0.04,0.04,0.0028,0.0025,0.0025,0.0025,0.0025,0.0025,0.0025,1,1,1.8 -6990000,0.98,-0.0067,-0.012,0.18,0.0025,0.011,-0.037,0,0,-4.9e+02,-0.0015,-0.0056,-9.4e-05,0,0,-0.13,0.21,-0.00049,0.44,0.00044,-0.0011,0.00036,0,0,-4.9e+02,0.0012,0.0012,0.054,0.16,0.17,0.031,0.1,0.1,0.066,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0026,0.0015,0.0012,0.0014,0.0015,0.0018,0.0014,1,1,1.8 -7090000,0.98,-0.0065,-0.012,0.18,0.00012,0.018,-0.038,0,0,-4.9e+02,-0.0016,-0.0056,-9.4e-05,0,0,-0.13,0.2,-0.00015,0.44,-0.00019,-0.00047,0.00017,0,0,-4.9e+02,0.0013,0.0013,0.048,0.18,0.19,0.03,0.13,0.13,0.066,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0024,0.0014,0.00067,0.0013,0.0014,0.0016,0.0013,1,1,1.8 -7190000,0.98,-0.0065,-0.012,0.18,-6.6e-05,0.019,-0.037,0,0,-4.9e+02,-0.0016,-0.0056,-9.4e-05,-6.3e-05,3.4e-05,-0.13,0.2,-0.0001,0.43,-0.00018,-0.00052,-3.3e-06,0,0,-4.9e+02,0.0013,0.0013,0.046,0.21,0.21,0.029,0.16,0.16,0.065,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0023,0.0013,0.00044,0.0013,0.0014,0.0016,0.0013,1,1,1.8 -7290000,0.98,-0.0064,-0.012,0.18,-0.00068,0.024,-0.034,0,0,-4.9e+02,-0.0016,-0.0057,-9.4e-05,-0.0003,0.00019,-0.13,0.2,-7.3e-05,0.43,-0.00037,-0.00044,6.5e-05,0,0,-4.9e+02,0.0014,0.0013,0.044,0.24,0.24,0.028,0.19,0.19,0.064,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0022,0.0013,0.00033,0.0013,0.0014,0.0016,0.0013,1,1,1.9 -7390000,0.98,-0.0063,-0.012,0.18,-0.0015,0.00095,-0.032,0,0,-4.9e+02,-0.0016,-0.0057,-9.4e-05,-0.00036,0.00036,-0.13,0.2,-5.7e-05,0.43,-0.00048,-0.0004,8.9e-05,0,0,-4.9e+02,0.0014,0.0014,0.043,25,25,0.027,1e+02,1e+02,0.064,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.002,0.0013,0.00027,0.0013,0.0014,0.0016,0.0013,1,1,1.9 -7490000,0.98,-0.0063,-0.012,0.18,0.00098,0.0035,-0.026,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00036,-0.13,0.2,-4.5e-05,0.43,-0.00042,-0.00038,-7.8e-05,0,0,-4.9e+02,0.0015,0.0014,0.043,25,25,0.026,1e+02,1e+02,0.063,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0019,0.0013,0.00022,0.0013,0.0014,0.0016,0.0013,1,1,1.9 -7590000,0.98,-0.0064,-0.012,0.18,0.0021,0.0061,-0.023,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00036,-0.13,0.2,-3.8e-05,0.43,-0.00035,-0.00039,-8.8e-06,0,0,-4.9e+02,0.0015,0.0015,0.042,25,25,0.025,51,51,0.062,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0018,0.0013,0.00019,0.0013,0.0014,0.0016,0.0013,1,1,1.9 -7690000,0.98,-0.0064,-0.013,0.18,0.0021,0.0093,-0.022,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00036,-0.13,0.2,-3.4e-05,0.43,-0.00031,-0.0004,3.2e-06,0,0,-4.9e+02,0.0016,0.0015,0.042,25,25,0.025,52,52,0.062,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0017,0.0013,0.00017,0.0013,0.0014,0.0016,0.0013,1,1,2 -7790000,0.98,-0.0064,-0.013,0.18,0.0056,0.01,-0.025,0,0,-4.9e+02,-0.0015,-0.0055,-9.2e-05,-0.00036,0.00036,-0.13,0.2,-2.9e-05,0.43,-0.00021,-0.00039,-8.1e-07,0,0,-4.9e+02,0.0016,0.0016,0.042,24,24,0.024,35,35,0.061,6.3e-05,6.2e-05,2.2e-06,0.04,0.04,0.0016,0.0013,0.00015,0.0013,0.0014,0.0016,0.0013,1,1,2 -7890000,0.98,-0.0064,-0.013,0.18,0.0047,0.014,-0.025,0,0,-4.9e+02,-0.0015,-0.0055,-9.2e-05,-0.00036,0.00036,-0.13,0.2,-2.6e-05,0.43,-0.00019,-0.0004,4.5e-05,0,0,-4.9e+02,0.0016,0.0016,0.042,24,24,0.023,36,36,0.06,6.3e-05,6.1e-05,2.2e-06,0.04,0.04,0.0015,0.0013,0.00013,0.0013,0.0014,0.0016,0.0013,1,1,2 -7990000,0.98,-0.0063,-0.013,0.18,0.0032,0.017,-0.022,0,0,-4.9e+02,-0.0016,-0.0056,-9.3e-05,-0.00036,0.00036,-0.13,0.2,-2.5e-05,0.43,-0.0002,-0.00042,7.5e-05,0,0,-4.9e+02,0.0017,0.0016,0.042,24,24,0.022,28,28,0.059,6.2e-05,6.1e-05,2.2e-06,0.04,0.04,0.0015,0.0013,0.00012,0.0013,0.0014,0.0016,0.0013,1,1,2 -8090000,0.98,-0.0062,-0.013,0.18,0.0043,0.019,-0.022,0,0,-4.9e+02,-0.0015,-0.0056,-9.5e-05,-0.00036,0.00036,-0.13,0.2,-2.2e-05,0.43,-0.00017,-0.00042,0.0001,0,0,-4.9e+02,0.0017,0.0017,0.042,24,24,0.022,30,30,0.059,6.2e-05,6e-05,2.2e-06,0.04,0.04,0.0014,0.0013,0.00011,0.0013,0.0014,0.0016,0.0013,1,1,2.1 -8190000,0.98,-0.0064,-0.012,0.18,0.0053,0.022,-0.018,0,0,-4.9e+02,-0.0015,-0.0056,-9.7e-05,-0.00036,0.00036,-0.13,0.2,-2e-05,0.44,-0.00014,-0.00041,0.00015,0,0,-4.9e+02,0.0018,0.0017,0.041,23,23,0.021,24,24,0.058,6.1e-05,5.9e-05,2.2e-06,0.04,0.04,0.0013,0.0013,0.0001,0.0013,0.0014,0.0016,0.0013,1,1,2.1 -8290000,0.98,-0.0062,-0.012,0.18,0.002,0.028,-0.017,0,0,-4.9e+02,-0.0015,-0.0058,-9.8e-05,-0.00036,0.00036,-0.13,0.2,-2e-05,0.43,-0.00014,-0.00044,6.8e-05,0,0,-4.9e+02,0.0018,0.0017,0.041,23,23,0.02,27,27,0.057,6.1e-05,5.8e-05,2.2e-06,0.04,0.04,0.0013,0.0013,9.6e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.1 -8390000,0.98,-0.0061,-0.012,0.18,-0.0023,0.028,-0.016,0,0,-4.9e+02,-0.0015,-0.0058,-9.9e-05,-0.00036,0.00036,-0.13,0.2,-1.9e-05,0.43,-0.00014,-0.00044,2.1e-05,0,0,-4.9e+02,0.0019,0.0018,0.041,21,21,0.02,23,23,0.057,6e-05,5.7e-05,2.2e-06,0.04,0.04,0.0012,0.0013,9e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.1 -8490000,0.98,-0.0058,-0.012,0.18,-0.0061,0.035,-0.017,0,0,-4.9e+02,-0.0016,-0.0059,-9.8e-05,-0.00036,0.00036,-0.13,0.2,-1.9e-05,0.43,-0.00014,-0.00048,-6.7e-06,0,0,-4.9e+02,0.0019,0.0018,0.041,21,21,0.019,25,25,0.056,5.9e-05,5.6e-05,2.2e-06,0.04,0.04,0.0011,0.0013,8.4e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 -8590000,0.98,-0.006,-0.012,0.18,-0.0003,0.034,-0.012,0,0,-4.9e+02,-0.0016,-0.0058,-9.7e-05,-0.00036,0.00036,-0.14,0.2,-1.7e-05,0.43,-0.00018,-0.00043,3.8e-06,0,0,-4.9e+02,0.0019,0.0018,0.041,19,19,0.018,22,22,0.055,5.8e-05,5.5e-05,2.2e-06,0.04,0.04,0.0011,0.0013,7.9e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 -8690000,0.98,-0.0059,-0.012,0.18,-0.0022,0.037,-0.014,0,0,-4.9e+02,-0.0016,-0.0058,-9.7e-05,-0.00036,0.00036,-0.14,0.2,-1.6e-05,0.43,-0.00022,-0.00045,-8.7e-05,0,0,-4.9e+02,0.002,0.0018,0.041,19,19,0.018,24,24,0.055,5.8e-05,5.3e-05,2.2e-06,0.04,0.04,0.001,0.0013,7.5e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 -8790000,0.98,-0.0059,-0.012,0.18,-0.005,0.039,-0.014,0,0,-4.9e+02,-0.0016,-0.0058,-9.9e-05,-0.00036,0.00036,-0.14,0.2,-1.5e-05,0.43,-0.00019,-0.00045,-0.00013,0,0,-4.9e+02,0.002,0.0018,0.041,19,19,0.018,27,27,0.055,5.7e-05,5.2e-05,2.2e-06,0.04,0.04,0.00099,0.0013,7.1e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 -8890000,0.98,-0.006,-0.012,0.18,0.00052,0.041,-0.0094,0,0,-4.9e+02,-0.0016,-0.0057,-9.6e-05,-0.00036,0.00036,-0.14,0.2,-1.4e-05,0.43,-0.00026,-0.00043,-0.00011,0,0,-4.9e+02,0.002,0.0018,0.041,17,17,0.017,24,24,0.054,5.6e-05,5e-05,2.2e-06,0.04,0.04,0.00094,0.0013,6.7e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 -8990000,0.98,-0.0059,-0.013,0.18,0.01,0.047,-0.0086,0,0,-4.9e+02,-0.0016,-0.0056,-9.1e-05,-0.00036,0.00036,-0.14,0.2,-1.4e-05,0.43,-0.00037,-0.00039,-6.6e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,17,17,0.017,27,27,0.054,5.5e-05,4.9e-05,2.2e-06,0.04,0.04,0.00091,0.0013,6.4e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 -9090000,0.98,-0.0055,-0.012,0.18,-0.0004,0.057,-0.0096,0,0,-4.9e+02,-0.0017,-0.0057,-9e-05,-0.00036,0.00036,-0.14,0.2,-1.5e-05,0.43,-0.00028,-0.0005,-8.8e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,15,15,0.016,24,24,0.053,5.3e-05,4.7e-05,2.2e-06,0.04,0.04,0.00087,0.0013,6.1e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 -9190000,0.98,-0.0053,-0.013,0.18,0.0028,0.064,-0.009,0,0,-4.9e+02,-0.0018,-0.0057,-8.8e-05,-0.00036,0.00036,-0.14,0.2,-1.5e-05,0.43,-0.00031,-0.00053,-0.00011,0,0,-4.9e+02,0.0021,0.0018,0.041,15,15,0.016,27,27,0.052,5.2e-05,4.5e-05,2.2e-06,0.04,0.04,0.00083,0.0013,5.9e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.3 -9290000,0.98,-0.0052,-0.013,0.18,0.013,0.062,-0.0074,0,0,-4.9e+02,-0.0017,-0.0056,-8.6e-05,-0.00036,0.00036,-0.14,0.2,-1.4e-05,0.43,-0.0004,-0.00049,-8.6e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,13,13,0.015,24,24,0.052,5.1e-05,4.4e-05,2.2e-06,0.04,0.04,0.00079,0.0013,5.6e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.4 -9390000,0.98,-0.0054,-0.013,0.18,0.014,0.06,-0.0063,0,0,-4.9e+02,-0.0017,-0.0056,-8.9e-05,-0.00036,0.00036,-0.14,0.2,-1.2e-05,0.43,-0.00035,-0.00044,-3.9e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,13,13,0.015,26,26,0.052,5e-05,4.2e-05,2.2e-06,0.04,0.04,0.00077,0.0013,5.4e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.4 -9490000,0.98,-0.0053,-0.013,0.18,0.0085,0.062,-0.0046,0,0,-4.9e+02,-0.0017,-0.0057,-8.9e-05,-0.00036,0.00036,-0.14,0.2,-1.2e-05,0.43,-0.00033,-0.00048,-7.7e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,12,12,0.015,23,23,0.051,4.8e-05,4e-05,2.2e-06,0.04,0.04,0.00074,0.0013,5.2e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.4 -9590000,0.98,-0.0057,-0.013,0.18,0.0075,0.053,-0.0045,0,0,-4.9e+02,-0.0016,-0.0057,-9.5e-05,-0.00036,0.00036,-0.14,0.2,-1e-05,0.43,-0.0003,-0.00042,-0.00012,0,0,-4.9e+02,0.0022,0.0018,0.041,12,12,0.014,26,26,0.05,4.7e-05,3.9e-05,2.2e-06,0.04,0.04,0.00071,0.0013,5e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.4 -9690000,0.98,-0.0059,-0.013,0.18,0.0093,0.048,-0.0016,0,0,-4.9e+02,-0.0015,-0.0057,-9.7e-05,-0.00036,0.00036,-0.14,0.2,-9.2e-06,0.43,-0.00031,-0.00038,-0.0001,0,0,-4.9e+02,0.0022,0.0018,0.041,10,10,0.014,23,23,0.05,4.6e-05,3.7e-05,2.2e-06,0.04,0.04,0.00068,0.0013,4.8e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 -9790000,0.98,-0.0061,-0.012,0.18,0.00062,0.042,-0.003,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,-0.00036,0.00036,-0.14,0.2,-7.8e-06,0.43,-0.00018,-0.00037,-0.00015,0,0,-4.9e+02,0.0022,0.0017,0.041,10,10,0.014,25,25,0.05,4.4e-05,3.5e-05,2.2e-06,0.04,0.04,0.00066,0.0013,4.7e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 -9890000,0.98,-0.0061,-0.012,0.18,0.0082,0.041,-0.0017,0,0,-4.9e+02,-0.0014,-0.0057,-0.0001,-0.00036,0.00036,-0.14,0.2,-7.6e-06,0.43,-0.00023,-0.00035,-9.7e-05,0,0,-4.9e+02,0.0022,0.0017,0.041,8.6,8.7,0.013,22,22,0.049,4.3e-05,3.4e-05,2.2e-06,0.04,0.04,0.00063,0.0013,4.5e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 -9990000,0.98,-0.0063,-0.012,0.18,0.002,0.034,-0.001,0,0,-4.9e+02,-0.0013,-0.0058,-0.00011,-0.00036,0.00036,-0.14,0.2,-6.5e-06,0.43,-0.00013,-0.00033,-0.00013,0,0,-4.9e+02,0.0022,0.0017,0.041,8.6,8.7,0.013,24,24,0.049,4.2e-05,3.2e-05,2.2e-06,0.04,0.04,0.00061,0.0013,4.4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 -10090000,0.98,-0.0067,-0.012,0.18,0.00021,0.019,0.00017,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,-0.00036,0.00036,-0.14,0.2,-4.9e-06,0.43,-9.2e-05,-0.00026,-0.00015,0,0,-4.9e+02,0.0022,0.0017,0.041,7.4,7.5,0.013,21,21,0.048,4e-05,3.1e-05,2.2e-06,0.04,0.04,0.00059,0.0013,4.2e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 -10190000,0.98,-0.0072,-0.012,0.18,0.0047,0.0051,0.001,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00036,0.00036,-0.14,0.2,-3.3e-06,0.43,-8.4e-05,-0.00012,-0.00015,0,0,-4.9e+02,0.0022,0.0016,0.041,7.4,7.6,0.012,23,23,0.048,3.9e-05,2.9e-05,2.2e-06,0.04,0.04,0.00057,0.0013,4.1e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 -10290000,0.98,-0.0071,-0.012,0.18,0.011,0.0088,-3.6e-05,0,0,-4.9e+02,-0.0011,-0.0057,-0.00011,-0.00036,0.00036,-0.14,0.2,-3.7e-06,0.43,-0.00015,-0.00011,-0.00012,0,0,-4.9e+02,0.0022,0.0016,0.041,6.4,6.5,0.012,20,20,0.048,3.8e-05,2.8e-05,2.2e-06,0.04,0.04,0.00055,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 -10390000,0.98,-0.0071,-0.012,0.18,0.0078,0.003,-0.0025,0,0,-4.9e+02,-0.0011,-0.0057,-0.00011,-0.00029,0.00039,-0.14,0.2,-3.8e-06,0.43,-0.00019,-0.00011,-7e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.24,0.24,0.012,0.5,0.5,0.047,3.4e-05,2.6e-05,2.2e-06,0.04,0.04,0.00053,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 -10490000,0.98,-0.0073,-0.012,0.18,0.0098,0.00095,0.00026,0,0,-4.9e+02,-0.001,-0.0057,-0.00012,-0.00037,0.00026,-0.14,0.2,-3e-06,0.43,-0.00015,-6.2e-05,-9.3e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.25,0.25,0.012,0.51,0.51,0.046,3.3e-05,2.4e-05,2.2e-06,0.04,0.04,0.00051,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 -10590000,0.98,-0.007,-0.012,0.18,0.00048,-3.4e-05,0.00078,0,0,-4.9e+02,-0.0011,-0.0057,-0.00011,-0.00031,0.0002,-0.14,0.2,-3.5e-06,0.43,-0.00017,-9.8e-05,-8e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.13,0.13,0.011,0.17,0.17,0.045,3.2e-05,2.3e-05,2.2e-06,0.04,0.04,0.00049,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 -10690000,0.98,-0.0071,-0.013,0.18,0.0033,-0.0027,0.0019,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-0.0003,0.00012,-0.14,0.2,-3.2e-06,0.43,-0.0002,-5.1e-05,-7.8e-05,0,0,-4.9e+02,0.002,0.0014,0.041,0.13,0.14,0.011,0.17,0.17,0.045,3.1e-05,2.2e-05,2.2e-06,0.04,0.04,0.00048,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 -10790000,0.98,-0.0073,-0.013,0.18,0.0058,-0.006,0.003,0,0,-4.9e+02,-0.001,-0.0056,-0.00011,-0.0002,-1e-05,-0.14,0.2,-3.1e-06,0.43,-0.00024,1e-05,-0.0001,0,0,-4.9e+02,0.0019,0.0014,0.041,0.09,0.095,0.011,0.11,0.11,0.044,2.8e-05,2e-05,2.2e-06,0.04,0.04,0.00046,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 -10890000,0.98,-0.0069,-0.013,0.18,0.0079,-0.0029,0.0025,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-4.2e-05,9.2e-05,-0.14,0.2,-4e-06,0.43,-0.0003,-2.8e-05,-8.1e-05,0,0,-4.9e+02,0.0019,0.0014,0.041,0.097,0.1,0.01,0.11,0.11,0.044,2.7e-05,1.9e-05,2.2e-06,0.04,0.04,0.00044,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 -10990000,0.98,-0.0069,-0.013,0.18,0.0053,0.0032,0.0039,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-0.0002,8.6e-05,-0.14,0.2,-4e-06,0.43,-0.00024,-5.9e-05,-0.00013,0,0,-4.9e+02,0.0018,0.0013,0.04,0.074,0.081,0.01,0.079,0.079,0.043,2.5e-05,1.8e-05,2.2e-06,0.04,0.04,0.00043,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 -11090000,0.98,-0.0075,-0.013,0.18,0.0091,0.0017,0.0063,0,0,-4.9e+02,-0.001,-0.0056,-0.00011,-0.00036,-0.00013,-0.14,0.2,-2.9e-06,0.43,-0.00022,1.9e-05,-0.00011,0,0,-4.9e+02,0.0018,0.0013,0.04,0.082,0.092,0.01,0.084,0.085,0.043,2.4e-05,1.7e-05,2.2e-06,0.04,0.04,0.00042,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 -11190000,0.98,-0.0077,-0.013,0.18,0.008,0.0024,0.0095,0,0,-4.9e+02,-0.00098,-0.0057,-0.00012,-0.0005,-4.9e-05,-0.14,0.2,-2.4e-06,0.43,-0.00015,-8.5e-06,-0.00013,0,0,-4.9e+02,0.0016,0.0012,0.04,0.066,0.075,0.0097,0.065,0.066,0.042,2.1e-05,1.5e-05,2.2e-06,0.04,0.04,0.0004,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 -11290000,0.98,-0.0077,-0.012,0.18,0.0063,-0.0001,0.011,0,0,-4.9e+02,-0.00097,-0.0057,-0.00012,-0.0006,0.00011,-0.14,0.2,-2.3e-06,0.43,-9.1e-05,-4.8e-05,-0.00016,0,0,-4.9e+02,0.0016,0.0012,0.04,0.074,0.087,0.0096,0.071,0.072,0.042,2.1e-05,1.5e-05,2.2e-06,0.04,0.04,0.00039,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 -11390000,0.98,-0.0076,-0.012,0.18,0.0043,0.00097,0.0084,0,0,-4.9e+02,-0.00098,-0.0058,-0.00012,-0.00061,3.5e-05,-0.14,0.2,-2.4e-06,0.43,-6.8e-05,-5.8e-05,-0.00018,0,0,-4.9e+02,0.0015,0.0011,0.04,0.062,0.073,0.0093,0.058,0.058,0.042,1.8e-05,1.3e-05,2.2e-06,0.04,0.039,0.00038,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 -11490000,0.98,-0.0075,-0.012,0.18,0.0049,-0.00048,0.011,0,0,-4.9e+02,-0.00098,-0.0057,-0.00012,-0.00059,-5.9e-05,-0.14,0.2,-2.4e-06,0.43,-8.9e-05,-3.8e-05,-0.00018,0,0,-4.9e+02,0.0015,0.0011,0.04,0.07,0.085,0.0092,0.063,0.064,0.041,1.7e-05,1.3e-05,2.2e-06,0.04,0.039,0.00037,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 -11590000,0.98,-0.0076,-0.012,0.18,0.0045,-0.00043,0.012,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00067,6.8e-05,-0.14,0.2,-2.4e-06,0.43,-4.3e-05,-7.8e-05,-0.0002,0,0,-4.9e+02,0.0013,0.001,0.04,0.06,0.071,0.009,0.053,0.054,0.041,1.5e-05,1.1e-05,2.2e-06,0.039,0.039,0.00036,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 -11690000,0.98,-0.0075,-0.012,0.18,0.004,0.002,0.014,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00062,0.0002,-0.14,0.2,-2.6e-06,0.43,-3.8e-05,-9.4e-05,-0.00022,0,0,-4.9e+02,0.0013,0.001,0.04,0.068,0.083,0.0089,0.059,0.06,0.041,1.4e-05,1.1e-05,2.2e-06,0.039,0.039,0.00035,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 -11790000,0.98,-0.0075,-0.012,0.18,0.0026,0.0028,0.015,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-7.1e-05,0.00018,-0.14,0.2,-2.7e-06,0.43,-5.2e-05,-9.8e-05,-0.00023,0,0,-4.9e+02,0.0012,0.00094,0.039,0.058,0.069,0.0087,0.05,0.051,0.04,1.2e-05,9.2e-06,2.2e-06,0.039,0.039,0.00034,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 -11890000,0.98,-0.0076,-0.012,0.18,0.0038,0.0015,0.013,0,0,-4.9e+02,-0.001,-0.0059,-0.00012,-0.00028,0.00036,-0.14,0.2,-2.6e-06,0.43,-2.3e-05,-0.0001,-0.00026,0,0,-4.9e+02,0.0012,0.00094,0.039,0.066,0.08,0.0086,0.056,0.058,0.04,1.2e-05,8.9e-06,2.2e-06,0.039,0.039,0.00034,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 -11990000,0.98,-0.0077,-0.012,0.18,0.0066,0.0036,0.013,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00033,0.00051,-0.14,0.2,-2.8e-06,0.43,-4.1e-05,-0.00011,-0.00026,0,0,-4.9e+02,0.001,0.00087,0.039,0.056,0.067,0.0084,0.048,0.049,0.04,9.9e-06,7.7e-06,2.2e-06,0.039,0.039,0.00033,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 -12090000,0.98,-0.0077,-0.012,0.18,0.0097,0.0013,0.015,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00052,0.00025,-0.14,0.2,-2.6e-06,0.43,-4e-05,-7.5e-05,-0.00026,0,0,-4.9e+02,0.001,0.00086,0.039,0.064,0.077,0.0084,0.055,0.056,0.039,9.7e-06,7.5e-06,2.2e-06,0.039,0.039,0.00032,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 -12190000,0.98,-0.0077,-0.012,0.18,0.011,0.0001,0.014,0,0,-4.9e+02,-0.00098,-0.0058,-0.00012,-0.0012,-0.00041,-0.14,0.2,-2.4e-06,0.43,-4.8e-06,-4e-05,-0.00028,0,0,-4.9e+02,0.00093,0.0008,0.039,0.054,0.064,0.0082,0.047,0.048,0.039,8.1e-06,6.5e-06,2.2e-06,0.039,0.039,0.00031,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 -12290000,0.98,-0.0078,-0.012,0.18,0.0079,-0.0033,0.013,0,0,-4.9e+02,-0.00096,-0.0058,-0.00013,-0.0015,-0.00022,-0.14,0.2,-2.2e-06,0.43,2.1e-05,-4.9e-05,-0.00029,0,0,-4.9e+02,0.00093,0.0008,0.039,0.062,0.074,0.0081,0.054,0.055,0.039,8e-06,6.3e-06,2.2e-06,0.039,0.038,0.00031,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 -12390000,0.98,-0.0079,-0.012,0.18,0.0078,-0.0046,0.013,0,0,-4.9e+02,-0.00095,-0.0058,-0.00013,-0.0018,-0.0007,-0.14,0.2,-2.2e-06,0.43,4.7e-05,-2.8e-05,-0.0003,0,0,-4.9e+02,0.00083,0.00074,0.039,0.052,0.061,0.008,0.047,0.048,0.038,6.7e-06,5.5e-06,2.2e-06,0.039,0.038,0.0003,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 -12490000,0.98,-0.008,-0.012,0.18,0.0094,-0.006,0.018,0,0,-4.9e+02,-0.00093,-0.0058,-0.00013,-0.002,-0.00095,-0.14,0.2,-2.1e-06,0.43,5.5e-05,1.4e-06,-0.00031,0,0,-4.9e+02,0.00084,0.00074,0.039,0.059,0.07,0.0079,0.053,0.055,0.038,6.6e-06,5.3e-06,2.1e-06,0.039,0.038,0.0003,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 -12590000,0.98,-0.0081,-0.012,0.18,0.011,-0.0099,0.019,0,0,-4.9e+02,-0.00092,-0.0058,-0.00013,-0.0022,-0.00082,-0.14,0.2,-2e-06,0.43,6.8e-05,1.5e-06,-0.00032,0,0,-4.9e+02,0.00076,0.00069,0.039,0.05,0.058,0.0078,0.046,0.047,0.038,5.7e-06,4.7e-06,2.1e-06,0.039,0.038,0.00029,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 -12690000,0.98,-0.008,-0.012,0.18,0.012,-0.014,0.019,0,0,-4.9e+02,-0.00092,-0.0058,-0.00013,-0.0024,-0.00076,-0.14,0.2,-2e-06,0.43,7.6e-05,5.3e-06,-0.00033,0,0,-4.9e+02,0.00076,0.00069,0.039,0.057,0.066,0.0077,0.053,0.054,0.038,5.6e-06,4.6e-06,2.1e-06,0.039,0.038,0.00028,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 -12790000,0.98,-0.0081,-0.012,0.18,0.014,-0.012,0.02,0,0,-4.9e+02,-0.00093,-0.0058,-0.00013,-0.0017,-0.0012,-0.14,0.2,-2e-06,0.43,4.1e-05,3e-05,-0.00031,0,0,-4.9e+02,0.0007,0.00065,0.039,0.048,0.055,0.0076,0.046,0.047,0.037,4.8e-06,4e-06,2.1e-06,0.038,0.038,0.00028,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 -12890000,0.98,-0.0081,-0.012,0.18,0.015,-0.013,0.021,0,0,-4.9e+02,-0.00094,-0.0058,-0.00013,-0.0013,-0.0014,-0.14,0.2,-2e-06,0.43,2.1e-05,3.4e-05,-0.00029,0,0,-4.9e+02,0.0007,0.00065,0.039,0.054,0.062,0.0076,0.052,0.054,0.038,4.7e-06,3.9e-06,2.1e-06,0.038,0.038,0.00027,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 -12990000,0.98,-0.0079,-0.012,0.18,0.013,-0.0087,0.022,0,0,-4.9e+02,-0.00098,-0.0058,-0.00012,-0.0011,-0.0015,-0.14,0.2,-2.5e-06,0.43,3.4e-05,9.8e-06,-0.00031,0,0,-4.9e+02,0.00065,0.00061,0.038,0.046,0.052,0.0074,0.046,0.047,0.037,4.1e-06,3.5e-06,2.1e-06,0.038,0.037,0.00027,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 -13090000,0.98,-0.0079,-0.012,0.18,0.015,-0.0076,0.02,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.0006,-0.0017,-0.14,0.2,-2.6e-06,0.43,9.9e-06,1.5e-05,-0.0003,0,0,-4.9e+02,0.00065,0.00061,0.038,0.051,0.058,0.0074,0.052,0.054,0.037,4.1e-06,3.4e-06,2.1e-06,0.038,0.037,0.00026,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 -13190000,0.98,-0.0079,-0.012,0.18,0.0096,-0.0077,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00035,-0.0022,-0.14,0.2,-2.7e-06,0.43,3.2e-05,1.3e-05,-0.00031,0,0,-4.9e+02,0.00061,0.00058,0.038,0.044,0.049,0.0073,0.045,0.047,0.036,3.6e-06,3.1e-06,2.1e-06,0.038,0.037,0.00026,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 -13290000,0.98,-0.008,-0.012,0.18,0.011,-0.0094,0.017,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00056,-0.0027,-0.14,0.2,-2.6e-06,0.43,4e-05,3.3e-05,-0.0003,0,0,-4.9e+02,0.00061,0.00058,0.038,0.049,0.055,0.0073,0.052,0.054,0.037,3.5e-06,3e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 -13390000,0.98,-0.0079,-0.012,0.18,0.009,-0.0081,0.017,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0012,-0.0027,-0.14,0.2,-2.9e-06,0.43,7.7e-05,3e-05,-0.00034,0,0,-4.9e+02,0.00057,0.00055,0.038,0.042,0.046,0.0071,0.045,0.046,0.036,3.1e-06,2.7e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 -13490000,0.98,-0.0079,-0.012,0.18,0.011,-0.0068,0.017,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0012,-0.0032,-0.14,0.2,-2.8e-06,0.43,7.9e-05,5.3e-05,-0.00035,0,0,-4.9e+02,0.00057,0.00055,0.038,0.046,0.052,0.0071,0.052,0.053,0.036,3.1e-06,2.7e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 -13590000,0.98,-0.0079,-0.012,0.18,0.014,-0.0071,0.018,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.0017,-0.0033,-0.14,0.2,-2.8e-06,0.43,8.7e-05,4.5e-05,-0.00034,0,0,-4.9e+02,0.00054,0.00053,0.038,0.04,0.044,0.007,0.045,0.046,0.036,2.8e-06,2.4e-06,2.1e-06,0.038,0.037,0.00024,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 -13690000,0.98,-0.0078,-0.012,0.18,0.014,-0.0082,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0014,-0.003,-0.14,0.2,-2.7e-06,0.43,7.4e-05,2.5e-05,-0.00032,0,0,-4.9e+02,0.00054,0.00053,0.038,0.044,0.048,0.007,0.052,0.053,0.036,2.8e-06,2.4e-06,2.1e-06,0.038,0.036,0.00024,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 -13790000,0.98,-0.0078,-0.012,0.18,0.019,-0.0045,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0018,-0.0024,-0.14,0.2,-3e-06,0.43,7.2e-05,3.8e-06,-0.00033,0,0,-4.9e+02,0.00052,0.00051,0.038,0.038,0.041,0.0069,0.045,0.046,0.036,2.5e-06,2.2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 -13890000,0.98,-0.0076,-0.012,0.18,0.019,-0.0031,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0012,-0.0019,-0.14,0.2,-3.2e-06,0.43,5e-05,-1.1e-05,-0.00033,0,0,-4.9e+02,0.00052,0.00051,0.038,0.042,0.046,0.0069,0.051,0.053,0.036,2.5e-06,2.2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 -13990000,0.98,-0.0076,-0.012,0.18,0.019,-0.0012,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00064,-0.0023,-0.14,0.2,-3.1e-06,0.43,5.7e-05,-1.4e-05,-0.0003,0,0,-4.9e+02,0.0005,0.0005,0.038,0.036,0.039,0.0068,0.045,0.046,0.035,2.3e-06,2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 -14090000,0.98,-0.0077,-0.011,0.18,0.017,-0.0084,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0024,-0.0021,-0.14,0.2,-3e-06,0.43,0.00011,-6.8e-06,-0.00034,0,0,-4.9e+02,0.0005,0.0005,0.038,0.04,0.043,0.0068,0.051,0.052,0.035,2.3e-06,2e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 -14190000,0.98,-0.0078,-0.011,0.18,0.016,-0.0078,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00014,-0.0035,-0.0033,-0.14,0.2,-2.8e-06,0.43,0.00016,1.8e-05,-0.00036,0,0,-4.9e+02,0.00048,0.00048,0.038,0.034,0.037,0.0067,0.045,0.046,0.035,2.1e-06,1.9e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 -14290000,0.98,-0.0078,-0.011,0.18,0.018,-0.0084,0.017,0,0,-4.9e+02,-0.00099,-0.0058,-0.00014,-0.0036,-0.0035,-0.14,0.2,-2.8e-06,0.43,0.00017,2.1e-05,-0.00036,0,0,-4.9e+02,0.00048,0.00049,0.038,0.037,0.04,0.0067,0.051,0.052,0.035,2.1e-06,1.8e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 -14390000,0.98,-0.0078,-0.011,0.18,0.018,-0.0098,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0033,-0.0043,-0.14,0.2,-2.6e-06,0.43,0.00017,2.6e-05,-0.00034,0,0,-4.9e+02,0.00047,0.00047,0.038,0.033,0.035,0.0066,0.045,0.046,0.035,1.9e-06,1.7e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 -14490000,0.98,-0.008,-0.011,0.18,0.018,-0.011,0.022,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0044,-0.0044,-0.14,0.2,-2.5e-06,0.43,0.0002,3.4e-05,-0.00036,0,0,-4.9e+02,0.00047,0.00047,0.038,0.036,0.038,0.0066,0.051,0.052,0.035,1.9e-06,1.7e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 -14590000,0.98,-0.0081,-0.011,0.18,0.017,-0.011,0.019,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0049,-0.0056,-0.14,0.2,-2.4e-06,0.43,0.00025,5.2e-05,-0.00037,0,0,-4.9e+02,0.00046,0.00046,0.038,0.031,0.033,0.0065,0.045,0.045,0.035,1.8e-06,1.6e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 -14690000,0.98,-0.0082,-0.011,0.18,0.017,-0.011,0.019,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0048,-0.0061,-0.14,0.2,-2.3e-06,0.43,0.00025,5.8e-05,-0.00036,0,0,-4.9e+02,0.00046,0.00046,0.038,0.034,0.036,0.0065,0.05,0.051,0.034,1.8e-06,1.6e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 -14790000,0.98,-0.0082,-0.011,0.18,0.019,-0.0038,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00014,-0.0041,-0.0075,-0.14,0.2,-2.5e-06,0.43,0.00025,5.6e-05,-0.00034,0,0,-4.9e+02,0.00045,0.00045,0.038,0.029,0.031,0.0064,0.044,0.045,0.034,1.7e-06,1.5e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 -14890000,0.98,-0.0082,-0.011,0.18,0.021,-0.006,0.023,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0036,-0.0091,-0.14,0.2,-2.1e-06,0.43,0.00025,7.8e-05,-0.0003,0,0,-4.9e+02,0.00045,0.00045,0.038,0.032,0.034,0.0064,0.05,0.051,0.034,1.7e-06,1.5e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 -14990000,0.98,-0.0084,-0.011,0.18,0.02,-0.0062,0.026,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0034,-0.011,-0.14,0.2,-1.8e-06,0.43,0.00027,0.00011,-0.00028,0,0,-4.9e+02,0.00044,0.00045,0.038,0.028,0.03,0.0063,0.044,0.045,0.034,1.6e-06,1.4e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 -15090000,0.98,-0.0083,-0.011,0.18,0.021,-0.0055,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0035,-0.011,-0.14,0.2,-1.8e-06,0.43,0.00028,0.00011,-0.00028,0,0,-4.9e+02,0.00044,0.00045,0.038,0.03,0.032,0.0063,0.05,0.051,0.034,1.6e-06,1.4e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 -15190000,0.98,-0.0085,-0.011,0.18,0.019,-0.0064,0.03,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.004,-0.012,-0.14,0.2,-1.7e-06,0.43,0.00031,0.00012,-0.00028,0,0,-4.9e+02,0.00043,0.00044,0.038,0.027,0.028,0.0063,0.044,0.045,0.034,1.5e-06,1.3e-06,2.1e-06,0.037,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 -15290000,0.98,-0.0087,-0.012,0.18,0.022,-0.0071,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0035,-0.013,-0.14,0.2,-1.5e-06,0.43,0.00031,0.00015,-0.00026,0,0,-4.9e+02,0.00043,0.00044,0.038,0.029,0.031,0.0063,0.049,0.05,0.034,1.5e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 -15390000,0.98,-0.0088,-0.012,0.18,0.022,-0.0046,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.014,-0.14,0.2,-1.7e-06,0.43,0.00034,0.00017,-0.00028,0,0,-4.9e+02,0.00042,0.00043,0.038,0.026,0.027,0.0062,0.044,0.044,0.034,1.4e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 -15490000,0.98,-0.0088,-0.012,0.18,0.022,-0.0074,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.014,-0.14,0.2,-1.7e-06,0.43,0.00034,0.00017,-0.00028,0,0,-4.9e+02,0.00042,0.00043,0.038,0.028,0.029,0.0062,0.049,0.05,0.034,1.4e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 -15590000,0.98,-0.0089,-0.011,0.18,0.023,-0.0088,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0033,-0.014,-0.14,0.2,-1.7e-06,0.43,0.00033,0.00017,-0.00027,0,0,-4.9e+02,0.00041,0.00043,0.038,0.024,0.026,0.0061,0.043,0.044,0.033,1.3e-06,1.2e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 -15690000,0.98,-0.0087,-0.011,0.18,0.024,-0.011,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0023,-0.012,-0.14,0.2,-2.1e-06,0.43,0.00028,0.00011,-0.00025,0,0,-4.9e+02,0.00041,0.00043,0.038,0.026,0.028,0.0061,0.049,0.049,0.033,1.3e-06,1.2e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 -15790000,0.98,-0.0086,-0.011,0.18,0.02,-0.01,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00011,-0.0012,-0.011,-0.14,0.2,-2.5e-06,0.43,0.00027,0.0001,-0.00024,0,0,-4.9e+02,0.00041,0.00042,0.038,0.023,0.025,0.0061,0.043,0.044,0.033,1.3e-06,1.1e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 -15890000,0.98,-0.0088,-0.011,0.18,0.02,-0.0093,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0022,-0.012,-0.14,0.2,-2.3e-06,0.43,0.00031,0.00012,-0.00026,0,0,-4.9e+02,0.00041,0.00042,0.038,0.025,0.027,0.0061,0.048,0.049,0.033,1.3e-06,1.1e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 -15990000,0.98,-0.0087,-0.011,0.18,0.018,-0.0083,0.026,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0024,-0.013,-0.14,0.2,-2.4e-06,0.43,0.00035,0.00016,-0.00028,0,0,-4.9e+02,0.0004,0.00042,0.038,0.022,0.024,0.006,0.043,0.043,0.033,1.2e-06,1.1e-06,2.1e-06,0.036,0.033,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 -16090000,0.98,-0.0087,-0.011,0.18,0.019,-0.01,0.023,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0031,-0.014,-0.14,0.2,-2.3e-06,0.43,0.00037,0.00019,-0.00029,0,0,-4.9e+02,0.0004,0.00042,0.038,0.024,0.025,0.006,0.048,0.049,0.033,1.2e-06,1.1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 -16190000,0.98,-0.0087,-0.011,0.18,0.015,-0.0085,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.015,-0.14,0.2,-2.4e-06,0.43,0.00041,0.00019,-0.00031,0,0,-4.9e+02,0.0004,0.00041,0.038,0.021,0.023,0.006,0.043,0.043,0.033,1.2e-06,1.1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 -16290000,0.98,-0.0087,-0.011,0.18,0.017,-0.01,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0034,-0.014,-0.14,0.2,-2.4e-06,0.43,0.00039,0.00018,-0.0003,0,0,-4.9e+02,0.0004,0.00041,0.038,0.023,0.024,0.006,0.047,0.048,0.033,1.2e-06,1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 -16390000,0.98,-0.0087,-0.011,0.18,0.019,-0.009,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0029,-0.016,-0.14,0.2,-2.2e-06,0.43,0.00041,0.00021,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.021,0.022,0.0059,0.042,0.043,0.033,1.1e-06,1e-06,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 -16490000,0.98,-0.0089,-0.011,0.18,0.022,-0.011,0.024,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0032,-0.017,-0.14,0.2,-2e-06,0.43,0.00042,0.00022,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.022,0.023,0.0059,0.047,0.048,0.033,1.1e-06,1e-06,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 -16590000,0.98,-0.0089,-0.011,0.18,0.026,-0.011,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0031,-0.017,-0.14,0.2,-2.2e-06,0.43,0.00044,0.00023,-0.00029,0,0,-4.9e+02,0.00039,0.00041,0.038,0.02,0.021,0.0059,0.042,0.042,0.033,1.1e-06,9.7e-07,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 -16690000,0.98,-0.0089,-0.011,0.18,0.028,-0.016,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0025,-0.017,-0.14,0.2,-2.3e-06,0.43,0.00042,0.00022,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.021,0.022,0.0059,0.047,0.047,0.033,1.1e-06,9.6e-07,2e-06,0.035,0.033,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 -16790000,0.98,-0.0088,-0.011,0.18,0.028,-0.015,0.027,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0019,-0.017,-0.14,0.2,-2.6e-06,0.43,0.00042,0.00021,-0.00028,0,0,-4.9e+02,0.00038,0.0004,0.038,0.019,0.02,0.0059,0.042,0.042,0.033,1e-06,9.3e-07,2e-06,0.035,0.033,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 -16890000,0.98,-0.0087,-0.011,0.18,0.028,-0.015,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.00086,-0.016,-0.14,0.2,-2.8e-06,0.43,0.00039,0.00021,-0.00026,0,0,-4.9e+02,0.00038,0.0004,0.038,0.02,0.022,0.0059,0.046,0.047,0.033,1e-06,9.3e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 -16990000,0.98,-0.0088,-0.011,0.18,0.026,-0.015,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.0005,-0.017,-0.13,0.2,-2.8e-06,0.43,0.0004,0.00023,-0.00026,0,0,-4.9e+02,0.00038,0.0004,0.038,0.018,0.019,0.0058,0.041,0.042,0.032,1e-06,9e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 -17090000,0.98,-0.009,-0.011,0.18,0.03,-0.018,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.00088,-0.019,-0.13,0.2,-2.9e-06,0.43,0.00044,0.00029,-0.00028,0,0,-4.9e+02,0.00038,0.0004,0.038,0.02,0.021,0.0058,0.046,0.047,0.032,1e-06,8.9e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 -17190000,0.98,-0.0091,-0.011,0.18,0.028,-0.023,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0018,-0.019,-0.13,0.2,-3.4e-06,0.43,0.00048,0.0003,-0.00031,0,0,-4.9e+02,0.00038,0.0004,0.038,0.018,0.019,0.0058,0.041,0.042,0.032,9.7e-07,8.7e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 -17290000,0.98,-0.0091,-0.011,0.18,0.031,-0.024,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0025,-0.019,-0.13,0.2,-3.4e-06,0.43,0.0005,0.00032,-0.00033,0,0,-4.9e+02,0.00038,0.0004,0.038,0.019,0.02,0.0058,0.045,0.046,0.032,9.6e-07,8.6e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 -17390000,0.98,-0.009,-0.011,0.18,0.025,-0.025,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0011,-0.018,-0.13,0.2,-3.7e-06,0.43,0.00048,0.00032,-0.00032,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.018,0.0057,0.041,0.041,0.032,9.4e-07,8.4e-07,2e-06,0.035,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 -17490000,0.98,-0.009,-0.011,0.18,0.024,-0.026,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0014,-0.018,-0.13,0.2,-3.7e-06,0.43,0.00049,0.00032,-0.00033,0,0,-4.9e+02,0.00037,0.00039,0.038,0.018,0.02,0.0057,0.045,0.046,0.032,9.3e-07,8.3e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 -17590000,0.98,-0.009,-0.011,0.18,0.021,-0.023,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00092,-0.019,-0.13,0.2,-4.3e-06,0.43,0.0005,0.00031,-0.00033,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.018,0.0057,0.04,0.041,0.032,9.1e-07,8.1e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 -17690000,0.98,-0.0091,-0.011,0.18,0.022,-0.024,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00061,-0.019,-0.13,0.2,-4.1e-06,0.43,0.00048,0.00029,-0.00031,0,0,-4.9e+02,0.00037,0.00039,0.038,0.018,0.019,0.0057,0.045,0.045,0.032,9e-07,8.1e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 -17790000,0.98,-0.0091,-0.011,0.18,0.023,-0.023,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.00017,-0.019,-0.13,0.2,-4.1e-06,0.43,0.00046,0.00026,-0.00029,0,0,-4.9e+02,0.00037,0.00039,0.038,0.016,0.017,0.0057,0.04,0.041,0.032,8.8e-07,7.9e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 -17890000,0.98,-0.009,-0.011,0.18,0.026,-0.025,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.00077,-0.018,-0.13,0.2,-4e-06,0.43,0.00043,0.00024,-0.00028,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.019,0.0057,0.044,0.045,0.032,8.8e-07,7.8e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 -17990000,0.98,-0.009,-0.011,0.18,0.025,-0.021,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.0016,-0.019,-0.13,0.2,-4.1e-06,0.43,0.00043,0.00024,-0.00026,0,0,-4.9e+02,0.00037,0.00038,0.038,0.016,0.017,0.0056,0.04,0.04,0.032,8.5e-07,7.6e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 -18090000,0.98,-0.0091,-0.011,0.18,0.026,-0.023,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.0017,-0.02,-0.13,0.2,-3.9e-06,0.43,0.00042,0.00024,-0.00025,0,0,-4.9e+02,0.00037,0.00038,0.038,0.017,0.018,0.0056,0.044,0.045,0.032,8.5e-07,7.6e-07,1.9e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 -18190000,0.98,-0.0091,-0.011,0.18,0.025,-0.021,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.0033,-0.021,-0.13,0.2,-4.2e-06,0.43,0.0004,0.00026,-0.00023,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0056,0.04,0.04,0.032,8.3e-07,7.4e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 -18290000,0.98,-0.0092,-0.011,0.18,0.028,-0.022,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.0001,0.0035,-0.022,-0.13,0.2,-4e-06,0.43,0.0004,0.00027,-0.00022,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.018,0.0056,0.044,0.044,0.032,8.2e-07,7.3e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 -18390000,0.98,-0.0091,-0.011,0.18,0.027,-0.02,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.0037,-0.022,-0.13,0.2,-4.3e-06,0.43,0.0004,0.00028,-0.00023,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0056,0.039,0.04,0.032,8e-07,7.2e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 -18490000,0.98,-0.0091,-0.011,0.18,0.031,-0.021,0.027,0,0,-4.9e+02,-0.0011,-0.0058,-9.9e-05,0.0044,-0.022,-0.13,0.2,-4.3e-06,0.43,0.00039,0.00028,-0.00022,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.017,0.0056,0.043,0.044,0.032,8e-07,7.1e-07,1.9e-06,0.033,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 -18590000,0.98,-0.0089,-0.011,0.18,0.028,-0.02,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0047,-0.021,-0.13,0.2,-4.8e-06,0.43,0.00039,0.00025,-0.00022,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0055,0.039,0.04,0.032,7.8e-07,6.9e-07,1.9e-06,0.033,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 -18690000,0.98,-0.0088,-0.011,0.18,0.029,-0.02,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.7e-05,0.0056,-0.019,-0.13,0.2,-4.8e-06,0.43,0.00035,0.00022,-0.0002,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.017,0.0055,0.043,0.044,0.031,7.8e-07,6.9e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 -18790000,0.98,-0.0088,-0.011,0.18,0.026,-0.019,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.0061,-0.019,-0.13,0.2,-5.2e-06,0.43,0.00035,0.00023,-0.00021,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.016,0.0055,0.039,0.04,0.032,7.6e-07,6.7e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 -18890000,0.98,-0.0088,-0.011,0.18,0.027,-0.019,0.024,0,0,-4.9e+02,-0.0012,-0.0058,-9.9e-05,0.0059,-0.02,-0.13,0.2,-5.3e-06,0.43,0.00037,0.00025,-0.00022,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.017,0.0055,0.043,0.044,0.031,7.5e-07,6.7e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 -18990000,0.98,-0.0087,-0.011,0.18,0.024,-0.019,0.025,0,0,-4.9e+02,-0.0012,-0.0058,-9.9e-05,0.0067,-0.019,-0.13,0.2,-5.9e-06,0.43,0.00036,0.00024,-0.00022,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.039,0.039,0.031,7.4e-07,6.5e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 -19090000,0.98,-0.0088,-0.011,0.18,0.023,-0.02,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.3e-05,0.0073,-0.019,-0.13,0.2,-5.8e-06,0.43,0.00035,0.00024,-0.00021,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.032,7.3e-07,6.5e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 -19190000,0.98,-0.0086,-0.011,0.18,0.02,-0.02,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0071,-0.018,-0.13,0.2,-6.6e-06,0.43,0.00037,0.00025,-0.00023,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.038,0.039,0.031,7.2e-07,6.4e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 -19290000,0.98,-0.0087,-0.011,0.18,0.021,-0.021,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0071,-0.019,-0.13,0.2,-6.6e-06,0.43,0.00037,0.00026,-0.00024,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.031,7.1e-07,6.3e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 -19390000,0.98,-0.0087,-0.011,0.18,0.019,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0077,-0.019,-0.13,0.2,-7.1e-06,0.43,0.00037,0.00025,-0.00024,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.038,0.039,0.031,7e-07,6.2e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 -19490000,0.98,-0.0088,-0.011,0.18,0.021,-0.019,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0071,-0.02,-0.13,0.2,-6.7e-06,0.43,0.00037,0.00023,-0.00023,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.031,6.9e-07,6.1e-07,1.9e-06,0.032,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 -19590000,0.98,-0.0088,-0.011,0.18,0.018,-0.02,0.03,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0074,-0.02,-0.13,0.2,-6.9e-06,0.43,0.00037,0.00023,-0.00023,0,0,-4.9e+02,0.00035,0.00036,0.038,0.013,0.015,0.0054,0.038,0.039,0.031,6.8e-07,6e-07,1.8e-06,0.032,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 -19690000,0.98,-0.0088,-0.011,0.18,0.018,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0079,-0.021,-0.13,0.2,-6.7e-06,0.43,0.00036,0.00023,-0.00022,0,0,-4.9e+02,0.00035,0.00036,0.038,0.014,0.016,0.0054,0.042,0.043,0.031,6.7e-07,6e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 -19790000,0.98,-0.0089,-0.011,0.18,0.016,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0079,-0.021,-0.13,0.2,-7.1e-06,0.43,0.00037,0.00024,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.038,0.039,0.031,6.6e-07,5.8e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 -19890000,0.98,-0.0089,-0.011,0.18,0.017,-0.018,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0079,-0.021,-0.13,0.2,-7.1e-06,0.43,0.00037,0.00024,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.6e-07,5.8e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 -19990000,0.98,-0.0089,-0.012,0.18,0.015,-0.018,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0089,-0.02,-0.13,0.2,-7.7e-06,0.43,0.00036,0.00024,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.038,0.038,0.031,6.4e-07,5.7e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 -20090000,0.98,-0.0089,-0.012,0.18,0.017,-0.021,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.009,-0.021,-0.13,0.2,-7.6e-06,0.43,0.00036,0.00024,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.4e-07,5.7e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5.1 -20190000,0.98,-0.009,-0.012,0.18,0.017,-0.018,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00012,0.0091,-0.021,-0.13,0.2,-8.2e-06,0.43,0.00036,0.00026,-0.00025,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.037,0.038,0.031,6.2e-07,5.5e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20290000,0.98,-0.009,-0.012,0.18,0.015,-0.02,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0091,-0.022,-0.13,0.2,-8.2e-06,0.43,0.00036,0.00027,-0.00025,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.2e-07,5.5e-07,1.8e-06,0.032,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20390000,0.98,-0.0089,-0.012,0.18,0.013,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.01,-0.021,-0.13,0.2,-8.3e-06,0.43,0.00034,0.00025,-0.00024,0,0,-4.9e+02,0.00034,0.00035,0.038,0.013,0.014,0.0054,0.037,0.038,0.031,6.1e-07,5.4e-07,1.8e-06,0.032,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20490000,0.98,-0.0089,-0.012,0.18,0.0096,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.01,-0.022,-0.13,0.2,-8.1e-06,0.43,0.00034,0.00024,-0.00024,0,0,-4.9e+02,0.00034,0.00035,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.1e-07,5.4e-07,1.8e-06,0.032,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20590000,0.98,-0.0089,-0.012,0.18,0.0089,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.011,-0.022,-0.13,0.2,-8.1e-06,0.43,0.00032,0.00022,-0.00022,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.9e-07,5.2e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20690000,0.98,-0.0088,-0.012,0.18,0.0078,-0.018,0.03,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.011,-0.022,-0.13,0.2,-8.3e-06,0.43,0.00032,0.00021,-0.00023,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.015,0.0054,0.041,0.042,0.031,5.9e-07,5.2e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20790000,0.98,-0.0081,-0.012,0.18,0.0039,-0.015,0.015,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.022,-0.13,0.2,-8.7e-06,0.43,0.00031,0.00022,-0.00023,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.8e-07,5.1e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20890000,0.98,0.00095,-0.0078,0.18,4.9e-05,-0.0038,-0.1,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.022,-0.13,0.2,-9.6e-06,0.43,0.0003,0.00034,-0.00017,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.015,0.0053,0.04,0.042,0.031,5.8e-07,5.1e-07,1.8e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 -20990000,0.98,0.0043,-0.0044,0.18,-0.012,0.015,-0.24,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.023,-0.13,0.2,-9.6e-06,0.43,0.0003,0.00032,-0.00013,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.6e-07,5e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21090000,0.98,0.0027,-0.0048,0.18,-0.023,0.03,-0.36,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.013,-0.023,-0.13,0.2,-7.8e-06,0.43,0.00035,0.00013,-0.00018,0,0,-4.9e+02,0.00033,0.00035,0.038,0.014,0.015,0.0053,0.04,0.041,0.031,5.6e-07,5e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21190000,0.98,-8.3e-05,-0.0064,0.18,-0.029,0.037,-0.49,0,0,-4.9e+02,-0.0012,-0.0058,-9.1e-05,0.012,-0.024,-0.13,0.2,-7.2e-06,0.43,0.00036,0.00015,-0.00017,0,0,-4.9e+02,0.00033,0.00034,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.5e-07,4.9e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21290000,0.98,-0.0023,-0.0077,0.18,-0.028,0.039,-0.62,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.012,-0.024,-0.13,0.2,-7.9e-06,0.43,0.00035,0.00019,-9.9e-05,0,0,-4.9e+02,0.00033,0.00034,0.037,0.014,0.015,0.0053,0.04,0.041,0.031,5.5e-07,4.8e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21390000,0.98,-0.0037,-0.0083,0.18,-0.026,0.036,-0.75,0,0,-4.9e+02,-0.0012,-0.0058,-9.7e-05,0.012,-0.024,-0.13,0.2,-7.4e-06,0.43,0.00036,0.00011,-0.00011,0,0,-4.9e+02,0.00032,0.00034,0.037,0.013,0.014,0.0053,0.037,0.038,0.031,5.3e-07,4.7e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21490000,0.98,-0.0045,-0.0088,0.18,-0.021,0.033,-0.88,0,0,-4.9e+02,-0.0012,-0.0058,-9e-05,0.012,-0.024,-0.13,0.2,-7.4e-06,0.43,0.00036,0.00014,-0.00016,0,0,-4.9e+02,0.00033,0.00034,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5.3e-07,4.7e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21590000,0.98,-0.0049,-0.0087,0.18,-0.014,0.03,-1,0,0,-4.9e+02,-0.0012,-0.0058,-8.5e-05,0.013,-0.023,-0.13,0.2,-7.5e-06,0.43,0.00034,0.00019,-0.00017,0,0,-4.9e+02,0.00032,0.00034,0.037,0.013,0.015,0.0053,0.037,0.038,0.031,5.2e-07,4.6e-07,1.7e-06,0.03,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21690000,0.98,-0.0052,-0.0086,0.18,-0.011,0.025,-1.1,0,0,-4.9e+02,-0.0012,-0.0058,-7.7e-05,0.013,-0.023,-0.13,0.2,-7.4e-06,0.43,0.00031,0.00023,-0.00016,0,0,-4.9e+02,0.00032,0.00034,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5.2e-07,4.6e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21790000,0.98,-0.0055,-0.0088,0.18,-0.0062,0.021,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,-6.8e-05,0.014,-0.023,-0.13,0.2,-7.4e-06,0.43,0.00031,0.00023,-0.00021,0,0,-4.9e+02,0.00032,0.00033,0.037,0.013,0.015,0.0052,0.037,0.038,0.031,5.1e-07,4.5e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21890000,0.98,-0.0058,-0.0089,0.18,-0.0025,0.016,-1.4,0,0,-4.9e+02,-0.0012,-0.0058,-7.1e-05,0.014,-0.023,-0.13,0.2,-7.8e-06,0.43,0.00029,0.00025,-0.0002,0,0,-4.9e+02,0.00032,0.00033,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5e-07,4.5e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -21990000,0.98,-0.0064,-0.0092,0.18,-0.00049,0.011,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-6.5e-05,0.014,-0.022,-0.13,0.2,-7.5e-06,0.43,0.00031,0.00026,-0.00022,0,0,-4.9e+02,0.00031,0.00033,0.037,0.013,0.015,0.0052,0.037,0.038,0.031,4.9e-07,4.4e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22090000,0.98,-0.0071,-0.01,0.18,0.0015,0.0076,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.6e-05,0.015,-0.021,-0.13,0.2,-7.4e-06,0.43,0.00031,0.00028,-0.00023,0,0,-4.9e+02,0.00031,0.00033,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,4.9e-07,4.4e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22190000,0.98,-0.0075,-0.01,0.18,0.0073,0.0033,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.8e-05,0.015,-0.02,-0.13,0.2,-7.6e-06,0.43,0.00032,0.00029,-0.00023,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.014,0.0052,0.037,0.038,0.03,4.8e-07,4.3e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22290000,0.98,-0.0082,-0.01,0.18,0.013,-0.0025,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5e-05,0.015,-0.02,-0.13,0.2,-7.5e-06,0.43,0.00031,0.00029,-0.00023,0,0,-4.9e+02,0.00031,0.00032,0.037,0.014,0.015,0.0052,0.04,0.041,0.03,4.8e-07,4.3e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22390000,0.98,-0.0085,-0.011,0.18,0.017,-0.011,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.2e-05,0.014,-0.019,-0.13,0.2,-7.7e-06,0.43,0.00033,0.00029,-0.00025,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.014,0.0052,0.037,0.038,0.03,4.7e-07,4.2e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22490000,0.98,-0.0087,-0.011,0.18,0.022,-0.018,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.7e-05,0.014,-0.019,-0.13,0.2,-8e-06,0.43,0.00033,0.00031,-0.00027,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.7e-07,4.2e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22590000,0.98,-0.0086,-0.012,0.18,0.029,-0.025,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.8e-05,0.014,-0.02,-0.13,0.2,-7.5e-06,0.43,0.00034,0.00033,-0.00026,0,0,-4.9e+02,0.0003,0.00032,0.037,0.012,0.014,0.0052,0.036,0.038,0.03,4.6e-07,4.1e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22690000,0.98,-0.0085,-0.012,0.18,0.032,-0.03,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.1e-05,0.014,-0.02,-0.13,0.2,-7.5e-06,0.43,0.00033,0.00033,-0.00028,0,0,-4.9e+02,0.0003,0.00032,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.6e-07,4.1e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22790000,0.98,-0.0085,-0.012,0.18,0.038,-0.038,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.4e-05,0.014,-0.02,-0.13,0.2,-7.7e-06,0.43,0.00032,0.0003,-0.0003,0,0,-4.9e+02,0.0003,0.00031,0.037,0.012,0.014,0.0052,0.036,0.038,0.03,4.4e-07,4e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22890000,0.98,-0.0087,-0.013,0.18,0.042,-0.043,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.5e-05,0.014,-0.02,-0.13,0.2,-7.4e-06,0.43,0.00033,0.00031,-0.00028,0,0,-4.9e+02,0.0003,0.00031,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.4e-07,4e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -22990000,0.98,-0.0086,-0.013,0.18,0.046,-0.047,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.7e-05,0.014,-0.02,-0.13,0.2,-7.7e-06,0.43,0.00032,0.00028,-0.00026,0,0,-4.9e+02,0.0003,0.00031,0.037,0.012,0.014,0.0052,0.036,0.038,0.03,4.3e-07,3.9e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23090000,0.98,-0.0086,-0.013,0.18,0.051,-0.052,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.014,-0.019,-0.13,0.2,-7.8e-06,0.43,0.00031,0.00029,-0.00024,0,0,-4.9e+02,0.0003,0.00031,0.037,0.013,0.014,0.0052,0.04,0.041,0.03,4.3e-07,3.9e-07,1.5e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23190000,0.98,-0.0086,-0.014,0.18,0.057,-0.054,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.9e-05,0.014,-0.019,-0.13,0.2,-8.5e-06,0.43,0.00029,0.00026,-0.00024,0,0,-4.9e+02,0.00029,0.00031,0.037,0.012,0.013,0.0052,0.036,0.038,0.03,4.2e-07,3.8e-07,1.5e-06,0.028,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23290000,0.98,-0.0091,-0.014,0.18,0.062,-0.059,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.6e-05,0.014,-0.019,-0.13,0.2,-8.6e-06,0.43,0.00026,0.0003,-0.00024,0,0,-4.9e+02,0.00029,0.00031,0.037,0.013,0.014,0.0052,0.039,0.041,0.03,4.2e-07,3.8e-07,1.5e-06,0.028,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23390000,0.98,-0.009,-0.014,0.18,0.067,-0.062,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.9e-05,0.015,-0.019,-0.13,0.2,-8.8e-06,0.43,0.00027,0.00027,-0.00022,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0052,0.036,0.037,0.03,4.2e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23490000,0.98,-0.0091,-0.014,0.18,0.072,-0.064,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.1e-05,0.015,-0.019,-0.13,0.2,-8.6e-06,0.43,0.00025,0.00033,-0.00027,0,0,-4.9e+02,0.00029,0.0003,0.037,0.013,0.014,0.0052,0.039,0.041,0.03,4.2e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23590000,0.98,-0.0093,-0.014,0.18,0.075,-0.066,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.8e-05,0.015,-0.019,-0.13,0.2,-9.5e-06,0.43,0.00021,0.0003,-0.00023,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.036,0.037,0.03,4.1e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23690000,0.98,-0.01,-0.015,0.18,0.074,-0.068,-1.3,0,0,-4.9e+02,-0.0013,-0.0058,-3e-05,0.016,-0.019,-0.13,0.2,-9.3e-06,0.43,0.00019,0.00032,-0.00023,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.014,0.0052,0.039,0.041,0.03,4.1e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23790000,0.98,-0.012,-0.018,0.18,0.068,-0.064,-0.94,0,0,-4.9e+02,-0.0013,-0.0058,-2.8e-05,0.017,-0.019,-0.13,0.2,-9e-06,0.43,0.00017,0.00035,-0.00021,0,0,-4.9e+02,0.00029,0.0003,0.037,0.011,0.013,0.0051,0.036,0.037,0.03,4e-07,3.6e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23890000,0.98,-0.015,-0.022,0.18,0.064,-0.064,-0.51,0,0,-4.9e+02,-0.0013,-0.0058,-2.6e-05,0.017,-0.019,-0.13,0.2,-9e-06,0.43,0.00016,0.00037,-0.00024,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.039,0.041,0.03,4e-07,3.6e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -23990000,0.98,-0.017,-0.024,0.18,0.063,-0.063,-0.12,0,0,-4.9e+02,-0.0013,-0.0058,-3.2e-05,0.018,-0.019,-0.13,0.2,-9.1e-06,0.43,0.00012,0.00039,1.3e-05,0,0,-4.9e+02,0.00029,0.0003,0.037,0.011,0.012,0.0051,0.036,0.037,0.03,3.9e-07,3.5e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24090000,0.98,-0.017,-0.023,0.18,0.07,-0.071,0.11,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.018,-0.019,-0.13,0.2,-9e-06,0.43,0.00014,0.00036,1.5e-05,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.039,0.04,0.03,3.9e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24190000,0.98,-0.014,-0.019,0.18,0.08,-0.076,0.1,0,0,-4.9e+02,-0.0013,-0.0058,-3.6e-05,0.019,-0.019,-0.13,0.2,-8.7e-06,0.43,0.00014,0.00033,0.00011,0,0,-4.9e+02,0.00028,0.0003,0.037,0.011,0.012,0.0051,0.036,0.037,0.03,3.8e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24290000,0.98,-0.012,-0.016,0.18,0.084,-0.08,0.079,0,0,-4.9e+02,-0.0013,-0.0058,-3.4e-05,0.019,-0.019,-0.13,0.2,-8.3e-06,0.43,0.00018,0.00028,0.00011,0,0,-4.9e+02,0.00028,0.0003,0.037,0.012,0.013,0.0051,0.039,0.04,0.03,3.8e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24390000,0.98,-0.011,-0.015,0.18,0.077,-0.074,0.095,0,0,-4.9e+02,-0.0013,-0.0058,-3.2e-05,0.021,-0.019,-0.13,0.2,-6.9e-06,0.43,0.00017,0.00033,0.00017,0,0,-4.9e+02,0.00028,0.0003,0.037,0.011,0.012,0.0051,0.035,0.037,0.03,3.8e-07,3.4e-07,1.4e-06,0.027,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24490000,0.98,-0.011,-0.015,0.18,0.073,-0.071,0.093,0,0,-4.9e+02,-0.0013,-0.0058,-1.9e-05,0.021,-0.02,-0.13,0.2,-6.9e-06,0.43,9.2e-05,0.00043,0.00022,0,0,-4.9e+02,0.00028,0.0003,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.8e-07,3.4e-07,1.4e-06,0.027,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24590000,0.98,-0.012,-0.015,0.18,0.069,-0.067,0.088,0,0,-4.9e+02,-0.0013,-0.0058,-3e-05,0.023,-0.02,-0.13,0.2,-5.6e-06,0.43,0.00013,0.00041,0.00024,0,0,-4.9e+02,0.00028,0.0003,0.037,0.011,0.012,0.0051,0.035,0.037,0.03,3.7e-07,3.4e-07,1.4e-06,0.027,0.026,9.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24690000,0.98,-0.012,-0.015,0.18,0.067,-0.067,0.088,0,0,-4.9e+02,-0.0013,-0.0058,-2.8e-05,0.023,-0.02,-0.13,0.2,-5.8e-06,0.43,0.00012,0.00044,0.00023,0,0,-4.9e+02,0.00028,0.0003,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.7e-07,3.4e-07,1.4e-06,0.027,0.026,9.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24790000,0.98,-0.012,-0.014,0.18,0.064,-0.065,0.079,0,0,-4.9e+02,-0.0013,-0.0058,-3.7e-05,0.024,-0.021,-0.13,0.2,-5.2e-06,0.43,0.00011,0.00044,0.00022,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.7e-07,3.3e-07,1.4e-06,0.027,0.026,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24890000,0.98,-0.012,-0.014,0.18,0.063,-0.068,0.069,0,0,-4.9e+02,-0.0013,-0.0058,-3.1e-05,0.024,-0.021,-0.13,0.2,-5e-06,0.43,0.00011,0.00045,0.00025,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.7e-07,3.3e-07,1.4e-06,0.027,0.026,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -24990000,0.98,-0.012,-0.014,0.18,0.054,-0.065,0.062,0,0,-4.9e+02,-0.0014,-0.0058,-4.5e-05,0.026,-0.023,-0.13,0.2,-5.2e-06,0.43,7.7e-05,0.00056,0.00026,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.6e-07,3.3e-07,1.4e-06,0.027,0.026,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25090000,0.98,-0.012,-0.014,0.18,0.051,-0.064,0.059,0,0,-4.9e+02,-0.0014,-0.0058,-4.6e-05,0.026,-0.022,-0.13,0.2,-5.8e-06,0.43,6e-05,0.00063,0.0003,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.6e-07,3.3e-07,1.4e-06,0.027,0.026,9.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25190000,0.98,-0.012,-0.014,0.18,0.045,-0.058,0.059,0,0,-4.9e+02,-0.0014,-0.0058,-6.4e-05,0.027,-0.023,-0.13,0.2,-5.8e-06,0.43,3.8e-05,0.00066,0.00029,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25290000,0.98,-0.012,-0.013,0.18,0.041,-0.06,0.054,0,0,-4.9e+02,-0.0014,-0.0058,-7.1e-05,0.027,-0.023,-0.13,0.2,-6.4e-06,0.43,3.1e-05,0.00069,0.00026,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25390000,0.98,-0.012,-0.013,0.18,0.032,-0.054,0.053,0,0,-4.9e+02,-0.0014,-0.0058,-8.6e-05,0.029,-0.024,-0.13,0.2,-7.2e-06,0.43,-8.6e-06,0.00074,0.00027,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25490000,0.98,-0.013,-0.013,0.18,0.028,-0.054,0.052,0,0,-4.9e+02,-0.0014,-0.0058,-8.8e-05,0.029,-0.024,-0.13,0.2,-7e-06,0.43,-1.4e-05,0.0007,0.00025,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25590000,0.98,-0.013,-0.013,0.18,0.023,-0.05,0.053,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,0.03,-0.025,-0.13,0.2,-7.8e-06,0.43,-4.6e-05,0.00072,0.00022,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.4e-07,3.2e-07,1.3e-06,0.027,0.025,9.5e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25690000,0.98,-0.012,-0.012,0.18,0.023,-0.05,0.043,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,0.03,-0.025,-0.13,0.2,-7.9e-06,0.43,-4.1e-05,0.00074,0.00024,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.4e-07,3.1e-07,1.3e-06,0.027,0.025,9.5e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25790000,0.98,-0.012,-0.012,0.18,0.011,-0.042,0.043,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.032,-0.026,-0.13,0.2,-8.4e-06,0.43,-0.0001,0.00067,0.00022,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.4e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25890000,0.98,-0.012,-0.012,0.18,0.0058,-0.04,0.045,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.032,-0.026,-0.13,0.2,-8.6e-06,0.43,-0.00012,0.00065,0.00018,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.4e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -25990000,0.98,-0.012,-0.012,0.18,-0.0033,-0.034,0.038,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.033,-0.026,-0.13,0.2,-1e-05,0.43,-0.00018,0.00063,0.00016,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.3e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26090000,0.98,-0.012,-0.012,0.18,-0.0079,-0.034,0.037,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.033,-0.026,-0.13,0.2,-9.5e-06,0.43,-0.00017,0.00062,0.00019,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26190000,0.98,-0.012,-0.012,0.18,-0.015,-0.026,0.033,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.026,-0.13,0.2,-9.9e-06,0.43,-0.0002,0.00061,0.0002,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.3e-07,3e-07,1.2e-06,0.027,0.025,9.3e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26290000,0.98,-0.012,-0.013,0.18,-0.015,-0.026,0.027,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.034,-0.026,-0.13,0.2,-1.1e-05,0.43,-0.00021,0.00063,0.00018,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3e-07,1.2e-06,0.027,0.025,9.3e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26390000,0.98,-0.011,-0.013,0.18,-0.021,-0.018,0.031,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.036,-0.027,-0.13,0.2,-1.2e-05,0.43,-0.00025,0.0006,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.3e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26490000,0.98,-0.011,-0.013,0.18,-0.023,-0.016,0.04,0,0,-4.9e+02,-0.0014,-0.0058,-0.00016,0.036,-0.027,-0.13,0.2,-1.2e-05,0.43,-0.00025,0.00064,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26590000,0.98,-0.01,-0.013,0.18,-0.026,-0.0075,0.04,0,0,-4.9e+02,-0.0015,-0.0058,-0.00017,0.036,-0.027,-0.13,0.2,-1.3e-05,0.43,-0.00028,0.00065,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26690000,0.98,-0.01,-0.013,0.18,-0.027,-0.0036,0.039,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.036,-0.027,-0.13,0.2,-1.4e-05,0.43,-0.0003,0.00066,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26790000,0.98,-0.0099,-0.012,0.18,-0.035,0.00075,0.038,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.4e-05,0.43,-0.00032,0.00064,0.00013,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26890000,0.98,-0.0092,-0.012,0.18,-0.04,0.0036,0.034,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.4e-05,0.43,-0.00032,0.00063,0.00013,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.2e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -26990000,0.98,-0.0087,-0.013,0.18,-0.048,0.011,0.033,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.4e-05,0.43,-0.00034,0.0006,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27090000,0.98,-0.0085,-0.013,0.18,-0.05,0.017,0.036,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.037,-0.027,-0.13,0.2,-1.4e-05,0.43,-0.00034,0.0006,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27190000,0.98,-0.0086,-0.013,0.18,-0.056,0.024,0.039,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.027,-0.13,0.2,-1.5e-05,0.43,-0.00035,0.00059,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27290000,0.98,-0.0088,-0.014,0.18,-0.063,0.029,0.15,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.027,-0.13,0.2,-1.5e-05,0.43,-0.00036,0.00059,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27390000,0.98,-0.01,-0.016,0.18,-0.071,0.036,0.48,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.00042,0.00051,0.0002,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27490000,0.98,-0.012,-0.018,0.18,-0.074,0.041,0.79,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.0004,0.00048,0.0002,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.8e-07,1.1e-06,0.026,0.025,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27590000,0.98,-0.011,-0.017,0.18,-0.07,0.045,0.89,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.00037,0.00042,0.00023,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27690000,0.98,-0.01,-0.014,0.18,-0.066,0.041,0.79,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.00036,0.00041,0.00021,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27790000,0.98,-0.0088,-0.013,0.18,-0.066,0.04,0.78,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.00037,0.00037,0.00022,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27890000,0.98,-0.0085,-0.013,0.18,-0.071,0.046,0.82,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.7e-05,0.43,-0.00036,0.00037,0.00022,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -27990000,0.98,-0.0089,-0.013,0.18,-0.072,0.049,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-0.00019,0.037,-0.028,-0.13,0.2,-1.8e-05,0.43,-0.00037,0.00031,0.00024,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28090000,0.98,-0.0092,-0.013,0.18,-0.076,0.049,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.037,-0.028,-0.13,0.2,-1.8e-05,0.43,-0.00038,0.00033,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28190000,0.98,-0.0086,-0.013,0.18,-0.077,0.047,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.037,-0.028,-0.13,0.2,-1.8e-05,0.43,-0.00036,0.00031,0.00024,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28290000,0.98,-0.0082,-0.014,0.18,-0.081,0.05,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00017,0.037,-0.029,-0.13,0.2,-1.7e-05,0.43,-0.00037,0.00034,0.00021,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28390000,0.98,-0.0082,-0.014,0.18,-0.082,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00016,0.036,-0.029,-0.13,0.2,-1.8e-05,0.43,-0.00042,0.00025,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28490000,0.98,-0.0084,-0.015,0.18,-0.085,0.057,0.83,0,0,-4.9e+02,-0.0014,-0.0058,-0.00017,0.036,-0.029,-0.13,0.2,-1.8e-05,0.43,-0.00039,0.00023,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 -28590000,0.98,-0.0085,-0.015,0.18,-0.079,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.035,-0.028,-0.13,0.2,-1.8e-05,0.43,-0.00036,0.00021,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -28690000,0.98,-0.0083,-0.014,0.18,-0.078,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.036,-0.029,-0.13,0.2,-1.8e-05,0.43,-0.00033,0.00022,0.00024,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -28790000,0.98,-0.0076,-0.014,0.18,-0.076,0.055,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.029,-0.13,0.2,-1.9e-05,0.43,-0.00036,0.00011,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -28890000,0.98,-0.0074,-0.013,0.18,-0.08,0.057,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.029,-0.13,0.2,-1.9e-05,0.43,-0.00036,0.00015,0.00022,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -28990000,0.98,-0.0072,-0.014,0.18,-0.077,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.034,-0.029,-0.13,0.2,-2e-05,0.43,-0.0004,-1.6e-06,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29090000,0.98,-0.007,-0.014,0.18,-0.08,0.056,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.034,-0.029,-0.13,0.2,-1.9e-05,0.43,-0.00042,-2.1e-05,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29190000,0.98,-0.007,-0.014,0.18,-0.078,0.056,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.033,-0.029,-0.13,0.2,-2.1e-05,0.43,-0.00045,-0.00016,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29290000,0.98,-0.0072,-0.014,0.18,-0.081,0.062,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.033,-0.029,-0.13,0.2,-2.2e-05,0.43,-0.00045,-0.00018,0.00028,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29390000,0.98,-0.0077,-0.013,0.18,-0.077,0.061,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00011,0.033,-0.029,-0.13,0.2,-2.3e-05,0.43,-0.00048,-0.00031,0.00029,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,9.9e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29490000,0.98,-0.0076,-0.013,0.18,-0.08,0.062,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-9.7e-05,0.033,-0.029,-0.13,0.2,-2.3e-05,0.43,-0.00051,-0.00028,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,9.8e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29590000,0.98,-0.0075,-0.013,0.18,-0.077,0.06,0.83,0,0,-4.9e+02,-0.0014,-0.0058,-8.1e-05,0.032,-0.029,-0.13,0.2,-2.4e-05,0.43,-0.00056,-0.00039,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.7e-07,2.6e-07,9.8e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29690000,0.98,-0.0075,-0.013,0.18,-0.082,0.059,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-7.4e-05,0.032,-0.029,-0.13,0.2,-2.4e-05,0.43,-0.00057,-0.00035,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.6e-07,9.7e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29790000,0.98,-0.0074,-0.013,0.18,-0.079,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-5.8e-05,0.031,-0.029,-0.13,0.2,-2.6e-05,0.43,-0.00063,-0.00047,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.7e-07,2.5e-07,9.6e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29890000,0.98,-0.0068,-0.014,0.18,-0.08,0.055,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-5.1e-05,0.031,-0.029,-0.13,0.2,-2.6e-05,0.43,-0.00065,-0.00044,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.6e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -29990000,0.98,-0.007,-0.014,0.18,-0.075,0.051,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-4e-05,0.03,-0.03,-0.13,0.2,-2.7e-05,0.43,-0.00064,-0.0005,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.7e-07,2.5e-07,9.5e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30090000,0.98,-0.0071,-0.014,0.18,-0.076,0.051,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5e-05,0.03,-0.03,-0.13,0.2,-2.8e-05,0.43,-0.00059,-0.00056,0.0003,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.029,2.7e-07,2.5e-07,9.4e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30190000,0.98,-0.0072,-0.014,0.18,-0.071,0.047,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5.3e-05,0.029,-0.03,-0.13,0.2,-3e-05,0.43,-0.00059,-0.00079,0.00036,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.7e-07,2.5e-07,9.3e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30290000,0.98,-0.0072,-0.014,0.18,-0.071,0.047,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5.1e-05,0.029,-0.03,-0.13,0.2,-3e-05,0.43,-0.00064,-0.00084,0.00037,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.3e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30390000,0.98,-0.0072,-0.013,0.18,-0.065,0.043,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-3.4e-05,0.029,-0.031,-0.13,0.2,-3.1e-05,0.43,-0.00078,-0.0011,0.00037,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.5e-07,9.2e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30490000,0.98,-0.0072,-0.014,0.18,-0.068,0.043,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-2.8e-05,0.029,-0.031,-0.13,0.2,-3e-05,0.43,-0.00083,-0.001,0.00035,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.2e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30590000,0.98,-0.0075,-0.014,0.17,-0.064,0.04,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.2e-05,0.028,-0.031,-0.13,0.2,-3.1e-05,0.43,-0.00094,-0.0012,0.00036,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.5e-07,9.1e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30690000,0.98,-0.0079,-0.014,0.17,-0.062,0.039,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.2e-05,0.029,-0.032,-0.13,0.2,-3.1e-05,0.43,-0.00091,-0.0011,0.00035,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.038,0.039,0.029,2.6e-07,2.5e-07,9e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30790000,0.98,-0.0076,-0.014,0.17,-0.056,0.034,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-7.9e-06,0.028,-0.032,-0.13,0.2,-3.2e-05,0.43,-0.00099,-0.0013,0.00039,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.6e-07,2.4e-07,9e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30890000,0.98,-0.007,-0.014,0.17,-0.056,0.03,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.5e-05,0.029,-0.033,-0.12,0.2,-3.3e-05,0.43,-0.0009,-0.0012,0.00041,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.9e-07,0.025,0.024,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -30990000,0.98,-0.0072,-0.013,0.17,-0.048,0.025,0.81,0,0,-4.9e+02,-0.0013,-0.0057,-7.2e-06,0.028,-0.034,-0.12,0.2,-3.4e-05,0.43,-0.00093,-0.0014,0.00044,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.4e-07,8.8e-07,0.025,0.024,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31090000,0.98,-0.0074,-0.014,0.17,-0.047,0.024,0.81,0,0,-4.9e+02,-0.0013,-0.0057,-1.2e-05,0.028,-0.034,-0.12,0.2,-3.4e-05,0.43,-0.00089,-0.0013,0.00046,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.8e-07,0.025,0.024,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31190000,0.98,-0.0076,-0.014,0.17,-0.043,0.02,0.81,0,0,-4.9e+02,-0.0013,-0.0057,4.3e-06,0.028,-0.035,-0.12,0.2,-3.5e-05,0.43,-0.00099,-0.0013,0.00045,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.4e-07,8.7e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31290000,0.98,-0.0078,-0.014,0.17,-0.04,0.017,0.81,0,0,-4.9e+02,-0.0013,-0.0057,9.3e-06,0.028,-0.035,-0.12,0.2,-3.4e-05,0.43,-0.001,-0.0012,0.00044,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.6e-07,2.4e-07,8.7e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31390000,0.98,-0.0076,-0.013,0.17,-0.035,0.011,0.81,0,0,-4.9e+02,-0.0013,-0.0057,8.7e-06,0.027,-0.035,-0.12,0.2,-3.3e-05,0.43,-0.0011,-0.0016,0.00049,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.6e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31490000,0.98,-0.0074,-0.014,0.17,-0.036,0.0076,0.81,0,0,-4.9e+02,-0.0013,-0.0057,7.1e-06,0.028,-0.035,-0.12,0.2,-3.2e-05,0.43,-0.0012,-0.0018,0.0005,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.6e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31590000,0.98,-0.0072,-0.014,0.17,-0.032,0.0058,0.82,0,0,-4.9e+02,-0.0013,-0.0057,1.7e-05,0.027,-0.035,-0.12,0.2,-3.2e-05,0.43,-0.0013,-0.0019,0.00053,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.5e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31690000,0.98,-0.0072,-0.015,0.17,-0.035,0.0051,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.028,-0.035,-0.12,0.2,-3.1e-05,0.43,-0.0014,-0.0019,0.00051,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.4e-07,8.4e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31790000,0.99,-0.0075,-0.015,0.17,-0.026,0.0025,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3e-05,0.028,-0.036,-0.12,0.2,-3.1e-05,0.43,-0.0015,-0.0021,0.00054,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.4e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31890000,0.99,-0.0072,-0.015,0.17,-0.024,0.0003,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.4e-05,0.028,-0.036,-0.12,0.2,-3e-05,0.43,-0.0016,-0.0022,0.00056,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.4e-07,8.3e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -31990000,0.99,-0.0075,-0.015,0.17,-0.016,-0.00077,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.1e-05,0.028,-0.036,-0.12,0.2,-3e-05,0.43,-0.0016,-0.0023,0.00062,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.2e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32090000,0.99,-0.0078,-0.014,0.17,-0.018,-0.0042,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.1e-05,0.029,-0.036,-0.12,0.2,-3e-05,0.43,-0.0016,-0.0024,0.00063,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.03,2.5e-07,2.4e-07,8.2e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32190000,0.99,-0.0081,-0.015,0.17,-0.013,-0.0078,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.7e-05,0.029,-0.037,-0.12,0.2,-2.9e-05,0.43,-0.0016,-0.0025,0.00068,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.3e-07,8.1e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32290000,0.99,-0.008,-0.015,0.17,-0.012,-0.01,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.2e-05,0.029,-0.037,-0.12,0.2,-2.8e-05,0.43,-0.0017,-0.0026,0.00069,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.3e-07,8.1e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32390000,0.99,-0.0081,-0.015,0.17,-0.0059,-0.012,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.9e-05,0.03,-0.037,-0.12,0.2,-2.6e-05,0.43,-0.0018,-0.0029,0.00075,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.3e-07,8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32490000,0.99,-0.011,-0.013,0.17,0.019,-0.078,-0.062,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.03,-0.037,-0.12,0.2,-2.7e-05,0.43,-0.0017,-0.0028,0.00074,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.014,0.0049,0.038,0.039,0.029,2.5e-07,2.3e-07,8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32590000,0.99,-0.011,-0.013,0.17,0.022,-0.079,-0.065,0,0,-4.9e+02,-0.0013,-0.0057,2.4e-05,0.03,-0.037,-0.12,0.2,-2.7e-05,0.43,-0.0016,-0.0025,0.00081,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.9e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32690000,0.99,-0.011,-0.013,0.17,0.017,-0.085,-0.066,0,0,-4.9e+02,-0.0013,-0.0057,2.3e-05,0.03,-0.037,-0.12,0.2,-2.7e-05,0.43,-0.0016,-0.0025,0.00081,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.9e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 -32790000,0.99,-0.011,-0.013,0.17,0.018,-0.084,-0.067,0,0,-4.9e+02,-0.0013,-0.0057,2.1e-05,0.03,-0.037,-0.12,0.2,-2.5e-05,0.43,-0.0017,-0.0024,0.00088,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.013,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -32890000,0.99,-0.011,-0.013,0.17,0.018,-0.091,-0.069,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.03,-0.037,-0.12,0.2,-2.5e-05,0.43,-0.0017,-0.0023,0.0009,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.8e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -32990000,0.99,-0.011,-0.013,0.17,0.018,-0.089,-0.068,0,0,-4.9e+02,-0.0013,-0.0057,2.6e-05,0.03,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0017,-0.0022,0.00096,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.7e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -33090000,0.99,-0.011,-0.013,0.17,0.014,-0.094,-0.065,0,0,-4.9e+02,-0.0013,-0.0057,2.6e-05,0.029,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0017,-0.0022,0.00096,0,0,-4.9e+02,0.00028,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.7e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -33190000,0.99,-0.011,-0.013,0.17,0.012,-0.094,-0.064,0,0,-4.9e+02,-0.0014,-0.0057,1.8e-05,0.031,-0.036,-0.12,0.2,-2.2e-05,0.43,-0.0017,-0.0022,0.00098,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.6e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -33290000,0.99,-0.011,-0.013,0.17,0.0082,-0.096,-0.064,0,0,-4.9e+02,-0.0014,-0.0057,2.8e-05,0.031,-0.036,-0.12,0.2,-2.1e-05,0.43,-0.0018,-0.0022,0.001,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.6e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 -33390000,0.99,-0.01,-0.013,0.17,0.006,-0.091,-0.062,0,0,-4.9e+02,-0.0014,-0.0057,2.1e-05,0.033,-0.035,-0.12,0.2,-1.8e-05,0.43,-0.0018,-0.0022,0.0011,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.5e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.033 -33490000,0.99,-0.01,-0.013,0.17,0.00077,-0.094,-0.061,0,0,-4.9e+02,-0.0014,-0.0057,2.6e-05,0.033,-0.035,-0.12,0.2,-1.6e-05,0.43,-0.0019,-0.0023,0.0011,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.5e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.058 -33590000,0.99,-0.01,-0.013,0.17,-0.002,-0.092,-0.058,0,0,-4.9e+02,-0.0014,-0.0057,2.5e-05,0.034,-0.034,-0.12,0.2,-1.3e-05,0.43,-0.002,-0.0024,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.2e-07,7.4e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.083 -33690000,0.99,-0.01,-0.013,0.17,-0.0053,-0.095,-0.059,0,0,-4.9e+02,-0.0014,-0.0057,2.9e-05,0.034,-0.034,-0.12,0.2,-1.4e-05,0.43,-0.002,-0.0022,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.2e-07,7.4e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.11 -33790000,0.98,-0.01,-0.013,0.17,-0.0072,-0.093,-0.054,0,0,-4.9e+02,-0.0014,-0.0057,1.9e-05,0.036,-0.034,-0.12,0.2,-1.2e-05,0.43,-0.0019,-0.002,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.3e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.13 -33890000,0.98,-0.01,-0.013,0.17,-0.011,-0.094,-0.053,0,0,-4.9e+02,-0.0014,-0.0057,2.9e-05,0.036,-0.034,-0.12,0.2,-1.1e-05,0.43,-0.002,-0.002,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.2e-07,7.3e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.16 -33990000,0.98,-0.01,-0.013,0.17,-0.012,-0.089,-0.05,0,0,-4.9e+02,-0.0014,-0.0057,1.6e-05,0.038,-0.033,-0.12,0.2,-8.4e-06,0.43,-0.002,-0.002,0.0013,0,0,-4.9e+02,0.00027,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.2e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.18 -34090000,0.98,-0.0099,-0.013,0.17,-0.016,-0.093,-0.049,0,0,-4.9e+02,-0.0014,-0.0057,1.9e-05,0.038,-0.033,-0.12,0.2,-8.9e-06,0.43,-0.002,-0.0019,0.0013,0,0,-4.9e+02,0.00027,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7.2e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.21 -34190000,0.98,-0.0099,-0.014,0.17,-0.017,-0.088,-0.046,0,0,-4.9e+02,-0.0014,-0.0057,1.5e-05,0.04,-0.033,-0.12,0.2,-6.6e-06,0.43,-0.0019,-0.0017,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.1e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.23 -34290000,0.98,-0.0097,-0.014,0.17,-0.018,-0.092,-0.045,0,0,-4.9e+02,-0.0014,-0.0057,2.2e-05,0.04,-0.033,-0.12,0.2,-5.9e-06,0.43,-0.002,-0.0017,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7.1e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.26 -34390000,0.98,-0.0096,-0.014,0.17,-0.02,-0.086,-0.041,0,0,-4.9e+02,-0.0014,-0.0056,1.4e-05,0.042,-0.033,-0.12,0.2,-3.9e-06,0.43,-0.0019,-0.0017,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.28 -34490000,0.98,-0.0096,-0.014,0.17,-0.023,-0.089,-0.039,0,0,-4.9e+02,-0.0014,-0.0056,2.2e-05,0.042,-0.033,-0.12,0.2,-3.5e-06,0.43,-0.0019,-0.0016,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.31 -34590000,0.98,-0.0095,-0.013,0.17,-0.025,-0.081,0.76,0,0,-4.9e+02,-0.0014,-0.0056,1.5e-05,0.043,-0.032,-0.12,0.2,-1.1e-06,0.43,-0.0019,-0.0016,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.011,0.0048,0.035,0.036,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.33 -34690000,0.98,-0.0095,-0.013,0.17,-0.031,-0.08,1.7,0,0,-4.9e+02,-0.0014,-0.0056,1.9e-05,0.043,-0.032,-0.12,0.2,-7.3e-07,0.43,-0.002,-0.0016,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.36 -34790000,0.98,-0.0094,-0.013,0.17,-0.034,-0.071,2.7,0,0,-4.9e+02,-0.0014,-0.0056,1.2e-05,0.045,-0.033,-0.12,0.2,2e-06,0.43,-0.002,-0.0015,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.011,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.38 -34890000,0.98,-0.0093,-0.013,0.17,-0.04,-0.069,3.7,0,0,-4.9e+02,-0.0014,-0.0056,1.5e-05,0.046,-0.033,-0.12,0.2,2.1e-06,0.43,-0.002,-0.0015,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,6.8e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.41 +6990000,0.98,-0.0067,-0.012,0.18,-0.0032,0.013,-0.037,0,0,-4.9e+02,-0.0015,-0.0056,-9.4e-05,0,0,-0.13,0.2,-0.00047,0.44,0.00044,-0.00092,0.00033,0,0,-4.9e+02,0.0013,0.0012,0.056,0.16,0.16,0.031,0.097,0.097,0.066,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0026,0.0015,0.0014,0.0015,0.0016,0.0018,0.0015,1,1,1.8 +7090000,0.98,-0.0065,-0.012,0.18,-0.0041,0.017,-0.038,0,0,-4.9e+02,-0.0016,-0.0056,-9.4e-05,0,0,-0.13,0.2,-0.0001,0.44,-0.00021,-0.00026,0.00015,0,0,-4.9e+02,0.0013,0.0013,0.049,0.16,0.16,0.03,0.1,0.1,0.066,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0024,0.0014,0.00071,0.0013,0.0014,0.0016,0.0013,1,1,1.8 +7190000,0.98,-0.0065,-0.012,0.18,-0.0046,0.019,-0.037,0,0,-4.9e+02,-0.0016,-0.0056,-9.4e-05,-6.1e-05,2.9e-05,-0.13,0.2,-7.3e-05,0.43,-0.00016,-0.00034,-2.6e-05,0,0,-4.9e+02,0.0013,0.0013,0.046,0.16,0.16,0.029,0.11,0.11,0.065,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0023,0.0013,0.00046,0.0013,0.0014,0.0016,0.0013,1,1,1.8 +7290000,0.98,-0.0064,-0.012,0.18,-0.0041,0.023,-0.034,0,0,-4.9e+02,-0.0016,-0.0057,-9.4e-05,-0.00029,0.00017,-0.13,0.2,-5e-05,0.43,-0.00035,-0.00025,5.4e-05,0,0,-4.9e+02,0.0014,0.0013,0.044,0.17,0.17,0.028,0.12,0.12,0.064,6.5e-05,6.4e-05,2.2e-06,0.04,0.04,0.0022,0.0013,0.00034,0.0013,0.0014,0.0016,0.0013,1,1,1.9 +7390000,0.98,-0.0063,-0.012,0.18,-0.0015,0.00095,-0.032,0,0,-4.9e+02,-0.0016,-0.0057,-9.4e-05,-0.00036,0.00035,-0.13,0.2,-3.9e-05,0.43,-0.00045,-0.00021,8.3e-05,0,0,-4.9e+02,0.0014,0.0014,0.044,25,25,0.027,1e+02,1e+02,0.064,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.002,0.0013,0.00028,0.0013,0.0014,0.0016,0.0013,1,1,1.9 +7490000,0.98,-0.0063,-0.012,0.18,0.00099,0.0035,-0.026,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00035,-0.13,0.2,-2.9e-05,0.43,-0.00038,-0.0002,-8.7e-05,0,0,-4.9e+02,0.0015,0.0014,0.043,25,25,0.026,1e+02,1e+02,0.063,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0019,0.0013,0.00023,0.0013,0.0014,0.0016,0.0013,1,1,1.9 +7590000,0.98,-0.0064,-0.012,0.18,0.0022,0.0061,-0.023,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00035,-0.13,0.2,-2.5e-05,0.43,-0.0003,-0.00021,-1.4e-05,0,0,-4.9e+02,0.0015,0.0015,0.043,25,25,0.025,51,51,0.062,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0018,0.0013,0.00019,0.0013,0.0014,0.0016,0.0013,1,1,1.9 +7690000,0.98,-0.0064,-0.013,0.18,0.0022,0.0093,-0.022,0,0,-4.9e+02,-0.0016,-0.0056,-9.2e-05,-0.00036,0.00035,-0.13,0.2,-2.2e-05,0.43,-0.00026,-0.00022,-6.3e-07,0,0,-4.9e+02,0.0016,0.0015,0.042,25,25,0.025,52,52,0.062,6.4e-05,6.3e-05,2.2e-06,0.04,0.04,0.0017,0.0013,0.00017,0.0013,0.0014,0.0016,0.0013,1,1,2 +7790000,0.98,-0.0064,-0.013,0.18,0.0057,0.01,-0.025,0,0,-4.9e+02,-0.0015,-0.0055,-9.2e-05,-0.00036,0.00035,-0.13,0.2,-1.9e-05,0.43,-0.00016,-0.00022,-4.7e-06,0,0,-4.9e+02,0.0016,0.0016,0.042,24,24,0.024,35,35,0.061,6.3e-05,6.2e-05,2.2e-06,0.04,0.04,0.0016,0.0013,0.00015,0.0013,0.0014,0.0016,0.0013,1,1,2 +7890000,0.98,-0.0064,-0.013,0.18,0.0048,0.014,-0.025,0,0,-4.9e+02,-0.0015,-0.0055,-9.2e-05,-0.00036,0.00035,-0.13,0.2,-1.7e-05,0.43,-0.00014,-0.00022,4.3e-05,0,0,-4.9e+02,0.0016,0.0016,0.042,24,24,0.023,36,36,0.06,6.3e-05,6.2e-05,2.2e-06,0.04,0.04,0.0015,0.0013,0.00014,0.0013,0.0014,0.0016,0.0013,1,1,2 +7990000,0.98,-0.0063,-0.013,0.18,0.0034,0.017,-0.022,0,0,-4.9e+02,-0.0016,-0.0056,-9.3e-05,-0.00036,0.00035,-0.13,0.2,-1.6e-05,0.43,-0.00015,-0.00025,7.5e-05,0,0,-4.9e+02,0.0017,0.0016,0.042,24,24,0.022,28,28,0.059,6.3e-05,6.1e-05,2.2e-06,0.04,0.04,0.0015,0.0013,0.00012,0.0013,0.0014,0.0016,0.0013,1,1,2 +8090000,0.98,-0.0062,-0.013,0.18,0.0045,0.019,-0.022,0,0,-4.9e+02,-0.0015,-0.0056,-9.5e-05,-0.00036,0.00035,-0.13,0.2,-1.4e-05,0.43,-0.00012,-0.00024,0.0001,0,0,-4.9e+02,0.0017,0.0017,0.042,24,24,0.022,30,30,0.059,6.2e-05,6e-05,2.2e-06,0.04,0.04,0.0014,0.0013,0.00011,0.0013,0.0014,0.0016,0.0013,1,1,2.1 +8190000,0.98,-0.0064,-0.012,0.18,0.0055,0.022,-0.018,0,0,-4.9e+02,-0.0015,-0.0056,-9.7e-05,-0.00036,0.00035,-0.13,0.2,-1.2e-05,0.44,-8.8e-05,-0.00023,0.00015,0,0,-4.9e+02,0.0018,0.0017,0.041,23,23,0.021,24,24,0.058,6.1e-05,5.9e-05,2.2e-06,0.04,0.04,0.0013,0.0013,0.0001,0.0013,0.0014,0.0016,0.0013,1,1,2.1 +8290000,0.98,-0.0062,-0.012,0.18,0.0024,0.028,-0.017,0,0,-4.9e+02,-0.0015,-0.0058,-9.8e-05,-0.00036,0.00035,-0.13,0.2,-1.3e-05,0.43,-8.5e-05,-0.00026,7.1e-05,0,0,-4.9e+02,0.0018,0.0017,0.041,23,23,0.02,27,27,0.057,6.1e-05,5.8e-05,2.2e-06,0.04,0.04,0.0013,0.0013,9.7e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.1 +8390000,0.98,-0.0062,-0.012,0.18,-0.0019,0.028,-0.016,0,0,-4.9e+02,-0.0015,-0.0058,-9.9e-05,-0.00036,0.00035,-0.13,0.2,-1.2e-05,0.43,-9e-05,-0.00026,2.5e-05,0,0,-4.9e+02,0.0019,0.0018,0.041,21,21,0.02,23,23,0.057,6e-05,5.7e-05,2.2e-06,0.04,0.04,0.0012,0.0013,9.1e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.1 +8490000,0.98,-0.0059,-0.012,0.18,-0.0056,0.035,-0.017,0,0,-4.9e+02,-0.0016,-0.0059,-9.8e-05,-0.00036,0.00035,-0.13,0.2,-1.3e-05,0.43,-8.8e-05,-0.0003,-1.8e-06,0,0,-4.9e+02,0.0019,0.0018,0.041,21,21,0.019,25,25,0.056,5.9e-05,5.6e-05,2.2e-06,0.04,0.04,0.0011,0.0013,8.5e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 +8590000,0.98,-0.006,-0.012,0.18,0.00022,0.034,-0.012,0,0,-4.9e+02,-0.0016,-0.0057,-9.7e-05,-0.00036,0.00035,-0.14,0.2,-1.1e-05,0.43,-0.00013,-0.00025,8.5e-06,0,0,-4.9e+02,0.0019,0.0018,0.041,19,19,0.018,22,22,0.055,5.9e-05,5.5e-05,2.2e-06,0.04,0.04,0.0011,0.0013,8e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 +8690000,0.98,-0.0059,-0.012,0.18,-0.0016,0.037,-0.014,0,0,-4.9e+02,-0.0016,-0.0058,-9.7e-05,-0.00036,0.00035,-0.14,0.2,-1.1e-05,0.43,-0.00017,-0.00026,-8.2e-05,0,0,-4.9e+02,0.002,0.0018,0.041,19,19,0.018,24,24,0.055,5.8e-05,5.3e-05,2.2e-06,0.04,0.04,0.001,0.0013,7.6e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 +8790000,0.98,-0.006,-0.012,0.18,-0.0043,0.039,-0.014,0,0,-4.9e+02,-0.0016,-0.0058,-9.9e-05,-0.00036,0.00035,-0.14,0.2,-1e-05,0.43,-0.00014,-0.00026,-0.00012,0,0,-4.9e+02,0.002,0.0018,0.041,19,19,0.018,27,27,0.055,5.7e-05,5.2e-05,2.2e-06,0.04,0.04,0.00099,0.0013,7.2e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.2 +8890000,0.98,-0.006,-0.012,0.18,0.0013,0.041,-0.0094,0,0,-4.9e+02,-0.0016,-0.0057,-9.6e-05,-0.00036,0.00035,-0.14,0.2,-9.6e-06,0.43,-0.00021,-0.00025,-0.00011,0,0,-4.9e+02,0.002,0.0018,0.041,17,17,0.017,24,24,0.054,5.6e-05,5e-05,2.2e-06,0.04,0.04,0.00094,0.0013,6.8e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 +8990000,0.98,-0.0059,-0.013,0.18,0.011,0.047,-0.0086,0,0,-4.9e+02,-0.0016,-0.0056,-9.1e-05,-0.00036,0.00035,-0.14,0.2,-9e-06,0.43,-0.00032,-0.0002,-6.1e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,17,17,0.017,27,27,0.054,5.5e-05,4.9e-05,2.2e-06,0.04,0.04,0.00091,0.0013,6.5e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 +9090000,0.98,-0.0055,-0.013,0.18,0.00043,0.056,-0.0096,0,0,-4.9e+02,-0.0017,-0.0057,-9e-05,-0.00036,0.00035,-0.14,0.2,-1.1e-05,0.43,-0.00023,-0.00031,-8.2e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,15,15,0.016,24,24,0.053,5.4e-05,4.7e-05,2.2e-06,0.04,0.04,0.00087,0.0013,6.2e-05,0.0013,0.0014,0.0016,0.0013,1,1,2.3 +9190000,0.98,-0.0053,-0.013,0.18,0.0037,0.064,-0.009,0,0,-4.9e+02,-0.0018,-0.0057,-8.8e-05,-0.00036,0.00035,-0.14,0.2,-1.1e-05,0.43,-0.00026,-0.00034,-0.0001,0,0,-4.9e+02,0.0021,0.0018,0.041,15,15,0.016,27,27,0.052,5.2e-05,4.6e-05,2.2e-06,0.04,0.04,0.00083,0.0013,5.9e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.3 +9290000,0.98,-0.0053,-0.013,0.18,0.014,0.062,-0.0074,0,0,-4.9e+02,-0.0017,-0.0056,-8.6e-05,-0.00036,0.00035,-0.14,0.2,-9.7e-06,0.43,-0.00034,-0.0003,-8e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,13,13,0.015,24,24,0.052,5.1e-05,4.4e-05,2.2e-06,0.04,0.04,0.00079,0.0013,5.6e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.4 +9390000,0.98,-0.0054,-0.013,0.18,0.015,0.06,-0.0063,0,0,-4.9e+02,-0.0017,-0.0056,-8.9e-05,-0.00036,0.00035,-0.14,0.2,-8.6e-06,0.43,-0.0003,-0.00025,-3.2e-05,0,0,-4.9e+02,0.0021,0.0018,0.041,13,13,0.015,26,26,0.052,5e-05,4.2e-05,2.2e-06,0.04,0.04,0.00077,0.0013,5.4e-05,0.0013,0.0013,0.0016,0.0013,1,1,2.4 +9490000,0.98,-0.0053,-0.013,0.18,0.0095,0.061,-0.0046,0,0,-4.9e+02,-0.0017,-0.0056,-8.9e-05,-0.00036,0.00035,-0.14,0.2,-8.8e-06,0.43,-0.00028,-0.00029,-7e-05,0,0,-4.9e+02,0.0022,0.0018,0.041,12,12,0.015,23,23,0.051,4.9e-05,4e-05,2.2e-06,0.04,0.04,0.00074,0.0013,5.2e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.4 +9590000,0.98,-0.0057,-0.013,0.18,0.0086,0.052,-0.0045,0,0,-4.9e+02,-0.0016,-0.0057,-9.5e-05,-0.00036,0.00035,-0.14,0.2,-6.5e-06,0.43,-0.00025,-0.00023,-0.00011,0,0,-4.9e+02,0.0022,0.0018,0.041,12,12,0.014,26,26,0.05,4.7e-05,3.9e-05,2.2e-06,0.04,0.04,0.00071,0.0013,5e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.4 +9690000,0.98,-0.0059,-0.013,0.18,0.01,0.047,-0.0016,0,0,-4.9e+02,-0.0015,-0.0056,-9.7e-05,-0.00036,0.00035,-0.14,0.2,-5.7e-06,0.43,-0.00025,-0.00019,-9.4e-05,0,0,-4.9e+02,0.0022,0.0018,0.041,10,10,0.014,23,23,0.05,4.6e-05,3.7e-05,2.2e-06,0.04,0.04,0.00068,0.0013,4.9e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 +9790000,0.98,-0.0061,-0.012,0.18,0.0018,0.041,-0.003,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,-0.00036,0.00035,-0.14,0.2,-4.4e-06,0.43,-0.00013,-0.00018,-0.00014,0,0,-4.9e+02,0.0022,0.0017,0.041,10,10,0.014,25,25,0.05,4.5e-05,3.6e-05,2.2e-06,0.04,0.04,0.00066,0.0013,4.7e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 +9890000,0.98,-0.0061,-0.012,0.18,0.0094,0.041,-0.0017,0,0,-4.9e+02,-0.0014,-0.0057,-0.0001,-0.00036,0.00035,-0.14,0.2,-4.3e-06,0.43,-0.00017,-0.00016,-8.9e-05,0,0,-4.9e+02,0.0022,0.0017,0.041,8.6,8.7,0.013,22,22,0.049,4.3e-05,3.4e-05,2.2e-06,0.04,0.04,0.00063,0.0013,4.5e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 +9990000,0.98,-0.0063,-0.012,0.18,0.0032,0.034,-0.001,0,0,-4.9e+02,-0.0013,-0.0058,-0.00011,-0.00036,0.00035,-0.14,0.2,-3.3e-06,0.43,-8e-05,-0.00015,-0.00013,0,0,-4.9e+02,0.0022,0.0017,0.041,8.6,8.7,0.013,24,24,0.049,4.2e-05,3.3e-05,2.2e-06,0.04,0.04,0.00061,0.0013,4.4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.5 +10090000,0.98,-0.0067,-0.012,0.18,0.0014,0.019,0.00016,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,-0.00036,0.00035,-0.14,0.2,-1.9e-06,0.43,-3.9e-05,-7e-05,-0.00014,0,0,-4.9e+02,0.0022,0.0017,0.041,7.4,7.5,0.013,21,21,0.048,4.1e-05,3.1e-05,2.2e-06,0.04,0.04,0.00059,0.0013,4.2e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 +10190000,0.98,-0.0072,-0.012,0.18,0.006,0.005,0.001,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00036,0.00035,-0.14,0.2,-3e-07,0.43,-3.1e-05,6.3e-05,-0.00015,0,0,-4.9e+02,0.0022,0.0016,0.041,7.4,7.6,0.012,23,23,0.048,3.9e-05,3e-05,2.2e-06,0.04,0.04,0.00057,0.0013,4.1e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 +10290000,0.98,-0.0071,-0.012,0.18,0.012,0.0087,-3.9e-05,0,0,-4.9e+02,-0.0011,-0.0057,-0.00011,-0.00036,0.00035,-0.14,0.2,-7.8e-07,0.43,-0.0001,7.5e-05,-0.00011,0,0,-4.9e+02,0.0022,0.0016,0.041,6.4,6.5,0.012,20,20,0.048,3.8e-05,2.8e-05,2.2e-06,0.04,0.04,0.00055,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 +10390000,0.98,-0.0071,-0.013,0.18,0.0079,0.003,-0.0025,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-0.00028,0.00038,-0.14,0.2,-9.1e-07,0.43,-0.00013,7.2e-05,-6.2e-05,0,0,-4.9e+02,0.0021,0.0015,0.041,0.24,0.24,0.012,0.5,0.5,0.047,3.5e-05,2.6e-05,2.2e-06,0.04,0.04,0.00053,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.6 +10490000,0.98,-0.0073,-0.012,0.18,0.01,0.00093,0.00026,0,0,-4.9e+02,-0.001,-0.0057,-0.00012,-0.00037,0.00025,-0.14,0.2,-1e-07,0.43,-9.9e-05,0.00012,-8.5e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.25,0.25,0.012,0.51,0.51,0.046,3.3e-05,2.5e-05,2.2e-06,0.04,0.04,0.00051,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 +10590000,0.98,-0.007,-0.012,0.18,0.00065,-4.6e-05,0.00078,0,0,-4.9e+02,-0.0011,-0.0057,-0.00011,-0.0003,0.00019,-0.14,0.2,-6.7e-07,0.43,-0.00011,8.7e-05,-7.3e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.13,0.13,0.011,0.17,0.17,0.045,3.2e-05,2.3e-05,2.2e-06,0.04,0.04,0.00049,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 +10690000,0.98,-0.0072,-0.013,0.18,0.0035,-0.0027,0.0019,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-0.00029,0.00011,-0.14,0.2,-3.7e-07,0.43,-0.00014,0.00013,-7.1e-05,0,0,-4.9e+02,0.002,0.0015,0.041,0.13,0.14,0.011,0.17,0.17,0.045,3.1e-05,2.2e-05,2.2e-06,0.04,0.04,0.00048,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 +10790000,0.98,-0.0073,-0.013,0.18,0.006,-0.006,0.003,0,0,-4.9e+02,-0.001,-0.0056,-0.00011,-0.00019,-2.5e-05,-0.14,0.2,-2.2e-07,0.43,-0.00019,0.0002,-9.2e-05,0,0,-4.9e+02,0.0019,0.0014,0.041,0.09,0.095,0.011,0.11,0.11,0.044,2.9e-05,2.1e-05,2.2e-06,0.04,0.04,0.00046,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.7 +10890000,0.98,-0.0069,-0.013,0.18,0.0082,-0.0029,0.0025,0,0,-4.9e+02,-0.0011,-0.0055,-0.00011,-3.7e-05,7.7e-05,-0.14,0.2,-1.1e-06,0.43,-0.00025,0.00016,-7.4e-05,0,0,-4.9e+02,0.0019,0.0014,0.041,0.097,0.1,0.01,0.11,0.11,0.044,2.8e-05,2e-05,2.2e-06,0.04,0.04,0.00044,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 +10990000,0.98,-0.0069,-0.013,0.18,0.0056,0.0032,0.0039,0,0,-4.9e+02,-0.0011,-0.0056,-0.00011,-0.0002,6.7e-05,-0.14,0.2,-1.2e-06,0.43,-0.00018,0.00013,-0.00012,0,0,-4.9e+02,0.0018,0.0013,0.04,0.074,0.081,0.01,0.079,0.079,0.043,2.5e-05,1.8e-05,2.2e-06,0.04,0.04,0.00043,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 +11090000,0.98,-0.0075,-0.013,0.18,0.0094,0.0017,0.0063,0,0,-4.9e+02,-0.001,-0.0056,-0.00011,-0.00036,-0.00015,-0.14,0.2,-1.3e-08,0.43,-0.00017,0.00021,-0.00011,0,0,-4.9e+02,0.0018,0.0013,0.04,0.082,0.093,0.01,0.084,0.085,0.043,2.4e-05,1.7e-05,2.2e-06,0.04,0.04,0.00042,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 +11190000,0.98,-0.0077,-0.013,0.18,0.0084,0.0024,0.0095,0,0,-4.9e+02,-0.00097,-0.0057,-0.00012,-0.0005,-7.2e-05,-0.14,0.2,4.7e-07,0.43,-9.4e-05,0.00018,-0.00012,0,0,-4.9e+02,0.0016,0.0012,0.04,0.066,0.075,0.0097,0.065,0.066,0.042,2.1e-05,1.5e-05,2.2e-06,0.04,0.04,0.0004,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.8 +11290000,0.98,-0.0077,-0.012,0.18,0.0067,-0.00011,0.011,0,0,-4.9e+02,-0.00097,-0.0057,-0.00012,-0.0006,9e-05,-0.14,0.2,5.8e-07,0.43,-3.4e-05,0.00014,-0.00015,0,0,-4.9e+02,0.0016,0.0012,0.04,0.074,0.088,0.0096,0.071,0.072,0.042,2.1e-05,1.5e-05,2.2e-06,0.04,0.04,0.00039,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 +11390000,0.98,-0.0076,-0.012,0.18,0.0046,0.00097,0.0084,0,0,-4.9e+02,-0.00098,-0.0058,-0.00012,-0.00061,5e-06,-0.14,0.2,5.1e-07,0.43,-9.7e-06,0.00013,-0.00018,0,0,-4.9e+02,0.0015,0.0011,0.04,0.062,0.073,0.0093,0.058,0.058,0.042,1.8e-05,1.3e-05,2.2e-06,0.04,0.039,0.00038,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 +11490000,0.98,-0.0075,-0.012,0.18,0.0053,-0.00049,0.011,0,0,-4.9e+02,-0.00098,-0.0057,-0.00012,-0.00059,-8.8e-05,-0.14,0.2,5.2e-07,0.43,-3e-05,0.00015,-0.00017,0,0,-4.9e+02,0.0015,0.0011,0.04,0.07,0.085,0.0092,0.063,0.064,0.041,1.7e-05,1.3e-05,2.2e-06,0.04,0.039,0.00037,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 +11590000,0.98,-0.0076,-0.012,0.18,0.0048,-0.00043,0.012,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00067,3.1e-05,-0.14,0.2,5e-07,0.43,1.7e-05,0.00011,-0.00019,0,0,-4.9e+02,0.0013,0.001,0.04,0.06,0.071,0.009,0.053,0.054,0.041,1.5e-05,1.1e-05,2.2e-06,0.039,0.039,0.00036,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,2.9 +11690000,0.98,-0.0075,-0.012,0.18,0.0043,0.002,0.014,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00062,0.00016,-0.14,0.2,2.9e-07,0.43,2.2e-05,9e-05,-0.00021,0,0,-4.9e+02,0.0013,0.001,0.04,0.068,0.083,0.0089,0.059,0.06,0.041,1.4e-05,1.1e-05,2.2e-06,0.039,0.039,0.00035,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 +11790000,0.98,-0.0075,-0.012,0.18,0.0029,0.0028,0.015,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-7.1e-05,0.00014,-0.14,0.2,1.7e-07,0.43,8.8e-06,8.5e-05,-0.00022,0,0,-4.9e+02,0.0012,0.00095,0.039,0.058,0.069,0.0087,0.05,0.051,0.04,1.2e-05,9.2e-06,2.2e-06,0.039,0.039,0.00034,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 +11890000,0.98,-0.0076,-0.012,0.18,0.0041,0.0015,0.013,0,0,-4.9e+02,-0.001,-0.0059,-0.00012,-0.00028,0.00031,-0.14,0.2,3.2e-07,0.43,3.8e-05,8.3e-05,-0.00026,0,0,-4.9e+02,0.0012,0.00094,0.039,0.066,0.08,0.0086,0.056,0.058,0.04,1.2e-05,8.9e-06,2.2e-06,0.039,0.039,0.00034,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 +11990000,0.98,-0.0077,-0.012,0.18,0.0069,0.0036,0.013,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00033,0.00046,-0.14,0.2,9e-08,0.43,2.1e-05,7.7e-05,-0.00026,0,0,-4.9e+02,0.001,0.00087,0.039,0.056,0.067,0.0084,0.048,0.049,0.04,9.9e-06,7.7e-06,2.2e-06,0.039,0.039,0.00033,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3 +12090000,0.98,-0.0077,-0.012,0.18,0.01,0.0013,0.015,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00052,0.00019,-0.14,0.2,3.4e-07,0.43,2.2e-05,0.00011,-0.00025,0,0,-4.9e+02,0.001,0.00086,0.039,0.064,0.077,0.0084,0.055,0.056,0.039,9.7e-06,7.5e-06,2.2e-06,0.039,0.039,0.00032,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 +12190000,0.98,-0.0077,-0.012,0.18,0.011,0.00011,0.014,0,0,-4.9e+02,-0.00097,-0.0058,-0.00012,-0.0012,-0.00047,-0.14,0.2,4.6e-07,0.43,5.8e-05,0.00014,-0.00028,0,0,-4.9e+02,0.00093,0.0008,0.039,0.054,0.064,0.0082,0.047,0.048,0.039,8.1e-06,6.5e-06,2.2e-06,0.039,0.039,0.00031,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 +12290000,0.98,-0.0078,-0.012,0.18,0.0082,-0.0033,0.013,0,0,-4.9e+02,-0.00096,-0.0058,-0.00013,-0.0015,-0.00028,-0.14,0.2,6.6e-07,0.43,8.4e-05,0.00013,-0.00028,0,0,-4.9e+02,0.00093,0.0008,0.039,0.062,0.074,0.0081,0.054,0.055,0.039,8e-06,6.3e-06,2.2e-06,0.039,0.038,0.00031,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 +12390000,0.98,-0.0079,-0.012,0.18,0.0081,-0.0046,0.013,0,0,-4.9e+02,-0.00095,-0.0058,-0.00013,-0.0018,-0.00077,-0.14,0.2,7e-07,0.43,0.00011,0.00016,-0.0003,0,0,-4.9e+02,0.00083,0.00074,0.039,0.053,0.061,0.008,0.047,0.048,0.038,6.8e-06,5.5e-06,2.2e-06,0.039,0.038,0.0003,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.1 +12490000,0.98,-0.008,-0.012,0.18,0.0097,-0.006,0.018,0,0,-4.9e+02,-0.00093,-0.0058,-0.00013,-0.002,-0.001,-0.14,0.2,8.2e-07,0.43,0.00012,0.00019,-0.00031,0,0,-4.9e+02,0.00084,0.00074,0.039,0.059,0.07,0.0079,0.053,0.055,0.038,6.6e-06,5.4e-06,2.1e-06,0.039,0.038,0.0003,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 +12590000,0.98,-0.0081,-0.012,0.18,0.012,-0.0099,0.019,0,0,-4.9e+02,-0.00092,-0.0058,-0.00013,-0.0022,-0.00089,-0.14,0.2,9.3e-07,0.43,0.00013,0.00019,-0.00032,0,0,-4.9e+02,0.00076,0.00069,0.039,0.051,0.058,0.0078,0.046,0.047,0.038,5.7e-06,4.7e-06,2.1e-06,0.039,0.038,0.00029,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 +12690000,0.98,-0.008,-0.012,0.18,0.012,-0.014,0.019,0,0,-4.9e+02,-0.00091,-0.0058,-0.00013,-0.0024,-0.00084,-0.14,0.2,9.4e-07,0.43,0.00014,0.00019,-0.00033,0,0,-4.9e+02,0.00076,0.00069,0.039,0.057,0.066,0.0077,0.053,0.054,0.038,5.6e-06,4.6e-06,2.1e-06,0.039,0.038,0.00028,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 +12790000,0.98,-0.0081,-0.012,0.18,0.014,-0.012,0.02,0,0,-4.9e+02,-0.00093,-0.0058,-0.00013,-0.0017,-0.0013,-0.14,0.2,9.2e-07,0.43,0.00011,0.00021,-0.0003,0,0,-4.9e+02,0.0007,0.00065,0.039,0.048,0.055,0.0076,0.046,0.047,0.037,4.8e-06,4e-06,2.1e-06,0.038,0.038,0.00028,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.2 +12890000,0.98,-0.0081,-0.012,0.18,0.016,-0.013,0.021,0,0,-4.9e+02,-0.00094,-0.0058,-0.00013,-0.0013,-0.0015,-0.14,0.2,8.6e-07,0.43,8.7e-05,0.00022,-0.00029,0,0,-4.9e+02,0.0007,0.00065,0.039,0.054,0.062,0.0076,0.052,0.054,0.038,4.7e-06,4e-06,2.1e-06,0.038,0.038,0.00027,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 +12990000,0.98,-0.0079,-0.012,0.18,0.013,-0.0087,0.022,0,0,-4.9e+02,-0.00098,-0.0058,-0.00012,-0.0011,-0.0016,-0.14,0.2,3.6e-07,0.43,9.9e-05,0.00019,-0.00031,0,0,-4.9e+02,0.00065,0.00061,0.038,0.046,0.052,0.0074,0.046,0.047,0.037,4.1e-06,3.5e-06,2.1e-06,0.038,0.037,0.00027,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 +13090000,0.98,-0.0079,-0.012,0.18,0.015,-0.0076,0.02,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.0006,-0.0018,-0.14,0.2,2.8e-07,0.43,7.5e-05,0.0002,-0.0003,0,0,-4.9e+02,0.00065,0.00061,0.038,0.052,0.058,0.0074,0.052,0.054,0.037,4.1e-06,3.4e-06,2.1e-06,0.038,0.037,0.00026,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 +13190000,0.98,-0.0079,-0.012,0.18,0.0098,-0.0077,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00035,-0.0022,-0.14,0.2,1.7e-07,0.43,9.8e-05,0.00019,-0.0003,0,0,-4.9e+02,0.00061,0.00058,0.038,0.044,0.049,0.0073,0.046,0.047,0.036,3.6e-06,3.1e-06,2.1e-06,0.038,0.037,0.00026,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.3 +13290000,0.98,-0.008,-0.012,0.18,0.011,-0.0094,0.017,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.00056,-0.0028,-0.14,0.2,3e-07,0.43,0.00011,0.00021,-0.0003,0,0,-4.9e+02,0.00061,0.00058,0.038,0.049,0.055,0.0073,0.052,0.054,0.037,3.5e-06,3e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 +13390000,0.98,-0.0079,-0.012,0.18,0.0092,-0.0081,0.017,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0012,-0.0028,-0.14,0.2,2.4e-08,0.43,0.00014,0.00021,-0.00034,0,0,-4.9e+02,0.00057,0.00055,0.038,0.042,0.046,0.0071,0.045,0.046,0.036,3.1e-06,2.7e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 +13490000,0.98,-0.0079,-0.012,0.18,0.011,-0.0068,0.017,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.0012,-0.0033,-0.14,0.2,6.2e-08,0.43,0.00015,0.00024,-0.00034,0,0,-4.9e+02,0.00057,0.00055,0.038,0.046,0.052,0.0071,0.052,0.053,0.036,3.1e-06,2.7e-06,2.1e-06,0.038,0.037,0.00025,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 +13590000,0.98,-0.0079,-0.012,0.18,0.014,-0.0071,0.018,0,0,-4.9e+02,-0.00099,-0.0058,-0.00012,-0.0017,-0.0034,-0.14,0.2,1.4e-07,0.43,0.00015,0.00023,-0.00034,0,0,-4.9e+02,0.00054,0.00053,0.038,0.04,0.044,0.007,0.045,0.046,0.036,2.8e-06,2.5e-06,2.1e-06,0.038,0.037,0.00024,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.4 +13690000,0.98,-0.0078,-0.012,0.18,0.014,-0.0082,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0014,-0.0031,-0.14,0.2,1.6e-07,0.43,0.00014,0.00021,-0.00032,0,0,-4.9e+02,0.00054,0.00053,0.038,0.044,0.048,0.007,0.052,0.053,0.036,2.8e-06,2.4e-06,2.1e-06,0.038,0.036,0.00024,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 +13790000,0.98,-0.0078,-0.012,0.18,0.019,-0.0045,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0019,-0.0025,-0.14,0.2,-8.1e-08,0.43,0.00014,0.00019,-0.00033,0,0,-4.9e+02,0.00052,0.00051,0.038,0.038,0.041,0.0069,0.045,0.046,0.036,2.5e-06,2.2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 +13890000,0.98,-0.0076,-0.012,0.18,0.019,-0.0031,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0012,-0.002,-0.14,0.2,-2.8e-07,0.43,0.00012,0.00017,-0.00033,0,0,-4.9e+02,0.00052,0.00051,0.038,0.042,0.046,0.0069,0.051,0.053,0.036,2.5e-06,2.2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 +13990000,0.98,-0.0076,-0.012,0.18,0.019,-0.0012,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.00064,-0.0024,-0.14,0.2,-1.8e-07,0.43,0.00012,0.00017,-0.0003,0,0,-4.9e+02,0.0005,0.0005,0.038,0.036,0.039,0.0068,0.045,0.046,0.035,2.3e-06,2e-06,2.1e-06,0.038,0.036,0.00023,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.5 +14090000,0.98,-0.0077,-0.011,0.18,0.017,-0.0084,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0024,-0.0022,-0.14,0.2,-9.8e-08,0.43,0.00018,0.00018,-0.00034,0,0,-4.9e+02,0.0005,0.0005,0.038,0.04,0.043,0.0068,0.051,0.052,0.035,2.3e-06,2e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 +14190000,0.98,-0.0078,-0.011,0.18,0.016,-0.0078,0.019,0,0,-4.9e+02,-0.00099,-0.0058,-0.00014,-0.0035,-0.0034,-0.14,0.2,7.8e-08,0.43,0.00023,0.0002,-0.00036,0,0,-4.9e+02,0.00048,0.00048,0.038,0.034,0.037,0.0067,0.045,0.046,0.035,2.1e-06,1.9e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 +14290000,0.98,-0.0078,-0.011,0.18,0.018,-0.0084,0.017,0,0,-4.9e+02,-0.00099,-0.0058,-0.00014,-0.0036,-0.0036,-0.14,0.2,1.6e-07,0.43,0.00023,0.0002,-0.00035,0,0,-4.9e+02,0.00048,0.00049,0.038,0.037,0.04,0.0067,0.051,0.052,0.035,2.1e-06,1.8e-06,2.1e-06,0.037,0.036,0.00022,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 +14390000,0.98,-0.0078,-0.011,0.18,0.018,-0.0098,0.018,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0034,-0.0044,-0.14,0.2,2.8e-07,0.43,0.00024,0.00021,-0.00034,0,0,-4.9e+02,0.00047,0.00047,0.038,0.033,0.035,0.0066,0.045,0.046,0.035,1.9e-06,1.7e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.6 +14490000,0.98,-0.008,-0.011,0.18,0.018,-0.011,0.022,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0044,-0.0045,-0.14,0.2,4.4e-07,0.43,0.00027,0.00022,-0.00035,0,0,-4.9e+02,0.00047,0.00047,0.038,0.036,0.038,0.0066,0.051,0.052,0.035,1.9e-06,1.7e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 +14590000,0.98,-0.0081,-0.011,0.18,0.017,-0.011,0.019,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0049,-0.0058,-0.14,0.2,5.4e-07,0.43,0.00032,0.00023,-0.00036,0,0,-4.9e+02,0.00046,0.00046,0.038,0.031,0.033,0.0065,0.045,0.045,0.035,1.8e-06,1.6e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 +14690000,0.98,-0.0082,-0.011,0.18,0.017,-0.011,0.019,0,0,-4.9e+02,-0.00098,-0.0058,-0.00014,-0.0048,-0.0062,-0.14,0.2,6.3e-07,0.43,0.00032,0.00024,-0.00036,0,0,-4.9e+02,0.00046,0.00046,0.038,0.034,0.036,0.0065,0.05,0.051,0.034,1.8e-06,1.6e-06,2.1e-06,0.037,0.035,0.00021,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 +14790000,0.98,-0.0082,-0.011,0.18,0.02,-0.0038,0.019,0,0,-4.9e+02,-0.001,-0.0058,-0.00014,-0.0041,-0.0076,-0.14,0.2,4.6e-07,0.43,0.00032,0.00024,-0.00033,0,0,-4.9e+02,0.00045,0.00045,0.038,0.029,0.031,0.0064,0.044,0.045,0.034,1.7e-06,1.5e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.7 +14890000,0.98,-0.0082,-0.011,0.18,0.021,-0.0059,0.023,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0036,-0.0092,-0.14,0.2,8.5e-07,0.43,0.00031,0.00026,-0.00029,0,0,-4.9e+02,0.00045,0.00045,0.038,0.032,0.034,0.0064,0.05,0.051,0.034,1.7e-06,1.5e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 +14990000,0.98,-0.0084,-0.011,0.18,0.02,-0.0062,0.026,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0034,-0.011,-0.14,0.2,1.1e-06,0.43,0.00034,0.00029,-0.00027,0,0,-4.9e+02,0.00044,0.00045,0.038,0.028,0.03,0.0063,0.044,0.045,0.034,1.6e-06,1.4e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 +15090000,0.98,-0.0083,-0.011,0.18,0.021,-0.0055,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0035,-0.011,-0.14,0.2,1.1e-06,0.43,0.00034,0.00029,-0.00027,0,0,-4.9e+02,0.00044,0.00045,0.038,0.03,0.032,0.0063,0.05,0.051,0.034,1.6e-06,1.4e-06,2.1e-06,0.037,0.035,0.0002,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 +15190000,0.98,-0.0085,-0.011,0.18,0.019,-0.0064,0.03,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.004,-0.012,-0.14,0.2,1.3e-06,0.43,0.00038,0.0003,-0.00028,0,0,-4.9e+02,0.00043,0.00044,0.038,0.027,0.028,0.0063,0.044,0.045,0.034,1.5e-06,1.3e-06,2.1e-06,0.037,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.8 +15290000,0.98,-0.0087,-0.012,0.18,0.022,-0.0071,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0035,-0.014,-0.14,0.2,1.4e-06,0.43,0.00037,0.00033,-0.00026,0,0,-4.9e+02,0.00043,0.00044,0.038,0.029,0.031,0.0063,0.049,0.05,0.034,1.5e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 +15390000,0.98,-0.0088,-0.012,0.18,0.022,-0.0046,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.014,-0.14,0.2,1.2e-06,0.43,0.00041,0.00035,-0.00027,0,0,-4.9e+02,0.00042,0.00043,0.038,0.026,0.027,0.0062,0.044,0.044,0.034,1.4e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 +15490000,0.98,-0.0088,-0.012,0.18,0.022,-0.0074,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.014,-0.14,0.2,1.2e-06,0.43,0.00041,0.00035,-0.00027,0,0,-4.9e+02,0.00042,0.00043,0.038,0.028,0.029,0.0062,0.049,0.05,0.034,1.4e-06,1.3e-06,2.1e-06,0.036,0.034,0.00019,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 +15590000,0.98,-0.0089,-0.011,0.18,0.023,-0.0088,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0033,-0.014,-0.14,0.2,1.2e-06,0.43,0.0004,0.00035,-0.00026,0,0,-4.9e+02,0.00041,0.00043,0.038,0.024,0.026,0.0061,0.043,0.044,0.033,1.3e-06,1.2e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,3.9 +15690000,0.98,-0.0087,-0.011,0.18,0.024,-0.011,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0023,-0.012,-0.14,0.2,8.3e-07,0.43,0.00035,0.00029,-0.00025,0,0,-4.9e+02,0.00041,0.00043,0.038,0.026,0.028,0.0061,0.049,0.049,0.033,1.3e-06,1.2e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 +15790000,0.98,-0.0086,-0.011,0.18,0.02,-0.01,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00011,-0.0012,-0.011,-0.14,0.2,3.9e-07,0.43,0.00034,0.00028,-0.00024,0,0,-4.9e+02,0.00041,0.00042,0.038,0.023,0.025,0.0061,0.043,0.044,0.033,1.3e-06,1.1e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 +15890000,0.98,-0.0088,-0.011,0.18,0.02,-0.0093,0.029,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0022,-0.012,-0.14,0.2,6.3e-07,0.43,0.00037,0.0003,-0.00026,0,0,-4.9e+02,0.00041,0.00042,0.038,0.025,0.027,0.0061,0.048,0.049,0.033,1.3e-06,1.1e-06,2.1e-06,0.036,0.034,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 +15990000,0.98,-0.0087,-0.011,0.18,0.018,-0.0083,0.026,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0024,-0.014,-0.14,0.2,4.6e-07,0.43,0.00041,0.00034,-0.00027,0,0,-4.9e+02,0.0004,0.00042,0.038,0.022,0.024,0.006,0.043,0.043,0.033,1.2e-06,1.1e-06,2.1e-06,0.036,0.033,0.00018,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4 +16090000,0.98,-0.0087,-0.011,0.18,0.02,-0.01,0.023,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0031,-0.014,-0.14,0.2,5.6e-07,0.43,0.00044,0.00037,-0.00029,0,0,-4.9e+02,0.0004,0.00042,0.038,0.024,0.025,0.006,0.048,0.049,0.033,1.2e-06,1.1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 +16190000,0.98,-0.0087,-0.011,0.18,0.015,-0.0085,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0037,-0.015,-0.14,0.2,5.1e-07,0.43,0.00048,0.00037,-0.0003,0,0,-4.9e+02,0.0004,0.00041,0.038,0.021,0.023,0.006,0.043,0.043,0.033,1.2e-06,1.1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 +16290000,0.98,-0.0087,-0.011,0.18,0.017,-0.01,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00013,-0.0034,-0.014,-0.14,0.2,4.9e-07,0.43,0.00046,0.00035,-0.0003,0,0,-4.9e+02,0.0004,0.00041,0.038,0.023,0.024,0.006,0.047,0.048,0.033,1.2e-06,1e-06,2e-06,0.036,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 +16390000,0.98,-0.0087,-0.011,0.18,0.019,-0.009,0.022,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0029,-0.017,-0.14,0.2,7.2e-07,0.43,0.00048,0.00039,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.021,0.022,0.0059,0.042,0.043,0.033,1.1e-06,1e-06,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.1 +16490000,0.98,-0.0089,-0.011,0.18,0.023,-0.011,0.024,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0032,-0.017,-0.14,0.2,9.2e-07,0.43,0.00049,0.0004,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.022,0.023,0.0059,0.047,0.048,0.033,1.1e-06,1e-06,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 +16590000,0.98,-0.0089,-0.011,0.18,0.026,-0.011,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0031,-0.017,-0.14,0.2,7.2e-07,0.43,0.0005,0.00041,-0.00028,0,0,-4.9e+02,0.00039,0.00041,0.038,0.02,0.021,0.0059,0.042,0.042,0.033,1.1e-06,9.7e-07,2e-06,0.035,0.033,0.00017,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 +16690000,0.98,-0.0089,-0.011,0.18,0.028,-0.016,0.028,0,0,-4.9e+02,-0.001,-0.0058,-0.00012,-0.0025,-0.017,-0.14,0.2,5.5e-07,0.43,0.00048,0.00039,-0.00027,0,0,-4.9e+02,0.00039,0.00041,0.038,0.021,0.022,0.0059,0.047,0.047,0.033,1.1e-06,9.6e-07,2e-06,0.035,0.033,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 +16790000,0.98,-0.0088,-0.011,0.18,0.028,-0.015,0.027,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0019,-0.017,-0.14,0.2,2.5e-07,0.43,0.00048,0.00039,-0.00027,0,0,-4.9e+02,0.00038,0.0004,0.038,0.019,0.02,0.0059,0.042,0.042,0.033,1e-06,9.4e-07,2e-06,0.035,0.033,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.2 +16890000,0.98,-0.0087,-0.011,0.18,0.028,-0.015,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.00084,-0.016,-0.14,0.2,9.5e-08,0.43,0.00045,0.00038,-0.00025,0,0,-4.9e+02,0.00038,0.0004,0.038,0.02,0.022,0.0059,0.046,0.047,0.033,1e-06,9.3e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 +16990000,0.98,-0.0088,-0.011,0.18,0.027,-0.015,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.00048,-0.017,-0.13,0.2,7.5e-08,0.43,0.00047,0.0004,-0.00025,0,0,-4.9e+02,0.00038,0.0004,0.038,0.018,0.019,0.0058,0.041,0.042,0.032,1e-06,9e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 +17090000,0.98,-0.009,-0.011,0.18,0.031,-0.018,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,-0.00087,-0.019,-0.13,0.2,2.8e-08,0.43,0.0005,0.00047,-0.00027,0,0,-4.9e+02,0.00038,0.0004,0.038,0.02,0.021,0.0058,0.046,0.047,0.032,1e-06,9e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 +17190000,0.98,-0.0091,-0.011,0.18,0.028,-0.023,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0018,-0.019,-0.13,0.2,-4.9e-07,0.43,0.00054,0.00048,-0.00031,0,0,-4.9e+02,0.00038,0.0004,0.038,0.018,0.019,0.0058,0.041,0.042,0.032,9.7e-07,8.7e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.3 +17290000,0.98,-0.0091,-0.011,0.18,0.031,-0.024,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0025,-0.019,-0.13,0.2,-5e-07,0.43,0.00057,0.00049,-0.00033,0,0,-4.9e+02,0.00038,0.0004,0.038,0.019,0.02,0.0058,0.045,0.046,0.032,9.7e-07,8.6e-07,2e-06,0.035,0.032,0.00016,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 +17390000,0.98,-0.009,-0.011,0.18,0.025,-0.025,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0011,-0.018,-0.13,0.2,-8.6e-07,0.43,0.00055,0.00049,-0.00032,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.018,0.0057,0.041,0.041,0.032,9.4e-07,8.4e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 +17490000,0.98,-0.009,-0.011,0.18,0.024,-0.026,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.0014,-0.018,-0.13,0.2,-8e-07,0.43,0.00055,0.00049,-0.00032,0,0,-4.9e+02,0.00037,0.00039,0.038,0.018,0.02,0.0057,0.045,0.046,0.032,9.3e-07,8.4e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 +17590000,0.98,-0.009,-0.011,0.18,0.022,-0.023,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00091,-0.019,-0.13,0.2,-1.5e-06,0.43,0.00057,0.00049,-0.00033,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.018,0.0057,0.04,0.041,0.032,9.1e-07,8.1e-07,2e-06,0.034,0.032,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.4 +17690000,0.98,-0.0091,-0.011,0.18,0.022,-0.024,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,-0.00059,-0.019,-0.13,0.2,-1.2e-06,0.43,0.00055,0.00046,-0.00031,0,0,-4.9e+02,0.00037,0.00039,0.038,0.018,0.019,0.0057,0.045,0.045,0.032,9e-07,8.1e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 +17790000,0.98,-0.0091,-0.011,0.18,0.023,-0.023,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.00019,-0.019,-0.13,0.2,-1.2e-06,0.43,0.00052,0.00044,-0.00029,0,0,-4.9e+02,0.00037,0.00039,0.038,0.016,0.017,0.0057,0.04,0.041,0.032,8.8e-07,7.9e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 +17890000,0.98,-0.009,-0.011,0.18,0.026,-0.025,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.0008,-0.018,-0.13,0.2,-1.2e-06,0.43,0.00049,0.00041,-0.00027,0,0,-4.9e+02,0.00037,0.00039,0.038,0.017,0.019,0.0057,0.044,0.045,0.032,8.8e-07,7.8e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 +17990000,0.98,-0.009,-0.011,0.18,0.025,-0.021,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.0016,-0.019,-0.13,0.2,-1.2e-06,0.43,0.00049,0.00042,-0.00026,0,0,-4.9e+02,0.00037,0.00038,0.038,0.016,0.017,0.0056,0.04,0.04,0.032,8.5e-07,7.6e-07,2e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.5 +18090000,0.98,-0.0091,-0.011,0.18,0.026,-0.023,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00012,0.0017,-0.02,-0.13,0.2,-1.1e-06,0.43,0.00049,0.00041,-0.00025,0,0,-4.9e+02,0.00037,0.00038,0.038,0.017,0.018,0.0056,0.044,0.045,0.032,8.5e-07,7.6e-07,1.9e-06,0.034,0.031,0.00015,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 +18190000,0.98,-0.0091,-0.011,0.18,0.025,-0.021,0.029,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.0033,-0.021,-0.13,0.2,-1.3e-06,0.43,0.00046,0.00043,-0.00023,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0056,0.04,0.04,0.032,8.3e-07,7.4e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 +18290000,0.98,-0.0092,-0.011,0.18,0.028,-0.022,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.0001,0.0035,-0.022,-0.13,0.2,-1.1e-06,0.43,0.00046,0.00044,-0.00021,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.018,0.0056,0.044,0.044,0.032,8.2e-07,7.3e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 +18390000,0.98,-0.0091,-0.011,0.18,0.027,-0.02,0.028,0,0,-4.9e+02,-0.0011,-0.0058,-0.00011,0.0038,-0.022,-0.13,0.2,-1.5e-06,0.43,0.00047,0.00045,-0.00022,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0056,0.039,0.04,0.032,8e-07,7.2e-07,1.9e-06,0.034,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.6 +18490000,0.98,-0.0091,-0.011,0.18,0.031,-0.021,0.027,0,0,-4.9e+02,-0.0011,-0.0058,-9.9e-05,0.0044,-0.022,-0.13,0.2,-1.4e-06,0.43,0.00045,0.00046,-0.00021,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.017,0.0056,0.043,0.044,0.032,8e-07,7.1e-07,1.9e-06,0.033,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 +18590000,0.98,-0.0089,-0.011,0.18,0.028,-0.02,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0047,-0.021,-0.13,0.2,-2e-06,0.43,0.00045,0.00043,-0.00021,0,0,-4.9e+02,0.00036,0.00038,0.038,0.015,0.016,0.0055,0.039,0.04,0.032,7.8e-07,7e-07,1.9e-06,0.033,0.031,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 +18690000,0.98,-0.0088,-0.011,0.18,0.029,-0.019,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.7e-05,0.0057,-0.019,-0.13,0.2,-2e-06,0.43,0.00041,0.0004,-0.00019,0,0,-4.9e+02,0.00036,0.00038,0.038,0.016,0.017,0.0055,0.043,0.044,0.031,7.8e-07,6.9e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 +18790000,0.98,-0.0088,-0.011,0.18,0.026,-0.019,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.0062,-0.019,-0.13,0.2,-2.4e-06,0.43,0.00042,0.00041,-0.0002,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.016,0.0055,0.039,0.04,0.032,7.6e-07,6.8e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.7 +18890000,0.98,-0.0088,-0.011,0.18,0.027,-0.019,0.024,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.006,-0.02,-0.13,0.2,-2.5e-06,0.43,0.00043,0.00042,-0.00021,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.017,0.0055,0.043,0.044,0.031,7.6e-07,6.7e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 +18990000,0.98,-0.0087,-0.011,0.18,0.024,-0.019,0.025,0,0,-4.9e+02,-0.0012,-0.0058,-9.9e-05,0.0067,-0.019,-0.13,0.2,-3.1e-06,0.43,0.00042,0.00041,-0.00021,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.039,0.039,0.031,7.4e-07,6.6e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 +19090000,0.98,-0.0088,-0.011,0.18,0.023,-0.02,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-9.2e-05,0.0073,-0.019,-0.13,0.2,-3e-06,0.43,0.00042,0.00042,-0.0002,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.032,7.3e-07,6.5e-07,1.9e-06,0.033,0.03,0.00014,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 +19190000,0.98,-0.0086,-0.011,0.18,0.02,-0.02,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0071,-0.019,-0.13,0.2,-3.8e-06,0.43,0.00043,0.00042,-0.00023,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.038,0.039,0.031,7.2e-07,6.4e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.8 +19290000,0.98,-0.0087,-0.011,0.18,0.021,-0.021,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0071,-0.019,-0.13,0.2,-3.8e-06,0.43,0.00044,0.00044,-0.00023,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.031,7.1e-07,6.3e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 +19390000,0.98,-0.0087,-0.011,0.18,0.019,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0077,-0.019,-0.13,0.2,-4.2e-06,0.43,0.00043,0.00043,-0.00023,0,0,-4.9e+02,0.00035,0.00037,0.038,0.014,0.015,0.0055,0.038,0.039,0.031,7e-07,6.2e-07,1.9e-06,0.033,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 +19490000,0.98,-0.0088,-0.011,0.18,0.021,-0.019,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0071,-0.02,-0.13,0.2,-3.9e-06,0.43,0.00043,0.0004,-0.00022,0,0,-4.9e+02,0.00035,0.00037,0.038,0.015,0.016,0.0055,0.042,0.043,0.031,6.9e-07,6.2e-07,1.9e-06,0.032,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 +19590000,0.98,-0.0088,-0.011,0.18,0.018,-0.02,0.03,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0074,-0.02,-0.13,0.2,-4.1e-06,0.43,0.00043,0.0004,-0.00022,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.015,0.0054,0.038,0.039,0.031,6.8e-07,6e-07,1.8e-06,0.032,0.03,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,4.9 +19690000,0.98,-0.0088,-0.011,0.18,0.018,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.0079,-0.021,-0.13,0.2,-3.8e-06,0.43,0.00043,0.0004,-0.00021,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.016,0.0054,0.042,0.043,0.031,6.8e-07,6e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 +19790000,0.98,-0.0089,-0.011,0.18,0.016,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.008,-0.021,-0.13,0.2,-4.3e-06,0.43,0.00043,0.00041,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.038,0.039,0.031,6.6e-07,5.9e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 +19890000,0.98,-0.0089,-0.011,0.18,0.017,-0.018,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.008,-0.021,-0.13,0.2,-4.3e-06,0.43,0.00043,0.00041,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.6e-07,5.8e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 +19990000,0.98,-0.0089,-0.012,0.18,0.015,-0.018,0.026,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0089,-0.02,-0.13,0.2,-4.9e-06,0.43,0.00042,0.00041,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.038,0.038,0.031,6.4e-07,5.7e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5 +20090000,0.98,-0.0089,-0.012,0.18,0.017,-0.021,0.027,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0091,-0.021,-0.13,0.2,-4.8e-06,0.43,0.00042,0.00042,-0.00023,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.4e-07,5.7e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,5.1 +20190000,0.98,-0.009,-0.012,0.18,0.017,-0.018,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00012,0.0091,-0.021,-0.13,0.2,-5.4e-06,0.43,0.00042,0.00043,-0.00024,0,0,-4.9e+02,0.00034,0.00036,0.038,0.013,0.014,0.0054,0.037,0.038,0.031,6.2e-07,5.5e-07,1.8e-06,0.032,0.029,0.00013,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20290000,0.98,-0.009,-0.012,0.18,0.015,-0.02,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.0091,-0.022,-0.13,0.2,-5.4e-06,0.43,0.00042,0.00044,-0.00025,0,0,-4.9e+02,0.00034,0.00036,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.2e-07,5.5e-07,1.8e-06,0.032,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20390000,0.98,-0.0089,-0.012,0.18,0.013,-0.017,0.028,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.01,-0.022,-0.13,0.2,-5.5e-06,0.43,0.00041,0.00042,-0.00023,0,0,-4.9e+02,0.00034,0.00035,0.038,0.013,0.014,0.0054,0.037,0.038,0.031,6.1e-07,5.4e-07,1.8e-06,0.032,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20490000,0.98,-0.0089,-0.012,0.18,0.0097,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.01,-0.022,-0.13,0.2,-5.3e-06,0.43,0.00041,0.00041,-0.00023,0,0,-4.9e+02,0.00034,0.00035,0.038,0.014,0.015,0.0054,0.041,0.042,0.031,6.1e-07,5.4e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20590000,0.98,-0.0089,-0.012,0.18,0.0089,-0.019,0.029,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.022,-0.13,0.2,-5.3e-06,0.43,0.00038,0.00039,-0.00022,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.9e-07,5.3e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20690000,0.98,-0.0088,-0.012,0.18,0.0078,-0.018,0.03,0,0,-4.9e+02,-0.0012,-0.0058,-0.00011,0.011,-0.022,-0.13,0.2,-5.5e-06,0.43,0.00039,0.00039,-0.00022,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.015,0.0054,0.041,0.042,0.031,5.9e-07,5.2e-07,1.8e-06,0.031,0.029,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20790000,0.98,-0.0081,-0.012,0.18,0.004,-0.015,0.015,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.022,-0.13,0.2,-5.9e-06,0.43,0.00037,0.00039,-0.00022,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.8e-07,5.1e-07,1.8e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20890000,0.98,0.00095,-0.0079,0.18,0.0001,-0.0039,-0.1,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.012,-0.023,-0.13,0.2,-6.8e-06,0.43,0.00037,0.00051,-0.00017,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.015,0.0053,0.04,0.042,0.031,5.8e-07,5.1e-07,1.8e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0013,0.0013,0.0015,0.0013,1,1,0.01 +20990000,0.98,0.0043,-0.0044,0.18,-0.012,0.015,-0.24,0,0,-4.9e+02,-0.0012,-0.0058,-0.0001,0.013,-0.023,-0.13,0.2,-6.8e-06,0.43,0.00036,0.0005,-0.00013,0,0,-4.9e+02,0.00033,0.00035,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.6e-07,5e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21090000,0.98,0.0027,-0.0048,0.18,-0.023,0.03,-0.36,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.013,-0.023,-0.13,0.2,-5e-06,0.43,0.00042,0.0003,-0.00017,0,0,-4.9e+02,0.00033,0.00035,0.038,0.014,0.015,0.0053,0.04,0.041,0.031,5.6e-07,5e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21190000,0.98,-8.5e-05,-0.0064,0.18,-0.029,0.037,-0.49,0,0,-4.9e+02,-0.0012,-0.0058,-9e-05,0.012,-0.024,-0.13,0.2,-4.5e-06,0.43,0.00042,0.00032,-0.00016,0,0,-4.9e+02,0.00033,0.00034,0.038,0.013,0.014,0.0053,0.037,0.038,0.031,5.5e-07,4.9e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21290000,0.98,-0.0023,-0.0077,0.18,-0.028,0.039,-0.62,0,0,-4.9e+02,-0.0012,-0.0058,-9.8e-05,0.012,-0.024,-0.13,0.2,-5.1e-06,0.43,0.00041,0.00036,-9.2e-05,0,0,-4.9e+02,0.00033,0.00034,0.037,0.014,0.015,0.0053,0.04,0.041,0.031,5.5e-07,4.8e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21390000,0.98,-0.0037,-0.0083,0.18,-0.026,0.036,-0.75,0,0,-4.9e+02,-0.0012,-0.0058,-9.6e-05,0.012,-0.024,-0.13,0.2,-4.6e-06,0.43,0.00043,0.00028,-0.00011,0,0,-4.9e+02,0.00032,0.00034,0.037,0.013,0.014,0.0053,0.037,0.038,0.031,5.3e-07,4.7e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21490000,0.98,-0.0045,-0.0088,0.18,-0.021,0.033,-0.88,0,0,-4.9e+02,-0.0012,-0.0058,-9e-05,0.013,-0.024,-0.13,0.2,-4.6e-06,0.43,0.00042,0.00031,-0.00015,0,0,-4.9e+02,0.00032,0.00034,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5.3e-07,4.7e-07,1.7e-06,0.031,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21590000,0.98,-0.0049,-0.0087,0.18,-0.014,0.03,-1,0,0,-4.9e+02,-0.0012,-0.0058,-8.5e-05,0.013,-0.023,-0.13,0.2,-4.7e-06,0.43,0.0004,0.00036,-0.00017,0,0,-4.9e+02,0.00032,0.00034,0.037,0.013,0.015,0.0053,0.037,0.038,0.031,5.2e-07,4.6e-07,1.7e-06,0.03,0.028,0.00012,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21690000,0.98,-0.0052,-0.0086,0.18,-0.011,0.025,-1.1,0,0,-4.9e+02,-0.0012,-0.0058,-7.7e-05,0.013,-0.024,-0.13,0.2,-4.6e-06,0.43,0.00038,0.00041,-0.00015,0,0,-4.9e+02,0.00032,0.00034,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5.2e-07,4.6e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21790000,0.98,-0.0055,-0.0088,0.18,-0.0061,0.021,-1.3,0,0,-4.9e+02,-0.0012,-0.0058,-6.8e-05,0.014,-0.023,-0.13,0.2,-4.7e-06,0.43,0.00038,0.0004,-0.00021,0,0,-4.9e+02,0.00032,0.00033,0.037,0.013,0.015,0.0052,0.037,0.038,0.031,5.1e-07,4.5e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21890000,0.98,-0.0058,-0.0089,0.18,-0.0025,0.016,-1.4,0,0,-4.9e+02,-0.0012,-0.0058,-7e-05,0.014,-0.023,-0.13,0.2,-5.1e-06,0.43,0.00035,0.00042,-0.0002,0,0,-4.9e+02,0.00032,0.00033,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,5.1e-07,4.5e-07,1.7e-06,0.03,0.028,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +21990000,0.98,-0.0064,-0.0092,0.18,-0.00044,0.011,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-6.5e-05,0.014,-0.022,-0.13,0.2,-4.7e-06,0.43,0.00038,0.00043,-0.00021,0,0,-4.9e+02,0.00031,0.00033,0.037,0.013,0.015,0.0052,0.037,0.038,0.031,4.9e-07,4.4e-07,1.7e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22090000,0.98,-0.0071,-0.01,0.18,0.0016,0.0076,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.6e-05,0.015,-0.021,-0.13,0.2,-4.7e-06,0.43,0.00038,0.00045,-0.00022,0,0,-4.9e+02,0.00031,0.00033,0.037,0.014,0.016,0.0053,0.04,0.041,0.031,4.9e-07,4.4e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22190000,0.98,-0.0075,-0.01,0.18,0.0073,0.0033,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.8e-05,0.016,-0.02,-0.13,0.2,-4.8e-06,0.43,0.00038,0.00047,-0.00022,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.014,0.0052,0.037,0.038,0.03,4.8e-07,4.3e-07,1.6e-06,0.03,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22290000,0.98,-0.0082,-0.01,0.18,0.013,-0.0025,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5e-05,0.015,-0.02,-0.13,0.2,-4.7e-06,0.43,0.00037,0.00046,-0.00022,0,0,-4.9e+02,0.00031,0.00032,0.037,0.014,0.015,0.0052,0.04,0.041,0.03,4.8e-07,4.3e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22390000,0.98,-0.0085,-0.011,0.18,0.017,-0.011,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.2e-05,0.014,-0.019,-0.13,0.2,-4.9e-06,0.43,0.00039,0.00046,-0.00024,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.014,0.0052,0.037,0.038,0.03,4.7e-07,4.2e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22490000,0.98,-0.0087,-0.011,0.18,0.022,-0.018,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.6e-05,0.014,-0.02,-0.13,0.2,-5.2e-06,0.43,0.0004,0.00048,-0.00026,0,0,-4.9e+02,0.00031,0.00032,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.7e-07,4.2e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22590000,0.98,-0.0086,-0.012,0.18,0.029,-0.025,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.8e-05,0.014,-0.02,-0.13,0.2,-4.7e-06,0.43,0.0004,0.0005,-0.00025,0,0,-4.9e+02,0.0003,0.00032,0.037,0.013,0.014,0.0052,0.036,0.038,0.03,4.6e-07,4.1e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22690000,0.98,-0.0085,-0.012,0.18,0.033,-0.03,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5e-05,0.014,-0.02,-0.13,0.2,-4.7e-06,0.43,0.0004,0.0005,-0.00027,0,0,-4.9e+02,0.0003,0.00032,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.6e-07,4.1e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22790000,0.98,-0.0085,-0.012,0.18,0.038,-0.038,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-5.4e-05,0.014,-0.02,-0.13,0.2,-4.9e-06,0.43,0.00039,0.00047,-0.00029,0,0,-4.9e+02,0.0003,0.00031,0.037,0.012,0.014,0.0052,0.036,0.038,0.03,4.4e-07,4e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22890000,0.98,-0.0087,-0.013,0.18,0.042,-0.043,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.5e-05,0.014,-0.02,-0.13,0.2,-4.6e-06,0.43,0.00039,0.00048,-0.00028,0,0,-4.9e+02,0.0003,0.00031,0.037,0.013,0.015,0.0052,0.04,0.041,0.03,4.4e-07,4e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +22990000,0.98,-0.0086,-0.013,0.18,0.046,-0.047,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.6e-05,0.014,-0.02,-0.13,0.2,-4.9e-06,0.43,0.00039,0.00045,-0.00025,0,0,-4.9e+02,0.0003,0.00031,0.037,0.012,0.014,0.0052,0.036,0.038,0.03,4.3e-07,3.9e-07,1.6e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23090000,0.98,-0.0086,-0.013,0.18,0.051,-0.052,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.014,-0.019,-0.13,0.2,-5e-06,0.43,0.00037,0.00046,-0.00024,0,0,-4.9e+02,0.0003,0.00031,0.037,0.013,0.014,0.0052,0.04,0.041,0.03,4.3e-07,3.9e-07,1.5e-06,0.029,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23190000,0.98,-0.0086,-0.014,0.18,0.057,-0.054,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.9e-05,0.014,-0.019,-0.13,0.2,-5.7e-06,0.43,0.00035,0.00043,-0.00023,0,0,-4.9e+02,0.00029,0.00031,0.037,0.012,0.013,0.0052,0.036,0.038,0.03,4.2e-07,3.8e-07,1.5e-06,0.028,0.027,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23290000,0.98,-0.0091,-0.014,0.18,0.062,-0.059,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.014,-0.019,-0.13,0.2,-5.8e-06,0.43,0.00032,0.00047,-0.00024,0,0,-4.9e+02,0.00029,0.00031,0.037,0.013,0.014,0.0052,0.04,0.041,0.03,4.3e-07,3.8e-07,1.5e-06,0.028,0.026,0.00011,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23390000,0.98,-0.009,-0.014,0.18,0.067,-0.062,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.9e-05,0.015,-0.019,-0.13,0.2,-6e-06,0.43,0.00033,0.00045,-0.00022,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0052,0.036,0.037,0.03,4.2e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23490000,0.98,-0.0091,-0.014,0.18,0.072,-0.064,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-4.1e-05,0.015,-0.019,-0.13,0.2,-5.8e-06,0.43,0.00032,0.0005,-0.00026,0,0,-4.9e+02,0.00029,0.0003,0.037,0.013,0.014,0.0052,0.039,0.041,0.03,4.2e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23590000,0.98,-0.0093,-0.014,0.18,0.075,-0.066,-1.4,0,0,-4.9e+02,-0.0013,-0.0058,-3.7e-05,0.015,-0.019,-0.13,0.2,-6.7e-06,0.43,0.00027,0.00047,-0.00023,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.036,0.037,0.03,4.1e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23690000,0.98,-0.01,-0.015,0.18,0.074,-0.068,-1.3,0,0,-4.9e+02,-0.0013,-0.0058,-3e-05,0.016,-0.019,-0.13,0.2,-6.5e-06,0.43,0.00025,0.00049,-0.00022,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.014,0.0052,0.039,0.041,0.03,4.1e-07,3.7e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23790000,0.98,-0.012,-0.018,0.18,0.068,-0.064,-0.94,0,0,-4.9e+02,-0.0013,-0.0058,-2.8e-05,0.017,-0.019,-0.13,0.2,-6.2e-06,0.43,0.00024,0.00053,-0.0002,0,0,-4.9e+02,0.00029,0.0003,0.037,0.011,0.013,0.0051,0.036,0.037,0.03,4e-07,3.6e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23890000,0.98,-0.015,-0.022,0.18,0.064,-0.064,-0.51,0,0,-4.9e+02,-0.0013,-0.0058,-2.5e-05,0.017,-0.019,-0.13,0.2,-6.2e-06,0.43,0.00023,0.00055,-0.00023,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.039,0.041,0.03,4e-07,3.6e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +23990000,0.98,-0.017,-0.024,0.18,0.063,-0.063,-0.12,0,0,-4.9e+02,-0.0013,-0.0058,-3.2e-05,0.018,-0.019,-0.13,0.2,-6.3e-06,0.43,0.00019,0.00056,2.1e-05,0,0,-4.9e+02,0.00029,0.0003,0.037,0.011,0.012,0.0051,0.036,0.037,0.03,3.9e-07,3.5e-07,1.5e-06,0.028,0.026,0.0001,0.0013,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24090000,0.98,-0.017,-0.023,0.18,0.07,-0.071,0.11,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.018,-0.019,-0.13,0.2,-6.2e-06,0.43,0.00021,0.00054,2.2e-05,0,0,-4.9e+02,0.00029,0.0003,0.037,0.012,0.013,0.0051,0.039,0.04,0.03,3.9e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24190000,0.98,-0.014,-0.019,0.18,0.08,-0.076,0.1,0,0,-4.9e+02,-0.0013,-0.0058,-3.5e-05,0.019,-0.019,-0.13,0.2,-5.9e-06,0.43,0.00021,0.0005,0.00012,0,0,-4.9e+02,0.00028,0.0003,0.037,0.011,0.012,0.0051,0.036,0.037,0.03,3.8e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24290000,0.98,-0.012,-0.016,0.18,0.084,-0.08,0.079,0,0,-4.9e+02,-0.0013,-0.0058,-3.3e-05,0.019,-0.019,-0.13,0.2,-5.5e-06,0.43,0.00024,0.00045,0.00012,0,0,-4.9e+02,0.00028,0.0003,0.037,0.012,0.013,0.0051,0.039,0.04,0.03,3.8e-07,3.5e-07,1.4e-06,0.028,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24390000,0.98,-0.011,-0.015,0.18,0.077,-0.074,0.095,0,0,-4.9e+02,-0.0013,-0.0058,-3.2e-05,0.021,-0.019,-0.13,0.2,-4.1e-06,0.43,0.00024,0.0005,0.00018,0,0,-4.9e+02,0.00028,0.0003,0.037,0.011,0.012,0.0051,0.035,0.037,0.03,3.8e-07,3.4e-07,1.4e-06,0.027,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24490000,0.98,-0.011,-0.015,0.18,0.073,-0.071,0.093,0,0,-4.9e+02,-0.0013,-0.0058,-1.8e-05,0.021,-0.02,-0.13,0.2,-4.1e-06,0.43,0.00016,0.00061,0.00023,0,0,-4.9e+02,0.00028,0.0003,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.8e-07,3.4e-07,1.4e-06,0.027,0.026,0.0001,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24590000,0.98,-0.012,-0.015,0.18,0.069,-0.067,0.088,0,0,-4.9e+02,-0.0013,-0.0058,-3e-05,0.023,-0.02,-0.13,0.2,-2.8e-06,0.43,0.0002,0.00058,0.00024,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.037,0.03,3.7e-07,3.4e-07,1.4e-06,0.027,0.026,9.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24690000,0.98,-0.012,-0.015,0.18,0.067,-0.067,0.088,0,0,-4.9e+02,-0.0013,-0.0058,-2.8e-05,0.023,-0.021,-0.13,0.2,-3e-06,0.43,0.00019,0.00061,0.00024,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.7e-07,3.4e-07,1.4e-06,0.027,0.026,9.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24790000,0.98,-0.012,-0.014,0.18,0.064,-0.065,0.079,0,0,-4.9e+02,-0.0013,-0.0058,-3.6e-05,0.024,-0.021,-0.13,0.2,-2.4e-06,0.43,0.00018,0.00061,0.00023,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.7e-07,3.3e-07,1.4e-06,0.027,0.026,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24890000,0.98,-0.012,-0.014,0.18,0.063,-0.068,0.069,0,0,-4.9e+02,-0.0013,-0.0058,-3.1e-05,0.024,-0.021,-0.13,0.2,-2.2e-06,0.43,0.00018,0.00062,0.00026,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.7e-07,3.3e-07,1.4e-06,0.027,0.026,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +24990000,0.98,-0.012,-0.014,0.18,0.054,-0.065,0.062,0,0,-4.9e+02,-0.0014,-0.0058,-4.5e-05,0.026,-0.023,-0.13,0.2,-2.4e-06,0.43,0.00014,0.00073,0.00027,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.6e-07,3.3e-07,1.4e-06,0.027,0.025,9.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25090000,0.98,-0.012,-0.014,0.18,0.051,-0.064,0.059,0,0,-4.9e+02,-0.0014,-0.0058,-4.5e-05,0.026,-0.022,-0.13,0.2,-3e-06,0.43,0.00013,0.0008,0.00031,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.6e-07,3.3e-07,1.4e-06,0.027,0.025,9.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25190000,0.98,-0.012,-0.014,0.18,0.045,-0.058,0.059,0,0,-4.9e+02,-0.0014,-0.0058,-6.3e-05,0.028,-0.023,-0.13,0.2,-3e-06,0.43,0.00011,0.00083,0.0003,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25290000,0.98,-0.012,-0.013,0.18,0.041,-0.06,0.054,0,0,-4.9e+02,-0.0014,-0.0058,-7e-05,0.027,-0.023,-0.13,0.2,-3.5e-06,0.43,9.8e-05,0.00086,0.00027,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25390000,0.98,-0.012,-0.013,0.18,0.032,-0.054,0.053,0,0,-4.9e+02,-0.0014,-0.0058,-8.6e-05,0.029,-0.024,-0.13,0.2,-4.4e-06,0.43,5.9e-05,0.00091,0.00028,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25490000,0.98,-0.013,-0.013,0.18,0.028,-0.054,0.052,0,0,-4.9e+02,-0.0014,-0.0058,-8.7e-05,0.029,-0.024,-0.13,0.2,-4.1e-06,0.43,5.3e-05,0.00087,0.00026,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.04,0.03,3.5e-07,3.2e-07,1.3e-06,0.027,0.025,9.6e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25590000,0.98,-0.013,-0.013,0.18,0.023,-0.05,0.053,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,0.03,-0.025,-0.13,0.2,-5e-06,0.43,2.1e-05,0.00089,0.00023,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.4e-07,3.2e-07,1.3e-06,0.027,0.025,9.5e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25690000,0.98,-0.012,-0.012,0.18,0.023,-0.05,0.043,0,0,-4.9e+02,-0.0014,-0.0058,-0.0001,0.03,-0.025,-0.13,0.2,-5.1e-06,0.43,2.6e-05,0.00092,0.00024,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.4e-07,3.2e-07,1.3e-06,0.027,0.025,9.5e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25790000,0.98,-0.012,-0.012,0.18,0.011,-0.042,0.043,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.032,-0.026,-0.13,0.2,-5.6e-06,0.43,-3.4e-05,0.00085,0.00023,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.4e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25890000,0.98,-0.012,-0.012,0.18,0.0058,-0.04,0.045,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.032,-0.026,-0.13,0.2,-5.8e-06,0.43,-5.4e-05,0.00082,0.00019,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.4e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +25990000,0.98,-0.012,-0.012,0.18,-0.0032,-0.034,0.038,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.033,-0.026,-0.13,0.2,-7.2e-06,0.43,-0.00011,0.0008,0.00017,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.0051,0.035,0.036,0.03,3.3e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26090000,0.98,-0.012,-0.012,0.18,-0.0078,-0.034,0.037,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.034,-0.026,-0.13,0.2,-6.7e-06,0.43,-0.00011,0.00079,0.0002,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3.1e-07,1.3e-06,0.027,0.025,9.4e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26190000,0.98,-0.012,-0.012,0.18,-0.015,-0.026,0.033,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.026,-0.13,0.2,-7.1e-06,0.43,-0.00013,0.00078,0.00021,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.3e-07,3e-07,1.2e-06,0.027,0.025,9.3e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26290000,0.98,-0.012,-0.013,0.18,-0.015,-0.026,0.027,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.026,-0.13,0.2,-7.7e-06,0.43,-0.00014,0.0008,0.00019,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3e-07,1.2e-06,0.027,0.025,9.3e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26390000,0.98,-0.011,-0.013,0.18,-0.021,-0.018,0.031,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.036,-0.027,-0.13,0.2,-8.9e-06,0.43,-0.00018,0.00077,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26490000,0.98,-0.011,-0.013,0.18,-0.023,-0.016,0.04,0,0,-4.9e+02,-0.0014,-0.0058,-0.00016,0.036,-0.027,-0.13,0.2,-9.3e-06,0.43,-0.00018,0.00081,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.3e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26590000,0.98,-0.01,-0.013,0.18,-0.026,-0.0076,0.04,0,0,-4.9e+02,-0.0015,-0.0058,-0.00017,0.036,-0.027,-0.13,0.2,-1.1e-05,0.43,-0.00022,0.00082,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26690000,0.98,-0.01,-0.013,0.18,-0.027,-0.0036,0.039,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.036,-0.028,-0.13,0.2,-1.1e-05,0.43,-0.00023,0.00083,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.2e-07,3e-07,1.2e-06,0.026,0.025,9.2e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26790000,0.98,-0.0099,-0.012,0.18,-0.035,0.00072,0.038,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.1e-05,0.43,-0.00025,0.00081,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.2e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26890000,0.98,-0.0092,-0.012,0.18,-0.04,0.0036,0.034,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.1e-05,0.43,-0.00025,0.00079,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.0051,0.038,0.039,0.03,3.2e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +26990000,0.98,-0.0087,-0.013,0.18,-0.048,0.011,0.033,0,0,-4.9e+02,-0.0015,-0.0058,-0.00018,0.037,-0.027,-0.13,0.2,-1.2e-05,0.43,-0.00027,0.00077,0.00014,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9.1e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27090000,0.98,-0.0085,-0.013,0.18,-0.05,0.017,0.036,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.027,-0.13,0.2,-1.2e-05,0.43,-0.00027,0.00077,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27190000,0.98,-0.0086,-0.013,0.18,-0.056,0.024,0.039,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.027,-0.13,0.2,-1.2e-05,0.43,-0.00028,0.00076,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27290000,0.98,-0.0087,-0.014,0.18,-0.063,0.029,0.15,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.028,-0.13,0.2,-1.2e-05,0.43,-0.00029,0.00076,0.00015,0,0,-4.9e+02,0.00028,0.00029,0.037,0.012,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.9e-07,1.2e-06,0.026,0.025,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27390000,0.98,-0.01,-0.016,0.18,-0.071,0.036,0.48,0,0,-4.9e+02,-0.0015,-0.0058,-0.00019,0.038,-0.028,-0.13,0.2,-1.4e-05,0.43,-0.00036,0.00068,0.00021,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27490000,0.98,-0.012,-0.018,0.18,-0.074,0.041,0.79,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.4e-05,0.43,-0.00033,0.00064,0.00021,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.013,0.005,0.038,0.039,0.03,3.1e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27590000,0.98,-0.011,-0.017,0.18,-0.07,0.045,0.89,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.4e-05,0.43,-0.00031,0.00059,0.00024,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27690000,0.98,-0.01,-0.014,0.18,-0.066,0.041,0.79,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.4e-05,0.43,-0.0003,0.00058,0.00022,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27790000,0.98,-0.0088,-0.013,0.18,-0.066,0.04,0.78,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.028,-0.13,0.2,-1.5e-05,0.43,-0.0003,0.00054,0.00023,0,0,-4.9e+02,0.00028,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.9e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27890000,0.98,-0.0085,-0.013,0.18,-0.071,0.046,0.82,0,0,-4.9e+02,-0.0015,-0.0058,-0.0002,0.038,-0.029,-0.13,0.2,-1.5e-05,0.43,-0.0003,0.00054,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.8e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +27990000,0.98,-0.0089,-0.013,0.18,-0.072,0.049,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-0.00019,0.037,-0.028,-0.13,0.2,-1.5e-05,0.43,-0.0003,0.00048,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,3e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +28090000,0.98,-0.0092,-0.013,0.18,-0.076,0.049,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.037,-0.028,-0.13,0.2,-1.5e-05,0.43,-0.00031,0.0005,0.00024,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,3e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +28190000,0.98,-0.0086,-0.013,0.18,-0.077,0.047,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00018,0.037,-0.028,-0.13,0.2,-1.5e-05,0.43,-0.00029,0.00048,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.8e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +28290000,0.98,-0.0081,-0.014,0.18,-0.081,0.05,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00017,0.037,-0.029,-0.13,0.2,-1.4e-05,0.43,-0.0003,0.00051,0.00022,0,0,-4.9e+02,0.00029,0.00029,0.037,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0015,0.0012,1,1,0.01 +28390000,0.98,-0.0082,-0.014,0.18,-0.082,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00016,0.036,-0.029,-0.13,0.2,-1.5e-05,0.43,-0.00035,0.00042,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28490000,0.98,-0.0084,-0.015,0.18,-0.085,0.057,0.83,0,0,-4.9e+02,-0.0014,-0.0058,-0.00017,0.036,-0.029,-0.13,0.2,-1.5e-05,0.43,-0.00032,0.0004,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1.1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28590000,0.98,-0.0085,-0.015,0.18,-0.079,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.036,-0.028,-0.13,0.2,-1.5e-05,0.43,-0.00029,0.00039,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.9e-07,2.7e-07,1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28690000,0.98,-0.0083,-0.014,0.18,-0.078,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00015,0.036,-0.029,-0.13,0.2,-1.5e-05,0.43,-0.00026,0.00039,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.9e-07,2.7e-07,1e-06,0.026,0.024,8.7e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28790000,0.98,-0.0076,-0.014,0.18,-0.076,0.055,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.029,-0.13,0.2,-1.6e-05,0.43,-0.00029,0.00028,0.00025,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28890000,0.98,-0.0074,-0.013,0.18,-0.08,0.057,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00014,0.035,-0.029,-0.13,0.2,-1.6e-05,0.43,-0.00029,0.00032,0.00023,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +28990000,0.98,-0.0072,-0.014,0.18,-0.077,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.034,-0.029,-0.13,0.2,-1.7e-05,0.43,-0.00033,0.00017,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29090000,0.98,-0.007,-0.014,0.18,-0.08,0.056,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00013,0.034,-0.029,-0.13,0.2,-1.7e-05,0.43,-0.00035,0.00015,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.026,0.024,8.6e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29190000,0.98,-0.007,-0.014,0.18,-0.078,0.056,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.033,-0.029,-0.13,0.2,-1.8e-05,0.43,-0.00038,1.6e-05,0.00028,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,1e-06,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29290000,0.98,-0.0072,-0.014,0.18,-0.081,0.062,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00012,0.033,-0.029,-0.13,0.2,-1.9e-05,0.43,-0.00038,-1.1e-05,0.00029,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,1e-06,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29390000,0.98,-0.0077,-0.013,0.18,-0.077,0.061,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-0.00011,0.033,-0.029,-0.13,0.2,-2e-05,0.43,-0.00041,-0.00014,0.0003,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.8e-07,2.6e-07,9.9e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29490000,0.98,-0.0076,-0.013,0.18,-0.08,0.062,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-9.7e-05,0.033,-0.029,-0.13,0.2,-2e-05,0.43,-0.00044,-0.00011,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.8e-07,2.6e-07,9.9e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29590000,0.98,-0.0075,-0.013,0.18,-0.077,0.06,0.83,0,0,-4.9e+02,-0.0014,-0.0058,-8.1e-05,0.032,-0.029,-0.13,0.2,-2.1e-05,0.43,-0.00049,-0.00022,0.00027,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.7e-07,2.6e-07,9.8e-07,0.025,0.024,8.5e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29690000,0.98,-0.0075,-0.013,0.18,-0.082,0.059,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-7.3e-05,0.032,-0.029,-0.13,0.2,-2.1e-05,0.43,-0.00051,-0.00018,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.6e-07,9.7e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29790000,0.98,-0.0074,-0.013,0.18,-0.079,0.054,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-5.8e-05,0.031,-0.029,-0.13,0.2,-2.3e-05,0.43,-0.00056,-0.0003,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.035,0.036,0.03,2.7e-07,2.5e-07,9.6e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29890000,0.98,-0.0068,-0.014,0.18,-0.08,0.055,0.82,0,0,-4.9e+02,-0.0014,-0.0058,-5.1e-05,0.031,-0.029,-0.13,0.2,-2.3e-05,0.43,-0.00059,-0.00027,0.00024,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.6e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +29990000,0.98,-0.007,-0.014,0.18,-0.075,0.051,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-4e-05,0.03,-0.03,-0.13,0.2,-2.4e-05,0.43,-0.00057,-0.00032,0.00026,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.7e-07,2.5e-07,9.5e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30090000,0.98,-0.0071,-0.014,0.18,-0.076,0.051,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5e-05,0.03,-0.03,-0.13,0.2,-2.5e-05,0.43,-0.00052,-0.00039,0.00031,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.029,2.7e-07,2.5e-07,9.4e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30190000,0.98,-0.0072,-0.014,0.18,-0.071,0.047,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5.3e-05,0.029,-0.03,-0.13,0.2,-2.8e-05,0.43,-0.00053,-0.00061,0.00037,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.7e-07,2.5e-07,9.4e-07,0.025,0.024,8.4e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30290000,0.98,-0.0072,-0.014,0.18,-0.071,0.047,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-5.1e-05,0.03,-0.03,-0.13,0.2,-2.7e-05,0.43,-0.00057,-0.00066,0.00037,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.3e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30390000,0.98,-0.0072,-0.013,0.18,-0.065,0.042,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-3.4e-05,0.029,-0.031,-0.13,0.2,-2.8e-05,0.43,-0.00072,-0.00088,0.00038,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.5e-07,9.2e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30490000,0.98,-0.0072,-0.014,0.18,-0.068,0.043,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-2.8e-05,0.029,-0.031,-0.13,0.2,-2.8e-05,0.43,-0.00076,-0.00087,0.00036,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.005,0.038,0.039,0.03,2.7e-07,2.5e-07,9.2e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30590000,0.98,-0.0075,-0.014,0.18,-0.064,0.04,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.2e-05,0.028,-0.031,-0.13,0.2,-2.8e-05,0.43,-0.00087,-0.00098,0.00036,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.5e-07,9.1e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30690000,0.98,-0.0079,-0.014,0.18,-0.062,0.039,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.2e-05,0.029,-0.032,-0.13,0.2,-2.9e-05,0.43,-0.00085,-0.00092,0.00036,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.038,0.039,0.029,2.6e-07,2.5e-07,9e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30790000,0.98,-0.0076,-0.014,0.17,-0.056,0.034,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-7.8e-06,0.028,-0.032,-0.13,0.2,-3e-05,0.43,-0.00093,-0.0011,0.0004,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.035,0.036,0.03,2.6e-07,2.4e-07,9e-07,0.025,0.024,8.3e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30890000,0.98,-0.007,-0.014,0.17,-0.056,0.03,0.81,0,0,-4.9e+02,-0.0014,-0.0058,-1.5e-05,0.029,-0.033,-0.12,0.2,-3e-05,0.43,-0.00083,-0.0011,0.00042,0,0,-4.9e+02,0.00029,0.00029,0.036,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.9e-07,0.025,0.024,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +30990000,0.98,-0.0072,-0.013,0.17,-0.048,0.025,0.81,0,0,-4.9e+02,-0.0013,-0.0057,-7.1e-06,0.028,-0.034,-0.12,0.2,-3.1e-05,0.43,-0.00087,-0.0012,0.00045,0,0,-4.9e+02,0.00029,0.00028,0.036,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.4e-07,8.8e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31090000,0.98,-0.0074,-0.014,0.17,-0.047,0.024,0.81,0,0,-4.9e+02,-0.0013,-0.0057,-1.1e-05,0.028,-0.034,-0.12,0.2,-3.2e-05,0.43,-0.00082,-0.0012,0.00046,0,0,-4.9e+02,0.00029,0.00028,0.036,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.8e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31190000,0.98,-0.0076,-0.014,0.17,-0.043,0.02,0.81,0,0,-4.9e+02,-0.0013,-0.0057,4.4e-06,0.028,-0.035,-0.12,0.2,-3.2e-05,0.43,-0.00092,-0.0012,0.00046,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.6e-07,2.4e-07,8.7e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31290000,0.98,-0.0078,-0.014,0.17,-0.04,0.017,0.81,0,0,-4.9e+02,-0.0013,-0.0057,9.5e-06,0.028,-0.035,-0.12,0.2,-3.1e-05,0.43,-0.00096,-0.0011,0.00044,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.6e-07,2.4e-07,8.7e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31390000,0.98,-0.0076,-0.013,0.17,-0.035,0.011,0.81,0,0,-4.9e+02,-0.0013,-0.0057,8.8e-06,0.028,-0.035,-0.12,0.2,-3.1e-05,0.43,-0.001,-0.0014,0.0005,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.6e-07,0.025,0.023,8.2e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31490000,0.98,-0.0073,-0.014,0.17,-0.036,0.0076,0.81,0,0,-4.9e+02,-0.0013,-0.0057,7.2e-06,0.028,-0.035,-0.12,0.2,-3e-05,0.43,-0.0011,-0.0016,0.00051,0,0,-4.9e+02,0.00029,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.03,2.6e-07,2.4e-07,8.6e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31590000,0.98,-0.0072,-0.014,0.17,-0.032,0.0058,0.82,0,0,-4.9e+02,-0.0013,-0.0057,1.7e-05,0.027,-0.035,-0.12,0.2,-2.9e-05,0.43,-0.0012,-0.0018,0.00053,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.5e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31690000,0.98,-0.0072,-0.015,0.17,-0.035,0.0051,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.028,-0.035,-0.12,0.2,-2.9e-05,0.43,-0.0013,-0.0018,0.00052,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.4e-07,8.4e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31790000,0.98,-0.0075,-0.015,0.17,-0.026,0.0025,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3e-05,0.028,-0.036,-0.12,0.2,-2.8e-05,0.43,-0.0015,-0.0019,0.00055,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.4e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31890000,0.99,-0.0072,-0.015,0.17,-0.024,0.0003,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.4e-05,0.028,-0.036,-0.12,0.2,-2.7e-05,0.43,-0.0015,-0.002,0.00057,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.4e-07,8.3e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +31990000,0.99,-0.0075,-0.015,0.17,-0.016,-0.00076,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.1e-05,0.029,-0.036,-0.12,0.2,-2.7e-05,0.43,-0.0015,-0.0021,0.00062,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.4e-07,8.2e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32090000,0.99,-0.0078,-0.014,0.17,-0.018,-0.0042,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.1e-05,0.029,-0.036,-0.12,0.2,-2.7e-05,0.43,-0.0015,-0.0022,0.00064,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.03,2.5e-07,2.4e-07,8.2e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32190000,0.99,-0.0081,-0.015,0.17,-0.013,-0.0078,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.7e-05,0.029,-0.037,-0.12,0.2,-2.6e-05,0.43,-0.0016,-0.0024,0.00069,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.3e-07,8.1e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32290000,0.99,-0.008,-0.015,0.17,-0.012,-0.01,0.81,0,0,-4.9e+02,-0.0013,-0.0057,3.2e-05,0.029,-0.037,-0.12,0.2,-2.5e-05,0.43,-0.0017,-0.0024,0.0007,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.038,0.039,0.029,2.5e-07,2.3e-07,8.1e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32390000,0.99,-0.0081,-0.015,0.17,-0.0059,-0.012,0.81,0,0,-4.9e+02,-0.0013,-0.0057,2.9e-05,0.03,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0017,-0.0027,0.00076,0,0,-4.9e+02,0.00028,0.00028,0.035,0.011,0.012,0.0049,0.035,0.036,0.029,2.5e-07,2.3e-07,8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32490000,0.99,-0.011,-0.013,0.17,0.019,-0.078,-0.062,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.03,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0016,-0.0026,0.00075,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.014,0.0049,0.038,0.039,0.029,2.5e-07,2.3e-07,8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32590000,0.99,-0.011,-0.013,0.17,0.022,-0.079,-0.065,0,0,-4.9e+02,-0.0013,-0.0057,2.4e-05,0.03,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0016,-0.0023,0.00082,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.9e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32690000,0.99,-0.011,-0.013,0.17,0.017,-0.085,-0.066,0,0,-4.9e+02,-0.0013,-0.0057,2.3e-05,0.03,-0.037,-0.12,0.2,-2.4e-05,0.43,-0.0016,-0.0023,0.00082,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.9e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32790000,0.99,-0.011,-0.013,0.17,0.018,-0.084,-0.067,0,0,-4.9e+02,-0.0013,-0.0057,2.1e-05,0.03,-0.037,-0.12,0.2,-2.2e-05,0.43,-0.0016,-0.0022,0.00089,0,0,-4.9e+02,0.00028,0.00027,0.035,0.011,0.013,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.8e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0013,0.0014,0.0012,1,1,0.01 +32890000,0.99,-0.011,-0.013,0.17,0.018,-0.091,-0.069,0,0,-4.9e+02,-0.0013,-0.0057,2.5e-05,0.03,-0.037,-0.12,0.2,-2.2e-05,0.43,-0.0016,-0.0021,0.0009,0,0,-4.9e+02,0.00028,0.00028,0.035,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.8e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 +32990000,0.98,-0.011,-0.013,0.17,0.018,-0.089,-0.068,0,0,-4.9e+02,-0.0013,-0.0057,2.6e-05,0.03,-0.037,-0.12,0.2,-2.1e-05,0.43,-0.0017,-0.002,0.00097,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.7e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 +33090000,0.98,-0.011,-0.013,0.17,0.014,-0.094,-0.065,0,0,-4.9e+02,-0.0013,-0.0057,2.7e-05,0.03,-0.037,-0.12,0.2,-2.1e-05,0.43,-0.0017,-0.002,0.00097,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.7e-07,0.025,0.023,8.1e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 +33190000,0.98,-0.011,-0.013,0.17,0.012,-0.094,-0.064,0,0,-4.9e+02,-0.0014,-0.0057,1.8e-05,0.031,-0.036,-0.12,0.2,-1.9e-05,0.43,-0.0016,-0.002,0.00099,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.6e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 +33290000,0.98,-0.011,-0.013,0.17,0.0084,-0.096,-0.064,0,0,-4.9e+02,-0.0014,-0.0057,2.8e-05,0.031,-0.036,-0.12,0.2,-1.8e-05,0.43,-0.0018,-0.002,0.001,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.6e-07,0.025,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.01 +33390000,0.98,-0.01,-0.013,0.17,0.0061,-0.091,-0.062,0,0,-4.9e+02,-0.0014,-0.0057,2.1e-05,0.033,-0.035,-0.12,0.2,-1.5e-05,0.43,-0.0018,-0.002,0.0011,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.3e-07,7.5e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.033 +33490000,0.99,-0.01,-0.013,0.17,0.00088,-0.094,-0.061,0,0,-4.9e+02,-0.0014,-0.0057,2.6e-05,0.033,-0.035,-0.12,0.2,-1.3e-05,0.43,-0.0019,-0.0021,0.0011,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.3e-07,7.5e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.058 +33590000,0.99,-0.01,-0.013,0.17,-0.0019,-0.092,-0.058,0,0,-4.9e+02,-0.0014,-0.0057,2.5e-05,0.034,-0.034,-0.12,0.2,-9.7e-06,0.43,-0.002,-0.0022,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.4e-07,2.2e-07,7.4e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.083 +33690000,0.98,-0.01,-0.013,0.17,-0.0052,-0.095,-0.059,0,0,-4.9e+02,-0.0014,-0.0057,2.9e-05,0.035,-0.034,-0.12,0.2,-1.1e-05,0.43,-0.0019,-0.002,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.2e-07,7.4e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.11 +33790000,0.98,-0.01,-0.013,0.17,-0.0071,-0.093,-0.054,0,0,-4.9e+02,-0.0014,-0.0057,1.9e-05,0.036,-0.034,-0.12,0.2,-9.2e-06,0.43,-0.0019,-0.0018,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.3e-07,0.024,0.023,8e-05,0.0012,4e-05,0.0012,0.0012,0.0014,0.0012,1,1,0.13 +33890000,0.98,-0.01,-0.013,0.17,-0.011,-0.094,-0.053,0,0,-4.9e+02,-0.0014,-0.0057,2.9e-05,0.036,-0.034,-0.12,0.2,-8.5e-06,0.43,-0.0019,-0.0018,0.0012,0,0,-4.9e+02,0.00027,0.00027,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.4e-07,2.2e-07,7.3e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.16 +33990000,0.98,-0.01,-0.013,0.17,-0.012,-0.089,-0.05,0,0,-4.9e+02,-0.0014,-0.0057,1.6e-05,0.038,-0.033,-0.12,0.2,-5.6e-06,0.43,-0.0019,-0.0018,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.2e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.18 +34090000,0.98,-0.0099,-0.013,0.17,-0.016,-0.093,-0.049,0,0,-4.9e+02,-0.0014,-0.0057,1.9e-05,0.038,-0.033,-0.12,0.2,-6.1e-06,0.43,-0.0019,-0.0017,0.0013,0,0,-4.9e+02,0.00027,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7.2e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.21 +34190000,0.98,-0.0099,-0.014,0.17,-0.017,-0.088,-0.046,0,0,-4.9e+02,-0.0014,-0.0057,1.5e-05,0.04,-0.033,-0.12,0.2,-3.8e-06,0.43,-0.0018,-0.0015,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7.1e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.23 +34290000,0.98,-0.0097,-0.014,0.17,-0.018,-0.092,-0.045,0,0,-4.9e+02,-0.0014,-0.0057,2.2e-05,0.04,-0.033,-0.12,0.2,-3e-06,0.43,-0.0019,-0.0016,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7.1e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.26 +34390000,0.98,-0.0096,-0.014,0.17,-0.02,-0.086,-0.041,0,0,-4.9e+02,-0.0014,-0.0056,1.4e-05,0.042,-0.033,-0.12,0.2,-9.7e-07,0.43,-0.0018,-0.0015,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,7e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.28 +34490000,0.98,-0.0096,-0.014,0.17,-0.023,-0.09,-0.039,0,0,-4.9e+02,-0.0014,-0.0056,2.3e-05,0.042,-0.033,-0.12,0.2,-6.4e-07,0.43,-0.0019,-0.0014,0.0013,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,7e-07,0.024,0.023,7.9e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.31 +34590000,0.98,-0.0095,-0.013,0.17,-0.025,-0.082,0.76,0,0,-4.9e+02,-0.0014,-0.0056,1.5e-05,0.043,-0.032,-0.12,0.2,1.8e-06,0.43,-0.0019,-0.0014,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.011,0.0048,0.035,0.036,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.33 +34690000,0.98,-0.0094,-0.013,0.17,-0.031,-0.08,1.7,0,0,-4.9e+02,-0.0014,-0.0056,1.9e-05,0.043,-0.032,-0.12,0.2,2.2e-06,0.43,-0.0019,-0.0014,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.012,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.36 +34790000,0.98,-0.0094,-0.013,0.17,-0.034,-0.071,2.7,0,0,-4.9e+02,-0.0014,-0.0056,1.2e-05,0.046,-0.033,-0.12,0.2,4.9e-06,0.43,-0.0019,-0.0013,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.011,0.011,0.0049,0.035,0.036,0.029,2.3e-07,2.2e-07,6.9e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.38 +34890000,0.98,-0.0093,-0.013,0.17,-0.04,-0.069,3.7,0,0,-4.9e+02,-0.0014,-0.0056,1.5e-05,0.046,-0.033,-0.12,0.2,5.1e-06,0.43,-0.0019,-0.0013,0.0014,0,0,-4.9e+02,0.00026,0.00026,0.034,0.012,0.013,0.0049,0.038,0.039,0.029,2.3e-07,2.2e-07,6.8e-07,0.024,0.023,7.8e-05,0.0012,4e-05,0.0012,0.0012,0.0013,0.0012,1,1,0.41 diff --git a/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.cpp b/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.cpp index 2d9a88f3ae..635b9b2704 100644 --- a/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.cpp +++ b/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.cpp @@ -210,6 +210,11 @@ bool EkfWrapper::isIntendingExternalVisionHeadingFusion() const return _ekf->control_status_flags().ev_yaw; } +bool EkfWrapper::isIntendingMagFusion() const +{ + return _ekf->control_status_flags().mag; +} + bool EkfWrapper::isIntendingMagHeadingFusion() const { return _ekf->control_status_flags().mag_hdg; @@ -225,6 +230,11 @@ bool EkfWrapper::isMagHeadingConsistent() const return _ekf->control_status_flags().mag_heading_consistent; } +bool EkfWrapper::isMagFaultDetected() const +{ + return _ekf->control_status_flags().mag_fault; +} + void EkfWrapper::setMagFuseTypeNone() { _ekf_params->ekf2_mag_type = MagFuseType::NONE; diff --git a/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.h b/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.h index 6601670eaf..4e36c19676 100644 --- a/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.h +++ b/src/modules/ekf2/test/sensor_simulator/ekf_wrapper.h @@ -102,9 +102,11 @@ public: void disableExternalVisionHeadingFusion(); bool isIntendingExternalVisionHeadingFusion() const; + bool isIntendingMagFusion() const; bool isIntendingMagHeadingFusion() const; bool isIntendingMag3DFusion() const; bool isMagHeadingConsistent() const; + bool isMagFaultDetected() const; void setMagFuseTypeNone(); void enableMagStrengthCheck(); void enableMagInclinationCheck(); diff --git a/src/modules/ekf2/test/sensor_simulator/mag.cpp b/src/modules/ekf2/test/sensor_simulator/mag.cpp index 6a407b9c65..d5151a3d31 100644 --- a/src/modules/ekf2/test/sensor_simulator/mag.cpp +++ b/src/modules/ekf2/test/sensor_simulator/mag.cpp @@ -15,7 +15,7 @@ Mag::~Mag() void Mag::send(uint64_t time) { - _ekf->setMagData(magSample{time, _mag_data}); + _ekf->setMagData(magSample{time, _mag_data + _bias}); } void Mag::setData(const Vector3f &mag) diff --git a/src/modules/ekf2/test/sensor_simulator/mag.h b/src/modules/ekf2/test/sensor_simulator/mag.h index 202ba63fb9..04808d20fd 100644 --- a/src/modules/ekf2/test/sensor_simulator/mag.h +++ b/src/modules/ekf2/test/sensor_simulator/mag.h @@ -52,9 +52,11 @@ public: ~Mag(); void setData(const Vector3f &mag); + void setBias(const Vector3f &bias) { _bias = bias; } private: Vector3f _mag_data; + Vector3f _bias; void send(uint64_t time) override; diff --git a/src/modules/ekf2/test/test_EKF_airspeed.cpp b/src/modules/ekf2/test/test_EKF_airspeed.cpp index 42dcea7730..20d323160d 100644 --- a/src/modules/ekf2/test/test_EKF_airspeed.cpp +++ b/src/modules/ekf2/test/test_EKF_airspeed.cpp @@ -280,7 +280,7 @@ TEST_F(EkfAirspeedTest, testAirspeedDeadReckoningLatLonAltReset) reset_logging_checker.capturePostResetState(); EXPECT_TRUE(reset_logging_checker.isVerticalVelocityResetCounterIncreasedBy(0)); EXPECT_TRUE(reset_logging_checker.isVerticalPositionResetCounterIncreasedBy(1)); - EXPECT_TRUE(reset_logging_checker.isHorizontalVelocityResetCounterIncreasedBy(0)); + EXPECT_TRUE(reset_logging_checker.isHorizontalVelocityResetCounterIncreasedBy(1)); EXPECT_TRUE(reset_logging_checker.isHorizontalPositionResetCounterIncreasedBy(1)); // AND WHEN: only the lat/lon is valid @@ -293,6 +293,56 @@ TEST_F(EkfAirspeedTest, testAirspeedDeadReckoningLatLonAltReset) reset_logging_checker.capturePostResetState(); EXPECT_TRUE(reset_logging_checker.isVerticalVelocityResetCounterIncreasedBy(0)); EXPECT_TRUE(reset_logging_checker.isVerticalPositionResetCounterIncreasedBy(1)); - EXPECT_TRUE(reset_logging_checker.isHorizontalVelocityResetCounterIncreasedBy(0)); + EXPECT_TRUE(reset_logging_checker.isHorizontalVelocityResetCounterIncreasedBy(1)); EXPECT_TRUE(reset_logging_checker.isHorizontalPositionResetCounterIncreasedBy(2)); } + +TEST_F(EkfAirspeedTest, testExternalWindResetOnGround) +{ + // WHEN: an external wind reset is performed before flight + const float wind_speed = 4.5f; + const float wind_speed_acc = 2.f; + const float wind_direction = math::radians(-90.f); + const float wind_direction_acc = math::radians(20.f); + _ekf->resetWindToExternalObservation(wind_speed, wind_direction, wind_speed_acc, wind_direction_acc); + + Vector2f vel_wind_earth = _ekf->getWindVelocity(); + EXPECT_EQ(wind_speed, vel_wind_earth.norm()); + EXPECT_EQ(wind_direction, atan2f(vel_wind_earth(1), vel_wind_earth(0))); + + _ekf->set_in_air_status(true); + _ekf->set_vehicle_at_rest(false); + _ekf->set_is_fixed_wing(true); + _ekf_wrapper.enableBetaFusion(); + _sensor_simulator.startAirspeedSensor(); + + ResetLoggingChecker reset_logging_checker(_ekf); + reset_logging_checker.capturePreResetState(); + + const float measured_airspeed = 25.f; + _sensor_simulator._airspeed.setData(measured_airspeed, measured_airspeed); + + // Since we are doing inertial dead-reckoning + // and that the measurement is inconsistent with the filter + EXPECT_FALSE(_ekf->isLocalHorizontalPositionValid()); + + _sensor_simulator.runSeconds(1); + + // THEN: the velocity is reset to the airspeed measurement + reset_logging_checker.capturePostResetState(); + EXPECT_TRUE(reset_logging_checker.isHorizontalVelocityResetCounterIncreasedBy(1)); + + const Vector3f vel = _ekf->getVelocity(); + const Vector2f air_relative_vel = vel.xy() - vel_wind_earth; + + EXPECT_NEAR(air_relative_vel.norm(), measured_airspeed, 1e-3f); + + // AND: wind estimate stayed close to its manually initialized value + vel_wind_earth = _ekf->getWindVelocity(); + EXPECT_NEAR(wind_speed, vel_wind_earth.norm(), 0.1f); + EXPECT_NEAR(wind_direction, atan2f(vel_wind_earth(1), vel_wind_earth(0)), 0.1f); + + EXPECT_TRUE(_ekf_wrapper.isIntendingAirspeedFusion()); + EXPECT_TRUE(_ekf_wrapper.isIntendingBetaFusion()); + EXPECT_TRUE(_ekf->isLocalHorizontalPositionValid()); +} diff --git a/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp b/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp index 93dd222375..665fa8e8c9 100644 --- a/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp +++ b/src/modules/ekf2/test/test_EKF_gnss_yaw.cpp @@ -281,7 +281,8 @@ TEST_F(EkfGpsHeadingTest, yawJmpOnGround) EXPECT_EQ(_ekf_wrapper.getQuaternionResetCounter(), initial_quat_reset_counter + 1); // AND THEN: restart GNSS yaw fusion - _sensor_simulator.runSeconds(5); + // The strict checks on ground require min_health_time_us (10s) to pass again. + _sensor_simulator.runSeconds(11); EXPECT_TRUE(_ekf_wrapper.isIntendingGpsHeadingFusion()); EXPECT_EQ(_ekf_wrapper.getQuaternionResetCounter(), initial_quat_reset_counter + 2); EXPECT_LT(fabsf(matrix::wrap_pi(_ekf_wrapper.getYawAngle() - gps_heading)), math::radians(1.f)); diff --git a/src/modules/ekf2/test/test_EKF_gps.cpp b/src/modules/ekf2/test/test_EKF_gps.cpp index debfec6560..ebd024e363 100644 --- a/src/modules/ekf2/test/test_EKF_gps.cpp +++ b/src/modules/ekf2/test/test_EKF_gps.cpp @@ -81,6 +81,10 @@ TEST_F(EkfGpsTest, gpsTimeout) // GIVEN:EKF that fuses GPS EXPECT_TRUE(_ekf_wrapper.isIntendingGpsFusion()); + // In air the simplified checks are used which do not include satellite count + _ekf->set_in_air_status(true); + _ekf->set_vehicle_at_rest(false); + // WHEN: the number of satellites drops below the minimum _sensor_simulator._gps.setNumberOfSatellites(3); @@ -174,7 +178,7 @@ TEST_F(EkfGpsTest, resetToGpsPosition) const Vector3f simulated_position_change(20.0f, -1.0f, 0.f); _sensor_simulator._gps.stepHorizontalPositionByMeters( Vector2f(simulated_position_change)); - _sensor_simulator.runSeconds(6); + _sensor_simulator.runSeconds(11); // THEN: a reset to the new GPS position should be done const Vector3f estimated_position = _ekf->getPosition(); diff --git a/src/modules/ekf2/test/test_EKF_mag.cpp b/src/modules/ekf2/test/test_EKF_mag.cpp index ca4f440c62..3d3c43d111 100644 --- a/src/modules/ekf2/test/test_EKF_mag.cpp +++ b/src/modules/ekf2/test/test_EKF_mag.cpp @@ -214,3 +214,98 @@ TEST_F(EkfMagTest, suddenInclinationChange) EXPECT_FALSE(_ekf_wrapper.isIntendingMagHeadingFusion()); EXPECT_FALSE(_ekf_wrapper.isIntendingMag3DFusion()); } + +TEST_F(EkfMagTest, velocityRotationOnYawReset) +{ + // GIVEN: Mag fusion is active and vehicle is flying with airspeed + const float initial_mag_heading = M_PI_F / 4.f; // 45 degrees + Vector3f mag_data(0.2f * cosf(initial_mag_heading), -0.2f * sinf(initial_mag_heading), 0.4f); + _sensor_simulator._mag.setData(mag_data); + _sensor_simulator.runSeconds(_init_duration_s); + + _ekf->set_in_air_status(true); + _ekf->set_vehicle_at_rest(false); + _ekf->set_is_fixed_wing(true); + + const float airspeed_body = 15.0f; // 15 m/s airspeed in body X direction + _sensor_simulator.startAirspeedSensor(); + _sensor_simulator._airspeed.setData(airspeed_body, airspeed_body); + + _ekf_wrapper.enableBetaFusion(); + _sensor_simulator.runSeconds(3); + + // initial state + const Vector3f vel_before = _ekf->getVelocity(); + const float yaw_before = _ekf_wrapper.getYawAngle(); + const matrix::Dcm2f R_ned_to_body_before(-yaw_before); + const Vector2f vel_body_before = R_ned_to_body_before * Vector2f(vel_before); + + // WHEN: Mag heading suddenly changes by more than 0.3 rad (90 degrees) + const float new_mag_heading = yaw_before + M_PI_F / 2.f; + mag_data = Vector3f(0.2f * cosf(new_mag_heading), -0.2f * sinf(new_mag_heading), 0.4f); + _sensor_simulator._mag.setData(mag_data); + _sensor_simulator.runSeconds(8.f); + + // THEN: the yaw should be reset to the new mag heading + const float yaw_after = _ekf_wrapper.getYawAngle(); + EXPECT_NEAR(yaw_after, new_mag_heading, radians(5.0f)) + << "Yaw after: " << degrees(yaw_after) + << " Expected: " << degrees(new_mag_heading); + + // AND: the NED velocity should be rotated to maintain consistent body-frame velocity + const Vector3f vel_after = _ekf->getVelocity(); + + // Calculate body-frame velocity after reset + const matrix::Dcm2f R_ned_to_body_after(-yaw_after); + const Vector2f vel_body_after = R_ned_to_body_after * Vector2f(vel_after); + + // Body-frame velocity should remain approximately the same + EXPECT_NEAR(vel_body_before(0), vel_body_after(0), 1.0f) + << "Body-frame velocity X before: " << vel_body_before(0) + << " after: " << vel_body_after(0); + EXPECT_NEAR(vel_body_before(1), vel_body_after(1), 1.0f) + << "Body-frame velocity Y before: " << vel_body_before(1) + << " after: " << vel_body_after(1); + + // Verify that the yaw change was sufficient to trigger velocity rotation (> 0.3 rad) + const float yaw_change = fabsf(wrap_pi(yaw_after - yaw_before)); + EXPECT_GT(yaw_change, 0.3f) << "Yaw change: " << degrees(yaw_change) << " deg"; +} + +TEST_F(EkfMagTest, magFaultCleared) +{ + // GIVEN: biased mag data + _sensor_simulator._mag.setBias(Vector3f(-0.3f, 0.2f, 0.f)); + _ekf_wrapper.enableGpsFusion(); + _sensor_simulator.startGps(); + _sensor_simulator.runSeconds(11); + + // THEN: the initial heading is incorrect + EXPECT_NEAR(degrees(_ekf_wrapper.getYawAngle()), -110.f, 5.f); + EXPECT_TRUE(_ekf_wrapper.isIntendingMagHeadingFusion()); + EXPECT_FALSE(_ekf_wrapper.isIntendingMag3DFusion()); + + // WHEN: motion allows the yaw estimator to converge + _sensor_simulator.setTrajectoryTargetVelocity(Vector3f(2.f, -2.f, -1.f)); + _ekf->set_in_air_status(true); + + _sensor_simulator.runTrajectorySeconds(3.f); + + // THEN: the heading error is detected, solved and mag is declared faulty + EXPECT_FALSE(_ekf_wrapper.isIntendingMagHeadingFusion()); + EXPECT_FALSE(_ekf_wrapper.isIntendingMag3DFusion()); + EXPECT_TRUE(_ekf_wrapper.isMagFaultDetected()); + + // BUT when: the mag disturbance is gone + _sensor_simulator._mag.setBias(Vector3f()); + _sensor_simulator.setTrajectoryTargetVelocity(Vector3f(0.f, 0.f, 0.f)); + + _sensor_simulator.runTrajectorySeconds(7.f); + + // THEN: the fault is cleared and mag fusion restarts + EXPECT_FALSE(_ekf_wrapper.isMagFaultDetected()); + EXPECT_TRUE(_ekf_wrapper.isMagHeadingConsistent()); + EXPECT_TRUE(_ekf_wrapper.isIntendingMagFusion()); + EXPECT_TRUE(_ekf_wrapper.isIntendingMagHeadingFusion()); + EXPECT_FALSE(_ekf_wrapper.isIntendingMag3DFusion()); // because in-flight alignment is required +} diff --git a/src/modules/esc_battery/EscBattery.cpp b/src/modules/esc_battery/EscBattery.cpp index 78d1c2c71f..6dfc17aeb3 100644 --- a/src/modules/esc_battery/EscBattery.cpp +++ b/src/modules/esc_battery/EscBattery.cpp @@ -105,7 +105,6 @@ EscBattery::Run() } average_voltage_v /= online_esc_count; - total_current_a /= online_esc_count; average_temperature_c /= online_esc_count; _battery.setConnected(true); diff --git a/src/modules/flight_mode_manager/CMakeLists.txt b/src/modules/flight_mode_manager/CMakeLists.txt index 84ccba6ac0..efd7d9a261 100644 --- a/src/modules/flight_mode_manager/CMakeLists.txt +++ b/src/modules/flight_mode_manager/CMakeLists.txt @@ -48,6 +48,7 @@ list(APPEND flight_tasks_all ManualAltitudeSmoothVel ManualPosition Transition + AltitudeCruise ) if(NOT px4_constrained_flash_build) diff --git a/src/modules/flight_mode_manager/FlightModeManager.cpp b/src/modules/flight_mode_manager/FlightModeManager.cpp index f17e00aa96..d69ca84c25 100644 --- a/src/modules/flight_mode_manager/FlightModeManager.cpp +++ b/src/modules/flight_mode_manager/FlightModeManager.cpp @@ -249,6 +249,17 @@ void FlightModeManager::start_flight_task() matching_task_running = matching_task_running && !task_failure; } + // Altitude cruise + if (_vehicle_status_sub.get().nav_state == vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE) { + found_some_task = true; + FlightTaskError error = FlightTaskError::NoError; + + error = switchTask(FlightTaskIndex::AltitudeCruise); + + task_failure = (error != FlightTaskError::NoError); + matching_task_running = matching_task_running && !task_failure; + } + // Emergency descend if (nav_state_descend || task_failure) { found_some_task = true; diff --git a/src/modules/flight_mode_manager/tasks/AltitudeCruise/CMakeLists.txt b/src/modules/flight_mode_manager/tasks/AltitudeCruise/CMakeLists.txt new file mode 100644 index 0000000000..238b5bbd0f --- /dev/null +++ b/src/modules/flight_mode_manager/tasks/AltitudeCruise/CMakeLists.txt @@ -0,0 +1,6 @@ +px4_add_library(FlightTaskAltitudeCruise + FlightTaskAltitudeCruise.cpp +) + +target_link_libraries(FlightTaskAltitudeCruise PUBLIC FlightTaskManualAltitudeSmoothVel) +target_include_directories(FlightTaskAltitudeCruise PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.cpp b/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.cpp new file mode 100644 index 0000000000..3e42cdf2c4 --- /dev/null +++ b/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.cpp @@ -0,0 +1,19 @@ +#include "FlightTaskAltitudeCruise.hpp" + +FlightTaskAltitudeCruise::FlightTaskAltitudeCruise() +{ + _sticks_data_required = false; // disable stick requirement to not report flight task failure when they're lost +} + +void FlightTaskAltitudeCruise::reActivate() +{ + FlightTaskManualAltitudeSmoothVel::reActivate(); + _stick_tilt_xy.reset(); +} + +void FlightTaskAltitudeCruise::_updateXYSetpoint() +{ + _acceleration_setpoint.xy() = + _stick_tilt_xy.generateAccelerationSetpointsForAltitudeCruise( + _sticks.getPitchRoll(), _deltatime, _yaw, _yaw_setpoint); +} diff --git a/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.hpp b/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.hpp new file mode 100644 index 0000000000..1915b20304 --- /dev/null +++ b/src/modules/flight_mode_manager/tasks/AltitudeCruise/FlightTaskAltitudeCruise.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "FlightTaskManualAltitudeSmoothVel.hpp" + +class FlightTaskAltitudeCruise : public FlightTaskManualAltitudeSmoothVel +{ +public: + FlightTaskAltitudeCruise(); + virtual ~FlightTaskAltitudeCruise() = default; + + void reActivate() override; + +protected: + void _updateXYSetpoint() override; +}; diff --git a/src/modules/flight_mode_manager/tasks/Auto/CMakeLists.txt b/src/modules/flight_mode_manager/tasks/Auto/CMakeLists.txt index fc43d98d27..3c9022f909 100644 --- a/src/modules/flight_mode_manager/tasks/Auto/CMakeLists.txt +++ b/src/modules/flight_mode_manager/tasks/Auto/CMakeLists.txt @@ -35,5 +35,5 @@ px4_add_library(FlightTaskAuto FlightTaskAuto.cpp ) -target_link_libraries(FlightTaskAuto PUBLIC FlightTask FlightTaskUtility StickYaw WeatherVane) +target_link_libraries(FlightTaskAuto PUBLIC FlightTask FlightTaskUtility Sticks StickYaw WeatherVane) target_include_directories(FlightTaskAuto PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.cpp b/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.cpp index dbbf2533f9..ec999cdc0f 100644 --- a/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.cpp +++ b/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.cpp @@ -44,15 +44,12 @@ bool FlightTaskAuto::activate(const trajectory_setpoint_s &last_setpoint) { bool ret = FlightTask::activate(last_setpoint); + // Set setpoints equal current state. _position_setpoint = _position; _velocity_setpoint = _velocity; _yaw_setpoint = _yaw; _yawspeed_setpoint = 0.0f; - // Set setpoints equal current state. - _velocity_setpoint = _velocity; - _position_setpoint = _position; - Vector3f vel_prev{last_setpoint.velocity}; Vector3f pos_prev{last_setpoint.position}; Vector3f accel_prev{last_setpoint.acceleration}; @@ -64,8 +61,8 @@ bool FlightTaskAuto::activate(const trajectory_setpoint_s &last_setpoint) // If the velocity setpoint is unknown, set to the current velocity if (!PX4_ISFINITE(vel_prev(i))) { vel_prev(i) = _velocity(i); } - // No acceleration estimate available, set to zero if the setpoint is NAN - if (!PX4_ISFINITE(accel_prev(i))) { accel_prev(i) = 0.f; } + // If accel setpoint unknown, set to the current accel + if (!PX4_ISFINITE(accel_prev(i))) { accel_prev(i) = _acceleration(i); } } _position_smoothing.reset(accel_prev, vel_prev, pos_prev); @@ -266,21 +263,28 @@ void FlightTaskAuto::_prepareLandSetpoints() Vector2f sticks_ne = sticks_xy; Sticks::rotateIntoHeadingFrameXY(sticks_ne, _yaw, _land_heading); - const float distance_to_circle = math::trajectory::getMaxDistanceToCircle(_position.xy(), _initial_land_position.xy(), - _param_mpc_land_radius.get(), sticks_ne); - float max_speed; + float max_speed = INFINITY; - if (PX4_ISFINITE(distance_to_circle)) { - max_speed = math::trajectory::computeMaxSpeedFromDistance(_stick_acceleration_xy.getMaxJerk(), - _stick_acceleration_xy.getMaxAcceleration(), distance_to_circle, 0.f); + if (_param_mpc_land_radius.get() > FLT_EPSILON) { - if (max_speed < 0.5f) { + // = NaN if we are outside of the allowed circle and nudging does not point back towards it + const float distance_to_circle = math::trajectory::getMaxDistanceToCircle(_position.xy(), _initial_land_position.xy(), + _param_mpc_land_radius.get(), sticks_ne); + + if (PX4_ISFINITE(distance_to_circle)) { + + // We are inside of the allowed circle. Limit speed so we can always brake in time to not leave the circle. + max_speed = math::trajectory::computeMaxSpeedFromDistance(_stick_acceleration_xy.getMaxJerk(), + _stick_acceleration_xy.getMaxAcceleration(), distance_to_circle, 0.f); + + if (max_speed < 0.5f) { + sticks_xy.setZero(); + } + + } else { + max_speed = 0.f; sticks_xy.setZero(); } - - } else { - max_speed = 0.f; - sticks_xy.setZero(); } _stick_acceleration_xy.setVelocityConstraint(max_speed); @@ -612,6 +616,7 @@ State FlightTaskAuto::_getCurrentState() const Vector3f u_prev_to_target = (_triplet_target - _triplet_prev_wp).unit_or_zero(); const Vector3f prev_to_pos = _position - _triplet_prev_wp; const Vector3f pos_to_target = _triplet_target - _position; + // Calculate the closest point to the vehicle position on the line prev_wp - target _closest_pt = _triplet_prev_wp + u_prev_to_target * (prev_to_pos * u_prev_to_target); @@ -629,10 +634,9 @@ State FlightTaskAuto::_getCurrentState() // Previous is in front return_state = State::previous_infront; - } else if ((_position - _closest_pt).longerThan(_target_acceptance_radius)) { + } else if (_type != WaypointType::land && (_position - _closest_pt).longerThan(_target_acceptance_radius)) { // Vehicle too far from the track return_state = State::offtrack; - } return return_state; @@ -707,19 +711,20 @@ void FlightTaskAuto::_ekfResetHandlerVelocityXY(const matrix::Vector2f &delta_vx _position_smoothing.forceSetVelocity({_velocity(0), _velocity(1), NAN}); } -void FlightTaskAuto::_ekfResetHandlerPositionZ(float delta_z) +void FlightTaskAuto::_ekfResetHandlerPositionZ(const float delta_z) { _position_smoothing.forceSetPosition({NAN, NAN, _position(2)}); } -void FlightTaskAuto::_ekfResetHandlerVelocityZ(float delta_vz) +void FlightTaskAuto::_ekfResetHandlerVelocityZ(const float delta_vz) { _position_smoothing.forceSetVelocity({NAN, NAN, _velocity(2)}); } -void FlightTaskAuto::_ekfResetHandlerHeading(float delta_psi) +void FlightTaskAuto::_ekfResetHandlerHeading(const float delta_psi) { - _yaw_setpoint_previous += delta_psi; + _yaw_setpoint_previous = wrap_pi(_yaw_setpoint_previous + delta_psi); + _heading_smoothing.reset(wrap_pi(_heading_smoothing.getSmoothedHeading() + delta_psi)); } void FlightTaskAuto::_checkEmergencyBraking() diff --git a/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.hpp b/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.hpp index 00610d910c..89dfc494c1 100644 --- a/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.hpp +++ b/src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.hpp @@ -49,9 +49,9 @@ #include #include #include +#include #include #include -#include "Sticks.hpp" #include "StickAccelerationXY.hpp" /** diff --git a/src/modules/flight_mode_manager/tasks/AutoFollowTarget/FlightTaskAutoFollowTarget.hpp b/src/modules/flight_mode_manager/tasks/AutoFollowTarget/FlightTaskAutoFollowTarget.hpp index 7e7b97b589..bc3d5e9506 100644 --- a/src/modules/flight_mode_manager/tasks/AutoFollowTarget/FlightTaskAutoFollowTarget.hpp +++ b/src/modules/flight_mode_manager/tasks/AutoFollowTarget/FlightTaskAutoFollowTarget.hpp @@ -44,7 +44,6 @@ #include "FlightTaskAuto.hpp" #include "follow_target_estimator/TargetEstimator.hpp" -#include "Sticks.hpp" #include #include @@ -57,6 +56,7 @@ #include #include +#include #include // << Follow Target Behavior related constants >> diff --git a/src/modules/flight_mode_manager/tasks/Descend/CMakeLists.txt b/src/modules/flight_mode_manager/tasks/Descend/CMakeLists.txt index eada0139e0..aaaceefd72 100644 --- a/src/modules/flight_mode_manager/tasks/Descend/CMakeLists.txt +++ b/src/modules/flight_mode_manager/tasks/Descend/CMakeLists.txt @@ -35,5 +35,5 @@ px4_add_library(FlightTaskDescend FlightTaskDescend.cpp ) -target_link_libraries(FlightTaskDescend PUBLIC FlightTask FlightTaskUtility StickYaw) +target_link_libraries(FlightTaskDescend PUBLIC FlightTask FlightTaskUtility Sticks StickYaw) target_include_directories(FlightTaskDescend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/modules/flight_mode_manager/tasks/Descend/FlightTaskDescend.hpp b/src/modules/flight_mode_manager/tasks/Descend/FlightTaskDescend.hpp index 6792e8fd12..46ae7543d1 100644 --- a/src/modules/flight_mode_manager/tasks/Descend/FlightTaskDescend.hpp +++ b/src/modules/flight_mode_manager/tasks/Descend/FlightTaskDescend.hpp @@ -37,9 +37,9 @@ #pragma once +#include #include #include "FlightTask.hpp" -#include "Sticks.hpp" #include "StickTiltXY.hpp" class FlightTaskDescend : public FlightTask diff --git a/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.cpp b/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.cpp index fa2943f147..58d0253012 100644 --- a/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.cpp +++ b/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.cpp @@ -153,6 +153,17 @@ void FlightTask::_evaluateVehicleLocalPosition() _velocity(2) = _sub_vehicle_local_position.get().vz; } + // acceleration is calculated as the velocity derivative in EKF2, + // if velocity is available acceleration values are available + if (_sub_vehicle_local_position.get().v_xy_valid) { + _acceleration(0) = _sub_vehicle_local_position.get().ax; + _acceleration(1) = _sub_vehicle_local_position.get().ay; + } + + if (_sub_vehicle_local_position.get().v_z_valid) { + _acceleration(2) = _sub_vehicle_local_position.get().az; + } + // distance to bottom if (_sub_vehicle_local_position.get().dist_bottom_valid && PX4_ISFINITE(_sub_vehicle_local_position.get().dist_bottom)) { diff --git a/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.hpp b/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.hpp index 06327d8ca8..080c594d1a 100644 --- a/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.hpp +++ b/src/modules/flight_mode_manager/tasks/FlightTask/FlightTask.hpp @@ -201,6 +201,7 @@ protected: /* Current vehicle state */ matrix::Vector3f _position; /**< current vehicle position */ matrix::Vector3f _velocity; /**< current vehicle velocity */ + matrix::Vector3f _acceleration; /**< current vehicle acceleration (derivative of velocity) */ float _yaw{}; /**< current vehicle yaw heading */ float _unaided_yaw{}; diff --git a/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.cpp b/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.cpp index 788b7cf989..f73fbe4023 100644 --- a/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.cpp +++ b/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.cpp @@ -74,12 +74,11 @@ bool FlightTaskManualAcceleration::update() static constexpr float min_vel = 2.f; // minimum max-velocity near max_hagl if (max_hagl_ratio > factor_threshold) { - max_hagl_ratio = math::min(max_hagl_ratio, 1.f); const float vxy_max = math::min(vehicle_local_pos.vxy_max, _param_mpc_vel_manual.get()); - _stick_acceleration_xy.setVelocityConstraint(interpolate(vxy_max, factor_threshold, min_vel, vxy_max, min_vel)); + _stick_acceleration_xy.setVelocityConstraint(interpolate(max_hagl_ratio, factor_threshold, 1.f, vxy_max, min_vel)); - } else { - _stick_acceleration_xy.setVelocityConstraint(math::min(_param_mpc_vel_manual.get(), vehicle_local_pos.vxy_max)); + } else if (PX4_ISFINITE(vehicle_local_pos.vxy_max)) { + _stick_acceleration_xy.setVelocityConstraint(vehicle_local_pos.vxy_max); } _stick_acceleration_xy.generateSetpoints(_sticks.getPitchRollExpo(), _yaw, _yaw_setpoint, _position, diff --git a/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.hpp b/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.hpp index 56fefcc792..2ce9a7c44f 100644 --- a/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.hpp +++ b/src/modules/flight_mode_manager/tasks/ManualAcceleration/FlightTaskManualAcceleration.hpp @@ -52,7 +52,7 @@ protected: StickAccelerationXY _stick_acceleration_xy{this}; WeatherVane _weathervane{this}; /**< weathervane library, used to implement a yaw control law that turns the vehicle nose into the wind */ - DEFINE_PARAMETERS_CUSTOM_PARENT(FlightTask, + DEFINE_PARAMETERS_CUSTOM_PARENT(FlightTaskManualAltitudeSmoothVel, (ParamFloat) _param_mpc_vel_manual, (ParamFloat) _param_mpc_acc_hor ) diff --git a/src/modules/flight_mode_manager/tasks/ManualAltitude/CMakeLists.txt b/src/modules/flight_mode_manager/tasks/ManualAltitude/CMakeLists.txt index 65abdf871c..59b51435e1 100644 --- a/src/modules/flight_mode_manager/tasks/ManualAltitude/CMakeLists.txt +++ b/src/modules/flight_mode_manager/tasks/ManualAltitude/CMakeLists.txt @@ -35,5 +35,5 @@ px4_add_library(FlightTaskManualAltitude FlightTaskManualAltitude.cpp ) -target_link_libraries(FlightTaskManualAltitude PUBLIC FlightTask FlightTaskUtility StickYaw) +target_link_libraries(FlightTaskManualAltitude PUBLIC FlightTask FlightTaskUtility Sticks StickYaw) target_include_directories(FlightTaskManualAltitude PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.cpp b/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.cpp index 2f27fd1aed..778cea55f2 100644 --- a/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.cpp +++ b/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.cpp @@ -91,8 +91,8 @@ void FlightTaskManualAltitude::_scaleSticks() // Use sticks input with deadzone and exponential curve for vertical velocity const float vel_max_up = fminf(_param_mpc_z_vel_max_up.get(), _velocity_constraint_up); const float vel_max_down = fminf(_param_mpc_z_vel_max_dn.get(), _velocity_constraint_down); - const float vel_max_z = (_sticks.getPosition()(2) > 0.0f) ? vel_max_down : vel_max_up; - _velocity_setpoint(2) = vel_max_z * _sticks.getPositionExpo()(2); + const float vel_max_z = (_sticks.getThrottleZeroCentered() < 0.f) ? vel_max_down : vel_max_up; + _velocity_setpoint(2) = vel_max_z * -_sticks.getThrottleZeroCenteredExpo(); } void FlightTaskManualAltitude::_updateAltitudeLock() @@ -101,7 +101,7 @@ void FlightTaskManualAltitude::_updateAltitudeLock() // If not locked, altitude setpoint is set to NAN. // Check if user wants to break - const bool apply_brake = fabsf(_sticks.getPositionExpo()(2)) <= FLT_EPSILON; + const bool apply_brake = fabsf(_sticks.getThrottleZeroCenteredExpo()) <= FLT_EPSILON; // Check if vehicle has stopped const bool stopped = (_param_mpc_hold_max_z.get() < FLT_EPSILON || fabsf(_velocity(2)) < _param_mpc_hold_max_z.get()); @@ -274,17 +274,29 @@ void FlightTaskManualAltitude::_ekfResetHandlerHagl(float delta_hagl) void FlightTaskManualAltitude::_updateSetpoints() { - _stick_yaw.generateYawSetpoint(_yawspeed_setpoint, _yaw_setpoint, _sticks.getYawExpo(), _yaw, _deltatime, _unaided_yaw); - _acceleration_setpoint.xy() = _stick_tilt_xy.generateAccelerationSetpoints(_sticks.getPitchRoll(), _deltatime, _yaw, - _yaw_setpoint); + _updateYawSetpoint(); + _updateXYSetpoint(); _updateAltitudeLock(); _respectGroundSlowdown(); } +void FlightTaskManualAltitude::_updateYawSetpoint() +{ + _stick_yaw.generateYawSetpoint(_yawspeed_setpoint, _yaw_setpoint, + _sticks.getYawExpo(), _yaw, _deltatime, + _unaided_yaw); +} + +void FlightTaskManualAltitude::_updateXYSetpoint() +{ + _acceleration_setpoint.xy() = _stick_tilt_xy.generateAccelerationSetpoints( + _sticks.getPitchRoll(), _deltatime, _yaw, _yaw_setpoint); +} + bool FlightTaskManualAltitude::_checkTakeoff() { // stick is deflected above 65% throttle (throttle stick is in the range [-1,1]) - return _sticks.getPosition()(2) < -0.3f; + return _sticks.getThrottleZeroCentered() > 0.3f; } bool FlightTaskManualAltitude::update() diff --git a/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.hpp b/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.hpp index 8386dfedad..92648daf7c 100644 --- a/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.hpp +++ b/src/modules/flight_mode_manager/tasks/ManualAltitude/FlightTaskManualAltitude.hpp @@ -40,8 +40,8 @@ #pragma once #include +#include #include "FlightTask.hpp" -#include "Sticks.hpp" #include "StickTiltXY.hpp" #include @@ -60,6 +60,8 @@ protected: void _ekfResetHandlerHagl(float delta_hagl) override; virtual void _updateSetpoints(); /**< updates all setpoints */ + virtual void _updateYawSetpoint(); + virtual void _updateXYSetpoint(); virtual void _scaleSticks(); /**< scales sticks to velocity in z */ bool _checkTakeoff() override; void _updateConstraintsFromEstimator(); diff --git a/src/modules/flight_mode_manager/tasks/Orbit/FlightTaskOrbit.cpp b/src/modules/flight_mode_manager/tasks/Orbit/FlightTaskOrbit.cpp index c8a79a7b0c..55c6b64273 100644 --- a/src/modules/flight_mode_manager/tasks/Orbit/FlightTaskOrbit.cpp +++ b/src/modules/flight_mode_manager/tasks/Orbit/FlightTaskOrbit.cpp @@ -173,7 +173,7 @@ void FlightTaskOrbit::_sanitizeParams(float &radius, float &velocity) const bool FlightTaskOrbit::activate(const trajectory_setpoint_s &last_setpoint) { - bool ret = FlightTaskManualAltitude::activate(last_setpoint); + bool ret = FlightTaskManualAltitudeSmoothVel::activate(last_setpoint); _currently_orbiting = false; _orbit_radius = _radius_min; _orbit_velocity = 1.f; @@ -292,8 +292,8 @@ void FlightTaskOrbit::_adjustParametersByStick() switch (_yaw_behaviour) { case orbit_status_s::ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TANGENT_TO_CIRCLE: - radius -= signFromBool(_started_clockwise) * _sticks.getPositionExpo()(1) * _deltatime * _param_mpc_xy_cruise.get(); - velocity += signFromBool(_started_clockwise) * _sticks.getPositionExpo()(0) * _deltatime * _param_mpc_acc_hor.get(); + radius -= signFromBool(_started_clockwise) * _sticks.getRollExpo() * _deltatime * _param_mpc_xy_cruise.get(); + velocity += signFromBool(_started_clockwise) * _sticks.getPitchExpo() * _deltatime * _param_mpc_acc_hor.get(); break; case orbit_status_s::ORBIT_YAW_BEHAVIOUR_HOLD_INITIAL_HEADING: @@ -302,8 +302,8 @@ void FlightTaskOrbit::_adjustParametersByStick() case orbit_status_s::ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TO_CIRCLE_CENTER: default: // stick input adjusts parameters within a fixed time frame - radius -= _sticks.getPositionExpo()(0) * _deltatime * _param_mpc_xy_cruise.get(); - velocity -= _sticks.getPositionExpo()(1) * _deltatime * _param_mpc_acc_hor.get(); + radius -= _sticks.getPitchExpo() * _deltatime * _param_mpc_xy_cruise.get(); + velocity -= _sticks.getRollExpo() * _deltatime * _param_mpc_acc_hor.get(); break; } diff --git a/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.cpp b/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.cpp index 727d7cd529..8192bfdd3d 100644 --- a/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.cpp +++ b/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.cpp @@ -57,6 +57,9 @@ bool FlightTaskTransition::activate(const trajectory_setpoint_s &last_setpoint) _vel_z_filter.reset(_velocity(2)); } + const Vector2f acceleration_xy{_sub_vehicle_local_position.get().ax, _sub_vehicle_local_position.get().ay}; + _accel_filter.reset(acceleration_xy); + if (_sub_vehicle_status.get().in_transition_to_fw) { _gear.landing_gear = landing_gear_s::GEAR_UP; @@ -86,21 +89,27 @@ bool FlightTaskTransition::update() // calculate a horizontal acceleration vector which corresponds to an attitude composed of pitch up by _param_fw_psp_off // and zero roll angle - float pitch_setpoint = math::radians(_param_fw_psp_off); + float tilt_setpoint = math::radians(_param_fw_psp_off); + Vector2f horizontal_acceleration_direction; if (!_sub_vehicle_status.get().in_transition_to_fw) { - pitch_setpoint = computeBackTranstionPitchSetpoint(); + tilt_setpoint = computeBackTransitionTiltSetpoint(); + const Vector2f velocity_xy{_velocity}; + horizontal_acceleration_direction = -velocity_xy.unit_or_zero(); + + } else { + // Forward transition: use heading direction + horizontal_acceleration_direction = Dcm2f(_yaw) * Vector2f(-1.0f, 0.0f); } - // Calculate horizontal acceleration components to follow a pitch setpoint with the current vehicle heading - const Vector2f horizontal_acceleration_direction = Dcm2f(_yaw) * Vector2f(-1.0f, 0.0f); - _acceleration_setpoint.xy() = tanf(pitch_setpoint) * CONSTANTS_ONE_G * horizontal_acceleration_direction; + _acceleration_setpoint.xy() = tanf(tilt_setpoint) * CONSTANTS_ONE_G * horizontal_acceleration_direction; _yaw_setpoint = NAN; + _yawspeed_setpoint = 0.f; return ret; } -float FlightTaskTransition::computeBackTranstionPitchSetpoint() +float FlightTaskTransition::computeBackTransitionTiltSetpoint() { const Vector2f position_xy{_position}; const Vector2f velocity_xy{_velocity}; @@ -109,8 +118,11 @@ float FlightTaskTransition::computeBackTranstionPitchSetpoint() float deceleration_setpoint = _param_vt_b_dec_mss; - if (_sub_position_sp_triplet.get().current.valid && _sub_vehicle_local_position.get().xy_global - && position_xy.isAllFinite() && velocity_xy.isAllFinite()) { + const float max_hor_pos_uncertainty_limit = 10.f; + + if (_sub_vehicle_local_position.get().eph < max_hor_pos_uncertainty_limit + && _sub_position_sp_triplet.get().current.valid + && _sub_vehicle_local_position.get().xy_global && position_xy.isAllFinite() && velocity_xy.isAllFinite()) { Vector2f position_setpoint_local; _geo_projection.project(_sub_position_sp_triplet.get().current.lat, _sub_position_sp_triplet.get().current.lon, position_setpoint_local(0), position_setpoint_local(1)); @@ -129,13 +141,13 @@ float FlightTaskTransition::computeBackTranstionPitchSetpoint() deceleration_setpoint = math::min(deceleration_setpoint, 2.f * _param_vt_b_dec_mss); } - // Pitch up to reach a negative accel_in_flight_direction otherwise we decelerate too slow - const Vector2f acceleration_xy{_sub_vehicle_local_position.get().ax, _sub_vehicle_local_position.get().ay}; + const Vector2f acceleration_xy_raw{_sub_vehicle_local_position.get().ax, _sub_vehicle_local_position.get().ay}; + const Vector2f acceleration_xy = _accel_filter.update(acceleration_xy_raw, _deltatime); const float deceleration = -acceleration_xy.dot(velocity_xy_direction); // Zero when velocity invalid const float deceleration_error = deceleration_setpoint - deceleration; // Update back-transition deceleration error integrator _decel_error_bt_int += (_param_vt_b_dec_i * deceleration_error) * _deltatime; - _decel_error_bt_int = math::constrain(_decel_error_bt_int, 0.f, DECELERATION_INTEGRATOR_LIMIT); + _decel_error_bt_int = math::constrain(_decel_error_bt_int, 0.f, kDecelerationIntegratorLimit); return _decel_error_bt_int; } diff --git a/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.hpp b/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.hpp index 12687223b5..a226ee9f6b 100644 --- a/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.hpp +++ b/src/modules/flight_mode_manager/tasks/Transition/FlightTaskTransition.hpp @@ -61,8 +61,9 @@ public: bool update() override; private: - static constexpr float VERTICAL_VELOCITY_TIME_CONSTANT = 2.0f; - static constexpr float DECELERATION_INTEGRATOR_LIMIT = .3f; + static constexpr float kVerticalVelocityTimeConstant = 2.0f; + static constexpr float kDecelerationIntegratorLimit = 0.3f; + static constexpr float kAccelerationFilterTimeConstant = 0.05f; uORB::SubscriptionData _sub_vehicle_status{ORB_ID(vehicle_status)}; uORB::SubscriptionData _sub_position_sp_triplet{ORB_ID(position_setpoint_triplet)}; @@ -71,8 +72,9 @@ private: float _param_vt_b_dec_i{0.f}; float _param_vt_b_dec_mss{0.f}; - AlphaFilter _vel_z_filter{VERTICAL_VELOCITY_TIME_CONSTANT}; + AlphaFilter _vel_z_filter{kVerticalVelocityTimeConstant}; + AlphaFilter _accel_filter{kAccelerationFilterTimeConstant}; float _decel_error_bt_int{0.f}; ///< Backtransition deceleration error integrator value - float computeBackTranstionPitchSetpoint(); + float computeBackTransitionTiltSetpoint(); }; diff --git a/src/modules/flight_mode_manager/tasks/Utility/CMakeLists.txt b/src/modules/flight_mode_manager/tasks/Utility/CMakeLists.txt index f81a994452..c12356658b 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/CMakeLists.txt +++ b/src/modules/flight_mode_manager/tasks/Utility/CMakeLists.txt @@ -32,13 +32,12 @@ ############################################################################ px4_add_library(FlightTaskUtility - Sticks.cpp StickAccelerationXY.cpp StickTiltXY.cpp Gimbal.cpp ) -target_link_libraries(FlightTaskUtility PUBLIC FlightTask hysteresis SlewRate motion_planning mathlib) +target_link_libraries(FlightTaskUtility PUBLIC FlightTask hysteresis SlewRate Sticks motion_planning mathlib) target_include_directories(FlightTaskUtility PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) px4_add_functional_gtest(SRC StickTiltXYTest.cpp LINKLIBS FlightTaskUtility) diff --git a/src/modules/flight_mode_manager/tasks/Utility/Gimbal.cpp b/src/modules/flight_mode_manager/tasks/Utility/Gimbal.cpp index 21e97f5fc3..f56ee48804 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/Gimbal.cpp +++ b/src/modules/flight_mode_manager/tasks/Utility/Gimbal.cpp @@ -63,29 +63,35 @@ bool Gimbal::checkForTelemetry(const hrt_abstime now) void Gimbal::acquireGimbalControlIfNeeded() { - if (!_have_gimbal_control) { - _have_gimbal_control = true; + gimbal_manager_status_s gimbal_manager_status; - vehicle_command_s vehicle_command{}; - vehicle_command.command = vehicle_command_s::VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE; - vehicle_command.param1 = _param_mav_sys_id.get(); - vehicle_command.param2 = _param_mav_comp_id.get(); - vehicle_command.param3 = -1.0f; // Leave unchanged. - vehicle_command.param4 = -1.0f; // Leave unchanged. - vehicle_command.timestamp = hrt_absolute_time(); - vehicle_command.source_system = _param_mav_sys_id.get(); - vehicle_command.source_component = _param_mav_comp_id.get(); - vehicle_command.target_system = _param_mav_sys_id.get(); - vehicle_command.target_component = _param_mav_sys_id.get(); - vehicle_command.from_external = false; - _vehicle_command_pub.publish(vehicle_command); + if (_gimbal_manager_status_sub.updated()) { + _gimbal_manager_status_sub.copy(&gimbal_manager_status); + + if (gimbal_manager_status.primary_control_compid != _param_mav_comp_id.get() || + gimbal_manager_status.primary_control_sysid != _param_mav_sys_id.get()) { + _tried_to_have_gimbal_control = true; + vehicle_command_s vehicle_command{}; + vehicle_command.command = vehicle_command_s::VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE; + vehicle_command.param1 = _param_mav_sys_id.get(); + vehicle_command.param2 = _param_mav_comp_id.get(); + vehicle_command.param3 = -1.0f; // Leave unchanged. + vehicle_command.param4 = -1.0f; // Leave unchanged. + vehicle_command.timestamp = hrt_absolute_time(); + vehicle_command.source_system = _param_mav_sys_id.get(); + vehicle_command.source_component = _param_mav_comp_id.get(); + vehicle_command.target_system = _param_mav_sys_id.get(); + vehicle_command.target_component = _param_mav_sys_id.get(); + vehicle_command.from_external = false; + _vehicle_command_pub.publish(vehicle_command); + } } } void Gimbal::releaseGimbalControlIfNeeded() { - if (_have_gimbal_control) { - _have_gimbal_control = false; + if (_tried_to_have_gimbal_control) { + _tried_to_have_gimbal_control = false; // Restore default flags, setting rate setpoints to NAN lead to unexpected behavior publishGimbalManagerSetAttitude(FLAGS_ROLL_PITCH_LOCKED, diff --git a/src/modules/flight_mode_manager/tasks/Utility/Gimbal.hpp b/src/modules/flight_mode_manager/tasks/Utility/Gimbal.hpp index 938ef32aa2..01a324b4a9 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/Gimbal.hpp +++ b/src/modules/flight_mode_manager/tasks/Utility/Gimbal.hpp @@ -45,9 +45,11 @@ #include #include #include +#include #include -#include "Sticks.hpp" +#include + class Gimbal : public ModuleParams @@ -73,9 +75,9 @@ public: | gimbal_manager_set_attitude_s::GIMBAL_MANAGER_FLAGS_PITCH_LOCK; private: - bool _have_gimbal_control{false}; - + bool _tried_to_have_gimbal_control{false}; uORB::Subscription _gimbal_device_attitude_status_sub{ORB_ID(gimbal_device_attitude_status)}; + uORB::Subscription _gimbal_manager_status_sub{ORB_ID(gimbal_manager_status)}; hrt_abstime _telemtry_timestamp{}; uint16_t _telemetry_flags{}; float _telemetry_yaw{}; diff --git a/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.cpp b/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.cpp index 052378244b..3eeb56bd86 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.cpp +++ b/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.cpp @@ -34,7 +34,7 @@ #include "StickAccelerationXY.hpp" #include -#include "Sticks.hpp" +#include using namespace matrix; @@ -43,6 +43,8 @@ StickAccelerationXY::StickAccelerationXY(ModuleParams *parent) : { _brake_boost_filter.reset(1.f); resetPosition(); + _velocity_slew_rate_xy.setSlewRate(_param_mpc_acc_hor.get()); + _velocity_slew_rate_xy.setForcedValue(_param_mpc_vel_manual.get()); } void StickAccelerationXY::resetPosition() @@ -75,23 +77,22 @@ void StickAccelerationXY::resetAcceleration(const matrix::Vector2f &acceleration } } +void StickAccelerationXY::setVelocityConstraint(float vel) +{ + if ((vel < _velocity_constraint) && (vel >= FLT_EPSILON)) { + _velocity_constraint = vel; + } +}; + void StickAccelerationXY::generateSetpoints(Vector2f stick_xy, const float yaw, const float yaw_sp, const Vector3f &pos, const matrix::Vector2f &vel_sp_feedback, const float dt) { - // gradually adjust velocity constraint because good tracking is required for the drag estimation - if (fabsf(_targeted_velocity_constraint - _current_velocity_constraint) > 0.1f) { - if (!PX4_ISFINITE(_current_velocity_constraint) || !PX4_ISFINITE(_targeted_velocity_constraint)) { - _current_velocity_constraint = _targeted_velocity_constraint; - - } else { - _current_velocity_constraint = math::constrain(_targeted_velocity_constraint, - _current_velocity_constraint - dt * _param_mpc_acc_hor.get(), - _current_velocity_constraint + dt * _param_mpc_acc_hor.get()); - } - } + // avoid setpoint steps from limit changes to improve velocity tracking and hence drag estimation + const float velocity_constraint = _velocity_slew_rate_xy.update(_velocity_constraint, dt); + _velocity_constraint = _param_mpc_vel_manual.get(); // reset, reduced to strictest limit in next loop // maximum commanded velocity can be constrained dynamically - const float velocity_sc = fminf(_param_mpc_vel_manual.get(), _current_velocity_constraint); + const float velocity_sc = fminf(_param_mpc_vel_manual.get(), velocity_constraint); Vector2f velocity_scale(velocity_sc, velocity_sc); // maximum commanded acceleration is scaled down with velocity const float acceleration_sc = _param_mpc_acc_hor.get() * (velocity_sc / _param_mpc_vel_manual.get()); diff --git a/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.hpp b/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.hpp index ad6f4afec1..feb4070643 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.hpp +++ b/src/modules/flight_mode_manager/tasks/Utility/StickAccelerationXY.hpp @@ -64,8 +64,10 @@ public: void getSetpoints(matrix::Vector3f &pos_sp, matrix::Vector3f &vel_sp, matrix::Vector3f &acc_sp); float getMaxAcceleration() { return _param_mpc_acc_hor.get(); }; float getMaxJerk() { return _param_mpc_jerk_max.get(); }; - void setVelocityConstraint(float vel) { _targeted_velocity_constraint = fmaxf(vel, FLT_EPSILON); }; - float getVelocityConstraint() { return _current_velocity_constraint; }; + + // Assuming the velocity constraint resets in every loop and update constraint if new value is lower + void setVelocityConstraint(float vel); + float getVelocityConstraint() { return _velocity_slew_rate_xy.getState(); }; private: CollisionPrevention _collision_prevention{this}; @@ -80,6 +82,7 @@ private: SlewRate _acceleration_slew_rate_x; SlewRate _acceleration_slew_rate_y; + SlewRate _velocity_slew_rate_xy; AlphaFilter _brake_boost_filter; matrix::Vector2f _position_setpoint; @@ -87,8 +90,7 @@ private: matrix::Vector2f _acceleration_setpoint; matrix::Vector2f _acceleration_setpoint_prev; - float _targeted_velocity_constraint{INFINITY}; - float _current_velocity_constraint{INFINITY}; + float _velocity_constraint{INFINITY}; DEFINE_PARAMETERS( (ParamFloat) _param_mpc_vel_manual, diff --git a/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.cpp b/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.cpp index 642c4ef8a1..6148bb985d 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.cpp +++ b/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.cpp @@ -34,7 +34,7 @@ #include "StickTiltXY.hpp" #include -#include "Sticks.hpp" +#include using namespace matrix; @@ -44,6 +44,11 @@ StickTiltXY::StickTiltXY(ModuleParams *parent) : updateParams(); } +void StickTiltXY::reset() +{ + _altitude_cruise_acceleration.setZero(); +} + void StickTiltXY::updateParams() { ModuleParams::updateParams(); @@ -62,3 +67,21 @@ Vector2f StickTiltXY::generateAccelerationSetpoints(Vector2f stick_xy, const flo Sticks::rotateIntoHeadingFrameXY(stick_xy, yaw, yaw_setpoint); return stick_xy * _maximum_acceleration; } + +Vector2f StickTiltXY::generateAccelerationSetpointsForAltitudeCruise(Vector2f stick_xy, const float dt, const float yaw, + const float yaw_setpoint) +{ + Sticks::limitStickUnitLengthXY(stick_xy); + const Vector2f increment = stick_xy; + // at full stick deflection it takes 1s from -tilt_max to tilt_max + _altitude_cruise_acceleration += increment * _maximum_acceleration * 2.f * dt; + + if (_altitude_cruise_acceleration.longerThan(_maximum_acceleration)) { + _altitude_cruise_acceleration = + _altitude_cruise_acceleration.unit_or_zero() * _maximum_acceleration; + } + + Vector2f global_altitude_cruise_acceleration = _altitude_cruise_acceleration; + Sticks::rotateIntoHeadingFrameXY(global_altitude_cruise_acceleration, yaw, yaw_setpoint); + return global_altitude_cruise_acceleration; +} diff --git a/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.hpp b/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.hpp index f5caea8550..992c975224 100644 --- a/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.hpp +++ b/src/modules/flight_mode_manager/tasks/Utility/StickTiltXY.hpp @@ -62,11 +62,17 @@ public: */ matrix::Vector2f generateAccelerationSetpoints(matrix::Vector2f stick_xy, const float dt, const float yaw, const float yaw_setpoint); + + matrix::Vector2f generateAccelerationSetpointsForAltitudeCruise(matrix::Vector2f stick_xy, const float dt, + const float yaw, const float yaw_setpoint); + + void reset(); private: void updateParams() override; float _maximum_acceleration{0.f}; AlphaFilter _man_input_filter; + matrix::Vector2f _altitude_cruise_acceleration{}; DEFINE_PARAMETERS( (ParamFloat) _param_mpc_man_tilt_max, ///< maximum tilt allowed for manual flight diff --git a/src/modules/fw_att_control/FixedwingAttitudeControl.cpp b/src/modules/fw_att_control/FixedwingAttitudeControl.cpp index f9328635e6..ec856e942d 100644 --- a/src/modules/fw_att_control/FixedwingAttitudeControl.cpp +++ b/src/modules/fw_att_control/FixedwingAttitudeControl.cpp @@ -48,6 +48,7 @@ FixedwingAttitudeControl::FixedwingAttitudeControl(bool vtol) : /* fetch initial parameter values */ parameters_update(); _landing_gear_wheel_pub.advertise(); + _attitude_sp_pub.advertise(); } FixedwingAttitudeControl::~FixedwingAttitudeControl() @@ -318,6 +319,9 @@ void FixedwingAttitudeControl::Run() if ((pid_autotune.state == autotune_attitude_control_status_s::STATE_ROLL || pid_autotune.state == autotune_attitude_control_status_s::STATE_PITCH || pid_autotune.state == autotune_attitude_control_status_s::STATE_YAW + || pid_autotune.state == autotune_attitude_control_status_s::STATE_ROLL_AMPLITUDE_DETECTION + || pid_autotune.state == autotune_attitude_control_status_s::STATE_PITCH_AMPLITUDE_DETECTION + || pid_autotune.state == autotune_attitude_control_status_s::STATE_YAW_AMPLITUDE_DETECTION || pid_autotune.state == autotune_attitude_control_status_s::STATE_TEST) && ((hrt_absolute_time() - pid_autotune.timestamp) < 1_s)) { diff --git a/src/modules/fw_att_control/fw_pitch_controller.h b/src/modules/fw_att_control/fw_pitch_controller.h index a71168f190..d8a40ab636 100644 --- a/src/modules/fw_att_control/fw_pitch_controller.h +++ b/src/modules/fw_att_control/fw_pitch_controller.h @@ -64,11 +64,11 @@ public: float get_body_rate_setpoint() { return _body_rate_setpoint; } private: - float _tc; - float _max_rate_pos; - float _max_rate_neg; - float _euler_rate_setpoint; - float _body_rate_setpoint; + float _tc{}; + float _max_rate_pos{}; + float _max_rate_neg{}; + float _euler_rate_setpoint{}; + float _body_rate_setpoint{}; }; #endif // FW_PITCH_CONTROLLER_H diff --git a/src/modules/fw_att_control/fw_roll_controller.h b/src/modules/fw_att_control/fw_roll_controller.h index a14277e3f0..5e47f0ffd0 100644 --- a/src/modules/fw_att_control/fw_roll_controller.h +++ b/src/modules/fw_att_control/fw_roll_controller.h @@ -63,10 +63,10 @@ public: float get_body_rate_setpoint() { return _body_rate_setpoint; } private: - float _tc; - float _max_rate; - float _euler_rate_setpoint; - float _body_rate_setpoint; + float _tc{}; + float _max_rate{}; + float _euler_rate_setpoint{}; + float _body_rate_setpoint{}; }; #endif // FW_ROLL_CONTROLLER_H diff --git a/src/modules/fw_att_control/fw_yaw_controller.h b/src/modules/fw_att_control/fw_yaw_controller.h index 7e97618a26..e6f9ff9795 100644 --- a/src/modules/fw_att_control/fw_yaw_controller.h +++ b/src/modules/fw_att_control/fw_yaw_controller.h @@ -71,9 +71,9 @@ public: float get_body_rate_setpoint() { return _body_rate_setpoint; } private: - float _max_rate; - float _euler_rate_setpoint; - float _body_rate_setpoint; + float _max_rate{}; + float _euler_rate_setpoint{}; + float _body_rate_setpoint{}; }; #endif // FW_YAW_CONTROLLER_H diff --git a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.cpp b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.cpp index 8bb783d3d1..e45741d2cf 100644 --- a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.cpp +++ b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.cpp @@ -48,7 +48,6 @@ FwAutotuneAttitudeControl::FwAutotuneAttitudeControl(bool is_vtol) : _actuator_controls_status_sub(is_vtol ? ORB_ID(actuator_controls_status_1) : ORB_ID(actuator_controls_status_0)) { _autotune_attitude_control_status_pub.advertise(); - reset(); } FwAutotuneAttitudeControl::~FwAutotuneAttitudeControl() @@ -73,11 +72,6 @@ bool FwAutotuneAttitudeControl::init() return true; } -void FwAutotuneAttitudeControl::reset() -{ - _param_fw_at_start.reset(); -} - void FwAutotuneAttitudeControl::Run() { if (should_exit()) { @@ -107,10 +101,23 @@ void FwAutotuneAttitudeControl::Run() } } + if (_vehicle_command_sub.updated()) { + vehicle_command_s vehicle_command; + + if (_vehicle_command_sub.copy(&vehicle_command)) { + if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_DO_AUTOTUNE_ENABLE) { + if (fabsf(vehicle_command.param1 - 1.0f) < FLT_EPSILON && fabsf(vehicle_command.param2) < FLT_EPSILON) { + _vehicle_cmd_start_autotune = true; + } + } + } + } + _aux_switch_en = isAuxEnableSwitchEnabled(); + _want_start_autotune = _vehicle_cmd_start_autotune || _aux_switch_en; // new control data needed every iteration - if ((_state == state::idle && !_aux_switch_en) + if ((_state == state::idle && !_want_start_autotune) || !_vehicle_torque_setpoint_sub.updated()) { return; @@ -124,11 +131,18 @@ void FwAutotuneAttitudeControl::Run() } } - vehicle_torque_setpoint_s vehicle_torque_setpoint; - vehicle_angular_velocity_s angular_velocity; - if (!_vehicle_torque_setpoint_sub.copy(&vehicle_torque_setpoint) - || !_vehicle_angular_velocity_sub.copy(&angular_velocity)) { + if (_vehicle_angular_velocity_sub.updated()) { + vehicle_angular_velocity_s vehicle_angular_velocity; + + if (_vehicle_angular_velocity_sub.copy(&vehicle_angular_velocity)) { + _angular_velocity = Vector3f(vehicle_angular_velocity.xyz); + } + } + + vehicle_torque_setpoint_s vehicle_torque_setpoint; + + if (!_vehicle_torque_setpoint_sub.copy(&vehicle_torque_setpoint)) { return; } @@ -152,17 +166,17 @@ void FwAutotuneAttitudeControl::Run() checkFilters(); - if (_state == state::roll) { + if (_state == state::roll || _state == state::roll_amp_detection) { _sys_id.update(_input_scale * vehicle_torque_setpoint.xyz[0], - angular_velocity.xyz[0]); + _angular_velocity(0)); - } else if (_state == state::pitch) { + } else if (_state == state::pitch || _state == state::pitch_amp_detection) { _sys_id.update(_input_scale * vehicle_torque_setpoint.xyz[1], - angular_velocity.xyz[1]); + _angular_velocity(1)); - } else if (_state == state::yaw) { + } else if (_state == state::yaw || _state == state::yaw_amp_detection) { _sys_id.update(_input_scale * vehicle_torque_setpoint.xyz[2], - angular_velocity.xyz[2]); + _angular_velocity(2)); } if (hrt_elapsed_time(&_last_publish) > _publishing_dt_hrt || _last_publish == 0) { @@ -188,9 +202,16 @@ void FwAutotuneAttitudeControl::Run() _attitude_p = math::constrain(1.f / (math::radians(60.f) * (_kiff(0) + _kiff(2))), 1.f, 5.f); const Vector &coeff_var = _sys_id.getVariances(); - const Vector3f rate_sp = _sys_id.areFiltersInitialized() - ? getIdentificationSignal() - : Vector3f(); + Vector3f rate_sp{}; + + if (_sys_id.areFiltersInitialized()) { + if (_state == state::roll_amp_detection || _state == state::pitch_amp_detection || _state == state::yaw_amp_detection) { + rate_sp = getAmplitudeDetectionSignal(); + + } else { + rate_sp = getIdentificationSignal(); + } + } autotune_attitude_control_status_s status{}; status.timestamp = now; @@ -296,7 +317,8 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) switch (_state) { case state::idle: - if (_param_fw_at_start.get() || _aux_switch_en) { + + if (_want_start_autotune) { mavlink_log_info(&_mavlink_log_pub, "Autotune started"); _state = state::init; @@ -308,7 +330,8 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) case state::init: if (_are_filters_initialized) { - _state = state::roll; + _state = state::roll_amp_detection; + _amplitude_detection_state = amplitudeDetectionState::init; _state_start_time = now; _sys_id.reset(sys_id_init); // first step needs to be shorter to keep the drone centered @@ -322,12 +345,29 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) break; - case state::roll: - if (!(_param_fw_at_axes.get() & Axes::roll)) { - // Should not tune this axis, skip - _state = state::roll_pause; + case state::roll_amp_detection: { + if (!(_param_fw_at_axes.get() & Axes::roll)) { + // Should not tune this axis, skip + _state = state::roll_pause; + break; + } + + const float abs_roll_rate = fabsf(_angular_velocity(0)); + const float target = 0.75f * math::radians(_param_fw_r_rmax.get()); + + updateAmplitudeDetectionState(now, abs_roll_rate, target); + + if (_amplitude_detection_state == amplitudeDetectionState::complete) { + + _state = state::roll; + _state_start_time = now; + } + + break; } + case state::roll: + if ((_sys_id.getFitness() < converged_thr) && ((now - _state_start_time) > 5_s)) { copyGains(0); @@ -341,7 +381,8 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) case state::roll_pause: if ((now - _state_start_time) > 2_s) { - _state = state::pitch; + _state = state::pitch_amp_detection; + _amplitude_detection_state = amplitudeDetectionState::init; _state_start_time = now; _sys_id.reset(sys_id_init); _input_scale = 1.f / _param_fw_pr_p.get(); @@ -354,12 +395,30 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) break; - case state::pitch: - if (!(_param_fw_at_axes.get() & Axes::pitch)) { - // Should not tune this axis, skip - _state = state::pitch_pause; + case state::pitch_amp_detection: { + if (!(_param_fw_at_axes.get() & Axes::pitch)) { + // Should not tune this axis, skip + _state = state::pitch_pause; + break; + } + + const float abs_pitch_rate = fabsf(_angular_velocity(1)); + const float max_pitch_rate = min(_param_fw_p_rmax_pos.get(), _param_fw_p_rmax_neg.get()); + const float target = 0.75f * math::radians(max_pitch_rate); + + updateAmplitudeDetectionState(now, abs_pitch_rate, target); + + if (_amplitude_detection_state == amplitudeDetectionState::complete) { + + _state = state::pitch; + _state_start_time = now; + } + + break; } + case state::pitch: + if ((_sys_id.getFitness() < converged_thr) && ((now - _state_start_time) > 5_s)) { copyGains(1); @@ -371,7 +430,8 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) case state::pitch_pause: if ((now - _state_start_time) > 2_s) { - _state = state::yaw; + _state = state::yaw_amp_detection; + _amplitude_detection_state = amplitudeDetectionState::init; _state_start_time = now; _sys_id.reset(sys_id_init); _input_scale = 1.f / _param_fw_yr_p.get(); @@ -379,19 +439,33 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) // first step needs to be shorter to keep the drone centered _steps_counter = 5; _max_steps = 10; - - // reset yaw signal filter states _signal_filter.reset(0.f); } break; - case state::yaw: - if (!(_param_fw_at_axes.get() & Axes::yaw)) { - // Should not tune this axis, skip - _state = state::yaw_pause; + case state::yaw_amp_detection: { + if (!(_param_fw_at_axes.get() & Axes::yaw)) { + // Should not tune this axis, skip + _state = state::yaw_pause; + break; + } + + const float abs_yaw_rate = fabsf(_angular_velocity(2)); + const float target = 0.75f * math::radians(_param_fw_y_rmax.get()); + + updateAmplitudeDetectionState(now, abs_yaw_rate, target); + + if (_amplitude_detection_state == amplitudeDetectionState::complete) { + + _state = state::yaw; + _state_start_time = now; + } + + break; } + case state::yaw: if ((_sys_id.getFitness() < converged_thr) && ((now - _state_start_time) > 5_s)) { copyGains(2); @@ -474,22 +548,55 @@ void FwAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) orb_advert_t mavlink_log_pub = nullptr; mavlink_log_info(&mavlink_log_pub, "Autotune returned to idle"); _state = state::idle; - _param_fw_at_start.set(false); - _param_fw_at_start.commit(); + _vehicle_cmd_start_autotune = false; } break; } // In case of convergence timeout - // the identification sequence is aborted immediately + // the identification sequence is aborted and the FSM moves on to the next axis if (_state != state::wait_for_disarm && _state != state::idle && _state != state::fail && _state != state::complete) { - if (now - _state_start_time > 20_s - || (_param_fw_at_man_aux.get() && !_aux_switch_en) - || _start_flight_mode != _nav_state) { - orb_advert_t mavlink_log_pub = nullptr; + + const bool timeout = (now - _state_start_time) > 30_s; + const bool mode_changed = (_start_flight_mode != _nav_state); + const bool aux_switched_off = (_param_fw_at_man_aux.get() && !_aux_switch_en); + + orb_advert_t mavlink_log_pub = nullptr; + + if (mode_changed || aux_switched_off) { + // Abort mavlink_log_critical(&mavlink_log_pub, "Autotune aborted before finishing"); _state = state::fail; + _start_flight_mode = _nav_state; + _state_start_time = now; + + } else if (timeout) { + // Skip to next axis + mavlink_log_critical(&mavlink_log_pub, "Autotune axis timeout, skipping to next axis"); + + switch (_state) { + case state::roll_amp_detection: + case state::roll: + _state = state::roll_pause; // proceed to pitch + break; + + case state::pitch_amp_detection: + case state::pitch: + _state = state::pitch_pause; // proceed to yaw + break; + + case state::yaw_amp_detection: + case state::yaw: + _state = state::yaw_pause; // proceed to verification + break; + + default: + _state = state::fail; // safety fallback + break; + } + + _start_flight_mode = _nav_state; _state_start_time = now; } } @@ -618,10 +725,94 @@ void FwAutotuneAttitudeControl::saveGainsToParams() } } -const Vector3f FwAutotuneAttitudeControl::getIdentificationSignal() +void FwAutotuneAttitudeControl::updateAmplitudeDetectionState(const hrt_abstime now, + const float rate, const float target_rate) { + const hrt_abstime time_since_last_amplitude_increase = now - _time_last_amplitude_increase; + switch (_amplitude_detection_state) { + case amplitudeDetectionState::init: + _signal_amp = 0.1f; // start with an initial amplitude of 0.1 rad/s + _rate_reached = false; + _time_last_amplitude_increase = _state_start_time; + _amplitude_detection_state = amplitudeDetectionState::first_period; + + break; + + + case amplitudeDetectionState::first_period: + + if (!_rate_reached && rate >= target_rate) { + _rate_reached = true; + } + + if (time_since_last_amplitude_increase >= 1_s) { + _amplitude_detection_state = _rate_reached ? + amplitudeDetectionState::second_period : + amplitudeDetectionState::increase_amplitude; + + // reset flag + _rate_reached = false; + } + + break; + + case amplitudeDetectionState::second_period: + if (!_rate_reached && rate >= target_rate) { + _rate_reached = true; + } + + if (time_since_last_amplitude_increase >= 2_s) { + _amplitude_detection_state = _rate_reached ? + amplitudeDetectionState::set_amplitude : + amplitudeDetectionState::increase_amplitude; + // reset flag + _rate_reached = false; + } + + break; + + + case amplitudeDetectionState::increase_amplitude: + + _signal_amp += kSignalAmpStep; + _time_last_amplitude_increase = now; + + _amplitude_detection_state = (_signal_amp > kSignalAmpMax) ? + amplitudeDetectionState::set_amplitude : + amplitudeDetectionState::first_period; + + + break; + + case amplitudeDetectionState::set_amplitude: + + _signal_amp = math::constrain(_signal_amp - kSignalAmpStep, 0.1f, kSignalAmpMax); + _amplitude_detection_state = amplitudeDetectionState::complete; + + break; + + case amplitudeDetectionState::complete: + break; + } +} + +const Vector3f FwAutotuneAttitudeControl::getAmplitudeDetectionSignal() +{ + const hrt_abstime now = hrt_absolute_time(); + const float t = static_cast(now - _state_start_time) * 1e-6f; + + float signal = sinf(2.0f * M_PI_F * t); + + signal *= _signal_amp; + Vector3f rate_sp = scaleInputSignal(signal); + + return rate_sp; +} + +const Vector3f FwAutotuneAttitudeControl::getIdentificationSignal() +{ const hrt_abstime now = hrt_absolute_time(); const float t = static_cast(now - _state_start_time) * 1e-6f; float signal = 0.0f; @@ -665,26 +856,32 @@ const Vector3f FwAutotuneAttitudeControl::getIdentificationSignal() } - signal *= _param_fw_at_sysid_amp.get(); + signal *= _signal_amp; + Vector3f rate_sp = scaleInputSignal(signal); + + return rate_sp; +} + +const Vector3f FwAutotuneAttitudeControl::scaleInputSignal(const float signal) +{ + float signal_scaled = 0.f; Vector3f rate_sp{}; - float signal_scaled = 0.f; - - if (_state == state::roll || _state == state::test) { + if (_state == state::roll_amp_detection || _state == state::roll || _state == state::test) { // Scale the signal such that the attitude controller is // able to cancel it completely at an attitude error of pi/8 signal_scaled = math::min(signal * M_PI_F / (8.f * _param_fw_r_tc.get()), math::radians(_param_fw_r_rmax.get())); rate_sp(0) = signal_scaled - _signal_filter.getState(); } - if (_state == state::pitch || _state == state::test) { + if (_state == state::pitch_amp_detection || _state == state::pitch || _state == state::test) { const float pitch_rate_max_deg = math::min(_param_fw_p_rmax_pos.get(), _param_fw_p_rmax_neg.get()); signal_scaled = math::min(signal * M_PI_F / (8.f * _param_fw_p_tc.get()), math::radians(pitch_rate_max_deg)); rate_sp(1) = signal_scaled - _signal_filter.getState(); } - if (_state == state::yaw) { + if (_state == state::yaw_amp_detection || _state == state::yaw) { // Do not send a signal that produces more than a full deflection of the rudder signal_scaled = math::min(signal, 1.f / (_param_fw_yr_ff.get() + _param_fw_yr_p.get()), math::radians(_param_fw_y_rmax.get())); diff --git a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.hpp b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.hpp index 4350724eed..5a8a780c90 100644 --- a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.hpp +++ b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control.hpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -101,11 +102,10 @@ private: void Run() override; - void reset(); - void checkFilters(); void updateStateMachine(hrt_abstime now); + void updateAmplitudeDetectionState(hrt_abstime now, float rate, float target_rate); void copyGains(int index); bool areGainsGood() const; void saveGainsToParams(); @@ -114,6 +114,9 @@ private: bool isAuxEnableSwitchEnabled(); const matrix::Vector3f getIdentificationSignal(); + const matrix::Vector3f getAmplitudeDetectionSignal(); + const matrix::Vector3f scaleInputSignal(const float signal); + uORB::SubscriptionCallbackWorkItem _vehicle_torque_setpoint_sub; uORB::SubscriptionCallbackWorkItem _parameter_update_sub{this, ORB_ID(parameter_update)}; @@ -122,6 +125,7 @@ private: uORB::Subscription _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)}; uORB::Subscription _vehicle_angular_velocity_sub{ORB_ID(vehicle_angular_velocity)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; + uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; uORB::PublicationData _autotune_attitude_control_status_pub{ORB_ID(autotune_attitude_control_status)}; @@ -130,10 +134,13 @@ private: enum class state { idle = autotune_attitude_control_status_s::STATE_IDLE, init = autotune_attitude_control_status_s::STATE_INIT, + roll_amp_detection = autotune_attitude_control_status_s::STATE_ROLL_AMPLITUDE_DETECTION, roll = autotune_attitude_control_status_s::STATE_ROLL, roll_pause = autotune_attitude_control_status_s::STATE_ROLL_PAUSE, + pitch_amp_detection = autotune_attitude_control_status_s::STATE_PITCH_AMPLITUDE_DETECTION, pitch = autotune_attitude_control_status_s::STATE_PITCH, pitch_pause = autotune_attitude_control_status_s::STATE_PITCH_PAUSE, + yaw_amp_detection = autotune_attitude_control_status_s::STATE_YAW_AMPLITUDE_DETECTION, yaw = autotune_attitude_control_status_s::STATE_YAW, yaw_pause = autotune_attitude_control_status_s::STATE_YAW_PAUSE, apply = autotune_attitude_control_status_s::STATE_APPLY, @@ -144,15 +151,35 @@ private: wait_for_disarm = autotune_attitude_control_status_s::STATE_WAIT_FOR_DISARM } _state{state::idle}; + enum class amplitudeDetectionState { + init, + first_period, + second_period, + increase_amplitude, + set_amplitude, + complete + } _amplitude_detection_state{amplitudeDetectionState::init}; + hrt_abstime _state_start_time{0}; uint8_t _steps_counter{0}; uint8_t _max_steps{5}; int8_t _signal_sign{0}; + // Amplitude detection variables + float _signal_amp{0.1f}; + bool _rate_reached{false}; + hrt_abstime _time_last_amplitude_increase{0}; + static constexpr float kSignalAmpMax{5.0f}; + static constexpr float kSignalAmpStep{0.1f}; + + matrix::Vector3f _angular_velocity{}; + bool _armed{false}; uint8_t _nav_state{0}; uint8_t _start_flight_mode{0}; bool _aux_switch_en{false}; + bool _vehicle_cmd_start_autotune{false}; + bool _want_start_autotune{false}; orb_advert_t _mavlink_log_pub{nullptr}; @@ -190,9 +217,7 @@ private: DEFINE_PARAMETERS( (ParamInt) _param_fw_at_axes, - (ParamBool) _param_fw_at_start, (ParamInt) _param_fw_at_man_aux, - (ParamFloat) _param_fw_at_sysid_amp, (ParamInt) _param_fw_at_apply, (ParamFloat) _param_imu_gyro_cutoff, @@ -219,6 +244,6 @@ private: (ParamInt) _param_fw_sysid_signal_type ) - static constexpr float _publishing_dt_s = 100e-3f; - static constexpr hrt_abstime _publishing_dt_hrt = 100_ms; + static constexpr float _publishing_dt_s = 20e-3f; + static constexpr hrt_abstime _publishing_dt_hrt = 20_ms; }; diff --git a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control_params.c b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control_params.c index 53c85457dd..4a60977f01 100644 --- a/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control_params.c +++ b/src/modules/fw_autotune_attitude_control/fw_autotune_attitude_control_params.c @@ -39,37 +39,7 @@ * @author Mathieu Bresciani */ -/** - * Start the autotuning sequence - * - * WARNING: this will inject steps to the rate controller - * and can be dangerous. Only activate if you know what you - * are doing, and in a safe environment. - * - * Any motion of the remote stick will abort the signal - * injection and reset this parameter - * Best is to perform the identification in position or - * hold mode. - * Increase the amplitude of the injected signal using - * FW_AT_SYSID_AMP for more signal/noise ratio - * - * @boolean - * @group Autotune - */ -PARAM_DEFINE_INT32(FW_AT_START, 0); -/** - * Amplitude of the injected signal - * - * This parameter scales the signal sent to the - * rate controller during system identification. - * - * @min 0.1 - * @max 6.0 - * @decimal 1 - * @group Autotune - */ -PARAM_DEFINE_FLOAT(FW_AT_SYSID_AMP, 1.0); /** * Controls when to apply the new gains @@ -146,7 +116,7 @@ PARAM_DEFINE_FLOAT(FW_AT_SYSID_F0, 1.f); * @unit Hz * @group Autotune */ -PARAM_DEFINE_FLOAT(FW_AT_SYSID_F1, 20.f); +PARAM_DEFINE_FLOAT(FW_AT_SYSID_F1, 10.f); /** * Maneuver time for each axis @@ -171,4 +141,4 @@ PARAM_DEFINE_FLOAT(FW_AT_SYSID_TIME, 10.f); * @value 2 Logarithmic sine sweep * @group Autotune */ -PARAM_DEFINE_INT32(FW_AT_SYSID_TYPE, 0); +PARAM_DEFINE_INT32(FW_AT_SYSID_TYPE, 1); diff --git a/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.cpp b/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.cpp index 1c42f5838c..00283b9848 100644 --- a/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.cpp +++ b/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.cpp @@ -70,6 +70,7 @@ FwLateralLongitudinalControl::FwLateralLongitudinalControl(bool is_vtol) : _attitude_sp_pub(is_vtol ? ORB_ID(fw_virtual_attitude_setpoint) : ORB_ID(vehicle_attitude_setpoint)), _loop_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")) { + _attitude_sp_pub.advertise(); _tecs_status_pub.advertise(); _flight_phase_estimation_pub.advertise(); _fixed_wing_lateral_status_pub.advertise(); @@ -140,11 +141,12 @@ void FwLateralLongitudinalControl::Run() if (_local_pos_sub.update(&_local_pos)) { - const float control_interval = math::constrain((_local_pos.timestamp - _last_time_loop_ran) * 1e-6f, - 0.001f, 0.1f); - _last_time_loop_ran = _local_pos.timestamp; + const hrt_abstime now = _local_pos.timestamp_sample; - updateControllerConfiguration(); + const float control_interval = math::constrain((now - _last_time_loop_ran) * 1e-6f, 0.001f, 0.1f); + _last_time_loop_ran = now; + + updateControllerConfiguration(now); _tecs.set_speed_weight(_long_configuration.speed_weight); updateTECSAltitudeTimeConstant(checkLowHeightConditions() @@ -164,7 +166,7 @@ void FwLateralLongitudinalControl::Run() _landed = landed.landed; } - _flight_phase_estimation_pub.get().flight_phase = flight_phase_estimation_s::FLIGHT_PHASE_UNKNOWN; + uint8_t current_flight_phase = flight_phase_estimation_s::FLIGHT_PHASE_UNKNOWN; _vehicle_status_sub.update(); _control_mode_sub.update(); @@ -175,7 +177,7 @@ void FwLateralLongitudinalControl::Run() _flaps_setpoint = flaps_setpoint.normalized_setpoint; } - update_control_state(); + update_control_state(now); if (_control_mode_sub.get().flag_control_manual_enabled && _control_mode_sub.get().flag_control_altitude_enabled && _local_pos.z_reset_counter != _z_reset_counter) { @@ -209,17 +211,18 @@ void FwLateralLongitudinalControl::Run() // If the both altitude and height rate are set, set altitude setpoint to NAN const float altitude_sp = PX4_ISFINITE(_long_control_sp.height_rate) ? NAN : _long_control_sp.altitude; - tecs_update_pitch_throttle(control_interval, altitude_sp, - airspeed_sp_eas, - _long_configuration.pitch_min, - _long_configuration.pitch_max, - _long_configuration.throttle_min, - _long_configuration.throttle_max, - _long_configuration.sink_rate_target, - _long_configuration.climb_rate_target, - _long_configuration.disable_underspeed_protection, - _long_control_sp.height_rate - ); + current_flight_phase = tecs_update_pitch_throttle(control_interval, altitude_sp, + airspeed_sp_eas, + _long_configuration.pitch_min, + _long_configuration.pitch_max, + _long_configuration.throttle_min, + _long_configuration.throttle_max, + _long_configuration.sink_rate_target, + _long_configuration.climb_rate_target, + _long_configuration.disable_underspeed_protection, + _long_control_sp.height_rate, + now + ); pitch_sp = PX4_ISFINITE(_long_control_sp.pitch_direct) ? _long_control_sp.pitch_direct : _tecs.get_pitch_setpoint(); throttle_sp = PX4_ISFINITE(_long_control_sp.throttle_direct) ? _long_control_sp.throttle_direct : @@ -278,13 +281,13 @@ void FwLateralLongitudinalControl::Run() lateral_accel_sp = 0.f; // mitigation if no valid setpoint is received: 0 lateral acceleration } - lateral_accel_sp = getCorrectedLateralAccelSetpoint(lateral_accel_sp); + lateral_accel_sp = getCorrectedLateralAccelSetpoint(lateral_accel_sp, now); lateral_accel_sp = math::constrain(lateral_accel_sp, -_lateral_configuration.lateral_accel_max, _lateral_configuration.lateral_accel_max); roll_sp = mapLateralAccelerationToRollAngle(lateral_accel_sp); fixed_wing_lateral_status_s fixed_wing_lateral_status{}; - fixed_wing_lateral_status.timestamp = hrt_absolute_time(); + fixed_wing_lateral_status.timestamp = now; fixed_wing_lateral_status.lateral_acceleration_setpoint = lateral_accel_sp; fixed_wing_lateral_status.can_run_factor = _can_run_factor; @@ -306,7 +309,7 @@ void FwLateralLongitudinalControl::Run() // roll slew rate roll_body = _roll_slew_rate.update(roll_body, control_interval); - _att_sp.timestamp = hrt_absolute_time(); + _att_sp.timestamp = now; const Quatf q(Eulerf(roll_body, pitch_body, yaw_body)); q.copyTo(_att_sp.q_d); @@ -316,22 +319,32 @@ void FwLateralLongitudinalControl::Run() } + // Publish flight phase with low rate, but immediately if updated + const bool flight_phase_updated = current_flight_phase != _flight_phase_estimation_pub.get().flight_phase; + const hrt_abstime time_since_last_flightphase_pub = now - _flight_phase_estimation_pub.get().timestamp; + + if (flight_phase_updated || time_since_last_flightphase_pub >= 1_s) { + _flight_phase_estimation_pub.get().timestamp = now; + _flight_phase_estimation_pub.get().flight_phase = current_flight_phase; + _flight_phase_estimation_pub.update(); + } + _z_reset_counter = _local_pos.z_reset_counter; } perf_end(_loop_perf); } -void FwLateralLongitudinalControl::updateControllerConfiguration() +void FwLateralLongitudinalControl::updateControllerConfiguration(hrt_abstime timestamp) { if (_lateral_configuration.timestamp == 0) { - _lateral_configuration.timestamp = _local_pos.timestamp; + _lateral_configuration.timestamp = timestamp; _lateral_configuration.lateral_accel_max = tanf(radians(_param_fw_r_lim.get())) * CONSTANTS_ONE_G; } if (_long_configuration.timestamp == 0) { - setDefaultLongitudinalControlConfiguration(); + setDefaultLongitudinalControlConfiguration(timestamp); } if (_long_control_configuration_sub.updated() || _parameter_update_sub.updated()) { @@ -355,12 +368,12 @@ void FwLateralLongitudinalControl::updateControllerConfiguration() } } -void +uint8_t FwLateralLongitudinalControl::tecs_update_pitch_throttle(const float control_interval, float alt_sp, float airspeed_sp, float pitch_min_rad, float pitch_max_rad, float throttle_min, float throttle_max, const float desired_max_sinkrate, const float desired_max_climbrate, - bool disable_underspeed_detection, float hgt_rate_sp) + bool disable_underspeed_detection, float hgt_rate_sp, hrt_abstime now) { bool tecs_is_running = true; @@ -369,8 +382,7 @@ FwLateralLongitudinalControl::tecs_update_pitch_throttle(const float control_int && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING || _vehicle_status_sub.get().in_transition_mode)) { tecs_is_running = false; - return; - + return flight_phase_estimation_s::FLIGHT_PHASE_UNKNOWN; } const float throttle_trim_compensated = _performance_model.getTrimThrottle(throttle_min, @@ -399,7 +411,7 @@ FwLateralLongitudinalControl::tecs_update_pitch_throttle(const float control_int _long_control_state.height_rate, hgt_rate_sp); - tecs_status_publish(alt_sp, airspeed_sp, airspeed_rate_estimate, throttle_trim_compensated); + tecs_status_publish(alt_sp, airspeed_sp, airspeed_rate_estimate, throttle_trim_compensated, now); if (tecs_is_running && !_vehicle_status_sub.get().in_transition_mode && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING)) { @@ -408,25 +420,28 @@ FwLateralLongitudinalControl::tecs_update_pitch_throttle(const float control_int // Check level flight: the height rate setpoint is not set or set to 0 and we are close to the target altitude and target altitude is not moving if ((fabsf(tecs_output.height_rate_reference) < MAX_ALT_REF_RATE_FOR_LEVEL_FLIGHT) && fabsf(_long_control_state.altitude_msl - tecs_output.altitude_reference) < _param_nav_fw_alt_rad.get()) { - _flight_phase_estimation_pub.get().flight_phase = flight_phase_estimation_s::FLIGHT_PHASE_LEVEL; + return flight_phase_estimation_s::FLIGHT_PHASE_LEVEL; } else if (((tecs_output.altitude_reference - _long_control_state.altitude_msl) >= _param_nav_fw_alt_rad.get()) || (tecs_output.height_rate_reference >= MAX_ALT_REF_RATE_FOR_LEVEL_FLIGHT)) { - _flight_phase_estimation_pub.get().flight_phase = flight_phase_estimation_s::FLIGHT_PHASE_CLIMB; + return flight_phase_estimation_s::FLIGHT_PHASE_CLIMB; } else if (((_long_control_state.altitude_msl - tecs_output.altitude_reference) >= _param_nav_fw_alt_rad.get()) || (tecs_output.height_rate_reference <= -MAX_ALT_REF_RATE_FOR_LEVEL_FLIGHT)) { - _flight_phase_estimation_pub.get().flight_phase = flight_phase_estimation_s::FLIGHT_PHASE_DESCEND; + return flight_phase_estimation_s::FLIGHT_PHASE_DESCEND; } else { - //We can't infer the flight phase , do nothing, estimation is reset at each step + // We can't infer the flight phase + return flight_phase_estimation_s::FLIGHT_PHASE_UNKNOWN; } } + + return flight_phase_estimation_s::FLIGHT_PHASE_UNKNOWN; } void FwLateralLongitudinalControl::tecs_status_publish(float alt_sp, float equivalent_airspeed_sp, - float true_airspeed_derivative_raw, float throttle_trim) + float true_airspeed_derivative_raw, float throttle_trim, hrt_abstime timestamp) { tecs_status_s tecs_status{}; @@ -457,7 +472,7 @@ FwLateralLongitudinalControl::tecs_status_publish(float alt_sp, float equivalent tecs_status.underspeed_ratio = _tecs.get_underspeed_ratio(); tecs_status.fast_descend_ratio = debug_output.fast_descend; - tecs_status.timestamp = hrt_absolute_time(); + tecs_status.timestamp = timestamp; _tecs_status_pub.publish(tecs_status); } @@ -530,16 +545,16 @@ fw_lat_lon_control computes attitude and throttle setpoints from lateral and lon return 0; } -void FwLateralLongitudinalControl::update_control_state() { +void FwLateralLongitudinalControl::update_control_state(hrt_abstime now) { updateAltitudeAndHeightRate(); updateAirspeed(); updateAttitude(); - updateWind(); + updateWind(now); _lateral_control_state.ground_speed = Vector2f(_local_pos.vx, _local_pos.vy); } -void FwLateralLongitudinalControl::updateWind() { +void FwLateralLongitudinalControl::updateWind(hrt_abstime now) { if (_wind_sub.updated()) { wind_s wind{}; _wind_sub.update(&wind); @@ -548,14 +563,14 @@ void FwLateralLongitudinalControl::updateWind() { _wind_valid = PX4_ISFINITE(wind.windspeed_north) && PX4_ISFINITE(wind.windspeed_east); - _time_wind_last_received = hrt_absolute_time(); + _time_wind_last_received = now; _lateral_control_state.wind_speed(0) = wind.windspeed_north; _lateral_control_state.wind_speed(1) = wind.windspeed_east; } else { // invalidate wind estimate usage (and correspondingly NPFG, if enabled) after subscription timeout - _wind_valid = _wind_valid && (hrt_absolute_time() - _time_wind_last_received) < WIND_EST_TIMEOUT; + _wind_valid = _wind_valid && (now - _time_wind_last_received) < WIND_EST_TIMEOUT; } if (!_wind_valid) { @@ -607,7 +622,7 @@ void FwLateralLongitudinalControl::updateAirspeed() { // do not use synthetic airspeed as this would create a thrust loop if (PX4_ISFINITE(airspeed_validated.calibrated_airspeed_m_s) && PX4_ISFINITE(airspeed_validated.true_airspeed_m_s) - && airspeed_validated.airspeed_source != airspeed_validated_s::SYNTHETIC) { + && airspeed_validated.airspeed_source != airspeed_validated_s::SOURCE_SYNTHETIC) { _time_airspeed_last_valid = airspeed_validated.timestamp; _long_control_state.airspeed_eas = airspeed_validated.calibrated_airspeed_m_s; @@ -734,32 +749,30 @@ float FwLateralLongitudinalControl::getGuidanceQualityFactor(const vehicle_local return flying_forward_factor * low_ground_speed_factor; } -float FwLateralLongitudinalControl::getCorrectedLateralAccelSetpoint(float lateral_accel_sp) +float FwLateralLongitudinalControl::getCorrectedLateralAccelSetpoint(float lateral_accel_sp, hrt_abstime now) { // Scale the npfg output to zero if npfg is not certain for correct output _can_run_factor = math::constrain(getGuidanceQualityFactor(_local_pos, _wind_valid), 0.f, 1.f); - hrt_abstime now{hrt_absolute_time()}; - // Warn the user when the scale is less than 90% for at least 2 seconds (disable in transition) // If the npfg was not running before, reset the user warning variables. - if ((now - _time_since_last_npfg_call) > ROLL_WARNING_TIMEOUT) { + if ((now - _time_of_last_npfg_call) > ROLL_WARNING_TIMEOUT) { _need_report_npfg_uncertain_condition = true; - _time_since_first_reduced_roll = 0U; + _time_of_first_reduced_roll = 0U; } if (_vehicle_status_sub.get().in_transition_mode || _can_run_factor > ROLL_WARNING_CAN_RUN_THRESHOLD || _landed) { // NPFG reports a good condition or we are in transition, reset the user warning variables. _need_report_npfg_uncertain_condition = true; - _time_since_first_reduced_roll = 0U; + _time_of_first_reduced_roll = 0U; } else if (_need_report_npfg_uncertain_condition) { - if (_time_since_first_reduced_roll == 0U) { - _time_since_first_reduced_roll = now; + if (_time_of_first_reduced_roll == 0U) { + _time_of_first_reduced_roll = now; } - if ((now - _time_since_first_reduced_roll) > ROLL_WARNING_TIMEOUT) { + if ((now - _time_of_first_reduced_roll) > ROLL_WARNING_TIMEOUT) { _need_report_npfg_uncertain_condition = false; events::send(events::ID("npfg_roll_command_uncertain"), events::Log::Warning, "Roll command reduced due to uncertain velocity/wind estimates!"); @@ -769,7 +782,7 @@ float FwLateralLongitudinalControl::getCorrectedLateralAccelSetpoint(float later // Nothing to do, already reported. } - _time_since_last_npfg_call = now; + _time_of_last_npfg_call = now; return _can_run_factor * (lateral_accel_sp); } @@ -777,8 +790,8 @@ float FwLateralLongitudinalControl::mapLateralAccelerationToRollAngle(float late return atanf(lateral_acceleration_sp / CONSTANTS_ONE_G); } -void FwLateralLongitudinalControl::setDefaultLongitudinalControlConfiguration() { - _long_configuration.timestamp = hrt_absolute_time(); +void FwLateralLongitudinalControl::setDefaultLongitudinalControlConfiguration(hrt_abstime timestamp) { + _long_configuration.timestamp = timestamp; _long_configuration.pitch_min = radians(_param_fw_p_lim_min.get()); _long_configuration.pitch_max = radians(_param_fw_p_lim_max.get()); _long_configuration.throttle_min = _param_fw_thr_min.get(); @@ -827,6 +840,12 @@ void FwLateralLongitudinalControl::updateLongitudinalControlConfiguration(const } else { _long_configuration.sink_rate_target = _param_sinkrate_target.get(); } + + if (PX4_ISFINITE(configuration_in.speed_weight)) { + _long_configuration.speed_weight = math::constrain(configuration_in.speed_weight, 0.f, 2.f); + } else { + _long_configuration.speed_weight = _param_t_spdweight.get(); + } } float FwLateralLongitudinalControl::getLoadFactor() const diff --git a/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.hpp b/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.hpp index 590054ae89..13b21e4529 100644 --- a/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.hpp +++ b/src/modules/fw_lateral_longitudinal_control/FwLateralLongitudinalControl.hpp @@ -157,6 +157,7 @@ private: (ParamFloat) _param_fw_t_vert_acc, (ParamFloat) _param_ste_rate_time_const, (ParamFloat) _param_seb_rate_ff, + (ParamFloat) _param_t_spdweight, (ParamFloat) _param_speed_standard_dev, (ParamFloat) _param_speed_rate_standard_dev, (ParamFloat) _param_process_noise_standard_dev, @@ -194,8 +195,8 @@ private: matrix::Vector2f wind_speed; } _lateral_control_state{}; bool _need_report_npfg_uncertain_condition{false}; ///< boolean if reporting of uncertain npfg output condition is needed - hrt_abstime _time_since_first_reduced_roll{0U}; ///< absolute time since start when entering reduced roll angle for the first time - hrt_abstime _time_since_last_npfg_call{0U}; ///< absolute time since start when the npfg reduced roll angle calculations was last performed + hrt_abstime _time_of_first_reduced_roll{0U}; ///< absolute time when entering reduced roll angle for the first time + hrt_abstime _time_of_last_npfg_call{0U}; ///< absolute time when the npfg reduced roll angle calculations was last performed vehicle_attitude_setpoint_s _att_sp{}; bool _landed{false}; float _can_run_factor{0.f}; @@ -211,15 +212,16 @@ private: float _min_airspeed_from_guidance{0.f}; // need to store it bc we only update after running longitudinal controller void parameters_update(); - void update_control_state(); - void tecs_update_pitch_throttle(const float control_interval, float alt_sp, float airspeed_sp, - float pitch_min_rad, float pitch_max_rad, float throttle_min, - float throttle_max, const float desired_max_sinkrate, - const float desired_max_climbrate, - bool disable_underspeed_detection, float hgt_rate_sp); + void update_control_state(hrt_abstime now); + + uint8_t tecs_update_pitch_throttle(const float control_interval, float alt_sp, float airspeed_sp, + float pitch_min_rad, float pitch_max_rad, float throttle_min, + float throttle_max, const float desired_max_sinkrate, + const float desired_max_climbrate, + bool disable_underspeed_detection, float hgt_rate_sp, hrt_abstime now); void tecs_status_publish(float alt_sp, float equivalent_airspeed_sp, float true_airspeed_derivative_raw, - float throttle_trim); + float throttle_trim, hrt_abstime now); void updateAirspeed(); @@ -229,7 +231,7 @@ private: float mapLateralAccelerationToRollAngle(float lateral_acceleration_sp) const; - void updateWind(); + void updateWind(hrt_abstime now); void updateTECSAltitudeTimeConstant(const bool is_low_height, const float dt); @@ -237,13 +239,13 @@ private: float getGuidanceQualityFactor(const vehicle_local_position_s &local_pos, const bool is_wind_valid) const; - float getCorrectedLateralAccelSetpoint(float lateral_accel_sp); + float getCorrectedLateralAccelSetpoint(float lateral_accel_sp, hrt_abstime now); - void setDefaultLongitudinalControlConfiguration(); + void setDefaultLongitudinalControlConfiguration(hrt_abstime now); void updateLongitudinalControlConfiguration(const longitudinal_control_configuration_s &configuration_in); - void updateControllerConfiguration(); + void updateControllerConfiguration(hrt_abstime now); float getLoadFactor() const; diff --git a/src/modules/fw_mode_manager/CMakeLists.txt b/src/modules/fw_mode_manager/CMakeLists.txt index 3e21a51ee1..dc32389580 100644 --- a/src/modules/fw_mode_manager/CMakeLists.txt +++ b/src/modules/fw_mode_manager/CMakeLists.txt @@ -41,7 +41,8 @@ set(POSCONTROL_DEPENDENCIES SlewRate tecs motion_planning - performance_model + performance_model + Sticks ) if(CONFIG_FIGURE_OF_EIGHT) diff --git a/src/modules/fw_mode_manager/FixedWingModeManager.cpp b/src/modules/fw_mode_manager/FixedWingModeManager.cpp index 84767f0368..710fffb4f8 100644 --- a/src/modules/fw_mode_manager/FixedWingModeManager.cpp +++ b/src/modules/fw_mode_manager/FixedWingModeManager.cpp @@ -36,9 +36,6 @@ #include #include -using math::constrain; -using math::max; -using math::min; using math::radians; using matrix::Dcmf; @@ -166,10 +163,12 @@ FixedWingModeManager::airspeed_poll() // do not use synthetic airspeed as it's for the use here not reliable enough if (PX4_ISFINITE(airspeed_validated.calibrated_airspeed_m_s) - && airspeed_validated.airspeed_source != airspeed_validated_s::SYNTHETIC) { + && airspeed_validated.airspeed_source != airspeed_validated_s::SOURCE_SYNTHETIC) { _airspeed_eas = airspeed_validated.calibrated_airspeed_m_s; } + + _time_airspeed_last_valid = airspeed_validated.timestamp; } // no airspeed updates for one second --> declare invalid @@ -207,23 +206,18 @@ FixedWingModeManager::wind_poll(const hrt_abstime now) void FixedWingModeManager::manual_control_setpoint_poll() { - _manual_control_setpoint_sub.update(&_manual_control_setpoint); + _sticks.checkAndUpdateStickInputs(); - _manual_control_setpoint_for_height_rate = _manual_control_setpoint.pitch; - _manual_control_setpoint_for_airspeed = _manual_control_setpoint.throttle; + _manual_control_setpoint_for_height_rate = _sticks.getPitch(); + _manual_control_setpoint_for_airspeed = _sticks.getThrottleZeroCentered(); if (_param_fw_pos_stk_conf.get() & STICK_CONFIG_SWAP_STICKS_BIT) { /* Alternate stick allocation (similar concept as for multirotor systems: * demanding up/down with the throttle stick, and move faster/break with the pitch one. */ - _manual_control_setpoint_for_height_rate = -_manual_control_setpoint.throttle; - _manual_control_setpoint_for_airspeed = _manual_control_setpoint.pitch; - } - // send neutral setpoints if no update for 1 s - if (hrt_elapsed_time(&_manual_control_setpoint.timestamp) > 1_s) { - _manual_control_setpoint_for_height_rate = 0.f; - _manual_control_setpoint_for_airspeed = 0.f; + _manual_control_setpoint_for_height_rate = -_sticks.getThrottleZeroCentered(); + _manual_control_setpoint_for_airspeed = _sticks.getPitch(); } } @@ -253,6 +247,7 @@ FixedWingModeManager::vehicle_attitude_poll() const Eulerf euler_angles(R); _yaw = euler_angles(2); + _pitch = euler_angles(1); const Vector3f body_acceleration = R.transpose() * Vector3f{_local_pos.ax, _local_pos.ay, _local_pos.az}; _body_acceleration_x = body_acceleration(0); @@ -262,6 +257,15 @@ FixedWingModeManager::vehicle_attitude_poll() } } +void FixedWingModeManager::vehicle_attitude_setpoint_poll() +{ + vehicle_attitude_setpoint_s vehicle_attitude_setpoint; + + if (_vehicle_attitude_setpoint_sub.update(&vehicle_attitude_setpoint)) { + _throttle = vehicle_attitude_setpoint.thrust_body[0]; + } +} + float FixedWingModeManager::get_manual_airspeed_setpoint() { @@ -393,11 +397,9 @@ FixedWingModeManager::set_control_mode_current(const hrt_abstime &now) } } else if ((_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled) - && (_position_setpoint_current_valid - || _pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_IDLE)) { + && _position_setpoint_current_valid) { - // Enter this mode only if the current waypoint has valid 3D position setpoints or is of type IDLE. - // A setpoint of type IDLE can be published by Navigator without a valid position, and is handled here in FW_POSCTRL_MODE_AUTO. + // Enter this mode only if the current waypoint has valid 3D position setpoints. if (doing_backtransition) { _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_LINE_FOLLOW; @@ -438,6 +440,28 @@ FixedWingModeManager::set_control_mode_current(const hrt_abstime &now) _control_mode_current = FW_POSCTRL_MODE_AUTO; } + } else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled + && (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_IDLE)) { + + // A setpoint of type IDLE can be published by Navigator without a valid position, and is handled here in FW_POSCTRL_MODE_AUTO. + if (doing_backtransition) { + _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_HEADING_HOLD; + + } else { + _control_mode_current = FW_POSCTRL_MODE_AUTO; + } + + } else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled + && (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_LAND)) { + + if (doing_backtransition) { + _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_HEADING_HOLD; + + } else { + // Only circular landing are supported when LAND is sent without valid position + _control_mode_current = FW_POSCTRL_MODE_AUTO_LANDING_CIRCULAR; + } + } else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_climb_rate_enabled && _control_mode.flag_armed // only enter this modes if armed, as pure failsafe modes @@ -1155,8 +1179,9 @@ FixedWingModeManager::control_auto_takeoff(const hrt_abstime &now, const float c fixed_wing_runway_control_s fw_runway_control{}; fw_runway_control.timestamp = now; + fw_runway_control.runway_takeoff_state = _runway_takeoff.getState(); fw_runway_control.wheel_steering_enabled = true; - fw_runway_control.wheel_steering_nudging_rate = _param_rwto_nudge.get() ? _manual_control_setpoint.yaw : 0.f; + fw_runway_control.wheel_steering_nudging_rate = _param_rwto_nudge.get() ? _sticks.getYaw() : 0.f; _fixed_wing_runway_control_pub.publish(fw_runway_control); @@ -1182,6 +1207,7 @@ FixedWingModeManager::control_auto_takeoff(const hrt_abstime &now, const float c _takeoff_init_position = global_position; _takeoff_ground_alt = _current_altitude; _launch_current_yaw = _yaw; + _time_launch_detected = now; } const Vector2f launch_local_position = _global_local_proj_ref.project(_takeoff_init_position(0), @@ -1257,6 +1283,9 @@ FixedWingModeManager::control_auto_takeoff(const hrt_abstime &now, const float c launch_detection_status_s launch_detection_status; launch_detection_status.timestamp = now; launch_detection_status.launch_detection_state = _launchDetector.getLaunchDetected(); + launch_detection_status.selected_control_surface_disarmed = + hrt_elapsed_time(&_time_launch_detected) < _param_fw_laun_cs_lk_dy.get() * 1_s + || _time_launch_detected == 0; _launch_detection_status_pub.publish(launch_detection_status); } @@ -1328,8 +1357,9 @@ FixedWingModeManager::control_auto_takeoff_no_nav(const hrt_abstime &now, const fixed_wing_runway_control_s fw_runway_control{}; fw_runway_control.timestamp = now; + fw_runway_control.runway_takeoff_state = _runway_takeoff.getState(); fw_runway_control.wheel_steering_enabled = true; - fw_runway_control.wheel_steering_nudging_rate = _param_rwto_nudge.get() ? _manual_control_setpoint.yaw : 0.f; + fw_runway_control.wheel_steering_nudging_rate = _param_rwto_nudge.get() ? _sticks.getYaw() : 0.f; _fixed_wing_runway_control_pub.publish(fw_runway_control); @@ -1351,6 +1381,7 @@ FixedWingModeManager::control_auto_takeoff_no_nav(const hrt_abstime &now, const if (!_launch_detected && _launchDetector.getLaunchDetected() > launch_detection_status_s::STATE_WAITING_FOR_LAUNCH) { _launch_detected = true; _takeoff_ground_alt = _current_altitude; + _time_launch_detected = now; } /* Launch has been detected, hence we have to control the plane. */ @@ -1382,6 +1413,9 @@ FixedWingModeManager::control_auto_takeoff_no_nav(const hrt_abstime &now, const launch_detection_status_s launch_detection_status; launch_detection_status.timestamp = now; launch_detection_status.launch_detection_state = _launchDetector.getLaunchDetected(); + launch_detection_status.selected_control_surface_disarmed = + hrt_elapsed_time(&_time_launch_detected) < _param_fw_laun_cs_lk_dy.get() * 1_s + || _time_launch_detected == 0; _launch_detection_status_pub.publish(launch_detection_status); } @@ -1453,6 +1487,8 @@ FixedWingModeManager::control_auto_landing_straight(const hrt_abstime &now, cons _flare_states.flaring = true; _flare_states.start_time = now; _flare_states.initial_height_rate_setpoint = -_local_pos.vz; + _flare_states.initial_pitch = _pitch; + _flare_states.initial_throttle = math::min(_throttle, _param_fw_thr_max.get()); events::send(events::ID("fixedwing_position_control_landing_flaring"), events::Log::Info, "Landing, flaring"); } @@ -1481,19 +1517,13 @@ FixedWingModeManager::control_auto_landing_straight(const hrt_abstime &now, cons const float flare_ramp_interpolator_sqrt = sqrtf(flare_ramp_interpolator); - // Use separate ramp for the altitude setpoint that's starting only when the other is finished - // to allow motor to be ramped down before height rate setpoint is adapted for flaring. - const float flare_hieght_rate_interpolator = math::constrain((seconds_since_flare_start - - _param_fw_lnd_fl_time.get()) / (_param_fw_lnd_fl_time.get()), 0.f, 1.f); - const float flare_hieght_rate_interpolator_sqrt = sqrt(flare_hieght_rate_interpolator); - - const float height_rate_setpoint = flare_hieght_rate_interpolator_sqrt * (-_param_fw_lnd_fl_sink.get()) + - (1.0f - flare_hieght_rate_interpolator_sqrt) * _flare_states.initial_height_rate_setpoint; + const float height_rate_setpoint = flare_ramp_interpolator_sqrt * (-_param_fw_lnd_fl_sink.get()) + + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_height_rate_setpoint; float pitch_min_rad = flare_ramp_interpolator_sqrt * radians(_param_fw_lnd_fl_pmin.get()) + - (1.0f - flare_ramp_interpolator_sqrt) * radians(_param_fw_p_lim_min.get()); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_pitch; float pitch_max_rad = flare_ramp_interpolator_sqrt * radians(_param_fw_lnd_fl_pmax.get()) + - (1.0f - flare_ramp_interpolator_sqrt) * radians(_param_fw_p_lim_max.get()); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_pitch; if (_param_fw_lnd_td_time.get() > FLT_EPSILON) { const float touchdown_time = math::max(_param_fw_lnd_td_time.get(), _param_fw_lnd_fl_time.get()); @@ -1510,9 +1540,9 @@ FixedWingModeManager::control_auto_landing_straight(const hrt_abstime &now, cons // idle throttle may be >0 for internal combustion engines // normally set to zero for electric motors + // Ramp throttle from current value to idle over flare duration const float throttle_max = flare_ramp_interpolator_sqrt * _param_fw_thr_idle.get() + - (1.0f - flare_ramp_interpolator_sqrt) * - _param_fw_thr_max.get(); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_throttle; const fixed_wing_longitudinal_setpoint_s fw_longitudinal_control_sp = { .timestamp = now, @@ -1576,9 +1606,10 @@ FixedWingModeManager::control_auto_landing_straight(const hrt_abstime &now, cons fixed_wing_runway_control_s fw_runway_control{}; fw_runway_control.timestamp = now; + fw_runway_control.runway_takeoff_state = fixed_wing_runway_control_s::STATE_FLYING; // not in takeoff, use FLYING as default fw_runway_control.wheel_steering_enabled = true; fw_runway_control.wheel_steering_nudging_rate = _param_fw_lnd_nudge.get() > LandingNudgingOption::kNudgingDisabled ? - _manual_control_setpoint.yaw : 0.f; + _sticks.getYaw() : 0.f; _fixed_wing_runway_control_pub.publish(fw_runway_control); @@ -1599,6 +1630,12 @@ void FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, const float control_interval, const Vector2f &ground_speed, const position_setpoint_s &pos_sp_curr) { + if (_time_started_landing == 0) { + // save time at which we started landing and reset landing abort status + reset_landing_state(); + _time_started_landing = now; + } + const float airspeed_land = (_param_fw_lnd_airspd.get() > FLT_EPSILON) ? _param_fw_lnd_airspd.get() : _param_fw_airspd_min.get(); @@ -1606,12 +1643,11 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons const Vector2f local_position{_local_pos.x, _local_pos.y}; - Vector2f local_landing_orbit_center = _global_local_proj_ref.project(pos_sp_curr.lat, pos_sp_curr.lon); - if (_time_started_landing == 0) { - // save time at which we started landing and reset landing abort status - reset_landing_state(); - _time_started_landing = now; + if (!_local_landing_orbit_center.isAllFinite()) { + _local_landing_orbit_center = _position_setpoint_current_valid + ? _global_local_proj_ref.project(pos_sp_curr.lat, pos_sp_curr.lon) + : local_position; } const bool abort_on_terrain_timeout = checkLandingAbortBitMask(_param_fw_lnd_abort.get(), @@ -1637,6 +1673,8 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons _flare_states.flaring = true; _flare_states.start_time = now; _flare_states.initial_height_rate_setpoint = -_local_pos.vz; + _flare_states.initial_pitch = _pitch; + _flare_states.initial_throttle = math::min(_throttle, _param_fw_thr_max.get()); events::send(events::ID("fixedwing_position_control_landing_circle_flaring"), events::Log::Info, "Landing, flaring"); } @@ -1647,7 +1685,7 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons 1.0f); /* lateral guidance first, because npfg will adjust the airspeed setpoint if necessary */ - const DirectionalGuidanceOutput sp = navigateLoiter(local_landing_orbit_center, local_position, loiter_radius, + const DirectionalGuidanceOutput sp = navigateLoiter(_local_landing_orbit_center, local_position, loiter_radius, loiter_direction_ccw, ground_speed, _wind_vel); fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint}; @@ -1664,9 +1702,9 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_height_rate_setpoint; float pitch_min_rad = flare_ramp_interpolator_sqrt * radians(_param_fw_lnd_fl_pmin.get()) + - (1.0f - flare_ramp_interpolator_sqrt) * radians(_param_fw_p_lim_min.get()); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_pitch; float pitch_max_rad = flare_ramp_interpolator_sqrt * radians(_param_fw_lnd_fl_pmax.get()) + - (1.0f - flare_ramp_interpolator_sqrt) * radians(_param_fw_p_lim_max.get()); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_pitch; if (_param_fw_lnd_td_time.get() > FLT_EPSILON) { const float touchdown_time = math::max(_param_fw_lnd_td_time.get(), _param_fw_lnd_fl_time.get()); @@ -1682,9 +1720,9 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons // idle throttle may be >0 for internal combustion engines // normally set to zero for electric motors + // Ramp throttle from current value to idle over flare duration const float throttle_max = flare_ramp_interpolator_sqrt * _param_fw_thr_idle.get() + - (1.0f - flare_ramp_interpolator_sqrt) * - _param_fw_thr_max.get(); + (1.0f - flare_ramp_interpolator_sqrt) * _flare_states.initial_throttle; const fixed_wing_longitudinal_setpoint_s fw_longitudinal_control_sp = { .timestamp = now, .altitude = NAN, @@ -1705,7 +1743,7 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons } else { // follow the glide slope - const DirectionalGuidanceOutput sp = navigateLoiter(local_landing_orbit_center, local_position, loiter_radius, + const DirectionalGuidanceOutput sp = navigateLoiter(_local_landing_orbit_center, local_position, loiter_radius, loiter_direction_ccw, ground_speed, _wind_vel); fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint}; @@ -1741,9 +1779,10 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons fixed_wing_runway_control_s fw_runway_control{}; fw_runway_control.timestamp = now; + fw_runway_control.runway_takeoff_state = fixed_wing_runway_control_s::STATE_FLYING; // not in takeoff, use FLYING as default fw_runway_control.wheel_steering_enabled = true; fw_runway_control.wheel_steering_nudging_rate = _param_fw_lnd_nudge.get() > LandingNudgingOption::kNudgingDisabled ? - _manual_control_setpoint.yaw : 0.f; + _sticks.getYaw() : 0.f; _fixed_wing_runway_control_pub.publish(fw_runway_control); @@ -1795,7 +1834,7 @@ FixedWingModeManager::control_manual_altitude(const float control_interval, cons _ctrl_configuration_handler.setPitchMin(min_pitch); _ctrl_configuration_handler.setThrottleMax(throttle_max); - const float roll_body = _manual_control_setpoint.roll * radians(_param_fw_r_lim.get()); + const float roll_body = _sticks.getRoll() * radians(_param_fw_r_lim.get()); const DirectionalGuidanceOutput sp = {.course_setpoint = NAN, .lateral_acceleration_feedforward = rollAngleToLateralAccel(roll_body)}; fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint}; fw_lateral_ctrl_sp.timestamp = hrt_absolute_time(); @@ -1831,8 +1870,8 @@ FixedWingModeManager::control_manual_position(const hrt_abstime now, const float /* heading control */ // TODO: either make it course hold (easier) or a real heading hold (minus all the complexity here) - if (fabsf(_manual_control_setpoint.roll) < HDG_HOLD_MAN_INPUT_THRESH && - fabsf(_manual_control_setpoint.yaw) < HDG_HOLD_MAN_INPUT_THRESH) { + if (fabsf(_sticks.getRoll()) < HDG_HOLD_MAN_INPUT_THRESH && + fabsf(_sticks.getYaw()) < HDG_HOLD_MAN_INPUT_THRESH) { /* heading / roll is zero, lock onto current heading */ if (fabsf(_yawrate) < HDG_HOLD_YAWRATE_THRESH && !_yaw_lock_engaged) { @@ -1891,13 +1930,13 @@ FixedWingModeManager::control_manual_position(const hrt_abstime now, const float _ctrl_configuration_handler.setPitchMin(min_pitch); _ctrl_configuration_handler.setThrottleMax(throttle_max); - if (!_yaw_lock_engaged || fabsf(_manual_control_setpoint.roll) >= HDG_HOLD_MAN_INPUT_THRESH || - fabsf(_manual_control_setpoint.yaw) >= HDG_HOLD_MAN_INPUT_THRESH) { + if (!_yaw_lock_engaged || fabsf(_sticks.getRoll()) >= HDG_HOLD_MAN_INPUT_THRESH || + fabsf(_sticks.getYaw()) >= HDG_HOLD_MAN_INPUT_THRESH) { _hdg_hold_enabled = false; _yaw_lock_engaged = false; - const float roll_body = _manual_control_setpoint.roll * radians(_param_fw_r_lim.get()); + const float roll_body = _sticks.getRoll() * radians(_param_fw_r_lim.get()); fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint}; fw_lateral_ctrl_sp.timestamp = hrt_absolute_time(); fw_lateral_ctrl_sp.lateral_acceleration = rollAngleToLateralAccel(roll_body); @@ -1958,17 +1997,12 @@ FixedWingModeManager::Run() perf_begin(_loop_perf); - if (_vehicle_status_sub.updated()) { - - if (_vehicle_status_sub.update(&_vehicle_status)) { - _nav_state = _vehicle_status.nav_state; - } - } + _vehicle_status_sub.update(&_vehicle_status); /* only run controller if position changed and we are not running an external mode*/ - const bool is_external_nav_state = (_nav_state >= vehicle_status_s::NAVIGATION_STATE_EXTERNAL1) - && (_nav_state <= vehicle_status_s::NAVIGATION_STATE_EXTERNAL8); + const bool is_external_nav_state = (_vehicle_status.nav_state >= vehicle_status_s::NAVIGATION_STATE_EXTERNAL1) + && (_vehicle_status.nav_state <= vehicle_status_s::NAVIGATION_STATE_EXTERNAL8); if (is_external_nav_state) { // this will cause the configuration handler to publish immediately the next time an internal flight @@ -2116,6 +2150,7 @@ FixedWingModeManager::Run() airspeed_poll(); manual_control_setpoint_poll(); vehicle_attitude_poll(); + vehicle_attitude_setpoint_poll(); vehicle_command_poll(); vehicle_control_mode_poll(); wind_poll(now); @@ -2285,6 +2320,8 @@ FixedWingModeManager::reset_takeoff_state() _launch_detected = false; + _time_launch_detected = 0; + _takeoff_ground_alt = _current_altitude; } @@ -2295,6 +2332,7 @@ FixedWingModeManager::reset_landing_state() _flare_states = FlareStates{}; + _local_landing_orbit_center.setNaN(); _lateral_touchdown_position_offset = 0.0f; _last_time_terrain_alt_was_valid = 0; @@ -2309,6 +2347,10 @@ FixedWingModeManager::reset_landing_state() float FixedWingModeManager::getMaxRollAngleNearGround(const float altitude, const float terrain_altitude) const { + if (!PX4_ISFINITE(altitude) || !PX4_ISFINITE(terrain_altitude)) { + return math::radians(_param_fw_r_lim.get()); + } + // we want the wings level when at the wing height above ground const float height_above_ground = math::max(altitude - (terrain_altitude + _param_fw_wing_height.get()), 0.0f); @@ -2385,14 +2427,14 @@ FixedWingModeManager::initializeAutoLanding(const hrt_abstime &now, const positi Vector2f FixedWingModeManager::calculateTouchdownPosition(const float control_interval, const Vector2f &local_land_position) { - if (fabsf(_manual_control_setpoint.yaw) > MANUAL_TOUCHDOWN_NUDGE_INPUT_DEADZONE + if (fabsf(_sticks.getYaw()) > MANUAL_TOUCHDOWN_NUDGE_INPUT_DEADZONE && _param_fw_lnd_nudge.get() > LandingNudgingOption::kNudgingDisabled && !_flare_states.flaring) { // laterally nudge touchdown location with yaw stick // positive is defined in the direction of a right hand turn starting from the approach vector direction const float signed_deadzone_threshold = MANUAL_TOUCHDOWN_NUDGE_INPUT_DEADZONE * math::signNoZero( - _manual_control_setpoint.yaw); - _lateral_touchdown_position_offset += (_manual_control_setpoint.yaw - signed_deadzone_threshold) * + _sticks.getYaw()); + _lateral_touchdown_position_offset += (_sticks.getYaw() - signed_deadzone_threshold) * MAX_TOUCHDOWN_POSITION_NUDGE_RATE * control_interval; _lateral_touchdown_position_offset = math::constrain(_lateral_touchdown_position_offset, -_param_fw_lnd_td_off.get(), _param_fw_lnd_td_off.get()); @@ -2434,7 +2476,7 @@ FixedWingModeManager::getLandingTerrainAltitudeEstimate(const hrt_abstime &now, if (_local_pos.dist_bottom_valid) { - const float terrain_estimate = _local_pos.ref_alt + -_local_pos.z - _local_pos.dist_bottom; + const float terrain_estimate = _reference_altitude + -_local_pos.z - _local_pos.dist_bottom; _last_valid_terrain_alt_estimate = terrain_estimate; _last_time_terrain_alt_was_valid = now; diff --git a/src/modules/fw_mode_manager/FixedWingModeManager.hpp b/src/modules/fw_mode_manager/FixedWingModeManager.hpp index b02e29678c..2a43968ffb 100644 --- a/src/modules/fw_mode_manager/FixedWingModeManager.hpp +++ b/src/modules/fw_mode_manager/FixedWingModeManager.hpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -180,11 +180,11 @@ private: uORB::Subscription _wind_sub{ORB_ID(wind)}; uORB::Subscription _control_mode_sub{ORB_ID(vehicle_control_mode)}; uORB::Subscription _global_pos_sub{ORB_ID(vehicle_global_position)}; - uORB::Subscription _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)}; uORB::Subscription _pos_sp_triplet_sub{ORB_ID(position_setpoint_triplet)}; uORB::Subscription _trajectory_setpoint_sub{ORB_ID(trajectory_setpoint)}; uORB::Subscription _vehicle_angular_velocity_sub{ORB_ID(vehicle_angular_velocity)}; uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; + uORB::Subscription _vehicle_attitude_setpoint_sub{ORB_ID(vehicle_attitude_setpoint)}; uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; @@ -201,7 +201,6 @@ private: uORB::Publication _fixed_wing_lateral_guidance_status_pub{ORB_ID(fixed_wing_lateral_guidance_status)}; uORB::Publication _fixed_wing_runway_control_pub{ORB_ID(fixed_wing_runway_control)}; - manual_control_setpoint_s _manual_control_setpoint{}; position_setpoint_triplet_s _pos_sp_triplet{}; vehicle_control_mode_s _control_mode{}; vehicle_local_position_s _local_pos{}; @@ -243,9 +242,10 @@ private: STICK_CONFIG_ENABLE_AIRSPEED_SP_MANUAL_BIT = (1 << 1) }; - // VEHICLE STATES - uint8_t _nav_state; + Sticks _sticks{this}; + + // VEHICLE STATES double _current_latitude{0}; double _current_longitude{0}; @@ -253,6 +253,8 @@ private: float _yaw{0.0f}; float _yawrate{0.0f}; + float _pitch{0.0f}; // [rad] current pitch angle from attitude + float _throttle{0.0f}; // [0-1] last set throttle float _body_acceleration_x{0.f}; float _body_velocity_x{0.f}; @@ -296,6 +298,9 @@ private: // true if a launch, specifically using the launch detector, has been detected bool _launch_detected{false}; + // [us] time stamp of (runway/catapult) launch detection + hrt_abstime _time_launch_detected{0}; + // [deg] global position of the vehicle at the time launch is detected (using launch detector) or takeoff is started (runway) Vector2d _takeoff_init_position{0, 0}; @@ -320,6 +325,7 @@ private: // orbit to altitude only when the aircraft has entered the final *straight approach. hrt_abstime _time_started_landing{0}; + Vector2f _local_landing_orbit_center{NAN, NAN}; // [m] lateral touchdown position offset manually commanded during landing float _lateral_touchdown_position_offset{0.0f}; @@ -336,6 +342,8 @@ private: bool flaring{false}; hrt_abstime start_time{0}; // [us] float initial_height_rate_setpoint{0.0f}; // [m/s] + float initial_pitch{0.0f}; // [rad] + float initial_throttle{0.0f}; // [0-1] throttle value when flare started } _flare_states; // [m] last terrain estimate which was valid @@ -419,6 +427,7 @@ private: void manual_control_setpoint_poll(); void vehicle_attitude_poll(); + void vehicle_attitude_setpoint_poll(); void vehicle_command_poll(); void vehicle_control_mode_poll(); @@ -859,6 +868,10 @@ private: (ParamFloat) _param_nav_gpsf_r, (ParamFloat) _param_t_spdweight, + // Launch detection parameters + (ParamBool) _param_fw_laun_detcn_on, + (ParamFloat) _param_fw_laun_cs_lk_dy, + // external parameters (ParamBool) _param_fw_use_airspd, (ParamFloat) _param_nav_loiter_rad, @@ -875,7 +888,6 @@ private: (ParamInt) _param_fw_lnd_abort, (ParamFloat) _param_fw_tko_airspd, (ParamFloat) _param_rwto_psp, - (ParamBool) _param_fw_laun_detcn_on, (ParamFloat) _param_fw_airspd_max, (ParamFloat) _param_fw_airspd_min, (ParamFloat) _param_fw_airspd_trim, diff --git a/src/modules/fw_mode_manager/figure_eight/FigureEight.cpp b/src/modules/fw_mode_manager/figure_eight/FigureEight.cpp index f7585f39b4..a995d28543 100644 --- a/src/modules/fw_mode_manager/figure_eight/FigureEight.cpp +++ b/src/modules/fw_mode_manager/figure_eight/FigureEight.cpp @@ -105,7 +105,7 @@ FigureEight::FigureEightPatternParameters FigureEight::sanitizeParameters(const } void FigureEight::initializePattern(const matrix::Vector2f &curr_pos_local, const matrix::Vector2f &ground_speed, - const FigureEightPatternParameters ¶meters, FigureEightPatternPoints pattern_points) + const FigureEightPatternParameters ¶meters, const FigureEightPatternPoints &pattern_points) { // Initialize the currently active segment, if it hasn't been active yet, or the pattern has been changed. if ((_current_segment == FigureEightSegment::SEGMENT_UNDEFINED) || (_active_parameters != parameters)) { diff --git a/src/modules/fw_mode_manager/figure_eight/FigureEight.hpp b/src/modules/fw_mode_manager/figure_eight/FigureEight.hpp index 297e07942c..fcdb39915c 100644 --- a/src/modules/fw_mode_manager/figure_eight/FigureEight.hpp +++ b/src/modules/fw_mode_manager/figure_eight/FigureEight.hpp @@ -140,7 +140,7 @@ private: * @param[in] pattern_points are the figure of eight pattern points. */ void initializePattern(const matrix::Vector2f &curr_pos_local, const matrix::Vector2f &ground_speed, - const FigureEightPatternParameters ¶meters, FigureEightPatternPoints pattern_points); + const FigureEightPatternParameters ¶meters, const FigureEightPatternPoints &pattern_points); /** * @brief Calculate figure eight pattern points diff --git a/src/modules/fw_mode_manager/fw_mode_manager_params.c b/src/modules/fw_mode_manager/fw_mode_manager_params.c index 3a2edb6052..0d3cdf292c 100644 --- a/src/modules/fw_mode_manager/fw_mode_manager_params.c +++ b/src/modules/fw_mode_manager/fw_mode_manager_params.c @@ -580,6 +580,21 @@ PARAM_DEFINE_INT32(FW_LND_ABORT, 3); */ PARAM_DEFINE_INT32(FW_LAUN_DETCN_ON, 0); +/** + * Control surface launch delay + * + * Locks control surfaces during pre-launch (armed) and until this time since launch has passed. + * Only affects control surfaces that have corresponding flag set, and not active for runway takeoff. + * Set to 0 to disable any surface locking after arming. + * + * @unit s + * @min 0.0 + * @decimal 1 + * @increment 0.1 + * @group FW Auto Takeoff + */ +PARAM_DEFINE_FLOAT(FW_LAUN_CS_LK_DY, 0.f); + /** * Flaps setting during take-off * diff --git a/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.cpp b/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.cpp index 498a5332b1..96cffebb52 100644 --- a/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.cpp +++ b/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.cpp @@ -86,7 +86,7 @@ void RunwayTakeoff::update(const hrt_abstime &time_now, const float takeoff_airs case RunwayTakeoffState::CLIMBOUT: if (vehicle_altitude > clearance_altitude) { - takeoff_state_ = RunwayTakeoffState::FLY; + takeoff_state_ = RunwayTakeoffState::FLYING; events::send(events::ID("runway_takeoff_reached_clearance_altitude"), events::Log::Info, "Reached clearance altitude"); } @@ -134,7 +134,7 @@ float RunwayTakeoff::getThrottle(const float idle_throttle) const break; - case RunwayTakeoffState::FLY: + case RunwayTakeoffState::FLYING: throttle = NAN; } @@ -147,7 +147,7 @@ float RunwayTakeoff::getMinPitch(float min_pitch_in_climbout, float min_pitch) c // constrain to the taxi pitch setpoint return math::radians(param_rwto_psp_.get() - 0.01f); - } else if (takeoff_state_ < RunwayTakeoffState::FLY) { + } else if (takeoff_state_ < RunwayTakeoffState::FLYING) { // ramp in the climbout pitch constraint over the rotation transition time const float taxi_pitch_min = math::radians(param_rwto_psp_.get() - 0.01f); return interpolateValuesOverAbsoluteTime(taxi_pitch_min, min_pitch_in_climbout, takeoff_time_, @@ -164,7 +164,7 @@ float RunwayTakeoff::getMaxPitch(const float max_pitch) const // constrain to the taxi pitch setpoint return math::radians(param_rwto_psp_.get() + 0.01f); - } else if (takeoff_state_ < RunwayTakeoffState::FLY) { + } else if (takeoff_state_ < RunwayTakeoffState::FLYING) { // ramp in the climbout pitch constraint over the rotation transition time const float taxi_pitch_max = math::radians(param_rwto_psp_.get() + 0.01f); return interpolateValuesOverAbsoluteTime(taxi_pitch_max, max_pitch, takeoff_time_, param_rwto_rot_time_.get()); diff --git a/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.h b/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.h index 22fa8a51ec..5b77426bca 100644 --- a/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.h +++ b/src/modules/fw_mode_manager/runway_takeoff/RunwayTakeoff.h @@ -57,7 +57,7 @@ enum RunwayTakeoffState { THROTTLE_RAMP = 0, // ramping up throttle CLAMPED_TO_RUNWAY, // clamped to runway, controlling yaw directly (wheel or rudder) CLIMBOUT, // climbout to safe height before navigation - FLY // navigate freely + FLYING // navigate freely }; class __EXPORT RunwayTakeoff : public ModuleParams @@ -135,7 +135,7 @@ public: float getMaxPitch(const float max_pitch) const; // NOTE: this is only to be used for mistaken mode transitions to takeoff while already in air - void forceSetFlyState() { takeoff_state_ = RunwayTakeoffState::FLY; } + void forceSetFlyState() { takeoff_state_ = RunwayTakeoffState::FLYING; } /** * @brief Reset the state machine. diff --git a/src/modules/fw_rate_control/FixedwingRateControl.cpp b/src/modules/fw_rate_control/FixedwingRateControl.cpp index 8bbd44c98c..69631979a5 100644 --- a/src/modules/fw_rate_control/FixedwingRateControl.cpp +++ b/src/modules/fw_rate_control/FixedwingRateControl.cpp @@ -36,7 +36,6 @@ using namespace time_literals; using namespace matrix; -using math::constrain; using math::interpolate; using math::radians; @@ -150,7 +149,7 @@ FixedwingRateControl::vehicle_land_detected_poll() } } -float FixedwingRateControl::get_airspeed_and_update_scaling() +float FixedwingRateControl::get_airspeed_and_update_scaling(float dt) { _airspeed_validated_sub.update(); const bool airspeed_valid = PX4_ISFINITE(_airspeed_validated_sub.get().calibrated_airspeed_m_s) @@ -163,6 +162,13 @@ float FixedwingRateControl::get_airspeed_and_update_scaling() /* prevent numerical drama by requiring 0.5 m/s minimal speed */ airspeed = math::max(0.5f, _airspeed_validated_sub.get().calibrated_airspeed_m_s); + if (dt > 1.f) { + _airspeed_filter_for_torque_scaling.reset(airspeed); + + } else { + airspeed = _airspeed_filter_for_torque_scaling.update(airspeed, dt); + } + } else { // VTOL: if we have no airspeed available and we are in hover mode then assume the lowest airspeed possible // this assumption is good as long as the vehicle is not hovering in a headwind which is much larger @@ -274,16 +280,27 @@ void FixedwingRateControl::Run() if (_vcontrol_mode.flag_control_rates_enabled) { - const float airspeed = get_airspeed_and_update_scaling(); + const float airspeed = get_airspeed_and_update_scaling(dt); /* reset integrals where needed */ if (_rates_sp.reset_integral) { _rate_control.resetIntegral(); } - // Reset integrators if the aircraft is on ground or not in a state where the fw attitude controller is run - if (_landed || !_in_fw_or_transition_wo_tailsitter_transition) { + launch_detection_status_s launch_detection_status{}; + _launch_detection_status_sub.copy(&launch_detection_status); + bool control_surfaces_locked = false; + + if (hrt_elapsed_time(&launch_detection_status.timestamp) < 100_ms + && launch_detection_status.selected_control_surface_disarmed) { + control_surfaces_locked = true; + } + + // Reset integrators if the aircraft is on ground or not in a state where the fw attitude controller is run + if (_landed || !_in_fw_or_transition_wo_tailsitter_transition || control_surfaces_locked) { + + _gain_compression.reset(); _rate_control.resetIntegral(); } @@ -363,10 +380,11 @@ void FixedwingRateControl::Run() _rate_control.setFeedForwardGain(scaled_gain_ff); // Run attitude RATE controllers which need the desired attitudes from above, add trim. - const Vector3f angular_acceleration_setpoint = _rate_control.update(rates, body_rates_setpoint, angular_accel, dt, - _landed); + const Vector3f angular_acceleration_setpoint = _rate_control.update(rates, body_rates_setpoint, angular_accel, dt, _landed); - Vector3f control_u = angular_acceleration_setpoint * _airspeed_scaling * _airspeed_scaling; + Vector3f control_u = _gain_compression.getGains().emult(angular_acceleration_setpoint * _airspeed_scaling * _airspeed_scaling); + + _gain_compression.update(control_u, dt); // Special case yaw in Acro: if the parameter FW_ACRO_YAW_EN is not set then don't rate-control yaw if (!_vcontrol_mode.flag_control_attitude_enabled && _vcontrol_mode.flag_control_manual_enabled @@ -410,6 +428,7 @@ void FixedwingRateControl::Run() } else { // full manual + _gain_compression.reset(); _rate_control.resetIntegral(); } diff --git a/src/modules/fw_rate_control/FixedwingRateControl.hpp b/src/modules/fw_rate_control/FixedwingRateControl.hpp index 2d87e86d8a..1bdab1c135 100644 --- a/src/modules/fw_rate_control/FixedwingRateControl.hpp +++ b/src/modules/fw_rate_control/FixedwingRateControl.hpp @@ -34,9 +34,11 @@ #pragma once #include +#include #include #include +#include #include #include #include @@ -68,6 +70,7 @@ #include #include #include +#include using matrix::Eulerf; using matrix::Quatf; @@ -108,6 +111,7 @@ private: uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; uORB::Subscription _vehicle_rates_sub{ORB_ID(vehicle_angular_velocity)}; + uORB::Subscription _launch_detection_status_sub{ORB_ID(launch_detection_status)}; uORB::SubscriptionMultiArray _control_allocator_status_subs{ORB_ID::control_allocator_status}; @@ -132,6 +136,9 @@ private: hrt_abstime _last_run{0}; + static constexpr float _kAirspeedFilterTimeConstant{1.f}; + AlphaFilter _airspeed_filter_for_torque_scaling{_kAirspeedFilterTimeConstant}; + float _airspeed_scaling{1.0f}; bool _landed{true}; @@ -208,6 +215,7 @@ private: ) RateControl _rate_control; ///< class for rate control calculations + GainCompression3d _gain_compression{this}; void updateActuatorControlsStatus(float dt); @@ -219,5 +227,5 @@ private: void vehicle_manual_poll(); void vehicle_land_detected_poll(); - float get_airspeed_and_update_scaling(); + float get_airspeed_and_update_scaling(float dt); }; diff --git a/src/modules/gimbal/common.h b/src/modules/gimbal/common.h index 2436bd68dd..fc528a305d 100644 --- a/src/modules/gimbal/common.h +++ b/src/modules/gimbal/common.h @@ -86,5 +86,12 @@ struct ControlData { uint64_t timestamp_last_update{0}; // Timestamp when there was the last setpoint set by the input used for timeout }; +// Must match paraneter MNT_DO_STAB +enum MntDoStabilize { + DISABLED = 0, + ALL_AXES, // Stabilize all axis + YAW_LOCK, // Stabilize yaw for absolute/lock mode. + PITCH_LOCK, // Stabilize pitch for absolute/lock mode. +}; } /* namespace gimbal */ diff --git a/src/modules/gimbal/gimbal.cpp b/src/modules/gimbal/gimbal.cpp index 9179055b31..85c0338888 100644 --- a/src/modules/gimbal/gimbal.cpp +++ b/src/modules/gimbal/gimbal.cpp @@ -254,14 +254,26 @@ static int gimbal_thread_main(int argc, char *argv[]) } } - if (params.mnt_do_stab == 1) { - thread_data.output_obj->set_stabilize(true, true, true); + switch (params.mnt_do_stab) { + case MntDoStabilize::ALL_AXES: { + thread_data.output_obj->set_stabilize(true, true, true); + break; + } - } else if (params.mnt_do_stab == 2) { - thread_data.output_obj->set_stabilize(false, false, true); + case MntDoStabilize::YAW_LOCK: { + thread_data.output_obj->set_stabilize(false, false, true); + break; + } - } else { - thread_data.output_obj->set_stabilize(false, false, false); + case MntDoStabilize::PITCH_LOCK: { + thread_data.output_obj->set_stabilize(false, true, false); + break; + } + + default: { + thread_data.output_obj->set_stabilize(false, false, false); + break; + } } if (thread_data.output_obj->check_and_handle_setpoint_timeout(thread_data.control_data, hrt_absolute_time())) { @@ -533,12 +545,10 @@ void update_params(ParameterHandles ¶m_handles, Parameters ¶ms) param_get(param_handles.mnt_man_roll, ¶ms.mnt_man_roll); param_get(param_handles.mnt_man_yaw, ¶ms.mnt_man_yaw); param_get(param_handles.mnt_do_stab, ¶ms.mnt_do_stab); - param_get(param_handles.mnt_range_pitch, ¶ms.mnt_range_pitch); + param_get(param_handles.mnt_max_pitch, ¶ms.mnt_max_pitch); + param_get(param_handles.mnt_min_pitch, ¶ms.mnt_min_pitch); param_get(param_handles.mnt_range_roll, ¶ms.mnt_range_roll); param_get(param_handles.mnt_range_yaw, ¶ms.mnt_range_yaw); - param_get(param_handles.mnt_off_pitch, ¶ms.mnt_off_pitch); - param_get(param_handles.mnt_off_roll, ¶ms.mnt_off_roll); - param_get(param_handles.mnt_off_yaw, ¶ms.mnt_off_yaw); param_get(param_handles.mav_sysid, ¶ms.mav_sysid); param_get(param_handles.mav_compid, ¶ms.mav_compid); param_get(param_handles.mnt_rate_pitch, ¶ms.mnt_rate_pitch); @@ -546,6 +556,7 @@ void update_params(ParameterHandles ¶m_handles, Parameters ¶ms) param_get(param_handles.mnt_rc_in_mode, ¶ms.mnt_rc_in_mode); param_get(param_handles.mnt_lnd_p_min, ¶ms.mnt_lnd_p_min); param_get(param_handles.mnt_lnd_p_max, ¶ms.mnt_lnd_p_max); + param_get(param_handles.mnt_tau, ¶ms.mnt_tau); } bool initialize_params(ParameterHandles ¶m_handles, Parameters ¶ms) @@ -558,12 +569,10 @@ bool initialize_params(ParameterHandles ¶m_handles, Parameters ¶ms) param_handles.mnt_man_roll = param_find("MNT_MAN_ROLL"); param_handles.mnt_man_yaw = param_find("MNT_MAN_YAW"); param_handles.mnt_do_stab = param_find("MNT_DO_STAB"); - param_handles.mnt_range_pitch = param_find("MNT_RANGE_PITCH"); + param_handles.mnt_max_pitch = param_find("MNT_MAX_PITCH"); + param_handles.mnt_min_pitch = param_find("MNT_MIN_PITCH"); param_handles.mnt_range_roll = param_find("MNT_RANGE_ROLL"); param_handles.mnt_range_yaw = param_find("MNT_RANGE_YAW"); - param_handles.mnt_off_pitch = param_find("MNT_OFF_PITCH"); - param_handles.mnt_off_roll = param_find("MNT_OFF_ROLL"); - param_handles.mnt_off_yaw = param_find("MNT_OFF_YAW"); param_handles.mav_sysid = param_find("MAV_SYS_ID"); param_handles.mav_compid = param_find("MAV_COMP_ID"); param_handles.mnt_rate_pitch = param_find("MNT_RATE_PITCH"); @@ -571,6 +580,7 @@ bool initialize_params(ParameterHandles ¶m_handles, Parameters ¶ms) param_handles.mnt_rc_in_mode = param_find("MNT_RC_IN_MODE"); param_handles.mnt_lnd_p_min = param_find("MNT_LND_P_MIN"); param_handles.mnt_lnd_p_max = param_find("MNT_LND_P_MAX"); + param_handles.mnt_tau = param_find("MNT_TAU"); if (param_handles.mnt_mode_in == PARAM_INVALID || param_handles.mnt_mode_out == PARAM_INVALID || @@ -580,19 +590,18 @@ bool initialize_params(ParameterHandles ¶m_handles, Parameters ¶ms) param_handles.mnt_man_roll == PARAM_INVALID || param_handles.mnt_man_yaw == PARAM_INVALID || param_handles.mnt_do_stab == PARAM_INVALID || - param_handles.mnt_range_pitch == PARAM_INVALID || + param_handles.mnt_max_pitch == PARAM_INVALID || + param_handles.mnt_min_pitch == PARAM_INVALID || param_handles.mnt_range_roll == PARAM_INVALID || param_handles.mnt_range_yaw == PARAM_INVALID || - param_handles.mnt_off_pitch == PARAM_INVALID || - param_handles.mnt_off_roll == PARAM_INVALID || - param_handles.mnt_off_yaw == PARAM_INVALID || param_handles.mav_sysid == PARAM_INVALID || param_handles.mav_compid == PARAM_INVALID || param_handles.mnt_rate_pitch == PARAM_INVALID || param_handles.mnt_rate_yaw == PARAM_INVALID || param_handles.mnt_rc_in_mode == PARAM_INVALID || param_handles.mnt_lnd_p_min == PARAM_INVALID || - param_handles.mnt_lnd_p_max == PARAM_INVALID + param_handles.mnt_lnd_p_max == PARAM_INVALID || + param_handles.mnt_tau == PARAM_INVALID ) { return false; } diff --git a/src/modules/gimbal/gimbal_params.c b/src/modules/gimbal/gimbal_params.c index a6b1889e2f..7a98214ced 100644 --- a/src/modules/gimbal/gimbal_params.c +++ b/src/modules/gimbal/gimbal_params.c @@ -146,25 +146,37 @@ PARAM_DEFINE_INT32(MNT_MAN_YAW, 0); * @value 0 Disable * @value 1 Stabilize all axis * @value 2 Stabilize yaw for absolute/lock mode. -* @min 0 -* @max 2 +* @value 3 Stabilize pitch for absolute/lock mode. * @group Mount */ PARAM_DEFINE_INT32(MNT_DO_STAB, 0); /** -* Range of pitch channel output in degrees (only in AUX output mode). +* Max positive angle of pitch setpoint (only in MNT_MODE_OUT=AUX). +* +* Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). * -* @min 1.0 -* @max 720.0 * @unit deg * @decimal 1 * @group Mount */ -PARAM_DEFINE_FLOAT(MNT_RANGE_PITCH, 90.0f); +PARAM_DEFINE_FLOAT(MNT_MAX_PITCH, 45.0f); /** -* Range of roll channel output in degrees (only in AUX output mode). +* Min negative angle of pitch setpoint (only in MNT_MODE_OUT=AUX). +* +* Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). +* +* @unit deg +* @decimal 1 +* @group Mount +*/ +PARAM_DEFINE_FLOAT(MNT_MIN_PITCH, -45.0f); + +/** +* Range of roll channel output (only in MNT_MODE_OUT=AUX). +* +* Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). Note that only symmetric angular ranges are supported. * * @min 1.0 * @max 720.0 @@ -175,7 +187,9 @@ PARAM_DEFINE_FLOAT(MNT_RANGE_PITCH, 90.0f); PARAM_DEFINE_FLOAT(MNT_RANGE_ROLL, 90.0f); /** -* Range of yaw channel output in degrees (only in AUX output mode). +* Range of yaw channel output (only in MNT_MODE_OUT=AUX). +* +* Use output driver settings to calibrate (e.g. PWM_CENT/_MIN/_MAX). Note that only symmetric angular ranges are supported. * * @min 1.0 * @max 720.0 @@ -185,38 +199,6 @@ PARAM_DEFINE_FLOAT(MNT_RANGE_ROLL, 90.0f); */ PARAM_DEFINE_FLOAT(MNT_RANGE_YAW, 360.0f); -/** -* Offset for pitch channel output in degrees. -* -* @min -360.0 -* @max 360.0 -* @unit deg -* @decimal 1 -* @group Mount -*/ -PARAM_DEFINE_FLOAT(MNT_OFF_PITCH, 0.0f); - -/** -* Offset for roll channel output in degrees. -* -* @min -360.0 -* @max 360.0 -* @unit deg -* @decimal 1 -* @group Mount -*/ -PARAM_DEFINE_FLOAT(MNT_OFF_ROLL, 0.0f); - -/** -* Offset for yaw channel output in degrees. -* -* @min -360.0 -* @max 360.0 -* @unit deg -* @decimal 1 -* @group Mount -*/ -PARAM_DEFINE_FLOAT(MNT_OFF_YAW, 0.0f); /** * Angular pitch rate for manual input in degrees/second. @@ -242,6 +224,19 @@ PARAM_DEFINE_FLOAT(MNT_RATE_PITCH, 30.0f); */ PARAM_DEFINE_FLOAT(MNT_RATE_YAW, 30.0f); +/** + * Alpha filter time constant defining the convergence rate (in seconds) for open-loop AUX mount control. + * + * Use when no angular position feedback is available. + * With MNT_MODE_OUT set to AUX, the mount operates in open-loop and directly commands the servo output. + * Parameters must be tuned for the specific servo to approximate its speed and response. + * + * @min 0.0 + * @group Mount + */ +PARAM_DEFINE_FLOAT(MNT_TAU, 0.3f); + + /** * Input mode for RC gimbal input * diff --git a/src/modules/gimbal/gimbal_params.h b/src/modules/gimbal/gimbal_params.h index 5a265d0237..e480dc41d2 100644 --- a/src/modules/gimbal/gimbal_params.h +++ b/src/modules/gimbal/gimbal_params.h @@ -64,12 +64,10 @@ struct Parameters { int32_t mnt_man_roll; int32_t mnt_man_yaw; int32_t mnt_do_stab; - float mnt_range_pitch; + float mnt_max_pitch; + float mnt_min_pitch; float mnt_range_roll; float mnt_range_yaw; - float mnt_off_pitch; - float mnt_off_roll; - float mnt_off_yaw; int32_t mav_sysid; int32_t mav_compid; float mnt_rate_pitch; @@ -77,6 +75,7 @@ struct Parameters { int32_t mnt_rc_in_mode; float mnt_lnd_p_min; float mnt_lnd_p_max; + float mnt_tau; }; struct ParameterHandles { @@ -88,12 +87,10 @@ struct ParameterHandles { param_t mnt_man_roll; param_t mnt_man_yaw; param_t mnt_do_stab; - param_t mnt_range_pitch; + param_t mnt_max_pitch; + param_t mnt_min_pitch; param_t mnt_range_roll; param_t mnt_range_yaw; - param_t mnt_off_pitch; - param_t mnt_off_roll; - param_t mnt_off_yaw; param_t mav_sysid; param_t mav_compid; param_t mnt_rate_pitch; @@ -101,6 +98,7 @@ struct ParameterHandles { param_t mnt_rc_in_mode; param_t mnt_lnd_p_min; param_t mnt_lnd_p_max; + param_t mnt_tau; }; } /* namespace gimbal */ diff --git a/src/modules/gimbal/input_mavlink.cpp b/src/modules/gimbal/input_mavlink.cpp index aef348ca53..de7ea22155 100644 --- a/src/modules/gimbal/input_mavlink.cpp +++ b/src/modules/gimbal/input_mavlink.cpp @@ -508,10 +508,12 @@ void InputMavlinkGimbalV2::_stream_gimbal_manager_information(const ControlData gimbal_manager_information_s::GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_LOCK | gimbal_manager_information_s::GIMBAL_MANAGER_CAP_FLAGS_CAN_POINT_LOCATION_GLOBAL; - gimbal_manager_info.pitch_max = _parameters.mnt_range_pitch; - gimbal_manager_info.pitch_min = -_parameters.mnt_range_pitch; - gimbal_manager_info.yaw_max = _parameters.mnt_range_yaw; - gimbal_manager_info.yaw_min = -_parameters.mnt_range_yaw; + gimbal_manager_info.pitch_max = math::radians(_parameters.mnt_max_pitch); + gimbal_manager_info.pitch_min = math::radians(_parameters.mnt_min_pitch); + gimbal_manager_info.yaw_max = math::radians(_parameters.mnt_range_yaw * 0.5f); + gimbal_manager_info.yaw_min = math::radians(-_parameters.mnt_range_yaw * 0.5f); + gimbal_manager_info.roll_max = math::radians(_parameters.mnt_range_roll * 0.5f); + gimbal_manager_info.roll_min = math::radians(-_parameters.mnt_range_roll * 0.5f); gimbal_manager_info.gimbal_device_id = control_data.device_compid; diff --git a/src/modules/gimbal/input_rc.cpp b/src/modules/gimbal/input_rc.cpp index 3c2926ffbc..ab399d10cb 100644 --- a/src/modules/gimbal/input_rc.cpp +++ b/src/modules/gimbal/input_rc.cpp @@ -141,7 +141,9 @@ InputRC::UpdateResult InputRC::_read_control_data_from_subscription(ControlData control_data.type_data.angle.frames[0] = ControlData::TypeData::TypeAngle::Frame::AngleAbsoluteFrame; control_data.type_data.angle.frames[1] = ControlData::TypeData::TypeAngle::Frame::AngleAbsoluteFrame; - control_data.type_data.angle.frames[2] = ControlData::TypeData::TypeAngle::Frame::AngleBodyFrame; + control_data.type_data.angle.frames[2] = (_parameters.mnt_do_stab == MntDoStabilize::ALL_AXES + || _parameters.mnt_do_stab == MntDoStabilize::YAW_LOCK) ? + ControlData::TypeData::TypeAngle::Frame::AngleAbsoluteFrame : ControlData::TypeData::TypeAngle::Frame::AngleBodyFrame; control_data.type_data.angle.angular_velocity[0] = NAN; control_data.type_data.angle.angular_velocity[1] = NAN; diff --git a/src/modules/gimbal/output.cpp b/src/modules/gimbal/output.cpp index ea474bf33e..fce2ad8a4b 100644 --- a/src/modules/gimbal/output.cpp +++ b/src/modules/gimbal/output.cpp @@ -146,6 +146,9 @@ void OutputBase::_set_angle_setpoints(const ControlData &control_data) _angle_velocity[0] = NAN; _angle_velocity[1] = NAN; _angle_velocity[2] = NAN; + _absolute_angle[0] = false; + _absolute_angle[1] = false; + _absolute_angle[2] = false; break; } } @@ -237,16 +240,19 @@ void OutputBase::_calculate_angle_output(const hrt_abstime &t) float dt = math::constrain((t - _last_update) * 1.e-6f, 0.001f, 1.f); const matrix::Quatf q_setpoint(_q_setpoint); - const bool q_setpoint_valid = q_setpoint.isAllFinite(); - matrix::Eulerf euler_gimbal{}; - if (q_setpoint_valid) { - euler_gimbal = q_setpoint; + if (q_setpoint.isAllFinite()) { + _last_valid_setpoint = q_setpoint; } + matrix::Eulerf euler_gimbal(_last_valid_setpoint); + for (int i = 0; i < 3; ++i) { - if (q_setpoint_valid && PX4_ISFINITE(euler_gimbal(i))) { + if (PX4_ISFINITE(euler_gimbal(i)) && compensate[i] && PX4_ISFINITE(euler_vehicle(i))) { + _angle_outputs[i] = euler_gimbal(i) - euler_vehicle(i); + + } else if (PX4_ISFINITE(euler_gimbal(i)) && !_absolute_angle[i]) { _angle_outputs[i] = euler_gimbal(i); } @@ -254,10 +260,6 @@ void OutputBase::_calculate_angle_output(const hrt_abstime &t) _angle_outputs[i] += dt * _angle_velocity[i]; } - if (compensate[i] && PX4_ISFINITE(euler_vehicle(i))) { - _angle_outputs[i] -= euler_vehicle(i); - } - if (PX4_ISFINITE(_angle_outputs[i]) && _parameters.mnt_rc_in_mode == 0) { // if we are in angle input mode, we bring angles into proper range [-pi, pi] _angle_outputs[i] = matrix::wrap_pi(_angle_outputs[i]); @@ -267,8 +269,12 @@ void OutputBase::_calculate_angle_output(const hrt_abstime &t) // constrain angle outputs to [-range/2, range/2] _angle_outputs[0] = math::constrain(_angle_outputs[0], math::radians(-_parameters.mnt_range_roll / 2), math::radians(_parameters.mnt_range_roll / 2)); - _angle_outputs[1] = math::constrain(_angle_outputs[1], math::radians(-_parameters.mnt_range_pitch / 2), - math::radians(_parameters.mnt_range_pitch / 2)); + + // constrain angle outputs to [min, max] to allow for asymmetrical angular ranges + _angle_outputs[1] = math::constrain(_angle_outputs[1], + math::radians(_parameters.mnt_min_pitch), + math::radians(_parameters.mnt_max_pitch)); + // constrain angle outputs to [-range/2, range/2] _angle_outputs[2] = math::constrain(_angle_outputs[2], math::radians(-_parameters.mnt_range_yaw / 2), math::radians(_parameters.mnt_range_yaw / 2)); @@ -280,6 +286,16 @@ void OutputBase::_calculate_angle_output(const hrt_abstime &t) math::radians(_parameters.mnt_lnd_p_max)); } } + + _angle_outputs_filtered.setParameters(dt, _parameters.mnt_tau); + matrix::Vector3f filtered_outputs = _angle_outputs_filtered.update(matrix::Vector3f(_angle_outputs)); + + for (int i = 0; i < 3; i++) { + _angle_outputs[i] = filtered_outputs(i); + } + + set_last_valid_setpoint(compensate, euler_vehicle); + } void OutputBase::set_stabilize(bool roll_stabilize, bool pitch_stabilize, bool yaw_stabilize) @@ -289,4 +305,54 @@ void OutputBase::set_stabilize(bool roll_stabilize, bool pitch_stabilize, bool y _stabilize[2] = yaw_stabilize; } +void OutputBase::set_last_valid_setpoint(const bool compensate[3], const matrix::Eulerf &euler_vehicle) +{ + // No updates from angular velocity, hence no modification of last valid setpoint + if (!PX4_ISFINITE(_angle_velocity[0]) && !PX4_ISFINITE(_angle_velocity[1]) && !PX4_ISFINITE(_angle_velocity[2])) { + return; + } + + // Angle outputs, from vehicle body frame to end effector (last actuator in the kinematic chain) + _last_valid_setpoint.phi() = _angle_outputs[0]; + _last_valid_setpoint.theta() = _angle_outputs[1]; + _last_valid_setpoint.psi() = _angle_outputs[2]; + + // Take into account vehicle attitude if it should + switch (_parameters.mnt_do_stab) { + + case MntDoStabilize::ALL_AXES: { + + for (int i = 0; i < 3; i++) { + if (compensate[i]) { + _last_valid_setpoint(i) += euler_vehicle(i); + } + } + + break; + } + + case MntDoStabilize::YAW_LOCK: { + if (compensate[2]) { + _last_valid_setpoint.psi() += euler_vehicle(2); + } + + break; + } + + case MntDoStabilize::PITCH_LOCK: { + + if (compensate[1]) { + _last_valid_setpoint.theta() += euler_vehicle(1); + } + + break; + } + + default: { + // Dont add anything + break; + } + } +} + } /* namespace gimbal */ diff --git a/src/modules/gimbal/output.h b/src/modules/gimbal/output.h index 0da012c35f..9d77fc1cb1 100644 --- a/src/modules/gimbal/output.h +++ b/src/modules/gimbal/output.h @@ -38,6 +38,8 @@ #include "gimbal_params.h" #include #include +#include +#include #include #include #include @@ -92,11 +94,27 @@ protected: // Pitch and role are by default aligned with the horizon. // Yaw follows the vehicle (not lock/absolute mode). bool _absolute_angle[3] = {true, true, false }; + AlphaFilter _angle_outputs_filtered; /** calculate the _angle_outputs (with speed) and stabilize if needed */ void _calculate_angle_output(const hrt_abstime &t); + /** + * The angular velocity setpoint modifies the angle setpoint. + * To correctly track and lock onto the desired orientation, the resulting change in angle + * must be incorporated into the world-frame attitude setpoint. Depending on MNT_DO_STAB and + * the received MAVLink command, the last valid setpoint is updated to account for the vehicle attitude. + * + * @param compensate Boolean per axis (roll, pitch, yaw). If true, the vehicle attitude is taken into account. + * @param euler_vehicle Reference to Euler float + */ + void set_last_valid_setpoint(const bool compensate[3], const matrix::Eulerf &euler_vehicle); + float _angle_outputs[3] = { 0.f, 0.f, 0.f }; ///< calculated output angles (roll, pitch, yaw) [rad] + + // Quaternion float last valid setpoint. + // Depending on MNT_DO_STAB and mavlink command the setpoint can be relative to vehicle or in the world frame + matrix::Eulerf _last_valid_setpoint; hrt_abstime _last_update; private: diff --git a/src/modules/gimbal/output_mavlink.cpp b/src/modules/gimbal/output_mavlink.cpp index ae5222c674..c3ceaab678 100644 --- a/src/modules/gimbal/output_mavlink.cpp +++ b/src/modules/gimbal/output_mavlink.cpp @@ -100,9 +100,9 @@ void OutputMavlinkV1::update(const ControlData &control_data, bool new_setpoints // gimbal spec has roll, pitch on channels 0, 1, respectively; MAVLink spec has roll, pitch on channels 1, 0, respectively // gimbal uses radians, MAVLink uses degrees - vehicle_command.param1 = math::degrees(_angle_outputs[1] + math::radians(_parameters.mnt_off_pitch)); - vehicle_command.param2 = math::degrees(_angle_outputs[0] + math::radians(_parameters.mnt_off_roll)); - vehicle_command.param3 = math::degrees(_angle_outputs[2] + math::radians(_parameters.mnt_off_yaw)); + vehicle_command.param1 = math::degrees(_angle_outputs[1]); + vehicle_command.param2 = math::degrees(_angle_outputs[0]); + vehicle_command.param3 = math::degrees(_angle_outputs[2]); vehicle_command.param7 = 2.0f; // MAV_MOUNT_MODE_MAVLINK_TARGETING; _gimbal_v1_command_pub.publish(vehicle_command); diff --git a/src/modules/gimbal/output_rc.cpp b/src/modules/gimbal/output_rc.cpp index dba7b02b1a..508d748b5b 100644 --- a/src/modules/gimbal/output_rc.cpp +++ b/src/modules/gimbal/output_rc.cpp @@ -38,8 +38,6 @@ #include #include -using math::constrain; - namespace gimbal { @@ -67,24 +65,58 @@ void OutputRC::update(const ControlData &control_data, bool new_setpoints, uint8 // _angle_outputs are in radians, gimbal_controls are in [-1, 1] gimbal_controls_s gimbal_controls{}; - gimbal_controls.control[gimbal_controls_s::INDEX_ROLL] = constrain( - (_angle_outputs[0] + math::radians(_parameters.mnt_off_roll)) * - (1.0f / (math::radians(_parameters.mnt_range_roll / 2.0f))), - -1.f, 1.f); - gimbal_controls.control[gimbal_controls_s::INDEX_PITCH] = constrain( - (_angle_outputs[1] + math::radians(_parameters.mnt_off_pitch)) * - (1.0f / (math::radians(_parameters.mnt_range_pitch / 2.0f))), - -1.f, 1.f); - gimbal_controls.control[gimbal_controls_s::INDEX_YAW] = constrain( - (_angle_outputs[2] + math::radians(_parameters.mnt_off_yaw)) * - (1.0f / (math::radians(_parameters.mnt_range_yaw / 2.0f))), - -1.f, 1.f); + gimbal_controls.control[gimbal_controls_s::INDEX_ROLL] = anglesMappedToOutput(gimbal_controls_s::INDEX_ROLL); + gimbal_controls.control[gimbal_controls_s::INDEX_PITCH] = anglesMappedToOutput(gimbal_controls_s::INDEX_PITCH); + gimbal_controls.control[gimbal_controls_s::INDEX_YAW] = anglesMappedToOutput(gimbal_controls_s::INDEX_YAW); gimbal_controls.timestamp = hrt_absolute_time(); _gimbal_controls_pub.publish(gimbal_controls); _last_update = now; } +float OutputRC::anglesMappedToOutput(const uint8_t index) +{ + + float value = 0.f; + float min_value = 0.f; + float max_value = 0.f; + + switch (index) { + case gimbal_controls_s::INDEX_ROLL: { + value = _angle_outputs[0]; + max_value = math::radians(_parameters.mnt_range_roll) * 0.5f; + min_value = -math::radians(_parameters.mnt_range_roll) * 0.5f; + break; + } + + case gimbal_controls_s::INDEX_PITCH: { + value = _angle_outputs[1]; + max_value = math::radians(_parameters.mnt_max_pitch); + min_value = math::radians(_parameters.mnt_min_pitch); + break; + } + + case gimbal_controls_s::INDEX_YAW: { + value = _angle_outputs[2]; + max_value = math::radians(_parameters.mnt_range_yaw) * 0.5f; + min_value = -math::radians(_parameters.mnt_range_yaw) * 0.5f; + break; + } + + default: { + PX4_WARN("INDEX does not exist"); + break; + } + } + + if (value >= FLT_EPSILON) { + return math::interpolate(value, 0.f, max_value, 0.f, 1.f); + + } else { + return math::interpolate(value, min_value, 0.f, -1.f, 0.f); + } +} + void OutputRC::print_status() const { PX4_INFO("Output: AUX"); @@ -98,20 +130,46 @@ void OutputRC::_stream_device_attitude_status() attitude_status.target_component = 0; attitude_status.device_flags = 0; - if (_absolute_angle[0]) { - attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_ROLL_LOCK; + matrix::Quatf q; + + switch (_parameters.mnt_do_stab) { + case MntDoStabilize::PITCH_LOCK: { + // Report device attitude in relative frame as external apps are dependent + attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME; + matrix::AxisAnglef angle_axis(matrix::Vector3f(0.f, 1.f, 0.f), _angle_outputs[1]); + q = matrix::Quaternionf(angle_axis); + break; + } + + case MntDoStabilize::YAW_LOCK: + case MntDoStabilize::ALL_AXES: + default: { + if (_absolute_angle[0]) { + attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_ROLL_LOCK; + } + + if (_absolute_angle[1]) { + attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_PITCH_LOCK; + } + + if (_absolute_angle[2]) { + attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_YAW_LOCK; + // absolute frame + q = matrix::Quaternionf(_last_valid_setpoint); + + } else { + attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME; + // yaw vehicle frame + q = matrix::Quaternionf(_last_valid_setpoint); + } + + + break; + } } - if (_absolute_angle[1]) { - attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_PITCH_LOCK; - } - if (_absolute_angle[2]) { - attitude_status.device_flags |= gimbal_device_attitude_status_s::DEVICE_FLAGS_YAW_LOCK; - } - matrix::Eulerf euler(_angle_outputs[0], _angle_outputs[1], _angle_outputs[2]); - matrix::Quatf q(euler); q.copyTo(attitude_status.q); attitude_status.failure_flags = 0; diff --git a/src/modules/gimbal/output_rc.h b/src/modules/gimbal/output_rc.h index de497c194f..616bfe86f6 100644 --- a/src/modules/gimbal/output_rc.h +++ b/src/modules/gimbal/output_rc.h @@ -55,6 +55,7 @@ public: private: void _stream_device_attitude_status(); + float anglesMappedToOutput(const uint8_t index); uORB::Publication _gimbal_controls_pub{ORB_ID(gimbal_controls)}; uORB::Publication _attitude_status_pub{ORB_ID(gimbal_device_attitude_status)}; diff --git a/src/modules/gyro_fft/CMSIS_5/.clang-tidy b/src/modules/gyro_fft/CMSIS_5/.clang-tidy deleted file mode 100644 index 64e1b8f404..0000000000 --- a/src/modules/gyro_fft/CMSIS_5/.clang-tidy +++ /dev/null @@ -1,120 +0,0 @@ ---- -Checks: '*, - -android*, - -bugprone-integer-division, - -cert-dcl50-cpp, - -cert-env33-c, - -cert-err34-c, - -cert-err58-cpp, - -cert-msc30-c, - -cert-msc50-cpp, - -cert-flp30-c, - -clang-analyzer-core.CallAndMessage, - -clang-analyzer-core.NullDereference, - -clang-analyzer-core.UndefinedBinaryOperatorResult, - -clang-analyzer-core.uninitialized.Assign, - -clang-analyzer-core.VLASize, - -clang-analyzer-cplusplus.NewDelete, - -clang-analyzer-cplusplus.NewDeleteLeaks, - -clang-analyzer-deadcode.DeadStores, - -clang-analyzer-optin.cplusplus.VirtualCall, - -clang-analyzer-optin.performance.Padding, - -clang-analyzer-security.FloatLoopCounter, - -clang-analyzer-security.insecureAPI.strcpy, - -clang-analyzer-unix.API, - -clang-analyzer-unix.cstring.BadSizeArg, - -clang-analyzer-unix.Malloc, - -clang-analyzer-unix.MallocSizeof, - -cppcoreguidelines-c-copy-assignment-signature, - -cppcoreguidelines-interfaces-global-init, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, - -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-const-cast, - -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-type-member-init, - -cppcoreguidelines-pro-type-reinterpret-cast, - -cppcoreguidelines-pro-type-union-access, - -cppcoreguidelines-pro-type-vararg, - -cppcoreguidelines-special-member-functions, - -fuchsia-default-arguments, - -fuchsia-overloaded-operator, - -google-build-using-namespace, - -google-explicit-constructor, - -google-global-names-in-headers, - -google-readability-braces-around-statements, - -google-readability-casting, - -google-readability-function-size, - -google-readability-namespace-comments, - -google-readability-todo, - -google-runtime-int, - -google-runtime-references, - -hicpp-braces-around-statements, - -hicpp-deprecated-headers, - -hicpp-explicit-conversions, - -hicpp-function-size, - -hicpp-member-init, - -hicpp-no-array-decay, - -hicpp-no-assembler, - -hicpp-no-malloc, - -hicpp-signed-bitwise, - -hicpp-special-member-functions, - -hicpp-use-auto, - -hicpp-use-equals-default, - -hicpp-use-equals-delete, - -hicpp-use-override, - -hicpp-vararg, - -llvm-header-guard, - -llvm-include-order, - -llvm-namespace-comment, - -misc-incorrect-roundings, - -misc-macro-parentheses, - -misc-misplaced-widening-cast, - -misc-redundant-expression, - -misc-unconventional-assign-operator, - -misc-unused-parameters, - -modernize-deprecated-headers, - -modernize-loop-convert, - -modernize-pass-by-value, - -modernize-return-braced-init-list, - -modernize-use-auto, - -modernize-use-bool-literals, - -modernize-use-default-member-init, - -modernize-use-emplace, - -modernize-use-equals-default, - -modernize-use-equals-delete, - -modernize-use-override, - -modernize-use-using, - -performance-inefficient-string-concatenation, - -performance-unnecessary-value-param, - -readability-avoid-const-params-in-decls, - -readability-braces-around-statements, - -readability-container-size-empty, - -readability-delete-null-pointer, - -readability-else-after-return, - -readability-function-size, - -readability-implicit-bool-cast, - -readability-implicit-bool-conversion, - -readability-inconsistent-declaration-parameter-name, - -readability-named-parameter, - -readability-non-const-parameter, - -readability-redundant-control-flow, - -readability-redundant-declaration, - -readability-redundant-member-init, - -readability-simplify-boolean-expr, - -readability-static-accessed-through-instance, - -readability-static-definition-in-anonymous-namespace, - ' -WarningsAsErrors: '*' -CheckOptions: - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: google-readability-function-size.BranchThreshold - value: '600' - - key: google-readability-function-size.LineThreshold - value: '4000' - - key: google-readability-function-size.StatementThreshold - value: '4000' -... diff --git a/src/modules/gyro_fft/CMakeLists.txt b/src/modules/gyro_fft/CMakeLists.txt index 9bf6832ed4..b342ef250f 100644 --- a/src/modules/gyro_fft/CMakeLists.txt +++ b/src/modules/gyro_fft/CMakeLists.txt @@ -38,8 +38,10 @@ if(${PX4_PLATFORM} MATCHES "NuttX") add_compile_options(-DARM_MATH_DSP) endif() -# Disable 32-bit assembly warnings on apple silicon. Triggered by unused code only. -if(${PX4_PLATFORM} MATCHES "posix" AND APPLE AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64") +# Disable 32-bit assembly warnings on arm64 platforms (Apple Silicon, Linux aarch64). +# CMSIS DSP contains ARM Cortex-M assembly that triggers clang warnings on 64-bit ARM. +# This code is unused on POSIX platforms - only the C fallback implementations run. +if(${PX4_PLATFORM} MATCHES "posix" AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64") add_compile_options(-Wno-asm-operand-widths) endif() diff --git a/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.cpp b/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.cpp index 33ab49eb32..0320870e08 100644 --- a/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.cpp +++ b/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.cpp @@ -108,36 +108,45 @@ void InternalCombustionEngineControl::Run() const hrt_abstime now = hrt_absolute_time(); - UserOnOffRequest user_request = UserOnOffRequest::Off; - switch (static_cast(_param_ice_on_source.get())) { case ICESource::ArmingState: { - if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) { - user_request = UserOnOffRequest::On; - } + _user_request = vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED ? UserOnOffRequest::On : + UserOnOffRequest::Off; } break; case ICESource::Aux1: { if (manual_control_setpoint.aux1 > 0.5f) { - user_request = UserOnOffRequest::On; + _user_request = UserOnOffRequest::On; + + } else if (manual_control_setpoint.aux1 < -0.5f) { + _user_request = UserOnOffRequest::Off; } } break; case ICESource::Aux2: { if (manual_control_setpoint.aux2 > 0.5f) { - user_request = UserOnOffRequest::On; + _user_request = UserOnOffRequest::On; + + } else if (manual_control_setpoint.aux2 < -0.5f) { + _user_request = UserOnOffRequest::Off; } } break; + + case ICESource::VtolStatus: { + _user_request = (vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING + || vehicle_status.in_transition_to_fw) ? UserOnOffRequest::On : UserOnOffRequest::Off; + } + break; } switch (_state) { case State::Stopped: { controlEngineStop(); - if (user_request == UserOnOffRequest::On && !maximumAttemptsReached()) { + if (_user_request == UserOnOffRequest::On && !maximumAttemptsReached()) { _state = State::Starting; _state_start_time = now; @@ -148,7 +157,7 @@ void InternalCombustionEngineControl::Run() case State::Starting: { - if (user_request == UserOnOffRequest::Off) { + if (_user_request == UserOnOffRequest::Off) { _state = State::Stopped; _starting_retry_cycle = 0; PX4_INFO("ICE: Stopped"); @@ -196,7 +205,7 @@ void InternalCombustionEngineControl::Run() case State::Running: { controlEngineRunning(throttle_in); - if (user_request == UserOnOffRequest::Off) { + if (_user_request == UserOnOffRequest::Off) { _state = State::Stopped; _starting_retry_cycle = 0; PX4_INFO("ICE: Stopped"); @@ -217,7 +226,7 @@ void InternalCombustionEngineControl::Run() case State::Fault: { - if (user_request == UserOnOffRequest::Off) { + if (_user_request == UserOnOffRequest::Off) { _state = State::Stopped; _starting_retry_cycle = 0; PX4_INFO("ICE: Stopped"); @@ -243,10 +252,10 @@ void InternalCombustionEngineControl::Run() _throttle_control_slew_rate.setForcedValue(0.f); } - publishControl(now, user_request); + publishControl(now); } -void InternalCombustionEngineControl::publishControl(const hrt_abstime now, const UserOnOffRequest user_request) +void InternalCombustionEngineControl::publishControl(const hrt_abstime now) { internal_combustion_engine_control_s ice_control{}; ice_control.timestamp = now; @@ -254,7 +263,7 @@ void InternalCombustionEngineControl::publishControl(const hrt_abstime now, cons ice_control.ignition_on = _ignition_on; ice_control.starter_engine_control = _starter_engine_control; ice_control.throttle_control = _throttle_control; - ice_control.user_request = static_cast(user_request); + ice_control.user_request = static_cast(_user_request); _internal_combustion_engine_control_pub.publish(ice_control); internal_combustion_engine_status_s ice_status; diff --git a/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.hpp b/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.hpp index 01884e4967..4b1cfedeb3 100644 --- a/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.hpp +++ b/src/modules/internal_combustion_engine_control/InternalCombustionEngineControl.hpp @@ -102,12 +102,13 @@ private: enum class UserOnOffRequest { Off, On - }; + } _user_request{UserOnOffRequest::Off}; enum class ICESource { ArmingState, Aux1, Aux2, + VtolStatus, }; hrt_abstime _state_start_time{0}; @@ -126,7 +127,7 @@ private: void controlEngineStartup(const hrt_abstime now); void controlEngineFault(); bool maximumAttemptsReached(); - void publishControl(const hrt_abstime now, const UserOnOffRequest user_request); + void publishControl(const hrt_abstime now); // Starting state specifics static constexpr float DELAY_BEFORE_RESTARTING{1.f}; diff --git a/src/modules/internal_combustion_engine_control/module.yaml b/src/modules/internal_combustion_engine_control/module.yaml index e0e9a69c57..4e3ca311cd 100644 --- a/src/modules/internal_combustion_engine_control/module.yaml +++ b/src/modules/internal_combustion_engine_control/module.yaml @@ -19,6 +19,7 @@ parameters: 0: On arming - disarming 1: Aux1 2: Aux2 + 3: On Vtol Transitions ICE_CHOKE_ST_DUR: description: diff --git a/src/modules/land_detector/FixedwingLandDetector.cpp b/src/modules/land_detector/FixedwingLandDetector.cpp index 0ca1523115..df7016f097 100644 --- a/src/modules/land_detector/FixedwingLandDetector.cpp +++ b/src/modules/land_detector/FixedwingLandDetector.cpp @@ -48,7 +48,6 @@ FixedwingLandDetector::FixedwingLandDetector() { // Use Trigger time when transitioning from in-air (false) to landed (true) / ground contact (true). _landed_hysteresis.set_hysteresis_time_from(false, _param_lndfw_trig_time.get() * 1_s); - _landed_hysteresis.set_hysteresis_time_from(true, FLYING_TRIGGER_TIME_US); } bool FixedwingLandDetector::_get_landed_state() @@ -58,18 +57,31 @@ bool FixedwingLandDetector::_get_landed_state() return true; } + // Force the landed state to stay landed if we're currently in an early state of the takeoff state machines. + // This prevents premature transitions to in-air during the early takeoff phase. + if (_landed_hysteresis.get_state()) { + launch_detection_status_s launch_detection_status{}; + _launch_detection_status_sub.copy(&launch_detection_status); + + fixed_wing_runway_control_s fixed_wing_runway_control{}; + _fixed_wing_runway_control_sub.copy(&fixed_wing_runway_control); + + // Check if we're in catapult/hand-launch waiting state + const bool waiting_for_catapult_launch = hrt_elapsed_time(&launch_detection_status.timestamp) < 500_ms + && launch_detection_status.launch_detection_state == launch_detection_status_s::STATE_WAITING_FOR_LAUNCH; + + // Check if we're in runway takeoff early phase (throttle ramp or clamped to runway) + const bool waiting_for_auto_runway_climbout = hrt_elapsed_time(&fixed_wing_runway_control.timestamp) < 500_ms + && fixed_wing_runway_control.runway_takeoff_state < fixed_wing_runway_control_s::STATE_CLIMBOUT; + + if (waiting_for_catapult_launch || waiting_for_auto_runway_climbout) { + return true; + } + } + bool landDetected = false; - launch_detection_status_s launch_detection_status{}; - _launch_detection_status_sub.copy(&launch_detection_status); - - // force the landed state to stay landed if we're currently in the catapult/hand-launch launch process. Detect that we are in this state - // by checking if the last publication of launch_detection_status is less than 0.5s old, and we're still in the wait for launch state. - if (_landed_hysteresis.get_state() && hrt_elapsed_time(&launch_detection_status.timestamp) < 500_ms - && launch_detection_status.launch_detection_state == launch_detection_status_s::STATE_WAITING_FOR_LAUNCH) { - landDetected = true; - - } else if (hrt_elapsed_time(&_vehicle_local_position.timestamp) < 1_s) { + if (hrt_elapsed_time(&_vehicle_local_position.timestamp) < 1_s) { float val = 0.0f; @@ -93,9 +105,9 @@ bool FixedwingLandDetector::_get_landed_state() airspeed_validated_s airspeed_validated{}; _airspeed_validated_sub.copy(&airspeed_validated); - const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_1 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_2 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_3; + const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_1 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_2 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_3; bool airspeed_invalid = false; diff --git a/src/modules/land_detector/FixedwingLandDetector.h b/src/modules/land_detector/FixedwingLandDetector.h index 3f3fa9ad35..2454b83f43 100644 --- a/src/modules/land_detector/FixedwingLandDetector.h +++ b/src/modules/land_detector/FixedwingLandDetector.h @@ -44,6 +44,7 @@ #include #include +#include #include #include "LandDetector.h" @@ -65,11 +66,9 @@ protected: void _set_hysteresis_factor(const int factor) override {}; private: - - static constexpr hrt_abstime FLYING_TRIGGER_TIME_US = 0_us; - uORB::Subscription _airspeed_validated_sub{ORB_ID(airspeed_validated)}; uORB::Subscription _launch_detection_status_sub{ORB_ID(launch_detection_status)}; + uORB::Subscription _fixed_wing_runway_control_sub{ORB_ID(fixed_wing_runway_control)}; float _airspeed_filtered{0.0f}; float _velocity_xy_filtered{0.0f}; diff --git a/src/modules/land_detector/RoverLandDetector.cpp b/src/modules/land_detector/RoverLandDetector.cpp index 90e7b4b7ef..78ee9ea9df 100644 --- a/src/modules/land_detector/RoverLandDetector.cpp +++ b/src/modules/land_detector/RoverLandDetector.cpp @@ -44,6 +44,11 @@ namespace land_detector { +RoverLandDetector::RoverLandDetector() +{ + _landed_hysteresis.set_hysteresis_time_from(true, 500_ms); +} + bool RoverLandDetector::_get_ground_contact_state() { return true; @@ -75,9 +80,4 @@ bool RoverLandDetector::_get_landed_state() return !_armed; // If we are armed we are not landed. } -void RoverLandDetector::_set_hysteresis_factor(const int factor) -{ - _landed_hysteresis.set_hysteresis_time_from(true, 500_ms); -} - } // namespace land_detector diff --git a/src/modules/land_detector/RoverLandDetector.h b/src/modules/land_detector/RoverLandDetector.h index 91e69e46e7..408fdb30cb 100644 --- a/src/modules/land_detector/RoverLandDetector.h +++ b/src/modules/land_detector/RoverLandDetector.h @@ -52,13 +52,13 @@ namespace land_detector class RoverLandDetector : public LandDetector { public: - RoverLandDetector() = default; + RoverLandDetector(); ~RoverLandDetector() override = default; protected: bool _get_ground_contact_state() override; bool _get_landed_state() override; - void _set_hysteresis_factor(const int factor) override; + void _set_hysteresis_factor(const int factor) override {}; private: uORB::Subscription _vehicle_global_position_sub{ORB_ID(vehicle_global_position)}; diff --git a/src/modules/logger/CMakeLists.txt b/src/modules/logger/CMakeLists.txt index c75622e1d7..b9ea444670 100644 --- a/src/modules/logger/CMakeLists.txt +++ b/src/modules/logger/CMakeLists.txt @@ -31,11 +31,20 @@ # ############################################################################ +set(LOGGER_MODULE_PARAMS) + +if(PX4_CRYPTO) + list(APPEND LOGGER_MODULE_PARAMS module_params_crypto.yaml) +endif() + px4_add_module( MODULE modules__logger MAIN logger PRIORITY "SCHED_PRIORITY_MAX-30" STACK_MAIN 2500 + MODULE_CONFIG + module.yaml + ${LOGGER_MODULE_PARAMS} COMPILE_FLAGS ${MAX_CUSTOM_OPT_LEVEL} -Wno-cast-align # TODO: fix and enable @@ -51,3 +60,5 @@ px4_add_module( version component_general_json # for checksums.h ) + +px4_add_unit_gtest(SRC ULogMessagesTest.cpp) diff --git a/src/modules/logger/ULogMessagesTest.cpp b/src/modules/logger/ULogMessagesTest.cpp new file mode 100644 index 0000000000..4e5f9d846c --- /dev/null +++ b/src/modules/logger/ULogMessagesTest.cpp @@ -0,0 +1,666 @@ +/**************************************************************************** + * + * Copyright (C) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include +#include "messages.h" + +// ---------------------------------------------------------------------------- +// Header & constants +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, HeaderLen) +{ + EXPECT_EQ(ULOG_MSG_HEADER_LEN, 3u); +} + +TEST(ULogMessages, MessageHeaderSize) +{ + EXPECT_EQ(sizeof(ulog_message_header_s), 3u); +} + +TEST(ULogMessages, MessageHeaderFieldOffsets) +{ + ulog_message_header_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.msg_size) - base, 0); + EXPECT_EQ(reinterpret_cast(&msg.msg_type) - base, 2); +} + +// ---------------------------------------------------------------------------- +// File header (16 bytes: 8 magic + 8 timestamp) +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, FileHeaderSize) +{ + EXPECT_EQ(sizeof(ulog_file_header_s), 16u); +} + +TEST(ULogMessages, FileHeaderMagic) +{ + ulog_file_header_s hdr = {}; + const uint8_t expected_magic[] = {'U', 'L', 'o', 'g', 0x01, 0x12, 0x35, 0x01}; + + memcpy(hdr.magic, expected_magic, sizeof(expected_magic)); + hdr.timestamp = 1000000ULL; + + EXPECT_EQ(memcmp(hdr.magic, expected_magic, 7), 0); + EXPECT_EQ(hdr.magic[7], 0x01); + EXPECT_EQ(hdr.timestamp, 1000000ULL); +} + +TEST(ULogMessages, FileHeaderFieldOffsets) +{ + ulog_file_header_s hdr = {}; + uint8_t *base = reinterpret_cast(&hdr); + + EXPECT_EQ(reinterpret_cast(&hdr.magic) - base, 0); + EXPECT_EQ(reinterpret_cast(&hdr.timestamp) - base, 8); +} + +// ---------------------------------------------------------------------------- +// Flag Bits ('B') — must be first message after header +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, FlagBitsSize) +{ + // payload: 8 compat + 8 incompat + 24 appended_offsets = 40 + EXPECT_EQ(sizeof(ulog_message_flag_bits_s), ULOG_MSG_HEADER_LEN + 40u); +} + +TEST(ULogMessages, FlagBitsTypeCode) +{ + ulog_message_flag_bits_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('B')); +} + +TEST(ULogMessages, FlagBitsFieldOffsets) +{ + ulog_message_flag_bits_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.compat_flags) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.incompat_flags) - base, ULOG_MSG_HEADER_LEN + 8); + EXPECT_EQ(reinterpret_cast(&msg.appended_offsets) - base, ULOG_MSG_HEADER_LEN + 16); +} + +TEST(ULogMessages, FlagBitsDataAppendedMask) +{ + EXPECT_EQ(ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK, 1 << 0); + EXPECT_EQ(ULOG_COMPAT_FLAG0_DEFAULT_PARAMETERS_MASK, 1 << 0); +} + +// ---------------------------------------------------------------------------- +// Format Definition ('F') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, FormatSize) +{ + EXPECT_EQ(sizeof(ulog_message_format_s), ULOG_MSG_HEADER_LEN + 1600u); +} + +TEST(ULogMessages, FormatTypeCode) +{ + ulog_message_format_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('F')); +} + +TEST(ULogMessages, FormatSerialization) +{ + ulog_message_format_s msg = {}; + const char *format_str = "test_topic:uint64_t timestamp;float value;"; + size_t len = strlen(format_str); + + strncpy(msg.format, format_str, sizeof(msg.format)); + msg.msg_size = len; + + EXPECT_EQ(msg.msg_size, len); + EXPECT_EQ(memcmp(msg.format, format_str, len), 0); +} + +// ---------------------------------------------------------------------------- +// Information ('I') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, InfoSize) +{ + // header(3) + key_len(1) + key_value_str(255) = 259 + EXPECT_EQ(sizeof(ulog_message_info_s), ULOG_MSG_HEADER_LEN + 1u + 255u); +} + +TEST(ULogMessages, InfoTypeCode) +{ + ulog_message_info_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('I')); +} + +TEST(ULogMessages, InfoStringLayout) +{ + const char *name = "hello"; + const char *value = "world"; + const size_t vlen = strlen(value); + + ulog_message_info_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + msg.msg_type = static_cast(ULogMessageType::INFO); + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "char[%zu] %s", vlen, name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + ASSERT_LT(vlen, sizeof(msg) - msg_size); + memcpy(&buffer[msg_size], value, vlen); + msg_size += vlen; + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + // msg_size == key_len_field(1) + key_len + vlen + EXPECT_EQ(msg.msg_size, msg.key_len + vlen + 1); + + const char expected_key[] = "char[5] hello"; + EXPECT_EQ(msg.key_len, strlen(expected_key)); + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + const uint8_t *value_start = &buffer[header_size + msg.key_len]; + EXPECT_EQ(memcmp(value_start, "world", vlen), 0); + + // no null terminator in msg_size + EXPECT_EQ(msg_size, header_size + msg.key_len + vlen); +} + +TEST(ULogMessages, InfoInt32Layout) +{ + const char *name = "sys_param"; + int32_t value = 42; + + ulog_message_info_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + msg.msg_type = static_cast(ULogMessageType::INFO); + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "int32_t %s", name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + ASSERT_LE(sizeof(value), sizeof(msg) - msg_size); + memcpy(&buffer[msg_size], &value, sizeof(value)); + msg_size += sizeof(value); + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + EXPECT_EQ(msg.msg_size, msg.key_len + sizeof(int32_t) + 1); + + const char expected_key[] = "int32_t sys_param"; + EXPECT_EQ(msg.key_len, strlen(expected_key)); + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + int32_t read_back = 0; + memcpy(&read_back, &buffer[header_size + msg.key_len], sizeof(int32_t)); + EXPECT_EQ(read_back, 42); +} + +TEST(ULogMessages, InfoFloatLayout) +{ + const char *name = "cal_offset"; + float value = 3.14f; + + ulog_message_info_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + msg.msg_type = static_cast(ULogMessageType::INFO); + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "float %s", name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + ASSERT_LE(sizeof(value), sizeof(msg) - msg_size); + memcpy(&buffer[msg_size], &value, sizeof(value)); + msg_size += sizeof(value); + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + EXPECT_EQ(msg.msg_size, msg.key_len + sizeof(float) + 1); + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + float read_back = 0.f; + memcpy(&read_back, &buffer[header_size + msg.key_len], sizeof(float)); + EXPECT_FLOAT_EQ(read_back, 3.14f); +} + +// ---------------------------------------------------------------------------- +// Information Multiple ('M') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, InfoMultipleSize) +{ + // header(3) + is_continued(1) + key_len(1) + key_value_str(1200) = 1205 + EXPECT_EQ(sizeof(ulog_message_info_multiple_s), ULOG_MSG_HEADER_LEN + 1u + 1u + 1200u); +} + +TEST(ULogMessages, InfoMultipleTypeCode) +{ + ulog_message_info_multiple_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('M')); +} + +TEST(ULogMessages, InfoMultipleStringLayout) +{ + const char *name = "ver"; + const char *value = "1.0"; + const size_t vlen = strlen(value); + + ulog_message_info_multiple_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + msg.msg_type = static_cast(ULogMessageType::INFO_MULTIPLE); + msg.is_continued = false; + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "char[%zu] %s", vlen, name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + ASSERT_LT(vlen, sizeof(msg) - msg_size); + memcpy(&buffer[msg_size], value, vlen); + msg_size += vlen; + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + EXPECT_EQ(msg.msg_size, msg_size - ULOG_MSG_HEADER_LEN); + EXPECT_EQ(msg.is_continued, 0); + + const char expected_key[] = "char[3] ver"; + EXPECT_EQ(msg.key_len, strlen(expected_key)); + + const uint8_t *value_start = &buffer[header_size + msg.key_len]; + EXPECT_EQ(memcmp(value_start, "1.0", vlen), 0); + + EXPECT_EQ(msg_size, header_size + msg.key_len + vlen); +} + +TEST(ULogMessages, InfoMultipleContinuation) +{ + ulog_message_info_multiple_s msg = {}; + msg.is_continued = 1; + + EXPECT_EQ(msg.is_continued, 1); + EXPECT_EQ(msg.msg_type, static_cast('M')); +} + +TEST(ULogMessages, InfoMultipleFieldOffsets) +{ + ulog_message_info_multiple_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.is_continued) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.key_len) - base, ULOG_MSG_HEADER_LEN + 1); + EXPECT_EQ(reinterpret_cast(&msg.key_value_str) - base, ULOG_MSG_HEADER_LEN + 2); +} + +// ---------------------------------------------------------------------------- +// Parameter ('P') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, ParameterSize) +{ + EXPECT_EQ(sizeof(ulog_message_parameter_s), ULOG_MSG_HEADER_LEN + 1u + 255u); +} + +TEST(ULogMessages, ParameterTypeCode) +{ + ulog_message_parameter_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('P')); +} + +TEST(ULogMessages, ParameterInt32Layout) +{ + const char *name = "SYS_AUTOSTART"; + int32_t value = 4001; + + ulog_message_parameter_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "int32_t %s", name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + memcpy(&buffer[msg_size], &value, sizeof(value)); + msg_size += sizeof(value); + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + EXPECT_EQ(msg.msg_size, msg.key_len + sizeof(int32_t) + 1); + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + int32_t read_back = 0; + memcpy(&read_back, &buffer[header_size + msg.key_len], sizeof(int32_t)); + EXPECT_EQ(read_back, 4001); +} + +TEST(ULogMessages, ParameterFloatLayout) +{ + const char *name = "MC_PITCHRATE_P"; + float value = 0.15f; + + ulog_message_parameter_s msg = {}; + uint8_t *buffer = reinterpret_cast(&msg); + + msg.key_len = snprintf(msg.key_value_str, sizeof(msg.key_value_str), + "float %s", name); + size_t msg_size = sizeof(msg) - sizeof(msg.key_value_str) + msg.key_len; + + memcpy(&buffer[msg_size], &value, sizeof(value)); + msg_size += sizeof(value); + + msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; + + const size_t header_size = sizeof(msg) - sizeof(msg.key_value_str); + float read_back = 0.f; + memcpy(&read_back, &buffer[header_size + msg.key_len], sizeof(float)); + EXPECT_FLOAT_EQ(read_back, 0.15f); +} + +// ---------------------------------------------------------------------------- +// Default Parameter ('Q') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, ParameterDefaultSize) +{ + // header(3) + default_types(1) + key_len(1) + key_value_str(255) = 260 + EXPECT_EQ(sizeof(ulog_message_parameter_default_s), ULOG_MSG_HEADER_LEN + 1u + 1u + 255u); +} + +TEST(ULogMessages, ParameterDefaultTypeCode) +{ + ulog_message_parameter_default_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('Q')); +} + +TEST(ULogMessages, ParameterDefaultTypeBits) +{ + EXPECT_EQ(static_cast(ulog_parameter_default_type_t::system), 1 << 0); + EXPECT_EQ(static_cast(ulog_parameter_default_type_t::current_setup), 1 << 1); + + auto combined = ulog_parameter_default_type_t::system | ulog_parameter_default_type_t::current_setup; + EXPECT_EQ(static_cast(combined), 0x03); +} + +TEST(ULogMessages, ParameterDefaultFieldOffsets) +{ + ulog_message_parameter_default_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.default_types) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.key_len) - base, ULOG_MSG_HEADER_LEN + 1); + EXPECT_EQ(reinterpret_cast(&msg.key_value_str) - base, ULOG_MSG_HEADER_LEN + 2); +} + +// ---------------------------------------------------------------------------- +// Subscription ('A') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, AddLoggedSize) +{ + // header(3) + multi_id(1) + msg_id(2) + message_name(255) = 261 + EXPECT_EQ(sizeof(ulog_message_add_logged_s), ULOG_MSG_HEADER_LEN + 1u + 2u + 255u); +} + +TEST(ULogMessages, AddLoggedTypeCode) +{ + ulog_message_add_logged_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('A')); +} + +TEST(ULogMessages, AddLoggedFieldOffsets) +{ + ulog_message_add_logged_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.multi_id) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.msg_id) - base, ULOG_MSG_HEADER_LEN + 1); + EXPECT_EQ(reinterpret_cast(&msg.message_name) - base, ULOG_MSG_HEADER_LEN + 3); +} + +TEST(ULogMessages, AddLoggedSerialization) +{ + ulog_message_add_logged_s msg = {}; + msg.multi_id = 0; + msg.msg_id = 7; + const char *topic = "sensor_accel"; + size_t len = strlen(topic); + + strncpy(msg.message_name, topic, sizeof(msg.message_name)); + msg.msg_size = sizeof(msg.multi_id) + sizeof(msg.msg_id) + len; + + EXPECT_EQ(msg.multi_id, 0); + EXPECT_EQ(msg.msg_id, 7); + EXPECT_EQ(memcmp(msg.message_name, "sensor_accel", len), 0); +} + +// ---------------------------------------------------------------------------- +// Unsubscription ('R') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, RemoveLoggedSize) +{ + // header(3) + msg_id(2) = 5 + EXPECT_EQ(sizeof(ulog_message_remove_logged_s), ULOG_MSG_HEADER_LEN + 2u); +} + +TEST(ULogMessages, RemoveLoggedTypeCode) +{ + ulog_message_remove_logged_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('R')); +} + +TEST(ULogMessages, RemoveLoggedSerialization) +{ + ulog_message_remove_logged_s msg = {}; + msg.msg_id = 42; + msg.msg_size = sizeof(msg.msg_id); + + EXPECT_EQ(msg.msg_id, 42); + EXPECT_EQ(msg.msg_size, 2); +} + +// ---------------------------------------------------------------------------- +// Logged Data ('D') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, DataSize) +{ + // header(3) + msg_id(2) = 5 (variable-length payload follows) + EXPECT_EQ(sizeof(ulog_message_data_s), ULOG_MSG_HEADER_LEN + 2u); +} + +TEST(ULogMessages, DataTypeCode) +{ + ulog_message_data_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('D')); +} + +TEST(ULogMessages, DataFieldOffset) +{ + ulog_message_data_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.msg_id) - base, ULOG_MSG_HEADER_LEN); +} + +// ---------------------------------------------------------------------------- +// Logging ('L') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, LoggingSize) +{ + // header(3) + log_level(1) + timestamp(8) + message(128) = 140 + EXPECT_EQ(sizeof(ulog_message_logging_s), ULOG_MSG_HEADER_LEN + 1u + 8u + 128u); +} + +TEST(ULogMessages, LoggingTypeCode) +{ + ulog_message_logging_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('L')); +} + +TEST(ULogMessages, LoggingFieldOffsets) +{ + ulog_message_logging_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.log_level) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.timestamp) - base, ULOG_MSG_HEADER_LEN + 1); + EXPECT_EQ(reinterpret_cast(&msg.message) - base, ULOG_MSG_HEADER_LEN + 9); +} + +TEST(ULogMessages, LoggingSerialization) +{ + ulog_message_logging_s msg = {}; + msg.log_level = 6; + msg.timestamp = 5000000ULL; + const char *text = "test message"; + size_t len = strlen(text); + + strncpy(msg.message, text, sizeof(msg.message)); + msg.msg_size = sizeof(msg.log_level) + sizeof(msg.timestamp) + len; + + EXPECT_EQ(msg.log_level, 6); + EXPECT_EQ(msg.timestamp, 5000000ULL); + EXPECT_EQ(memcmp(msg.message, "test message", len), 0); +} + +// ---------------------------------------------------------------------------- +// Logging Tagged ('C') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, LoggingTaggedSize) +{ + // header(3) + log_level(1) + tag(2) + timestamp(8) + message(128) = 142 + EXPECT_EQ(sizeof(ulog_message_logging_tagged_s), ULOG_MSG_HEADER_LEN + 1u + 2u + 8u + 128u); +} + +TEST(ULogMessages, LoggingTaggedTypeCode) +{ + ulog_message_logging_tagged_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('C')); +} + +TEST(ULogMessages, LoggingTaggedFieldOffsets) +{ + ulog_message_logging_tagged_s msg = {}; + uint8_t *base = reinterpret_cast(&msg); + + EXPECT_EQ(reinterpret_cast(&msg.log_level) - base, ULOG_MSG_HEADER_LEN); + EXPECT_EQ(reinterpret_cast(&msg.tag) - base, ULOG_MSG_HEADER_LEN + 1); + EXPECT_EQ(reinterpret_cast(&msg.timestamp) - base, ULOG_MSG_HEADER_LEN + 3); + EXPECT_EQ(reinterpret_cast(&msg.message) - base, ULOG_MSG_HEADER_LEN + 11); +} + +// ---------------------------------------------------------------------------- +// Sync ('S') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, SyncSize) +{ + // header(3) + sync_magic(8) = 11 + EXPECT_EQ(sizeof(ulog_message_sync_s), ULOG_MSG_HEADER_LEN + 8u); +} + +TEST(ULogMessages, SyncTypeCode) +{ + ulog_message_sync_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('S')); +} + +TEST(ULogMessages, SyncMagicBytes) +{ + ulog_message_sync_s msg = {}; + const uint8_t expected_magic[] = {0x2F, 0x73, 0x13, 0x20, 0x25, 0x0C, 0xBB, 0x12}; + + memcpy(msg.sync_magic, expected_magic, sizeof(expected_magic)); + msg.msg_size = sizeof(msg.sync_magic); + + EXPECT_EQ(memcmp(msg.sync_magic, expected_magic, 8), 0); + EXPECT_EQ(msg.msg_size, 8); +} + +// ---------------------------------------------------------------------------- +// Dropout ('O') +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, DropoutSize) +{ + // header(3) + duration(2) = 5 + EXPECT_EQ(sizeof(ulog_message_dropout_s), ULOG_MSG_HEADER_LEN + 2u); +} + +TEST(ULogMessages, DropoutTypeCode) +{ + ulog_message_dropout_s msg = {}; + EXPECT_EQ(msg.msg_type, static_cast('O')); +} + +TEST(ULogMessages, DropoutDefaultMsgSize) +{ + ulog_message_dropout_s msg = {}; + EXPECT_EQ(msg.msg_size, sizeof(uint16_t)); +} + +TEST(ULogMessages, DropoutSerialization) +{ + ulog_message_dropout_s msg = {}; + msg.duration = 150; + + EXPECT_EQ(msg.duration, 150); + EXPECT_EQ(msg.msg_size, sizeof(uint16_t)); +} + +// ---------------------------------------------------------------------------- +// ULogMessageType enum values +// ---------------------------------------------------------------------------- + +TEST(ULogMessages, TypeEnumValues) +{ + EXPECT_EQ(static_cast(ULogMessageType::FORMAT), 'F'); + EXPECT_EQ(static_cast(ULogMessageType::DATA), 'D'); + EXPECT_EQ(static_cast(ULogMessageType::INFO), 'I'); + EXPECT_EQ(static_cast(ULogMessageType::INFO_MULTIPLE), 'M'); + EXPECT_EQ(static_cast(ULogMessageType::PARAMETER), 'P'); + EXPECT_EQ(static_cast(ULogMessageType::PARAMETER_DEFAULT), 'Q'); + EXPECT_EQ(static_cast(ULogMessageType::ADD_LOGGED_MSG), 'A'); + EXPECT_EQ(static_cast(ULogMessageType::REMOVE_LOGGED_MSG), 'R'); + EXPECT_EQ(static_cast(ULogMessageType::SYNC), 'S'); + EXPECT_EQ(static_cast(ULogMessageType::DROPOUT), 'O'); + EXPECT_EQ(static_cast(ULogMessageType::LOGGING), 'L'); + EXPECT_EQ(static_cast(ULogMessageType::LOGGING_TAGGED), 'C'); + EXPECT_EQ(static_cast(ULogMessageType::FLAG_BITS), 'B'); +} diff --git a/src/modules/logger/log_writer.h b/src/modules/logger/log_writer.h index 32fdea46df..a28132d6bd 100644 --- a/src/modules/logger/log_writer.h +++ b/src/modules/logger/log_writer.h @@ -173,7 +173,8 @@ public: { if (_log_writer_file) { _log_writer_file->set_encryption_parameters(algorithm, key_idx, exchange_key_idx); } } -#endif +#endif // PX4_CRYPTO + private: LogWriterFile *_log_writer_file = nullptr; diff --git a/src/modules/logger/log_writer_file.cpp b/src/modules/logger/log_writer_file.cpp index 530076f49b..1ec37cf73e 100644 --- a/src/modules/logger/log_writer_file.cpp +++ b/src/modules/logger/log_writer_file.cpp @@ -40,9 +40,12 @@ #include #include -#include #include +#if defined(PX4_CRYPTO) +# include +#endif // PX4_CRYPTO + #if defined(__PX4_NUTTX) # include # include @@ -288,7 +291,11 @@ int LogWriterFile::thread_start() param.sched_priority = SCHED_PRIORITY_DEFAULT - 40; (void)pthread_attr_setschedparam(&thr_attr, ¶m); +#ifdef CONFIG_FS_LITTLEFS + pthread_attr_setstacksize(&thr_attr, PX4_STACK_ADJUSTED(1800)); /* littlefs needs more stack */ +#else pthread_attr_setstacksize(&thr_attr, PX4_STACK_ADJUSTED(1170)); +#endif int ret = pthread_create(&_thread, &thr_attr, &LogWriterFile::run_helper, this); pthread_attr_destroy(&thr_attr); @@ -378,7 +385,7 @@ void LogWriterFile::run() #if defined(PX4_CRYPTO) // Split into min blocksize chunks, so it is good for encrypting in pieces available = (available / _min_blocksize) * _min_blocksize; -#endif +#endif // PX4_CRYPTO /* if sufficient data available or partial read or terminating, write data */ if (available >= min_available[i] || is_part || (!buffer._should_run && available > 0)) { @@ -408,7 +415,7 @@ void LogWriterFile::run() } } -#endif +#endif // PX4_CRYPTO int written = buffer.write_to_file(read_ptr, available, call_fsync); @@ -469,7 +476,7 @@ void LogWriterFile::run() /* close the crypto session */ _crypto.close(); -#endif +#endif // PX4_CRYPTO break; } diff --git a/src/modules/logger/log_writer_file.h b/src/modules/logger/log_writer_file.h index 4739b5b799..8b99e002d9 100644 --- a/src/modules/logger/log_writer_file.h +++ b/src/modules/logger/log_writer_file.h @@ -39,7 +39,10 @@ #include #include #include -#include + +#if defined(PX4_CRYPTO) +# include +#endif // PX4_CRYPTO namespace px4 { @@ -143,7 +146,7 @@ public: _key_idx = key_idx; _exchange_key_idx = exchange_key_idx; } -#endif +#endif // PX4_CRYPTO private: static void *run_helper(void *); @@ -223,6 +226,7 @@ private: pthread_mutex_t _mtx; pthread_cond_t _cv; pthread_t _thread = 0; + #if defined(PX4_CRYPTO) bool init_logfile_encryption(const LogType type); PX4Crypto _crypto; @@ -230,7 +234,7 @@ private: px4_crypto_algorithm_t _algorithm; uint8_t _key_idx; uint8_t _exchange_key_idx; -#endif +#endif // PX4_CRYPTO }; diff --git a/src/modules/logger/logged_topics.cpp b/src/modules/logger/logged_topics.cpp index 38d6074d53..5e366273d3 100644 --- a/src/modules/logger/logged_topics.cpp +++ b/src/modules/logger/logged_topics.cpp @@ -51,7 +51,7 @@ void LoggedTopics::add_default_topics() add_topic("airspeed", 1000); add_optional_topic("airspeed_validated", 200); add_optional_topic("autotune_attitude_control_status", 100); - add_topic_multi("battery_info", 5000, 2); + add_topic_multi("battery_info", 5000, 3); add_optional_topic("camera_capture"); add_optional_topic("camera_trigger"); add_topic("cellular_status", 200); @@ -59,11 +59,11 @@ void LoggedTopics::add_default_topics() add_topic("config_overrides"); add_topic("cpuload"); add_topic("distance_sensor_mode_change_request"); + add_topic("device_information", 900); add_topic_multi("dronecan_node_status", 250); add_optional_topic("external_ins_attitude"); add_optional_topic("external_ins_global_position"); add_optional_topic("external_ins_local_position"); - // add_optional_topic("esc_status", 250); add_topic("esc_status"); add_topic("failure_detector_status", 100); add_topic("failsafe_flags"); @@ -73,9 +73,10 @@ void LoggedTopics::add_default_topics() add_optional_topic("flaps_setpoint", 1000); add_optional_topic("flight_phase_estimation", 1000); add_optional_topic("fuel_tank_status", 10); + add_optional_topic("gain_compression", 100); add_topic("gimbal_manager_set_attitude", 500); add_optional_topic("generator_status"); - add_optional_topic("gps_dump"); + add_topic("gps_dump"); add_optional_topic("gimbal_controls", 200); add_optional_topic("gripper"); add_optional_topic("heater_status"); @@ -90,6 +91,7 @@ void LoggedTopics::add_default_topics() add_optional_topic("landing_gear_wheel", 100); add_optional_topic("landing_target_pose", 1000); add_optional_topic("launch_detection_status", 200); + add_topic("logger_status", 200); add_optional_topic("magnetometer_bias_estimate", 200); add_topic("manual_control_setpoint", 200); add_topic("manual_control_switches"); @@ -148,6 +150,7 @@ void LoggedTopics::add_default_topics() add_topic("vehicle_rates_setpoint", 20); add_topic("vehicle_roi", 1000); add_topic("vehicle_status"); + add_topic("vtx"); add_optional_topic("vtol_vehicle_status", 200); add_topic("wind", 1000); add_topic("fixed_wing_lateral_setpoint"); @@ -164,6 +167,7 @@ void LoggedTopics::add_default_topics() add_optional_topic_multi("control_allocator_status", 200, 2); add_optional_topic_multi("rate_ctrl_status", 200, 2); add_optional_topic_multi("sensor_hygrometer", 500, 4); + add_optional_topic_multi("sensor_temp", 100, 4); add_optional_topic_multi("rpm", 200); add_topic_multi("timesync_status", 1000, 3); add_optional_topic_multi("telemetry_status", 1000, 4); @@ -195,7 +199,7 @@ void LoggedTopics::add_default_topics() add_topic_multi("differential_pressure", 1000, 2); add_topic_multi("distance_sensor", 1000, 2); add_optional_topic_multi("sensor_accel", 1000, 4); - add_optional_topic_multi("sensor_baro", 1000, 4); + add_topic_multi("sensor_baro", 1000, 4); add_topic_multi("sensor_gps", 1000, 2); add_topic_multi("sensor_gnss_relative", 1000, 1); add_optional_topic_multi("sensor_gyro", 1000, 4); @@ -207,7 +211,6 @@ void LoggedTopics::add_default_topics() add_optional_topic_multi("vehicle_magnetometer", 500, 4); add_topic("vehicle_optical_flow", 500); add_topic("aux_global_position", 500); - //add_optional_topic("vehicle_optical_flow_vel", 100); add_optional_topic("pps_capture"); // additional control allocation logging diff --git a/src/modules/logger/logger.cpp b/src/modules/logger/logger.cpp index 99ec75898c..7e65cf448c 100644 --- a/src/modules/logger/logger.cpp +++ b/src/modules/logger/logger.cpp @@ -1310,7 +1310,7 @@ int Logger::get_log_file_name(LogType type, char *file_name, size_t file_name_si crypto_suffix = "e"; } -#endif +#endif // PX4_CRYPTO char *log_file_name = _file_name[(int)type].log_file_name; @@ -1419,7 +1419,7 @@ void Logger::start_log_file(LogType type) (px4_crypto_algorithm_t)_param_sdlog_crypto_algorithm.get(), _param_sdlog_crypto_key.get(), _param_sdlog_crypto_exchange_key.get()); -#endif +#endif // PX4_CRYPTO if (_writer.start_log_file(type, file_name)) { _writer.select_write_backend(LogWriter::BackendFile); @@ -1714,8 +1714,8 @@ void Logger::write_formats(LogType type) formats_to_write.set(_event_subscription.get_topic()->o_id); - - static_assert(sizeof(msg.format) > uORB::orb_tokenized_fields_max_length, "uORB message definition too long"); + // Due to leftover_length we need to add 150 bytes of margin, measured empirically + static_assert(sizeof(msg.format) > (uORB::orb_untokenized_fields_max_length + 150u), "uORB message definition too long"); uORB::MessageFormatReader format_reader(msg.format, sizeof(msg.format)); bool done = false; @@ -1890,7 +1890,7 @@ void Logger::write_info(LogType type, const char *name, const char *value) /* copy string value directly to buffer */ if (vlen < (sizeof(msg) - msg_size)) { - memcpy(&buffer[msg_size], value, vlen); + memcpy(&buffer[msg_size], value, vlen + 1); msg_size += vlen; msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; @@ -1916,7 +1916,7 @@ void Logger::write_info_multiple(LogType type, const char *name, const char *val /* copy string value directly to buffer */ if (vlen < (sizeof(msg) - msg_size)) { - memcpy(&buffer[msg_size], value, vlen); + memcpy(&buffer[msg_size], value, vlen + 1); msg_size += vlen; msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN; @@ -1990,6 +1990,11 @@ void Logger::write_info(LogType type, const char *name, uint32_t value) write_info_template(type, name, value, "uint32_t"); } +void Logger::write_info(LogType type, const char *name, uint64_t value) +{ + write_info_template(type, name, value, "uint64_t"); +} + template void Logger::write_info_template(LogType type, const char *name, T value, const char *type_str) @@ -2122,6 +2127,12 @@ void Logger::write_version(LogType type) write_info(type, "time_ref_utc", _param_sdlog_utc_offset.get() * 60); + uint64_t boot_time_utc_us; + + if (util::get_log_time(boot_time_utc_us, _param_sdlog_utc_offset.get() * 60, true)) { + write_info(type, "boot_time_utc_us", boot_time_utc_us); + } + if (_replay_file_name) { write_info(type, "replay", _replay_file_name); } diff --git a/src/modules/logger/logger.h b/src/modules/logger/logger.h index 44499c71b5..673ee8756a 100644 --- a/src/modules/logger/logger.h +++ b/src/modules/logger/logger.h @@ -267,6 +267,7 @@ private: void write_info_multiple(LogType type, const char *name, int fd); void write_info(LogType type, const char *name, int32_t value); void write_info(LogType type, const char *name, uint32_t value); + void write_info(LogType type, const char *name, uint64_t value); /** generic common template method for write_info variants */ template @@ -402,7 +403,7 @@ private: , (ParamInt) _param_sdlog_crypto_algorithm, (ParamInt) _param_sdlog_crypto_key, (ParamInt) _param_sdlog_crypto_exchange_key -#endif +#endif // PX4_CRYPTO ) }; diff --git a/src/modules/logger/module.yaml b/src/modules/logger/module.yaml new file mode 100644 index 0000000000..e1984c89a7 --- /dev/null +++ b/src/modules/logger/module.yaml @@ -0,0 +1,124 @@ +module_name: logger +parameters: +- group: SD Logging + definitions: + SDLOG_UTC_OFFSET: + description: + short: 'UTC offset (unit: min)' + long: the difference in hours and minutes from Coordinated Universal Time + (UTC) for a your place and date. for example, In case of South Korea(UTC+09:00), + UTC offset is 540 min (9*60) refer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets + type: int32 + default: 0 + unit: min + min: -1000 + max: 1000 + SDLOG_MODE: + description: + short: Logging Mode + long: 'Determines when to start and stop logging. By default, logging is started + when arming the system, and stopped when disarming. Note: The logging start/end + points that can be configured here only apply to SD logging. The mavlink + backend is started/stopped independently of these points.' + type: enum + values: + 0: when armed until disarm (default) + 1: from boot until disarm + 2: from boot until shutdown + 3: while manual input AUX1 >30% + 4: from 1st armed until shutdown + default: 0 + reboot_required: true + SDLOG_BACKEND: + description: + short: Logging Backend (integer bitmask) + long: 'If no logging is set the logger will not be started. Set bits true + to enable: 0: SD card logging 1: Mavlink logging' + type: bitmask + bit: + 0: SD card logging + 1: Mavlink logging + default: 3 + min: 0 + max: 3 + reboot_required: true + SDLOG_BOOT_BAT: + description: + short: Battery-only Logging + long: When enabled, logging will not start from boot if battery power is not + detected (e.g. powered via USB on a test bench). This prevents extraneous + flight logs from being created during bench testing. Note that this only + applies to log-from-boot modes. This has no effect on arm-based modes. + type: boolean + default: 0 + SDLOG_MISSION: + description: + short: Mission Log + long: If enabled, a small additional "mission" log file will be written to + the SD card. The log contains just those messages that are useful for tasks + like generating flight statistics and geotagging. The different modes can + be used to further reduce the logged data (and thus the log file size). + For example, choose geotagging mode to only log data required for geotagging. + Note that the normal/full log is still created, and contains all the data + in the mission log (and more). + type: enum + values: + 0: Disabled + 1: All mission messages + 2: Geotagging messages + default: 0 + reboot_required: true + SDLOG_PROFILE: + description: + short: Logging topic profile (integer bitmask) + long: 'This integer bitmask controls the set and rates of logged topics. The + default allows for general log analysis while keeping the log file size + reasonably small. Enabling multiple sets leads to higher bandwidth requirements + and larger log files. Set bits true to enable: 0 : Default set (used for + general log analysis) 1 : Full rate estimator (EKF2) replay topics 2 : Topics + for thermal calibration (high rate raw IMU and Baro sensor data) 3 : Topics + for system identification (high rate actuator control and IMU data) 4 : + Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators) + 5 : Debugging topics (debug_*.msg topics, for custom code) 6 : Topics for + sensor comparison (low rate raw IMU, Baro and magnetometer data) 7 : Topics + for computer vision and collision prevention 8 : Raw FIFO high-rate IMU + (Gyro) 9 : Raw FIFO high-rate IMU (Accel) 10: Logging of mavlink tunnel + message (useful for payload communication debugging)' + type: bitmask + bit: + 0: Default set (general log analysis) + 1: Estimator replay (EKF2) + 2: Thermal calibration + 3: System identification + 4: High rate + 5: Debug + 6: Sensor comparison + 7: Computer Vision and Avoidance + 8: Raw FIFO high-rate IMU (Gyro) + 9: Raw FIFO high-rate IMU (Accel) + 10: Mavlink tunnel message logging + 11: High rate sensors + default: 1 + min: 0 + max: 4095 + reboot_required: true + SDLOG_DIRS_MAX: + description: + short: Maximum number of log directories to keep + long: 'If there are more log directories than this value, the system will + delete the oldest directories during startup. In addition, the system will + delete old logs if there is not enough free space left. The minimum amount + is 300 MB. If this is set to 0, old directories will only be removed if + the free space falls below the minimum. Note: this does not apply to mission + log files.' + type: int32 + default: 0 + min: 0 + max: 1000 + reboot_required: true + SDLOG_UUID: + description: + short: Log UUID + long: If set to 1, add an ID to the log, which uniquely identifies the vehicle + type: boolean + default: 1 diff --git a/src/modules/logger/module_params_crypto.yaml b/src/modules/logger/module_params_crypto.yaml new file mode 100644 index 0000000000..b3eae7243f --- /dev/null +++ b/src/modules/logger/module_params_crypto.yaml @@ -0,0 +1,36 @@ +module_name: logger +parameters: +- group: SD Logging + definitions: + SDLOG_ALGORITHM: + description: + short: Logfile Encryption algorithm + long: Selects the algorithm used for logfile encryption + type: enum + values: + 0: Disabled + 2: XChaCha20 + default: 2 + SDLOG_KEY: + description: + short: Logfile Encryption key index + long: Selects the key in keystore, used for encrypting the log. When using + a symmetric encryption algorithm, the key is generated at logging start + and kept stored in this index. For symmetric algorithms, the key is volatile + and valid only for the duration of logging. The key is stored in encrypted + format on the sdcard alongside the logfile, using an RSA2048 key defined + by the SDLOG_EXCHANGE_KEY + type: int32 + default: 2 + min: 0 + max: 255 + SDLOG_EXCH_KEY: + description: + short: Logfile Encryption key exchange key + long: If the logfile is encrypted using a symmetric key algorithm, the used + encryption key is generated at logging start and stored on the sdcard RSA2048 + encrypted using this key. + type: int32 + default: 1 + min: 0 + max: 255 diff --git a/src/modules/logger/params.c b/src/modules/logger/params.c deleted file mode 100644 index 97eafb2cac..0000000000 --- a/src/modules/logger/params.c +++ /dev/null @@ -1,244 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2012-2016 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * UTC offset (unit: min) - * - * the difference in hours and minutes from Coordinated - * Universal Time (UTC) for a your place and date. - * - * for example, In case of South Korea(UTC+09:00), - * UTC offset is 540 min (9*60) - * - * refer to https://en.wikipedia.org/wiki/List_of_UTC_time_offsets - * - * @unit min - * @min -1000 - * @max 1000 - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_UTC_OFFSET, 0); - -/** - * Logging Mode - * - * Determines when to start and stop logging. By default, logging is started - * when arming the system, and stopped when disarming. - * - * Note: The logging start/end points that can be configured here only apply to - * SD logging. The mavlink backend is started/stopped independently - * of these points. - * - * @value 0 when armed until disarm (default) - * @value 1 from boot until disarm - * @value 2 from boot until shutdown - * @value 3 while manual input AUX1 >30% - * @value 4 from 1st armed until shutdown - * - * @reboot_required true - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_MODE, 0); - -/** - * Logging Backend (integer bitmask). - * - * If no logging is set the logger will not be started. - * - * Set bits true to enable: - * 0: SD card logging - * 1: Mavlink logging - * - * @min 0 - * @max 3 - * @bit 0 SD card logging - * @bit 1 Mavlink logging - * - * @reboot_required true - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_BACKEND, 3); - -/** - * Battery-only Logging - * - * When enabled, logging will not start from boot if battery power is not detected - * (e.g. powered via USB on a test bench). This prevents extraneous flight logs from - * being created during bench testing. - * - * Note that this only applies to log-from-boot modes. This has no effect on arm-based - * modes. - * - * @boolean - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_BOOT_BAT, 0); - -/** - * Mission Log - * - * If enabled, a small additional "mission" log file will be written to the SD card. - * The log contains just those messages that are useful for tasks like - * generating flight statistics and geotagging. - * - * The different modes can be used to further reduce the logged data - * (and thus the log file size). For example, choose geotagging mode to - * only log data required for geotagging. - - * Note that the normal/full log is still created, and contains all - * the data in the mission log (and more). - * - * @value 0 Disabled - * @value 1 All mission messages - * @value 2 Geotagging messages - * - * @reboot_required true - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_MISSION, 0); - -/** - * Logging topic profile (integer bitmask). - * - * This integer bitmask controls the set and rates of logged topics. - * The default allows for general log analysis while keeping the - * log file size reasonably small. - * - * Enabling multiple sets leads to higher bandwidth requirements and larger log - * files. - * - * Set bits true to enable: - * 0 : Default set (used for general log analysis) - * 1 : Full rate estimator (EKF2) replay topics - * 2 : Topics for thermal calibration (high rate raw IMU and Baro sensor data) - * 3 : Topics for system identification (high rate actuator control and IMU data) - * 4 : Full rates for analysis of fast maneuvers (RC, attitude, rates and actuators) - * 5 : Debugging topics (debug_*.msg topics, for custom code) - * 6 : Topics for sensor comparison (low rate raw IMU, Baro and magnetometer data) - * 7 : Topics for computer vision and collision prevention - * 8 : Raw FIFO high-rate IMU (Gyro) - * 9 : Raw FIFO high-rate IMU (Accel) - * 10: Logging of mavlink tunnel message (useful for payload communication debugging) - * - * @min 0 - * @max 4095 - * @bit 0 Default set (general log analysis) - * @bit 1 Estimator replay (EKF2) - * @bit 2 Thermal calibration - * @bit 3 System identification - * @bit 4 High rate - * @bit 5 Debug - * @bit 6 Sensor comparison - * @bit 7 Computer Vision and Avoidance - * @bit 8 Raw FIFO high-rate IMU (Gyro) - * @bit 9 Raw FIFO high-rate IMU (Accel) - * @bit 10 Mavlink tunnel message logging - * @bit 11 High rate sensors - * @reboot_required true - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_PROFILE, 1); - -/** - * Maximum number of log directories to keep - * - * If there are more log directories than this value, - * the system will delete the oldest directories during startup. - * - * In addition, the system will delete old logs if there is not enough free space left. - * The minimum amount is 300 MB. - * - * If this is set to 0, old directories will only be removed if the free space falls below - * the minimum. - * - * Note: this does not apply to mission log files. - * - * @min 0 - * @max 1000 - * @reboot_required true - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_DIRS_MAX, 0); - -/** - * Log UUID - * - * If set to 1, add an ID to the log, which uniquely identifies the vehicle - * - * @boolean - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_UUID, 1); - -/** - * Logfile Encryption algorithm - * - * Selects the algorithm used for logfile encryption - * - * @value 0 Disabled - * @value 2 XChaCha20 - * - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_ALGORITHM, 2); - -/** - * Logfile Encryption key index - * - * Selects the key in keystore, used for encrypting the log. When using - * a symmetric encryption algorithm, the key is generated at logging start - * and kept stored in this index. For symmetric algorithms, the key is - * volatile and valid only for the duration of logging. The key is stored - * in encrypted format on the sdcard alongside the logfile, using an RSA2048 - * key defined by the SDLOG_EXCHANGE_KEY - * - * @min 0 - * @max 255 - * - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_KEY, 2); - -/** - * Logfile Encryption key exchange key - * - * If the logfile is encrypted using a symmetric key algorithm, - * the used encryption key is generated at logging start and stored - * on the sdcard RSA2048 encrypted using this key. - * - * @min 0 - * @max 255 - * - * @group SD Logging - */ -PARAM_DEFINE_INT32(SDLOG_EXCH_KEY, 1); diff --git a/src/modules/logger/util.cpp b/src/modules/logger/util.cpp index efff34af6a..5fdd576bcf 100644 --- a/src/modules/logger/util.cpp +++ b/src/modules/logger/util.cpp @@ -72,20 +72,19 @@ bool file_exist(const char *filename) return stat(filename, &buffer) == 0; } -bool get_log_time(struct tm *tt, int utc_offset_sec, bool boot_time) +bool get_log_time(uint64_t &utc_time_usec, int utc_offset_sec, bool boot_time) { uORB::Subscription vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; - time_t utc_time_sec; bool use_clock_time = true; /* Get the latest GPS publication */ sensor_gps_s gps_pos; if (vehicle_gps_position_sub.copy(&gps_pos)) { - utc_time_sec = gps_pos.time_utc_usec / 1e6; + utc_time_usec = gps_pos.time_utc_usec; - if (gps_pos.fix_type >= 2 && utc_time_sec >= GPS_EPOCH_SECS) { + if (gps_pos.fix_type >= 2 && utc_time_usec >= (uint64_t) GPS_EPOCH_SECS * 1000000ULL) { use_clock_time = false; } } @@ -94,22 +93,30 @@ bool get_log_time(struct tm *tt, int utc_offset_sec, bool boot_time) /* take clock time if there's no fix (yet) */ struct timespec ts = {}; px4_clock_gettime(CLOCK_REALTIME, &ts); - utc_time_sec = ts.tv_sec + (ts.tv_nsec / 1e9); + utc_time_usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL; - if (utc_time_sec < GPS_EPOCH_SECS) { + if (utc_time_usec < (uint64_t) GPS_EPOCH_SECS * 1000000ULL) { return false; } } /* strip the time elapsed since boot */ if (boot_time) { - utc_time_sec -= hrt_absolute_time() / 1e6; + utc_time_usec -= hrt_absolute_time(); } /* apply utc offset */ - utc_time_sec += utc_offset_sec; + utc_time_usec += (int64_t) utc_offset_sec * 1000000LL; - return gmtime_r(&utc_time_sec, tt) != nullptr; + return true; +} + +bool get_log_time(struct tm *tt, int utc_offset_sec, bool boot_time) +{ + uint64_t utc_time_usec; + bool result = get_log_time(utc_time_usec, utc_offset_sec, boot_time); + time_t utc_time_sec = static_cast(utc_time_usec / 1000000ULL); + return result && gmtime_r(&utc_time_sec, tt) != nullptr; } int check_free_space(const char *log_root_dir, int32_t max_log_dirs_to_keep, orb_advert_t &mavlink_log_pub, diff --git a/src/modules/logger/util.h b/src/modules/logger/util.h index 535815c7fb..f2939b0794 100644 --- a/src/modules/logger/util.h +++ b/src/modules/logger/util.h @@ -75,6 +75,16 @@ bool file_exist(const char *filename); int check_free_space(const char *log_root_dir, int32_t max_log_dirs_to_keep, orb_advert_t &mavlink_log_pub, int &sess_dir_index); + +/** + * Utility for fetching UTC time in microseconds from sensor_gps or CLOCK_REALTIME + * @param utc_time_usec returned microseconds + * @param utc_offset_sec UTC time offset [s] + * @param boot_time use time when booted instead of current time + * @return true on success, false otherwise (eg. if no gps) + */ +bool get_log_time(uint64_t &utc_time_usec, int utc_offset_sec, bool boot_time); + /** * Get the time for log file name * @param tt returned time diff --git a/src/modules/manual_control/ManualControl.cpp b/src/modules/manual_control/ManualControl.cpp index 082b2ccaa3..759088524a 100644 --- a/src/modules/manual_control/ManualControl.cpp +++ b/src/modules/manual_control/ManualControl.cpp @@ -52,6 +52,15 @@ ManualControl::~ManualControl() bool ManualControl::init() { +#if defined(PAYLOAD_POWER_EN) + + // If the payload power switch is mapped, default to power off until the RC switch explicitly commands it on. + if (_param_rc_map_pay_sw.get()) { + PAYLOAD_POWER_EN(false); + } + +#endif // PAYLOAD_POWER_EN + ScheduleNow(); return true; } @@ -293,6 +302,18 @@ void ManualControl::processSwitches(hrt_abstime &now) } else if (!_armed) { // Directly initialize mode using RC switch but only before arming evaluateModeSlot(switches.mode_slot); +#if defined(PAYLOAD_POWER_EN) + + // Apply payload power state on first switch receipt if not armed + if (switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_ON) { + PAYLOAD_POWER_EN(true); + + } else if (switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_OFF + || switches.payload_power_switch == manual_control_switches_s::SWITCH_POS_MIDDLE) { + PAYLOAD_POWER_EN(false); + } + +#endif // PAYLOAD_POWER_EN } _previous_switches = switches; @@ -309,9 +330,9 @@ void ManualControl::updateParams() { ModuleParams::updateParams(); - _stick_arm_hysteresis.set_hysteresis_time_from(false, _param_com_rc_arm_hyst.get() * 1_ms); - _stick_disarm_hysteresis.set_hysteresis_time_from(false, _param_com_rc_arm_hyst.get() * 1_ms); - _button_arm_hysteresis.set_hysteresis_time_from(false, _param_com_rc_arm_hyst.get() * 1_ms); + _stick_arm_hysteresis.set_hysteresis_time_from(false, 1_s); + _stick_disarm_hysteresis.set_hysteresis_time_from(false, 1_s); + _button_arm_hysteresis.set_hysteresis_time_from(false, 1_s); _stick_kill_hysteresis.set_hysteresis_time_from(false, _param_man_kill_gest_t.get() * 1_s); _selector.setRcInMode(_param_com_rc_in_mode.get()); @@ -590,6 +611,7 @@ int8_t ManualControl::navStateFromParam(int32_t param_value) case 13: return vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND; case 14: return vehicle_status_s::NAVIGATION_STATE_ORBIT; case 15: return vehicle_status_s::NAVIGATION_STATE_AUTO_VTOL_TAKEOFF; + case 16: return vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE; case 100: return vehicle_status_s::NAVIGATION_STATE_EXTERNAL1; case 101: return vehicle_status_s::NAVIGATION_STATE_EXTERNAL2; diff --git a/src/modules/manual_control/ManualControl.hpp b/src/modules/manual_control/ManualControl.hpp index 660a125665..fd01cbdab0 100644 --- a/src/modules/manual_control/ManualControl.hpp +++ b/src/modules/manual_control/ManualControl.hpp @@ -148,8 +148,8 @@ private: (ParamFloat) _param_com_rc_stick_ov, (ParamBool) _param_man_arm_gesture, (ParamFloat) _param_man_kill_gest_t, - (ParamInt) _param_com_rc_arm_hyst, (ParamBool) _param_com_arm_swisbtn, + (ParamInt) _param_rc_map_pay_sw, (ParamInt) _param_fltmode_1, (ParamInt) _param_fltmode_2, (ParamInt) _param_fltmode_3, diff --git a/src/modules/manual_control/ManualControlSelector.cpp b/src/modules/manual_control/ManualControlSelector.cpp index 0ea367d8c9..aa2e175beb 100644 --- a/src/modules/manual_control/ManualControlSelector.cpp +++ b/src/modules/manual_control/ManualControlSelector.cpp @@ -43,20 +43,11 @@ void ManualControlSelector::updateValidityOfChosenInput(uint64_t now) void ManualControlSelector::updateWithNewInputSample(uint64_t now, const manual_control_setpoint_s &input, int instance) { - if (input.valid) { - if (isRc(input.data_source)) { _timestamp_last_rc = input.timestamp_sample; } - - if (isMavlink(input.data_source)) { _timestamp_last_mavlink = input.timestamp_sample; } - } - // First check if the chosen input got invalid, so it can get replaced updateValidityOfChosenInput(now); - const bool update_existing_input = _setpoint.valid && (input.data_source == _setpoint.data_source); - const bool start_using_new_input = !_setpoint.valid; - - // Switch to new input if it's valid and we don't already have a valid one - if (isInputValid(input, now) && (update_existing_input || start_using_new_input)) { + // Update with input sample if it's valid and should be chosen according to COM_RC_IN_MODE + if (isInputValid(input, now)) { _setpoint = input; _setpoint.valid = true; _setpoint.timestamp = now; // timestamp_sample is preserved @@ -78,32 +69,44 @@ bool ManualControlSelector::isInputValid(const manual_control_setpoint_s &input, bool match = false; switch (_rc_in_mode) { // COM_RC_IN_MODE - case 0: // RC Transmitter only + case RcInMode::RcOnly: match = isRc(input.data_source); break; - case 1: // Joystick only - match = isMavlink(input.data_source); + case RcInMode::MavLinkOnly: + match = isMavlink(input.data_source) && ((input.data_source == _setpoint.data_source) || !_setpoint.valid); break; - case 2: // RC and Joystick with fallback - match = true; + case RcInMode::RcOrMavlinkWithFallback: + match = (input.data_source == _setpoint.data_source) || !_setpoint.valid; break; - case 3: // RC or Joystick keep first + case RcInMode::RcOrMavlinkKeepFirst: match = (input.data_source == _first_valid_source) || (_first_valid_source == manual_control_setpoint_s::SOURCE_UNKNOWN); break; - case 5: // RC priority, Joystick fallback - match = isRc(input.data_source) || (now > _timestamp_last_rc + _timeout); + case RcInMode::PriorityRcThenMavlinkAscending: + match = !_setpoint.valid || (input.data_source <= _setpoint.data_source); break; - case 6: // Joystick priority, RC fallback - match = isMavlink(input.data_source) || (now > _timestamp_last_mavlink + _timeout); + case RcInMode::PriorityMavlinkAscendingThenRc: + match = !_setpoint.valid + || (isRc(input.data_source) && isRc(_setpoint.data_source)) + || (isMavlink(input.data_source) && (isRc(_setpoint.data_source) || input.data_source <= _setpoint.data_source)); break; - case 4: // Stick input disabled + case RcInMode::PriorityRcThenMavlinkDescending: + match = !_setpoint.valid + || isRc(input.data_source) + || (isMavlink(input.data_source) && isMavlink(_setpoint.data_source) && input.data_source >= _setpoint.data_source); + break; + + case RcInMode::PriorityMavlinkDescendingThenRc: + match = !_setpoint.valid || (input.data_source >= _setpoint.data_source); + break; + + case RcInMode::DisableManualControl: default: break; } diff --git a/src/modules/manual_control/ManualControlSelector.hpp b/src/modules/manual_control/ManualControlSelector.hpp index ae9b8662a3..357c13a667 100644 --- a/src/modules/manual_control/ManualControlSelector.hpp +++ b/src/modules/manual_control/ManualControlSelector.hpp @@ -39,7 +39,7 @@ class ManualControlSelector { public: - void setRcInMode(int32_t rc_in_mode) { _rc_in_mode = rc_in_mode; } + void setRcInMode(int32_t rc_in_mode) { _rc_in_mode = static_cast(rc_in_mode); } void setTimeout(uint64_t timeout) { _timeout = timeout; } void updateValidityOfChosenInput(uint64_t now); void updateWithNewInputSample(uint64_t now, const manual_control_setpoint_s &input, int instance); @@ -51,11 +51,22 @@ private: static bool isRc(uint8_t source); static bool isMavlink(uint8_t source); + // COM_RC_IN_MODE parameter values + enum class RcInMode : int32_t { + RcOnly = 0, + MavLinkOnly = 1, + RcOrMavlinkWithFallback = 2, + RcOrMavlinkKeepFirst = 3, + DisableManualControl = 4, + PriorityRcThenMavlinkAscending = 5, + PriorityMavlinkAscendingThenRc = 6, + PriorityRcThenMavlinkDescending = 7, + PriorityMavlinkDescendingThenRc = 8 + }; + manual_control_setpoint_s _setpoint{}; uint64_t _timeout{0}; - int32_t _rc_in_mode{0}; + RcInMode _rc_in_mode{RcInMode::DisableManualControl}; int _instance{-1}; uint8_t _first_valid_source{manual_control_setpoint_s::SOURCE_UNKNOWN}; - uint64_t _timestamp_last_rc{0}; - uint64_t _timestamp_last_mavlink{0}; }; diff --git a/src/modules/manual_control/ManualControlSelectorTest.cpp b/src/modules/manual_control/ManualControlSelectorTest.cpp index 544f1dae2c..45ad56b0f0 100644 --- a/src/modules/manual_control/ManualControlSelectorTest.cpp +++ b/src/modules/manual_control/ManualControlSelectorTest.cpp @@ -352,10 +352,10 @@ TEST(ManualControlSelector, RcOutdated) EXPECT_EQ(selector.instance(), -1); } -TEST(ManualControlSelector, RcMavlinkInputRcPriority) +TEST(ManualControlSelector, PriorityRcThenMavlinkAscending) { ManualControlSelector selector; - selector.setRcInMode(5); // Configure RC priority + selector.setRcInMode(5); // Configure RC, then Joystick ascending selector.setTimeout(500_ms); uint64_t timestamp = SOME_TIME; @@ -373,7 +373,7 @@ TEST(ManualControlSelector, RcMavlinkInputRcPriority) timestamp += 100_ms; - // Now provide input from MAVLink as well which should get ignored + // Now provide input from MAVLink 0 as well which should get ignored input.data_source = SOURCE_MAVLINK_0; input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 1); @@ -384,7 +384,7 @@ TEST(ManualControlSelector, RcMavlinkInputRcPriority) timestamp += 500_ms; - // Now we update MAVLink and let RC time out, so it should switch to RC + // Now we update MAVLink 0 and let RC time out, so it should switch to MAVLink 0 input.data_source = SOURCE_MAVLINK_0; input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 1); @@ -393,7 +393,7 @@ TEST(ManualControlSelector, RcMavlinkInputRcPriority) EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); EXPECT_EQ(selector.instance(), 1); - // If we get RC back immediately, it should use it with priority + // If we get RC back immediately, it should take over with priority input.data_source = SOURCE_RC; input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 0); @@ -401,63 +401,65 @@ TEST(ManualControlSelector, RcMavlinkInputRcPriority) EXPECT_TRUE(selector.setpoint().valid); EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); EXPECT_EQ(selector.instance(), 0); -} - -TEST(ManualControlSelector, RcMavlinkInputMavlinkPriority) -{ - ManualControlSelector selector; - selector.setRcInMode(6); // Configure MAVLink priority - selector.setTimeout(500_ms); - - uint64_t timestamp = SOME_TIME; - - // Valid MAVLink input gets used - manual_control_setpoint_s input{}; - input.data_source = SOURCE_MAVLINK_0; - input.valid = true; - input.timestamp_sample = timestamp; - selector.updateWithNewInputSample(timestamp, input, 0); - - EXPECT_TRUE(selector.setpoint().valid); - EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); - EXPECT_EQ(selector.instance(), 0); timestamp += 100_ms; - // Now provide input from RC as well which should get ignored - input.data_source = SOURCE_RC; + // Now provide input from MAVLink 1, which should get ignored + input.data_source = SOURCE_MAVLINK_1; input.timestamp_sample = timestamp; - selector.updateWithNewInputSample(timestamp, input, 1); + selector.updateWithNewInputSample(timestamp, input, 2); EXPECT_TRUE(selector.setpoint().valid); - EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); EXPECT_EQ(selector.instance(), 0); timestamp += 500_ms; - // Now we update RC and let MAVLink time out, so it should switch to RC - input.data_source = SOURCE_RC; + // Now we update MAVLink 1 and let RC time out, so it should switch to MAVLink 1 + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 100_ms; + + // Now provide input from MAVLink 0, which has higher priority and should take over + input.data_source = SOURCE_MAVLINK_0; input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 1); EXPECT_TRUE(selector.setpoint().valid); - EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); EXPECT_EQ(selector.instance(), 1); - // If we get MAVLink back immediately, it should use it with priority - input.data_source = SOURCE_MAVLINK_0; + // If we get MAVLink 1 back immediately, it should be ignored since MAVLink 0 has higher priority + input.data_source = SOURCE_MAVLINK_1; input.timestamp_sample = timestamp; - selector.updateWithNewInputSample(timestamp, input, 0); + selector.updateWithNewInputSample(timestamp, input, 2); EXPECT_TRUE(selector.setpoint().valid); EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); - EXPECT_EQ(selector.instance(), 0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 500_ms; + + // Now we update MAVLink 1 and let MAVLink 0 time out, so it should switch to MAVLink 1 + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); } -TEST(ManualControlSelector, MavlinkTwoInstanceInputMavlinkPriority) +TEST(ManualControlSelector, PriorityMavlinkAscendingThenRc) { ManualControlSelector selector; - selector.setRcInMode(6); // Configure MAVLink priority + selector.setRcInMode(6); // Configure Joystick ascending, then RC selector.setTimeout(500_ms); uint64_t timestamp = SOME_TIME; @@ -467,10 +469,114 @@ TEST(ManualControlSelector, MavlinkTwoInstanceInputMavlinkPriority) input.data_source = SOURCE_MAVLINK_0; input.valid = true; input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 100_ms; + + // Now provide input from MAVLink 1 as well which should get ignored + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 500_ms; + + // Now we update MAVLink 1 and let MAVLink 0 time out, so it should switch to MAVLink 1 + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + // If we get MAVLink 0 back immediately, it should take over with priority + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 100_ms; + + // Now provide input from RC, which should get ignored + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 0); EXPECT_TRUE(selector.setpoint().valid); EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 500_ms; + + // Now we update RC and let MAVLink 0 time out, so it should switch to RC + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); + + timestamp += 100_ms; + + // Now provide input from MAVLink 1, which has higher priority and should take over + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + // If we get RC back immediately, it should be ignored since MAVLink 1 has higher priority + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 500_ms; + + // Now we update RC and let MAVLink 1 time out, so it should switch to RC + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); +} + +TEST(ManualControlSelector, PriorityRcThenMavlinkDescending) +{ + ManualControlSelector selector; + selector.setRcInMode(7); // Configure RC, then Joystick descending + selector.setTimeout(500_ms); + + uint64_t timestamp = SOME_TIME; + + // Valid RC input gets used + manual_control_setpoint_s input{}; + input.data_source = SOURCE_RC; + input.valid = true; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); EXPECT_EQ(selector.instance(), 0); timestamp += 100_ms; @@ -478,29 +584,186 @@ TEST(ManualControlSelector, MavlinkTwoInstanceInputMavlinkPriority) // Now provide input from MAVLink 1 as well which should get ignored input.data_source = SOURCE_MAVLINK_1; input.timestamp_sample = timestamp; - selector.updateWithNewInputSample(timestamp, input, 1); + selector.updateWithNewInputSample(timestamp, input, 2); EXPECT_TRUE(selector.setpoint().valid); - EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); EXPECT_EQ(selector.instance(), 0); timestamp += 500_ms; - // Now we update MAVLink 1 and let MAVLink 0 time out, so it should switch to MAVLink 1 + // Now we update MAVLink 0 and let RC time out, so it should switch to MAVLink 0 input.data_source = SOURCE_MAVLINK_1; input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + // If we get RC back immediately, it should take over with priority + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); + + timestamp += 100_ms; + + // Now provide input from MAVLink 0, which should get ignored + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); + + timestamp += 500_ms; + + // Now we update MAVLink 0 and let RC time out, so it should switch to MAVLink 0 + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 100_ms; + + // Now provide input from MAVLink 1, which has higher priority and should take over + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + // If we get MAVLink 0 back immediately, it should be ignored since MAVLink 1 has higher priority + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 1); EXPECT_TRUE(selector.setpoint().valid); EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 500_ms; + + // Now we update MAVLink 0 and let MAVLink 1 time out, so it should switch to MAVLink 0 + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); +} + +TEST(ManualControlSelector, PriorityMavlinkDescendingThenRc) +{ + ManualControlSelector selector; + selector.setRcInMode(8); // Configure Joystick descending, then RC + selector.setTimeout(500_ms); + + uint64_t timestamp = SOME_TIME; + + // Valid MAVLink 1 input gets used + manual_control_setpoint_s input{}; + input.data_source = SOURCE_MAVLINK_1; + input.valid = true; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 100_ms; + + // Now provide input from MAVLink 0 as well which should get ignored + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 500_ms; + + // Now we update MAVLink 0 and let MAVLink 1 time out, so it should switch to MAVLink 0 + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); EXPECT_EQ(selector.instance(), 1); - // If we get MAVLink 0 back immediately, it should not switch since MAVLink 1 has the same priority - input.data_source = SOURCE_MAVLINK_0; + // If we get MAVLink 1 back immediately, it should take over with priority + input.data_source = SOURCE_MAVLINK_1; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 2); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 100_ms; + + // Now provide input from RC, which should get ignored + input.data_source = SOURCE_RC; input.timestamp_sample = timestamp; selector.updateWithNewInputSample(timestamp, input, 0); EXPECT_TRUE(selector.setpoint().valid); EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_1); + EXPECT_EQ(selector.instance(), 2); + + timestamp += 500_ms; + + // Now we update RC and let MAVLink 1 time out, so it should switch to RC + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); + + timestamp += 100_ms; + + // Now provide input from MAVLink 0, which has higher priority and should take over + input.data_source = SOURCE_MAVLINK_0; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 1); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); EXPECT_EQ(selector.instance(), 1); + + // If we get RC back immediately, it should be ignored since MAVLink 0 has higher priority + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_MAVLINK_0); + EXPECT_EQ(selector.instance(), 1); + + timestamp += 500_ms; + + // Now we update RC and let MAVLink 0 time out, so it should switch to RC + input.data_source = SOURCE_RC; + input.timestamp_sample = timestamp; + selector.updateWithNewInputSample(timestamp, input, 0); + + EXPECT_TRUE(selector.setpoint().valid); + EXPECT_EQ(selector.setpoint().data_source, SOURCE_RC); + EXPECT_EQ(selector.instance(), 0); } diff --git a/src/modules/manual_control/manual_control_params.c b/src/modules/manual_control/manual_control_params.c index 7fde0d6dd3..30bfa35b4c 100644 --- a/src/modules/manual_control/manual_control_params.c +++ b/src/modules/manual_control/manual_control_params.c @@ -58,3 +58,20 @@ PARAM_DEFINE_INT32(MAN_ARM_GESTURE, 1); * @max 15 */ PARAM_DEFINE_FLOAT(MAN_KILL_GEST_T, -1.f); + +/** + * Deadzone for sticks (only specific use cases) + * + * Range around stick center ignored to prevent + * vehicle drift from stick hardware inaccuracy. + * + * Does not apply to any precise constant input like + * throttle and attitude or rate piloting. + * + * @min 0 + * @max 1 + * @decimal 2 + * @increment 0.01 + * @group Manual Control + */ +PARAM_DEFINE_FLOAT(MAN_DEADZONE, 0.1f); diff --git a/src/modules/mavlink/CMakeLists.txt b/src/modules/mavlink/CMakeLists.txt index 45aa9b1cc8..4701863c07 100644 --- a/src/modules/mavlink/CMakeLists.txt +++ b/src/modules/mavlink/CMakeLists.txt @@ -92,6 +92,7 @@ target_sources(mavlink_c target_include_directories(mavlink_c INTERFACE ${MAVLINK_LIBRARY_DIR} + ${MAVLINK_LIBRARY_DIR}/../ ${MAVLINK_LIBRARY_DIR}/${CONFIG_MAVLINK_DIALECT} ${MAVLINK_LIBRARY_DIR}/${MAVLINK_DIALECT_UAVIONIX} ) diff --git a/src/modules/mavlink/mavlink b/src/modules/mavlink/mavlink index f9dbd8c496..1ba67b3c9c 160000 --- a/src/modules/mavlink/mavlink +++ b/src/modules/mavlink/mavlink @@ -1 +1 @@ -Subproject commit f9dbd8c4968e9e135383e007244e4911ad4f729f +Subproject commit 1ba67b3c9c46f56a644e6f4e8a4c359172ed14bc diff --git a/src/modules/mavlink/mavlink_main.cpp b/src/modules/mavlink/mavlink_main.cpp index ab321edbe1..2003189297 100644 --- a/src/modules/mavlink/mavlink_main.cpp +++ b/src/modules/mavlink/mavlink_main.cpp @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -82,6 +83,8 @@ static pthread_mutex_t mavlink_module_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mavlink_event_buffer_mutex = PTHREAD_MUTEX_INITIALIZER; +static px4::atomic mavlink_instance_count {0}; + events::EventBuffer *Mavlink::_event_buffer = nullptr; Mavlink *mavlink_module_instances[MAVLINK_COMM_NUM_BUFFERS] {}; @@ -159,9 +162,6 @@ Mavlink::~Mavlink() } while (running()); } - if (_instance_id >= 0) { - mavlink_module_instances[_instance_id] = nullptr; - } // if this instance was responsible for checking events then select a new mavlink instance if (check_events()) { @@ -187,12 +187,7 @@ Mavlink::mavlink_update_parameters() { updateParams(); - int32_t proto = _param_mav_proto_ver.get(); - - if (_protocol_version_switch != proto) { - _protocol_version_switch = proto; - set_proto_version(proto); - } + setProtocolVersion(_param_mav_proto_ver.get()); if (_param_mav_type.get() < 0 || _param_mav_type.get() >= MAV_TYPE_ENUM_END) { _param_mav_type.set(0); @@ -270,6 +265,7 @@ Mavlink::set_instance_id() if (mavlink_module_instances[instance_id] == nullptr) { mavlink_module_instances[instance_id] = this; _instance_id = instance_id; + mavlink_instance_count.fetch_add(1); return true; } } @@ -277,16 +273,13 @@ Mavlink::set_instance_id() return false; } -void -Mavlink::set_proto_version(unsigned version) +void Mavlink::setProtocolVersion(uint8_t version) { - if ((version == 1 || version == 0) && - ((_protocol_version_switch == 0) || (_protocol_version_switch == 1))) { + if (version == 1) { get_status()->flags |= MAVLINK_STATUS_FLAG_OUT_MAVLINK1; _protocol_version = 1; - } else if (version == 2 && - ((_protocol_version_switch == 0) || (_protocol_version_switch == 2))) { + } else { get_status()->flags &= ~(MAVLINK_STATUS_FLAG_OUT_MAVLINK1); _protocol_version = 2; } @@ -381,8 +374,13 @@ Mavlink::destroy_all_instances() LockGuard lg{mavlink_module_mutex}; // we know all threads have exited, so it's safe to delete objects. - for (Mavlink *inst_to_del : mavlink_module_instances) { - delete inst_to_del; + for (int i = 0; i < MAVLINK_COMM_NUM_BUFFERS; i++) { + if (mavlink_module_instances[i] != nullptr) { + Mavlink *inst = mavlink_module_instances[i]; + mavlink_module_instances[i] = nullptr; + mavlink_instance_count.fetch_sub(1); + delete inst; + } } } @@ -471,6 +469,11 @@ Mavlink::forward_message(const mavlink_message_t *msg, Mavlink *self) } } + // Avoid locking/iteration when there is no instance to forward to. + if (mavlink_instance_count.load() <= 1) { + return; + } + // If it's a message only for us, we keep it if (target_system_id == self->get_system_id() && target_component_id == self->get_component_id()) { return; @@ -1156,13 +1159,7 @@ Mavlink::send_protocol_version() //memcpy(&msg.spec_version_hash, &mavlink_spec_git_version_binary, sizeof(msg.spec_version_hash)); memcpy(&msg.library_version_hash, &mavlink_lib_git_version_binary, sizeof(msg.library_version_hash)); - // Switch to MAVLink 2 - int curr_proto_ver = _protocol_version; - set_proto_version(2); - // Send response - if it passes through the link its fine to use MAVLink 2 mavlink_msg_protocol_version_send_struct(get_channel(), &msg); - // Reset to previous value - set_proto_version(curr_proto_ver); } int @@ -1208,8 +1205,8 @@ Mavlink::configure_stream(const char *stream_name, const float rate) } // if we reach here, the stream list does not contain the stream. - // flash constrained target's don't include all streams, and some are only available for the development dialect -#if defined(CONSTRAINED_FLASH) || !defined(MAVLINK_DEVELOPMENT_H) + // flash constrained target's don't include all streams +#if defined(CONSTRAINED_FLASH) return PX4_OK; #else PX4_WARN("stream %s not found", stream_name); @@ -1436,11 +1433,16 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("ESC_STATUS", 1.0f); configure_stream_local("ESTIMATOR_STATUS", 0.5f); configure_stream_local("EXTENDED_SYS_STATE", 1.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); +#if defined(MAVLINK_MSG_ID_GLOBAL_POSITION) configure_stream_local("GLOBAL_POSITION", 5.0f); +#endif configure_stream_local("GLOBAL_POSITION_INT", 5.0f); +#if defined(MAVLINK_MSG_ID_GNSS_INTEGRITY) + configure_stream_local("GNSS_INTEGRITY", 1.0f); +#endif configure_stream_local("GPS2_RAW", 1.0f); configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); configure_stream_local("GPS_RAW_INT", 5.0f); @@ -1509,10 +1511,13 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("EFI_STATUS", 2.0f); configure_stream_local("ESTIMATOR_STATUS", 1.0f); configure_stream_local("EXTENDED_SYS_STATE", 5.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GLOBAL_POSITION_INT", 50.0f); +#if defined(MAVLINK_MSG_ID_GNSS_INTEGRITY) + configure_stream_local("GNSS_INTEGRITY", 1.0f); +#endif configure_stream_local("GPS2_RAW", unlimited_rate); configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); configure_stream_local("GPS_RAW_INT", unlimited_rate); @@ -1673,11 +1678,14 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("ESTIMATOR_STATUS", 5.0f); configure_stream_local("EXTENDED_SYS_STATE", 2.0f); configure_stream_local("GLOBAL_POSITION_INT", 10.0f); +#if defined(MAVLINK_MSG_ID_GNSS_INTEGRITY) + configure_stream_local("GNSS_INTEGRITY", 1.0f); +#endif configure_stream_local("GPS2_RAW", unlimited_rate); configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); configure_stream_local("GPS_RAW_INT", unlimited_rate); configure_stream_local("GPS_STATUS", 1.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 0.5f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("HIGHRES_IMU", 50.0f); configure_stream_local("HOME_POSITION", 0.5f); @@ -1757,8 +1765,7 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("DISTANCE_SENSOR", 10.0f); configure_stream_local("MOUNT_ORIENTATION", 10.0f); configure_stream_local("OBSTACLE_DISTANCE", 10.0f); - configure_stream_local("ODOMETRY", 30.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 5.0f); configure_stream_local("ESC_INFO", 1.0f); @@ -1772,9 +1779,14 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("CURRENT_MODE", 0.5f); configure_stream_local("ESTIMATOR_STATUS", 1.0f); configure_stream_local("EXTENDED_SYS_STATE", 1.0f); +#if defined(MAVLINK_MSG_ID_GLOBAL_POSITION) configure_stream_local("GLOBAL_POSITION", 10.0f); +#endif configure_stream_local("GLOBAL_POSITION_INT", 10.0f); configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); +#if defined(MAVLINK_MSG_ID_GNSS_INTEGRITY) + configure_stream_local("GNSS_INTEGRITY", 1.0f); +#endif configure_stream_local("GPS2_RAW", unlimited_rate); configure_stream_local("GPS_RAW_INT", unlimited_rate); configure_stream_local("HOME_POSITION", 0.5f); @@ -1816,18 +1828,17 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("TIMESYNC", 10.0f); configure_stream_local("CAMERA_TRIGGER", 2.0f); configure_stream_local("LOCAL_POSITION_NED", 1.0f); - configure_stream_local("ATTITUDE", 1.0f); + configure_stream_local("ATTITUDE_QUATERNION", 2.0f); configure_stream_local("ALTITUDE", 1.0f); - configure_stream_local("DISTANCE_SENSOR", 2.0f); + configure_stream_local("DISTANCE_SENSOR", 1.0f); configure_stream_local("MOUNT_ORIENTATION", 2.0f); configure_stream_local("OBSTACLE_DISTANCE", 2.0f); - configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 1.0f); + configure_stream_local("GIMBAL_DEVICE_ATTITUDE_STATUS", 5.0f); configure_stream_local("GIMBAL_MANAGER_STATUS", 0.5f); configure_stream_local("GIMBAL_DEVICE_SET_ATTITUDE", 2.0f); configure_stream_local("ESC_INFO", 1.0f); configure_stream_local("ESC_STATUS", 2.0f); - - configure_stream_local("ADSB_VEHICLE", 2.0f); + configure_stream_local("ADSB_VEHICLE", 1.0f); configure_stream_local("ATTITUDE_TARGET", 0.5f); configure_stream_local("AVAILABLE_MODES", 0.3f); configure_stream_local("BATTERY_STATUS", 0.5f); @@ -1835,25 +1846,32 @@ Mavlink::configure_streams_to_default(const char *configure_single_stream) configure_stream_local("CURRENT_MODE", 0.5f); configure_stream_local("ESTIMATOR_STATUS", 1.0f); configure_stream_local("EXTENDED_SYS_STATE", 0.5f); - configure_stream_local("GLOBAL_POSITION_INT", 1.0f); + configure_stream_local("GLOBAL_POSITION_INT", 2.0f); +#if defined(MAVLINK_MSG_ID_GLOBAL_POSITION) + configure_stream_local("GLOBAL_POSITION", 2.0f); +#endif configure_stream_local("GPS_GLOBAL_ORIGIN", 1.0f); configure_stream_local("GPS2_RAW", 2.0f); configure_stream_local("GPS_RAW_INT", 2.0f); configure_stream_local("HOME_POSITION", 0.5f); - configure_stream_local("NAV_CONTROLLER_OUTPUT", 1.5f); - configure_stream_local("OPTICAL_FLOW_RAD", 1.0f); - configure_stream_local("ORBIT_EXECUTION_STATUS", 2.0f); + configure_stream_local("NAV_CONTROLLER_OUTPUT", 0.1f); + configure_stream_local("OPTICAL_FLOW_RAD", 0.1f); + configure_stream_local("ORBIT_EXECUTION_STATUS", 1.0f); configure_stream_local("PING", 0.1f); - configure_stream_local("POSITION_TARGET_GLOBAL_INT", 1.0f); - configure_stream_local("POSITION_TARGET_LOCAL_NED", 1.0f); + configure_stream_local("POSITION_TARGET_GLOBAL_INT", 0.5f); + configure_stream_local("POSITION_TARGET_LOCAL_NED", 0.5f); + configure_stream_local("RAW_RPM", 1.0f); configure_stream_local("RC_CHANNELS", 5.0f); - configure_stream_local("SERVO_OUTPUT_RAW_0", 1.0f); + configure_stream_local("SERVO_OUTPUT_RAW_0", 0.1f); configure_stream_local("SYS_STATUS", 0.5f); configure_stream_local("SYSTEM_TIME", 2.0f); configure_stream_local("TIME_ESTIMATE_TO_TARGET", 0.5f); - configure_stream_local("VFR_HUD", 1.0f); + configure_stream_local("VFR_HUD", 1.5f); configure_stream_local("VIBRATION", 0.1f); configure_stream_local("WIND_COV", 0.1f); +#if defined(MAVLINK_MSG_ID_FIGURE_EIGHT_EXECUTION_STATUS) + configure_stream_local("FIGURE_EIGHT_EXECUTION_STATUS", 0.5f); +#endif // MAVLINK_MSG_ID_FIGURE_EIGHT_EXECUTION_STATUS break; case MAVLINK_MODE_UAVIONIX: @@ -2901,6 +2919,14 @@ int Mavlink::start_helper(int argc, char *argv[]) res = instance->task_main(argc, argv); if (res != PX4_OK) { + LockGuard lg{mavlink_module_mutex}; + int instance_id = instance->get_instance_id(); + + if (instance_id >= 0) { + mavlink_module_instances[instance_id] = nullptr; + mavlink_instance_count.fetch_sub(1); + } + delete instance; } } @@ -3046,7 +3072,7 @@ Mavlink::display_status() } printf("\tForwarding: %s\n", get_forwarding_on() ? "On" : "Off"); - printf("\tMAVLink version: %" PRId32 "\n", _protocol_version); + printf("\tMAVLink version: %" PRId8 "\n", _protocol_version); printf("\ttransport protocol: "); @@ -3215,8 +3241,9 @@ Mavlink::stop_command(int argc, char *argv[]) for (int mavlink_instance = 0; mavlink_instance < MAVLINK_COMM_NUM_BUFFERS; mavlink_instance++) { if (mavlink_module_instances[mavlink_instance] == inst) { - delete inst; mavlink_module_instances[mavlink_instance] = nullptr; + mavlink_instance_count.fetch_sub(1); + delete inst; return PX4_OK; } } diff --git a/src/modules/mavlink/mavlink_main.h b/src/modules/mavlink/mavlink_main.h index 0379bd2c11..cdf079f9db 100644 --- a/src/modules/mavlink/mavlink_main.h +++ b/src/modules/mavlink/mavlink_main.h @@ -109,22 +109,10 @@ class Mavlink final : public ModuleParams { public: - /** - * Constructor - */ Mavlink(); - - /** - * Destructor, also kills the mavlinks task. - */ ~Mavlink(); - /** - * Start the mavlink task. - * - * @return OK on success. - */ - static int start(int argc, char *argv[]); + static int start(int argc, char *argv[]); bool running() const { return _task_running.load(); } bool should_exit() const { return _task_should_exit.load(); } @@ -134,70 +122,40 @@ public: _receiver.request_stop(); } - /** - * Display the mavlink status. - */ - void display_status(); + void display_status(); + void display_status_streams(); - /** - * Display the status of all enabled streams. - */ - void display_status_streams(); + static int stop_command(int argc, char *argv[]); + static int stream_command(int argc, char *argv[]); - static int stop_command(int argc, char *argv[]); - static int stream_command(int argc, char *argv[]); + static int instance_count(); + static Mavlink *new_instance(); + static Mavlink *get_instance_for_device(const char *device_name); - static int instance_count(); + mavlink_message_t *get_buffer() { return &_mavlink_buffer; } + mavlink_status_t *get_status() { return &_mavlink_status; } - static Mavlink *new_instance(); + void setProtocolVersion(uint8_t version); + uint8_t getProtocolVersion() const { return _protocol_version; }; - static Mavlink *get_instance_for_device(const char *device_name); + static int destroy_all_instances(); + static int get_status_all_instances(bool show_streams_status); + static bool serial_instance_exists(const char *device_name, Mavlink *self); - mavlink_message_t *get_buffer() { return &_mavlink_buffer; } + static bool component_was_seen(int system_id, int component_id, Mavlink &self); + static void forward_message(const mavlink_message_t *msg, Mavlink *self); - mavlink_status_t *get_status() { return &_mavlink_status; } + bool check_events() const { return _should_check_events.load(); } + void check_events_enable() { _should_check_events.store(true); } + void check_events_disable() { _should_check_events.store(false); } - /** - * Set the MAVLink version - * - * Currently supporting v1 and v2 - * - * @param version MAVLink version - */ - void set_proto_version(unsigned version); + bool sending_parameters() const { return _sending_parameters.load(); } + void set_sending_parameters(bool sending) { _sending_parameters.store(sending); } - static int destroy_all_instances(); + int get_uart_fd() const { return _uart_fd; } - static int get_status_all_instances(bool show_streams_status); - - static bool serial_instance_exists(const char *device_name, Mavlink *self); - - static bool component_was_seen(int system_id, int component_id, Mavlink &self); - - static void forward_message(const mavlink_message_t *msg, Mavlink *self); - - bool check_events() const { return _should_check_events.load(); } - void check_events_enable() { _should_check_events.store(true); } - void check_events_disable() { _should_check_events.store(false); } - - bool sending_parameters() const { return _sending_parameters.load(); } - void set_sending_parameters(bool sending) { _sending_parameters.store(sending); } - - int get_uart_fd() const { return _uart_fd; } - - /** - * Get the MAVLink system id. - * - * @return The system ID of this vehicle - */ - int get_system_id() const { return mavlink_system.sysid; } - - /** - * Get the MAVLink component id. - * - * @return The component ID of this vehicle - */ - int get_component_id() const { return mavlink_system.compid; } + int get_system_id() const { return mavlink_system.sysid; } + int get_component_id() const { return mavlink_system.compid; } const char *_device_name{DEFAULT_DEVICE_NAME}; @@ -620,8 +578,7 @@ private: uint64_t _last_write_success_time{0}; uint64_t _last_write_try_time{0}; uint64_t _mavlink_start_time{0}; - int32_t _protocol_version_switch{-1}; - int32_t _protocol_version{0}; + uint8_t _protocol_version = 0; ///< after initialization the only values are 1 and 2 unsigned _bytes_tx{0}; unsigned _bytes_txerr{0}; diff --git a/src/modules/mavlink/mavlink_messages.cpp b/src/modules/mavlink/mavlink_messages.cpp index 876d4c5825..a68c138747 100644 --- a/src/modules/mavlink/mavlink_messages.cpp +++ b/src/modules/mavlink/mavlink_messages.cpp @@ -79,6 +79,9 @@ #include "streams/GLOBAL_POSITION.hpp" #endif //MAVLINK_MSG_ID_GLOBAL_POSITION #include "streams/GLOBAL_POSITION_INT.hpp" +#if defined(MAVLINK_MSG_ID_GNSS_INTEGRITY) +#include "streams/GNSS_INTEGRITY.hpp" +#endif #include "streams/GPS_GLOBAL_ORIGIN.hpp" #include "streams/GPS_RAW_INT.hpp" #include "streams/GPS_RTCM_DATA.hpp" @@ -507,6 +510,9 @@ static const StreamListItem streams_list[] = { #if defined(UAVIONIX_ADSB_OUT_DYNAMIC_HPP) create_stream_list_item(), #endif // UAVIONIX_ADSB_OUT_DYNAMIC_HPP +#if defined(GNSS_INTEGRITY_HPP) + create_stream_list_item(), +#endif // GNSS_INTEGRITY_HPP #if defined(AVAILABLE_MODES_HPP) create_stream_list_item(), #endif // AVAILABLE_MODES_HPP diff --git a/src/modules/mavlink/mavlink_mission.cpp b/src/modules/mavlink/mavlink_mission.cpp index 822b0144e7..4453b7ab00 100644 --- a/src/modules/mavlink/mavlink_mission.cpp +++ b/src/modules/mavlink/mavlink_mission.cpp @@ -1538,6 +1538,12 @@ MavlinkMissionManager::parse_mavlink_mission_item(const mavlink_mission_item_t * mission_item->params[0] = (uint16_t)mavlink_mission_item->param1; break; + case MAV_CMD_DO_AUTOTUNE_ENABLE: + mission_item->nav_cmd = (NAV_CMD)mavlink_mission_item->command; + mission_item->params[0] = (uint16_t)mavlink_mission_item->param1; + mission_item->params[1] = (uint16_t)mavlink_mission_item->param2; + break; + default: mission_item->nav_cmd = NAV_CMD_INVALID; PX4_DEBUG("Unsupported command %d", mavlink_mission_item->command); @@ -1627,6 +1633,7 @@ MavlinkMissionManager::parse_mavlink_mission_item(const mavlink_mission_item_t * case MAV_CMD_CONDITION_DELAY: case MAV_CMD_CONDITION_DISTANCE: case MAV_CMD_DO_SET_ACTUATOR: + case MAV_CMD_DO_AUTOTUNE_ENABLE: case MAV_CMD_COMPONENT_ARM_DISARM: mission_item->nav_cmd = (NAV_CMD)mavlink_mission_item->command; break; diff --git a/src/modules/mavlink/mavlink_parameters.cpp b/src/modules/mavlink/mavlink_parameters.cpp index f1908d5e09..60841a34e6 100644 --- a/src/modules/mavlink/mavlink_parameters.cpp +++ b/src/modules/mavlink/mavlink_parameters.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2015-2018 PX4 Development Team. All rights reserved. + * Copyright (c) 2015-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,6 +38,7 @@ * @author Anton Babushkin * @author Lorenz Meier * @author Beat Kueng + * @author Hamish Willee */ #include @@ -80,6 +81,7 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) #if defined(CONFIG_MAVLINK_UAVCAN_PARAMETERS) if (req_list.target_system == mavlink_system.sysid && req_list.target_component < 127 && + !(req_list.target_component >= MAV_COMP_ID_CAMERA && req_list.target_component <= MAV_COMP_ID_CAMERA6) && (req_list.target_component != mavlink_system.compid || req_list.target_component == MAV_COMP_ID_ALL)) { // publish list request to UAVCAN driver via uORB. uavcan_parameter_request_s req{}; @@ -115,6 +117,9 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) _send_all_index = -1; } + /* Error report that _HASH_CHECK parameter is read-only */ + send_error(MAV_PARAM_ERROR_READ_ONLY, name, -1, msg->sysid, msg->compid); + /* No other action taken, return */ return; } @@ -124,10 +129,17 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) if (param == PARAM_INVALID) { PX4_ERR("unknown param: %s", name); + send_error(MAV_PARAM_ERROR_DOES_NOT_EXIST, name, -1, msg->sysid, msg->compid); + + } else if (!((set.param_type == MAV_PARAM_TYPE_INT32) || (set.param_type == MAV_PARAM_TYPE_REAL32))) { + PX4_ERR("param type unsupported: %s", name); + send_error(MAV_PARAM_ERROR_TYPE_UNSUPPORTED, name, -1, msg->sysid, msg->compid); } else if (!((param_type(param) == PARAM_TYPE_INT32 && set.param_type == MAV_PARAM_TYPE_INT32) || (param_type(param) == PARAM_TYPE_FLOAT && set.param_type == MAV_PARAM_TYPE_REAL32))) { PX4_ERR("param types mismatch param: %s", name); + send_error(MAV_PARAM_ERROR_TYPE_MISMATCH, name, -1, msg->sysid, msg->compid); + } else { // According to the mavlink spec we should always acknowledge a write operation. @@ -139,6 +151,7 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) #if defined(CONFIG_MAVLINK_UAVCAN_PARAMETERS) if (set.target_system == mavlink_system.sysid && set.target_component < 127 && + !(set.target_component >= MAV_COMP_ID_CAMERA && set.target_component <= MAV_COMP_ID_CAMERA6) && (set.target_component != mavlink_system.compid || set.target_component == MAV_COMP_ID_ALL)) { // publish set request to UAVCAN driver via uORB. uavcan_parameter_request_s req{}; @@ -198,18 +211,32 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) /* enforce null termination */ name[MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN] = '\0'; /* attempt to find parameter and send it */ - send_param(param_find_no_notification(name)); + + const int result = send_param(param_find_no_notification(name)); + + if (result == 1) { + PX4_ERR("Unknown param name: %s", name); + send_error(MAV_PARAM_ERROR_DOES_NOT_EXIST, name, -1, msg->sysid, msg->compid); + + } else if (result == 2) { + PX4_ERR("Failed loading param from storage: %s", name); + send_error(MAV_PARAM_ERROR_READ_FAIL, name, -1, msg->sysid, msg->compid); + } } } else { + /* when index is >= 0, send this parameter again */ int ret = send_param(param_for_used_index(req_read.param_index)); if (ret == 1) { - PX4_ERR("unknown param ID: %i", req_read.param_index); + PX4_ERR("Unknown param index: %i", req_read.param_index); + send_error(MAV_PARAM_ERROR_DOES_NOT_EXIST, nullptr, req_read.param_index, msg->sysid, msg->compid); } else if (ret == 2) { - PX4_ERR("failed loading param from storage ID: %i", req_read.param_index); + PX4_ERR("Failed loading param from storage index: %i", req_read.param_index); + send_error(MAV_PARAM_ERROR_READ_FAIL, nullptr, req_read.param_index, msg->sysid, msg->compid); + } } } @@ -217,6 +244,7 @@ MavlinkParametersManager::handle_message(const mavlink_message_t *msg) #if defined(CONFIG_MAVLINK_UAVCAN_PARAMETERS) if (req_read.target_system == mavlink_system.sysid && req_read.target_component < 127 && + !(req_read.target_component >= MAV_COMP_ID_CAMERA && req_read.target_component <= MAV_COMP_ID_CAMERA6) && (req_read.target_component != mavlink_system.compid || req_read.target_component == MAV_COMP_ID_ALL)) { // publish set request to UAVCAN driver via uORB. uavcan_parameter_request_s req{}; @@ -471,6 +499,7 @@ MavlinkParametersManager::send_one() int MavlinkParametersManager::send_param(param_t param, int component_id) { + if (param == PARAM_INVALID) { return 1; } @@ -546,7 +575,7 @@ MavlinkParametersManager::send_param(param_t param, int component_id) mavlink_msg_param_value_send_struct(_mavlink.get_channel(), &msg); } else { - // Re-pack the message with a different component ID + // Re-pack the message with a passed component ID mavlink_message_t mavlink_packet; mavlink_msg_param_value_encode_chan(mavlink_system.sysid, component_id, _mavlink.get_channel(), &mavlink_packet, &msg); _mavlink_resend_uart(_mavlink.get_channel(), &mavlink_packet); @@ -557,6 +586,57 @@ MavlinkParametersManager::send_param(param_t param, int component_id) return 0; } + +int MavlinkParametersManager:: send_error(MAV_PARAM_ERROR error, const char *param_id, const int param_index, + const int target_sysid, const int target_compid, + int component_id) +{ + /* no free TX buf to send this param error message */ + if (_mavlink.get_free_tx_buf() < MAVLINK_MSG_ID_PARAM_ERROR_LEN) { + return 1; + } + + mavlink_param_error_t msg; + msg.target_system = target_sysid; + msg.target_component = target_compid; + msg.error = error; + + if (param_index > -1) { // param_id is not used + + msg.param_index = param_index; + + } else { +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif + /* + * coverity[buffer_size_warning : FALSE] + * + * The MAVLink spec does not require the string to be NUL-terminated if it + * has length 16. In this case the receiving end needs to terminate it + * when copying it. + */ + strncpy(msg.param_id, param_id, MAVLINK_MSG_PARAM_ERROR_FIELD_PARAM_ID_LEN); +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif/* code */ + } + + /* default component ID */ + if (component_id < 0) { + mavlink_msg_param_error_send_struct(_mavlink.get_channel(), &msg); + + } else { + // Re-pack the message with a different component ID + mavlink_message_t mavlink_packet; + mavlink_msg_param_error_encode_chan(mavlink_system.sysid, component_id, _mavlink.get_channel(), &mavlink_packet, &msg); + _mavlink_resend_uart(_mavlink.get_channel(), &mavlink_packet); + } + + return 0; +} + #if defined(CONFIG_MAVLINK_UAVCAN_PARAMETERS) bool MavlinkParametersManager::send_uavcan() diff --git a/src/modules/mavlink/mavlink_parameters.h b/src/modules/mavlink/mavlink_parameters.h index 478c487881..c43052c020 100644 --- a/src/modules/mavlink/mavlink_parameters.h +++ b/src/modules/mavlink/mavlink_parameters.h @@ -112,6 +112,14 @@ protected: int send_param(param_t param, int component_id = -1); + /** + * Send error message. + * /// @return true if a error message was sent + */ + int send_error(MAV_PARAM_ERROR error, const char *param_id = nullptr, + const int param_index = -1, int target_system = -1, + int target_component = -1, int component_id = -1); + #if defined(CONFIG_MAVLINK_UAVCAN_PARAMETERS) /** * Send UAVCAN params diff --git a/src/modules/mavlink/mavlink_params.c b/src/modules/mavlink/mavlink_params.c index 8a793f5e5f..f616bd01d6 100644 --- a/src/modules/mavlink/mavlink_params.c +++ b/src/modules/mavlink/mavlink_params.c @@ -52,11 +52,10 @@ PARAM_DEFINE_INT32(MAV_COMP_ID, 1); /** * MAVLink protocol version * @group MAVLink - * @value 0 Default to 1, switch to 2 if GCS sends version 2 - * @value 1 Always use version 1 - * @value 2 Always use version 2 + * @value 1 Version 1 with auto-upgrade to v2 if detected + * @value 2 Version 2 */ -PARAM_DEFINE_INT32(MAV_PROTO_VER, 0); +PARAM_DEFINE_INT32(MAV_PROTO_VER, 2); /** * MAVLink SiK Radio ID diff --git a/src/modules/mavlink/mavlink_receiver.cpp b/src/modules/mavlink/mavlink_receiver.cpp index 4673ed6e72..d34074cba2 100644 --- a/src/modules/mavlink/mavlink_receiver.cpp +++ b/src/modules/mavlink/mavlink_receiver.cpp @@ -450,8 +450,8 @@ MavlinkReceiver::evaluate_target_ok(int command, int target_system, int target_c break; default: - target_ok = (target_system == mavlink_system.sysid) && ((target_component == mavlink_system.compid) - || (target_component == MAV_COMP_ID_ALL)); + target_ok = ((target_system == 0) || (target_system == mavlink_system.sysid)) + && ((target_component == mavlink_system.compid) || (target_component == MAV_COMP_ID_ALL)); break; } @@ -622,46 +622,37 @@ void MavlinkReceiver::handle_message_command_both(mavlink_message_t *msg, const autotune_attitude_control_status_s status{}; _autotune_attitude_control_status_sub.copy(&status); - // if not busy enable via the parameter - // do not check the return value of the uORB copy above because the module - // starts publishing only when MC_AT_START is set + // publish vehicle command once if: + // - autotune is not already running + // - we are not in transition + // - autotune module is enabled if (status.state == autotune_attitude_control_status_s::STATE_IDLE) { vehicle_status_s vehicle_status{}; _vehicle_status_sub.copy(&vehicle_status); if (!vehicle_status.in_transition_mode) { - param_t atune_start; switch (vehicle_status.vehicle_type) { case vehicle_status_s::VEHICLE_TYPE_FIXED_WING: - atune_start = param_find("FW_AT_START"); - + has_module = param_find("FW_AT_APPLY"); break; case vehicle_status_s::VEHICLE_TYPE_ROTARY_WING: - atune_start = param_find("MC_AT_START"); - + has_module = param_find("MC_AT_APPLY"); break; default: - atune_start = PARAM_INVALID; + has_module = false; break; } - if (atune_start == PARAM_INVALID) { - has_module = false; - - } else { - int32_t start = 1; - param_set(atune_start, &start); + if (has_module) { + _cmd_pub.publish(vehicle_command); } - - } else { - has_module = false; } } - if (has_module) { + if (has_module && fabsf(vehicle_command.param1 - 1.f) <= FLT_EPSILON && fabsf(vehicle_command.param2) < FLT_EPSILON) { // most are in progress result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_IN_PROGRESS; @@ -715,6 +706,10 @@ void MavlinkReceiver::handle_message_command_both(mavlink_message_t *msg, const break; } + } else if (has_module && (fabsf(vehicle_command.param1 - 1.f) > FLT_EPSILON || fabsf(vehicle_command.param2) > FLT_EPSILON)) { + + result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_DENIED; + } else { result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED; } @@ -1120,6 +1115,8 @@ MavlinkReceiver::handle_message_set_position_target_local_ned(mavlink_message_t ocm.position = !matrix::Vector3f(setpoint.position).isAllNan(); ocm.velocity = !matrix::Vector3f(setpoint.velocity).isAllNan(); ocm.acceleration = !matrix::Vector3f(setpoint.acceleration).isAllNan(); + ocm.attitude = PX4_ISFINITE(setpoint.yaw); + ocm.body_rate = PX4_ISFINITE(setpoint.yawspeed); if (ocm.acceleration && (type_mask & POSITION_TARGET_TYPEMASK_FORCE_SET)) { mavlink_log_critical(&_mavlink_log_pub, "SET_POSITION_TARGET_LOCAL_NED force not supported\t"); @@ -1242,6 +1239,8 @@ MavlinkReceiver::handle_message_set_position_target_global_int(mavlink_message_t ocm.position = !matrix::Vector3f(setpoint.position).isAllNan(); ocm.velocity = !matrix::Vector3f(setpoint.velocity).isAllNan(); ocm.acceleration = !matrix::Vector3f(setpoint.acceleration).isAllNan(); + ocm.attitude = PX4_ISFINITE(setpoint.yaw); + ocm.body_rate = PX4_ISFINITE(setpoint.yawspeed); if (ocm.acceleration && (type_mask & POSITION_TARGET_TYPEMASK_FORCE_SET)) { mavlink_log_critical(&_mavlink_log_pub, "SET_POSITION_TARGET_GLOBAL_INT force not supported\t"); @@ -1288,8 +1287,6 @@ MavlinkReceiver::handle_message_set_gps_global_origin(mavlink_message_t *msg) vcmd.timestamp = hrt_absolute_time(); _cmd_pub.publish(vcmd); } - - handle_request_message_command(MAVLINK_MSG_ID_GPS_GLOBAL_ORIGIN); } #if defined(MAVLINK_MSG_ID_SET_VELOCITY_LIMITS) // For now only defined if development.xml is used @@ -1992,6 +1989,10 @@ MavlinkReceiver::handle_message_tunnel(mavlink_message_t *msg) _esc_serial_passthru_pub.publish(tunnel); break; + case MAV_TUNNEL_PAYLOAD_TYPE_MODALAI_IO_UART_PASSTHRU: + _io_serial_passthru_pub.publish(tunnel); + break; + default: _mavlink_tunnel_pub.publish(tunnel); break; @@ -3165,7 +3166,7 @@ MavlinkReceiver::run() ssize_t nread = 0; hrt_abstime last_send_update = 0; - while (!_mavlink.should_exit()) { + while (!_should_exit.load()) { // check for parameter updates if (_parameter_update_sub.updated()) { @@ -3228,10 +3229,11 @@ MavlinkReceiver::run() for (ssize_t i = 0; i < nread; i++) { if (mavlink_parse_char(_mavlink.get_channel(), buf[i], &msg, &_status)) { - /* check if we received version 2 and request a switch. */ - if (!(_mavlink.get_status()->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1)) { - /* this will only switch to proto version 2 if allowed in settings */ - _mavlink.set_proto_version(2); + // If we receive a complete MAVLink 2 packet, also switch the outgoing protocol version + if (!(_mavlink.get_status()->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1) + && _mavlink.getProtocolVersion() != 2) { + PX4_INFO("Upgrade to MAVLink v2 because of incoming packet"); + _mavlink.setProtocolVersion(2); } switch (_mavlink.get_mode()) { diff --git a/src/modules/mavlink/mavlink_receiver.h b/src/modules/mavlink/mavlink_receiver.h index d1c477e1c7..5023c7a7df 100644 --- a/src/modules/mavlink/mavlink_receiver.h +++ b/src/modules/mavlink/mavlink_receiver.h @@ -310,6 +310,7 @@ private: uORB::Publication _log_message_pub{ORB_ID(log_message)}; uORB::Publication _mavlink_tunnel_pub{ORB_ID(mavlink_tunnel)}; uORB::Publication _esc_serial_passthru_pub{ORB_ID(esc_serial_passthru)}; + uORB::Publication _io_serial_passthru_pub{ORB_ID(io_serial_passthru)}; uORB::Publication _obstacle_distance_pub{ORB_ID(obstacle_distance)}; uORB::Publication _offboard_control_mode_pub{ORB_ID(offboard_control_mode)}; uORB::Publication _onboard_computer_status_pub{ORB_ID(onboard_computer_status)}; diff --git a/src/modules/mavlink/mavlink_timesync.cpp b/src/modules/mavlink/mavlink_timesync.cpp index c9df0a4126..18746283dc 100644 --- a/src/modules/mavlink/mavlink_timesync.cpp +++ b/src/modules/mavlink/mavlink_timesync.cpp @@ -65,6 +65,8 @@ MavlinkTimesync::handle_message(const mavlink_message_t *msg) rsync.tc1 = now * 1000ULL; rsync.ts1 = tsync.ts1; + rsync.target_component = msg->compid; + rsync.target_system = msg->sysid; mavlink_msg_timesync_send_struct(_mavlink.get_channel(), &rsync); diff --git a/src/modules/mavlink/module.yaml b/src/modules/mavlink/module.yaml index fa2fe38834..a8eee0d093 100644 --- a/src/modules/mavlink/module.yaml +++ b/src/modules/mavlink/module.yaml @@ -201,3 +201,40 @@ parameters: num_instances: *max_num_config_instances default: [0.015, 0.015, 0.015] reboot_required: true + + MAV_S_MODE: + description: + short: MAVLink Mode for SOM to FMU communication channel + long: | + The MAVLink Mode defines the set of streamed messages (for example the + vehicle's attitude) and their sending rates. + + type: enum + values: + 0: Normal + #1: Custom + 2: Onboard + #3: OSD + #4: Magic + 5: Config + #6: Iridium + 7: Minimal + #8: External Vision + #9: External Vision Minimal + #10: Gimbal + 11: Onboard Low Bandwidth + #12: uAvionix + 13: Low Bandwidth + # We shadow the modes that can block the FMU to SOM connection + reboot_required: true + default: 11 + + MAV_S_FORWARD: + description: + short: Enable MAVLink forwarding on TELEM2 + long : | + TELEM2 on Skynode only. + + type: boolean + reboot_required: true + default: false diff --git a/src/modules/mavlink/streams/AVAILABLE_MODES.hpp b/src/modules/mavlink/streams/AVAILABLE_MODES.hpp index c0d7730188..27e5852129 100644 --- a/src/modules/mavlink/streams/AVAILABLE_MODES.hpp +++ b/src/modules/mavlink/streams/AVAILABLE_MODES.hpp @@ -38,6 +38,7 @@ #include #include #include +#include class MavlinkStreamAvailableModes : public MavlinkStream { @@ -71,6 +72,8 @@ private: char name[sizeof(register_ext_component_reply_s::name)] {}; }; ExternalModeName *_external_mode_names{nullptr}; + uint8_t _not_user_selectable_mask{0}; + static_assert(MAX_NUM_EXTERNAL_MODES <= (sizeof(_not_user_selectable_mask) * CHAR_BIT), "Mask too small"); uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; uORB::Subscription _register_ext_component_reply_sub{ORB_ID(register_ext_component_reply)}; @@ -116,6 +119,10 @@ private: } else if (_external_mode_names) { strncpy(available_modes.mode_name, _external_mode_names[external_mode_index].name, sizeof(available_modes.mode_name)); available_modes.mode_name[sizeof(available_modes.mode_name) - 1] = '\0'; + + if ((_not_user_selectable_mask & (1 << external_mode_index)) > 0) { + available_modes.properties |= MAV_MODE_PROPERTY_NOT_USER_SELECTABLE; + } } } else { // Internal @@ -205,6 +212,13 @@ private: if (_external_mode_names && mode_index < MAX_NUM_EXTERNAL_MODES) { memcpy(_external_mode_names[mode_index].name, reply.name, sizeof(ExternalModeName::name)); + + if (reply.not_user_selectable) { + _not_user_selectable_mask |= (1 << mode_index); + + } else { + _not_user_selectable_mask &= ~(1 << mode_index); + } } dynamic_update = true; diff --git a/src/modules/mavlink/streams/ESC_INFO.hpp b/src/modules/mavlink/streams/ESC_INFO.hpp index 609112ed0a..d4066a2332 100644 --- a/src/modules/mavlink/streams/ESC_INFO.hpp +++ b/src/modules/mavlink/streams/ESC_INFO.hpp @@ -34,7 +34,9 @@ #ifndef ESC_INFO_HPP #define ESC_INFO_HPP +#include #include +#include class MavlinkStreamESCInfo : public MavlinkStream { @@ -49,50 +51,121 @@ public: unsigned get_size() override { - static constexpr unsigned size_per_batch = MAVLINK_MSG_ID_ESC_INFO_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES; - return _esc_status_sub.advertised() ? size_per_batch * _number_of_batches : 0; + static constexpr unsigned message_size = MAVLINK_MSG_ID_ESC_INFO_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES; + return _esc_status_subs.advertised_count() * message_size; } private: explicit MavlinkStreamESCInfo(Mavlink *mavlink) : MavlinkStream(mavlink) {} - uORB::Subscription _esc_status_sub{ORB_ID(esc_status)}; - uint8_t _number_of_batches{0}; + uORB::SubscriptionMultiArray _esc_status_subs{ORB_ID::esc_status}; + + static constexpr uint8_t MAX_ESC_OUTPUTS = 12; // See output_functions.hpp + static constexpr uint8_t ESCS_PER_MSG = MAVLINK_MSG_ESC_INFO_FIELD_TEMPERATURE_LEN; + static constexpr uint8_t MAX_NUM_MSGS = MAX_ESC_OUTPUTS / ESCS_PER_MSG; + + static constexpr hrt_abstime ESC_TIMEOUT = 100000; + + struct EscOutputInterfaceInfo { + uint16_t counter; + uint8_t esc_count; + uint8_t esc_connectiontype; + uint8_t esc_online_flags; + }; + + struct EscInfo { + hrt_abstime timestamp; + uint16_t failure_flags; + uint32_t error_count; + int16_t temperature; + bool online; + }; + + int _total_esc_count = {}; + EscOutputInterfaceInfo _interface[MAX_NUM_MSGS] = {}; + EscInfo _escs[MAX_ESC_OUTPUTS] = {}; + + void update_data() override + { + int subscriber_count = math::min(_esc_status_subs.size(), MAX_NUM_MSGS); + + for (int i = 0; i < subscriber_count; i++) { + esc_status_s esc = {}; + + if (_esc_status_subs[i].update(&esc)) { + _interface[i].counter = esc.counter; + _interface[i].esc_count = esc.esc_count; + _interface[i].esc_connectiontype = esc.esc_connectiontype; + + // Capture online_flags, we will map from index to motor number + uint8_t online_flags = esc.esc_online_flags; + _interface[i].esc_online_flags = 0; + + for (int j = 0; j < esc_status_s::CONNECTED_ESC_MAX; j++) { + bool is_motor = ((int)esc.esc[j].actuator_function >= esc_report_s::ACTUATOR_FUNCTION_MOTOR1) && + ((int)esc.esc[j].actuator_function <= esc_report_s::ACTUATOR_FUNCTION_MOTOR12); + + if (is_motor) { + // Map OutputFunction number to index + int index = (int)esc.esc[j].actuator_function - esc_report_s::ACTUATOR_FUNCTION_MOTOR1; + _escs[index].online = online_flags & (1 << j); + _escs[index].failure_flags = esc.esc[j].failures; + _escs[index].error_count = esc.esc[j].esc_errorcount; + _escs[index].timestamp = esc.esc[j].timestamp; + _escs[index].temperature = esc.esc[j].esc_temperature * 100.f; + } + } + } + } + + int count = 0; + + for (int i = 0; i < MAX_NUM_MSGS; i++) { + count += _interface[i].esc_count; + } + + _total_esc_count = count; + } bool send() override { - static constexpr uint8_t batch_size = MAVLINK_MSG_ESC_INFO_FIELD_TEMPERATURE_LEN; - esc_status_s esc_status; + bool updated = false; - if (_esc_status_sub.update(&esc_status)) { - mavlink_esc_info_t msg{}; + for (int i = 0; i < MAX_NUM_MSGS; i++) { - msg.time_usec = esc_status.timestamp; - msg.counter = esc_status.counter; - msg.count = esc_status.esc_count; - msg.connection_type = esc_status.esc_connectiontype; - msg.info = esc_status.esc_online_flags; + hrt_abstime now = hrt_absolute_time(); - // Ceil value of integer division. For 1-4 esc => 1 batch, 5-8 esc => 2 batches etc - _number_of_batches = ceilf((float)esc_status.esc_count / batch_size); + mavlink_esc_info_t msg = {}; + msg.index = i * ESCS_PER_MSG; + msg.time_usec = now; + msg.counter = _interface[i].counter; + msg.count = _total_esc_count; + msg.connection_type = _interface[i].esc_connectiontype; + msg.info = _interface[i].esc_online_flags; - for (int batch_number = 0; batch_number < _number_of_batches; batch_number++) { - msg.index = batch_number * batch_size; + bool atleast_one_esc_updated = false; - for (int esc_index = 0; esc_index < batch_size ; esc_index++) { - msg.failure_flags[esc_index] = esc_status.esc[esc_index].failures; - msg.error_count[esc_index] = esc_status.esc[esc_index].esc_errorcount; - msg.temperature[esc_index] = static_cast(esc_status.esc[esc_index].esc_temperature * - 100.f); // convert to centiDegrees + for (int j = 0; j < ESCS_PER_MSG; j++) { + + EscInfo &esc = _escs[i * ESCS_PER_MSG + j]; + + msg.info |= (esc.online << j); + + if ((esc.timestamp != 0) && (esc.timestamp + ESC_TIMEOUT) > now) { + msg.failure_flags[j] = esc.failure_flags; + msg.error_count[j] = esc.error_count; + msg.temperature[j] = esc.temperature; + atleast_one_esc_updated = true; } - - mavlink_msg_esc_info_send_struct(_mavlink->get_channel(), &msg); } - return true; + if (atleast_one_esc_updated) { + mavlink_msg_esc_info_send_struct(_mavlink->get_channel(), &msg); + updated = true; + } } - return false; + return updated; } }; diff --git a/src/modules/mavlink/streams/ESC_STATUS.hpp b/src/modules/mavlink/streams/ESC_STATUS.hpp index 54c11cbd8e..925f77ab81 100644 --- a/src/modules/mavlink/streams/ESC_STATUS.hpp +++ b/src/modules/mavlink/streams/ESC_STATUS.hpp @@ -34,7 +34,9 @@ #ifndef ESC_STATUS_HPP #define ESC_STATUS_HPP +#include #include +#include class MavlinkStreamESCStatus : public MavlinkStream { @@ -49,46 +51,88 @@ public: unsigned get_size() override { - static constexpr unsigned size_per_batch = MAVLINK_MSG_ID_ESC_STATUS_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES; - return _esc_status_sub.advertised() ? size_per_batch * _number_of_batches : 0; + static constexpr unsigned message_size = MAVLINK_MSG_ID_ESC_STATUS_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES; + return _esc_status_subs.advertised_count() * message_size; } private: explicit MavlinkStreamESCStatus(Mavlink *mavlink) : MavlinkStream(mavlink) {} - uORB::Subscription _esc_status_sub{ORB_ID(esc_status)}; - uint8_t _number_of_batches{0}; + uORB::SubscriptionMultiArray _esc_status_subs{ORB_ID::esc_status}; + + static constexpr uint8_t MAX_ESC_OUTPUTS = 12; // See output_functions.hpp + static constexpr uint8_t ESCS_PER_MSG = MAVLINK_MSG_ESC_STATUS_FIELD_RPM_LEN; + static constexpr uint8_t MAX_NUM_MSGS = MAX_ESC_OUTPUTS / ESCS_PER_MSG; + static constexpr hrt_abstime ESC_TIMEOUT = 100000; + + struct EscStatus { + hrt_abstime timestamp; + int32_t rpm; + float voltage; + float current; + }; + + EscStatus _escs[MAX_ESC_OUTPUTS] = {}; + + void update_data() override + { + int subscriber_count = math::min(_esc_status_subs.size(), MAX_NUM_MSGS); + + for (int i = 0; i < subscriber_count; i++) { + esc_status_s esc = {}; + + if (_esc_status_subs[i].update(&esc)) { + for (int j = 0; j < esc_status_s::CONNECTED_ESC_MAX; j++) { + + bool is_motor = ((int)esc.esc[j].actuator_function >= esc_report_s::ACTUATOR_FUNCTION_MOTOR1) && + ((int)esc.esc[j].actuator_function <= esc_report_s::ACTUATOR_FUNCTION_MOTOR12); + + if (is_motor) { + // Map OutputFunction number to index + int index = (int)esc.esc[j].actuator_function - esc_report_s::ACTUATOR_FUNCTION_MOTOR1; + _escs[index].timestamp = esc.esc[j].timestamp; + _escs[index].rpm = esc.esc[j].esc_rpm; + _escs[index].voltage = esc.esc[j].esc_voltage; + _escs[index].current = esc.esc[j].esc_current; + } + } + } + } + } bool send() override { - static constexpr uint8_t batch_size = MAVLINK_MSG_ESC_STATUS_FIELD_RPM_LEN; - esc_status_s esc_status; + bool updated = false; - if (_esc_status_sub.update(&esc_status)) { - mavlink_esc_status_t msg{}; + for (int i = 0; i < MAX_NUM_MSGS; i++) { - msg.time_usec = esc_status.timestamp; + hrt_abstime now = hrt_absolute_time(); - // Ceil value of integer division. For 1-4 esc => 1 batch, 5-8 esc => 2 batches etc - _number_of_batches = ceilf((float)esc_status.esc_count / batch_size); + mavlink_esc_status_t msg = {}; + msg.index = i * ESCS_PER_MSG; + msg.time_usec = now; - for (int batch_number = 0; batch_number < _number_of_batches; batch_number++) { - msg.index = batch_number * batch_size; + bool atleast_one_esc_updated = false; - for (int esc_index = 0; esc_index < batch_size - && msg.index + esc_index < esc_status_s::CONNECTED_ESC_MAX; esc_index++) { - msg.rpm[esc_index] = esc_status.esc[msg.index + esc_index].esc_rpm; - msg.voltage[esc_index] = esc_status.esc[msg.index + esc_index].esc_voltage; - msg.current[esc_index] = esc_status.esc[msg.index + esc_index].esc_current; + for (int j = 0; j < ESCS_PER_MSG; j++) { + + EscStatus &esc = _escs[i * ESCS_PER_MSG + j]; + + if ((esc.timestamp != 0) && (esc.timestamp + ESC_TIMEOUT) > now) { + msg.rpm[j] = esc.rpm; + msg.voltage[j] = esc.voltage; + msg.current[j] = esc.current; + atleast_one_esc_updated = true; } - - mavlink_msg_esc_status_send_struct(_mavlink->get_channel(), &msg); } - return true; + if (atleast_one_esc_updated) { + mavlink_msg_esc_status_send_struct(_mavlink->get_channel(), &msg); + updated = true; + } } - return false; + return updated; } }; diff --git a/src/modules/mavlink/streams/GNSS_INTEGRITY.hpp b/src/modules/mavlink/streams/GNSS_INTEGRITY.hpp new file mode 100644 index 0000000000..a7205952e8 --- /dev/null +++ b/src/modules/mavlink/streams/GNSS_INTEGRITY.hpp @@ -0,0 +1,115 @@ +/**************************************************************************** + * + * Copyright (c) 2024 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef GNSS_INTEGRITY_HPP +#define GNSS_INTEGRITY_HPP + + +#include +#include +#include + +using namespace time_literals; + +class MavlinkStreamGNSSIntegrity : public MavlinkStream +{ +public: + static MavlinkStream *new_instance(Mavlink *mavlink) { return new MavlinkStreamGNSSIntegrity(mavlink); } + + static constexpr const char *get_name_static() { return "GNSS_INTEGRITY"; } + static constexpr uint16_t get_id_static() { return MAVLINK_MSG_ID_GNSS_INTEGRITY; } + + const char *get_name() const override { return get_name_static(); } + uint16_t get_id() override { return get_id_static(); } + + unsigned get_size() override + { + return _vehicle_gps_position_sub.advertised() ? (MAVLINK_MSG_ID_GNSS_INTEGRITY_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES) : 0; + } + +private: + static constexpr int GPS_MAX_RECEIVERS = 2; + + explicit MavlinkStreamGNSSIntegrity(Mavlink *mavlink) : MavlinkStream(mavlink) {} + + uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; + uORB::SubscriptionMultiArray _sensor_gnss_status_sub{ORB_ID::sensor_gnss_status}; + + bool send() override + { + sensor_gps_s vehicle_gps_position{}; + + if (_vehicle_gps_position_sub.update(&vehicle_gps_position)) { + mavlink_gnss_integrity_t msg{}; + + msg.id = vehicle_gps_position.device_id; + msg.system_errors = vehicle_gps_position.system_error; + msg.authentication_state = vehicle_gps_position.authentication_state; + msg.jamming_state = vehicle_gps_position.jamming_state; + msg.spoofing_state = vehicle_gps_position.spoofing_state; + + msg.corrections_quality = UINT8_MAX; + msg.system_status_summary = UINT8_MAX; + msg.gnss_signal_quality = UINT8_MAX; + msg.post_processing_quality = UINT8_MAX; + + for (int i = 0; i < GPS_MAX_RECEIVERS; i++) { + sensor_gnss_status_s sensor_gnss_status{}; + + if (_sensor_gnss_status_sub[i].copy(&sensor_gnss_status)) { + if ((hrt_elapsed_time(&sensor_gnss_status.timestamp) < 3_s) + && (sensor_gnss_status.device_id == vehicle_gps_position.device_id) + && (sensor_gnss_status.quality_available)) { + msg.corrections_quality = sensor_gnss_status.quality_corrections; + msg.system_status_summary = sensor_gnss_status.quality_receiver; + msg.gnss_signal_quality = sensor_gnss_status.quality_gnss_signals; + msg.post_processing_quality = sensor_gnss_status.quality_post_processing; + break; + } + } + } + + msg.raim_hfom = UINT16_MAX; + msg.raim_vfom = UINT16_MAX; + + mavlink_msg_gnss_integrity_send_struct(_mavlink->get_channel(), &msg); + + return true; + } + + return false; + } + +}; + +#endif // GNSS_INTEGRITY_HPP diff --git a/src/modules/mavlink/streams/GPS2_RAW.hpp b/src/modules/mavlink/streams/GPS2_RAW.hpp index 08f80877d9..025421e471 100644 --- a/src/modules/mavlink/streams/GPS2_RAW.hpp +++ b/src/modules/mavlink/streams/GPS2_RAW.hpp @@ -68,7 +68,13 @@ private: hrt_abstime now{}; if (_sensor_gps_sub.update(&gps)) { - msg.time_usec = gps.timestamp; + if (gps.time_utc_usec > 0) { + msg.time_usec = gps.timestamp; + + } else { + msg.time_usec = gps.time_utc_usec; + } + msg.fix_type = gps.fix_type; msg.lat = static_cast(round(gps.latitude_deg * 1e7)); msg.lon = static_cast(round(gps.longitude_deg * 1e7)); diff --git a/src/modules/mavlink/streams/GPS_RAW_INT.hpp b/src/modules/mavlink/streams/GPS_RAW_INT.hpp index ca2077d5a7..a3b7620fb7 100644 --- a/src/modules/mavlink/streams/GPS_RAW_INT.hpp +++ b/src/modules/mavlink/streams/GPS_RAW_INT.hpp @@ -68,7 +68,13 @@ private: hrt_abstime now{}; if (_sensor_gps_sub.update(&gps)) { - msg.time_usec = gps.timestamp; + if (gps.time_utc_usec > 0) { + msg.time_usec = gps.timestamp; + + } else { + msg.time_usec = gps.time_utc_usec; + } + msg.fix_type = gps.fix_type; msg.lat = static_cast(round(gps.latitude_deg * 1e7)); msg.lon = static_cast(round(gps.longitude_deg * 1e7)); diff --git a/src/modules/mavlink/streams/HIGHRES_IMU.hpp b/src/modules/mavlink/streams/HIGHRES_IMU.hpp index 7a3d96cb38..c6e4d7580b 100644 --- a/src/modules/mavlink/streams/HIGHRES_IMU.hpp +++ b/src/modules/mavlink/streams/HIGHRES_IMU.hpp @@ -63,7 +63,7 @@ public: private: explicit MavlinkStreamHighresIMU(Mavlink *mavlink) : MavlinkStream(mavlink) {} - uORB::SubscriptionMultiArray _vehicle_imu_subs{ORB_ID::vehicle_imu}; + uORB::SubscriptionMultiArray _vehicle_imu_subs{ORB_ID::vehicle_imu}; uORB::Subscription _estimator_sensor_bias_sub{ORB_ID(estimator_sensor_bias)}; uORB::Subscription _estimator_selector_status_sub{ORB_ID(estimator_selector_status)}; uORB::Subscription _sensor_selection_sub{ORB_ID(sensor_selection)}; @@ -190,8 +190,8 @@ private: msg.xmag = mag(0); msg.ymag = mag(1); msg.zmag = mag(2); - msg.abs_pressure = air_data.baro_pressure_pa; - msg.diff_pressure = differential_pressure.differential_pressure_pa; + msg.abs_pressure = air_data.baro_pressure_pa * 0.01f; // Pa to hPa + msg.diff_pressure = differential_pressure.differential_pressure_pa * 0.01f; // Pa to hPa msg.pressure_alt = air_data.baro_alt_meter; msg.temperature = air_data.ambient_temperature; msg.fields_updated = fields_updated; diff --git a/src/modules/mavlink/streams/HIGH_LATENCY2.hpp b/src/modules/mavlink/streams/HIGH_LATENCY2.hpp index 8723f14131..74ca48d554 100644 --- a/src/modules/mavlink/streams/HIGH_LATENCY2.hpp +++ b/src/modules/mavlink/streams/HIGH_LATENCY2.hpp @@ -685,7 +685,7 @@ private: hrt_abstime _last_update_time{0}; float _update_rate_filtered{0}; - PerBatteryData _batteries[battery_status_s::MAX_INSTANCES] {0, 1, 2, 3}; + PerBatteryData _batteries[battery_status_s::MAX_INSTANCES] {0, 1, 2}; }; #endif // HIGH_LATENCY2_HPP diff --git a/src/modules/mavlink/streams/ODOMETRY.hpp b/src/modules/mavlink/streams/ODOMETRY.hpp index 60b8564bc2..5cf680e2f2 100644 --- a/src/modules/mavlink/streams/ODOMETRY.hpp +++ b/src/modules/mavlink/streams/ODOMETRY.hpp @@ -112,7 +112,7 @@ private: // Row-major representation of a 6x6 pose cross-covariance matrix upper right triangle // (states: x, y, z, roll, pitch, yaw; first six entries are the first ROW, next five entries are the second ROW, etc.) for (auto &pc : msg.pose_covariance) { - pc = NAN; + pc = 0.f; } msg.pose_covariance[0] = odom.position_variance[0]; // X row 0, col 0 @@ -127,7 +127,7 @@ private: // Row-major representation of a 6x6 velocity cross-covariance matrix upper right triangle // (states: vx, vy, vz, rollspeed, pitchspeed, yawspeed; first six entries are the first ROW, next five entries are the second ROW, etc.) for (auto &vc : msg.velocity_covariance) { - vc = NAN; + vc = 0.f; } msg.velocity_covariance[0] = odom.velocity_variance[0]; // X row 0, col 0 diff --git a/src/modules/mavlink/streams/VFR_HUD.hpp b/src/modules/mavlink/streams/VFR_HUD.hpp index 76af7fc39e..c7d5f014d2 100644 --- a/src/modules/mavlink/streams/VFR_HUD.hpp +++ b/src/modules/mavlink/streams/VFR_HUD.hpp @@ -82,9 +82,9 @@ private: airspeed_validated_s airspeed_validated{}; _airspeed_validated_sub.copy(&airspeed_validated); - const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_1 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_2 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_3; + const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_1 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_2 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_3; mavlink_vfr_hud_t msg{}; // display NAN in case of source not being one of the sensors diff --git a/src/modules/mc_att_control/mc_att_control.hpp b/src/modules/mc_att_control/mc_att_control.hpp index 4743d1936d..7c69f45790 100644 --- a/src/modules/mc_att_control/mc_att_control.hpp +++ b/src/modules/mc_att_control/mc_att_control.hpp @@ -126,7 +126,6 @@ private: SlewRate _hover_thrust_slew_rate{.5f}; float _yaw_setpoint_stabilized{0.f}; - bool _heading_good_for_control{true}; // initialized true to have heading lock when local position never published float _unaided_heading{NAN}; // initialized NAN to not distract heading lock when local position never published float _man_tilt_max{0.f}; /**< maximum tilt allowed for manual flight [rad] */ @@ -161,13 +160,12 @@ private: (ParamFloat) _param_mc_yawrate_max, /* Stabilized mode params */ - (ParamFloat) _param_mpc_hold_dz, + (ParamFloat) _param_man_deadzone, (ParamFloat) _param_mpc_man_tilt_max, (ParamFloat) _param_mpc_manthr_min, (ParamFloat) _param_mpc_thr_max, (ParamFloat) _param_mpc_thr_hover, (ParamInt) _param_mpc_thr_curve, - (ParamFloat) _param_mpc_yaw_expo, (ParamFloat) _param_com_spoolup_time ) diff --git a/src/modules/mc_att_control/mc_att_control_main.cpp b/src/modules/mc_att_control/mc_att_control_main.cpp index f79e8ff911..e4dd239eee 100644 --- a/src/modules/mc_att_control/mc_att_control_main.cpp +++ b/src/modules/mc_att_control/mc_att_control_main.cpp @@ -141,13 +141,12 @@ MulticopterAttitudeControl::generate_attitude_setpoint(const Quatf &q, float dt) // Avoid accumulating absolute yaw error with arming stick gesture const bool arming_gesture = (_manual_control_setpoint.throttle < -.9f) && (_param_mc_airmode.get() != 2); - if (arming_gesture || !_heading_good_for_control) { + if (arming_gesture) { _yaw_setpoint_stabilized = NAN; } const float yaw = Eulerf(q).psi(); - const float yaw_stick_input = math::expo_deadzone(_manual_control_setpoint.yaw, _param_mpc_yaw_expo.get(), - _param_mpc_hold_dz.get()); + const float yaw_stick_input = math::expo_deadzone(_manual_control_setpoint.yaw, .6f, _param_man_deadzone.get()); _stick_yaw.generateYawSetpoint(attitude_setpoint.yaw_sp_move_rate, _yaw_setpoint_stabilized, yaw_stick_input, yaw, dt, _unaided_heading); @@ -279,7 +278,6 @@ MulticopterAttitudeControl::Run() vehicle_local_position_s vehicle_local_position; if (_vehicle_local_position_sub.copy(&vehicle_local_position)) { - _heading_good_for_control = vehicle_local_position.heading_good_for_control; _unaided_heading = vehicle_local_position.unaided_heading; } } diff --git a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.cpp b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.cpp index 3d2c0dab7f..c638492067 100644 --- a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.cpp +++ b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.cpp @@ -46,7 +46,6 @@ McAutotuneAttitudeControl::McAutotuneAttitudeControl() : WorkItem(MODULE_NAME, px4::wq_configurations::hp_default) { _autotune_attitude_control_status_pub.advertise(); - reset(); } McAutotuneAttitudeControl::~McAutotuneAttitudeControl() @@ -56,7 +55,8 @@ McAutotuneAttitudeControl::~McAutotuneAttitudeControl() bool McAutotuneAttitudeControl::init() { - if (!_parameter_update_sub.registerCallback()) { + + if (!_vehicle_torque_setpoint_sub.registerCallback()) { PX4_ERR("callback registration failed"); return false; } @@ -66,11 +66,6 @@ bool McAutotuneAttitudeControl::init() return true; } -void McAutotuneAttitudeControl::reset() -{ - _param_mc_at_start.reset(); -} - void McAutotuneAttitudeControl::Run() { if (should_exit()) { @@ -91,17 +86,12 @@ void McAutotuneAttitudeControl::Run() updateStateMachine(hrt_absolute_time()); } - // new control data needed every iteration - if (_state == state::idle - || !_vehicle_torque_setpoint_sub.updated()) { - return; - } - if (_vehicle_status_sub.updated()) { vehicle_status_s vehicle_status; if (_vehicle_status_sub.copy(&vehicle_status)) { _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); + _nav_state = vehicle_status.nav_state; } } @@ -113,6 +103,24 @@ void McAutotuneAttitudeControl::Run() } } + if (_vehicle_command_sub.updated()) { + vehicle_command_s vehicle_command; + + if (_vehicle_command_sub.copy(&vehicle_command)) { + if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_DO_AUTOTUNE_ENABLE) { + if (fabsf(vehicle_command.param1 - 1.0f) < FLT_EPSILON && fabsf(vehicle_command.param2) < FLT_EPSILON) { + _vehicle_cmd_start_autotune = true; + } + } + } + } + + // new control data needed every iteration + if ((_state == state::idle && !_vehicle_cmd_start_autotune) + || !_vehicle_torque_setpoint_sub.updated()) { + return; + } + vehicle_torque_setpoint_s vehicle_torque_setpoint; vehicle_angular_velocity_s angular_velocity; @@ -271,7 +279,7 @@ void McAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) switch (_state) { case state::idle: - if (_param_mc_at_start.get()) { + if (_vehicle_cmd_start_autotune) { if (registerActuatorControlsCallback()) { _state = state::init; @@ -280,6 +288,7 @@ void McAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) } _state_start_time = now; + _start_flight_mode = _nav_state; } break; @@ -438,17 +447,23 @@ void McAutotuneAttitudeControl::updateStateMachine(hrt_abstime now) break; } - // In case of convergence timeout or pilot intervention, + // In case of convergence timeout, pilot intervention or mode change, // the identification sequence is aborted immediately manual_control_setpoint_s manual_control_setpoint{}; _manual_control_setpoint_sub.copy(&manual_control_setpoint); + const bool timeout = (now - _state_start_time) > 20_s; + const bool mode_changed = (_start_flight_mode != _nav_state); + const bool pilot_intervention = ((fabsf(manual_control_setpoint.roll) > 0.05f) + || (fabsf(manual_control_setpoint.pitch) > 0.05f)); + + const bool should_abort = timeout || mode_changed || pilot_intervention; + if (_state != state::wait_for_disarm - && _state != state::idle - && (((now - _state_start_time) > 20_s) - || (fabsf(manual_control_setpoint.roll) > 0.05f) - || (fabsf(manual_control_setpoint.pitch) > 0.05f))) { + && _state != state::idle && should_abort) { + _state = state::fail; + _start_flight_mode = _nav_state; _state_start_time = now; } } @@ -580,8 +595,7 @@ void McAutotuneAttitudeControl::saveGainsToParams() void McAutotuneAttitudeControl::stopAutotune() { - _param_mc_at_start.set(false); - _param_mc_at_start.commit(); + _vehicle_cmd_start_autotune = false; _vehicle_torque_setpoint_sub.unregisterCallback(); } diff --git a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.hpp b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.hpp index 4307edfcd1..cc6ce692e5 100644 --- a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.hpp +++ b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control.hpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -86,8 +87,6 @@ public: private: void Run() override; - void reset(); - void checkFilters(); void updateStateMachine(hrt_abstime now); @@ -109,6 +108,7 @@ private: uORB::Subscription _manual_control_setpoint_sub{ORB_ID(manual_control_setpoint)}; uORB::Subscription _vehicle_angular_velocity_sub{ORB_ID(vehicle_angular_velocity)}; uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; + uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; uORB::PublicationData _autotune_attitude_control_status_pub{ORB_ID(autotune_attitude_control_status)}; @@ -137,6 +137,9 @@ private: int8_t _signal_sign{0}; bool _armed{false}; + uint8_t _nav_state{0}; + uint8_t _start_flight_mode{0}; + bool _vehicle_cmd_start_autotune{false}; matrix::Vector3f _kid{}; matrix::Vector3f _rate_k{}; @@ -177,7 +180,6 @@ private: perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")}; DEFINE_PARAMETERS( - (ParamBool) _param_mc_at_start, (ParamFloat) _param_mc_at_sysid_amp, (ParamInt) _param_mc_at_apply, (ParamFloat) _param_mc_at_rise_time, diff --git a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control_params.c b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control_params.c index 1dc1e43c22..c2df3fd8f6 100644 --- a/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control_params.c +++ b/src/modules/mc_autotune_attitude_control/mc_autotune_attitude_control_params.c @@ -47,24 +47,6 @@ */ PARAM_DEFINE_INT32(MC_AT_EN, 0); -/** - * Start the autotuning sequence - * - * WARNING: this will inject steps to the rate controller - * and can be dangerous. Only activate if you know what you - * are doing, and in a safe environment. - * - * Any motion of the remote stick will abort the signal - * injection and reset this parameter - * Best is to perform the identification in position or - * hold mode. - * Increase the amplitude of the injected signal using - * MC_AT_SYSID_AMP for more signal/noise ratio - * - * @boolean - * @group Autotune - */ -PARAM_DEFINE_INT32(MC_AT_START, 0); /** * Amplitude of the injected signal diff --git a/src/modules/mc_pos_control/GotoControl/GotoControl.cpp b/src/modules/mc_pos_control/GotoControl/GotoControl.cpp index a266a5ec1b..663c3a969c 100644 --- a/src/modules/mc_pos_control/GotoControl/GotoControl.cpp +++ b/src/modules/mc_pos_control/GotoControl/GotoControl.cpp @@ -42,6 +42,7 @@ #include using namespace time_literals; +using namespace matrix; bool GotoControl::checkForSetpoint(const hrt_abstime &now, const bool enabled) { @@ -64,10 +65,11 @@ bool GotoControl::checkForSetpoint(const hrt_abstime &now, const bool enabled) return need_to_run; } -void GotoControl::update(const float dt, const matrix::Vector3f &position, const float heading) +void GotoControl::update(const float dt, const Vector3f &position, const Vector3f &velocity, const Vector3f &acceleration, + const float heading) { if (!_is_initialized) { - resetPositionSmoother(position); + resetPositionSmoother(position, velocity, acceleration); resetHeadingSmoother(heading); _is_initialized = true; } @@ -87,7 +89,7 @@ void GotoControl::update(const float dt, const matrix::Vector3f &position, const } if (_need_smoother_reset) { - resetPositionSmoother(position); + resetPositionSmoother(position, velocity, acceleration); } setPositionSmootherLimits(_goto_setpoint); @@ -138,7 +140,7 @@ void GotoControl::update(const float dt, const matrix::Vector3f &position, const _vehicle_constraints_pub.publish(vehicle_constraints); } -void GotoControl::resetPositionSmoother(const matrix::Vector3f &position) +void GotoControl::resetPositionSmoother(const Vector3f &position, const Vector3f &velocity, const Vector3f &acceleration) { if (!position.isAllFinite()) { // TODO: error messaging @@ -146,9 +148,7 @@ void GotoControl::resetPositionSmoother(const matrix::Vector3f &position) return; } - const Vector3f initial_acceleration{}; - const Vector3f initial_velocity{}; - _position_smoothing.reset(initial_acceleration, initial_velocity, position); + _position_smoothing.reset(acceleration, velocity, position); _need_smoother_reset = false; } diff --git a/src/modules/mc_pos_control/GotoControl/GotoControl.hpp b/src/modules/mc_pos_control/GotoControl/GotoControl.hpp index f9ff08f9ca..4ae7aa9ec8 100644 --- a/src/modules/mc_pos_control/GotoControl/GotoControl.hpp +++ b/src/modules/mc_pos_control/GotoControl/GotoControl.hpp @@ -64,9 +64,11 @@ public: /** * @brief resets the position smoother at the current position with zero velocity and acceleration. * - * @param position [m] (NED) local vehicle position + * @param position [m] vehicle position state NED local frame + * @param velocity [m/s] vehicle velocity state + * @param acceleration [m/s^2] vehicle acceleration state */ - void resetPositionSmoother(const matrix::Vector3f &position); + void resetPositionSmoother(const matrix::Vector3f &position, const matrix::Vector3f &velocity, const matrix::Vector3f &acceleration); /** * @brief resets the heading smoother at the current heading with zero heading rate and acceleration. @@ -80,12 +82,15 @@ public: * loops to track. * * @param[in] dt [s] time since last control update - * @param[in] position [m] (NED) local vehicle position + * @param[in] position [m] vehicle position state NED local frame + * @param[in] velocity [m/s] vehicle velocity state + * @param[in] acceleration [m/s^2] vehicle acceleration state * @param[in] heading [rad] (from North) vehicle heading * @param[in] goto_setpoint struct containing current go-to setpoints * @param[out] trajectory_setpoint struct containing trajectory (tracking) setpoints */ - void update(const float dt, const matrix::Vector3f &position, const float heading); + void update(const float dt, const matrix::Vector3f &position, const matrix::Vector3f &velocity, const matrix::Vector3f &acceleration, + const float heading); // Setting all parameters from the outside saves 300bytes flash void setParamMpcAccHor(const float param_mpc_acc_hor) { _param_mpc_acc_hor = param_mpc_acc_hor; } diff --git a/src/modules/mc_pos_control/MulticopterPositionControl.cpp b/src/modules/mc_pos_control/MulticopterPositionControl.cpp index 0501dadcc8..fe5f138050 100644 --- a/src/modules/mc_pos_control/MulticopterPositionControl.cpp +++ b/src/modules/mc_pos_control/MulticopterPositionControl.cpp @@ -408,6 +408,7 @@ void MulticopterPositionControl::Run() } else if (previous_position_control_enabled && !_vehicle_control_mode.flag_multicopter_position_control_enabled) { // clear existing setpoint when controller is no longer active _setpoint = PositionControl::empty_trajectory_setpoint; + _control.setInputSetpoint(_setpoint); } } } @@ -432,7 +433,7 @@ void MulticopterPositionControl::Run() && !_trajectory_setpoint_sub.updated(); if (_goto_control.checkForSetpoint(vehicle_local_position.timestamp_sample, goto_setpoint_enable)) { - _goto_control.update(dt, states.position, states.yaw); + _goto_control.update(dt, states.position, states.velocity, states.acceleration, states.yaw); } _trajectory_setpoint_sub.update(&_setpoint); diff --git a/src/modules/mc_pos_control/PositionControl/PositionControl.cpp b/src/modules/mc_pos_control/PositionControl/PositionControl.cpp index 72ae5a4a31..30e35f3235 100644 --- a/src/modules/mc_pos_control/PositionControl/PositionControl.cpp +++ b/src/modules/mc_pos_control/PositionControl/PositionControl.cpp @@ -84,8 +84,11 @@ void PositionControl::updateHoverThrust(const float hover_thrust_new) const float previous_hover_thrust = _hover_thrust; setHoverThrust(hover_thrust_new); - _vel_int(2) += (_acc_sp(2) - CONSTANTS_ONE_G) * previous_hover_thrust / _hover_thrust - + CONSTANTS_ONE_G - _acc_sp(2); + if (PX4_ISFINITE(_acc_sp(2))) { + _vel_int(2) += (_acc_sp(2) - CONSTANTS_ONE_G) * previous_hover_thrust / _hover_thrust + + CONSTANTS_ONE_G - _acc_sp(2); + } + } void PositionControl::setState(const PositionControlStates &states) diff --git a/src/modules/mc_pos_control/multicopter_nudging_params.c b/src/modules/mc_pos_control/multicopter_nudging_params.c index c431e88fd0..89f8f9714f 100644 --- a/src/modules/mc_pos_control/multicopter_nudging_params.c +++ b/src/modules/mc_pos_control/multicopter_nudging_params.c @@ -53,13 +53,17 @@ PARAM_DEFINE_INT32(MPC_LAND_RC_HELP, 0); /** * User assisted landing radius * - * When nudging is enabled (see MPC_LAND_RC_HELP), this controls - * the maximum allowed horizontal displacement from the original landing point. + * When nudging is enabled (see MPC_LAND_RC_HELP), this defines the maximum + * allowed horizontal displacement from the original landing point. + * - If inside of the radius, only allow nudging inputs that do not move the vehicle outside of it. + * - If outside of the radius, only allow nudging inputs that move the vehicle back towards it. + * + * Set it to -1 for infinite radius. * * @unit m - * @min 0 + * @min -1 * @decimal 0 * @increment 1 * @group Multicopter Position Control */ -PARAM_DEFINE_FLOAT(MPC_LAND_RADIUS, 1000.f); +PARAM_DEFINE_FLOAT(MPC_LAND_RADIUS, -1.0f); diff --git a/src/modules/mc_pos_control/multicopter_position_mode_params.c b/src/modules/mc_pos_control/multicopter_position_mode_params.c index b70bb95a3e..97c905f819 100644 --- a/src/modules/mc_pos_control/multicopter_position_mode_params.c +++ b/src/modules/mc_pos_control/multicopter_position_mode_params.c @@ -129,67 +129,3 @@ PARAM_DEFINE_FLOAT(MPC_ACC_HOR_MAX, 5.f); * @group Multicopter Position Control */ PARAM_DEFINE_FLOAT(MPC_JERK_MAX, 8.f); - -/** - * Deadzone for sticks in manual piloted modes - * - * Does not apply to manual throttle and direct attitude piloting by stick. - * - * @min 0 - * @max 1 - * @decimal 2 - * @increment 0.01 - * @group Multicopter Position Control - */ -PARAM_DEFINE_FLOAT(MPC_HOLD_DZ, 0.1f); - -/** - * Manual position control stick exponential curve sensitivity - * - * The higher the value the less sensitivity the stick has around zero - * while still reaching the maximum value with full stick deflection. - * - * 0 Purely linear input curve - * 1 Purely cubic input curve - * - * @min 0 - * @max 1 - * @decimal 2 - * @increment 0.01 - * @group Multicopter Position Control - */ -PARAM_DEFINE_FLOAT(MPC_XY_MAN_EXPO, 0.6f); - -/** - * Manual control stick vertical exponential curve - * - * The higher the value the less sensitivity the stick has around zero - * while still reaching the maximum value with full stick deflection. - * - * 0 Purely linear input curve - * 1 Purely cubic input curve - * - * @min 0 - * @max 1 - * @decimal 2 - * @increment 0.01 - * @group Multicopter Position Control - */ -PARAM_DEFINE_FLOAT(MPC_Z_MAN_EXPO, 0.6f); - -/** - * Manual control stick yaw rotation exponential curve - * - * The higher the value the less sensitivity the stick has around zero - * while still reaching the maximum value with full stick deflection. - * - * 0 Purely linear input curve - * 1 Purely cubic input curve - * - * @min 0 - * @max 1 - * @decimal 2 - * @increment 0.01 - * @group Multicopter Position Control - */ -PARAM_DEFINE_FLOAT(MPC_YAW_EXPO, 0.6f); diff --git a/src/modules/mc_pos_control/multicopter_stabilized_mode_params.c b/src/modules/mc_pos_control/multicopter_stabilized_mode_params.c index 6229b18bc5..c804a034bb 100644 --- a/src/modules/mc_pos_control/multicopter_stabilized_mode_params.c +++ b/src/modules/mc_pos_control/multicopter_stabilized_mode_params.c @@ -32,7 +32,7 @@ ****************************************************************************/ /** - * Maximal tilt angle in Stabilized or Altitude mode + * Maximal tilt angle in Stabilized, Altitude and Altitude Cruise mode * * @unit deg * @min 1 diff --git a/src/modules/mc_raptor/CHECKLIST.md b/src/modules/mc_raptor/CHECKLIST.md new file mode 100644 index 0000000000..ce2ca6be47 --- /dev/null +++ b/src/modules/mc_raptor/CHECKLIST.md @@ -0,0 +1,3 @@ +# Checklist +1. Check the `REMAP_CRAZYFLIE` flag (this remaps the Crazyflie outputs to the PX4 SIH inputs) +2. Check the `CONTROL_MULTIPLE` setting (this controls how much faster the control loop is than the simulation/step frequency during training. This is needed to aggregate e.g. 4 steps of action history into one step of the policy input) diff --git a/src/modules/mc_raptor/CMakeLists.txt b/src/modules/mc_raptor/CMakeLists.txt new file mode 100644 index 0000000000..5cde791827 --- /dev/null +++ b/src/modules/mc_raptor/CMakeLists.txt @@ -0,0 +1,21 @@ +include(px4_add_library) + +px4_add_git_submodule(TARGET git_raptor_blob PATH "blob") + +px4_add_module( + MODULE modules__mc_raptor + MAIN mc_raptor + STACK_MAIN 4000 + SRCS + mc_raptor.cpp + MODULE_CONFIG + module.yaml + DEPENDS + px4_work_queue + rl_tools + git_raptor_blob + EXTERNAL + ) + +target_compile_features(modules__mc_raptor PRIVATE cxx_std_17) +target_compile_options(modules__mc_raptor PRIVATE -Wno-unused-result) diff --git a/src/modules/mc_raptor/Kconfig b/src/modules/mc_raptor/Kconfig new file mode 100644 index 0000000000..a99c05db70 --- /dev/null +++ b/src/modules/mc_raptor/Kconfig @@ -0,0 +1,12 @@ +menuconfig MODULES_MC_RAPTOR + bool "mc_raptor" + default n + ---help--- + Enable support for mc_raptor + +menuconfig USER_MC_RAPTOR + bool "mc_raptor running as userspace module" + default n + depends on BOARD_PROTECTED && MODULES_MC_RAPTOR + ---help--- + Put mc_raptor in userspace memory diff --git a/src/modules/mc_raptor/README.md b/src/modules/mc_raptor/README.md new file mode 100644 index 0000000000..753187b43e --- /dev/null +++ b/src/modules/mc_raptor/README.md @@ -0,0 +1,116 @@ +# RAPTOR + + +## SITL +#### Standalone Usage (Without External Trajectory Setpoint) +Build PX4 SITL with Raptor, disable QGC requirement, and adjust the `IMU_GYRO_RATEMAX` to match the simulation IMU rate +```bash +make px4_sitl_raptor gz_x500 +param set NAV_DLL_ACT 0 +param set COM_DISARM_LAND -1 # When taking off in offboard the landing detector can cause mid-air disarms +param set IMU_GYRO_RATEMAX 250 # Just for SITL. Tested with IMU_GYRO_RATEMAX=400 on real FCUs +param set MC_RAPTOR_ENABLE 1 +param set MC_RAPTOR_OFFB 0 +param save +``` +Upload the RAPTOR checkpoint to the "SD card": Separate terminal +```bash +mavproxy.py --master udp:127.0.0.1:14540 +ftp mkdir /raptor # for the real FMU use: /fs/microsd/raptor +ftp put src/modules/mc_raptor/blob/policy.tar /raptor/policy.tar +``` +restart (ctrl+c) +```bash +make px4_sitl_raptor gz_x500 +commander takeoff +commander status +``` + +Note the external mode ID of `RAPTOR` in the status report + +```bash +commander mode ext{RAPTOR_MODE_ID} +``` + + +#### Usage with External Trajectory Setpoint + + +Send Lissajous setpoints via Mavlink: +```bash +pip install px4 +px4 udp:localhost:14540 track lissajous --A 2.0 --B 1.0 --duration 10 --ramp-duration 5 --takeoff 10.0 --iterations 2 +``` + + +## SIH +```bash +make px4_fmu-v6c_raptor upload +``` +In QGroundControl: +- Airframes => SIH Quadrotor X +- Settings => Comm Links => Disable Pixhawk (disable automatic USB serial connection) +```bash +mavproxy.py --master /dev/serial/by-id/usb-Auterion_PX4_FMU_v6C.x_0-if00 --out udp:localhost:14550 --out udp:localhost:13337 --out udp:localhost:13338 +``` +New terminal (optional): +```bash +./Tools/mavlink_shell.py udp:localhost:13338 +``` + +```bash +param set SIH_IXX 0.005 +param set SIH_IYY 0.005 +param set SIH_IZZ 0.010 +param set IMU_GYRO_RATEMAX 400 +param save +reboot +``` + +New terminal: +```bash +./Tools/simulation/jmavsim/jmavsim_run.sh -u -p 13337 -o +``` + + +## Real World +Using a DroneBridge WiFi telemetry @ 1000000 baud (also set `SER_TEL1_BAUD=1000000`) and maximum packet size = 16. It seems like larger maximum packet sizes can lead to delays in forwarding the `SET_POSITION_TARGET_LOCAL_NED` messages to `trajectory_setpoint`. +```bash +./Tools/mavlink_shell.py tcp:192.168.2.1:5760 +``` +```bash +px4 tcp:192.168.2.1:5760 track lissajous --A 0.5 --B 0.5 --duration 10 --ramp-duration 5 --takeoff 1.0 --iterations 2 +``` + + +## Troubleshooting + + +```bash +cat > logger_topics.txt << EOF +raptor_status 0 +raptor_input 0 +trajectory_setpoint 0 +vehicle_local_position 0 +vehicle_angular_velocity 0 +vehicle_attitude 0 +vehicle_status 0 +actuator_motors 0 +EOF +``` +```bash +mavproxy.py +``` +```bash +ftp mkdir /fs/microsd/etc +ftp mkdir /fs/microsd/etc/logging +ftp put logger_topics.txt /fs/microsd/etc/logging/logger_topics.txt +``` + +For SITL: + +```bash +ftp mkdir etc +ftp mkdir logging +ftp put logger_topics.txt etc/logging/logger_topics.txt +``` diff --git a/src/modules/mc_raptor/blob b/src/modules/mc_raptor/blob new file mode 160000 index 0000000000..4f31fc9736 --- /dev/null +++ b/src/modules/mc_raptor/blob @@ -0,0 +1 @@ +Subproject commit 4f31fc97366487e460e44a43054756a085ab6cb7 diff --git a/src/modules/mc_raptor/mc_raptor.cpp b/src/modules/mc_raptor/mc_raptor.cpp new file mode 100644 index 0000000000..4d3f0d486c --- /dev/null +++ b/src/modules/mc_raptor/mc_raptor.cpp @@ -0,0 +1,1077 @@ +#include "mc_raptor.hpp" +#undef OK + +#include +#include + +#include + +Raptor::Raptor(): ModuleParams(nullptr), ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::rate_ctrl) +{ + // node state + timestamp_last_angular_velocity_set = false; + timestamp_last_local_position_set = false; + timestamp_last_attitude_set = false; + timestamp_last_trajectory_setpoint_set = false; + timestamp_last_vehicle_status_set = false; + previous_trajectory_setpoint_stale = false; + previous_active = false; + timeout_message_sent = false; + timestamp_last_policy_frequency_check_set = false; + last_intermediate_status_set = false; + last_native_status_set = false; + policy_frequency_check_counter = 0; + flightmode_state = FlightModeState::UNREGISTERED; + can_arm = false; + trajectory_setpoint_dt_index = 0; + trajectory_setpoint_dts_full = false; + trajectory_setpoint_invalid_count = 0; + trajectory_setpoint_dt_max_since_reset = 0; + internal_reference_activation_position[0] = 0.0f; + internal_reference_activation_position[1] = 0.0f; + internal_reference_activation_position[2] = 0.0f; + internal_reference_params_changed = false; + + _actuator_motors_pub.advertise(); + _tune_control_pub.advertise(); +} +void Raptor::reset() +{ + + trajectory_setpoint_dt_index = 0; + trajectory_setpoint_dts_full = false; + trajectory_setpoint_invalid_count = 0; + trajectory_setpoint_dt_max_since_reset = 0; + timestamp_last_trajectory_setpoint_set = false; + + + for (TI action_i = 0; action_i < EXECUTOR_SPEC::OUTPUT_DIM; action_i++) { + this->previous_action[action_i] = RESET_PREVIOUS_ACTION_VALUE; + } + + rlt::reset(device, executor, policy, rng); +} + +Raptor::~Raptor() +{ + perf_free(_loop_perf); + perf_free(_loop_interval_perf); +} + +#ifdef MC_RAPTOR_EMBED_POLICY +bool Raptor::test_policy() +{ +#else +bool Raptor::test_policy(FILE *f, TI input_offset, TI output_offset) +{ +#endif + using namespace rl_tools::inference::applications::l2f; +#ifndef RL_TOOLS_DISABLE_TEST + // This tests the policy using a known input output pair that has been saved into the policy checkpoint to verify that it has been loaded correctly + using POLICY = EXECUTOR_CONFIG::POLICY_TEST; + POLICY::template Buffer buffers_test; + POLICY::State policy_state_test; + rl_tools::Tensor, false>> + test_output; + rl_tools::Mode> mode; + using EXAMPLE_INPUT_SPEC = MC_RAPTOR_EXAMPLE_NAMESPACE::input::SPEC; + using EXAMPLE_OUTPUT_SPEC = MC_RAPTOR_EXAMPLE_NAMESPACE::output::SPEC; + float acc = 0; + uint64_t num_values = 0; + rl_tools::inference::applications::l2f::Action action; + + for (TI batch_i = 0; batch_i < EXECUTOR_CONFIG::TEST_BATCH_SIZE_ACTUAL; batch_i++) { + rl_tools::reset(device, policy, policy_state_test, rng); + + for (TI step_i = 0; step_i < EXECUTOR_CONFIG::TEST_SEQUENCE_LENGTH_ACTUAL; step_i++) { +#ifdef MC_RAPTOR_EMBED_POLICY + const auto step_input = rl_tools::view(device, MC_RAPTOR_EXAMPLE_NAMESPACE::input::container, step_i); + const auto batch_input = rl_tools::view_range(device, step_input, batch_i, rlt::tensor::ViewSpec<0, 1> {}); + const auto step_output_target = rl_tools::view(device, MC_RAPTOR_EXAMPLE_NAMESPACE::output::container, step_i); + const auto batch_output_target = rl_tools::view_range(device, step_output_target, batch_i, rlt::tensor::ViewSpec<0, 1> {}); +#else + rl_tools::Tensor, false>> + batch_input; + rl_tools::Tensor, false>> + batch_output_target; + fseek(f, input_offset + (step_i * EXAMPLE_INPUT_SPEC::STRIDE::FIRST + batch_i * EXAMPLE_INPUT_SPEC::STRIDE::template GET<1>)*sizeof( + EXAMPLE_INPUT_SPEC::T), SEEK_SET); + fread(batch_input._data, sizeof(EXAMPLE_INPUT_SPEC::T), EXAMPLE_INPUT_SPEC::SHAPE::LAST, f); + fseek(f, output_offset + (step_i * EXAMPLE_OUTPUT_SPEC::STRIDE::FIRST + batch_i * EXAMPLE_OUTPUT_SPEC::STRIDE::template GET<1>)*sizeof( + EXAMPLE_OUTPUT_SPEC::T), SEEK_SET); + fread(batch_output_target._data, sizeof(EXAMPLE_OUTPUT_SPEC::T), EXAMPLE_OUTPUT_SPEC::SHAPE::LAST, f); +#endif + rl_tools::utils::assert_exit(device, !rl_tools::is_nan(device, batch_input), "input is nan"); + rl_tools::evaluate_step(device, policy, batch_input, policy_state_test, test_output, buffers_test, rng, mode); + rl_tools::utils::assert_exit(device, !rl_tools::is_nan(device, test_output), "output is nan"); + + for (TI action_i = 0; action_i < EXECUTOR_CONFIG::OUTPUT_DIM; action_i++) { + acc += rl_tools::math::abs(device.math, rl_tools::get(device, test_output, 0, action_i) - rl_tools::get(device, batch_output_target, 0, + action_i)); + num_values += 1; + rl_tools::utils::assert_exit(device, !rl_tools::math::is_nan(device.math, acc), "output is nan"); + + if (batch_i == 0 && step_i == EXECUTOR_CONFIG::TEST_SEQUENCE_LENGTH_ACTUAL - 1) { + action.action[action_i] = rl_tools::get(device, test_output, 0, action_i); + } + } + } + } + + float abs_diff = acc / num_values; + PX4_INFO("Checkpoint test diff: %f", (double)abs_diff); + + for (TI output_i = 0; output_i < EXECUTOR_CONFIG::OUTPUT_DIM; output_i++) { + PX4_INFO("output[%d]: %f", (int)output_i, (double)action.action[output_i]); + } + + constexpr float EPSILON = 1e-5; + + bool healthy = abs_diff < EPSILON; + + if (!healthy) { + PX4_ERR("Checkpoint test failed with diff %.10f", (double)abs_diff); + return false; + + } else { + PX4_INFO("Checkpoint test passed with diff %.10f", (double)abs_diff); + return true; + } + +#else + return 0; +#endif +} + +bool Raptor::init() +{ + this->init_time = hrt_absolute_time(); + + if (!_vehicle_angular_velocity_sub.registerCallback()) { + PX4_ERR("vehicle_angular_velocity_sub callback registration failed"); + return false; + } + +#ifndef MC_RAPTOR_EMBED_POLICY + const char *path = PX4_STORAGEDIR "/raptor/policy.tar"; + + struct stat st; + bool file_exists = (stat(path, &st) == 0); + + if (file_exists) { + PX4_INFO("Policy checkpoint %s exists", path); + FILE *f = fopen(path, "rb"); + + if (!f) { + PX4_ERR("Failed to open %s: %s", path, strerror(errno)); + return false; + } + + if (fseek(f, 0, SEEK_END) != 0) { + PX4_ERR("fseek failed: %s", strerror(errno)); + fclose(f); + return false; + } + + long size = ftell(f); + + if (size < 0) { + PX4_ERR("ftell failed: %s", strerror(errno)); + fclose(f); + return false; + + } else { + rewind(f); + bool successfully_loaded = false; + using SPEC = rlt::persist::backends::tar::ReaderGroupSpecification>; + rlt::persist::backends::tar::ReaderGroup reader_group; + reader_group.data.f = f; + reader_group.data.size = size; + auto actor_group = rlt::get_group(device, reader_group, "actor"); + successfully_loaded = rlt::load(device, policy, actor_group); + constexpr TI METADATA_BUFFER_SIZE = 256; + char metadata_buffer[METADATA_BUFFER_SIZE]; + TI read_size = 0; + rlt::persist::backends::tar::get(device, reader_group.data, "actor/meta", metadata_buffer, METADATA_BUFFER_SIZE, read_size); + TI checkpoint_name_position = 0; + TI checkpoint_name_len = 0; + + if (rlt::persist::backends::tar::seek_in_metadata(device, metadata_buffer, METADATA_BUFFER_SIZE, "checkpoint_name", + checkpoint_name_position, checkpoint_name_len)) { + strncpy(checkpoint_name, metadata_buffer + checkpoint_name_position, CHECKPOINT_NAME_LENGTH); + checkpoint_name[checkpoint_name_len < CHECKPOINT_NAME_LENGTH ? checkpoint_name_len : CHECKPOINT_NAME_LENGTH - 1] = '\0'; + + } else { + PX4_ERR("Failed to get checkpoint name from metadata"); + return false; + } + + if (successfully_loaded) { + PX4_INFO("Policy loaded from file %s", path); + TI input_offset = 0; + TI input_size = 0; + rlt::persist::backends::tar::seek(device, reader_group.data, "example/input/data", input_offset, input_size); + PX4_INFO("Input offset: %d", (int)input_offset); + TI output_offset = 0; + TI output_size = 0; + rlt::persist::backends::tar::seek(device, reader_group.data, "example/output/data", output_offset, output_size); + PX4_INFO("Output offset: %d", (int)output_offset); + + if (!test_policy(f, input_offset, output_offset)) { + PX4_ERR("Checkpoint test failed"); + return false; + } + + } else { + PX4_ERR("Failed to load policy from file %s", path); + return false; + } + + fclose(f); + } + + } else { + PX4_INFO("File %s does not exist", path); + return false; + } + +#else + + strncpy(checkpoint_name, MC_RAPTOR_META_NAMESPACE::name, CHECKPOINT_NAME_LENGTH); + + if (!test_policy()) { + PX4_ERR("Checkpoint test failed"); + return false; + } + +#endif + PX4_INFO("Checkpoint name: %s", checkpoint_name); + + + register_ext_component_request_s register_ext_component_request{}; + register_ext_component_request.timestamp = hrt_absolute_time(); + strncpy(register_ext_component_request.name, "RAPTOR", sizeof(register_ext_component_request.name) - 1); + register_ext_component_request.request_id = Raptor::EXT_COMPONENT_REQUEST_ID; + register_ext_component_request.px4_ros2_api_version = 1; + register_ext_component_request.register_arming_check = true; + register_ext_component_request.register_mode = true; + register_ext_component_request.enable_replace_internal_mode = _param_mc_raptor_offboard.get(); + register_ext_component_request.replace_internal_mode = vehicle_status_s::NAVIGATION_STATE_OFFBOARD; + _register_ext_component_request_pub.publish(register_ext_component_request); + + int32_t imu_gyro_ratemax = _param_imu_gyro_ratemax.get(); + + if (imu_gyro_ratemax % POLICY_CONTROL_FREQUENCY_TRAINING != 0) { + PX4_WARN("IMU_GYRO_RATEMAX=%d Hz is not a multiple of the training frequency (%d Hz)", (int)imu_gyro_ratemax, + (int)POLICY_CONTROL_FREQUENCY_TRAINING); + } + + int32_t force_sync_native = imu_gyro_ratemax / POLICY_CONTROL_FREQUENCY_TRAINING; + executor.executor.force_sync_native = force_sync_native; + executor.executor.force_sync_native_initialized = true; + PX4_INFO("IMU_GYRO_RATEMAX=%d Hz", (int)imu_gyro_ratemax); + PX4_INFO("POLICY_CONTROL_FREQUENCY_TRAINING=%d Hz", (int)POLICY_CONTROL_FREQUENCY_TRAINING); + PX4_INFO("Setting force_sync_native = %d Hz / %d Hz = %d", (int)imu_gyro_ratemax, (int)POLICY_CONTROL_FREQUENCY_TRAINING, + (int)force_sync_native); + + this->use_internal_reference = _param_mc_raptor_intref.get(); + + this->reset(); + + return true; +} +template +T clip(T x, T max, T min) +{ + if (x > max) { + return max; + } + + if (x < min) { + return min; + } + + return x; +} +template +void quaternion_multiplication(T q1[4], T q2[4], T q_res[4]) +{ + q_res[0] = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3]; + q_res[1] = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2]; + q_res[2] = q1[0] * q2[2] - q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1]; + q_res[3] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0]; +} +template +void quaternion_conjugate(T q[4], T q_res[4]) +{ + q_res[0] = +q[0]; + q_res[1] = -q[1]; + q_res[2] = -q[2]; + q_res[3] = -q[3]; +} +template +void quaternion_to_rotation_matrix(T q[4], T R[9]) +{ + // row-major + T qw = q[0]; + T qx = q[1]; + T qy = q[2]; + T qz = q[3]; + + R[0] = 1 - 2 * qy * qy - 2 * qz * qz; + R[1] = 2 * qx * qy - 2 * qw * qz; + R[2] = 2 * qx * qz + 2 * qw * qy; + R[3] = 2 * qx * qy + 2 * qw * qz; + R[4] = 1 - 2 * qx * qx - 2 * qz * qz; + R[5] = 2 * qy * qz - 2 * qw * qx; + R[6] = 2 * qx * qz - 2 * qw * qy; + R[7] = 2 * qy * qz + 2 * qw * qx; + R[8] = 1 - 2 * qx * qx - 2 * qy * qy; +} + +template +void rotate_vector(T R[9], T v[3], T v_rotated[3]) +{ + v_rotated[0] = R[0] * v[0] + R[1] * v[1] + R[2] * v[2]; + v_rotated[1] = R[3] * v[0] + R[4] * v[1] + R[5] * v[2]; + v_rotated[2] = R[6] * v[0] + R[7] * v[1] + R[8] * v[2]; +} + +void Raptor::observe(rl_tools::inference::applications::l2f::Observation &observation) +{ + // converting from FRD to FLU + T Rt_inv[9]; + + { + // Orientation + // FRD to FLU + T q_target[4]; + q_target[0] = cosf(0.5f * _trajectory_setpoint.yaw); // minus because the setpoint yaw is in NED + q_target[1] = 0; + q_target[2] = 0; + q_target[3] = sinf(0.5f * _trajectory_setpoint.yaw); + + T qt[4], qtc[4], qr[4]; + qt[0] = +q_target[0]; // conjugate to build the difference between setpoint and current + qt[1] = +q_target[1]; + qt[2] = -q_target[2]; + qt[3] = -q_target[3]; + quaternion_conjugate(qt, qtc); + quaternion_to_rotation_matrix(qtc, Rt_inv); + + qr[0] = +_vehicle_attitude.q[0]; + qr[1] = +_vehicle_attitude.q[1]; + qr[2] = -_vehicle_attitude.q[2]; + qr[3] = -_vehicle_attitude.q[3]; + // qr = qt * qd + // qd = qt' * qr + T qd[4]; + quaternion_multiplication(qtc, qr, qd); + + observation.orientation[0] = qd[0]; + observation.orientation[1] = qd[1]; + observation.orientation[2] = qd[2]; + observation.orientation[3] = qd[3]; + } + + { + // Position + T p[3], pt[3]; // FLU + p[0] = +(position[0] - _trajectory_setpoint.position[0]); + p[1] = -(position[1] - _trajectory_setpoint.position[1]); + p[2] = -(position[2] - _trajectory_setpoint.position[2]); + rotate_vector(Rt_inv, p, pt); // The position and velocity error are in the target frame + observation.position[0] = clip(pt[0], max_position_error, -max_position_error); + observation.position[1] = clip(pt[1], max_position_error, -max_position_error); + observation.position[2] = clip(pt[2], max_position_error, -max_position_error); + } + { + // Linear Velocity + T v[3], vt[3]; + v[0] = +(linear_velocity[0] - _trajectory_setpoint.velocity[0]); + v[1] = -(linear_velocity[1] - _trajectory_setpoint.velocity[1]); + v[2] = -(linear_velocity[2] - _trajectory_setpoint.velocity[2]); + rotate_vector(Rt_inv, v, vt); + observation.linear_velocity[0] = clip(vt[0], max_velocity_error, -max_velocity_error); + observation.linear_velocity[1] = clip(vt[1], max_velocity_error, -max_velocity_error); + observation.linear_velocity[2] = clip(vt[2], max_velocity_error, -max_velocity_error); + } + { + // Angular Velocity + observation.angular_velocity[0] = +_vehicle_angular_velocity.xyz[0]; + observation.angular_velocity[1] = -_vehicle_angular_velocity.xyz[1]; + observation.angular_velocity[2] = -_vehicle_angular_velocity.xyz[2]; + } + + for (TI action_i = 0; action_i < EXECUTOR_CONFIG::OUTPUT_DIM; action_i++) { + observation.previous_action[action_i] = this->previous_action[action_i]; + } +} + + +void Raptor::updateArmingCheckReply() +{ + if (flightmode_state == FlightModeState::CONFIGURED) { + if (_arming_check_request_sub.updated()) { + arming_check_request_s arming_check_request; + _arming_check_request_sub.copy(&arming_check_request); + arming_check_reply_s arming_check_reply; + arming_check_reply.timestamp = hrt_absolute_time(); + arming_check_reply.request_id = arming_check_request.request_id; + arming_check_reply.registration_id = ext_component_arming_check_id; + arming_check_reply.health_component_index = arming_check_reply.HEALTH_COMPONENT_INDEX_NONE; + arming_check_reply.num_events = 0; + arming_check_reply.can_arm_and_run = can_arm; + arming_check_reply.mode_req_angular_velocity = true; + arming_check_reply.mode_req_local_position = true; + arming_check_reply.mode_req_attitude = true; + arming_check_reply.mode_req_local_alt = true; + arming_check_reply.mode_req_home_position = false; + arming_check_reply.mode_req_mission = false; + arming_check_reply.mode_req_global_position = false; + arming_check_reply.mode_req_prevent_arming = false; + arming_check_reply.mode_req_manual_control = false; + _arming_check_reply_pub.publish(arming_check_reply); + } + } +} + + +void Raptor::Run() +{ + if (should_exit()) { + _vehicle_angular_velocity_sub.unregisterCallback(); + + if (flightmode_state >= FlightModeState::REGISTERED) { + unregister_ext_component_s unregister_ext_component{}; + unregister_ext_component.timestamp = hrt_absolute_time(); + strncpy(unregister_ext_component.name, "RAPTOR", sizeof(unregister_ext_component.name) - 1); + unregister_ext_component.arming_check_id = ext_component_arming_check_id; + unregister_ext_component.mode_id = ext_component_mode_id; + unregister_ext_component.mode_executor_id = -1; + _unregister_ext_component_pub.publish(unregister_ext_component); + } + + ScheduleClear(); + exit_and_cleanup(); + return; + } + + register_ext_component_reply_s register_ext_component_reply; + + if (_register_ext_component_reply_sub.update(®ister_ext_component_reply)) { + if (register_ext_component_reply.request_id == Raptor::EXT_COMPONENT_REQUEST_ID && register_ext_component_reply.success) { + ext_component_arming_check_id = register_ext_component_reply.arming_check_id; + ext_component_mode_id = register_ext_component_reply.mode_id; + flightmode_state = FlightModeState::REGISTERED; + PX4_INFO("Raptor mode registration successful, arming_check_id: %d, mode_id: %d", ext_component_arming_check_id, ext_component_mode_id); + } + } + + if (flightmode_state == FlightModeState::REGISTERED) { + vehicle_control_mode_s config_control_setpoints{}; + config_control_setpoints.timestamp = hrt_absolute_time(); + config_control_setpoints.source_id = ext_component_mode_id; + config_control_setpoints.flag_multicopter_position_control_enabled = false; + config_control_setpoints.flag_control_manual_enabled = false; + config_control_setpoints.flag_control_offboard_enabled = false; + config_control_setpoints.flag_control_position_enabled = false; + config_control_setpoints.flag_control_climb_rate_enabled = false; + config_control_setpoints.flag_control_allocation_enabled = false; + config_control_setpoints.flag_control_termination_enabled = true; + _config_control_setpoints_pub.publish(config_control_setpoints); + flightmode_state = FlightModeState::CONFIGURED; + PX4_INFO("Raptor mode configuration sent"); + } + + + perf_count(_loop_interval_perf); + + perf_begin(_loop_perf); + hrt_abstime current_time = hrt_absolute_time(); + + raptor_status_s status{}; + status.timestamp = current_time; + status.timestamp_sample = current_time; + status.exit_reason = raptor_status_s::EXIT_REASON_NONE; + status.substep = 0; + status.active = false; + status.control_interval = NAN; + status.trajectory_setpoint_dt_mean = NAN; + status.trajectory_setpoint_dt_max = NAN; + status.trajectory_setpoint_dt_max_since_activation = NAN; + + if (trajectory_setpoint_dts_full || trajectory_setpoint_dt_index > 0) { + float trajectory_setpoint_dt_mean = 0; + float trajectory_setpoint_dt_max = 0; + + for (TI i = 0; i < (trajectory_setpoint_dts_full ? NUM_TRAJECTORY_SETPOINT_DTS : trajectory_setpoint_dt_index); i++) { + TI index = trajectory_setpoint_dts_full ? i : trajectory_setpoint_dt_index - 1 - i; + trajectory_setpoint_dt_mean += trajectory_setpoint_dts[index]; + + if (trajectory_setpoint_dts[index] > trajectory_setpoint_dt_max) { + trajectory_setpoint_dt_max = trajectory_setpoint_dts[index]; + } + } + + if (trajectory_setpoint_dt_max > trajectory_setpoint_dt_max_since_reset) { + trajectory_setpoint_dt_max_since_reset = trajectory_setpoint_dt_max; + } + + trajectory_setpoint_dt_mean /= NUM_TRAJECTORY_SETPOINT_DTS; + status.trajectory_setpoint_dt_mean = trajectory_setpoint_dt_mean; + status.trajectory_setpoint_dt_max = trajectory_setpoint_dt_max; + status.trajectory_setpoint_dt_max_since_activation = trajectory_setpoint_dt_max_since_reset; + } + + status.subscription_update_vehicle_status = _vehicle_status_sub.update(&_vehicle_status); + + if (status.subscription_update_vehicle_status) { + timestamp_last_vehicle_status = current_time; + timestamp_last_vehicle_status_set = true; + } + + bool next_active = timestamp_last_vehicle_status_set && _vehicle_status.nav_state == ext_component_mode_id; + + if (!previous_active && next_active) { + this->reset(); + PX4_INFO("Resetting Inference Executor (Recurrent State)"); + + } else { + if (previous_active && !next_active) { + PX4_INFO("inactive"); + } + } + + bool angular_velocity_update = false; + status.subscription_update_angular_velocity = _vehicle_angular_velocity_sub.update(&_vehicle_angular_velocity); + + if (status.subscription_update_angular_velocity) { + timestamp_last_angular_velocity = current_time; + timestamp_last_angular_velocity_set = true; + angular_velocity_update = true; + } + + status.timestamp_last_vehicle_angular_velocity = current_time; + status.timestamp_sample = _vehicle_angular_velocity.timestamp_sample; + + status.subscription_update_local_position = _vehicle_local_position_sub.update(&_vehicle_local_position); + + if (status.subscription_update_local_position) { + timestamp_last_local_position = current_time; + timestamp_last_local_position_set = true; + } + + status.timestamp_last_vehicle_local_position = current_time; + + status.subscription_update_attitude = _vehicle_attitude_sub.update(&_vehicle_attitude); + + if (status.subscription_update_attitude) { + timestamp_last_attitude = current_time; + timestamp_last_attitude_set = true; + } + + status.timestamp_last_vehicle_attitude = timestamp_last_attitude; + + trajectory_setpoint_s temp_trajectory_setpoint; + bool use_external_reference = !use_internal_reference; + status.subscription_update_trajectory_setpoint = use_external_reference && _trajectory_setpoint_sub.update(&temp_trajectory_setpoint); + + if (status.subscription_update_trajectory_setpoint) { + if ( + PX4_ISFINITE(temp_trajectory_setpoint.position[0]) && + PX4_ISFINITE(temp_trajectory_setpoint.position[1]) && + PX4_ISFINITE(temp_trajectory_setpoint.position[2]) && + PX4_ISFINITE(temp_trajectory_setpoint.yaw) && + PX4_ISFINITE(temp_trajectory_setpoint.velocity[0]) && + PX4_ISFINITE(temp_trajectory_setpoint.velocity[1]) && + PX4_ISFINITE(temp_trajectory_setpoint.velocity[2]) && + PX4_ISFINITE(temp_trajectory_setpoint.yawspeed) + ) { + if (timestamp_last_trajectory_setpoint_set) { + trajectory_setpoint_dts[trajectory_setpoint_dt_index] = current_time - timestamp_last_trajectory_setpoint; + trajectory_setpoint_dt_index++; + + if (trajectory_setpoint_dt_index == NUM_TRAJECTORY_SETPOINT_DTS) { + if (next_active && !trajectory_setpoint_dts_full) { + PX4_INFO("trajectory_setpoint_dts_full"); + } + + trajectory_setpoint_dts_full = true; + trajectory_setpoint_dt_index = 0; + } + } + + timestamp_last_trajectory_setpoint_set = true; + status.timestamp_last_trajectory_setpoint = current_time; + timestamp_last_trajectory_setpoint = current_time; + _trajectory_setpoint = temp_trajectory_setpoint; + + } else { + trajectory_setpoint_invalid_count++; + + if (next_active && trajectory_setpoint_invalid_count % TRAJECTORY_SETPOINT_INVALID_COUNT_WARNING_INTERVAL == 0) { + PX4_WARN("trajectory_setpoint invalid, count: %d", (int)trajectory_setpoint_invalid_count); + } + } + } + + constexpr bool PUBLISH_NON_COMPLETE_STATUS = true; + + if (!angular_velocity_update) { + status.exit_reason = raptor_status_s::EXIT_REASON_NO_ANGULAR_VELOCITY_UPDATE; + + if constexpr(PUBLISH_NON_COMPLETE_STATUS) { + _raptor_status_pub.publish(status); + } + + updateArmingCheckReply(); + return; + } + + if (!timestamp_last_angular_velocity_set || !timestamp_last_local_position_set || !timestamp_last_attitude_set) { + status.exit_reason = raptor_status_s::EXIT_REASON_NOT_ALL_OBSERVATIONS_SET; + status.vehicle_angular_velocity_stale = !timestamp_last_angular_velocity_set; + status.vehicle_local_position_stale = !timestamp_last_local_position_set; + status.vehicle_attitude_stale = !timestamp_last_attitude_set; + + if constexpr(PUBLISH_NON_COMPLETE_STATUS) { + _raptor_status_pub.publish(status); + } + + can_arm = false; + updateArmingCheckReply(); + return; + } + + if ((current_time - timestamp_last_angular_velocity) > OBSERVATION_TIMEOUT_ANGULAR_VELOCITY) { + status.exit_reason = raptor_status_s::EXIT_REASON_ANGULAR_VELOCITY_STALE; + + if constexpr(PUBLISH_NON_COMPLETE_STATUS) { + _raptor_status_pub.publish(status); + } + + if (!timeout_message_sent) { + PX4_ERR("angular velocity timeout"); + timeout_message_sent = true; + } + + can_arm = false; + updateArmingCheckReply(); + return; + } + + if ((current_time - timestamp_last_local_position) > OBSERVATION_TIMEOUT_LOCAL_POSITION) { + status.exit_reason = raptor_status_s::EXIT_REASON_LOCAL_POSITION_STALE; + + if constexpr(PUBLISH_NON_COMPLETE_STATUS) { + _raptor_status_pub.publish(status); + } + + if (!timeout_message_sent) { + PX4_ERR("local position timeout"); + timeout_message_sent = true; + } + + can_arm = false; + updateArmingCheckReply(); + return; + + } else { + position[0] = _vehicle_local_position.x; + position[1] = _vehicle_local_position.y; + position[2] = _vehicle_local_position.z; + linear_velocity[0] = _vehicle_local_position.vx; + linear_velocity[1] = _vehicle_local_position.vy; + linear_velocity[2] = _vehicle_local_position.vz; + } + + // position and linear_velocity are guaranteed to be set after this point + auto previous_internal_reference = internal_reference; + internal_reference = static_cast(_param_mc_raptor_intref.get()); + bool internal_reference_changed = previous_internal_reference != internal_reference; + + if (internal_reference_changed) { + PX4_INFO("internal reference changed from %d to %d", (int)previous_internal_reference, (int)internal_reference); + } + + if (use_internal_reference && internal_reference != InternalReference::NONE) { + if (next_active && (!previous_active || internal_reference_changed || internal_reference_params_changed)) { + internal_reference_activation_position[0] = position[0]; + internal_reference_activation_position[1] = - position[1]; + internal_reference_activation_position[2] = - position[2]; + internal_reference_activation_orientation[0] = _vehicle_attitude.q[0]; + internal_reference_activation_orientation[1] = _vehicle_attitude.q[1]; + internal_reference_activation_orientation[2] = -_vehicle_attitude.q[2]; + internal_reference_activation_orientation[3] = -_vehicle_attitude.q[3]; + internal_reference_activation_time = current_time; + PX4_INFO("internal reference activated at: %f %f %f", (double)internal_reference_activation_position[0], + (double)internal_reference_activation_position[1], (double)internal_reference_activation_position[2]); + internal_reference_params_changed = false; + } + + Setpoint setpoint{}; + + if (internal_reference == InternalReference::LISSAJOUS) { + setpoint = lissajous(static_cast(current_time - internal_reference_activation_time) / 1000000, lissajous_params); + + } else { + PX4_ERR("internal reference type not supported"); + } + + auto &q = internal_reference_activation_orientation; + matrix::Quatf q_activation_frame(q[0], q[1], q[2], q[3]); + matrix::Vector3f position_activation_frame = q_activation_frame.rotateVector(matrix::Vector3f(setpoint.position[0], setpoint.position[1], + setpoint.position[2])); + matrix::Vector3f linear_velocity_activation_frame = q_activation_frame.rotateVector(matrix::Vector3f(setpoint.linear_velocity[0], + setpoint.linear_velocity[1], setpoint.linear_velocity[2])); + + _trajectory_setpoint.position[0] = +(internal_reference_activation_position[0] + position_activation_frame(0)); + _trajectory_setpoint.position[1] = -(internal_reference_activation_position[1] + position_activation_frame(1)); + _trajectory_setpoint.position[2] = -(internal_reference_activation_position[2] + position_activation_frame(2)); + _trajectory_setpoint.yaw = - atan2f(2.0f * (q[1] * q[2] + q[0] * q[3]), 1.0f - 2.0f * (q[2] * q[2] + q[3] * q[3])) - setpoint.yaw; + _trajectory_setpoint.velocity[0] = +linear_velocity_activation_frame(0); + _trajectory_setpoint.velocity[1] = -linear_velocity_activation_frame(1); + _trajectory_setpoint.velocity[2] = -linear_velocity_activation_frame(2); + _trajectory_setpoint.yawspeed = -setpoint.yaw_rate; + timestamp_last_trajectory_setpoint_set = true; + status.timestamp_last_trajectory_setpoint = current_time; + timestamp_last_trajectory_setpoint = current_time; + + status.internal_reference_position[0] = _trajectory_setpoint.position[0]; + status.internal_reference_position[1] = _trajectory_setpoint.position[1]; + status.internal_reference_position[2] = _trajectory_setpoint.position[2]; + status.internal_reference_linear_velocity[0] = _trajectory_setpoint.velocity[0]; + status.internal_reference_linear_velocity[1] = _trajectory_setpoint.velocity[1]; + status.internal_reference_linear_velocity[2] = _trajectory_setpoint.velocity[2]; + } + + if ((current_time - timestamp_last_attitude) > OBSERVATION_TIMEOUT_ATTITUDE) { + status.exit_reason = raptor_status_s::EXIT_REASON_ATTITUDE_STALE; + + if constexpr(PUBLISH_NON_COMPLETE_STATUS) { + _raptor_status_pub.publish(status); + } + + if (!timeout_message_sent) { + PX4_ERR("attitude timeout"); + timeout_message_sent = true; + } + + can_arm = false; + updateArmingCheckReply(); + return; + } + + timeout_message_sent = false; + + // is ready to control at this point + can_arm = true; + updateArmingCheckReply(); + + if (!timestamp_last_trajectory_setpoint_set || use_internal_reference + || (current_time - timestamp_last_trajectory_setpoint) > TRAJECTORY_SETPOINT_TIMEOUT) { + status.trajectory_setpoint_stale = true; + + if (!previous_trajectory_setpoint_stale || (!previous_active && next_active)) { + _trajectory_setpoint.position[0] = position[0]; + _trajectory_setpoint.position[1] = position[1]; + _trajectory_setpoint.position[2] = position[2]; + auto &q = _vehicle_attitude.q; + _trajectory_setpoint.yaw = atan2f(2.0f * (q[1] * q[2] + q[0] * q[3]), 1.0f - 2.0f * (q[2] * q[2] + q[3] * q[3])); + _trajectory_setpoint.velocity[0] = 0; + _trajectory_setpoint.velocity[1] = 0; + _trajectory_setpoint.velocity[2] = 0; + _trajectory_setpoint.yawspeed = 0; + + if (!previous_trajectory_setpoint_stale) { + PX4_WARN("trajectory_setpoint turned stale at: %f %f %f, yaw: %f %llu / %llu us", (double)position[0], (double)position[1], + (double)position[2], + (double)_trajectory_setpoint.yaw, (unsigned long long)(current_time - timestamp_last_trajectory_setpoint), + (unsigned long long)(TRAJECTORY_SETPOINT_TIMEOUT)); + + } else { + PX4_WARN("trajectory_setpoint reset due to activation at: %f %f %f, yaw: %f", (double)position[0], (double)position[1], (double)position[2], + (double)_trajectory_setpoint.yaw); + } + } + + previous_trajectory_setpoint_stale = true; + + } else { + if (previous_trajectory_setpoint_stale) { + PX4_WARN("trajectory_setpoint turned non-stale at: %f %f %f", (double)position[0], (double)position[1], (double)position[2]); + previous_trajectory_setpoint_stale = false; + } + + status.trajectory_setpoint_stale = false; + } + + + + + + rl_tools::inference::applications::l2f::Observation observation; + rl_tools::inference::applications::l2f::Action action; + observe(observation); + hrt_abstime nanoseconds = current_time * 1000; + auto executor_status = rl_tools::control(device, executor, nanoseconds, policy, observation, action, rng); + + if (!executor_status.OK) { + if (executor_status.TIMESTAMP_INVALID) { + PX4_ERR("RLtools executor error: Timestamp invalid"); + } + + if (executor_status.LAST_CONTROL_TIMESTAMP_GREATER_THAN_LAST_OBSERVATION_TIMESTAMP) { + PX4_ERR("RLtools executor error: Last control timestamp %llu greater than last observation timestamp %llu", + (unsigned long long)executor.executor.last_control_timestamp, (unsigned long long)executor.executor.last_observation_timestamp); + } + } + + if (executor_status.source != decltype(executor_status.source)::CONTROL) { + // status.exit_reason = raptor_status_s::EXIT_REASON_EXECUTOR_STATUS_SOURCE_NOT_CONTROL; + // if constexpr(PUBLISH_NON_COMPLETE_STATUS){ + // _raptor_status_pub.publish(status); + // } + // Exit early if it is not time to control + return; + } + + + status.active = next_active; + + + // no return after this point! + + raptor_input_s input_msg; + input_msg.active = status.active; + static_assert(raptor_input_s::ACTION_DIM == EXECUTOR_CONFIG::OUTPUT_DIM); + input_msg.timestamp = current_time; + input_msg.timestamp_sample = _vehicle_angular_velocity.timestamp_sample; + + for (TI dim_i = 0; dim_i < 3; dim_i++) { + input_msg.position[dim_i] = observation.position[dim_i]; + input_msg.orientation[dim_i] = observation.orientation[dim_i]; + input_msg.linear_velocity[dim_i] = observation.linear_velocity[dim_i]; + input_msg.angular_velocity[dim_i] = observation.angular_velocity[dim_i]; + } + + input_msg.orientation[3] = observation.orientation[3]; + + for (TI dim_i = 0; dim_i < EXECUTOR_CONFIG::OUTPUT_DIM; dim_i++) { + input_msg.previous_action[dim_i] = observation.previous_action[dim_i]; + } + + _raptor_input_pub.publish(input_msg); + _raptor_status_pub.publish(status); + + actuator_motors_s actuator_motors{}; + actuator_motors.timestamp = hrt_absolute_time(); + actuator_motors.timestamp_sample = _vehicle_angular_velocity.timestamp_sample; + + for (TI action_i = 0; action_i < actuator_motors_s::NUM_CONTROLS; action_i++) { + if (action_i < EXECUTOR_CONFIG::OUTPUT_DIM) { + T value = action.action[action_i]; + this->previous_action[action_i] = value; + value = (value + 1) / 2; + constexpr T training_min = 0; + constexpr T training_max = 1.0; + T scaled_value = (training_max - training_min) * value + training_min; + actuator_motors.control[action_i] = scaled_value; + + } else { + actuator_motors.control[action_i] = NAN; + } + } + + if constexpr(Raptor::REMAP_FROM_CRAZYFLIE) { + actuator_motors_s temp = actuator_motors; + temp.control[0] = actuator_motors.control[0]; + temp.control[1] = actuator_motors.control[2]; + temp.control[2] = actuator_motors.control[3]; + temp.control[3] = actuator_motors.control[1]; + actuator_motors = temp; + } + + if (status.active) { + _actuator_motors_pub.publish(actuator_motors); + } + + perf_end(_loop_perf); + previous_active = next_active; + + if (executor_status.source == decltype(executor_status.source)::CONTROL) { + if (executor_status.step_type == decltype(executor_status.step_type)::INTERMEDIATE) { + this->last_intermediate_status = executor_status; + this->last_intermediate_status_set = true; + + } else if (executor_status.step_type == decltype(executor_status.step_type)::NATIVE) { + this->last_native_status = executor_status; + this->last_native_status_set = true; + } + } + + if (!this->timestamp_last_policy_frequency_check_set + || (current_time - timestamp_last_policy_frequency_check) > POLICY_FREQUENCY_CHECK_INTERVAL) { + if (this->timestamp_last_policy_frequency_check_set) { + if (last_intermediate_status_set) { + if (!this->last_intermediate_status.timing_bias.OK || !this->last_intermediate_status.timing_jitter.OK) { + PX4_WARN("Raptor: INTERMEDIATE: BIAS %fx JITTER %fx", (double)this->last_intermediate_status.timing_bias.MAGNITUDE, + (double)this->last_intermediate_status.timing_jitter.MAGNITUDE); + + } else { + if (ENABLE_CONTROL_FREQUENCY_INFO && this->policy_frequency_check_counter % POLICY_FREQUENCY_INFO_INTERVAL == 0) { + PX4_INFO("Raptor: INTERMEDIATE: BIAS %fx JITTER %fx", (double)this->last_intermediate_status.timing_bias.MAGNITUDE, + (double)this->last_intermediate_status.timing_jitter.MAGNITUDE); + } + } + } + + if (last_native_status_set) { + if (!this->last_native_status.timing_bias.OK || !this->last_native_status.timing_jitter.OK) { + PX4_WARN("Raptor: NATIVE: BIAS %fx JITTER %fx", (double)this->last_native_status.timing_bias.MAGNITUDE, + (double)this->last_native_status.timing_jitter.MAGNITUDE); + + } else { + if (ENABLE_CONTROL_FREQUENCY_INFO && this->policy_frequency_check_counter % POLICY_FREQUENCY_INFO_INTERVAL == 0) { + PX4_INFO("Raptor: NATIVE: BIAS %fx JITTER %fx", (double)this->last_native_status.timing_bias.MAGNITUDE, + (double)this->last_native_status.timing_jitter.MAGNITUDE); + } + } + } + } + + this->num_healthy_executor_statii_intermediate = 0; + this->num_non_healthy_executor_statii_intermediate = 0; + this->num_healthy_executor_statii_native = 0; + this->num_non_healthy_executor_statii_native = 0; + this->num_statii = 0; + this->timestamp_last_policy_frequency_check = current_time; + this->timestamp_last_policy_frequency_check_set = true; + this->policy_frequency_check_counter++; + } + + this->num_statii++; + this->num_healthy_executor_statii_intermediate += executor_status.OK && executor_status.source == decltype(executor_status.source)::CONTROL + && executor_status.step_type == decltype(executor_status.step_type)::INTERMEDIATE; + this->num_non_healthy_executor_statii_intermediate += (!executor_status.OK) + && executor_status.source == decltype(executor_status.source)::CONTROL + && executor_status.step_type == decltype(executor_status.step_type)::INTERMEDIATE; + this->num_healthy_executor_statii_native += executor_status.OK && executor_status.source == decltype(executor_status.source)::CONTROL + && executor_status.step_type == decltype(executor_status.step_type)::NATIVE; + this->num_non_healthy_executor_statii_native += (!executor_status.OK) + && executor_status.source == decltype(executor_status.source)::CONTROL + && executor_status.step_type == decltype(executor_status.step_type)::NATIVE; +} + +int Raptor::task_spawn(int argc, char *argv[]) +{ + Raptor *instance = new Raptor(); + + if (instance) { + _object.store(instance); + _task_id = task_id_is_work_queue; + + if (instance->init()) { + return PX4_OK; + } + + } else { + PX4_ERR("alloc failed"); + } + + delete instance; + _object.store(nullptr); + _task_id = -1; + + return PX4_ERROR; +} + +int Raptor::print_status() +{ + perf_print_counter(_loop_perf); + perf_print_counter(_loop_interval_perf); + perf_print_counter(_loop_interval_policy_perf); + PX4_INFO_RAW("Checkpoint: %s\n", checkpoint_name); + return 0; +} + +int Raptor::custom_command(int argc, char *argv[]) +{ + if (argc >= 2 && strcmp(argv[0], "intref") == 0) { + if (strcmp(argv[1], "lissajous") == 0) { + // Usage: mc_raptor intref lissajous + if (argc != 10) { + PX4_ERR("Usage: mc_raptor intref lissajous "); + return PX4_ERROR; + } + + Raptor *instance = get_instance(); + + if (instance == nullptr) { + PX4_ERR("mc_raptor is not running"); + return PX4_ERROR; + } + + instance->lissajous_params.A = strtof(argv[2], nullptr); + instance->lissajous_params.B = strtof(argv[3], nullptr); + instance->lissajous_params.C = strtof(argv[4], nullptr); + instance->lissajous_params.a = strtof(argv[5], nullptr); + instance->lissajous_params.b = strtof(argv[6], nullptr); + instance->lissajous_params.c = strtof(argv[7], nullptr); + instance->lissajous_params.duration = strtof(argv[8], nullptr); + instance->lissajous_params.ramp_duration = strtof(argv[9], nullptr); + instance->internal_reference_params_changed = true; + + PX4_INFO("Lissajous params set: A=%.2f B=%.2f C=%.2f fa=%.2f fb=%.2f fc=%.2f duration=%.2f ramp=%.2f \n", + (double)instance->lissajous_params.A, + (double)instance->lissajous_params.B, + (double)instance->lissajous_params.C, + (double)instance->lissajous_params.a, + (double)instance->lissajous_params.b, + (double)instance->lissajous_params.c, + (double)instance->lissajous_params.duration, + (double)instance->lissajous_params.ramp_duration); + + + return PX4_OK; + } + } + + return print_usage("unknown command"); +} + +int Raptor::print_usage(const char *reason) +{ + if (reason) { + PX4_WARN("%s\n", reason); + } + + PRINT_MODULE_DESCRIPTION( + R"DESCR_STR( +### Description +RAPTOR Policy Flight Mode + +)DESCR_STR"); + + PRINT_MODULE_USAGE_NAME("mc_raptor", "template"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_COMMAND_DESCR("intref", "Modify internal reference"); + PRINT_MODULE_USAGE_ARG("lissajous", "Set Lissajous trajectory parameters", false); + PRINT_MODULE_USAGE_ARG("", "Amplitude X [m]", false); + PRINT_MODULE_USAGE_ARG("", "Amplitude Y [m]", false); + PRINT_MODULE_USAGE_ARG("", "Amplitude Z [m]", false); + PRINT_MODULE_USAGE_ARG("", "Frequency a", false); + PRINT_MODULE_USAGE_ARG("", "Frequency b", false); + PRINT_MODULE_USAGE_ARG("", "Frequency c", false); + PRINT_MODULE_USAGE_ARG("", "Total duration [s]", false); + PRINT_MODULE_USAGE_ARG("", "Ramp duration [s]", false); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); + + return 0; +} + +extern "C" __EXPORT int mc_raptor_main(int argc, char *argv[]) +{ + return Raptor::main(argc, argv); +} diff --git a/src/modules/mc_raptor/mc_raptor.hpp b/src/modules/mc_raptor/mc_raptor.hpp new file mode 100644 index 0000000000..0ffb8e6d01 --- /dev/null +++ b/src/modules/mc_raptor/mc_raptor.hpp @@ -0,0 +1,283 @@ +#pragma once + +#include "trajectories/lissajous.hpp" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef OK + +#ifdef __PX4_POSIX +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "blob/policy.h" + +#include +#include +#include +#include +#include + +namespace rlt = rl_tools; + +#define MC_RAPTOR_POLICY_NAMESPACE rlt::checkpoint::actor +#define MC_RAPTOR_EXAMPLE_NAMESPACE rlt::checkpoint::example +#define MC_RAPTOR_META_NAMESPACE rlt::checkpoint::meta +// #define MC_RAPTOR_EMBED_POLICY // you can use this to directly embed the policy into the firmware instead of loading it from the sd card. To fit into the flash you might need to disable some unnecessary features in the .px4board config. + + + + + +using namespace time_literals; + +class Raptor : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem +{ +public: + Raptor(); + ~Raptor() override; + + /** @see ModuleBase */ + static int task_spawn(int argc, char *argv[]); + + /** @see ModuleBase */ + static int custom_command(int argc, char *argv[]); + + /** @see ModuleBase */ + static int print_usage(const char *reason = nullptr); + + bool init(); + + int print_status() override; + +private: +#ifdef __PX4_POSIX + using DEVICE = rlt::devices::DefaultCPU; +#else + using DEV_SPEC = rlt::devices::DefaultARMSpecification; + using DEVICE = rlt::devices::arm::OPT; +#endif + using TI = typename DEVICE::index_t; + using RNG = DEVICE::SPEC::RANDOM::ENGINE<>; + using T = float; + static constexpr uint64_t EXT_COMPONENT_REQUEST_ID = 1337; + DEVICE device; + RNG rng; + hrt_abstime init_time; + // node constants + static constexpr TI OBSERVATION_TIMEOUT_ANGULAR_VELOCITY = 10 * 1000; + static constexpr TI OBSERVATION_TIMEOUT_LOCAL_POSITION = 100 * 1000; + static constexpr TI OBSERVATION_TIMEOUT_ATTITUDE = 50 * 1000; + static constexpr TI TRAJECTORY_SETPOINT_TIMEOUT = 200 * 1000; + static constexpr T RESET_PREVIOUS_ACTION_VALUE = 0; // -1 to 1 + static constexpr bool ENABLE_CONTROL_FREQUENCY_INFO = false; + + T max_position_error = 0.5; + T max_velocity_error = 1.0; + + void Run() override; + + decltype(register_ext_component_reply_s::mode_id) ext_component_mode_id; + decltype(register_ext_component_reply_s::arming_check_id) ext_component_arming_check_id; + + enum class FlightModeState : TI { + UNREGISTERED = 0, + REGISTERED = 1, + CONFIGURED = 2 + }; + FlightModeState flightmode_state = FlightModeState::UNREGISTERED; + bool can_arm = false; + void updateArmingCheckReply(); + + // node state + vehicle_local_position_s _vehicle_local_position{}; + vehicle_angular_velocity_s _vehicle_angular_velocity{}; + vehicle_attitude_s _vehicle_attitude{}; + vehicle_status_s _vehicle_status{}; + trajectory_setpoint_s _trajectory_setpoint{}; + hrt_abstime timestamp_last_local_position, timestamp_last_angular_velocity, timestamp_last_attitude, timestamp_last_trajectory_setpoint, + timestamp_last_manual_control_input, timestamp_last_vehicle_status; + bool timestamp_last_local_position_set = false, timestamp_last_angular_velocity_set = false, timestamp_last_attitude_set = false, + timestamp_last_trajectory_setpoint_set = false, timestamp_last_manual_control_input_set = false, timestamp_last_vehicle_status_set = false; + bool timeout_message_sent = false; + bool previous_trajectory_setpoint_stale = false; + bool previous_active = false; + + T position[3]; + T linear_velocity[3]; + + uORB::Subscription _vehicle_local_position_sub{ORB_ID(vehicle_local_position)}; + uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)}; + uORB::Subscription _register_ext_component_reply_sub{ORB_ID(register_ext_component_reply)}; + uORB::Subscription _trajectory_setpoint_sub{ORB_ID(trajectory_setpoint)}; + uORB::Subscription _arming_check_request_sub{ORB_ID(arming_check_request)}; + uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; + uORB::SubscriptionCallbackWorkItem _vehicle_angular_velocity_sub{this, ORB_ID(vehicle_angular_velocity)}; + uORB::Publication _actuator_motors_pub{ORB_ID(actuator_motors)}; + uORB::Publication _raptor_status_pub{ORB_ID(raptor_status)}; + uORB::Publication _raptor_input_pub{ORB_ID(raptor_input)}; + uORB::Publication _tune_control_pub{ORB_ID(tune_control)}; + uORB::Publication _register_ext_component_request_pub{ORB_ID(register_ext_component_request)}; + uORB::Publication _unregister_ext_component_pub{ORB_ID(unregister_ext_component)}; + uORB::Publication _config_control_setpoints_pub{ORB_ID(config_control_setpoints)}; + uORB::Publication _arming_check_reply_pub{ORB_ID(arming_check_reply)}; + // Performance (perf) counters + perf_counter_t _loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")}; + perf_counter_t _loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")}; + perf_counter_t _loop_interval_policy_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval_policy")}; + + struct EXECUTOR_CONFIG { + static constexpr TI ACTION_HISTORY_LENGTH = 1; + static constexpr TI CONTROL_INTERVAL_INTERMEDIATE_NS = 2.5 * 1000 * 1000; // Inference is at 500hz + static constexpr TI CONTROL_INTERVAL_NATIVE_NS = 10 * 1000 * 1000; // Training is 100hz + static constexpr TI TIMING_STATS_NUM_STEPS = 100; + static constexpr bool FORCE_SYNC_INTERMEDIATE = true; + static constexpr bool FORCE_SYNC_NATIVE_RUNTIME = true; + static constexpr TI FORCE_SYNC_NATIVE = 8; + static constexpr bool DYNAMIC_ALLOCATION = false; + + using ACTOR_TYPE_ORIGINAL = MC_RAPTOR_POLICY_NAMESPACE ::TYPE; + using POLICY_TEST = MC_RAPTOR_POLICY_NAMESPACE ::TYPE::template CHANGE_BATCH_SIZE::template CHANGE_SEQUENCE_LENGTH; + using POLICY_BATCH_SIZE = ACTOR_TYPE_ORIGINAL::template CHANGE_BATCH_SIZE; +#ifdef MC_RAPTOR_EMBED_POLICY + using POLICY = POLICY_BATCH_SIZE; +#else + using POLICY = POLICY_BATCH_SIZE::template CHANGE_CAPABILITY>; +#endif + using TYPE_POLICY = typename POLICY::TYPE_POLICY; + +#if defined(__PX4_POSIX) + // Relax warning levels for Gazebo sitl. Because Gazebo SITL runs at 250Hz IMU rate, it is not a clean multiple of the training frequency (100hz), hence if the thresholds are set too strict, warnings will be triggered all the time. Generally, Raptor is quite robuts agains control frequency deviations. + struct WARNING_LEVELS: rlt::inference::executor::WarningLevelsDefault { + using T = typename TYPE_POLICY::DEFAULT; + static constexpr T INTERMEDIATE_TIMING_JITTER_HIGH_THRESHOLD = 2.0; + static constexpr T INTERMEDIATE_TIMING_JITTER_LOW_THRESHOLD = 0.5; + static constexpr T INTERMEDIATE_TIMING_BIAS_HIGH_THRESHOLD = 2.0; + static constexpr T INTERMEDIATE_TIMING_BIAS_LOW_THRESHOLD = 0.5; + static constexpr T NATIVE_TIMING_JITTER_HIGH_THRESHOLD = 2.0; + static constexpr T NATIVE_TIMING_JITTER_LOW_THRESHOLD = 0.5; + static constexpr T NATIVE_TIMING_BIAS_HIGH_THRESHOLD = 2.0; + static constexpr T NATIVE_TIMING_BIAS_LOW_THRESHOLD = 0.5; + }; +#else + struct WARNING_LEVELS: rlt::inference::executor::WarningLevelsDefault { + using T = typename TYPE_POLICY::DEFAULT; + static constexpr T NATIVE_TIMING_JITTER_HIGH_THRESHOLD = 1.5; + static constexpr T NATIVE_TIMING_JITTER_LOW_THRESHOLD = 0.5; + }; +#endif + using TIMESTAMP = hrt_abstime; + static constexpr TI OUTPUT_DIM = 4; + static constexpr TI TEST_SEQUENCE_LENGTH_ACTUAL = 5; + static constexpr TI TEST_BATCH_SIZE_ACTUAL = 2; + + using EXECUTOR_SPEC = + rl_tools::inference::applications::l2f::Specification; + using EXECUTOR_STATUS = rlt::inference::executor::Status; + }; + using EXECUTOR_SPEC = EXECUTOR_CONFIG::EXECUTOR_SPEC; + rl_tools::inference::applications::L2F executor; +#ifdef MC_RAPTOR_EMBED_POLICY + const decltype(MC_RAPTOR_POLICY_NAMESPACE ::module) &policy = MC_RAPTOR_POLICY_NAMESPACE::module; +#else + EXECUTOR_CONFIG::POLICY policy; +#endif + static constexpr TI CHECKPOINT_NAME_LENGTH = 100; + char checkpoint_name[CHECKPOINT_NAME_LENGTH] = "n/a"; + +#ifdef MC_RAPTOR_EMBED_POLICY + bool test_policy(); +#else + bool test_policy(FILE *f, TI input_offset, TI output_offset); +#endif + + void reset(); + void observe(rl_tools::inference::applications::l2f::Observation &observation); + + static constexpr bool REMAP_FROM_CRAZYFLIE = + true; // Policy (Crazyflie assignment) => Quadrotor (PX4 Quadrotor X assignment) PX4 SIH assumes the Quadrotor X configuration, which assumes different rotor positions than the crazyflie mapping (from crazyflie outputs to PX4): 1=>1, 2=>4, 3=>2, 4=>3 + // controller state + + // messaging state + static constexpr TI POLICY_INTERVAL_WARNING_THRESHOLD = 100; // us + static constexpr TI POLICY_FREQUENCY_CHECK_INTERVAL = 1000 * 1000; // 1s + static constexpr TI POLICY_FREQUENCY_INFO_INTERVAL = 10; // 10 x POLICY_FREQUENCY_CHECK_INTERVAL = 10x + static constexpr TI POLICY_CONTROL_FREQUENCY_TRAINING = 100; + + TI num_statii; + TI num_healthy_executor_statii_intermediate, num_non_healthy_executor_statii_intermediate, num_healthy_executor_statii_native, + num_non_healthy_executor_statii_native; + EXECUTOR_CONFIG::EXECUTOR_STATUS last_intermediate_status, last_native_status; + bool last_intermediate_status_set, last_native_status_set; + + TI policy_frequency_check_counter; + hrt_abstime timestamp_last_policy_frequency_check; + bool timestamp_last_policy_frequency_check_set = false; + + static constexpr TI NUM_TRAJECTORY_SETPOINT_DTS = 100; + int32_t trajectory_setpoint_dts[NUM_TRAJECTORY_SETPOINT_DTS]; + TI trajectory_setpoint_dt_index = 0; + TI trajectory_setpoint_dt_max_since_reset = 0; + bool trajectory_setpoint_dts_full = false; + + static constexpr TI TRAJECTORY_SETPOINT_INVALID_COUNT_WARNING_INTERVAL = 100; + TI trajectory_setpoint_invalid_count = 0; + + float previous_action[EXECUTOR_SPEC::OUTPUT_DIM]; + bool use_internal_reference = false; + bool internal_reference_params_changed = false; + T internal_reference_activation_position[3]; + T internal_reference_activation_orientation[4]; + hrt_abstime internal_reference_activation_time; + enum class InternalReference : TI { // make sure this corresponds to the enum values for MC_RAPTOR_INTREF in module.yaml + NONE = 0, + LISSAJOUS = 1 + }; + InternalReference internal_reference = InternalReference::NONE; + LissajousParameters lissajous_params{}; // Set via 'mc_raptor intref lissajous ...' command + DEFINE_PARAMETERS( + (ParamInt) _param_imu_gyro_ratemax, + (ParamBool) _param_mc_raptor_offboard, + (ParamInt) _param_mc_raptor_intref + ) + + +}; diff --git a/src/modules/mc_raptor/module.yaml b/src/modules/mc_raptor/module.yaml new file mode 100644 index 0000000000..2b61df845e --- /dev/null +++ b/src/modules/mc_raptor/module.yaml @@ -0,0 +1,43 @@ +module_name: mc_raptor +parameters: + - group: Multicopter Raptor + definitions: + MC_RAPTOR_ENABLE: + description: + short: Enable Raptor flight mode + long: | + When enabled, the Raptor flight mode will be available. Please set MC_RAPTOR_OFFB according to your use case. + type: boolean + default: false + category: System + MC_RAPTOR_VERBOS: + description: + short: Enable verbose output + long: | + When enabled, the Raptor flight mode will print verbose output to the console. + type: boolean + default: false + category: System + + MC_RAPTOR_OFFB: + description: + short: Enable Offboard mode replacement + long: | + When enabled, the Raptor mode will replace the Offboard mode. + If disabled, the Raptor mode will be available as a separate external mode. In the latter case, Raptor will just hold the position, without requiring external setpoints. When Raptor replaces the Offboard mode, it requires external setpoints to be activated. + type: boolean + default: false + category: System + + MC_RAPTOR_INTREF: + description: + short: Use internal reference instead of trajectory_setpoint + long: | + When enabled, instead of using the trajectory_setpoint, the position and yaw of the vehicle at the point when the Raptor mode is activated will be used as reference. + Use `mc_raptor intref lissajous ` to configure the trajectory. + type: enum + values: + 0: None + 1: Lissajous + default: 0 + category: System diff --git a/src/modules/mc_raptor/trajectories/lissajous.hpp b/src/modules/mc_raptor/trajectories/lissajous.hpp new file mode 100644 index 0000000000..340ead01bf --- /dev/null +++ b/src/modules/mc_raptor/trajectories/lissajous.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "trajectory.hpp" +#include + +struct LissajousParameters { + float A = 0.5f; // amplitude a + float B = 1.0f; // amplitude b + float C = 0.0f; // amplitude c + float a = 2.0f; // frequency a + float b = 1.0f; // frequency b + float c = 1.0f; // frequency c + float duration = 10.0f; + float ramp_duration = 3.0f; +}; + +inline Setpoint lissajous(float time, const LissajousParameters ¶ms) +{ + float time_velocity = (params.ramp_duration > 0.0f) + ? fminf(time, params.ramp_duration) / params.ramp_duration + : 1.0f; + + float ramp_time = time_velocity * fminf(time, params.ramp_duration) / 2.0f; + float progress = (ramp_time + fmaxf(0.0f, time - params.ramp_duration)) * 2.0f * static_cast(M_PI) / params.duration; + float d_progress = 2.0f * static_cast(M_PI) * time_velocity / params.duration; + + Setpoint setpoint{}; + setpoint.position[0] = params.A * sinf(params.a * progress); + setpoint.position[1] = params.B * sinf(params.b * progress); + setpoint.position[2] = params.C * sinf(params.c * progress); + setpoint.yaw = 0.0f; + setpoint.linear_velocity[0] = params.A * cosf(params.a * progress) * params.a * d_progress; + setpoint.linear_velocity[1] = params.B * cosf(params.b * progress) * params.b * d_progress; + setpoint.linear_velocity[2] = params.C * cosf(params.c * progress) * params.c * d_progress; + setpoint.yaw_rate = 0.0f; + + return setpoint; +} diff --git a/src/modules/mc_raptor/trajectories/trajectory.hpp b/src/modules/mc_raptor/trajectories/trajectory.hpp new file mode 100644 index 0000000000..fcdf405701 --- /dev/null +++ b/src/modules/mc_raptor/trajectories/trajectory.hpp @@ -0,0 +1,6 @@ +struct Setpoint { + float position[3]; + float yaw; + float linear_velocity[3]; + float yaw_rate; +}; diff --git a/src/modules/muorb/apps/muorb_main.cpp b/src/modules/muorb/apps/muorb_main.cpp index d3c4d78cec..8db18141e0 100644 --- a/src/modules/muorb/apps/muorb_main.cpp +++ b/src/modules/muorb/apps/muorb_main.cpp @@ -58,7 +58,9 @@ muorb_init() if (channel && channel->Initialize(enable_debug)) { uORB::Manager::get_instance()->set_uorb_communicator(channel); - if (channel->Test()) { return OK; } + if (channel->Test()) { + return OK; + } } return -EINVAL; diff --git a/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp b/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp index 437e328156..df2376da27 100644 --- a/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp +++ b/src/modules/muorb/apps/uORBAppsProtobufChannel.cpp @@ -291,6 +291,20 @@ int16_t uORB::AppsProtobufChannel::register_handler(uORBCommunicator::IChannelRx return 0; } +int16_t uORB::AppsProtobufChannel::shutdown() +{ + if (_ShutdownRequested) { + return 0; + } + + _ShutdownRequested = true; + + PX4_ERR("Sending kill command to SLPI!!!"); + fc_sensor_kill_slpi(); + sleep(1); + return 0; +} + int16_t uORB::AppsProtobufChannel::send_message(const char *messageName, int length, uint8_t *data) { // This is done to slow down high rate debug messages. diff --git a/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp b/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp index 7d280a460b..006a8714ef 100644 --- a/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp +++ b/src/modules/muorb/apps/uORBAppsProtobufChannel.hpp @@ -147,6 +147,16 @@ public: */ int16_t send_message(const char *messageName, int length, uint8_t *data); + /** + * @brief Interface to notify the remote entity of a shutdown. + * + * @return + * 0 = success; This means the shutdown is successfully sent to the receiver + * Note: This does not mean that the receiver has received it. + * otherwise = failure. + */ + int16_t shutdown(); + /** * @brief Interface to test the functions of the protobuf channel. * @@ -169,6 +179,7 @@ private: static bool _Debug; bool _Initialized; + bool _ShutdownRequested{false}; uint32_t _MessageCounter; private: diff --git a/src/modules/navigator/MissionFeasibility/FeasibilityChecker.cpp b/src/modules/navigator/MissionFeasibility/FeasibilityChecker.cpp index 713eb151b7..448fc57038 100644 --- a/src/modules/navigator/MissionFeasibility/FeasibilityChecker.cpp +++ b/src/modules/navigator/MissionFeasibility/FeasibilityChecker.cpp @@ -257,6 +257,7 @@ bool FeasibilityChecker::checkMissionItemValidity(mission_item_s &mission_item, mission_item.nav_cmd != NAV_CMD_CONDITION_GATE && mission_item.nav_cmd != NAV_CMD_DO_WINCH && mission_item.nav_cmd != NAV_CMD_DO_GRIPPER && + mission_item.nav_cmd != NAV_CMD_DO_AUTOTUNE_ENABLE && mission_item.nav_cmd != NAV_CMD_DO_JUMP && mission_item.nav_cmd != NAV_CMD_DO_CHANGE_SPEED && mission_item.nav_cmd != NAV_CMD_DO_SET_HOME && diff --git a/src/modules/navigator/land.cpp b/src/modules/navigator/land.cpp index 55116c78e3..b51999ac55 100644 --- a/src/modules/navigator/land.cpp +++ b/src/modules/navigator/land.cpp @@ -72,11 +72,7 @@ Land::on_activation() // reset cruising speed to default _navigator->reset_cruising_speed(); - // set gimbal to neutral position (level with horizon) to reduce change of damage on landing - _navigator->acquire_gimbal_control(); - _navigator->set_gimbal_neutral(); - _navigator->release_gimbal_control(); - + _navigator->activate_set_gimbal_neutral_timer(hrt_absolute_time()); } void diff --git a/src/modules/navigator/mission.cpp b/src/modules/navigator/mission.cpp index 08a200eda0..68226b17a7 100644 --- a/src/modules/navigator/mission.cpp +++ b/src/modules/navigator/mission.cpp @@ -263,6 +263,10 @@ void Mission::setActiveMissionItems() pos_sp_triplet->next.valid = false; } + } else if (_mission_item.nav_cmd == NAV_CMD_DELAY) { + // Invalidate next waypoint to ensure vehicle holds position and doesn't try to track ahead + pos_sp_triplet->next.valid = false; + } else { handleVtolTransition(new_work_item_type, next_mission_items, num_found_items); } diff --git a/src/modules/navigator/mission_base.cpp b/src/modules/navigator/mission_base.cpp index 052968ed7e..79fa7aefd9 100644 --- a/src/modules/navigator/mission_base.cpp +++ b/src/modules/navigator/mission_base.cpp @@ -180,8 +180,10 @@ MissionBase::on_inactivation() _navigator->disable_camera_trigger(); _navigator->stop_capturing_images(); - _navigator->set_gimbal_neutral(); // point forward - _navigator->release_gimbal_control(); + + if (!_navigator->get_land_detected()->landed) { + _navigator->activate_set_gimbal_neutral_timer(hrt_absolute_time()); + } if (_navigator->get_precland()->is_activated()) { _navigator->get_precland()->on_inactivation(); @@ -554,7 +556,9 @@ void MissionBase::setEndOfMissionItems() _mission_item.nav_cmd = NAV_CMD_IDLE; } else { - if (pos_sp_triplet->current.valid && pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_LOITER) { + if (pos_sp_triplet->current.valid && + (pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_LOITER || + pos_sp_triplet->current.type == position_setpoint_s::SETPOINT_TYPE_POSITION)) { setLoiterItemFromCurrentPositionSetpoint(&_mission_item); } else { @@ -698,10 +702,7 @@ void MissionBase::handleLanding(WorkItemType &new_work_item_type, mission_item_s // if the vehicle drifted off the path during back-transition it should just go straight to the landing point _navigator->reset_position_setpoint(pos_sp_triplet->previous); - // set gimbal to neutral position (level with horizon) to reduce change of damage on landing - _navigator->acquire_gimbal_control(); - _navigator->set_gimbal_neutral(); - _navigator->release_gimbal_control(); + _navigator->activate_set_gimbal_neutral_timer(hrt_absolute_time()); } else { diff --git a/src/modules/navigator/mission_block.cpp b/src/modules/navigator/mission_block.cpp index 168debf23a..d28abffc03 100644 --- a/src/modules/navigator/mission_block.cpp +++ b/src/modules/navigator/mission_block.cpp @@ -83,6 +83,7 @@ MissionBlock::is_mission_item_reached_or_completed() case NAV_CMD_DO_MOUNT_CONTROL: case NAV_CMD_DO_GIMBAL_MANAGER_CONFIGURE: case NAV_CMD_COMPONENT_ARM_DISARM: + case NAV_CMD_DO_AUTOTUNE_ENABLE: case NAV_CMD_DO_SET_ROI: case NAV_CMD_DO_SET_ROI_LOCATION: case NAV_CMD_DO_SET_ROI_WPNEXT_OFFSET: @@ -1027,10 +1028,18 @@ void MissionBlock::updateFailsafeChecks() void MissionBlock::updateMaxHaglFailsafe() { const float target_alt = _navigator->get_position_setpoint_triplet()->current.alt; + const float max_alt = math::min(_navigator->get_local_position()->hagl_max_z, _navigator->get_local_position()->hagl_max_xy); + const float terrain_alt = _navigator->get_global_position()->terrain_alt; + const bool terrain_alt_valid = _navigator->get_global_position()->terrain_alt_valid; - if (_navigator->get_global_position()->terrain_alt_valid - && ((target_alt - _navigator->get_global_position()->terrain_alt) - > math::min(_navigator->get_local_position()->hagl_max_z, _navigator->get_local_position()->hagl_max_xy))) { + // If the HAGL failsafe is declared during front transition, we enter a + // FW hold at the current low altitude while not having finished the + // transition. This is dangerous and worse than possibly fusing neither + // optical flow nor airspeed for a couple seconds, so we bypass the + // failsafe here. + const bool in_transition_to_fw = _navigator->get_vstatus()->in_transition_to_fw; + + if (!in_transition_to_fw && terrain_alt_valid && (target_alt - terrain_alt) > max_alt) { // Handle case where the altitude setpoint is above the maximum HAGL (height above ground level) mavlink_log_info(_navigator->get_mavlink_log_pub(), "Target altitude higher than max HAGL\t"); events::send(events::ID("navigator_fail_max_hagl"), events::Log::Error, "Target altitude higher than max HAGL"); diff --git a/src/modules/navigator/navigation.h b/src/modules/navigator/navigation.h index 1c32f3042e..a6b9977dfc 100644 --- a/src/modules/navigator/navigation.h +++ b/src/modules/navigator/navigation.h @@ -73,6 +73,7 @@ enum NAV_CMD { NAV_CMD_DO_MOUNT_CONFIGURE = 204, NAV_CMD_DO_MOUNT_CONTROL = 205, NAV_CMD_DO_GRIPPER = 211, + NAV_CMD_DO_AUTOTUNE_ENABLE = 212, NAV_CMD_DO_SET_CAM_TRIGG_INTERVAL = 214, NAV_CMD_DO_SET_CAM_TRIGG_DIST = 206, NAV_CMD_OBLIQUE_SURVEY = 260, diff --git a/src/modules/navigator/navigator.h b/src/modules/navigator/navigator.h index cdabb9d36e..d70c7bd69b 100644 --- a/src/modules/navigator/navigator.h +++ b/src/modules/navigator/navigator.h @@ -282,6 +282,13 @@ public: void release_gimbal_control(); void set_gimbal_neutral(); + /* Set gimbal to neutral position (level with horizon) to reduce risk of damage on landing. + The commands are executed after time delay. */ + void neutralize_gimbal_if_control_activated(); + /* Accepts a new timestamp only if the current timestamp is UINT64_MAX, preventing the + timer from resetting during an ongoing neutral command. */ + void activate_set_gimbal_neutral_timer(const hrt_abstime timestamp); + void preproject_stop_point(double &lat, double &lon); void stop_capturing_images(); @@ -391,6 +398,9 @@ private: bool _is_capturing_images{false}; // keep track if we need to stop capturing images + // timer to trigger a delayed set gimbal neutral command + hrt_abstime _gimbal_neutral_activation_time{UINT64_MAX}; + // update subscriptions void params_update(); diff --git a/src/modules/navigator/navigator_main.cpp b/src/modules/navigator/navigator_main.cpp index c3c2fb3656..b07d92c176 100644 --- a/src/modules/navigator/navigator_main.cpp +++ b/src/modules/navigator/navigator_main.cpp @@ -652,6 +652,10 @@ void Navigator::run() _vtol_takeoff.setTransitionAltitudeAbsolute(cmd.param7); + if (std::fabs(cmd.param2 - 3.0f) < FLT_EPSILON) { // Specified transition direction + _vtol_takeoff.setTransitionDirection(cmd.param4); + } + // after the transition the vehicle will establish on a loiter at this position _vtol_takeoff.setLoiterLocation(matrix::Vector2d(cmd.param5, cmd.param6)); @@ -755,6 +759,21 @@ void Navigator::run() reset_cruising_speed(); set_cruising_throttle(); } + + else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_AUTOTUNE_ENABLE) { + + + if (fabsf(cmd.param1 - 1.f) > FLT_EPSILON) { + // only support enabling autotune (consistent with autotune module) + events::send(events::ID("navigator_autotune_unsupported_input"), {events::Log::Warning, events::LogInternal::Warning}, + "Provided autotune command is not supported. To enable autotune in mission, set param1 to 1"); + + } else if (fabsf(cmd.param2) > FLT_EPSILON) { + // warn user about axis selection + events::send(events::ID("navigator_autotune_unsupported_ax"), {events::Log::Warning, events::LogInternal::Info}, + "Autotune axis selection not supported through Mission. Use FW_AT_AXES to set axes for fixed-wing vehicles"); + } + } } #if CONFIG_NAVIGATOR_ADSB @@ -823,6 +842,7 @@ void Navigator::run() case vehicle_status_s::NAVIGATION_STATE_MANUAL: case vehicle_status_s::NAVIGATION_STATE_ACRO: case vehicle_status_s::NAVIGATION_STATE_ALTCTL: + case vehicle_status_s::NAVIGATION_STATE_ALTITUDE_CRUISE: case vehicle_status_s::NAVIGATION_STATE_POSCTL: case vehicle_status_s::NAVIGATION_STATE_DESCEND: case vehicle_status_s::NAVIGATION_STATE_TERMINATION: @@ -904,6 +924,8 @@ void Navigator::run() publish_mission_result(); } + neutralize_gimbal_if_control_activated(); + publish_navigator_status(); publish_distance_sensor_mode_request(); @@ -1080,7 +1102,7 @@ int Navigator::task_spawn(int argc, char *argv[]) _task_id = px4_task_spawn_cmd("navigator", SCHED_DEFAULT, SCHED_PRIORITY_NAVIGATION, - PX4_STACK_ADJUSTED(2200), + PX4_STACK_ADJUSTED(2230), (px4_main_t)&run_trampoline, (char *const *)argv); @@ -1629,6 +1651,27 @@ void Navigator::set_gimbal_neutral() publish_vehicle_command(vehicle_command); } +void Navigator::activate_set_gimbal_neutral_timer(const hrt_abstime timestamp) +{ + if (_gimbal_neutral_activation_time == UINT64_MAX) { + _gimbal_neutral_activation_time = timestamp; + } +} + +void Navigator::neutralize_gimbal_if_control_activated() +{ + const hrt_abstime now{hrt_absolute_time()}; + + // The time delay must be sufficiently long to allow flight tasks to complete its + // destruction and release gimbal control before the navigator takes control of the gimbal. + if (_gimbal_neutral_activation_time != UINT64_MAX && now > _gimbal_neutral_activation_time + 250_ms) { + acquire_gimbal_control(); + set_gimbal_neutral(); + release_gimbal_control(); + _gimbal_neutral_activation_time = UINT64_MAX; + } +} + void Navigator::sendWarningDescentStoppedDueToTerrain() { mavlink_log_critical(&_mavlink_log_pub, "Terrain collision risk, descent is stopped\t"); diff --git a/src/modules/navigator/rtl.cpp b/src/modules/navigator/rtl.cpp index b2898be415..1420113437 100644 --- a/src/modules/navigator/rtl.cpp +++ b/src/modules/navigator/rtl.cpp @@ -226,7 +226,10 @@ void RTL::on_activation() case RtlType::RTL_DIRECT_MISSION_LAND: // Fall through case RtlType::RTL_MISSION_FAST: // Fall through case RtlType::RTL_MISSION_FAST_REVERSE: - _rtl_mission_type_handle->setReturnAltMin(_enforce_rtl_alt); + if (_rtl_mission_type_handle) { + _rtl_mission_type_handle->setReturnAltMin(_enforce_rtl_alt); + } + break; case RtlType::RTL_DIRECT: @@ -237,10 +240,7 @@ void RTL::on_activation() break; } - // set gimbal to neutral position (level with horizon) to reduce change of damage on landing - _navigator->acquire_gimbal_control(); - _navigator->set_gimbal_neutral(); - _navigator->release_gimbal_control(); + _navigator->activate_set_gimbal_neutral_timer(hrt_absolute_time()); } void RTL::on_active() @@ -313,171 +313,235 @@ bool RTL::isLanding() void RTL::setRtlTypeAndDestination() { + uint8_t safe_point_index = UINT8_MAX; + RtlType new_rtl_type{RtlType::RTL_DIRECT}; - init_rtl_mission_type(); + // init destination with Home (used also with Type 2 and 4 as backup) + DestinationType destination_type = DestinationType::DESTINATION_TYPE_HOME; + PositionYawSetpoint destination; + destination.lat = _home_pos_sub.get().lat; + destination.lon = _home_pos_sub.get().lon; + destination.alt = _home_pos_sub.get().alt; + destination.yaw = _home_pos_sub.get().yaw; - uint8_t safe_point_index{0U}; + loiter_point_s landing_loiter; + landing_loiter.lat = destination.lat; + landing_loiter.lon = destination.lon; + landing_loiter.height_m = NAN; - if (_param_rtl_type.get() != 2 && _param_rtl_type.get() != 4) { + if (_param_rtl_type.get() == 2) { + if (hasMissionLandStart()) { + new_rtl_type = RtlType::RTL_MISSION_FAST; + + } else if (_navigator->get_mission_result()->valid) { + new_rtl_type = RtlType::RTL_MISSION_FAST_REVERSE; + + } else { + // no valid mission, go direct to home + new_rtl_type = RtlType::RTL_DIRECT; + } + + } else if (_param_rtl_type.get() == 4) { + if (hasMissionLandStart() && reverseIsFurther()) { + new_rtl_type = RtlType::RTL_MISSION_FAST; + + } else if (_navigator->get_mission_result()->valid) { + new_rtl_type = RtlType::RTL_MISSION_FAST_REVERSE; + + } else { + // no valid mission, go direct to home + new_rtl_type = RtlType::RTL_DIRECT; + } + + } else { // check the closest allowed destination. - DestinationType destination_type{DestinationType::DESTINATION_TYPE_HOME}; - PositionYawSetpoint rtl_position; - float rtl_alt; - findRtlDestination(destination_type, rtl_position, rtl_alt, safe_point_index); + findRtlDestination(destination_type, destination, safe_point_index); - switch (destination_type) { - case DestinationType::DESTINATION_TYPE_MISSION_LAND: - _rtl_type = RtlType::RTL_DIRECT_MISSION_LAND; - _rtl_mission_type_handle->setRtlAlt(rtl_alt); - break; + if (destination_type == DestinationType::DESTINATION_TYPE_MISSION_LAND) { + new_rtl_type = RtlType::RTL_DIRECT_MISSION_LAND; - case DestinationType::DESTINATION_TYPE_SAFE_POINT: // Fallthrough - case DestinationType::DESTINATION_TYPE_HOME: // Fallthrough - default: + } else { - loiter_point_s landing_loiter; - landing_loiter.lat = rtl_position.lat; - landing_loiter.lon = rtl_position.lon; + new_rtl_type = RtlType::RTL_DIRECT; + + land_approaches_s rtl_land_approaches{readVtolLandApproaches(destination)}; + + // set loiter position to destination initially, overwrite for VTOL if land approaches exist + landing_loiter.lat = destination.lat; + landing_loiter.lon = destination.lon; landing_loiter.height_m = NAN; - land_approaches_s rtl_land_approaches{readVtolLandApproaches(rtl_position)}; - if (_vehicle_status_sub.get().is_vtol && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING) && rtl_land_approaches.isAnyApproachValid()) { landing_loiter = chooseBestLandingApproach(rtl_land_approaches); } - - _rtl_type = RtlType::RTL_DIRECT; - _rtl_direct.setRtlAlt(rtl_alt); - _rtl_direct.setRtlPosition(rtl_position, landing_loiter); - - break; } } + const float rtl_alt = computeReturnAltitude(destination, destination_type, (float)_param_rtl_cone_ang.get()); + _rtl_direct.setRtlAlt(rtl_alt); + _rtl_direct.setRtlPosition(destination, landing_loiter); + + const bool new_type_is_mission_based = (new_rtl_type == RtlType::RTL_MISSION_FAST) + || (new_rtl_type == RtlType::RTL_MISSION_FAST_REVERSE) + || (new_rtl_type == RtlType::RTL_DIRECT_MISSION_LAND); + + if (new_type_is_mission_based && (_rtl_type != new_rtl_type)) { + initRtlMissionType(new_rtl_type, rtl_alt); + } + + _rtl_type = new_rtl_type; + // Publish rtl status - _rtl_status_pub.get().timestamp = hrt_absolute_time(); - _rtl_status_pub.get().safe_points_id = _safe_points_id; - _rtl_status_pub.get().is_evaluation_pending = _dataman_state != DatamanState::UpdateRequestWait; - _rtl_status_pub.get().has_vtol_approach = _home_has_land_approach || _one_rally_point_has_land_approach; - - _rtl_status_pub.get().rtl_type = static_cast(_rtl_type); - _rtl_status_pub.get().safe_point_index = safe_point_index; - - _rtl_status_pub.update(); - + rtl_status_s rtl_status{}; + rtl_status.safe_points_id = _safe_points_id; + rtl_status.is_evaluation_pending = _dataman_state != DatamanState::UpdateRequestWait; + rtl_status.has_vtol_approach = _home_has_land_approach || _one_rally_point_has_land_approach; + rtl_status.rtl_type = static_cast(_rtl_type); + rtl_status.safe_point_index = safe_point_index; + rtl_status.timestamp = hrt_absolute_time(); + _rtl_status_pub.publish(rtl_status); } -void RTL::findRtlDestination(DestinationType &destination_type, PositionYawSetpoint &rtl_position, float &rtl_alt, - uint8_t &safe_point_index) +PositionYawSetpoint RTL::findClosestSafePoint(float min_dist, uint8_t &safe_point_index) { - // set destination to home per default, then check if other valid landing spot is closer - rtl_position.alt = _home_pos_sub.get().alt; - rtl_position.lat = _home_pos_sub.get().lat; - rtl_position.lon = _home_pos_sub.get().lon; - rtl_position.yaw = _home_pos_sub.get().yaw; - destination_type = DestinationType::DESTINATION_TYPE_HOME; - - const bool vtol_in_rw_mode = _vehicle_status_sub.get().is_vtol - && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING); - const bool vtol_in_fw_mode = _vehicle_status_sub.get().is_vtol && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING); - // get distance to home position - float home_dist{get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, rtl_position.lat, rtl_position.lon)}; - float min_dist; - - _home_has_land_approach = hasVtolLandApproach(rtl_position); - - if (((_param_rtl_type.get() == 1) && !vtol_in_rw_mode) || (vtol_in_fw_mode && (_param_rtl_approach_force.get() == 1) - && !_home_has_land_approach)) { - // Set minimum distance to maximum value when RTL_TYPE is set to 1 and we are not in RW mode or we forces approach landing for vtol in fw and it is not defined for home. - min_dist = FLT_MAX; - - } else { - min_dist = home_dist; - } - - // consider the mission landing if available and allowed - if (((_param_rtl_type.get() == 1) || (_param_rtl_type.get() == 3) || (fabsf(FLT_MAX - min_dist) < FLT_EPSILON)) - && hasMissionLandStart()) { - mission_item_s land_mission_item; - const dm_item_t dm_item = static_cast(_mission_sub.get().mission_dataman_id); - bool success = _dataman_cache_landItem.loadWait(dm_item, _mission_sub.get().land_index, - reinterpret_cast(&land_mission_item), sizeof(mission_item_s), 500_ms); - - if (!success) { - /* not supposed to happen unless the datamanager can't access the SD card, etc. */ - mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Mission land item could not be read.\t"); - events::send(events::ID("rtl_failed_to_read_land_item"), events::Log::Error, - "Mission land item could not be read"); - } - - float dist{get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, land_mission_item.lat, land_mission_item.lon)}; - - if ((dist + MIN_DIST_THRESHOLD) < min_dist) { - if (_param_rtl_type.get() != 0) { - min_dist = dist; - - } else { - // Mission landing is not allowed, but home has no approaches. Still use mission landing. - min_dist = FLT_MAX; - } - - setLandPosAsDestination(rtl_position, land_mission_item); - destination_type = DestinationType::DESTINATION_TYPE_MISSION_LAND; - } - } + PositionYawSetpoint safe_point{(double)NAN, (double)NAN, NAN, NAN}; if (_safe_points_updated) { - _one_rally_point_has_land_approach = false; for (int current_seq = 0; current_seq < _dataman_cache_safepoint.size(); ++current_seq) { mission_item_s mission_safe_point; - bool success = _dataman_cache_safepoint.loadWait(static_cast(_stats.dataman_id), current_seq, - reinterpret_cast(&mission_safe_point), - sizeof(mission_item_s), 500_ms); + const bool success = _dataman_cache_safepoint.loadWait(static_cast(_stats.dataman_id), current_seq, + reinterpret_cast(&mission_safe_point), + sizeof(mission_item_s), 500_ms); if (!success) { PX4_ERR("dm_read failed"); continue; } - // Ignore safepoints which are too close to the homepoint - const float dist_to_home = get_distance_to_next_waypoint(_home_pos_sub.get().lat, _home_pos_sub.get().lon, - mission_safe_point.lat, mission_safe_point.lon); + // Ignore safepoints which are too close to the homepoint (only if home is an option to return to) + const bool far_from_home = get_distance_to_next_waypoint(_home_pos_sub.get().lat, _home_pos_sub.get().lon, + mission_safe_point.lat, mission_safe_point.lon) > MAX_DIST_FROM_HOME_FOR_LAND_APPROACHES; - if (mission_safe_point.nav_cmd == NAV_CMD_RALLY_POINT && dist_to_home > MAX_DIST_FROM_HOME_FOR_LAND_APPROACHES) { - float dist{get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, mission_safe_point.lat, mission_safe_point.lon)}; + if (mission_safe_point.nav_cmd == NAV_CMD_RALLY_POINT && (far_from_home || (_param_rtl_type.get() == 5))) { + const float dist{get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, mission_safe_point.lat, mission_safe_point.lon)}; PositionYawSetpoint safepoint_position; setSafepointAsDestination(safepoint_position, mission_safe_point); - bool current_safe_point_has_approaches{hasVtolLandApproach(safepoint_position)}; + const bool current_safe_point_has_approaches{hasVtolLandApproach(safepoint_position)}; _one_rally_point_has_land_approach |= current_safe_point_has_approaches; - if (((dist + MIN_DIST_THRESHOLD) < min_dist) && (!vtol_in_fw_mode || (_param_rtl_approach_force.get() == 0) - || current_safe_point_has_approaches)) { + if (((dist + MIN_DIST_THRESHOLD) < min_dist) + && (!vtol_in_fw_mode || (_param_rtl_appr_force.get() == 0) || current_safe_point_has_approaches)) { min_dist = dist; - rtl_position = safepoint_position; - destination_type = DestinationType::DESTINATION_TYPE_SAFE_POINT; + safe_point = safepoint_position; safe_point_index = current_seq; } } } } - if (_param_rtl_cone_half_angle_deg.get() > 0 - && _vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) { - rtl_alt = calculate_return_alt_from_cone_half_angle(rtl_position, (float)_param_rtl_cone_half_angle_deg.get()); + return safe_point; +} - } else { - rtl_alt = max(_global_pos_sub.get().alt, rtl_position.alt + _param_rtl_return_alt.get()); +void RTL::findRtlDestination(DestinationType &destination_type, PositionYawSetpoint &destination, uint8_t &safe_point_index) +{ + const bool vtol_in_rw_mode = _vehicle_status_sub.get().is_vtol + && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING); + + const bool vtol_in_fw_mode = _vehicle_status_sub.get().is_vtol + && (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING); + + float min_dist = FLT_MAX; + + if (_param_rtl_type.get() != 5) { + _home_has_land_approach = hasVtolLandApproach(destination); + + const bool prioritize_safe_points_over_home = ((_param_rtl_type.get() == 1) && !vtol_in_rw_mode); + const bool required_approach_missing_for_home = (vtol_in_fw_mode && (_param_rtl_appr_force.get() == 1) && !_home_has_land_approach); + + // Set minimum distance to maximum value when RTL_TYPE is set to 1 and we are not in RW mode or we force approach landing for vtol in fw and it is not defined for home. + const bool deprioritize_home = prioritize_safe_points_over_home || required_approach_missing_for_home; + + if (!deprioritize_home) { + // distance to home position + min_dist = get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, destination.lat, destination.lon); + } + + // Mission landing + if (((_param_rtl_type.get() == 1) || (_param_rtl_type.get() == 3) || (fabsf(FLT_MAX - min_dist) < FLT_EPSILON)) && hasMissionLandStart()) { + mission_item_s land_mission_item; + const dm_item_t dm_item = static_cast(_mission_sub.get().mission_dataman_id); + bool success = _dataman_cache_landItem.loadWait(dm_item, _mission_sub.get().land_index, + reinterpret_cast(&land_mission_item), sizeof(mission_item_s), 500_ms); + + if (!success) { + /* not supposed to happen unless the datamanager can't access the SD card, etc. */ + mavlink_log_critical(_navigator->get_mavlink_log_pub(), "Mission land item could not be read.\t"); + events::send(events::ID("rtl_failed_to_read_land_item"), events::Log::Error, + "Mission land item could not be read"); + } + + float dist{get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, land_mission_item.lat, land_mission_item.lon)}; + + if ((dist + MIN_DIST_THRESHOLD) < min_dist) { + if (_param_rtl_type.get() != 0) { + min_dist = dist; + + } else { + // Mission landing is not allowed, but home has no approaches. Still use mission landing. + min_dist = FLT_MAX; + } + + setLandPosAsDestination(destination, land_mission_item); + destination_type = DestinationType::DESTINATION_TYPE_MISSION_LAND; + } + } + } + + // Safe/rally points + PositionYawSetpoint safe_point = findClosestSafePoint(min_dist, safe_point_index); + + if (safe_point_index != UINT8_MAX) { + destination = safe_point; + destination_type = DestinationType::DESTINATION_TYPE_SAFE_POINT; + + } else if (_param_rtl_type.get() == 5) { + // Safe points only but no valid safe point, fallback to last position with valid data link + for (auto &telemetry_status : _telemetry_status_subs) { + telemetry_status_s telemetry; + + if (telemetry_status.update(&telemetry)) { + + if (telemetry.heartbeat_type_gcs) { + _last_position_before_link_loss.alt = _global_pos_sub.get().alt; + _last_position_before_link_loss.lat = _global_pos_sub.get().lat; + _last_position_before_link_loss.lon = _global_pos_sub.get().lon; + break; + } + } + } + + if (PX4_ISFINITE(_last_position_before_link_loss.lat) && PX4_ISFINITE(_last_position_before_link_loss.lon)) { + destination = _last_position_before_link_loss; + + } else { + // If no valid data link position, fallback to current position + destination.alt = _global_pos_sub.get().alt; + destination.lat = _global_pos_sub.get().lat; + destination.lon = _global_pos_sub.get().lon; + } + + destination_type = DestinationType::DESTINATION_TYPE_LAST_LINK_POSITION; } } @@ -487,11 +551,9 @@ void RTL::setLandPosAsDestination(PositionYawSetpoint &rtl_position, mission_ite _home_pos_sub.get().alt : land_mission_item.altitude; rtl_position.lat = land_mission_item.lat; rtl_position.lon = land_mission_item.lon; - rtl_position.yaw = _home_pos_sub.get().yaw; } -void RTL::setSafepointAsDestination(PositionYawSetpoint &rtl_position, - const mission_item_s &mission_safe_point) const +void RTL::setSafepointAsDestination(PositionYawSetpoint &rtl_position, const mission_item_s &mission_safe_point) const { // There is a safe point closer than home/mission landing // TODO: handle all possible mission_safe_point.frame cases @@ -500,14 +562,12 @@ void RTL::setSafepointAsDestination(PositionYawSetpoint &rtl_position, rtl_position.lat = mission_safe_point.lat; rtl_position.lon = mission_safe_point.lon; rtl_position.alt = mission_safe_point.altitude; - rtl_position.yaw = _home_pos_sub.get().yaw;; break; case 3: // MAV_FRAME_GLOBAL_RELATIVE_ALT rtl_position.lat = mission_safe_point.lat; rtl_position.lon = mission_safe_point.lon; rtl_position.alt = mission_safe_point.altitude + _home_pos_sub.get().alt; // alt of safe point is rel to home - rtl_position.yaw = _home_pos_sub.get().yaw;; break; default: @@ -518,102 +578,95 @@ void RTL::setSafepointAsDestination(PositionYawSetpoint &rtl_position, } } -float RTL::calculate_return_alt_from_cone_half_angle(const PositionYawSetpoint &rtl_position, - float cone_half_angle_deg) const +float RTL::computeReturnAltitude(const PositionYawSetpoint &rtl_position, DestinationType destination_type, float cone_half_angle_deg) const { - // horizontal distance to destination - const float destination_dist = get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, - rtl_position.lat, rtl_position.lon); + if (destination_type == DestinationType::DESTINATION_TYPE_LAST_LINK_POSITION) { + // when returning to last known link position, do not modify altitude + return rtl_position.alt; + } - // minium rtl altitude to use when outside of horizontal acceptance radius of target position. - // We choose the minimum height to be two times the distance from the land position in order to - // avoid the vehicle touching the ground while still moving horizontally. - const float return_altitude_min_outside_acceptance_rad_amsl = rtl_position.alt + 2.0f * _param_nav_acc_rad.get(); + if (_param_rtl_cone_ang.get() > 0 && _vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) { + // horizontal distance to destination + const float destination_dist = + get_distance_to_next_waypoint(_global_pos_sub.get().lat, _global_pos_sub.get().lon, rtl_position.lat, rtl_position.lon); - const float max_return_altitude = rtl_position.alt + _param_rtl_return_alt.get(); + // minium rtl altitude to use when outside of horizontal acceptance radius of target position. + // We choose the minimum height to be two times the distance from the land position in order to + // avoid the vehicle touching the ground while still moving horizontally. + const float return_altitude_min_outside_acceptance_rad_amsl = rtl_position.alt + 2.0f * _param_nav_acc_rad.get(); - float return_altitude_amsl = max_return_altitude; + const float max_return_altitude = rtl_position.alt + _param_rtl_return_alt.get(); - if (destination_dist <= _param_nav_acc_rad.get()) { - return_altitude_amsl = rtl_position.alt + 2.0f * destination_dist; + float return_altitude_amsl = max_return_altitude; + + if (destination_dist <= _param_nav_acc_rad.get()) { + return_altitude_amsl = rtl_position.alt + 2.0f * destination_dist; + + } else { + if (destination_dist <= _param_rtl_min_dist.get()) { + + // constrain cone half angle to meaningful values. All other cases are already handled above. + const float cone_half_angle_rad = radians(constrain(cone_half_angle_deg, 1.0f, 89.0f)); + + // minimum altitude we need in order to be within the user defined cone + const float cone_intersection_altitude_amsl = destination_dist / tanf(cone_half_angle_rad) + rtl_position.alt; + + return_altitude_amsl = min(cone_intersection_altitude_amsl, return_altitude_amsl); + } + + return_altitude_amsl = max(return_altitude_amsl, return_altitude_min_outside_acceptance_rad_amsl); + } + + return constrain(return_altitude_amsl, _global_pos_sub.get().alt, max_return_altitude); } else { - if (destination_dist <= _param_rtl_min_dist.get()) { - - // constrain cone half angle to meaningful values. All other cases are already handled above. - const float cone_half_angle_rad = radians(constrain(cone_half_angle_deg, 1.0f, 89.0f)); - - // minimum altitude we need in order to be within the user defined cone - const float cone_intersection_altitude_amsl = destination_dist / tanf(cone_half_angle_rad) + rtl_position.alt; - - return_altitude_amsl = min(cone_intersection_altitude_amsl, return_altitude_amsl); - } - - return_altitude_amsl = max(return_altitude_amsl, return_altitude_min_outside_acceptance_rad_amsl); + // standard behaviour: return altitude above rtl destination + return max(_global_pos_sub.get().alt, rtl_position.alt + _param_rtl_return_alt.get()); } - - return constrain(return_altitude_amsl, _global_pos_sub.get().alt, max_return_altitude); } -void RTL::init_rtl_mission_type() +void RTL::initRtlMissionType(RtlType new_rtl_type, float rtl_alt) { - RtlType new_rtl_mission_type{RtlType::RTL_DIRECT_MISSION_LAND}; - - if (_param_rtl_type.get() == 2) { - if (hasMissionLandStart()) { - new_rtl_mission_type = RtlType::RTL_MISSION_FAST; - - } else { - new_rtl_mission_type = RtlType::RTL_MISSION_FAST_REVERSE; - } - - } else if (_param_rtl_type.get() == 4) { - if (hasMissionLandStart() && reverseIsFurther()) { - new_rtl_mission_type = RtlType::RTL_MISSION_FAST; - - } else { - new_rtl_mission_type = RtlType::RTL_MISSION_FAST_REVERSE; - } - } - - if (_set_rtl_mission_type == new_rtl_mission_type) { - return; - } - if (_rtl_mission_type_handle) { delete _rtl_mission_type_handle; _rtl_mission_type_handle = nullptr; - _set_rtl_mission_type = RtlType::NONE; } mission_s new_mission = _mission_sub.get(); - switch (new_rtl_mission_type) { + switch (new_rtl_type) { case RtlType::RTL_DIRECT_MISSION_LAND: _rtl_mission_type_handle = new RtlDirectMissionLand(_navigator); - _set_rtl_mission_type = RtlType::RTL_DIRECT_MISSION_LAND; + + if (_rtl_mission_type_handle) { + _rtl_mission_type_handle->setRtlAlt(rtl_alt); + _rtl_mission_type_handle->initialize(); + } + // RTL type is either direct or mission land have to set it later. break; case RtlType::RTL_MISSION_FAST: _rtl_mission_type_handle = new RtlMissionFast(_navigator, new_mission); - _set_rtl_mission_type = RtlType::RTL_MISSION_FAST; - _rtl_type = RtlType::RTL_MISSION_FAST; + + if (_rtl_mission_type_handle) { + _rtl_mission_type_handle->initialize(); + } + break; case RtlType::RTL_MISSION_FAST_REVERSE: _rtl_mission_type_handle = new RtlMissionFastReverse(_navigator, new_mission); - _set_rtl_mission_type = RtlType::RTL_MISSION_FAST_REVERSE; - _rtl_type = RtlType::RTL_MISSION_FAST_REVERSE; + + if (_rtl_mission_type_handle) { + _rtl_mission_type_handle->initialize(); + } + break; default: break; } - - if (_rtl_mission_type_handle) { - _rtl_mission_type_handle->initialize(); - } } void RTL::parameters_update() diff --git a/src/modules/navigator/rtl.h b/src/modules/navigator/rtl.h index 207af7ceb5..d6c5a9afb6 100644 --- a/src/modules/navigator/rtl.h +++ b/src/modules/navigator/rtl.h @@ -55,11 +55,13 @@ #include #include #include +#include #include #include #include #include #include +#include class Navigator; @@ -71,11 +73,11 @@ public: ~RTL() = default; enum class RtlType { - NONE, - RTL_DIRECT, - RTL_DIRECT_MISSION_LAND, - RTL_MISSION_FAST, - RTL_MISSION_FAST_REVERSE, + NONE = rtl_status_s::RTL_STATUS_TYPE_NONE, + RTL_DIRECT = rtl_status_s::RTL_STATUS_TYPE_DIRECT_SAFE_POINT, + RTL_DIRECT_MISSION_LAND = rtl_status_s::RTL_STATUS_TYPE_DIRECT_MISSION_LAND, + RTL_MISSION_FAST = rtl_status_s::RTL_STATUS_TYPE_FOLLOW_MISSION, + RTL_MISSION_FAST_REVERSE = rtl_status_s::RTL_STATUS_TYPE_FOLLOW_MISSION_REVERSE, }; void on_inactive() override; @@ -95,6 +97,7 @@ private: DESTINATION_TYPE_HOME, DESTINATION_TYPE_MISSION_LAND, DESTINATION_TYPE_SAFE_POINT, + DESTINATION_TYPE_LAST_LINK_POSITION }; private: @@ -130,8 +133,13 @@ private: * @brief Find RTL destination. * */ - void findRtlDestination(DestinationType &destination_type, PositionYawSetpoint &rtl_position, float &rtl_alt, - uint8_t &safe_point_index); + void findRtlDestination(DestinationType &destination_type, PositionYawSetpoint &destination, uint8_t &safe_point_index); + + /** + * @brief Find RTL destination if only safe points are considered + * + */ + PositionYawSetpoint findClosestSafePoint(float min_dist, uint8_t &safe_point_index); /** * @brief Set the position of the land start marker in the planned mission as destination. @@ -147,20 +155,20 @@ private: void setSafepointAsDestination(PositionYawSetpoint &rtl_position, const mission_item_s &mission_safe_point) const; /** - * @brief calculate return altitude from cone half angle + * @brief calculate return altitude from return altitude parameter, current altitude and cone angle * * @param[in] rtl_position landing position of the rtl + * @param[in] destination_type type of the rtl destination * @param[in] cone_half_angle_deg half angle of the cone [deg] * @return return altitude */ - float calculate_return_alt_from_cone_half_angle(const PositionYawSetpoint &rtl_position, - float cone_half_angle_deg) const; + float computeReturnAltitude(const PositionYawSetpoint &rtl_position, DestinationType destination_type, float cone_half_angle_deg) const; /** * @brief initialize RTL mission type * */ - void init_rtl_mission_type(); + void initRtlMissionType(RtlType new_rtl_type, float rtl_alt); /** * @brief Update parameters @@ -206,8 +214,6 @@ private: hrt_abstime _destination_check_time{0}; RtlBase *_rtl_mission_type_handle{nullptr}; - RtlType _set_rtl_mission_type{RtlType::NONE}; - RtlType _rtl_type{RtlType::RTL_DIRECT}; bool _home_has_land_approach; ///< Flag if the home position has a land approach defined @@ -223,6 +229,7 @@ private: mutable DatamanCache _dataman_cache_landItem{"rtl_dm_cache_miss_land", 2}; uint32_t _mission_id = 0u; uint32_t _safe_points_id = 0u; + PositionYawSetpoint _last_position_before_link_loss{(double)NAN, (double)NAN, NAN, NAN}; mission_stats_entry_s _stats; @@ -232,11 +239,11 @@ private: DEFINE_PARAMETERS( (ParamInt) _param_rtl_type, - (ParamInt) _param_rtl_cone_half_angle_deg, + (ParamInt) _param_rtl_cone_ang, (ParamFloat) _param_rtl_return_alt, (ParamFloat) _param_rtl_min_dist, (ParamFloat) _param_nav_acc_rad, - (ParamInt) _param_rtl_approach_force + (ParamInt) _param_rtl_appr_force ) uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; @@ -246,7 +253,8 @@ private: uORB::SubscriptionData _mission_sub{ORB_ID(mission)}; uORB::SubscriptionData _home_pos_sub{ORB_ID(home_position)}; uORB::SubscriptionData _wind_sub{ORB_ID(wind)}; + uORB::SubscriptionMultiArray _telemetry_status_subs{ORB_ID::telemetry_status}; uORB::Publication _rtl_time_estimate_pub{ORB_ID(rtl_time_estimate)}; - uORB::PublicationData _rtl_status_pub{ORB_ID(rtl_status)}; + uORB::Publication _rtl_status_pub{ORB_ID(rtl_status)}; }; diff --git a/src/modules/navigator/rtl_direct.cpp b/src/modules/navigator/rtl_direct.cpp index 03d39e9d54..9c53bca44f 100644 --- a/src/modules/navigator/rtl_direct.cpp +++ b/src/modules/navigator/rtl_direct.cpp @@ -54,8 +54,6 @@ RtlDirect::RtlDirect(Navigator *navigator) : MissionBlock(navigator, vehicle_status_s::NAVIGATION_STATE_AUTO_RTL), ModuleParams(navigator) { - _destination.lat = static_cast(NAN); - _destination.lon = static_cast(NAN); _land_approach.lat = static_cast(NAN); _land_approach.lon = static_cast(NAN); _land_approach.height_m = NAN; @@ -127,8 +125,6 @@ void RtlDirect::on_inactive() void RtlDirect::setRtlPosition(PositionYawSetpoint rtl_position, loiter_point_s loiter_pos) { - _home_pos_sub.update(); - parameters_update(); // Only allow to set a new approach if the mode is not activated yet. @@ -136,20 +132,6 @@ void RtlDirect::setRtlPosition(PositionYawSetpoint rtl_position, loiter_point_s _destination = rtl_position; _force_heading = false; - // Input sanitation - if (!PX4_ISFINITE(_destination.lat) || !PX4_ISFINITE(_destination.lon)) { - // We don't have a valid rtl position, use the home position instead. - _destination.lat = _home_pos_sub.get().lat; - _destination.lon = _home_pos_sub.get().lon; - _destination.alt = _home_pos_sub.get().alt; - _destination.yaw = _home_pos_sub.get().yaw; - } - - if (!PX4_ISFINITE(_destination.alt)) { - // Not a valid rtl land altitude. Assume same altitude as home position. - _destination.alt = _home_pos_sub.get().alt; - } - _land_approach = sanitizeLandApproach(loiter_pos); const float dist_to_destination{get_distance_to_next_waypoint(_land_approach.lat, _land_approach.lon, _destination.lat, _destination.lon)}; @@ -507,7 +489,7 @@ rtl_time_estimate_s RtlDirect::calc_rtl_time_estimate() case RTLState::MOVE_TO_LAND: case RTLState::TRANSITION_TO_MC: case RTLState::MOVE_TO_LAND_HOVER: { - // Add cruise segment to home + // Add cruise segment to destination float move_to_land_dist{0.f}; matrix::Vector2f direction{}; diff --git a/src/modules/navigator/rtl_direct.h b/src/modules/navigator/rtl_direct.h index c2dd3e00ea..40fb18e0cc 100644 --- a/src/modules/navigator/rtl_direct.h +++ b/src/modules/navigator/rtl_direct.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -167,10 +166,10 @@ private: bool _force_heading{false}; RtlTimeEstimator _rtl_time_estimator; - PositionYawSetpoint _destination; ///< the RTL position to fly to + PositionYawSetpoint _destination{(double)NAN, (double)NAN, NAN, NAN}; ///< the RTL position to fly to loiter_point_s _land_approach; - float _rtl_alt{0.0f}; ///< AMSL altitude at which the vehicle should return to the home position + float _rtl_alt{0.0f}; ///< AMSL altitude at which the vehicle should transit to the destination DEFINE_PARAMETERS( (ParamFloat) _param_rtl_descend_alt, @@ -185,7 +184,6 @@ private: uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; uORB::SubscriptionData _global_pos_sub{ORB_ID(vehicle_global_position)}; /**< global position subscription */ - uORB::SubscriptionData _home_pos_sub{ORB_ID(home_position)}; /**< home position subscription */ uORB::SubscriptionData _land_detected_sub{ORB_ID(vehicle_land_detected)}; /**< vehicle land detected subscription */ uORB::SubscriptionData _vehicle_status_sub{ORB_ID(vehicle_status)}; /**< vehicle status subscription */ uORB::SubscriptionData _wind_sub{ORB_ID(wind)}; diff --git a/src/modules/navigator/rtl_direct_mission_land.cpp b/src/modules/navigator/rtl_direct_mission_land.cpp index 7e8b3d4aa4..7fdbe1add5 100644 --- a/src/modules/navigator/rtl_direct_mission_land.cpp +++ b/src/modules/navigator/rtl_direct_mission_land.cpp @@ -122,6 +122,7 @@ void RtlDirectMissionLand::setActiveMissionItems() { WorkItemType new_work_item_type{WorkItemType::WORK_ITEM_TYPE_DEFAULT}; position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet(); + const position_setpoint_s current_setpoint_copy = pos_sp_triplet->current; // Climb to altitude if (_needs_climbing && _work_item_type == WorkItemType::WORK_ITEM_TYPE_DEFAULT) { @@ -203,8 +204,6 @@ void RtlDirectMissionLand::setActiveMissionItems() _mission_item.autocontinue = true; _mission_item.time_inside = 0.0f; - - pos_sp_triplet->previous = pos_sp_triplet->current; } if (num_found_items > 0) { @@ -213,6 +212,12 @@ void RtlDirectMissionLand::setActiveMissionItems() mission_item_to_position_setpoint(_mission_item, &pos_sp_triplet->current); + // Only set the previous position item if the current one really changed + if ((_work_item_type != WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND) && + !position_setpoint_equal(&pos_sp_triplet->current, ¤t_setpoint_copy)) { + pos_sp_triplet->previous = current_setpoint_copy; + } + // prevent lateral guidance from loitering at a waypoint as part of a mission landing if the altitude // is not achieved. const bool fw_on_mission_landing = _vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING diff --git a/src/modules/navigator/rtl_mission_fast.cpp b/src/modules/navigator/rtl_mission_fast.cpp index ccfc91cfde..6c1d99d5fd 100644 --- a/src/modules/navigator/rtl_mission_fast.cpp +++ b/src/modules/navigator/rtl_mission_fast.cpp @@ -57,7 +57,7 @@ void RtlMissionFast::on_inactive() MissionBase::on_inactive(); _vehicle_status_sub.update(); _mission_index_prior_rtl = _vehicle_status_sub.get().nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION ? - _mission.current_seq : -1; + _mission.current_seq : INT32_C(-1); } void RtlMissionFast::on_activation() @@ -65,13 +65,30 @@ void RtlMissionFast::on_activation() _home_pos_sub.update(); // set mission item to closest item if not already in mission - if (_mission_index_prior_rtl < 0) { + if (_mission_index_prior_rtl < INT32_C(0)) { _is_current_planned_mission_item_valid = setMissionToClosestItem(_global_pos_sub.get().lat, _global_pos_sub.get().lon, _global_pos_sub.get().alt, _home_pos_sub.get().alt, _vehicle_status_sub.get()) == PX4_OK; } else { - setMissionIndex(_mission_index_prior_rtl); - _is_current_planned_mission_item_valid = isMissionValid(); + int32_t next_mission_item_index; + size_t num_found_items{0U}; + getNextPositionItems(_mission_index_prior_rtl, &next_mission_item_index, num_found_items, UINT8_C(1)); + + if (num_found_items > 0U) { + setMissionIndex(next_mission_item_index); + _is_current_planned_mission_item_valid = isMissionValid(); + + } else { + // No more position items left. Set it to the land item if it exists + if (_mission.land_index > 0) { + setMissionIndex(_mission.land_index); + _is_current_planned_mission_item_valid = isMissionValid(); + + } else { + // Nothing we can do, set the validity to false to trigger end of mission reaction + _is_current_planned_mission_item_valid = false; + } + } } if (_land_detected_sub.get().landed) { @@ -91,6 +108,7 @@ void RtlMissionFast::setActiveMissionItems() { WorkItemType new_work_item_type{WorkItemType::WORK_ITEM_TYPE_DEFAULT}; position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet(); + const position_setpoint_s current_setpoint_copy = pos_sp_triplet->current; /* Skip VTOL/FW Takeoff item if in air, fixed-wing and didn't start the takeoff already*/ if ((_mission_item.nav_cmd == NAV_CMD_VTOL_TAKEOFF || _mission_item.nav_cmd == NAV_CMD_TAKEOFF) && @@ -158,19 +176,28 @@ void RtlMissionFast::setActiveMissionItems() _mission_item.autocontinue = true; _mission_item.time_inside = 0.0f; - pos_sp_triplet->previous = pos_sp_triplet->current; } - - if (num_found_items > 0) { mission_item_to_position_setpoint(next_mission_items[0u], &pos_sp_triplet->next); } mission_item_to_position_setpoint(_mission_item, &pos_sp_triplet->current); - if (_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING && isLanding() && - _mission_item.nav_cmd == NAV_CMD_WAYPOINT) { + // Only set the previous position item if the current one really changed + if ((_work_item_type != WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND) && + !position_setpoint_equal(&pos_sp_triplet->current, ¤t_setpoint_copy)) { + pos_sp_triplet->previous = current_setpoint_copy; + } + + const bool fw_on_mission_landing = _vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING + && isLanding() && + _mission_item.nav_cmd == NAV_CMD_WAYPOINT; + const bool mc_landing_after_transition = _vehicle_status_sub.get().vehicle_type == + vehicle_status_s::VEHICLE_TYPE_ROTARY_WING && _vehicle_status_sub.get().is_vtol && + new_work_item_type == WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND; + + if (fw_on_mission_landing || mc_landing_after_transition) { pos_sp_triplet->current.alt_acceptance_radius = FLT_MAX; } } diff --git a/src/modules/navigator/rtl_mission_fast.h b/src/modules/navigator/rtl_mission_fast.h index d1231022b6..38814f96d0 100644 --- a/src/modules/navigator/rtl_mission_fast.h +++ b/src/modules/navigator/rtl_mission_fast.h @@ -64,7 +64,7 @@ private: bool setNextMissionItem() override; void setActiveMissionItems() override; - int _mission_index_prior_rtl{-1}; + int32_t _mission_index_prior_rtl{INT32_C(-1)}; uORB::SubscriptionData _home_pos_sub{ORB_ID(home_position)}; /**< home position subscription */ }; diff --git a/src/modules/navigator/rtl_mission_fast_reverse.cpp b/src/modules/navigator/rtl_mission_fast_reverse.cpp index 6abf4cf10f..7f3bb46f9f 100644 --- a/src/modules/navigator/rtl_mission_fast_reverse.cpp +++ b/src/modules/navigator/rtl_mission_fast_reverse.cpp @@ -57,7 +57,7 @@ void RtlMissionFastReverse::on_inactive() MissionBase::on_inactive(); _vehicle_status_sub.update(); _mission_index_prior_rtl = _vehicle_status_sub.get().nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION ? - _mission.current_seq : -1; + _mission.current_seq : INT32_C(-1); } void RtlMissionFastReverse::on_inactivation() @@ -71,13 +71,24 @@ void RtlMissionFastReverse::on_activation() _home_pos_sub.update(); // set mission item to closest item if not already in mission. If we are in mission, set to the previous item. - if (_mission_index_prior_rtl < 0) { + if (_mission_index_prior_rtl < INT32_C(0)) { _is_current_planned_mission_item_valid = setMissionToClosestItem(_global_pos_sub.get().lat, _global_pos_sub.get().lon, _global_pos_sub.get().alt, _home_pos_sub.get().alt, _vehicle_status_sub.get()) == PX4_OK; } else { - setMissionIndex(math::max(_mission_index_prior_rtl - 1, 0)); - _is_current_planned_mission_item_valid = isMissionValid(); + int32_t previous_mission_item_index; + size_t num_found_items{0U}; + getPreviousPositionItems(math::max(_mission_index_prior_rtl - INT32_C(1), INT32_C(0)), &previous_mission_item_index, + num_found_items, UINT8_C(1)); + + if (num_found_items > 0U) { + setMissionIndex(previous_mission_item_index); + _is_current_planned_mission_item_valid = isMissionValid(); + + } else { + // No prior position items, so try to go to the first one. + _is_current_planned_mission_item_valid = (goToNextPositionItem(false) == PX4_OK); + } } if (_land_detected_sub.get().landed) { @@ -246,10 +257,12 @@ void RtlMissionFastReverse::handleLanding(WorkItemType &new_work_item_type) } else if ((_work_item_type == WorkItemType::WORK_ITEM_TYPE_CLIMB || _work_item_type == WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND || _work_item_type == WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND_AFTER_TRANSITION)) { - _mission_item.nav_cmd = NAV_CMD_LAND; + _mission_item.lat = _home_pos_sub.get().lat; _mission_item.lon = _home_pos_sub.get().lon; _mission_item.yaw = NAN; + _mission_item.altitude = _global_pos_sub.get().alt; + _mission_item.altitude_is_relative = false; // make previous and next setpoints invalid, such that there will be no line following. // If the vehicle drifted off the path during back-transition it should just go straight to the landing point. @@ -260,15 +273,17 @@ void RtlMissionFastReverse::handleLanding(WorkItemType &new_work_item_type) do_need_move_to_item()) { new_work_item_type = WorkItemType::WORK_ITEM_TYPE_MOVE_TO_LAND; - _mission_item.altitude = _global_pos_sub.get().alt; - _mission_item.altitude_is_relative = false; _mission_item.nav_cmd = NAV_CMD_WAYPOINT; _mission_item.autocontinue = true; _mission_item.time_inside = 0.0f; } else { - _mission_item.altitude = _home_pos_sub.get().alt; - _mission_item.altitude_is_relative = false; + _mission_item.nav_cmd = NAV_CMD_LAND; + + if (_param_rtl_land_delay.get() < -FLT_EPSILON) { // parameter negative -> loiter indefinitely instead of landing + _mission_item.altitude = _home_pos_sub.get().alt + _param_rtl_descend_alt.get(); + _mission_item.nav_cmd = NAV_CMD_WAYPOINT; + } _mission_item.land_precision = _param_rtl_pld_md.get(); diff --git a/src/modules/navigator/rtl_mission_fast_reverse.h b/src/modules/navigator/rtl_mission_fast_reverse.h index 0351f8dbf8..8f96b95dc6 100644 --- a/src/modules/navigator/rtl_mission_fast_reverse.h +++ b/src/modules/navigator/rtl_mission_fast_reverse.h @@ -69,13 +69,15 @@ private: void setActiveMissionItems() override; void handleLanding(WorkItemType &new_work_item_type); - int _mission_index_prior_rtl{-1}; + int32_t _mission_index_prior_rtl{INT32_C(-1)}; bool _in_landing_phase{false}; uORB::SubscriptionData _home_pos_sub{ORB_ID(home_position)}; /**< home position subscription */ DEFINE_PARAMETERS_CUSTOM_PARENT( RtlBase, - (ParamInt) _param_rtl_pld_md + (ParamInt) _param_rtl_pld_md, + (ParamFloat) _param_rtl_descend_alt, + (ParamFloat) _param_rtl_land_delay ) }; diff --git a/src/modules/navigator/rtl_params.c b/src/modules/navigator/rtl_params.c index af02033c3a..0216f6606d 100644 --- a/src/modules/navigator/rtl_params.c +++ b/src/modules/navigator/rtl_params.c @@ -109,10 +109,11 @@ PARAM_DEFINE_FLOAT(RTL_MIN_DIST, 10.0f); * Return mode destination and flight path (home location, rally point, mission landing pattern, reverse mission) * * @value 0 Return to closest safe point (home or rally point) via direct path. - * @value 1 Return to closest safe point other than home (mission landing pattern or rally point), via direct path. If no mission landing or rally points are defined return home via direct path. Always chose closest safe landing point if vehicle is a VTOL in hover mode. + * @value 1 Return to closest safe point other than home (mission landing pattern or rally point), via direct path. If no mission landing or rally points are defined return home via direct path. Always choose closest safe landing point if vehicle is a VTOL in hover mode. * @value 2 Return to a planned mission landing, if available, using the mission path, else return to home via the reverse mission path. Do not consider rally points. * @value 3 Return via direct path to closest destination: home, start of mission landing pattern or safe point. If the destination is a mission landing pattern, follow the pattern to land. * @value 4 Return to the planned mission landing, or to home via the reverse mission path, whichever is closer by counting waypoints. Do not consider rally points. + * @value 5 Return directly to safe landing point (do not consider mission landing and Home) * @group Return Mode */ PARAM_DEFINE_INT32(RTL_TYPE, 0); diff --git a/src/modules/navigator/takeoff.cpp b/src/modules/navigator/takeoff.cpp index 618108ca4b..eddcfa5cf9 100644 --- a/src/modules/navigator/takeoff.cpp +++ b/src/modules/navigator/takeoff.cpp @@ -203,6 +203,8 @@ Takeoff::set_takeoff_position() } if (!PX4_ISFINITE(_loiter_altitude_msl)) { + _loiter_altitude_msl = takeoff_altitude_amsl; + if (_navigator->get_loiter_min_alt() > FLT_EPSILON) { _loiter_altitude_msl = math::max(_loiter_altitude_msl, takeoff_altitude_amsl + _navigator->get_loiter_min_alt()); diff --git a/src/modules/navigator/vtol_takeoff.cpp b/src/modules/navigator/vtol_takeoff.cpp index 686886a911..b78f5f6e21 100644 --- a/src/modules/navigator/vtol_takeoff.cpp +++ b/src/modules/navigator/vtol_takeoff.cpp @@ -71,8 +71,15 @@ VtolTakeoff::on_active() position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet(); _mission_item.nav_cmd = NAV_CMD_WAYPOINT; - _mission_item.yaw = wrap_pi(get_bearing_to_next_waypoint(_mission_item.lat, - _mission_item.lon, _loiter_location(0), _loiter_location(1))); + + if (!PX4_ISFINITE(_transition_direction_deg)) { + _mission_item.yaw = wrap_pi(get_bearing_to_next_waypoint(_navigator->get_home_position()->lat, + _navigator->get_home_position()->lon, _loiter_location(0), _loiter_location(1))); + + } else { + _mission_item.yaw = wrap_pi(math::radians(_transition_direction_deg)); + } + _mission_item.force_heading = true; mission_item_to_position_setpoint(_mission_item, &pos_sp_triplet->current); pos_sp_triplet->current.cruising_speed = -1.f; diff --git a/src/modules/navigator/vtol_takeoff.h b/src/modules/navigator/vtol_takeoff.h index 3ba32ce7df..162209893d 100644 --- a/src/modules/navigator/vtol_takeoff.h +++ b/src/modules/navigator/vtol_takeoff.h @@ -55,6 +55,7 @@ public: void on_active() override; void setTransitionAltitudeAbsolute(const float alt_amsl) {_transition_alt_amsl = alt_amsl; } + void setTransitionDirection(const float tran_bear) {_transition_direction_deg = tran_bear; } void setLoiterLocation(matrix::Vector2d loiter_location) { _loiter_location = loiter_location; } void setLoiterHeight(const float height_m) { _loiter_height = height_m; } @@ -73,6 +74,7 @@ private: float _takeoff_alt_msl{0.f}; matrix::Vector2d _loiter_location; float _loiter_height{0}; + float _transition_direction_deg{NAN}; DEFINE_PARAMETERS( (ParamFloat) _param_loiter_alt diff --git a/src/modules/rc_update/params.c b/src/modules/rc_update/params.c index d764ae5d34..3709a3a841 100644 --- a/src/modules/rc_update/params.c +++ b/src/modules/rc_update/params.c @@ -87,18 +87,6 @@ PARAM_DEFINE_FLOAT(RC1_MAX, 2000.0f); */ PARAM_DEFINE_FLOAT(RC1_REV, 1.0f); -/** - * RC channel 1 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @unit us - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC1_DZ, 10.0f); - /** * RC channel 2 minimum * @@ -148,18 +136,6 @@ PARAM_DEFINE_FLOAT(RC2_MAX, 2000.0f); */ PARAM_DEFINE_FLOAT(RC2_REV, 1.0f); -/** - * RC channel 2 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @unit us - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC2_DZ, 10.0f); - /** * RC channel 3 minimum * @@ -209,18 +185,6 @@ PARAM_DEFINE_FLOAT(RC3_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC3_REV, 1.0f); -/** - * RC channel 3 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @unit us - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC3_DZ, 10.0f); - /** * RC channel 4 minimum * @@ -270,18 +234,6 @@ PARAM_DEFINE_FLOAT(RC4_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC4_REV, 1.0f); -/** - * RC channel 4 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @unit us - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC4_DZ, 10.0f); - /** * RC channel 5 minimum * @@ -331,17 +283,6 @@ PARAM_DEFINE_FLOAT(RC5_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC5_REV, 1.0f); -/** - * RC channel 5 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC5_DZ, 10.0f); - /** * RC channel 6 minimum * @@ -391,17 +332,6 @@ PARAM_DEFINE_FLOAT(RC6_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC6_REV, 1.0f); -/** - * RC channel 6 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC6_DZ, 10.0f); - /** * RC channel 7 minimum * @@ -451,17 +381,6 @@ PARAM_DEFINE_FLOAT(RC7_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC7_REV, 1.0f); -/** - * RC channel 7 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC7_DZ, 10.0f); - /** * RC channel 8 minimum * @@ -511,17 +430,6 @@ PARAM_DEFINE_FLOAT(RC8_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC8_REV, 1.0f); -/** - * RC channel 8 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC8_DZ, 10.0f); - /** * RC channel 9 minimum * @@ -571,17 +479,6 @@ PARAM_DEFINE_FLOAT(RC9_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC9_REV, 1.0f); -/** - * RC channel 9 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC9_DZ, 0.0f); - /** * RC channel 10 minimum * @@ -631,17 +528,6 @@ PARAM_DEFINE_FLOAT(RC10_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC10_REV, 1.0f); -/** - * RC channel 10 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC10_DZ, 0.0f); - /** * RC channel 11 minimum * @@ -691,17 +577,6 @@ PARAM_DEFINE_FLOAT(RC11_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC11_REV, 1.0f); -/** - * RC channel 11 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC11_DZ, 0.0f); - /** * RC channel 12 minimum * @@ -751,17 +626,6 @@ PARAM_DEFINE_FLOAT(RC12_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC12_REV, 1.0f); -/** - * RC channel 12 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC12_DZ, 0.0f); - /** * RC channel 13 minimum * @@ -811,17 +675,6 @@ PARAM_DEFINE_FLOAT(RC13_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC13_REV, 1.0f); -/** - * RC channel 13 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC13_DZ, 0.0f); - /** * RC channel 14 minimum * @@ -871,17 +724,6 @@ PARAM_DEFINE_FLOAT(RC14_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC14_REV, 1.0f); -/** - * RC channel 14 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC14_DZ, 0.0f); - /** * RC channel 15 minimum * @@ -931,17 +773,6 @@ PARAM_DEFINE_FLOAT(RC15_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC15_REV, 1.0f); -/** - * RC channel 15 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC15_DZ, 0.0f); - /** * RC channel 16 minimum * @@ -991,17 +822,6 @@ PARAM_DEFINE_FLOAT(RC16_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC16_REV, 1.0f); -/** - * RC channel 16 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC16_DZ, 0.0f); - /** * RC channel 17 minimum * @@ -1051,17 +871,6 @@ PARAM_DEFINE_FLOAT(RC17_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC17_REV, 1.0f); -/** - * RC channel 17 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC17_DZ, 0.0f); - /** * RC channel 18 minimum * @@ -1111,17 +920,6 @@ PARAM_DEFINE_FLOAT(RC18_MAX, 2000); */ PARAM_DEFINE_FLOAT(RC18_REV, 1.0f); -/** - * RC channel 18 dead zone - * - * The +- range of this value around the trim value will be considered as zero. - * - * @min 0.0 - * @max 100.0 - * @group Radio Calibration - */ -PARAM_DEFINE_FLOAT(RC18_DZ, 0.0f); - /** * RC channel count * diff --git a/src/modules/rc_update/rc_update.cpp b/src/modules/rc_update/rc_update.cpp index 7c8960a357..52d65bf915 100644 --- a/src/modules/rc_update/rc_update.cpp +++ b/src/modules/rc_update/rc_update.cpp @@ -87,10 +87,6 @@ RCUpdate::RCUpdate() : /* channel reverse */ snprintf(nbuf, sizeof(nbuf), "RC%d_REV", i + 1); _parameter_handles.rev[i] = param_find(nbuf); - - /* channel deadzone */ - snprintf(nbuf, sizeof(nbuf), "RC%d_DZ", i + 1); - _parameter_handles.dz[i] = param_find(nbuf); } // RC to parameter mapping for changing parameters with RC @@ -145,10 +141,6 @@ void RCUpdate::updateParams() float rev = 0.f; param_get(_parameter_handles.rev[i], &rev); _parameters.rev[i] = (rev < 0.f); - - float dz = 0.f; - param_get(_parameter_handles.dz[i], &dz); - _parameters.dz[i] = dz; } for (int i = 0; i < rc_parameter_map_s::RC_PARAM_MAP_NCHAN; i++) { @@ -449,12 +441,9 @@ void RCUpdate::Run() const float min = _parameters.min[i]; const float trim = _parameters.trim[i]; const float max = _parameters.max[i]; - const float dz = _parameters.dz[i]; // piecewise linear function to apply RC calibration - _rc.channels[i] = math::interpolateNXY(value, - {min, trim - dz, trim + dz, max}, - {-1.f, 0.f, 0.f, 1.f}); + _rc.channels[i] = math::interpolateNXY(value, {min, trim, max}, {-1.f, 0.f, 1.f}); if (_parameters.rev[i]) { _rc.channels[i] = -_rc.channels[i]; @@ -725,11 +714,11 @@ int RCUpdate::print_status() PX4_INFO_RAW("Running\n"); if (_channel_count_max > 0) { - PX4_INFO_RAW(" # MIN MAX TRIM DZ REV\n"); + PX4_INFO_RAW(" # MIN MAX TRIM REV\n"); for (int i = 0; i < _channel_count_max; i++) { - PX4_INFO_RAW("%2d %4d %4d %4d %3d %3d\n", i, _parameters.min[i], _parameters.max[i], _parameters.trim[i], - _parameters.dz[i], _parameters.rev[i]); + PX4_INFO_RAW("%2d %4d %4d %4d %3d\n", + i, _parameters.min[i], _parameters.max[i], _parameters.trim[i], _parameters.rev[i]); } } diff --git a/src/modules/rc_update/rc_update.h b/src/modules/rc_update/rc_update.h index 812408debe..2ebdebb4c0 100644 --- a/src/modules/rc_update/rc_update.h +++ b/src/modules/rc_update/rc_update.h @@ -148,7 +148,6 @@ protected: uint16_t min[RC_MAX_CHAN_COUNT]; uint16_t trim[RC_MAX_CHAN_COUNT]; uint16_t max[RC_MAX_CHAN_COUNT]; - uint16_t dz[RC_MAX_CHAN_COUNT]; bool rev[RC_MAX_CHAN_COUNT]; int32_t rc_map_param[rc_parameter_map_s::RC_PARAM_MAP_NCHAN]; @@ -159,7 +158,6 @@ protected: param_t trim[RC_MAX_CHAN_COUNT]; param_t max[RC_MAX_CHAN_COUNT]; param_t rev[RC_MAX_CHAN_COUNT]; - param_t dz[RC_MAX_CHAN_COUNT]; param_t rc_map_param[rc_parameter_map_s::RC_PARAM_MAP_NCHAN]; param_t rc_param[rc_parameter_map_s::RC_PARAM_MAP_NCHAN]; /**< param handles for the parameters which are bound diff --git a/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.cpp b/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.cpp index 3d3a1cb6e6..bacf072cf0 100644 --- a/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.cpp +++ b/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.cpp @@ -76,6 +76,11 @@ void MecanumAttControl::updateAttControl() rover_attitude_setpoint_s rover_attitude_setpoint{}; _rover_attitude_setpoint_sub.copy(&rover_attitude_setpoint); _yaw_setpoint = rover_attitude_setpoint.yaw_setpoint; + _last_yaw_setpoint_timestamp = hrt_absolute_time(); + } + + if (hrt_elapsed_time(&_last_yaw_setpoint_timestamp) > YAW_SETPOINT_TIMEOUT_US) { + _yaw_setpoint = NAN; } if (PX4_ISFINITE(_yaw_setpoint)) { diff --git a/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.hpp b/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.hpp index 327b4652ad..88879380bb 100644 --- a/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.hpp +++ b/src/modules/rover_mecanum/MecanumAttControl/MecanumAttControl.hpp @@ -34,6 +34,7 @@ #pragma once // PX4 includes +#include #include #include @@ -52,6 +53,8 @@ #include #include +using namespace time_literals; + /** * @brief Class for mecanum attitude control. */ @@ -103,6 +106,10 @@ private: float _max_yaw_rate{0.f}; float _yaw_setpoint{NAN}; + hrt_abstime _last_yaw_setpoint_timestamp{0}; + /** Timeout in us for yaw setpoint to get considered invalid */ + static constexpr uint64_t YAW_SETPOINT_TIMEOUT_US = 500_ms; + // Controllers PID _pid_yaw; SlewRateYaw _adjusted_yaw_setpoint; diff --git a/src/modules/rover_mecanum/MecanumDriveModes/MecanumOffboardMode/MecanumOffboardMode.cpp b/src/modules/rover_mecanum/MecanumDriveModes/MecanumOffboardMode/MecanumOffboardMode.cpp index f217ada200..fec1fab36b 100644 --- a/src/modules/rover_mecanum/MecanumDriveModes/MecanumOffboardMode/MecanumOffboardMode.cpp +++ b/src/modules/rover_mecanum/MecanumDriveModes/MecanumOffboardMode/MecanumOffboardMode.cpp @@ -88,7 +88,10 @@ void MecanumOffboardMode::offboardControl() rover_attitude_setpoint.yaw_setpoint = atan2f(velocity_ned(1), velocity_ned(0)); _rover_attitude_setpoint_pub.publish(rover_attitude_setpoint); - } else if (offboard_control_mode.attitude) { + } + + // For Mecanum wheel systems, attitude and position control can be decoupled + if (offboard_control_mode.attitude) { rover_attitude_setpoint_s rover_attitude_setpoint{}; rover_attitude_setpoint.timestamp = hrt_absolute_time(); rover_attitude_setpoint.yaw_setpoint = trajectory_setpoint.yaw; diff --git a/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.cpp b/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.cpp index 3ec9be67d3..969bb28b30 100644 --- a/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.cpp +++ b/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.cpp @@ -47,8 +47,6 @@ MecanumPosControl::MecanumPosControl(ModuleParams *parent) : ModuleParams(parent void MecanumPosControl::updateParams() { ModuleParams::updateParams(); - _max_yaw_rate = _param_ro_yaw_rate_limit.get() * M_DEG_TO_RAD_F; - } void MecanumPosControl::updatePosControl() @@ -89,10 +87,6 @@ void MecanumPosControl::updatePosControl() rover_speed_setpoint.speed_body_x = velocity_in_body_frame(0); rover_speed_setpoint.speed_body_y = velocity_in_body_frame(1); _rover_speed_setpoint_pub.publish(rover_speed_setpoint); - rover_attitude_setpoint_s rover_attitude_setpoint{}; - rover_attitude_setpoint.timestamp = timestamp; - rover_attitude_setpoint.yaw_setpoint = _yaw_setpoint; - _rover_attitude_setpoint_pub.publish(rover_attitude_setpoint); } else { rover_speed_setpoint_s rover_speed_setpoint{}; @@ -100,10 +94,6 @@ void MecanumPosControl::updatePosControl() rover_speed_setpoint.speed_body_x = 0.f; rover_speed_setpoint.speed_body_y = 0.f; _rover_speed_setpoint_pub.publish(rover_speed_setpoint); - rover_attitude_setpoint_s rover_attitude_setpoint{}; - rover_attitude_setpoint.timestamp = timestamp; - rover_attitude_setpoint.yaw_setpoint = _vehicle_yaw; - _rover_attitude_setpoint_pub.publish(rover_attitude_setpoint); if (!_stopped && fabsf(_vehicle_speed) < FLT_EPSILON) { _stopped = true; @@ -124,7 +114,6 @@ void MecanumPosControl::updateSubscriptions() vehicle_attitude_s vehicle_attitude{}; _vehicle_attitude_sub.copy(&vehicle_attitude); _vehicle_attitude_quaternion = matrix::Quatf(vehicle_attitude.q); - _vehicle_yaw = matrix::Eulerf(_vehicle_attitude_quaternion).psi(); } if (_vehicle_local_position_sub.updated()) { diff --git a/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.hpp b/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.hpp index 54880657ec..7e89f6c711 100644 --- a/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.hpp +++ b/src/modules/rover_mecanum/MecanumPosControl/MecanumPosControl.hpp @@ -114,9 +114,6 @@ private: Vector2f _start_ned{}; Vector2f _target_waypoint_ned{}; float _arrival_speed{0.f}; - float _vehicle_yaw{0.f}; - float _max_yaw_rate{0.f}; - float _yaw_setpoint{NAN}; float _vehicle_speed{0.f}; float _cruising_speed{NAN}; bool _stopped{false}; diff --git a/src/modules/sensors/vehicle_gps_position/CMakeLists.txt b/src/modules/sensors/vehicle_gps_position/CMakeLists.txt index 12b625ead6..c82a636118 100644 --- a/src/modules/sensors/vehicle_gps_position/CMakeLists.txt +++ b/src/modules/sensors/vehicle_gps_position/CMakeLists.txt @@ -36,6 +36,8 @@ px4_add_library(vehicle_gps_position VehicleGPSPosition.hpp gps_blending.cpp gps_blending.hpp + PpsTimeSync.cpp + PpsTimeSync.hpp ) target_link_libraries(vehicle_gps_position PRIVATE diff --git a/src/modules/sensors/vehicle_gps_position/PpsTimeSync.cpp b/src/modules/sensors/vehicle_gps_position/PpsTimeSync.cpp new file mode 100644 index 0000000000..44df911b6f --- /dev/null +++ b/src/modules/sensors/vehicle_gps_position/PpsTimeSync.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file PpsTimeSync.cpp + * + * PPS-based time synchronization implementation + */ + +#include "PpsTimeSync.hpp" +#include +#include + +void PpsTimeSync::process_pps(const pps_capture_s &pps) +{ + if (pps.timestamp == 0 || pps.rtc_timestamp == 0) { + return; + } + + _pps_hrt_timestamp = pps.timestamp; + _pps_rtc_timestamp = pps.rtc_timestamp; + _time_offset = (int64_t)pps.rtc_timestamp - (int64_t)pps.timestamp; + _initialized = true; + _updated = true; +} + +uint64_t PpsTimeSync::correct_gps_timestamp(uint64_t gps_fc_timestamp, uint64_t gps_utc_timestamp) +{ + if (!is_valid()) { + return gps_fc_timestamp; + } + + const int64_t corrected_fc_timestamp = (int64_t)gps_utc_timestamp - _time_offset; + + if (_updated) { + const int64_t correction_amount = corrected_fc_timestamp - (int64_t)gps_fc_timestamp; + + if (math::abs_t(correction_amount) > kPpsMaxCorrectionUs) { + PX4_DEBUG("PPS: Correction too large: %" PRId64 " us (%.1f ms), rejecting", + correction_amount, (double)correction_amount / 1000.0); + return gps_fc_timestamp; + } + + // Additional sanity check: corrected timestamp should not be too far in the future (0.1s) + const uint64_t now = hrt_absolute_time(); + + if ((uint64_t)corrected_fc_timestamp > now + 100000) { + return gps_fc_timestamp; + } + + _updated = false; + } + + return (uint64_t)corrected_fc_timestamp; +} + +bool PpsTimeSync::is_valid() const +{ + if (!_initialized) { + return false; + } + + uint64_t now = hrt_absolute_time(); + + if (now < _pps_hrt_timestamp) { + now = UINT64_MAX; + } + + return now - _pps_hrt_timestamp < kPpsStaleTimeoutUs; +} diff --git a/src/modules/ekf2/EKF/aid_sources/range_finder/Sensor.hpp b/src/modules/sensors/vehicle_gps_position/PpsTimeSync.hpp similarity index 65% rename from src/modules/ekf2/EKF/aid_sources/range_finder/Sensor.hpp rename to src/modules/sensors/vehicle_gps_position/PpsTimeSync.hpp index 8134418fab..433d13154b 100644 --- a/src/modules/ekf2/EKF/aid_sources/range_finder/Sensor.hpp +++ b/src/modules/sensors/vehicle_gps_position/PpsTimeSync.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2020-2023 PX4 Development Team. All rights reserved. + * Copyright (c) 2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,53 +32,36 @@ ****************************************************************************/ /** - * @file Sensor.hpp - * Abstract class for sensors - * - * @author Mathieu Bresciani + * @file PpsTimeSync.hpp * + * PPS-based time synchronization for GPS timestamp correction */ -#ifndef EKF_SENSOR_HPP -#define EKF_SENSOR_HPP +#pragma once -#include +#include +#include +#include -namespace estimator -{ -namespace sensor -{ - -class Sensor +class PpsTimeSync { public: - virtual ~Sensor() {}; + PpsTimeSync() = default; + ~PpsTimeSync() = default; - /* - * run sanity checks on the current data - * this has to be called immediately after - * setting new data - */ - virtual void runChecks() {}; + void process_pps(const pps_capture_s &pps); + uint64_t correct_gps_timestamp(uint64_t gps_fc_timestamp, uint64_t gps_utc_timestamp); - /* - * return true if the sensor is healthy - */ - virtual bool isHealthy() const = 0; +private: + bool is_valid() const; - /* - * return true if the delayed sample is healthy - * and can be fused in the estimator - */ - virtual bool isDataHealthy() const = 0; + uint64_t _pps_hrt_timestamp{0}; // FC time when PPS pulse arrived (usec since boot) + uint64_t _pps_rtc_timestamp{0}; // GPS UTC time at PPS pulse (usec since Unix epoch) + int64_t _time_offset{0}; - /* - * return true if the sensor data rate is - * stable and high enough - */ - virtual bool isRegularlySendingData() const = 0; + static constexpr uint64_t kPpsStaleTimeoutUs = 5'000'000; + static constexpr int64_t kPpsMaxCorrectionUs = 300'000; // max delay (max of EKF2_GPS_DELAY) + + bool _initialized{false}; + bool _updated{false}; }; - -} // namespace sensor -} // namespace estimator -#endif // !EKF_SENSOR_HPP diff --git a/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.cpp b/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.cpp index 964b5fdecc..27ff755741 100644 --- a/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.cpp +++ b/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.cpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace sensors { @@ -95,7 +96,12 @@ void VehicleGPSPosition::ParametersUpdate(bool force) _gps_blending.setBlendingUseHPosAccuracy(_param_sens_gps_mask.get() & BLEND_MASK_USE_HPOS_ACC); _gps_blending.setBlendingUseVPosAccuracy(_param_sens_gps_mask.get() & BLEND_MASK_USE_VPOS_ACC); _gps_blending.setBlendingTimeConstant(_param_sens_gps_tau.get()); - _gps_blending.setPrimaryInstance(_param_sens_gps_prime.get()); + + const int gps_prime = _param_sens_gps_prime.get(); + + if (math::isInRange(gps_prime, -1, 1)) { + _gps_blending.setPrimaryInstance(gps_prime); + } } } @@ -104,9 +110,16 @@ void VehicleGPSPosition::Run() perf_begin(_cycle_perf); ParametersUpdate(); + pps_capture_s pps_capture; + + if (_pps_capture_sub.update(&pps_capture)) { + _pps_time_sync.process_pps(pps_capture); + } + // Check all GPS instance bool any_gps_updated = false; bool gps_updated = false; + const int32_t gps_prime = _param_sens_gps_prime.get(); for (uint8_t i = 0; i < GPS_MAX_RECEIVERS; i++) { gps_updated = _sensor_gps_sub[i].updated(); @@ -119,6 +132,16 @@ void VehicleGPSPosition::Run() _sensor_gps_sub[i].copy(&gps_data); _gps_blending.setGpsData(gps_data, i); + if (math::isInRange(static_cast(gps_prime), 2, 127)) { + device::Device::DeviceId device_id{}; + device_id.devid = gps_data.device_id; + + if (device_id.devid_s.bus_type == device::Device::DeviceBusType_UAVCAN + && device_id.devid_s.address == static_cast(gps_prime)) { + _gps_blending.setPrimaryInstance(i); + } + } + if (!_sensor_gps_sub[i].registered()) { _sensor_gps_sub[i].registerCallback(); } @@ -136,6 +159,7 @@ void VehicleGPSPosition::Run() gps_output.device_id = 0; } + gps_output.timestamp_sample = _pps_time_sync.correct_gps_timestamp(gps_output.timestamp, gps_output.time_utc_usec); _vehicle_gps_position_pub.publish(gps_output); } } diff --git a/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.hpp b/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.hpp index 971f24ae4a..c2d60e6db3 100644 --- a/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.hpp +++ b/src/modules/sensors/vehicle_gps_position/VehicleGPSPosition.hpp @@ -45,8 +45,10 @@ #include #include #include +#include #include "gps_blending.hpp" +#include "PpsTimeSync.hpp" using namespace time_literals; @@ -88,9 +90,12 @@ private: {this, ORB_ID(sensor_gps), 1}, }; + uORB::Subscription _pps_capture_sub{ORB_ID(pps_capture)}; + perf_counter_t _cycle_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")}; GpsBlending _gps_blending; + PpsTimeSync _pps_time_sync; DEFINE_PARAMETERS( (ParamInt) _param_sens_gps_mask, diff --git a/src/modules/sensors/vehicle_gps_position/params.c b/src/modules/sensors/vehicle_gps_position/params.c index 651e6e15fa..310c7bfc6b 100644 --- a/src/modules/sensors/vehicle_gps_position/params.c +++ b/src/modules/sensors/vehicle_gps_position/params.c @@ -70,13 +70,16 @@ PARAM_DEFINE_FLOAT(SENS_GPS_TAU, 10.0f); * send data to the EKF even if a secondary instance is already available. * The secondary instance is then only used if the primary one times out. * - * To have an equal priority of all the instances, set this parameter to -1 and - * the best receiver will be used. + * Accepted values: + * -1 : Auto (equal priority for all instances) + * 0 : Main serial GPS instance + * 1 : Secondary serial GPS instance + * 2-127 : UAVCAN module node ID * * This parameter has no effect if blending is active. * * @group Sensors * @min -1 - * @max 1 + * @max 127 */ PARAM_DEFINE_INT32(SENS_GPS_PRIME, 0); diff --git a/src/modules/sensors/vehicle_imu/VehicleIMU.cpp b/src/modules/sensors/vehicle_imu/VehicleIMU.cpp index b8c0a9547e..7ba258a66b 100644 --- a/src/modules/sensors/vehicle_imu/VehicleIMU.cpp +++ b/src/modules/sensors/vehicle_imu/VehicleIMU.cpp @@ -706,8 +706,8 @@ void VehicleIMU::UpdateIntegratorConfiguration() _gyro_integrator.set_reset_interval(roundf((gyro_integral_samples - 0.5f) * gyro_interval_us)); _gyro_integrator.set_reset_samples(gyro_integral_samples); - _backup_schedule_timeout_us = math::constrain((int)math::min(sensor_accel_s::ORB_QUEUE_LENGTH * accel_interval_us, - sensor_gyro_s::ORB_QUEUE_LENGTH * gyro_interval_us) / 2, 1000, 20000); + _backup_schedule_timeout_us = math::constrain((int)math::min((sensor_accel_s::ORB_QUEUE_LENGTH - 1) * accel_interval_us, + (sensor_gyro_s::ORB_QUEUE_LENGTH - 1) * gyro_interval_us), 1000, 20000); // gyro: find largest integer multiple of gyro_integral_samples for (int n = sensor_gyro_s::ORB_QUEUE_LENGTH; n > 0; n--) { @@ -716,6 +716,12 @@ void VehicleIMU::UpdateIntegratorConfiguration() } if (gyro_integral_samples % n == 0) { + // Make sure _backup_schedule_timeout_us is not smaller than normal scheduling interval + + if (_backup_schedule_timeout_us < n * gyro_interval_us) { + _backup_schedule_timeout_us = (n + 1) * gyro_interval_us; + } + _sensor_gyro_sub.set_required_updates(n); _sensor_gyro_sub.registerCallback(); diff --git a/src/modules/simulation/gz_bridge/CMakeLists.txt b/src/modules/simulation/gz_bridge/CMakeLists.txt index d6565d0b1f..c639b4c679 100644 --- a/src/modules/simulation/gz_bridge/CMakeLists.txt +++ b/src/modules/simulation/gz_bridge/CMakeLists.txt @@ -32,15 +32,21 @@ ############################################################################ if(NOT DEFINED ENV{GZ_DISTRO} OR NOT "$ENV{GZ_DISTRO}" STREQUAL "harmonic") - find_package(gz-transport NAMES gz-transport14 gz-transport13) + find_package(gz-transport NAMES gz-transport gz-transport14 gz-transport13) else() find_package(gz-transport NAMES gz-transport13) endif() -file(GLOB gz_worlds ${PX4_SOURCE_DIR}/Tools/simulation/gz/worlds/*.sdf) -file(GLOB gz_airframes ${PX4_SOURCE_DIR}/ROMFS/px4fmu_common/init.d-posix/airframes/*_gz_*) - if (gz-transport_FOUND) + px4_add_git_submodule(TARGET git_gz PATH "${PX4_SOURCE_DIR}/Tools/simulation/gz") + + file(GLOB gz_worlds ${PX4_SOURCE_DIR}/Tools/simulation/gz/worlds/*.sdf) + file(GLOB gz_airframes ${PX4_SOURCE_DIR}/ROMFS/px4fmu_common/init.d-posix/airframes/*_gz_*) + if (gz-transport_VERSION VERSION_LESS "15") + set(GZ_TRANSPORT_TARGET "gz-transport${gz-transport_VERSION_MAJOR}::core") + else() + set(GZ_TRANSPORT_TARGET "gz-transport::core") + endif() px4_add_module( MODULE modules__simulation__gz_bridge MAIN gz_bridge @@ -60,7 +66,7 @@ if (gz-transport_FOUND) DEPENDS mixer_module px4_work_queue - gz-transport${gz-transport_VERSION_MAJOR}::core + ${GZ_TRANSPORT_TARGET} MODULE_CONFIG module.yaml ) @@ -73,7 +79,6 @@ if (gz-transport_FOUND) target_include_directories(modules__simulation__gz_bridge PUBLIC px4_gz_msgs) target_link_libraries(modules__simulation__gz_bridge PUBLIC px4_gz_msgs) - px4_add_git_submodule(TARGET git_gz PATH "${PX4_SOURCE_DIR}/Tools/simulation/gz") include(ExternalProject) ExternalProject_Add(gz SOURCE_DIR ${PX4_SOURCE_DIR}/Tools/simulation/gz diff --git a/src/modules/simulation/gz_bridge/GZGimbal.cpp b/src/modules/simulation/gz_bridge/GZGimbal.cpp index 451f846563..f5bc4881b7 100644 --- a/src/modules/simulation/gz_bridge/GZGimbal.cpp +++ b/src/modules/simulation/gz_bridge/GZGimbal.cpp @@ -38,12 +38,14 @@ bool GZGimbal::init(const std::string &world_name, const std::string &model_name // Mount parameters _mnt_range_roll_handle = param_find("MNT_RANGE_ROLL"); - _mnt_range_pitch_handle = param_find("MNT_RANGE_PITCH"); + _mnt_max_pitch_handle = param_find("MNT_MAX_PITCH"); + _mnt_min_pitch_handle = param_find("MNT_MIN_PITCH"); _mnt_range_yaw_handle = param_find("MNT_RANGE_YAW"); _mnt_mode_out_handle = param_find("MNT_MODE_OUT"); if (_mnt_range_roll_handle == PARAM_INVALID || - _mnt_range_pitch_handle == PARAM_INVALID || + _mnt_max_pitch_handle == PARAM_INVALID || + _mnt_min_pitch_handle == PARAM_INVALID || _mnt_range_yaw_handle == PARAM_INVALID || _mnt_mode_out_handle == PARAM_INVALID) { return false; @@ -76,7 +78,8 @@ void GZGimbal::Run() if (pollSetpoint()) { //TODO handle device flags publishJointCommand(_gimbal_roll_cmd_publisher, _roll_stp, _roll_rate_stp, _last_roll_stp, _roll_min, _roll_max, dt); - publishJointCommand(_gimbal_pitch_cmd_publisher, _pitch_stp, _pitch_rate_stp, _last_pitch_stp, _pitch_min, _pitch_max, + publishJointCommand(_gimbal_pitch_cmd_publisher, _pitch_stp, _pitch_rate_stp, _last_pitch_stp, _mnt_min_pitch, + _mnt_max_pitch, dt); publishJointCommand(_gimbal_yaw_cmd_publisher, _yaw_stp, _yaw_rate_stp, _last_yaw_stp, _yaw_min, _yaw_max, dt); } @@ -100,11 +103,15 @@ void GZGimbal::gimbalIMUCallback(const gz::msgs::IMU &IMU_data) pthread_mutex_lock(&_node_mutex); static const matrix::Quatf q_FLU_to_FRD = matrix::Quatf(0.0f, 1.0f, 0.0f, 0.0f); + static const matrix::Quatf q_ENU_to_NED = matrix::Quatf(0.0f, cosf(M_PI_4_F), cosf(M_PI_4_F), 0.0f); + + // Get the gimbal orientation. Gimbal frame is FLU in Gazebo, reference frame is ENU in Gazebo const matrix::Quatf q_gimbal_FLU = matrix::Quatf(IMU_data.orientation().w(), IMU_data.orientation().x(), IMU_data.orientation().y(), IMU_data.orientation().z()); - _q_gimbal = q_FLU_to_FRD * q_gimbal_FLU * q_FLU_to_FRD.inversed(); + + _q_gimbal = q_ENU_to_NED * q_gimbal_FLU * q_FLU_to_FRD.inversed(); matrix::Vector3f rate = q_FLU_to_FRD.rotateVector(matrix::Vector3f(IMU_data.angular_velocity().x(), IMU_data.angular_velocity().y(), @@ -119,8 +126,10 @@ void GZGimbal::gimbalIMUCallback(const gz::msgs::IMU &IMU_data) void GZGimbal::updateParameters() { + param_get(_mnt_range_roll_handle, &_mnt_range_roll); - param_get(_mnt_range_pitch_handle, &_mnt_range_pitch); + param_get(_mnt_max_pitch_handle, &_mnt_max_pitch); + param_get(_mnt_min_pitch_handle, &_mnt_min_pitch); param_get(_mnt_range_yaw_handle, &_mnt_range_yaw); param_get(_mnt_mode_out_handle, &_mnt_mode_out); } @@ -147,10 +156,12 @@ bool GZGimbal::pollSetpoint() gimbal_controls_s msg; if (_gimbal_controls_sub.copy(&msg)) { - // map control inputs from [-1;1] to [min_angle; max_angle] using the range parameters + // map control inputs from [-1;1] to [min_angle; max_angle] _roll_stp = math::constrain(math::radians(msg.control[msg.INDEX_ROLL] * _mnt_range_roll / 2), _roll_min, _roll_max); - _pitch_stp = math::constrain(math::radians(msg.control[msg.INDEX_PITCH] * _mnt_range_pitch / 2), _pitch_min, - _pitch_max); + _pitch_stp = math::radians(math::constrain(_mnt_min_pitch + 0.5f * (msg.control[msg.INDEX_PITCH] + 1.f) * + (_mnt_max_pitch - _mnt_min_pitch), + _mnt_min_pitch, + _mnt_max_pitch)); _yaw_stp = math::constrain(math::radians(msg.control[msg.INDEX_YAW] * _mnt_range_yaw / 2), _yaw_min, _yaw_max); return true; @@ -192,8 +203,8 @@ void GZGimbal::publishDeviceInfo() device_info.custom_cap_flags = _custom_cap_flags; device_info.roll_min = _roll_min; device_info.roll_max = _roll_max; - device_info.pitch_min = _pitch_min; - device_info.pitch_max = _pitch_max; + device_info.pitch_min = _mnt_min_pitch; + device_info.pitch_max = _mnt_max_pitch; device_info.yaw_min = _yaw_min; device_info.yaw_max = _yaw_max; device_info.gimbal_device_id = _gimbal_device_id; @@ -206,13 +217,11 @@ void GZGimbal::publishDeviceInfo() void GZGimbal::publishDeviceAttitude() { - // TODO handle flags - gimbal_device_attitude_status_s gimbal_att{}; gimbal_att.target_system = 0; // Broadcast gimbal_att.target_component = 0; // Broadcast - gimbal_att.device_flags = 0; + gimbal_att.device_flags = gimbal_device_attitude_status_s::DEVICE_FLAGS_YAW_IN_EARTH_FRAME; _q_gimbal.copyTo(gimbal_att.q); gimbal_att.angular_velocity_x = _gimbal_rate[0]; gimbal_att.angular_velocity_y = _gimbal_rate[1]; @@ -231,7 +240,7 @@ void GZGimbal::publishJointCommand(gz::transport::Node::Publisher &publisher, co float new_stp = computeJointSetpoint(att_stp, rate_stp, last_stp, dt); new_stp = math::constrain(new_stp, min_stp, max_stp); last_stp = new_stp; - msg.set_data(new_stp); + msg.set_data((double)new_stp); publisher.Publish(msg); } diff --git a/src/modules/simulation/gz_bridge/GZGimbal.hpp b/src/modules/simulation/gz_bridge/GZGimbal.hpp index 897c43150f..a2a7965094 100644 --- a/src/modules/simulation/gz_bridge/GZGimbal.hpp +++ b/src/modules/simulation/gz_bridge/GZGimbal.hpp @@ -66,11 +66,13 @@ private: hrt_abstime _last_time_update; // Mount parameters - param_t _mnt_range_pitch_handle = PARAM_INVALID; + param_t _mnt_max_pitch_handle = PARAM_INVALID; + param_t _mnt_min_pitch_handle = PARAM_INVALID; param_t _mnt_range_roll_handle = PARAM_INVALID; param_t _mnt_range_yaw_handle = PARAM_INVALID; param_t _mnt_mode_out_handle = PARAM_INVALID; - float _mnt_range_pitch = 0.0f; + float _mnt_max_pitch = 0.0f; + float _mnt_min_pitch = 0.0f; float _mnt_range_roll = 0.0f; float _mnt_range_yaw = 0.0f; int32_t _mnt_mode_out = 0; @@ -109,8 +111,6 @@ private: // its mechanical limits. So the values below have to match the characteristics of the simulated gimbal const float _roll_min = -0.785398f; const float _roll_max = 0.785398f; - const float _pitch_min = -2.35619f; - const float _pitch_max = 0.785398f; const float _yaw_min = NAN; // infinite yaw const float _yaw_max = NAN; // infinite yaw diff --git a/src/modules/simulation/gz_bridge/GZMixingInterfaceESC.cpp b/src/modules/simulation/gz_bridge/GZMixingInterfaceESC.cpp index f556817ea9..f989434068 100644 --- a/src/modules/simulation/gz_bridge/GZMixingInterfaceESC.cpp +++ b/src/modules/simulation/gz_bridge/GZMixingInterfaceESC.cpp @@ -109,15 +109,20 @@ void GZMixingInterfaceESC::motorSpeedCallback(const gz::msgs::Actuators &actuato pthread_mutex_lock(&_node_mutex); esc_status_s esc_status{}; - esc_status.esc_count = actuators.velocity_size(); + int limited_escs = math::min(actuators.velocity_size(), (int)esc_status_s::CONNECTED_ESC_MAX); + esc_status.esc_count = limited_escs; - for (int i = 0; i < actuators.velocity_size(); i++) { + for (int i = 0; i < limited_escs; i++) { esc_status.esc[i].timestamp = hrt_absolute_time(); esc_status.esc[i].esc_rpm = actuators.velocity(i); esc_status.esc_online_flags |= 1 << i; + // This is a race condition with the failure detector, for smaller models it always resolves before + // the failure detector runs, but for larger models (with more than 8 ESCs) the failure detector + // can run before the velocity of some escs is set > 0. To mitigate this, if one esc has a velocity > 0, + // we assume all escs are armed. if (actuators.velocity(i) > 0) { - esc_status.esc_armed_flags |= 1 << i; + esc_status.esc_armed_flags = (1 << limited_escs) - 1; } } diff --git a/src/modules/simulation/gz_bridge/GZMixingInterfaceServo.cpp b/src/modules/simulation/gz_bridge/GZMixingInterfaceServo.cpp index aaca2a3035..38c1c1dfde 100644 --- a/src/modules/simulation/gz_bridge/GZMixingInterfaceServo.cpp +++ b/src/modules/simulation/gz_bridge/GZMixingInterfaceServo.cpp @@ -33,6 +33,8 @@ #include "GZMixingInterfaceServo.hpp" +#include + float GZMixingInterfaceServo::get_servo_angle_max(const size_t index) @@ -115,8 +117,8 @@ bool GZMixingInterfaceServo::init(const std::string &model_name) return false; } - double min_val = get_servo_angle_min(i); - double max_val = get_servo_angle_max(i); + double min_val = (double)get_servo_angle_min(i); + double max_val = (double)get_servo_angle_max(i); _angle_min_rad.push_back(min_val); _angular_range_rad.push_back(max_val - min_val); } diff --git a/src/modules/simulation/gz_bridge/module.yaml b/src/modules/simulation/gz_bridge/module.yaml index e41aedb1e3..cb860db2da 100644 --- a/src/modules/simulation/gz_bridge/module.yaml +++ b/src/modules/simulation/gz_bridge/module.yaml @@ -1,3 +1,4 @@ +__max_num_motors: &max_num_motors 16 __max_num_servos: &max_num_servos 8 __max_num_tilts: &max_num_tilts 4 @@ -18,7 +19,7 @@ actuator_output: min: { min: 0, max: 1000, default: 0 } max: { min: 0, max: 1000, default: 1000 } failsafe: { min: 0, max: 1000 } - num_channels: *max_num_servos + num_channels: *max_num_motors - param_prefix: SIM_GZ_SV group_label: 'Servos' channel_label: 'Servo' diff --git a/src/modules/simulation/gz_plugins/CMakeLists.txt b/src/modules/simulation/gz_plugins/CMakeLists.txt index 1eb9f59886..16bfa6077c 100644 --- a/src/modules/simulation/gz_plugins/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/CMakeLists.txt @@ -34,10 +34,10 @@ project(px4_gz_plugins) if(NOT DEFINED ENV{GZ_DISTRO} OR NOT "$ENV{GZ_DISTRO}" STREQUAL "harmonic") - find_package(gz-transport NAMES gz-transport14 gz-transport13) - find_package(gz-sim NAMES gz-sim9 gz-sim8) - find_package(gz-sensors NAMES gz-sensors9 gz-sensors8) - find_package(gz-plugin NAMES gz-plugin3 gz-plugin2 COMPONENTS register) + find_package(gz-transport NAMES gz-transport gz-transport14 gz-transport13) + find_package(gz-sim NAMES gz-sim gz-sim9 gz-sim8) + find_package(gz-sensors NAMES gz-sensors gz-sensors9 gz-sensors8) + find_package(gz-plugin NAMES gz-plugin gz-plugin3 gz-plugin2 COMPONENTS register) else() find_package(gz-transport NAMES gz-transport13) find_package(gz-sim NAMES gz-sim8) @@ -46,6 +46,17 @@ else() endif() if (gz-transport_FOUND) + if (gz-transport_VERSION VERSION_LESS "15") + set(GZ_TRANSPORT_TARGET "gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR}") + set(GZ_SIM_TARGET "gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR}") + set(GZ_SENSORS_TARGET "gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR}") + set(GZ_PLUGIN_TARGET "gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR}") + else() + set(GZ_TRANSPORT_TARGET "gz-transport::gz-transport") + set(GZ_SIM_TARGET "gz-sim::gz-sim") + set(GZ_SENSORS_TARGET "gz-sensors::gz-sensors") + set(GZ_PLUGIN_TARGET "gz-plugin::gz-plugin") + endif() # Create a flat output directory for all plugin libraries set(PX4_GZ_PLUGIN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE PATH "Directory for all Gazebo plugin libraries") file(MAKE_DIRECTORY ${PX4_GZ_PLUGIN_OUTPUT_DIR}) @@ -59,11 +70,13 @@ if (gz-transport_FOUND) add_subdirectory(generic_motor) add_subdirectory(buoyancy) add_subdirectory(spacecraft_thruster) + add_subdirectory(motor_failure) + add_subdirectory(airspeed) # Add an alias target for each plugin if (TARGET GstCameraSystem) - add_custom_target(px4_gz_plugins ALL DEPENDS OpticalFlowSystem MovingPlatformController TemplatePlugin GenericMotorModelPlugin BuoyancySystemPlugin GstCameraSystem SpacecraftThrusterModelPlugin) + add_custom_target(px4_gz_plugins ALL DEPENDS OpticalFlowSystem MovingPlatformController TemplatePlugin GenericMotorModelPlugin BuoyancySystemPlugin GstCameraSystem SpacecraftThrusterModelPlugin MotorFailurePlugin AirSpeedPlugin) else() - add_custom_target(px4_gz_plugins ALL DEPENDS OpticalFlowSystem MovingPlatformController TemplatePlugin GenericMotorModelPlugin BuoyancySystemPlugin SpacecraftThrusterModelPlugin) + add_custom_target(px4_gz_plugins ALL DEPENDS OpticalFlowSystem MovingPlatformController TemplatePlugin GenericMotorModelPlugin BuoyancySystemPlugin SpacecraftThrusterModelPlugin MotorFailurePlugin AirSpeedPlugin) endif() endif() diff --git a/src/modules/simulation/gz_plugins/airspeed/AirSpeed.cpp b/src/modules/simulation/gz_plugins/airspeed/AirSpeed.cpp new file mode 100644 index 0000000000..8d0c74dab7 --- /dev/null +++ b/src/modules/simulation/gz_plugins/airspeed/AirSpeed.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "AirSpeed.hpp" + +#include +#include + +using namespace px4; + +// Sign function taken from https://stackoverflow.com/a/4609795/8548472 +template int sign(T val) +{ + return (T(0) < val) - (val < T(0)); +} + +// Register the plugin +GZ_ADD_PLUGIN( + AirSpeed, + gz::sim::System, + AirSpeed::ISystemPreUpdate, + AirSpeed::ISystemConfigure +) + +void AirSpeed::Configure(const gz::sim::Entity &entity, + const std::shared_ptr &sdf, + gz::sim::EntityComponentManager &ecm, + gz::sim::EventManager &eventMgr) +{ + _entity = entity; + _model = gz::sim::Model(entity); + + const std::string link_name = sdf->Get("link_name"); + _link_entity = _model.LinkByName(ecm, link_name); + std::string model_name = _model.Name(ecm); + + if (!_link_entity) { + throw std::runtime_error("Airspeed::Configure: Link \"" + link_name + "\" was not found. " + "Please ensure that your model contains the corresponding link."); + } + + _link = gz::sim::Link(_link_entity); + + // Needed to report linear & angular velocity + _link.EnableVelocityChecks(ecm, true); + + _world_entity = gz::sim::worldEntity(ecm); + _world = gz::sim::World(_world_entity); + std::string world_name = _world.Name(ecm).value_or("default"); + + std::string airspeed_topic = "/world/" + world_name + "/model/" + model_name + + "/link/airspeed_link/sensor/air_speed/air_speed"; + _pub = _node.Advertise(airspeed_topic); + + std::string wind_topic = "/world/" + world_name + "/wind_info"; + + _node.Subscribe(wind_topic, &AirSpeed::windCallback, this); + + ///TODO: Read sdf for altitude home position +} + +void AirSpeed::PreUpdate(const gz::sim::UpdateInfo &_info, + gz::sim::EntityComponentManager &_ecm) +{ + const auto optional_pose = _link.WorldPose(_ecm); + + if (optional_pose.has_value()) { + _vehicle_position = optional_pose.value().Pos(); + _vehicle_attitude = optional_pose.value().Rot(); + + } else { + gzerr << "Unable to get pose" << std::endl; + } + + const auto optional_vel = _link.WorldLinearVelocity(_ecm); + + if (optional_vel.has_value()) { + _vehicle_velocity = optional_vel.value(); + + } else { + gzerr << "Unable to get linear velocity" << std::endl; + } + + // Compute the air density at the local altitude / temperature + const float alt_rel = _vehicle_position.Z(); // Z-component from ENU + const float alt_amsl = (float)_alt_home + alt_rel; + const float temperature_local = TEMPERATURE_MSL - LAPSE_RATE * alt_amsl; + const float density_ratio = powf(TEMPERATURE_MSL / temperature_local, 4.256f); + const float air_density = AIR_DENSITY_MSL / density_ratio; + + // Calculate differential pressure + noise in hPa + const float diff_pressure_noise = standard_normal_distribution_(random_generator_) * diff_pressure_stddev_; + // Body-relateive air velocity + gz::math::Vector3d air_relative_velocity = _vehicle_velocity - _wind_velocity; + gz::math::Vector3d body_velocity = _vehicle_attitude.RotateVectorReverse(air_relative_velocity); + // Calculate differential pressure in hPa + double diff_pressure = sign(body_velocity.X()) * 0.005 * (double)air_density * body_velocity.X() * body_velocity.X() + + (double)diff_pressure_noise; + gz::msgs::AirSpeed airspeed_msg; + airspeed_msg.set_diff_pressure(diff_pressure * 100.0); + _pub.Publish(airspeed_msg); +} + +void AirSpeed::windCallback(const gz::msgs::Wind &msg) +{ + _wind_velocity = gz::math::Vector3d(msg.linear_velocity().x(), msg.linear_velocity().y(), msg.linear_velocity().z()); +} diff --git a/src/modules/simulation/gz_plugins/airspeed/AirSpeed.hpp b/src/modules/simulation/gz_plugins/airspeed/AirSpeed.hpp new file mode 100644 index 0000000000..108ffd47f5 --- /dev/null +++ b/src/modules/simulation/gz_plugins/airspeed/AirSpeed.hpp @@ -0,0 +1,96 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include "gz/sim/components/LinearVelocity.hh" +#include + +#include + +#include + +namespace px4 +{ + +static constexpr float DEFAULT_HOME_ALT_AMSL = 488.0; // altitude AMSL at Irchel Park, Zurich, Switzerland [m] + +// international standard atmosphere (troposphere model - valid up to 11km) see [1] +static constexpr float TEMPERATURE_MSL = 288.15; // temperature at MSL [K] (15 [C]) +static constexpr float PRESSURE_MSL = 101325.0; // pressure at MSL [Pa] +static constexpr float LAPSE_RATE = 0.0065; // reduction in temperature with altitude for troposphere [K/m] +static constexpr float AIR_DENSITY_MSL = 1.225; // air density at MSL [kg/m^3] + +class AirSpeed: + public gz::sim::System, + public gz::sim::ISystemPreUpdate, + public gz::sim::ISystemConfigure +{ +public: + void PreUpdate(const gz::sim::UpdateInfo &_info, + gz::sim::EntityComponentManager &_ecm) final; + + void Configure(const gz::sim::Entity &entity, + const std::shared_ptr &sdf, + gz::sim::EntityComponentManager &ecm, + gz::sim::EventManager &eventMgr) override; + void windCallback(const gz::msgs::Wind &msg); + +private: + gz::sim::Entity _entity; + gz::sim::Model _model{gz::sim::kNullEntity}; + gz::sim::Entity _link_entity; + gz::sim::Link _link; + gz::sim::Entity _world_entity; + gz::sim::World _world; + + gz::transport::Node _node; + gz::transport::Node::Publisher _pub; + + gz::math::Quaterniond _vehicle_attitude; + gz::math::Vector3d _vehicle_velocity{0., 0., 0.}; + gz::math::Vector3d _vehicle_position{0., 0., 0.}; + gz::math::Vector3d _wind_velocity{0., 0., 0.}; + + std::default_random_engine random_generator_; + std::normal_distribution standard_normal_distribution_; + + float diff_pressure_stddev_{0.01f}; // [hPa] + float _alt_home{DEFAULT_HOME_ALT_AMSL}; +}; +} // end namespace px4 diff --git a/src/modules/simulation/gz_plugins/airspeed/CMakeLists.txt b/src/modules/simulation/gz_plugins/airspeed/CMakeLists.txt new file mode 100644 index 0000000000..2afd37c86e --- /dev/null +++ b/src/modules/simulation/gz_plugins/airspeed/CMakeLists.txt @@ -0,0 +1,57 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +project(AirSpeedPlugin) + + +add_library(${PROJECT_NAME} SHARED + AirSpeed.cpp +) + +target_link_libraries(${PROJECT_NAME} + PUBLIC px4_gz_msgs + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${CMAKE_CURRENT_BINARY_DIR} + PUBLIC px4_gz_msgs +) + +if (NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/px4_gz_plugins) +endif() diff --git a/src/modules/simulation/gz_plugins/buoyancy/CMakeLists.txt b/src/modules/simulation/gz_plugins/buoyancy/CMakeLists.txt index a89818eb11..762cd701d8 100644 --- a/src/modules/simulation/gz_plugins/buoyancy/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/buoyancy/CMakeLists.txt @@ -48,10 +48,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} # Add other dependencies as needed # PUBLIC ${OtherLib_LIBS} ) diff --git a/src/modules/simulation/gz_plugins/generic_motor/CMakeLists.txt b/src/modules/simulation/gz_plugins/generic_motor/CMakeLists.txt index 5753d45ca6..db3ac3f3cd 100644 --- a/src/modules/simulation/gz_plugins/generic_motor/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/generic_motor/CMakeLists.txt @@ -48,10 +48,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} # Add other dependencies as needed # PUBLIC ${OtherLib_LIBS} ) diff --git a/src/modules/simulation/gz_plugins/gstreamer/CMakeLists.txt b/src/modules/simulation/gz_plugins/gstreamer/CMakeLists.txt index 09e5b1d23d..4397463b5c 100644 --- a/src/modules/simulation/gz_plugins/gstreamer/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/gstreamer/CMakeLists.txt @@ -47,10 +47,10 @@ else() target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} PUBLIC ${GSTREAMER_LIBRARIES} PUBLIC ${GSTREAMER_APP_LIBRARIES} ) @@ -67,4 +67,8 @@ else() PRIVATE ${GSTREAMER_CFLAGS} PRIVATE ${GSTREAMER_APP_CFLAGS} ) + + if (NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/px4_gz_plugins) + endif() endif() diff --git a/src/modules/simulation/gz_plugins/motor_failure/CMakeLists.txt b/src/modules/simulation/gz_plugins/motor_failure/CMakeLists.txt new file mode 100644 index 0000000000..23ced01515 --- /dev/null +++ b/src/modules/simulation/gz_plugins/motor_failure/CMakeLists.txt @@ -0,0 +1,52 @@ +############################################################################ +# +# Copyright (c) 2025 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +project(MotorFailurePlugin) + +add_library(${PROJECT_NAME} SHARED + MotorFailureSystem.cpp +) + +target_link_libraries(${PROJECT_NAME} + PUBLIC px4_gz_msgs + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${CMAKE_CURRENT_BINARY_DIR} + PUBLIC px4_gz_msgs +) diff --git a/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.cpp b/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.cpp new file mode 100644 index 0000000000..e6dd2955d7 --- /dev/null +++ b/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.cpp @@ -0,0 +1,221 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "MotorFailureSystem.hpp" + +#include +#include +#include +#include +#include + +using namespace gz; +using namespace sim; +using namespace systems; + +////////////////////////////////////////////////// +void MotorFailureSystem::Configure(const Entity &_entity, + const std::shared_ptr &_sdf, + EntityComponentManager &_ecm, + EventManager &/*_eventMgr*/) +{ + this->_model = Model(_entity); + this->_model_entity = _entity; + + if (!this->_model.Valid(_ecm)) { + gzerr << "[MotorFailureSystem] plugin should be attached to a model " + << "entity. Failed to initialize." << std::endl; + return; + } + + // Get model name to use as namespace + std::string model_name = this->_model.Name(_ecm); + + // Get Gazebo Transport topic name for motor failure number subscription + if (_sdf->HasElement("MotorFailureTopic")) { + this->_gz_topic = _sdf->Get("MotorFailureTopic"); + + } else { + // Use Gazebo model-scoped topic naming convention + this->_gz_topic = "/model/" + model_name + "/motor_failure/motor_number"; + } + + // Subscribe to Gazebo Transport topic + if (!this->_node.Subscribe(this->_gz_topic, &MotorFailureSystem::MotorFailureNumberCallback, this)) { + gzerr << "[MotorFailureSystem] Error subscribing to topic [" << this->_gz_topic << "]" << std::endl; + return; + } + + gzmsg << "[MotorFailureSystem] Subscribed to Gazebo Transport topic: " << this->_gz_topic << std::endl; + gzmsg << "[MotorFailureSystem] Initialized for model: " << model_name << std::endl; +} + +////////////////////////////////////////////////// +void MotorFailureSystem::FindMotorJoints(EntityComponentManager &_ecm) +{ + if (this->_joints_found) { + return; + } + + // Find all joints with "rotor_X_joint" pattern + this->_motor_joints.clear(); + + // Get all joints in the model + auto joints = this->_model.Joints(_ecm); + + // Regular expression to match rotor joints (e.g., "rotor_0_joint", "rotor_1_joint") + std::regex motorPattern("rotor_(\\d+)_joint"); + std::smatch match; + + // Find rotor joints and sort by motor number + std::map motorMap; + + for (const auto &joint : joints) { + auto nameComp = _ecm.Component(joint); + + if (nameComp) { + std::string jointName = nameComp->Data(); + + // Try to match the joint name against the pattern + if (std::regex_match(jointName, match, motorPattern)) { + // Extract motor number from the first capture group + try { + int motorNumber = std::stoi(match[1].str()); + motorMap[motorNumber] = joint; + gzdbg << "[MotorFailureSystem] Found motor " << motorNumber + << ": " << jointName << std::endl; + + } catch (const std::exception &e) { + gzwarn << "[MotorFailureSystem] Failed to parse motor number from: " + << jointName << std::endl; + } + } + } + } + + // Convert map to vector for indexed access + for (const auto &pair : motorMap) { + // Ensure vector is large enough + if (pair.first >= static_cast(this->_motor_joints.size())) { + this->_motor_joints.resize(pair.first + 1, kNullEntity); + } + + this->_motor_joints[pair.first] = pair.second; + } + + if (!this->_motor_joints.empty()) { + gzmsg << "[MotorFailureSystem] Found " << this->_motor_joints.size() + << " motor joints" << std::endl; + this->_joints_found = true; + + } else { + gzwarn << "[MotorFailureSystem] No motor joints found in model" << std::endl; + } +} + +////////////////////////////////////////////////// +void MotorFailureSystem::ApplyMotorFailure(EntityComponentManager &_ecm) +{ + int32_t current_failure; + { + std::lock_guard lock(this->_motor_failure_mutex); + current_failure = this->_motor_failure_number; + } + + // Check if failure status changed + if (current_failure != this->_prev_motor_failure_number) { + if (current_failure > 0) { + gzerr << "[MotorFailureSystem] Motor " << current_failure << " failed!" << std::endl; + + } else if (current_failure == 0 && this->_prev_motor_failure_number > 0) { + gzerr << "[MotorFailureSystem] Motor " << this->_prev_motor_failure_number + << " recovered!" << std::endl; + } + + this->_prev_motor_failure_number = current_failure; + } + + // Apply motor failure if active (1-indexed motor number, convert to 0-indexed) + if (current_failure > 0 && current_failure <= static_cast(this->_motor_joints.size())) { + int motorIdx = current_failure - 1; + Entity jointEntity = this->_motor_joints[motorIdx]; + + if (jointEntity != kNullEntity) { + // Force joint velocity command to 0 + // This is done in PreUpdate to override MulticopterMotorModel's commands + auto jointVelCmd = _ecm.Component(jointEntity); + + if (jointVelCmd) { + *jointVelCmd = components::JointVelocityCmd({0.0}); + } + } + } +} + +////////////////////////////////////////////////// +void MotorFailureSystem::PreUpdate(const UpdateInfo &_info, + EntityComponentManager &_ecm) +{ + // Skip if paused + if (_info.paused) { + return; + } + + // Find motor joints on first update + if (!this->_joints_found) { + this->FindMotorJoints(_ecm); + + } else { + this->ApplyMotorFailure(const_cast(_ecm)); + } +} + +////////////////////////////////////////////////// +void MotorFailureSystem::MotorFailureNumberCallback(const gz::msgs::Int32 &_msg) +{ + std::lock_guard lock(this->_motor_failure_mutex); + this->_motor_failure_number = _msg.data(); + gzdbg << "[MotorFailureSystem] Received motor failure number: " + << this->_motor_failure_number << std::endl; +} + +// Register the plugin +GZ_ADD_PLUGIN( + MotorFailureSystem, + gz::sim::System, + MotorFailureSystem::ISystemConfigure, + MotorFailureSystem::ISystemPreUpdate +) + +GZ_ADD_PLUGIN_ALIAS(MotorFailureSystem, + "gz::sim::systems::MotorFailureSystem") diff --git a/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.hpp b/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.hpp new file mode 100644 index 0000000000..1f3c216128 --- /dev/null +++ b/src/modules/simulation/gz_plugins/motor_failure/MotorFailureSystem.hpp @@ -0,0 +1,123 @@ +/**************************************************************************** + * + * Copyright (c) 2025 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef GZ_SIM_SYSTEMS_MOTORFAILURESYSTEM_HPP_ +#define GZ_SIM_SYSTEMS_MOTORFAILURESYSTEM_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include + +// Gazebo Transport includes +#include +#include + +namespace gz +{ +namespace sim +{ +// Inline bracket to help doxygen filtering. +inline namespace GZ_SIM_VERSION_NAMESPACE +{ +namespace systems +{ + +/// \brief This system subscribes to a Gazebo Transport topic to receive motor failure +/// commands and directly controls motor joints to simulate failures. +/// This allows simulating motor failures in multirotor vehicles. +class MotorFailureSystem: + public System, + public ISystemConfigure, + public ISystemPreUpdate +{ +public: + // Documentation inherited + void Configure(const Entity &_entity, + const std::shared_ptr &_sdf, + EntityComponentManager &_ecm, + EventManager &_eventMgr) override; + + // Documentation inherited + void PreUpdate(const gz::sim::UpdateInfo &_info, + gz::sim::EntityComponentManager &_ecm) override; + +private: + /// \brief Callback for Gazebo Transport motor failure number subscription + void MotorFailureNumberCallback(const gz::msgs::Int32 &_msg); + + /// \brief Find all motor joints in the model + void FindMotorJoints(gz::sim::EntityComponentManager &_ecm); + + /// \brief Apply motor failure (set velocity to 0) + void ApplyMotorFailure(gz::sim::EntityComponentManager &_ecm); + + /// \brief Gazebo Transport node for communication + gz::transport::Node _node; + + /// \brief Model entity + gz::sim::Entity _model_entity; + + /// \brief Model interface + gz::sim::Model _model; + + /// \brief Vector of motor joint entities (indexed by motor number) + std::vector _motor_joints; + + /// \brief Current motor failure number (-1 or 0 means no failure, 1-indexed motor number) + int32_t _motor_failure_number{-1}; + + /// \brief Previous motor failure number to detect changes + int32_t _prev_motor_failure_number{-1}; + + /// \brief Gazebo Transport topic name for subscribing to motor failure commands + /// Defaults to /model//motor_failure/motor_number if not specified in SDF + std::string _gz_topic{"/motor_failure/motor_number"}; + + /// \brief Mutex to protect _motor_failure_number + std::mutex _motor_failure_mutex; + + /// \brief Flag to indicate if motor joints have been found + bool _joints_found{false}; +}; + +} // namespace systems +} // namespace GZ_SIM_VERSION_NAMESPACE +} // namespace sim +} // namespace gz + +#endif // GZ_SIM_SYSTEMS_MOTORFAILURESYSTEM_HPP_ diff --git a/src/modules/simulation/gz_plugins/motor_failure/README.md b/src/modules/simulation/gz_plugins/motor_failure/README.md new file mode 100644 index 0000000000..8f1da6ed01 --- /dev/null +++ b/src/modules/simulation/gz_plugins/motor_failure/README.md @@ -0,0 +1,85 @@ +# Motor Failure System Plugin + +This Gazebo plugin enables motor failure simulation for multirotor vehicles in PX4 SITL. + +## Overview + +The Motor Failure System plugin subscribes to a Gazebo Transport topic to receive motor failure commands and directly controls motor joints to simulate failures. This allows simulating motor failures during flight testing. + +## Features + +- Gazebo Transport integration for receiving motor failure commands +- Automatic detection of motor joints (rotor_0_joint, rotor_1_joint, etc.) +- Direct joint velocity override in PreUpdate cycle +- Thread-safe motor failure number handling +- Configurable topic names via SDF + +## Configuration + +### SDF Parameters + +- `` (optional): Gazebo Transport topic for receiving motor failure commands + - Default: `/model//motor_failure/motor_number` + - Follows Gazebo model-scoped topic naming convention + - If specified: Uses the exact topic name provided + +### Example SDF Usage + +**IMPORTANT**: The MotorFailureSystem plugin must be declared **AFTER** the `gz-sim-multicopter-motor-model-system` plugin in your SDF file. This ensures the motor failure override runs after the motor model sets its velocity commands. + +```xml + + + + + + + + + + + + + + /custom/topic/name + +``` + +## Usage + +### Publishing Motor Failure Commands + +To trigger a motor failure, publish a message to the Gazebo Transport topic. + +For a vehicle with namespace `x500_0`: + +```bash +# Fail motor 1 (motors are 1-indexed: 1, 2, 3, 4, ...) +gz topic -t /model/x500_0/motor_failure/motor_number -m gz.msgs.Int32 -p "data: 1" + +# Clear motor failure (restore normal operation) +gz topic -t /model/x500_0/motor_failure/motor_number -m gz.msgs.Int32 -p "data: 0" +``` + +**Note**: Replace `x500_0` with your vehicle's model name. + +**Motor Numbering**: +- Motors are **1-indexed**: 1, 2, 3, 4, etc. +- `data: 0` clears the motor failure +- `data: -1` also clears the motor failure + +### Monitoring Motor Failure Status + +You can monitor the motor failure messages in the Gazebo console output. + + +## Notes + +- The plugin applies motor failure in the PreUpdate cycle by setting joint velocity to 0 +- **Plugin Declaration Order**: This plugin must be declared AFTER the MulticopterMotorModel plugin in the SDF file to ensure proper execution order diff --git a/src/modules/simulation/gz_plugins/moving_platform_controller/CMakeLists.txt b/src/modules/simulation/gz_plugins/moving_platform_controller/CMakeLists.txt index f0ddf3322f..243a92af53 100644 --- a/src/modules/simulation/gz_plugins/moving_platform_controller/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/moving_platform_controller/CMakeLists.txt @@ -39,10 +39,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} ) target_include_directories(${PROJECT_NAME} @@ -50,3 +50,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} PUBLIC px4_gz_msgs ) + +if (NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/px4_gz_plugins) +endif() diff --git a/src/modules/simulation/gz_plugins/moving_platform_controller/MovingPlatformController.cpp b/src/modules/simulation/gz_plugins/moving_platform_controller/MovingPlatformController.cpp index f8f1ab26e2..80568aaf84 100644 --- a/src/modules/simulation/gz_plugins/moving_platform_controller/MovingPlatformController.cpp +++ b/src/modules/simulation/gz_plugins/moving_platform_controller/MovingPlatformController.cpp @@ -240,7 +240,7 @@ void MovingPlatformController::updateWrenchCommand( if (accel_xy > max_accel) { const float scaling = max_accel / accel_xy; - _force += feedback_force * gz::math::Vector3d(scaling, scaling, 1.); + _force += feedback_force * gz::math::Vector3d((double)scaling, (double)scaling, 1.); } else { _force += feedback_force; diff --git a/src/modules/simulation/gz_plugins/optical_flow/CMakeLists.txt b/src/modules/simulation/gz_plugins/optical_flow/CMakeLists.txt index 21c7afc3a3..62d9c7c959 100644 --- a/src/modules/simulation/gz_plugins/optical_flow/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/optical_flow/CMakeLists.txt @@ -46,10 +46,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} PUBLIC ${OpenCV_LIBS} PUBLIC ${OpticalFlow_LIBS} ) @@ -63,3 +63,7 @@ target_include_directories(${PROJECT_NAME} ) add_dependencies(${PROJECT_NAME} OpticalFlow) + +if (NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/px4_gz_plugins) +endif() diff --git a/src/modules/simulation/gz_plugins/optical_flow/OpticalFlowSensor.hpp b/src/modules/simulation/gz_plugins/optical_flow/OpticalFlowSensor.hpp index 497fd79276..e566ec190e 100644 --- a/src/modules/simulation/gz_plugins/optical_flow/OpticalFlowSensor.hpp +++ b/src/modules/simulation/gz_plugins/optical_flow/OpticalFlowSensor.hpp @@ -64,8 +64,8 @@ private: int _integration_time_us; // Camera - double _horizontal_fov {0.0}; - double _vertical_fov {0.0}; + //double _horizontal_fov {0.0}; + //double _vertical_fov {0.0}; cv::Mat _last_image_gray; uint32_t _last_image_timestamp {0}; diff --git a/src/modules/simulation/gz_plugins/optical_flow/optical_flow.cmake b/src/modules/simulation/gz_plugins/optical_flow/optical_flow.cmake index 8ac1c1f649..f7486aa1fc 100644 --- a/src/modules/simulation/gz_plugins/optical_flow/optical_flow.cmake +++ b/src/modules/simulation/gz_plugins/optical_flow/optical_flow.cmake @@ -35,19 +35,20 @@ include(ExternalProject) find_package(OpenCV REQUIRED) if(NOT TARGET OpticalFlow) + set(OPTICAL_FLOW_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/OpticalFlow/install") + ExternalProject_Add(OpticalFlow GIT_REPOSITORY https://github.com/PX4/PX4-OpticalFlow.git GIT_TAG master PREFIX ${CMAKE_BINARY_DIR}/OpticalFlow - INSTALL_DIR ${CMAKE_BINARY_DIR}/OpticalFlow/install - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= - BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/OpticalFlow/install/lib/libOpticalFlow.so + INSTALL_DIR ${OPTICAL_FLOW_INSTALL_PREFIX} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${OPTICAL_FLOW_INSTALL_PREFIX} + BUILD_BYPRODUCTS ${OPTICAL_FLOW_INSTALL_PREFIX}/lib/libOpticalFlow.so UPDATE_DISCONNECTED ON BUILD_ALWAYS OFF STEP_TARGETS build ) - ExternalProject_Get_Property(OpticalFlow install_dir) - set(OpticalFlow_INCLUDE_DIRS ${install_dir}/include CACHE INTERNAL "") - set(OpticalFlow_LIBS ${install_dir}/lib/libOpticalFlow.so CACHE INTERNAL "") + set(OpticalFlow_INCLUDE_DIRS ${OPTICAL_FLOW_INSTALL_PREFIX}/include CACHE INTERNAL "") + set(OpticalFlow_LIBS ${OPTICAL_FLOW_INSTALL_PREFIX}/lib/libOpticalFlow.so CACHE INTERNAL "") endif() diff --git a/src/modules/simulation/gz_plugins/spacecraft_thruster/CMakeLists.txt b/src/modules/simulation/gz_plugins/spacecraft_thruster/CMakeLists.txt index 5f196526dd..1955c497dd 100644 --- a/src/modules/simulation/gz_plugins/spacecraft_thruster/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/spacecraft_thruster/CMakeLists.txt @@ -48,10 +48,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} # Add other dependencies as needed # PUBLIC ${OtherLib_LIBS} ) diff --git a/src/modules/simulation/gz_plugins/template_plugin/CMakeLists.txt b/src/modules/simulation/gz_plugins/template_plugin/CMakeLists.txt index c7e582fd9f..f948736523 100644 --- a/src/modules/simulation/gz_plugins/template_plugin/CMakeLists.txt +++ b/src/modules/simulation/gz_plugins/template_plugin/CMakeLists.txt @@ -48,10 +48,10 @@ add_library(${PROJECT_NAME} SHARED target_link_libraries(${PROJECT_NAME} PUBLIC px4_gz_msgs - PUBLIC gz-sensors${gz-sensors_VERSION_MAJOR}::gz-sensors${gz-sensors_VERSION_MAJOR} - PUBLIC gz-plugin${gz-plugin_VERSION_MAJOR}::gz-plugin${gz-plugin_VERSION_MAJOR} - PUBLIC gz-sim${gz-sim_VERSION_MAJOR}::gz-sim${gz-sim_VERSION_MAJOR} - PUBLIC gz-transport${gz-transport_VERSION_MAJOR}::gz-transport${gz-transport_VERSION_MAJOR} + PUBLIC ${GZ_SENSORS_TARGET} + PUBLIC ${GZ_PLUGIN_TARGET} + PUBLIC ${GZ_SIM_TARGET} + PUBLIC ${GZ_TRANSPORT_TARGET} # Add other dependencies as needed # PUBLIC ${OtherLib_LIBS} ) @@ -66,3 +66,7 @@ target_include_directories(${PROJECT_NAME} # Add dependencies if needed # add_dependencies(${PROJECT_NAME} ExternalDependency) + +if (NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/px4_gz_plugins) +endif() diff --git a/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.cpp b/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.cpp index 7b0d9556ca..5566efbb1c 100644 --- a/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.cpp +++ b/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.cpp @@ -144,7 +144,7 @@ void SensorAirspeedSim::Run() // report.timestamp_sample = time; differential_pressure.device_id = 1377548; // 1377548: DRV_DIFF_PRESS_DEVTYPE_SIM, BUS: 1, ADDR: 5, TYPE: SIMULATION differential_pressure.differential_pressure_pa = (double)diff_pressure * 100.0; // hPa to Pa; - differential_pressure.temperature = temperature_local; + differential_pressure.temperature = temperature_local + ABSOLUTE_ZERO_C; // K to C differential_pressure.timestamp = hrt_absolute_time(); _differential_pressure_pub.publish(differential_pressure); diff --git a/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.hpp b/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.hpp index 64305dccca..3aafc9ca93 100644 --- a/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.hpp +++ b/src/modules/simulation/sensor_airspeed_sim/SensorAirspeedSim.hpp @@ -49,6 +49,7 @@ using namespace time_literals; +static constexpr float ABSOLUTE_ZERO_C = -273.15; // absolute 0 temperature [C] static constexpr float TEMPERATURE_MSL = 288.15; // temperature at MSL [K] (15 [C]) static constexpr float PRESSURE_MSL = 101325.0; // pressure at MSL [Pa] static constexpr float LAPSE_RATE = 0.0065; // reduction in temperature with altitude for troposphere [K/m] diff --git a/src/modules/simulation/sensor_baro_sim/SensorBaroSim.cpp b/src/modules/simulation/sensor_baro_sim/SensorBaroSim.cpp index fc70998e9a..e7dd2bd991 100644 --- a/src/modules/simulation/sensor_baro_sim/SensorBaroSim.cpp +++ b/src/modules/simulation/sensor_baro_sim/SensorBaroSim.cpp @@ -155,7 +155,7 @@ void SensorBaroSim::Run() _baro_drift_pa += _baro_drift_pa_per_sec * dt; const float absolute_pressure_noisy = absolute_pressure + abs_pressure_noise + _baro_drift_pa; - // convert to hPa + // Apply pressure offset float pressure = absolute_pressure_noisy + _sim_baro_off_p.get(); // calculate temperature in Celsius diff --git a/src/modules/simulation/simulator_mavlink/sitl_targets_gazebo-classic.cmake b/src/modules/simulation/simulator_mavlink/sitl_targets_gazebo-classic.cmake index 649f0f99c8..693c0fa6e5 100644 --- a/src/modules/simulation/simulator_mavlink/sitl_targets_gazebo-classic.cmake +++ b/src/modules/simulation/simulator_mavlink/sitl_targets_gazebo-classic.cmake @@ -44,12 +44,20 @@ if(gazebo_FOUND) # project to build sitl_gazebo if necessary px4_add_git_submodule(TARGET git_sitl_gazebo-classic PATH "${PX4_SOURCE_DIR}/Tools/simulation/gazebo-classic/sitl_gazebo-classic") include(ExternalProject) + + # Set MAVLINK_DEVELOPMENT if using development dialect + set(GAZEBO_MAVLINK_ARGS) + if(CONFIG_MAVLINK_DIALECT STREQUAL "development") + list(APPEND GAZEBO_MAVLINK_ARGS -DMAVLINK_DEVELOPMENT=1) + endif() + ExternalProject_Add(sitl_gazebo-classic SOURCE_DIR ${PX4_SOURCE_DIR}/Tools/simulation/gazebo-classic/sitl_gazebo-classic CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DSEND_ODOMETRY_DATA=ON -DGENERATE_ROS_MODELS=ON + ${GAZEBO_MAVLINK_ARGS} BINARY_DIR ${PX4_BINARY_DIR}/build_gazebo-classic INSTALL_COMMAND "" DEPENDS git_sitl_gazebo-classic diff --git a/src/modules/simulation/simulator_sih/sih.cpp b/src/modules/simulation/simulator_sih/sih.cpp index d6227ed4fa..389c7481f9 100644 --- a/src/modules/simulation/simulator_sih/sih.cpp +++ b/src/modules/simulation/simulator_sih/sih.cpp @@ -79,8 +79,6 @@ void Sih::run() static_cast(VehicleType::First), static_cast(VehicleType::Last))); - _actuator_out_sub = uORB::Subscription{ORB_ID(actuator_outputs_sim)}; - #if defined(ENABLE_LOCKSTEP_SCHEDULER) lockstep_loop(); #else diff --git a/src/modules/simulation/simulator_sih/sih.hpp b/src/modules/simulation/simulator_sih/sih.hpp index bda4484884..38bcaf19e1 100644 --- a/src/modules/simulation/simulator_sih/sih.hpp +++ b/src/modules/simulation/simulator_sih/sih.hpp @@ -131,7 +131,7 @@ private: uORB::Publication _global_position_ground_truth_pub{ORB_ID(vehicle_global_position_groundtruth)}; uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; - uORB::Subscription _actuator_out_sub{ORB_ID(actuator_outputs)}; + uORB::Subscription _actuator_out_sub{ORB_ID(actuator_outputs_sim)}; // hard constants static constexpr uint16_t NUM_ACTUATORS_MAX = 9; diff --git a/src/modules/temperature_compensation/TemperatureCompensationModule.cpp b/src/modules/temperature_compensation/TemperatureCompensationModule.cpp index ec19359181..deb69fd6e4 100644 --- a/src/modules/temperature_compensation/TemperatureCompensationModule.cpp +++ b/src/modules/temperature_compensation/TemperatureCompensationModule.cpp @@ -306,7 +306,7 @@ void TemperatureCompensationModule::Run() } if (got_temperature_calibration_command) { - int ret = run_temperature_calibration(accel, baro, gyro, mag); + int ret = run_temperature_calibration(accel, gyro, mag, baro); // publish ACK vehicle_command_ack_s command_ack{}; diff --git a/src/modules/temperature_compensation/temperature_calibration/baro.cpp b/src/modules/temperature_compensation/temperature_calibration/baro.cpp index 7cee4739df..1bc0a2f98b 100644 --- a/src/modules/temperature_compensation/temperature_calibration/baro.cpp +++ b/src/modules/temperature_compensation/temperature_calibration/baro.cpp @@ -96,7 +96,7 @@ int TemperatureCalibrationBaro::update_sensor_instance(PerSensorData &data, int data.device_id = baro_data.device_id; - data.sensor_sample_filt[0] = 100.0f * baro_data.pressure; // convert from hPA to Pa + data.sensor_sample_filt[0] = baro_data.pressure; data.sensor_sample_filt[1] = baro_data.temperature; diff --git a/src/modules/uuv_att_control/uuv_att_control.cpp b/src/modules/uuv_att_control/uuv_att_control.cpp index c7186fc487..1a20eb13dc 100644 --- a/src/modules/uuv_att_control/uuv_att_control.cpp +++ b/src/modules/uuv_att_control/uuv_att_control.cpp @@ -237,15 +237,22 @@ void UUVAttitudeControl::control_attitude_geo(const vehicle_attitude_s &attitude void UUVAttitudeControl::generate_attitude_setpoint(float dt) { + const bool js_heave_sway_mode = joystick_heave_sway_mode(); + // Avoid accumulating absolute yaw error with arming stick gesture float roll = Eulerf(matrix::Quatf(_attitude_setpoint.q_d)).phi(); float pitch = Eulerf(matrix::Quatf(_attitude_setpoint.q_d)).theta(); float yaw = Eulerf(matrix::Quatf(_attitude_setpoint.q_d)).psi(); - // Integrate manual control inputs + float roll_setpoint = 0.0f; + float pitch_setpoint = 0.0f; float yaw_setpoint = yaw + _manual_control_setpoint.yaw * dt * _param_sgm_yaw.get(); - float roll_setpoint = roll + _manual_control_setpoint.roll * dt * _param_sgm_roll.get(); - float pitch_setpoint = pitch + -_manual_control_setpoint.pitch * dt * _param_sgm_pitch.get(); + + if (!js_heave_sway_mode) { + // Integrate roll/pitch from sticks + roll_setpoint = roll + _manual_control_setpoint.roll * dt * _param_sgm_roll.get(); + pitch_setpoint = pitch + -_manual_control_setpoint.pitch * dt * _param_sgm_pitch.get(); + } // Generate target quaternion Eulerf euler_sp(roll_setpoint, pitch_setpoint, yaw_setpoint); @@ -256,21 +263,52 @@ void UUVAttitudeControl::generate_attitude_setpoint(float dt) q_sp.copyTo(_attitude_setpoint.q_d); - _attitude_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * _param_sgm_thrtl.get(); + // Thrust mapping + const float throttle_manual_attitude_gain = _param_sgm_thrtl.get(); + + if (js_heave_sway_mode) { + // XYZ thrust + _attitude_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * throttle_manual_attitude_gain; // surge +x + _attitude_setpoint.thrust_body[1] = _manual_control_setpoint.roll * throttle_manual_attitude_gain; // sway +y + _attitude_setpoint.thrust_body[2] = -_manual_control_setpoint.pitch * throttle_manual_attitude_gain; // heave +z down + + } else { + // Throttle only on +x (surge) + _attitude_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * throttle_manual_attitude_gain; + _attitude_setpoint.thrust_body[1] = 0.f; + _attitude_setpoint.thrust_body[2] = 0.f; + } _attitude_setpoint.timestamp = hrt_absolute_time(); } void UUVAttitudeControl::generate_rates_setpoint(float dt) { - // Integrate manual control inputs - _rates_setpoint.roll = _manual_control_setpoint.roll * dt * _param_rgm_roll.get(); - _rates_setpoint.pitch = -_manual_control_setpoint.pitch * dt * _param_rgm_pitch.get(); - _rates_setpoint.yaw = _manual_control_setpoint.yaw * dt * _param_rgm_yaw.get(); + const bool js_heave_sway_mode = joystick_heave_sway_mode(); + const float throttle_manual_rate_gain = _param_rgm_thrtl.get(); + + if (js_heave_sway_mode) { + // Hold pitch/roll level. Only yaw is a rate command. XYZ thrust + _rates_setpoint.roll = 0.0f; + _rates_setpoint.pitch = 0.0f; + _rates_setpoint.yaw = _manual_control_setpoint.yaw * dt * _param_rgm_yaw.get(); + + _rates_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * throttle_manual_rate_gain; // surge +x + _rates_setpoint.thrust_body[1] = _manual_control_setpoint.roll * throttle_manual_rate_gain; // sway +y + _rates_setpoint.thrust_body[2] = -_manual_control_setpoint.pitch * throttle_manual_rate_gain; // heave +z down + + } else { + // Roll/pitch/yaw are rate commands; thrust only surge + _rates_setpoint.roll = _manual_control_setpoint.roll * dt * _param_rgm_roll.get(); + _rates_setpoint.pitch = -_manual_control_setpoint.pitch * dt * _param_rgm_pitch.get(); + _rates_setpoint.yaw = _manual_control_setpoint.yaw * dt * _param_rgm_yaw.get(); + + _rates_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * throttle_manual_rate_gain; + _rates_setpoint.thrust_body[1] = 0.f; + _rates_setpoint.thrust_body[2] = 0.f; + } - _rates_setpoint.thrust_body[0] = _manual_control_setpoint.throttle * _param_rgm_thrtl.get(); _rates_setpoint.timestamp = hrt_absolute_time(); - } void UUVAttitudeControl::check_setpoint_validity(vehicle_attitude_s &v_att) @@ -352,13 +390,33 @@ void UUVAttitudeControl::Run() } else if (!_vcontrol_mode.flag_control_attitude_enabled && !_vcontrol_mode.flag_control_rates_enabled) { + /* Manual Control mode (e.g. gamepad,...) - raw feedthrough no assistance */ - constrain_actuator_commands(_manual_control_setpoint.roll * _param_mgm_roll.get(), - -_manual_control_setpoint.pitch * _param_mgm_pitch.get(), - _manual_control_setpoint.yaw * _param_mgm_yaw.get(), - _manual_control_setpoint.throttle * _param_mgm_thrtl.get(), - 0.f, - 0.f); + const bool js_heave_sway_mode = joystick_heave_sway_mode(); + + if (js_heave_sway_mode) { + // Keep roll/pitch level, yaw torque, full XYZ thrust + const float throttle_manual_gain = _param_mgm_thrtl.get(); + + const float roll_u = 0.0f; + const float pitch_u = 0.0f; + const float yaw_u = _manual_control_setpoint.yaw * _param_mgm_yaw.get(); + + const float thrust_x = _manual_control_setpoint.throttle * throttle_manual_gain; // surge + const float thrust_y = _manual_control_setpoint.roll * throttle_manual_gain; // sway + const float thrust_z = -_manual_control_setpoint.pitch * throttle_manual_gain; // heave + + constrain_actuator_commands(roll_u, pitch_u, yaw_u, thrust_x, thrust_y, thrust_z); + + } else { + // Pitch/roll/yaw torques from sticks, thrust only surge + constrain_actuator_commands(_manual_control_setpoint.roll * _param_mgm_roll.get(), + -_manual_control_setpoint.pitch * _param_mgm_pitch.get(), + _manual_control_setpoint.yaw * _param_mgm_yaw.get(), + _manual_control_setpoint.throttle * _param_mgm_thrtl.get(), + 0.f, + 0.f); + } } } else { diff --git a/src/modules/uuv_att_control/uuv_att_control.hpp b/src/modules/uuv_att_control/uuv_att_control.hpp index 76588848a3..390d64dbb8 100644 --- a/src/modules/uuv_att_control/uuv_att_control.hpp +++ b/src/modules/uuv_att_control/uuv_att_control.hpp @@ -149,7 +149,8 @@ private: (ParamFloat) _param_mgm_thrtl, (ParamFloat) _param_torque_sat, (ParamFloat) _param_thrust_sat, - (ParamFloat) _param_setpoint_max_age + (ParamFloat) _param_setpoint_max_age, + (ParamInt) _param_stick_mode ) @@ -171,4 +172,6 @@ private: void generate_rates_setpoint(float dt); void reset_attitude_setpoint(vehicle_attitude_s &v_att); void check_setpoint_validity(vehicle_attitude_s &v_att); + + inline bool joystick_heave_sway_mode() const { return _param_stick_mode.get() == 0; } }; diff --git a/src/modules/uuv_att_control/uuv_att_control_params.c b/src/modules/uuv_att_control/uuv_att_control_params.c index 08dea0ef41..2a62edbcdc 100644 --- a/src/modules/uuv_att_control/uuv_att_control_params.c +++ b/src/modules/uuv_att_control/uuv_att_control_params.c @@ -239,3 +239,12 @@ PARAM_DEFINE_FLOAT(UUV_THRUST_SAT, 0.1f); * @group UUV Attitude Control */ PARAM_DEFINE_FLOAT(UUV_SP_MAX_AGE, 2.0f); + +/** + * Stick mode selector (0=Heave/sway control, roll/pitch leveled; 1=Pitch/roll control) + * + * @group UUV Attitude Control + * @min 0 + * @max 1 + */ +PARAM_DEFINE_INT32(UUV_STICK_MODE, 0); diff --git a/src/modules/uxrce_dds_client/CMakeLists.txt b/src/modules/uxrce_dds_client/CMakeLists.txt index e5fc481543..fba4ca45cf 100644 --- a/src/modules/uxrce_dds_client/CMakeLists.txt +++ b/src/modules/uxrce_dds_client/CMakeLists.txt @@ -63,7 +63,6 @@ else() endif() include(ExternalProject) - ExternalProject_Add( libmicroxrceddsclient_project PREFIX ${microxrceddsclient_build_dir} @@ -139,7 +138,6 @@ else() # -DDEBUG_BUILD ${MAX_CUSTOM_OPT_LEVEL} SRCS - ${CMAKE_CURRENT_BINARY_DIR}/dds_topics.h uxrce_dds_client.cpp uxrce_dds_client.h vehicle_command_srv.cpp diff --git a/src/modules/uxrce_dds_client/dds_topics.h.em b/src/modules/uxrce_dds_client/dds_topics.h.em index 7ff7605ccd..30ba6053ea 100644 --- a/src/modules/uxrce_dds_client/dds_topics.h.em +++ b/src/modules/uxrce_dds_client/dds_topics.h.em @@ -67,6 +67,7 @@ struct SendSubscription { uint32_t topic_size; UcdrSerializeMethod ucdr_serialize_method; uint64_t publish_interval_ms; + uint8_t orb_instance; }; // Subscribers for messages to send @@ -81,6 +82,7 @@ struct SendTopicsSubs { ucdr_topic_size_@(pub['simple_base_type'])(), &ucdr_serialize_@(pub['simple_base_type']), static_cast((@(pub.get('rate_limit', 0)) > 0) ? (1e3 / @(pub.get('rate_limit', 1e3))) : UXRCE_DEFAULT_POLL_INTERVAL_MS), + @(pub['instance']) }, @[ end for]@ }; @@ -98,13 +100,13 @@ bool SendTopicsSubs::init(uxrSession *session, uxrStreamId reliable_out_stream_i bool ret = true; for (unsigned idx = 0; idx < sizeof(send_subscriptions)/sizeof(send_subscriptions[0]); ++idx) { if (fds[idx].events == 0) { - fds[idx].fd = orb_subscribe(send_subscriptions[idx].orb_meta); + fds[idx].fd = orb_subscribe_multi(send_subscriptions[idx].orb_meta, send_subscriptions[idx].orb_instance); fds[idx].events = POLLIN; orb_set_interval(fds[idx].fd, send_subscriptions[idx].publish_interval_ms); } if (!create_data_writer(session, reliable_out_stream_id, participant_id, static_cast(send_subscriptions[idx].orb_meta->o_id), client_namespace, send_subscriptions[idx].topic, - send_subscriptions[idx].message_version, + send_subscriptions[idx].message_version, send_subscriptions[idx].orb_instance, send_subscriptions[idx].dds_type_name, send_subscriptions[idx].data_writer)) { ret = false; } diff --git a/src/modules/uxrce_dds_client/dds_topics.yaml b/src/modules/uxrce_dds_client/dds_topics.yaml index e315a7f1d5..dc6cc1f2cf 100644 --- a/src/modules/uxrce_dds_client/dds_topics.yaml +++ b/src/modules/uxrce_dds_client/dds_topics.yaml @@ -50,6 +50,9 @@ publications: type: px4_msgs::msg::TimesyncStatus rate_limit: 10. + - topic: /fmu/out/transponder_report + type: px4_msgs::msg::TransponderReport + # - topic: /fmu/out/vehicle_angular_velocity # type: px4_msgs::msg::VehicleAngularVelocity @@ -59,6 +62,7 @@ publications: - topic: /fmu/out/vehicle_attitude type: px4_msgs::msg::VehicleAttitude + rate_limit: 50. - topic: /fmu/out/vehicle_control_mode type: px4_msgs::msg::VehicleControlMode @@ -81,6 +85,7 @@ publications: - topic: /fmu/out/vehicle_odometry type: px4_msgs::msg::VehicleOdometry + rate_limit: 100. - topic: /fmu/out/vehicle_status type: px4_msgs::msg::VehicleStatus @@ -101,6 +106,10 @@ publications: type: px4_msgs::msg::Wind rate_limit: 1. + - topic: /fmu/out/gimbal_device_attitude_status + type: px4_msgs::msg::GimbalDeviceAttitudeStatus + rate_limit: 20. + # Create uORB::Publication subscriptions: - topic: /fmu/in/register_ext_component_request diff --git a/src/modules/uxrce_dds_client/generate_dds_topics.py b/src/modules/uxrce_dds_client/generate_dds_topics.py index 3698c71e9e..957ff4b578 100644 --- a/src/modules/uxrce_dds_client/generate_dds_topics.py +++ b/src/modules/uxrce_dds_client/generate_dds_topics.py @@ -102,12 +102,24 @@ def process_message_type(msg_type): # topic_simple: eg vehicle_status msg_type['topic_simple'] = msg_type['topic'].split('/')[-1] +def process_message_instance(msg_type): + if 'instance' in msg_type: + # if instance is given, check if it is a non negative integer + if not (type(msg_type['instance']) is int and msg_type['instance'] >= 0) : + raise TypeError("`instance` must be a non negative integer") + # add trailing instance to topic name + msg_type['topic'] = f"{msg_type['topic']}{msg_type['instance']}" + else: + # if instance is not given, + msg_type['instance'] = 0 + merged_em_globals['namespace'] = namespace pubs_not_empty = msg_map['publications'] is not None if pubs_not_empty: for p in msg_map['publications']: process_message_type(p) + process_message_instance(p) merged_em_globals['publications'] = msg_map['publications'] if pubs_not_empty else [] diff --git a/src/modules/uxrce_dds_client/module.yaml b/src/modules/uxrce_dds_client/module.yaml index 773475f1f5..5988a5a92c 100644 --- a/src/modules/uxrce_dds_client/module.yaml +++ b/src/modules/uxrce_dds_client/module.yaml @@ -129,3 +129,27 @@ parameters: reboot_required: true default: -1 unit: s + + UXRCE_DDS_NS_IDX: + description: + short: Define an index-based message namespace + long: | + Defines an index-based namespace for DDS messages, e.g, uav_0, uav_1, up to uav_9999 + A value less than zero leaves the namespace empty + type: int32 + min: -1 + max: 9999 + category: System + reboot_required: true + default: -1 + + UXRCE_DDS_FLCTRL: + description: + short: Enable serial flow control for UXRCE interface + long: | + This is used to enable flow control for the serial uXRCE instance. + Used for reliable high bandwidth communication. + type: boolean + category: System + reboot_required: true + default: 0 diff --git a/src/modules/uxrce_dds_client/utilities.hpp b/src/modules/uxrce_dds_client/utilities.hpp index c2d038b3ed..346dc28455 100644 --- a/src/modules/uxrce_dds_client/utilities.hpp +++ b/src/modules/uxrce_dds_client/utilities.hpp @@ -50,7 +50,7 @@ static bool generate_topic_name(char *topic_name, const char *client_namespace, } static bool create_data_writer(uxrSession *session, uxrStreamId reliable_out_stream_id, uxrObjectId participant_id, - ORB_ID orb_id, const char *client_namespace, const char *topic, uint32_t message_version, const char *type_name, + ORB_ID orb_id, const char *client_namespace, const char *topic, uint32_t message_version, uint8_t instance, const char *type_name, uxrObjectId &datawriter_id) { // topic @@ -61,7 +61,7 @@ static bool create_data_writer(uxrSession *session, uxrStreamId reliable_out_str return false; } - uxrObjectId topic_id = topic_id_from_orb(orb_id); + uxrObjectId topic_id = topic_id_from_orb(orb_id, instance); uint16_t topic_req = uxr_buffer_create_topic_bin(session, reliable_out_stream_id, topic_id, participant_id, topic_name, type_name, UXR_REPLACE); diff --git a/src/modules/uxrce_dds_client/uxrce_dds_client.cpp b/src/modules/uxrce_dds_client/uxrce_dds_client.cpp index d8beb4f609..5eff22af36 100644 --- a/src/modules/uxrce_dds_client/uxrce_dds_client.cpp +++ b/src/modules/uxrce_dds_client/uxrce_dds_client.cpp @@ -49,6 +49,7 @@ #include #include +static constexpr char NAMESPACE_PREFIX[] = "uav_"; #define PARTICIPANT_XML_SIZE 512 static constexpr uint8_t TIMESYNC_MAX_TIMEOUTS = 10; @@ -836,8 +837,16 @@ bool UxrceddsClient::setBaudrate(int fd, unsigned baud) // uart_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); - /* no parity, one stop bit, disable flow control */ - uart_config.c_cflag &= ~(CSTOPB | PARENB | CRTSCTS); + /* no parity, one stop bit */ + uart_config.c_cflag &= ~(CSTOPB | PARENB); + + /* enable flow control if needed */ + if (_param_uxrce_dds_flctrl.get() > 0) { + uart_config.c_cflag |= CRTSCTS; + + } else { + uart_config.c_cflag &= ~CRTSCTS; + } /* set baud rate */ if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) { @@ -1028,6 +1037,23 @@ UxrceddsClient *UxrceddsClient::instantiate(int argc, char *argv[]) } } + if (client_namespace == nullptr) { + int32_t ns_idx = -1; + param_get(param_find("UXRCE_DDS_NS_IDX"), &ns_idx); + + if (ns_idx > -1) { + if (ns_idx < 10000) { + // Allocate buffer for prefix + '\0' + 4 digits + static char client_namespace_buf[sizeof(NAMESPACE_PREFIX) + 4]; + snprintf(client_namespace_buf, sizeof client_namespace_buf, "%s%u", NAMESPACE_PREFIX, (uint16_t)ns_idx); + client_namespace = client_namespace_buf; + + } else { + PX4_WARN("namespace index must be between 0 and 9999 inclusive; ignoring index-based namespace"); + } + } + } + #if defined(UXRCE_DDS_CLIENT_UDP) if (port[0] == '\0') { @@ -1092,7 +1118,7 @@ $ uxrce_dds_client start -t udp -h 127.0.0.1 -p 15555 PRINT_MODULE_USAGE_PARAM_INT('b', 0, 0, 3000000, "Baudrate (can also be p:)", true); PRINT_MODULE_USAGE_PARAM_STRING('h', nullptr, "", "Agent IP. If not provided, defaults to UXRCE_DDS_AG_IP", true); PRINT_MODULE_USAGE_PARAM_INT('p', -1, 0, 65535, "Agent listening port. If not provided, defaults to UXRCE_DDS_PRT", true); - PRINT_MODULE_USAGE_PARAM_STRING('n', nullptr, nullptr, "Client DDS namespace", true); + PRINT_MODULE_USAGE_PARAM_STRING('n', nullptr, nullptr, "Client DDS namespace. If not provided but UXRCE_DDS_NS_IDX is between 0 and 9999 inclusive, then uav_ + UXRCE_DDS_NS_IDX will be used", true); PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); return 0; diff --git a/src/modules/uxrce_dds_client/uxrce_dds_client.h b/src/modules/uxrce_dds_client/uxrce_dds_client.h index 7b5208a80e..c5c60b1784 100644 --- a/src/modules/uxrce_dds_client/uxrce_dds_client.h +++ b/src/modules/uxrce_dds_client/uxrce_dds_client.h @@ -210,6 +210,7 @@ private: (ParamInt) _param_uxrce_dds_syncc, (ParamInt) _param_uxrce_dds_synct, (ParamInt) _param_uxrce_dds_tx_to, - (ParamInt) _param_uxrce_dds_rx_to + (ParamInt) _param_uxrce_dds_rx_to, + (ParamInt) _param_uxrce_dds_flctrl ) }; diff --git a/src/modules/vtol_att_control/standard.cpp b/src/modules/vtol_att_control/standard.cpp index 5ab114ba16..6c5bba004e 100644 --- a/src/modules/vtol_att_control/standard.cpp +++ b/src/modules/vtol_att_control/standard.cpp @@ -180,7 +180,7 @@ void Standard::update_transition_state() return; } - memcpy(_v_att_sp, _mc_virtual_att_sp, sizeof(vehicle_attitude_setpoint_s)); + *_v_att_sp = *_mc_virtual_att_sp; } else { // we need a recent incoming (fw virtual) attitude setpoint, otherwise return (means the previous setpoint stays active) @@ -188,7 +188,7 @@ void Standard::update_transition_state() return; } - memcpy(_v_att_sp, _fw_virtual_att_sp, sizeof(vehicle_attitude_setpoint_s)); + *_v_att_sp = *_fw_virtual_att_sp; _v_att_sp->thrust_body[2] = -_fw_virtual_att_sp->thrust_body[0]; } @@ -198,11 +198,12 @@ void Standard::update_transition_state() float pitch_body = attitude_setpoint_euler.theta(); float yaw_body = attitude_setpoint_euler.psi(); - if (_v_control_mode->flag_control_climb_rate_enabled) { - roll_body = Eulerf(Quatf(_fw_virtual_att_sp->q_d)).phi(); - } - if (_vtol_mode == vtol_mode::TRANSITION_TO_FW) { + + if (_v_control_mode->flag_control_climb_rate_enabled) { + roll_body = Eulerf(Quatf(_fw_virtual_att_sp->q_d)).phi(); + } + if (_param_vt_psher_slew.get() <= FLT_EPSILON) { // just set the final target throttle value _pusher_throttle = _param_vt_f_trans_thr.get(); @@ -239,12 +240,24 @@ void Standard::update_transition_state() _v_att_sp->thrust_body[0] = _pusher_throttle; const Quatf q_sp(Eulerf(roll_body, pitch_body, yaw_body)); q_sp.copyTo(_v_att_sp->q_d); + mc_weight = math::constrain(mc_weight, 0.0f, 1.0f); } else if (_vtol_mode == vtol_mode::TRANSITION_TO_MC) { + // continually increase mc attitude control as we transition back to mc mode + if (_param_vt_b_trans_ramp.get() > FLT_EPSILON) { + mc_weight = _time_since_trans_start / _param_vt_b_trans_ramp.get(); + } + + mc_weight = math::constrain(mc_weight, 0.0f, 1.0f); + if (_v_control_mode->flag_control_climb_rate_enabled) { // control backtransition deceleration using pitch. pitch_body = Eulerf(Quatf(_mc_virtual_att_sp->q_d)).theta(); + + // blend roll setpoint between FW and MC + const float roll_body_fw = Eulerf(Quatf(_fw_virtual_att_sp->q_d)).phi(); + roll_body = mc_weight * roll_body + (1.0f - mc_weight) * roll_body_fw; } const Quatf q_sp(Eulerf(roll_body, pitch_body, yaw_body)); @@ -252,15 +265,8 @@ void Standard::update_transition_state() q_sp.copyTo(_v_att_sp->q_d); _pusher_throttle = 0.0f; - - // continually increase mc attitude control as we transition back to mc mode - if (_param_vt_b_trans_ramp.get() > FLT_EPSILON) { - mc_weight = _time_since_trans_start / _param_vt_b_trans_ramp.get(); - } } - mc_weight = math::constrain(mc_weight, 0.0f, 1.0f); - _mc_roll_weight = mc_weight; _mc_pitch_weight = mc_weight; _mc_yaw_weight = mc_weight; diff --git a/src/modules/vtol_att_control/vtol_att_control_main.cpp b/src/modules/vtol_att_control/vtol_att_control_main.cpp index 081c5a8106..75c124d4fe 100644 --- a/src/modules/vtol_att_control/vtol_att_control_main.cpp +++ b/src/modules/vtol_att_control/vtol_att_control_main.cpp @@ -368,9 +368,9 @@ VtolAttitudeControl::Run() airspeed_validated_s airspeed_validated; if (_airspeed_validated_sub.copy(&airspeed_validated)) { - const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_1 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_2 - || airspeed_validated.airspeed_source == airspeed_validated_s::SENSOR_3; + const bool airspeed_from_sensor = airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_1 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_2 + || airspeed_validated.airspeed_source == airspeed_validated_s::SOURCE_SENSOR_3; const bool use_airspeed = _param_fw_use_airspd.get() && airspeed_from_sensor; _calibrated_airspeed = use_airspeed ? airspeed_validated.calibrated_airspeed_m_s : NAN; diff --git a/src/modules/vtol_att_control/vtol_att_control_params.c b/src/modules/vtol_att_control/vtol_att_control_params.c index 4b9452d3b6..96727f0c53 100644 --- a/src/modules/vtol_att_control/vtol_att_control_params.c +++ b/src/modules/vtol_att_control/vtol_att_control_params.c @@ -341,7 +341,7 @@ PARAM_DEFINE_FLOAT(VT_FW_DIFTHR_S_P, 1.f); PARAM_DEFINE_FLOAT(VT_FW_DIFTHR_S_Y, 0.1f); /** - * Backtransition deceleration setpoint to pitch I gain. + * Backtransition deceleration setpoint to tilt I gain. * * @unit rad s/m * @min 0 @@ -365,7 +365,7 @@ PARAM_DEFINE_FLOAT(VT_B_DEC_I, 0.1f); * @decimal 1 * @group VTOL Attitude Control */ -PARAM_DEFINE_FLOAT(VT_PITCH_MIN, -5.0f); +PARAM_DEFINE_FLOAT(VT_PITCH_MIN, 0.0f); /** * Minimum pitch angle during hover landing. @@ -380,7 +380,7 @@ PARAM_DEFINE_FLOAT(VT_PITCH_MIN, -5.0f); * @decimal 1 * @group VTOL Attitude Control */ -PARAM_DEFINE_FLOAT(VT_LND_PITCH_MIN, -5.0f); +PARAM_DEFINE_FLOAT(VT_LND_PITCH_MIN, 0.0f); /** * Spoiler setting while landing (hover) diff --git a/src/modules/vtol_att_control/vtol_type.cpp b/src/modules/vtol_att_control/vtol_type.cpp index def70ece07..8195df5f8b 100644 --- a/src/modules/vtol_att_control/vtol_type.cpp +++ b/src/modules/vtol_att_control/vtol_type.cpp @@ -515,12 +515,8 @@ float VtolType::pusher_assist() // limit forward actuation to [0, 0.9] forward_thrust = math::constrain(forward_thrust, 0.0f, 0.9f); - // Set the pitch to 0 if the pitch limit is negative (pitch down), but allow a positive (pitch up) pitch. - // This can be used for tiltrotor to make them hover with a positive angle of attack - const float pitch_new = pitch_setpoint_min > 0.f ? pitch_setpoint_min : 0.f; - // create corrected desired body z axis in heading frame - const Dcmf R_tmp = Eulerf(roll_new, pitch_new, 0.0f); + const Dcmf R_tmp = Eulerf(roll_new, pitch_setpoint_min, 0.0f); Vector3f tilt_new(R_tmp(0, 2), R_tmp(1, 2), R_tmp(2, 2)); // rotate the vector into a new frame which is rotated in z by the desired heading diff --git a/src/modules/zenoh/CMakeLists.txt b/src/modules/zenoh/CMakeLists.txt index 158b1e2333..5854b0fd88 100644 --- a/src/modules/zenoh/CMakeLists.txt +++ b/src/modules/zenoh/CMakeLists.txt @@ -52,7 +52,9 @@ if(NOT DEFINED CONFIG_PTHREAD_MUTEX_TYPES AND CONFIG_PLATFORM_NUTTX) message( SEND_ERROR "Pthread mutex is diabled, Zenoh will not function." ) endif() -set(Z_TRANSPORT_LEASE 60000 CACHE STRING "Link lease duration in milliseconds to announce to other zenoh nodes") # Match ROS2 RMW_ZENOH +# Match ROS2 rmw_zenoh settings +set(Z_TRANSPORT_LEASE 60000 CACHE STRING "Link lease duration in milliseconds to announce to other zenoh nodes") +set(Z_TRANSPORT_LEASE_EXPIRE_FACTOR 2 CACHE STRING "Link lease duration in milliseconds to announce to other zenoh nodes") set(FRAG_MAX_SIZE 512 CACHE STRING "Use this to override the maximum size for fragmented messages") set(BATCH_UNICAST_SIZE 256 CACHE STRING "Use this to override the maximum unicast batch size") @@ -72,7 +74,8 @@ target_compile_options(zenohpico_static PUBLIC -Wno-cast-align -Wno-type-limits -Wno-unused-variable -Wno-maybe-uninitialized - -Wno-conversion) + -Wno-conversion + -Wno-float-equal) target_compile_options(zenohpico_static PRIVATE -Wno-missing-prototypes) if(CONFIG_PLATFORM_NUTTX) diff --git a/src/modules/zenoh/Kconfig b/src/modules/zenoh/Kconfig index 6e98efc2e5..ae050c6ad8 100644 --- a/src/modules/zenoh/Kconfig +++ b/src/modules/zenoh/Kconfig @@ -19,7 +19,7 @@ if MODULES_ZENOH config ZENOH_DEFAULT_LOCATOR string "Zenoh default mode" default "tcp/127.0.0.1:7447" if PLATFORM_POSIX - default "" if !PLATFORM_POSIX + default "tcp/10.41.10.1:7447#iface=eth0" if !PLATFORM_POSIX config ZENOH_RMW_LIVELINESS bool "[EXPERIMENTAL] rmw_zenoh liveliness implemenation" diff --git a/src/modules/zenoh/Kconfig.topics b/src/modules/zenoh/Kconfig.topics index b16a0c41fa..1b59139374 100644 --- a/src/modules/zenoh/Kconfig.topics +++ b/src/modules/zenoh/Kconfig.topics @@ -645,6 +645,14 @@ menu "Zenoh publishers/subscribers" bool "rover_rate_status" default n + config ZENOH_PUBSUB_ROVER_SPEED_SETPOINT + bool "rover_speed_setpoint" + default n + + config ZENOH_PUBSUB_ROVER_SPEED_STATUS + bool "rover_speed_status" + default n + config ZENOH_PUBSUB_ROVER_STEERING_SETPOINT bool "rover_steering_setpoint" default n @@ -653,14 +661,6 @@ menu "Zenoh publishers/subscribers" bool "rover_throttle_setpoint" default n - config ZENOH_PUBSUB_ROVER_VELOCITY_SETPOINT - bool "rover_velocity_setpoint" - default n - - config ZENOH_PUBSUB_ROVER_VELOCITY_STATUS - bool "rover_velocity_status" - default n - config ZENOH_PUBSUB_RPM bool "rpm" default n @@ -705,6 +705,10 @@ menu "Zenoh publishers/subscribers" bool "sensor_gnss_relative" default n + config ZENOH_PUBSUB_SENSOR_GNSS_STATUS + bool "sensor_gnss_status" + default n + config ZENOH_PUBSUB_SENSOR_GPS bool "sensor_gps" default n @@ -741,6 +745,10 @@ menu "Zenoh publishers/subscribers" bool "sensor_selection" default n + config ZENOH_PUBSUB_SENSOR_TEMP + bool "sensor_temp" + default n + config ZENOH_PUBSUB_SENSOR_UWB bool "sensor_uwb" default n @@ -1103,10 +1111,10 @@ config ZENOH_PUBSUB_ALL_SELECTION select ZENOH_PUBSUB_ROVER_POSITION_SETPOINT select ZENOH_PUBSUB_ROVER_RATE_SETPOINT select ZENOH_PUBSUB_ROVER_RATE_STATUS + select ZENOH_PUBSUB_ROVER_SPEED_SETPOINT + select ZENOH_PUBSUB_ROVER_SPEED_STATUS select ZENOH_PUBSUB_ROVER_STEERING_SETPOINT select ZENOH_PUBSUB_ROVER_THROTTLE_SETPOINT - select ZENOH_PUBSUB_ROVER_VELOCITY_SETPOINT - select ZENOH_PUBSUB_ROVER_VELOCITY_STATUS select ZENOH_PUBSUB_RPM select ZENOH_PUBSUB_RTL_STATUS select ZENOH_PUBSUB_RTL_TIME_ESTIMATE @@ -1118,6 +1126,7 @@ config ZENOH_PUBSUB_ALL_SELECTION select ZENOH_PUBSUB_SENSOR_COMBINED select ZENOH_PUBSUB_SENSOR_CORRECTION select ZENOH_PUBSUB_SENSOR_GNSS_RELATIVE + select ZENOH_PUBSUB_SENSOR_GNSS_STATUS select ZENOH_PUBSUB_SENSOR_GPS select ZENOH_PUBSUB_SENSOR_GYRO select ZENOH_PUBSUB_SENSOR_GYRO_FFT @@ -1127,6 +1136,7 @@ config ZENOH_PUBSUB_ALL_SELECTION select ZENOH_PUBSUB_SENSOR_OPTICAL_FLOW select ZENOH_PUBSUB_SENSOR_PREFLIGHT_MAG select ZENOH_PUBSUB_SENSOR_SELECTION + select ZENOH_PUBSUB_SENSOR_TEMP select ZENOH_PUBSUB_SENSOR_UWB select ZENOH_PUBSUB_SENSORS_STATUS select ZENOH_PUBSUB_SENSORS_STATUS_IMU diff --git a/src/modules/zenoh/module.yaml b/src/modules/zenoh/module.yaml index 25e658f9f3..095e1f4dc8 100644 --- a/src/modules/zenoh/module.yaml +++ b/src/modules/zenoh/module.yaml @@ -6,9 +6,12 @@ parameters: ZENOH_ENABLE: description: - short: Zenoh Enable - long: Zenoh + short: Enable Zenoh + long: | + Set true (1) to start the Zenoh driver module (a.k.a the "Zenoh-Pico Node"). + See https://docs.px4.io/main/en/middleware/zenoh and + https://docs.px4.io/main/en/modules/modules_driver.html#zenoh category: System - type: int32 + type: boolean reboot_required: true default: 0 diff --git a/src/modules/zenoh/publishers/uorb_publisher.hpp b/src/modules/zenoh/publishers/uorb_publisher.hpp index 110cbea8eb..2f95fd319d 100644 --- a/src/modules/zenoh/publishers/uorb_publisher.hpp +++ b/src/modules/zenoh/publishers/uorb_publisher.hpp @@ -66,7 +66,7 @@ public: ~uORB_Zenoh_Publisher() override = default; // Update the uORB Subscription and broadcast a Zenoh ROS2 message - virtual int8_t update() override + virtual z_result_t update() override { #ifdef CONFIG_ZENOH_PUB_ON_MATCHING z_matching_status_t status; diff --git a/src/modules/zenoh/publishers/zenoh_publisher.cpp b/src/modules/zenoh/publishers/zenoh_publisher.cpp index 6bef35a714..e38af892ae 100644 --- a/src/modules/zenoh/publishers/zenoh_publisher.cpp +++ b/src/modules/zenoh/publishers/zenoh_publisher.cpp @@ -78,8 +78,10 @@ int Zenoh_Publisher::declare_publisher(z_owned_session_t s, const char *keyexpr, return 0; } -int8_t Zenoh_Publisher::publish(const uint8_t *buf, int size) +z_result_t Zenoh_Publisher::publish(const uint8_t *buf, int size) { + z_result_t ret; + z_publisher_put_options_t options; z_publisher_put_options_default(&options); @@ -87,12 +89,21 @@ int8_t Zenoh_Publisher::publish(const uint8_t *buf, int size) _attachment.time = hrt_absolute_time(); z_owned_bytes_t z_attachment; - z_bytes_from_static_buf(&z_attachment, (const uint8_t *)&_attachment, RMW_ATTACHEMENT_SIZE); + ret = z_bytes_from_static_buf(&z_attachment, (const uint8_t *)&_attachment, RMW_ATTACHEMENT_SIZE); + + if (ret != Z_OK) { + return ret; + } options.attachment = z_move(z_attachment); z_owned_bytes_t payload; - z_bytes_copy_from_buf(&payload, buf, size); + ret = z_bytes_copy_from_buf(&payload, buf, size); + + if (ret != Z_OK) { + return ret; + } + return z_publisher_put(z_loan(_pub), z_move(payload), &options); } diff --git a/src/modules/zenoh/publishers/zenoh_publisher.hpp b/src/modules/zenoh/publishers/zenoh_publisher.hpp index 89ae1f9f09..b787f39737 100644 --- a/src/modules/zenoh/publishers/zenoh_publisher.hpp +++ b/src/modules/zenoh/publishers/zenoh_publisher.hpp @@ -60,7 +60,7 @@ public: virtual int undeclare_publisher(); - virtual int8_t update() = 0; + virtual z_result_t update() = 0; virtual void print(); diff --git a/src/modules/zenoh/zenoh-pico b/src/modules/zenoh/zenoh-pico index ede74c3f5b..6ec4dc1995 160000 --- a/src/modules/zenoh/zenoh-pico +++ b/src/modules/zenoh/zenoh-pico @@ -1 +1 @@ -Subproject commit ede74c3f5b0ac190d074e796057c62848bb9a488 +Subproject commit 6ec4dc1995f185330e4f6faa8c719eb86f180deb diff --git a/src/modules/zenoh/zenoh.cpp b/src/modules/zenoh/zenoh.cpp index e8a4c62bdc..ec4bc5e06f 100644 --- a/src/modules/zenoh/zenoh.cpp +++ b/src/modules/zenoh/zenoh.cpp @@ -270,6 +270,7 @@ int ZENOH::setupTopics(px4_pollfd_struct_t *pfds) #ifdef Z_SUBSCRIBE _zenoh_subscribers = (Zenoh_Subscriber **)malloc(sizeof(Zenoh_Subscriber *)*_sub_count); + memset(_zenoh_subscribers, 0x0, sizeof(Zenoh_Subscriber *)*_sub_count); if (_zenoh_subscribers) { char topic[TOPIC_INFO_SIZE]; @@ -305,6 +306,7 @@ int ZENOH::setupTopics(px4_pollfd_struct_t *pfds) #endif } else { + _zenoh_subscribers[i] = NULL; PX4_ERR("Could not create a subscriber for type %s", type); } @@ -325,6 +327,7 @@ int ZENOH::setupTopics(px4_pollfd_struct_t *pfds) #ifdef Z_PUBLISH _zenoh_publishers = (uORB_Zenoh_Publisher **)malloc(_pub_count * sizeof(uORB_Zenoh_Publisher *)); + memset(_zenoh_publishers, 0x0, _pub_count * sizeof(uORB_Zenoh_Publisher *)); if (_zenoh_publishers) { char topic[TOPIC_INFO_SIZE]; @@ -361,6 +364,7 @@ int ZENOH::setupTopics(px4_pollfd_struct_t *pfds) #endif } else { + _zenoh_publishers[i] = NULL; PX4_ERR("Could not create a publisher for type %s", type); } @@ -384,7 +388,7 @@ int ZENOH::setupTopics(px4_pollfd_struct_t *pfds) void ZENOH::run() { - int8_t ret; + z_result_t ret; int i; _pub_count = _config.getPubCount(); _sub_count = _config.getSubCount(); @@ -395,6 +399,8 @@ void ZENOH::run() return; } + connected = true; + PX4_INFO("Starting reading/writing tasks..."); if (setupTopics(pfds) < 0) { @@ -451,6 +457,8 @@ void ZENOH::run() zp_stop_lease_task(z_session_loan_mut(&_s)); z_drop(z_session_move(&_s)); + + connected = false; exit_and_cleanup(); } @@ -496,7 +504,12 @@ Zenoh demo bridge int ZENOH::print_status() { - PX4_INFO("running"); + if (connected) { + PX4_INFO("Connected"); + + } else { + PX4_INFO("Connecting"); + } PX4_INFO("Publishers"); diff --git a/src/modules/zenoh/zenoh.h b/src/modules/zenoh/zenoh.h index 70ecdbd525..c3940a5582 100644 --- a/src/modules/zenoh/zenoh.h +++ b/src/modules/zenoh/zenoh.h @@ -97,11 +97,12 @@ private: Zenoh_Config _config; int _pub_count; - uORB_Zenoh_Publisher **_zenoh_publishers; + uORB_Zenoh_Publisher **_zenoh_publishers = nullptr; int _sub_count; - Zenoh_Subscriber **_zenoh_subscribers; + Zenoh_Subscriber **_zenoh_subscribers = nullptr; z_owned_session_t _s; + bool connected = false; px4_guid_t _px4_guid{}; diff --git a/src/systemcmds/failure/failure.cpp b/src/systemcmds/failure/failure.cpp index 2b28aefde8..2d764d9b91 100644 --- a/src/systemcmds/failure/failure.cpp +++ b/src/systemcmds/failure/failure.cpp @@ -175,12 +175,6 @@ extern "C" __EXPORT int failure_main(int argc, char *argv[]) return 0; } - if (argc < 3) { - PX4_ERR("Not enough arguments."); - print_usage(); - return 1; - } - const char *myoptarg = nullptr; int ch = 0; int myoptind = 1; @@ -200,6 +194,12 @@ extern "C" __EXPORT int failure_main(int argc, char *argv[]) } } + if ((argc < 3) || (myoptind + 1) >= argc) { + print_usage(); + PX4_ERR("Not enough arguments."); + return 1; + } + const char *requested_failure_unit = argv[myoptind]; for (const auto &failure_unit : failure_units) { diff --git a/src/systemcmds/tests/.clang-tidy b/src/systemcmds/tests/.clang-tidy deleted file mode 100644 index 9d2589717a..0000000000 --- a/src/systemcmds/tests/.clang-tidy +++ /dev/null @@ -1,119 +0,0 @@ ---- -Checks: '*, - -android*, - -bugprone-integer-division, - -cert-dcl50-cpp, - -cert-env33-c, - -cert-err34-c, - -cert-err58-cpp, - -cert-msc30-c, - -cert-msc50-cpp, - -cert-flp30-c, - -clang-analyzer-core.CallAndMessage, - -clang-analyzer-core.NullDereference, - -clang-analyzer-core.UndefinedBinaryOperatorResult, - -clang-analyzer-core.uninitialized.Assign, - -clang-analyzer-core.VLASize, - -clang-analyzer-cplusplus.NewDelete, - -clang-analyzer-cplusplus.NewDeleteLeaks, - -clang-analyzer-deadcode.DeadStores, - -clang-analyzer-optin.cplusplus.VirtualCall, - -clang-analyzer-optin.performance.Padding, - -clang-analyzer-security.FloatLoopCounter, - -clang-analyzer-security.insecureAPI.strcpy, - -clang-analyzer-unix.API, - -clang-analyzer-unix.cstring.BadSizeArg, - -clang-analyzer-unix.Malloc, - -clang-analyzer-unix.MallocSizeof, - -cppcoreguidelines-c-copy-assignment-signature, - -cppcoreguidelines-interfaces-global-init, - -cppcoreguidelines-no-malloc, - -cppcoreguidelines-owning-memory, - -cppcoreguidelines-pro-bounds-array-to-pointer-decay, - -cppcoreguidelines-pro-bounds-constant-array-index, - -cppcoreguidelines-pro-bounds-pointer-arithmetic, - -cppcoreguidelines-pro-type-const-cast, - -cppcoreguidelines-pro-type-cstyle-cast, - -cppcoreguidelines-pro-type-member-init, - -cppcoreguidelines-pro-type-reinterpret-cast, - -cppcoreguidelines-pro-type-union-access, - -cppcoreguidelines-pro-type-vararg, - -cppcoreguidelines-special-member-functions, - -fuchsia-default-arguments, - -fuchsia-overloaded-operator, - -google-build-using-namespace, - -google-explicit-constructor, - -google-global-names-in-headers, - -google-readability-casting, - -google-readability-function-size, - -google-readability-namespace-comments, - -google-readability-todo, - -google-runtime-int, - -google-runtime-references, - -hicpp-braces-around-statements, - -hicpp-deprecated-headers, - -hicpp-explicit-conversions, - -hicpp-function-size, - -hicpp-member-init, - -hicpp-no-array-decay, - -hicpp-no-assembler, - -hicpp-no-malloc, - -hicpp-signed-bitwise, - -hicpp-special-member-functions, - -hicpp-use-auto, - -hicpp-use-equals-default, - -hicpp-use-equals-delete, - -hicpp-use-override, - -hicpp-vararg, - -llvm-header-guard, - -llvm-include-order, - -llvm-namespace-comment, - -misc-incorrect-roundings, - -misc-macro-parentheses, - -misc-misplaced-widening-cast, - -misc-redundant-expression, - -misc-unconventional-assign-operator, - -misc-unused-parameters, - -modernize-deprecated-headers, - -modernize-loop-convert, - -modernize-pass-by-value, - -modernize-return-braced-init-list, - -modernize-use-auto, - -modernize-use-bool-literals, - -modernize-use-default-member-init, - -modernize-use-emplace, - -modernize-use-equals-default, - -modernize-use-equals-delete, - -modernize-use-override, - -modernize-use-using, - -performance-inefficient-string-concatenation, - -performance-unnecessary-value-param, - -readability-avoid-const-params-in-decls, - -readability-braces-around-statements, - -readability-container-size-empty, - -readability-delete-null-pointer, - -readability-else-after-return, - -readability-function-size, - -readability-implicit-bool-cast, - -readability-implicit-bool-conversion, - -readability-inconsistent-declaration-parameter-name, - -readability-named-parameter, - -readability-non-const-parameter, - -readability-redundant-control-flow, - -readability-redundant-declaration, - -readability-redundant-member-init, - -readability-simplify-boolean-expr, - -readability-static-accessed-through-instance, - -readability-static-definition-in-anonymous-namespace, - ' -WarningsAsErrors: '*' -CheckOptions: - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: google-readability-function-size.BranchThreshold - value: '600' - - key: google-readability-function-size.LineThreshold - value: '4000' - - key: google-readability-function-size.StatementThreshold - value: '4000' -... diff --git a/test/mavsdk_tests/MAVSDK_VERSION b/test/mavsdk_tests/MAVSDK_VERSION index 7c69a55dbb..1e33456831 100644 --- a/test/mavsdk_tests/MAVSDK_VERSION +++ b/test/mavsdk_tests/MAVSDK_VERSION @@ -1 +1 @@ -3.7.0 +3.11.2 diff --git a/test/mavsdk_tests/autopilot_tester_figure_eight.cpp b/test/mavsdk_tests/autopilot_tester_figure_eight.cpp index 2d6e8f0b85..b855cc3ceb 100644 --- a/test/mavsdk_tests/autopilot_tester_figure_eight.cpp +++ b/test/mavsdk_tests/autopilot_tester_figure_eight.cpp @@ -1,7 +1,7 @@ /**************************************************************************** * - * Copyright (c) 2023 PX4 Development Team. All rights reserved. + * Copyright (c) 2023-2025 PX4 Development Team. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,8 +39,9 @@ #include #include + #include -#include + using namespace mavsdk::geometry; diff --git a/test/mavsdk_tests/test_multicopter_basics.cpp b/test/mavsdk_tests/test_multicopter_basics.cpp index 52b933ff17..427e69c03f 100644 --- a/test/mavsdk_tests/test_multicopter_basics.cpp +++ b/test/mavsdk_tests/test_multicopter_basics.cpp @@ -40,7 +40,7 @@ TEST_CASE("Takeoff and hold position", "[multicopter][vtol]") { const float takeoff_altitude = 10.f; - const float altitude_tolerance = 0.1f; + const float altitude_tolerance = 0.2f; const int delay_seconds = 60.f; AutopilotTester tester; diff --git a/validation/module_schema.yaml b/validation/module_schema.yaml index 1e1baa1037..a2f77f75ee 100644 --- a/validation/module_schema.yaml +++ b/validation/module_schema.yaml @@ -155,7 +155,7 @@ parameters: 'm/s^3/sqrt(Hz)', 'm/s/sqrt(Hz)', 's/(1000*PWM)', '%m/s', 'min', 'us/C', 'N/(m/s)', 'Nm/(rad/s)', 'Nm', 'N', 'rpm', - 'normalized_thrust/s', 'normalized_thrust', 'norm', 'SD'] + 'normalized_thrust/s', 'normalized_thrust', 'norm', 'SD', 'dBHz'] bit: # description of all bits for type bitmask. # The first bit is 0. @@ -352,6 +352,28 @@ actuator_output: # ui only shows the param if this condition is true type: string regex: *condition_regex + center: + type: dict + schema: + min: + # Minimum center value + type: integer + min: 0 + max: 65536 + max: + # Maximum center value + type: integer + min: 0 + max: 65536 + default: + # Default center value + type: integer + min: 0 + max: 65536 + show_if: + # ui only shows the param if this condition is true + type: string + regex: *condition_regex failsafe: type: dict schema: